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

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

Не используйте нестандартные клиенты к БД

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

Стали разбираться — эволюция базы повисла на переименовании таблицы. Сервис — монолит, кроме него в базу только метрики ходят (но не в эту таблицу). Однако переименование таблицы — это действие, которое требует ACCESS EXCLUSIVE лок, и ни одна операция, хоть как-то трогающая таблицу, не может выполняться параллельно.

“Убийцей” оказалась IntelliJ Idea Ultimate, в которой коллега запускал проверки на проде перед деплоем. На препроде воспроизвести не удалось, но при повторном деплое опять “все повисло” и только когда прибили Idea, все накатилось. Судя по всему, она запрашивала метаданные для автодополнения и т.п. и где-то висела незакрытая транзакция. psql такого бы себе не позволил (по умолчанию, по крайней мере) :/ А вообще еще лучше никаких лишних открытых соединений не держать при накатке изменений.

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

Northguard

Как-то совсем мимо меня прошло, что LinkedIn вырос из им же созданной Kafka и сделал новый брокер сообщений/логов — Northguard.

Причина довольно прозаична: контроллер хранил довольно большое состояние централизованно на 1 узле и это в масштабах LinkedIn стало бутылочным горлышком. И это с учетом того, что от Zookeeper отказались еще в 2021. А еще были проблемы с балансировкой и обслуживанием тьмы кластеров. Продумали и миграцию, за это отвечает Xinfra — по сути, адаптер, поддерживающий оба брокера.

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

ИИ — это не "просто другой уровень абстракции"

Один из популярных аргументов вайбкодеров заключается в том, что с ИИ мы просто переходим на более высокий уровень абстракции: сначала был машинный код, потом появились языки низкого уровня, затем высокого, фреймворки и т.п. И, мол, вы же не читаете вывод компилятора в машинных кодах? Тогда и код, выплюнутый нейронкой, читать не надо. Если что — с ее же помощью потом и исправите.

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

Первая — запись намерения. Для совместной работы над программным продуктом используют текущий уровень абстракции — если, например, это код на питоне, то у вас в репозитории, пул-реквестах и т.п. фигурирует конкретный код на питоне, а не какой-то его продукт, например, байт-код. Если вы используете фреймворк, то артефактом у вас будут вызовы каких-то конкретных функций/шаблонов/API этого фреймворка, а не скрытый за ними код. Через LLM вы обычно получаете код, т.е. артефакт принадлежит более низкому уровню абстракции. У вас в репозитории не хранятся промпты, которыми был код сгенерирован. Если не записано намерение, то совместная работа опускается минимум на один уровень абстракции ниже, а собственно намерение придется выковыривать из него. И вся сложность решения остается как есть, без инкапсуляции.

Вторая — воспроизводимость. Компилятор преобразует один и тот же вход в один и тот же выход. Обращение к фреймворку приведет к одному и тому же участку кода. Если, например, у вас написано json.dumps(obj), то это будет везде работать одинаково (если не быть ультрадушнилой). Нейронка же вам будет выдавать на один промпт разный результат каждый раз. Поэтому их и хранить бесполезно (так-то нейронки могут легко и всякие верхнеуровневые инструкции игнорировать). Без воспроизводимости придется либо переделывать одну и ту же работу по проверке качества и/или играть в рулетку при каждом изменении. А каждый проект с такой “абстракцией” становится “снежинкой”.

Третья — ответственность. У компилятора/языка/фреймворка есть разработчики, документация, какое-никакое сообщество и т.п. Если в них обнаружится какая-то проблема, то, скорее всего, она будет не только у вас, и у разработчиков будет мотивация это исправить. Еще у популярных инструментов есть какая-никакая репутация, и шансы, что они будут творить какую-то дичь, не очень высоки. У LLM ноль агентности с точки зрения ответственности, и в итоге артефакт с более низкого уровня абстракции становится вашей проблемой. А адекватному бизнесу нужна как раз предсказуемость.

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

Более уместно говорить о том, что использование нейронок — это передача работы в аутсорс (хотя это тоже некорректно). Задайтесь вопросом — если бы аутсорс/фриланс был бы универсальным решением (даже если он супербыстрый и дешевый), то почему в последние года был бум продуктивизаций компаний, когда у кучи совсем неайтишных компаний, даже годами делегировавших все на аутсорс, стали появляться свои отделы разработки?

P.S. Кстати очень забавно читать некоторые новости про ИИ/LLM, заменяя все это на “аутсорс”:)

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

Выбор лицензии

Сабж.

Для “продвинутых пользователей” — в форме душной таблицы. Но даже она неполная.

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

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

50 оттенков преждевременной оптимизации

Обычно под преждевременной оптимизацией имеют в виду переоптимизации в коде, который находится не на критическом пути, или микрооптимизации типа x = (x * 0xCCCCCCCD) >> 35, которые обычно вредны. И что, разумеется, нужно ориентироваться на бенчмарки.

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

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

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

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

Экологические карты

Чистота воздуха: WAQI и IQAir.

Качество воды: GeoAquaWatch и WWF.

Карта загрязнений (явно неполная).

Источники электричества (еще там указан карбоновый след).

Уровень шума и конкретно шум от аэропортов.

Ветер, температура, давление.

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

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

Бенчмарки ИИ не стоят доверия

Внезапно™, бенчмарки по качеству нейронок типа SWEBench — полная фигня с точки зрения защиты от читерства: никакой изоляции задания и решения, не надо даже ничего хакать: можно посмотреть решение в git log, манки-патчнуть pytest, чтобы все тесты прошли, или просто… открыть браузер и скачать ответы. И это вдобавок к тому, что и к качеству тестов есть вопросы.

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

В преподские времена проверял лабы по алгоритмам с помощью Ejudge. Он был дырявый насквозь, но там хотя бы надо было ИБ-дырки искать (ладно, ответы тоже были, но от тупого копирования была базовая проверка на списывание).

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

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

Нормальные формы в БД

В одном (нерабочем) чате мимолетно промелькнуло упоминание нормальных форм БД. Я понял, что уже забыл вообще все, что связано с ними. Почитал определения — ничего не понял с первого раза. Посмотрел примеры — “а, ну да”. Но воспроизвести все 8 нормальных форм наизусть я даже после освежения их в памяти не смогу.

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

При всем этом я видел, как в проде не выполнялась даже 1НФ, причем это решение выглядело плюс-минус адекватным. И это даже если исключить денормализацию ради поиска.

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

Песочницы OAuth

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

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

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