Минутка просвещения

Читать в телеге. Когда-то там были посты не только от меня.

Буфер обмена с консольной виртуалкой

Сымитировать буфер обмена в консоли без графического окружения (например, на виртуалке) можно, установив gpm — демон для мышки. С помощью него можно выделять текст левой кнопкой, а правой — вставлять. Кто-то даже упоролся и сделал интеграцию с буфером хост-машины, но выглядит стремно. Древние фиче-реквесты прилагаются.

СсылкаКомментировать

Оптимизация хэш-таблицы

Прикольный доклад про пошаговую оптимизацию хэш-таблицы в плюсах: начинается с экономии указателей в методе цепочек и заканчивается оптимизацией под кэши процессора.

Кто “выше” таких оптимизаций — может посмотреть про оптимизацию хэш-таблицы для многопоточного доступа (и там же можно освежить в памяти как хэш-таблицы вообще работают).

СсылкаКомментировать

Отладка Jenkins пайплайна

Чтобы быстрее отладить/доработать скрипт пайплана в jenkins, можно использовать:

  • Генератор кода http://${jenkinsHost}/pipeline-syntax, в котором можно накликать один из шагов из плагинов.
  • REPL http://${jenkinsHost}/script, чтобы проверить небольшие кусочки или какие-то моменты из Groovy. Недостаток — контекст немного отличается от пайплайна (запускается без песочницы), и код из REPL не всегда будет работать в пайплайне.
  • Список глобальных переменных и методов http://${jenkinsHost}/pipeline-syntax/globals, чтобы посмотреть, что доступно.
  • Скрипт для одобрения методов за пределами песочницы (если пришлось залезть в кишки), чтобы одобрять методы не по одному.
  • Replay билда + отключение шагов, которые можно пропустить, для более быстрой проверки работоспособности.
СсылкаКомментировать

Запуск нескольких целей в Maven

С помощью defaultGoal и профиля можно запускать несколько фаз или целей:

<profile>
  <id>some-profile</id>
  <build>
    <defaultGoal>
      test
      a.group:an.artifact:some-plugin:goal@custom-goal-config
    </defaultGoal>
...

При такой настройке mvn -Psome-profile будет эквивалентен mvn test a.group:an.artifact:some-plugin:goal@custom-goal-config. Это удобно для разделения этапов в пайплайне (и когда есть конфигурации для целей). Мне пригодилось для получения агрегированного результата покрытия после параллельного выполнения тестов.

СсылкаКомментировать

Проектирование API

Посмотрел на днях доклад про проектирование API, он неплох (особенно для джунов), но ничего нового для себя, увы, не узнал. Доклад довольно старый, аж из 2007 вернуть бы его, но рекомендую хотя бы пролистать презентацию: повторение — мать ученья.

Интересно в этом докладе то, что докладчик — автор книги Effective Java, той самой, которую очень любили создатели Kotlin, и откуда пошли многие (в том числе спорные) решения в языке. Забавно, что некоторые API java и Гугла (где работал автор) советам, изложенным в докладе, явно не соответствуют.

СсылкаКомментировать

Конвертер видео

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

ffmpeg -i video.mp4 -ab 320k audio.mp3
СсылкаКомментировать

Хрупкие аннотации Spring

Одна из самых бесючих проблем в Spring — это то, что одной аннотацией можно неочевидно сломать работающий код.

Например, добавление @ComponentScan превратит в тыкву @WebMvcTest.

@Transactional может сломать любой сервис без интерфейса, причем в лучшем случае будет NoSuchBeanDefinitionException, а в худшем, а в худшем, если класс-потребитель не финальный, то будет тупо null вместо бина.

Поставил @TestExecutionListeners без mergeMode = MERGE_WITH_DEFAULTS — и тесты перестают работать.

И подобных примеров еще массу можно напридумывать:(

СсылкаКомментировать

Связи в проекте и Github Action

Очевидно, что связи между артефактами в проекте очень полезны. Код привязан к коммиту, коммит — к тикету и код-ревью/пулл-реквесту, тикет к ТЗ/эпику/истории и/или документации. Причем хорошо, когда эти связи еще и двусторонние: например, чтобы по коду можно посмотреть тикет и зачем он был написан, а по тикету — написанный код. Иначе при смене процесса придется искать эти связи вручную или не напрямую. Кажется, это одна из “продающих” фишек Gitlab или Space.

Мне не хватало связи пулл-реквеста GitHub с тикетом, существующие варианты action’ов показались унылыми, поэтому я написал свой, старался сделать его максимально универсальным.

К сожалению, для написания action’ов есть только два варианта: nodejs или docker-образ. Я по глупости выбрал первый вариант, потому что большинство action’ов были написаны на нем, да и библиотека для работы с GitHub была только для JS. В очередной раз вляпался в экосистему nodejs: обновление npm через него самого сделало его непригодным для использования. Куча пулл-реквестов от Dependabot — это мрак, группировки обновлений нет годами.

TypeScript вроде мощный и классный, можно выражения в шаблонах считать, но нет каких-то банальных вещей вроде безопасного enum или filterNotNull. Но мне понравились линтеры и форматтеры — благодаря им исправилась половина моих ошибок.

Сама библиотека для работы с GitHub сильно разочаровала. Хочешь получить текст коммита в пулл-реквесте? Запрашивай через API. Хочешь имя ветки? Используй окружение или костыли. Конфигурация в yaml, но параметры только строчные. Наконец, добила возможность гонок: все работы из action’ов запускаются параллельно, а контекст запуска статичный, поэтому пришлось менять получение тела из контекста на запрос к API.

СсылкаКомментировать

Что говорит наука о разработке?

Многие “лучшие практики” разработки основаны на мнениях и личном опыте, а не на исследованиях. А исследований про процесс разработки очень мало и к ним есть много вопросов относительно качества. Мне понравился доклад на эту тему.

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

В другом исследовании выяснили, что в говнокоде больше вероятность наличия багов, но при этом его переписывание не коррелирует со снижением числа багов. Еще было исследование исходников кучи проектов на GitHub с результатом, что программы на ФЯП имели меньше багов, чем программы на императивных языках, а на языках с автоматическим управлением памятью — меньше, чем на языках с ручным управлением и т.п. (что вроде очевидно). Однако последующее исследование показало ошибку в методике, а с ее учетом выяснилось, что ни у одного языка нет преимуществ относительно другого. Похожие проблемы были при исследовании TDD, систем типов, парного программирования.

Но есть и вещи, которые более-менее подтверждаются наукой. Эмпирически доказано, что устройство организации сильно влияет на устройство кода. Многие самые дорогие баги — это проблемы архитектуры или требований. Практика, которая работает — код-ревью, она позволяет ловить 60-80% багов. А еще одни из самых существенных факторов для качественной разработки (да и любой работы в целом) — это отсутствие стресса и хороший сон. Бессонная ночь = -50% к производительности. Кранчи делают итоговый продукт хуже по всем метрикам.

Ссылки на статьи из доклада можно найти тут.

СсылкаКомментировать