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

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

Устранение шумов микрофона в Linux

Без понятия, почему это не включено по умолчанию, но хотя бы можно включить. В /etc/pulse/default.pa надо добавить

.ifexists module-echo-cancel.so
load-module module-echo-cancel aec_method=webrtc source_name=echocancel sink_name=echocancel1
set-default-source echocancel
set-default-sink echocancel1
.endif

И перезапустить PulseAudio (pulseaudio -k) или перезагрузиться. После этого в настройках звука появятся дополнительные входы/выходы с пометкой echo cancelled.

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

Судьба GIL в Python

Кажется, Python близок к тому, чтобы отказаться от GIL. Статью рекомендую к прочтению.

Одна из основных проблем GIL — сборщик мусора, а именно счетчики ссылок. Чтобы они работали корректно при конкурентном доступе, их можно заменить на атомарные, но это будет серьезным ударом по производительности — до 60%. Большинство программ на Python — однопоточные, и подобные расходы непозволительны.

Сэм Гросс, один из авторов PyTorch, предложил интересное решение этой проблемы на основе соответствующего исследования. У каждого объекта теперь два счетчика ссылок — локальный (для владельца) и глобальный (для остальных тредов). Первый счетчик — быстрый и неатомарный, потому что у владельца к нему эксклюзивный доступ, второй — атомарный, но к нему, скорее всего, будет гораздо меньше обращений, потому что большинство объектов локальные.

Локальный счетчик не совсем прост: два младших бита у него зарезервированы под флаги. Первый нужен для бессмертных объектов: True, False, None, -127..128 и т.п. — считать ссылки на них бесполезно, удалять их не нужно. Второй флаг используется для долгоживущих объектов вроде модулей и функций: они почти всегда попадают в globals или создают циклические ссылки. Проще пройтись сборщиком мусора и найти неиспользуемые.

Дополнительно Гросс оптимизировал кучу мелочей в интерпретаторе, и он стал быстрее на 10%. Похоже, что такими темпами можно будет увидеть Python4 :)

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

Поиск всех пулл-реквестов пользователя в GitHub

Чтобы посмотреть вклад в Open Source, можно зайти на https://github.com/pulls и убрать фильтр открытых:

is:pr author:ov7a

Однако может потребоваться фильтр по владельцу репозитория/организации, чтобы отсеять коммиты, за которые платят зарплату:

is:pr author:udalov -user:JetBrains -user:Kotlin
СсылкаКомментировать

Приостановка процесса

Чтобы приостановить работу какого-нибудь долгого процесса, можно отправить ему сигнал TSTP:

kill -TSTP [pid]

или, если он был проигнорирован — STOP:

kill -STOP [pid]

Продолжить процесс потом можно будет через сигнал CONT:

kill -CONT [pid]

Мне эти команды пригодились для временной остановки питонячего скрипта миграции данных, который "долго запрягает, но быстро едет". Перезапуск потребовал бы ручной перенастройки (чтобы не повторять уже выполненные операции). Скрипт проигнорировал TSTP, а вот после STOP успешно приостановил свою работу.

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

Есть ли будущее у мутационного тестирования?

Интересная заметка про мутационное тестирование. Тезисно:

  • Мутационное тестирование не используется широко в индустрии, потому что оно свидетельствует о том, что и так уже известно: тесты плохо помогают находить ошибки кодирования.
  • Мутационное тестирование жрет слишком много ресурсов.
  • Мутационное тестирование часто предполагает, что ошибка находится в одной строке. Несколько исследований показывают, что это не так: однострочные исправления составляют примерно 10% от общего количества багфиксов.
  • Фаззинг-тестирование выглядит более достойной альтернативой.
СсылкаКомментировать

Большие запросы без пагинации и scroll'а в ElasticSearch

Параметр search_after позволяет выполнить последовательность запросов без использования пагинации (у которой есть ограничения на размер page*size, по умолчанию 10 000) и без использования scroll (который практически создает слепок индекса и жрет память). Идея довольно простая: использовать сортировку по какому-то полю, взять первые N результатов, а потом сделать запрос, в которого значение поля сортировки больше, чем у N-ного результата.

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

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

