Сохранёнки программиста
رفتن به کانال در Telegram
Заметки и ссылки на будущее, чтобы изучить когда будет время. Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Другие наши проекты: https://tprg.ru/med
نمایش بیشتر6 481
مشترکین
-624 ساعت
-237 روز
-4830 روز
آرشیو پست ها
Ускорение строковых агрегаций в DuckDB через таблицу измерений
SQL-гайд по замене повторяющихся строк числовыми ключами показывает, как сократить обработку текста при группировке. Таблица измерений хранит каждое название один раз вместе с ключом: запрос считает группы по числам и возвращает названия после агрегации.
Пример построен на 380 959 записях об остановках поездов и 537 названиях станций. Для них хватает двухбайтового USMALLINT. Ключи назначаются в алфавитном порядке, поэтому сортировка по ключу сохраняет порядок названий. LEFT JOIN сохраняет строки без станции, с NULL вместо ключа.
Для инженеров данных разобраны два варианта: сохранить ключи в основной таблице или соединять её со справочником при каждом запросе. Первый требует переписать таблицу один раз; второй оставляет обработку строк при каждом соединении.
#производительность #гайды
Детерминированные тесты TigerBeetle: проверки внутри реплик
Обстоятельный разбор тестирования распределённой базы с доступом к состоянию каждой реплики. Проверки через публичный API показывают поведение базы для клиента, но не охватывают все внутренние гарантии.
Симулятор запускает настоящий код базы, заменяет сеть и диски управляемыми моделями и ускоряет время. Он воспроизводит разрывы сети, повреждения дисков и падения реплик; найденный сбой можно повторить.
При фиксации каждой операции симулятор сверяет её контрольную сумму между репликами. Разбор также показывает, как проверки хранения связаны с требованием побайтового совпадения данных. В рабочей базе нарушение проверяемой гарантии останавливает реплику.
Для разработчиков распределённых систем это карта проверок за пределами API. Условие подхода: код базы должен выполняться детерминированно.
#разборы #архитектура
Автоматизация обслуживания ScyllaDB в Discord: устройство задач и сценариев
Инженерный разбор замены хрупких скриптов системой управления кластерами. Команда Discord обслуживает сотни узлов ScyllaDB и перед обновлениями создаёт временные копии кластеров, которые получают те же чтения и записи, что и рабочие базы.
В разборе Scylla Control Plane показаны задачи на Rust и сценарии в YAML. Перед выполнением задачи проверяются условия безопасности. Повторный запуск должен давать тот же результат, что и однократный: это требование делает повторы при сбоях безопасными. Ограничения параллелизма позволяют перезапускать узлы по одной зоне размещения, не более двух одновременно внутри неё.
Для инженеров инфраструктуры здесь есть ориентир: порядок шагов, проверки состояния и допустимый параллелизм задаются явно, а не остаются в голове оператора.
#архитектура #разборы
Как изолировать медленного WebSocket-клиента
При блокирующей отправке клиент, который не успевает читать события, задерживает общий цикл: остальные тоже ждут. Обстоятельный разбор обратного давления показывает, как локализовать перегрузку.
Каждому клиенту выделяют отдельную ограниченную очередь, а события кладут в неё без ожидания. Если очередь заполнена, новое событие отбрасывают только для этого клиента, учитывают потерю и переходят к следующему. В архитектуре NomadCrew буфер вмещает 256 событий.
Отбрасывание оставляет пробел в данных. Поэтому клиенту нужен путь повторной синхронизации: заново запросить текущее состояние. Так он восстановит актуальную картину, но не историю пропущенных событий.
Для WebSocket-хаба проверьте три вещи: очереди ограничены, пропуски видны в метриках, клиент может перечитать текущее состояние после отставания.
Как подготовить Rails-код к параллельной работе через Ractor
Глубокий разбор адаптации Rails-кода к Ractor. У каждого Ractor своя блокировка виртуальной машины, что позволяет исполнять Ruby-код параллельно. Цена этого: запрет делить изменяемые объекты между Ractor.
В карте такого рефакторинга разобраны четыре узла:
Глубокая заморозка объектов через
Ractor.make_shareable;
удаление мемоизации или перенос вычисления в initialize либо freeze;
Read-Copy-Update для настроек: скопировать значение, изменить, заморозить и заменить;
новый API для публичных изменяемых значений без поломки обратной совместимости.
Небольшие приложения команда уже запускает на Ractor, но крупные Rails-приложения с множеством гемов пока остаются целью. Читать Ruby-разработчикам, которые хотят начать аудит с изменяемых констант, ленивых вычислений и настраиваемых API.Почему BPF LPM trie замедляется с ростом таблицы префиксов
Обстоятельный разбор сбоя Cloudflare в продакшене начинается с блокировки процессора: освобождение BPF-карты с миллионами записей заняло более 10 секунд. Автор объясняет устройство trie, поиск самого длинного префикса и ограничения реализации в ядре Linux.
Узлы лишь с двумя потомками заставляют плотную карту проходить цепочку однобитовых сравнений; сжатия уровней нет. Разрозненные адреса узлов дают промахи кэша L1, а примерно с 80 000 записей узким местом становятся промахи dTLB при преобразовании адресов. При миллионе записей скорость поиска падает примерно до 1,5 млн операций в секунду.
Читать стоит разработчикам сетевых сервисов и тем, кто эксплуатирует BPF-карты. Прогоните поиск и освобождение карты на своей плотности ключей и объёме данных: распределение префиксов определяет эффективность сжатия путей.
Как Apache Hudi отсекает лишние партиции и файлы
Это первая часть обстоятельного разбора индексной подсистемы Hudi. Материал объясняет, как таблица метаданных ускоряет поиск записей и помогает не читать заведомо лишние данные.
Таблица метаданных сама устроена как Hudi Merge-on-Read и разделена по типам индексов. В HFile ключи отсортированы, а индекс блоков помогает найти нужный блок в памяти и прочитать его с диска.
По умолчанию работают индексы файлов, статистики столбцов и статистики партиций. Для условия
price >= 300 Hudi сначала отбрасывает партиции по максимумам цен, затем файлы по статистике отдельных столбцов.
Индексы обновляются в той же транзакции, что и данные, а уплотнение запускается после каждых 10 операций записи в таблицу метаданных. Инженерам данных стоит сверить набор индексируемых столбцов: без явной настройки Hudi берёт первые 32.Go расширил экспериментальный SIMD без ассемблерных вставок
В Go 1.27 разработчики представили пакет
simd/archsimd (включается флагом GOEXPERIMENT=simd): эксперимент для amd64 (AVX, AVX2, AVX-512) начался в 1.26, а в 1.27 добавили arm64 (NEON) и wasm (128-битный SIMD). Вместо си-интринсиков предложены методы вроде ShiftAllLeft, а выражение x.Add(y).Masked(m) на AVX-512 компилируется в одну инструкцию VPADD. Разницу платформ учли в именах: PermuteOrZero на amd64 обнуляет байт при отрицательном индексе, а LookupOrZero на arm64 и wasm обнуляет байт при любом индексе вне диапазона от 0 до 15.
Пример из статьи — разворот порядка бит в байтах через матричное умножение GFNI константой 0x8040201008040201: 64 байта обрабатываются за один шаг без таблиц поиска и сдвигов. Также авторы сформулировали три правила для надежности и скорости.
Инструкции требуют проверок фич CPU (archsimd.X86.AVX512() и других): иначе на неподдерживаемом процессоре программа упадет с SIGILL, а компилятор не сможет объединять операции. Границы стрид-цикла советуют писать как i < len(src)-v.Len()+1, чтобы оптимизатор убрал проверки среза. Наконец, векторы не стоит заворачивать в большие структуры или массивы: ABI Go пока выгружает крупные композитные типы из регистров в память.
@prog_stuffОтредактировал снимок билета без сброса криптографической даты
В стандарте C2PA подпись связывает провенанс с содержимым, а штамп времени фиксирует создание подписи. Но спецификация позволяет исключать произвольные диапазоны байтов из расчёта хеша привязки.
Дэвид Бьюкенен показал, как обойти защиту: он исключил из расчёта весь файл целиком. Хеш изображения превратился в хеш пустой строки, поэтому изменение пикселей не нарушало подпись с прежним штампом времени. Для демо автор снял лотерейный билет до тиража, а после публикации результатов вписал выигрышные числа.
Сервер времени работал штатно, подпись корректна, а выигрыш остался демонстрационным. В эксперименте автора проверка подписи проходит: валидаторы принимают манифест, дата предшествует тиражу, хотя изображение подписью не защищено. Инженерный урок: исключения из хеша должны строго ограничиваться стандартом и валидаторами, иначе заверяется пустота.
@prog_stuff
Как искать баги, которые не воспроизводятся в тестах
В обстоятельном разборе трёх расследований повреждение SQLite, потеря сообщений в TCP-сервисе и гонки в биллинге сводятся к одной методике: редкий сбой ищут телеметрией из рабочей среды, а не догадками.
Гонка между контрольной точкой SQLite и записью прожила минимум 16 лет. В TCP-сервисе четыре счётчика показали потерю: сервер разобрал 100 000 строк, но отправил 99 987 ответов, потому что принимал вызов
read() за готовое сообщение.
Ставьте счётчики на границах слоёв, меняйте по одной переменной и подтверждайте исправление положительным сигналом. Читать бэкенд-разработчикам и инженерам эксплуатации, которые расследуют редкие сбои в продакшене.Producer-Consumer в Java, Go и Rust: как выбрать уровень решения
Разбор трёх способов связать производителей и потребителей через ограниченный буфер. Выбор зависит от требований к задержке, а не от языка.
В Java блокирующая очередь останавливает производителя при заполненном буфере, в Go это делает буферизированный канал, в Rust кольцевой буфер с атомарными операциями позволяет убрать блокировки.
Сравнение трёх уровней решения пригодится разработчикам многопоточных систем. Начинайте со стандартной очереди, а атомарные алгоритмы выбирайте под измеренный предел задержки.
Как искать нарушения IEEE 754 в математических ядрах ИИ-ускорителей
Обстоятельный разбор аудита tt-metal показывает, почему случайные тесты не заменяют таблицу особых значений. Функция ttnn.atan2 для +∞ и +0 возвращала 0 вместо π/2: конечный диапазон тестов этот случай не создавал.
Карта расследования:
1. Заранее записать эталон для ±0, ±∞, NaN и значений у границ диапазона;
2. восстановить алгоритм ядра и вручную провести через него каждый случай;
3. заменить ошибочную проверку
min == 0 на max == 0 во всех трёх аппаратных копиях;
4. закрепить точные входы детерминированным тестом.
В полном разборе поиска и исправления ошибки ценен порядок работы: спецификация идёт раньше кода, а крайние значения становятся регрессионными тестами. Читать разработчикам вычислительных библиотек и ML-инфраструктуры, которые проверяют численную корректность ускорителей.Как ИИ меняет большие миграции: опыт Asana, Airbnb и Uber
В обстоятельном разборе крупных миграций важно сравнение процессов: срок одной компании нельзя переносить в свой план.
Asana начала перенос 4 000+ файлов с Enzyme на React Testing Library в 2024 году, обработала около 25%, а остаток завершила с ИИ за две недели и $12 000. Пять лет до этого были сроком низкоприоритетной миграции, а не непрерывной работы команды.
Сначала спроектируйте проверку результата, затем оценивайте, сколько типовых изменений можно поручить ИИ.
Как переводить целые книги с LLM и не терять контекст
Практический разбор Python-пайплайна для EPUB и PDF. Книгу делят по главам, затем на фрагменты по 2 000–4 000 токенов. В новый запрос обычно добавляют два последних абзаца только как контекст и словарь имён и терминов: так связность сохраняется без повторного перевода.
В разборе пайплайна есть код для подсчёта токенов и разбиения абзацев. Внутри главы запросы идут по очереди: следующий зависит от предыдущего. Параллельно обрабатывают разные книги. Для романа на 100 000 токенов авторы приводят ориентир: около 30 запросов и 4–6 минут.
Сохраните разбор, если работаете с длинными документами. Инженерный вывод: перекрытие фрагментов и отдельная память о терминах улучшают связность, но зависимые части придётся обрабатывать по очереди.
Почему 118 зелёных тестов не спасли MQTT-брокер на Rust
Обстоятельный инженерный разбор MQTT-брокера, написанного на Rust без сторонних пакетов. 118 автоматических тестов прошли, но mosquitto_pub в режиме доставки QoS 1 ждал подтверждения четыре секунды и завершался по тайм-ауту.
Тесты проверяли кодирование пакета подтверждения PUBACK, однако обработчик вообще его не отправлял. После разделения реестра тем на четыре сегмента вскрылся второй сбой: подписка sensors/+/temp и публикация sensors/kitchen/temp попадали в разные сегменты.
В разборе BlitzBroker есть и замер: около 495 тыс. сообщений в секунду против 402 тыс. у одного сегмента.
Читать разработчикам сетевых протоколов и интеграционных тестов. Проверяйте собранный бинарник независимым клиентом: подтверждения, подписки с подстановкой и переполнение очередей.
Как запускать асинхронное GRPO без общей машины
Обстоятельный разбор рабочей системы: тренер с LoRA и серверы генерации работают в отдельных Hugging Face Jobs, без общей машины и межузлового обмена через NCCL.
Тренер кладёт адаптер в объектное хранилище, которое каждый Job видит как файловую систему. Прокси добавляет авторизацию, выбирает реплику, где уже вычислено начало запроса, и сообщает всем репликам о новой версии.
Адаптер ранга 1 для модели на 1,5 млрд параметров занимает несколько мегабайт против примерно 3 ГБ у полной модели. При max_staleness=4 нужны шесть слотов LoRA, иначе vLLM может вытеснить версию с незавершёнными запросами.
Схема и пять последовательных прогонов показывают, где искать узкое место: 500 шагов удалось сократить с 3 часов 27 минут до 53 минут. Читать ML-инженерам, которые разносят обучение и генерацию по отдельным машинам.
Как исследовать легаси-код с ИИ до первого рефакторинга
Гайд по «археологии» незнакомой системы: странное условие или повторный расчёт могут хранить бизнес-исключение либо внешний контракт. ИИ здесь нужен для поиска вопросов, а не мгновенной переписи кода.
Начните с карты репозитория и точек входа: HTTP-запросов, фоновых задач, скриптов, импортов и вебхуков. Каждый вывод модели должен ссылаться на конкретные файлы, а сомнения нужно отмечать явно.
Готовые запросы к ИИ и маршрут анализа пригодятся при миграции или работе со старым проектом. До рефакторинга составьте проверяемую карту системы и список открытых вопросов.
Как устроена криптография Ethereum-кошелька на Go
Статья о цепочке «создать ключ, получить адрес, подписать транзакцию»: автор собирает учебный CLI-кошелёк на Go и показывает детали, от которых зависят совместимость и безопасность.
В практическом разборе разбираются BIP39, путь BIP44 и соглашения для поля
v, защищающего транзакции от повторного воспроизведения.
Тест «зашифровали и расшифровали» не нашёл ошибку в параметрах scrypt: обе операции повторяли её. Нужен эталонный набор данных.
CLI создан для обучения, не для реальных средств. Читайте, если хотите проверить реализацию Ethereum-стандартов в Go.Как вынести тени в отдельные проходы Custom SRP в Unity
Обстоятельное продолжение серии о собственном конвейере рендеринга на Unity 6000.5.8f1. Рефакторинг ведут поэтапно: после каждого раздела тени остаются рабочими, поэтому материал читается как карта безопасного изменения архитектуры.
Сначала объект Shadows уходит из LightingPass под управление CameraRenderer. Затем LightingPass получает структуру Handles и возвращает только буферы освещения. После появляется отдельный ShadowsPass: он строит списки отрисовки, запускает рендеринг теней и отдаёт их дескрипторы.
Дальше код из Shadows переносят в новый проход, чтобы затем разделить обработку направленных и остальных источников света.
Разбор с правками кода полезен тем, кто уже строит Custom SRP. Ориентир для рефакторинга: разделяйте владение состоянием и запись проходов небольшими шагами, проверяя тени после каждого.
Как настроить распределённую трассировку Java-микросервисов с OpenTelemetry
Обстоятельный разбор OpenTelemetry показывает, как связать путь запроса через Java-микросервисы и найти сервис, запрос к базе или внешний вызов, который добавляет задержку.
Карта материала:
1. почему разрозненные логи и метрики не восстанавливают путь запроса;
2. как SDK собирает трассы, метрики и логи, а процессоры фильтруют и группируют их;
3. как подключить Maven, экспорт по OTLP, Jaeger и собственные участки трассы.
Примеры рассчитаны на Spring Boot 3.x и OpenTelemetry 1.35.0: стартер автоматически охватывает HTTP, JDBC, JPA, Kafka и RabbitMQ. Локальный Jaeger запускается через Docker Compose; бизнес-операции можно размечать собственными участками трассы.
Подойдёт Java-бэкендерам и SRE: на тестовом стенде проверьте сквозной идентификатор trace_id, а перед рабочей средой пересмотрите выборку в 100%.
