Обновить
512K+

Программирование *

Искусство создания компьютерных программ

984,28
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Ваш recover() эту ошибку не поймает

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели7.3K

В Go‑сервисе recover() может выглядеть надёжной страховкой, пока конкурентная запись в map не завершает процесс через fatal error: concurrent map writes. При этом часть гонок проходит незаметно и приводит к потере данных без единой ошибки в логах. В статье разбираемся, почему recover() не спасает в таких ситуациях, как обнаружить проблему с помощью -race и какой способ синхронизации выбрать для общей map.

Разобрать проблему

Новости

Внутри диаграммы Ганта: холст 480 на 360, палитра на 30 цветов и число без последнего бита

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели7.6K

Я собираю файл конфигурации из XML так, чтобы он совпал с платформенным с точностью до бита. Диаграммы Ганта в типовых конфигурациях пустые, и на них ушло шесть дней. Внутри нашлись обычная диаграмма, воображаемый холст 480 на 360, число, у которого платформа теряет последний бит, и палитра, где серия номер -1 получает 15-й цвет. Рассказываю, как это устроено и как добывалось: дизассемблер, Frida и серия загрузок платформой.

Читать далее

Два бага, 20 часов откатов: как я чинил гонки в M:N-рантайме Nova

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.2K

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

Три истории о гонках в M:N-рантайме языка Nova: что сломалось, как я это искал и что в итоге нашло баг. Объясняю простыми словами, знать устройство рантайма не нужно, а в конце — чек-лист для отладки гонок в многопоточном коде.

Читать далее

Подводные камни битовых полей в C++

Уровень сложностиСредний
Время на прочтение23 мин
Охват и читатели6.6K

Думаю, вы знаете, что C++ — язык, который разрешает вам вообще всё. А потом молча смотрит, как вы на этом подрываетесь. Обычно мы привыкли мыслить категориями байтов, но что делать, если стандартная сетка типов кажется слишком расточительной? Когда внутренний перфекционист требует компактности, на помощь приходят битовые поля. Зачем отдавать под скромный флаг “да/нет” целый восьмибитный контейнер, если можно ювелирно отрезать ровно один бит? Поставил двоеточие — и ты повелитель памяти. Но там, где начинается экономия, заканчивается порядок и предсказуемость. Программист остается один на один с тонкостями стандартов и поведением конкретных платформ. Предлагаю вместе заглянуть под капот C++ и подробно разобрать, как на самом деле устроены битовые поля.

Читать далее

Когда генератор нагрузки замирает вместе с сервером

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели4.8K

Если генератор и тестируемая система работают в одной JVM, пауза GC останавливает обоих. Сервер не отвечает, но и новые запросы никто не планирует. В итоге p99 выглядит лучше, чем его увидели бы реальные клиенты. Они-то сборку мусора не ждут.

В экспериментах SPECjbb2015 разница между режимами достигала 34 против 100 мс, а с Serial GC даже 278 против 1750 мс.

В статье разбираем coordinated omission и объясняем, почему для честного измерения задержек генератор нагрузки стоит вынести в отдельную JVM.

Читать далее

Пайпы OpenWebUI: зачем писать код там, где «всё уже есть в настройках»

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели5K

Настроить кастомную модель с инструментами и RAG в OpenWebUI — легко. Заставить её работать предсказуемо в бою — сложнее. Наш бот техподдержки на Gemma 4 сначала отвечал правдоподобно, но без данных из систем. Мы разобрались, почему это происходит, и превратили «одну модель в интерфейсе» в детерминированный конвейер с помощью пайпов.

Читать далее

Данные без противоречий: генерация через RegExp

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели4.1K

Идея не новая. Генерировать строки по регулярке умеют randexp в JavaScript, Xeger в Java, exrex и Hypothesis в Python. В TDCV2 я добавил это тоже, и первая половина статьи будет знакома тем, кто ими пользовался. Своё начинается дальше: уникальность, которая заранее знает, хватит ли места; точные доли прямо внутри выражения; условие, при котором одна часть строки следует из другой. Последние две вещи живут в расширенном генераторе advanced_regex, и в таком виде я их больше нигде не встречал.

И про слова. RegExp здесь - это синтаксис регулярных выражений, который TDCV2 использует как язык описания строки: конечное подмножество привычного синтаксиса плюс несколько своих конструкций. В конфиге генераторы называются regex и advanced_regex.