CQRS

CQRS (Command and Query Responsibility Segregation) — это очень простой принцип построения систем, который является продолжением CQS (сommand-query separation). Напомню, что CQS говорит о том, что всякий метод является либо командой, которая меняет данные, но ничего не возвращает, либо запросом, который возвращает данные, но не меняет их. А CQRS дополняет его, говоря о том, для обработки команд и обработки запросов используются разные сущности (например, сервисы).

Подробнее можно посмотреть в презентации, которую я делал для внутреннего доклада, или посмотреть видосик (но им я недоволен, потому что речь моя оставляет желать лучшего).

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

Иерархия мотивации

Один из самых классных докладов на конференции TeamLead 2020 был про мотивацию.

В нем обозначена проблема, что руководство пытается лечить симптомы (поведение), а не корневую причину. Рассмотрены 6 мотивационных статусов:

  1. Автоматическая мотивация — делаешь на автомате, мысли о другом.
  2. Внешняя — ждешь награду, не обязательно материальную.
  3. Навязанная — избегаешь "наказания" (увольнения, стыда, позора, провала и т.п.).
  4. Согласованная — видишь связь со своей целью. "Я хочу заниматься этой задачей".
  5. Интегрированная — получаешь удовольствие, чувствуешь связь с призванием, "работа мечты". Ошибки воспринимаются как полезный опыт.
  6. Поток — наслаждение, "хочу делать только это, на остальное пофиг". Важен процесс, нет гарантии результата.

В 4-6 цель внутри, задачи выполняются ответственно, мотивация оптимальная. В 1-3 цель вне задач и они выполняются для галочки. Долго в низких уровнях мало кто может находится. Кроме этого, существуют 3 базовых психологических потребности: автономия, принадлежность, компетентность. Если какая-то не закрыта, то с мотивацией будут проблемы.

Чтобы повысить мотивацию, есть 2 основных способа:

  1. Внезапно, устранить проблемы, если у демотивации есть объективная причина.
  2. Включить саморегуляцию: осознанность (чтобы сотрудник думал о себе, рефлексировал), цели (для чего он к ней идет), ценности (которые определяют направление его движения и помогают ставить цели, принимать решения).

Задайте себе вопрос — если бы пропали деньги из мира, стали бы вы заниматься тем, чем занимаетесь сейчас?

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

Макакачность

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

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

Но вот когда с разбегу не получилось, то легко провалиться в яму "ну вот, почти работает, сейчас чуть-чуть поправлю здесь и будет все хорошо". Еще хуже будет, когда переключаешься на другую активность и не можешь сосредоточиться на проблеме (или не хочешь).

Начал замечать за собой такое поведение: например, когда реализовывал поиск по префиксному дереву с учетом разовой ошибки. Все тесты были уже готовы, просто хотел решить сам, чтобы понять, какие трудности могут возникнуть у моих студентов. Алгоритмы там очень простые, накидал почти не думая решение — тесты не прошли. Поправил немного в месте, где скорее всего ошибка — не прошли другие. Как макака, повторял эти действия. Через пару часов очнулся: вместо кода — лапша с костылями al dente, тесты не проходят. Все стер, включил мозги и написал минут за 10 нормально.

Вот смотрю на себя и на то, что вокруг, и думаю: индустрия хотела 10x-инженеров, а получила 10x-макак.

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

Большие стрелки и маленькие квадратики

Когда готовил доклад про скучное программирование, то не нашел эту статью, поэтому заменил затравку на цитату Хоара ("Inside every large program is a small program struggling to get out.").

А ключевая идея статьи заключается в том, что больше всего времени разработчика тратится не на бизнес-логику приложения, а на интеграции и передачу данных между различными слоями и компонентами. И картинки с тонкими стрелочками и крупными блоками искажают картину. С точки зрения трудозатрат они должны выглядеть примерно так:

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

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