Читать далее

В логе было «не удалось получить данные:» и дальше пустота. Это и была вся ошибка

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели4.7K

В логе моего сборщика данных годами появлялась строка «не удалось получить данные:» и дальше ничего. Я считал это багом форматирования, пока не посмотрел: код написан правильно, просто у asyncio.TimeoutError пустой str(). Дальше выяснилось интереснее. Рядом лежит хелпер с тремя попытками и паузой в пять секунд, написанный ровно под сетевые сбои, а ловит он except aiohttp.ClientError. Начиная с Python 3.11 asyncio.TimeoutError это встроенный TimeoutError, наследник OSError, и к иерархии aiohttp он отношения не имеет. То есть единственная ошибка, ради которой ретраи существовали, пролетала мимо них. Причём у aiohttp есть и свои таймаутные исключения, которые как раз ClientError, и именно это сбивает с толку. Заодно разбираю, как я на основе этих пустых ошибок записал в заметки несуществующее «сетевое ограничение VPS» и построил вокруг него архитектурное решение.

Читать далее

52 бесплатных урока ноября: от разработки и архитектуры до GenAI и кибербезопасности

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели5.9K

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

В ноябре преподаватели OTUS разберут эти и другие вопросы на 52 бесплатных демо-уроках. В дайджесте — расписание занятий по восьми ИТ-направлениям: от программирования и архитектуры до машинного обучения, информационной безопасности и управления.

Перейти к расписанию ↓

Я не планировал становиться open-source разработчиком, а теперь развиваю проект с 1000+ звёзд на GitHub

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели10K

В начале 2026 года на новогодних праздниках у меня было много свободного времени, и я поставил Claude Code. До этого я уже писал код с ИИ в Cursor и Windsurf, но только на знакомых языках и смотрел весь написанный код. С CLI-агентами всё пошло иначе: я пробовал Claude Code, потом OpenCode и быстро захотел управлять агентом не только из-за компьютера, но и с телефона.

Так появился opencode-telegram-bot — Telegram-клиент для OpenCode. В момент написания этой статьи у него 1298 звезд на GitHub и 48 контрибьюторов. В статье расскажу, как инструмент для себя вырос в open-source-проект и что я понял, пока его развивал.

Читать далее

Staging-слой на EAV: случай, когда антипаттерн оправдан

Уровень сложностиПростой
Время на прочтение15 мин
Охват и читатели4.7K

В этой статье — про STAGING-слой нашего DWH и о том, как мы работаем с EAV-паттерном. EAV в реляционной базе — устоявшийся антипаттерн, который в большинстве задач стоит обходить стороной. Рассказываю не о том, хорош EAV в целом или плох, а о конкретном случае, когда он оказался оправдан: почему он к нам пришёл, как мы с ним живём, что он даёт и где реально мешает.

Читать далее

Как я один создал браузер для бухгалтеров: история BELPORTAL от снимков реестра до WebView2 и 56 млн скачиваний

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели4.5K

Когда-то работа бухгалтера с госпорталами была настоящим квестом: IE, ActiveX и километры инструкций. Я расскажу, как один создал BELPORTAL — программу, которую скачали 56 млн раз. Путь от снимков реестра Windows до полноценного браузера на WebView2, борьба с кризисом Avest и спасение отчетных периодов.

Читать далее

Маппинг данных: как объединить разные источники и не исказить результаты анализа

Время на прочтение11 мин
Охват и читатели3.8K

Про data mapping простыми словами: что такое маппинг данных, как выглядит процесс, какие инструменты используют и кто занимается маппингом. Примеры для аналитиков, инженеров и продактов.

Читать далее

Ближайшие события

Думал, дел на пару вечеров… Но демка на Vercel выросла в PWA с собственным CI/CD на Coolify

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели6.9K

Привет! На связи Никита Шелепин, менеджер поддержки в Selectel. Расскажу о том, как однажды подписался на легкое на первый взгляд задание, предвкушая потратить пару вечеров, а закончилось все собственным CI/CD, Docker’ом и PWA.

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

За моими плечами тогда было около года опыта — я писал инструменты администрирования на Vue с Bootstrap для одной компании в качестве подработки. Затем самостоятельно познакомился с SvelteKit — мне понравились его философия и модульность, а также то, что «из коробки» он дает удобный роутер и простые инструменты для создания fullstack-приложения.

С этим багажом знаний я и приступил к работе.

Читать далее →

Роботы-коммунисты: что бывает, когда у тысячи ИИ-агентов нет начальника

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели5.6K

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

Звучит как странный эксперимент или неудачный стартап. Но исследователи из Microsoft Research проделали это на ИИ-агентах. В препринте Agensh до 1024 экземпляров одной модели шесть часов вместе воспроизводили поведение готовых программ, и никто ими не руководил. При этом рой показал результат лучше одиночки. Заодно сам завел у себя ревьюеров, интеграторов и регламенты.

Давайте разберемся, как это устроено, что измеряли и где в цифрах прячутся оговорки.

Читать далее

Smart Plant OS: что обнаружилось между HTML-макетом и первой прошивкой

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели6.5K

В прошлой статье я рассказывал про идею открытой локальной системы ухода за растениями. На тот момент у проекта были документация, спецификации и большой HTML-макет. Можно было открыть страницу, посмотреть на растения, походить по настройкам и представить, как всё будет работать. Теперь этот интерфейс открывается с настоящей ESP32 в домашней сети. Между этими двумя состояниями пришлось решить несколько инженерных вопросов, которых на красивой странице не видно.

После публикации я услышал много критики, хороших идей и правильных вопросов. Особенно оживлённым получилось обсуждение избыточности и надёжности ESP32 на каждый горшок. Зачем столько вычислительных ресурсов для датчика и насоса? Почему не поставить один главный контроллер, а к нему подключить простые устройства по проводам? Что произойдёт, когда растений станет пятьдесят?

Читать далее

chunk(), lazy() и cursor() в Laravel: замеры памяти и почему chunk() теряет половину строк при обновлении

Время на прочтение8 мин
Охват и читатели7.1K

Когда в Laravel нужно обработать большую таблицу, обычно советуют «не делать all(), использовать chunk()». Совет верный, но неполный: у chunk() есть ловушка, из-за которой фоновая задача тихо обрабатывает только часть строк. Ниже замеры пяти способов обхода таблицы на 100 000 строк, разбор потери строк и правила выбора метода.

Читать далее

Один счётчик, десять потоков и неправильный результат: разбираемся в многопоточности C++

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели3.6K

Представим простую задачу: десять потоков должны увеличить общий счётчик по миллиону раз. Математика элементарная — в результате ожидаем десять миллионов.

Но программа может вывести совсем другое число. Причём ошибка не обязательно будет повторяться при каждом запуске.

Разберёмся, почему так происходит, как исправить проблему с помощью std::mutex и std::atomic, когда нужны std::condition_variable и std::future, а также чем std::jthread удобнее обычного std::thread.

Все примеры рассчитаны на C++20, если не указано иное.

Читать далее

Ревью кода стало узким местом: цифры Anthropic и мой опыт

Время на прочтение4 мин
Охват и читатели7.9K

Тут The Register пересказал инженерный блог Anthropic, что мае этого года компания мержила в основную ветку около 2500 изменений в день, к сентябрю уже больше 30 000. Рост более чем в 12 раз потянул за собой инфраструктуру. CI делает около 25 миллионов чекаутов в сутки, и под такую нагрузку компания строит собственную систему контроля версий. В блоге о новом хранилище кода инженеры пишут, что очень часто их роль сводилась к тому, чтобы сказать Claude «нет», потому что агенты иногда нарушают ключевые ограничения системы ради шаблона, который в этом месте не нужен.

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

Читать далее

Два git notes add параллельно: оба вернули 0, а одна заметка пропала

Время на прочтение5 мин
Охват и читатели7.4K

Две команды git notes add добавляют заметки к двум разным коммитам одновременно. Обе завершаются с кодом 0, но одна заметка исчезает: на обычной Linux-машине — в 25 запусках из 30. Фарид Закария нашёл эту гонку своей детерминированной виртуальной машиной Rewind VM и показывает, как тремя вопросами к записанным прогонам дойти от «тест иногда падает» до одной строки в notes-utils.c, которая обновляет ссылку refs/notes/commits без проверки, что её не успел изменить соседний процесс. Патч уже отправлен в рассылку git.

Читать далее