dbit.one© 2026
000
booting_
Loading experience0%
dbit.one

Инженерные стандарты

Обновлено 2026-08-15

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

01

Решения

Большая часть провалов в разработке — это не плохой код, а уверенное решение, принятое без замера.

Сначала измеряем, потом чиним

Догадка о причине тормозов почти всегда неверна. Прежде чем оптимизировать, мы воспроизводим проблему и получаем число, а после правки — второе число.

Пример

Первый экран нашего сайта грузился 6,4 секунды. Очевидная причина — тяжёлый 3D-фон — оказалась второстепенной: виновата была заставка, которую сервер рисовал всем ещё до того, как узнавал, кто пришёл. Исправление дало 2,2 секунды. Разбор с методикой замера лежит в блоге.

Архитектура до кода

Решения о структуре, данных и границах системы принимаются до первой строки. Переписать документ дешевле, чем переписать сервис.

Сомневаешься — проверь на слабом железе

Разработка идёт на быстрых машинах, а пользуются продуктом на разных. Мы проверяем на медленном процессоре и на плохой сети, а не только у себя.

Пример

Жалобу «лагает на слабых ноутбуках» мы воспроизвели программным рендерером: кадр сцены занимал 175 мс против 17 мс без неё. После правки первый экран стал выдавать 104 кадра в секунду вместо пяти.

02

Код

Комментарий объясняет «почему», а не «что»

Что делает строка — видно из строки. В комментарии идёт причина: почему сделано так, что было испробовано до этого и что сломается, если переписать «очевидным» способом.

Пример

В нашем коде рядом с директивой nginx стоит объяснение, что `add_header` внутри location отменяет все заголовки, унаследованные с уровня server. Без этой строки следующий человек уберёт «дублирующиеся» заголовки и молча снимет защиту с картинок.

Зависимость должна окупаться

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

Пример

Инструмент для обработки изображений ставится на время пережатия и удаляется из зависимостей сразу после. Почтовая служба, которая принимает письма и отвечает на них, живёт на одной зависимости.

Код читают чаще, чем пишут

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

03

Проверки

Ошибку дешевле всего поймать до выкатки и дороже всего — от пользователя.

Каждый коммит проходит четыре проверки

Типы, линтер, сборка и контроль контента — до того, как изменение попадёт на сервер. Не прошло — не выкатывается.

На каждый пойманный баг — регрессия

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

Пример

После того как выяснилось, что без поддержки WebGL сайт падал в пустой экран целиком, появился скрипт, проверяющий три сценария отказа: обычный браузер, браузер без 3D-контекста и браузер с заблокированным WebGL.

Контент проверяется как код

Битая внутренняя ссылка, статья без адреса, повторяющийся якорь или слишком длинное описание для поиска роняют сборку так же, как ошибка типов.

Плавающий тест — это баг, а не погода

«Перезапустите ещё раз» — не ответ. Если тест падает раз в триста прогонов, у него есть причина: конкретный порядок выполнения, который в тот раз выбрала операционная система.

Пример

Мы написали для этого открытый инструмент — unflake. Он отбирает расписание у операционной системы: время, таймеры и порядок готовых колбэков берутся из сида, поэтому падение воспроизводится побайтово на любой машине, а найденный баг сжимается до минимального расписания. TypeScript, MIT, ноль зависимостей, опубликован в npm.

Зелёный прогон — не доказательство

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

Пример

Так держатся два наших открытых репозитория. В bulwark — реализации алгоритма консенсуса Raft — есть музей багов: семь экспонатов, каждый выключает ровно одно правило алгоритма, и харнесс обязан поймать его с сидом и именем нарушенного свойства. В adya — движке изоляции транзакций — каждый уровень проверяется в обе стороны: он не производит того, что обязан предотвращать, и производит то, что предотвращает следующий. Без второй половины первая пуста: движок, отклоняющий все транзакции, был бы «чист» на всех уровнях, а проверка, ничего не находящая, с ним бы согласилась. Дальше всех этот же приём доведён в pnueli: сломанное сокращение перебора отвечает ровно то же, что и рабочее — «нарушений не найдено», — поэтому рядом оставлен полный перебор, медленный и неспособный ошибиться, и вердикты обязаны совпадать.

04

Выкатка

Сборка не мешает работе

Новая версия собирается в отдельном каталоге и подменяет работающую двумя переименованиями. Пользователь не видит полусобранный сайт.

Пример

Раньше сборка шла поверх работающей версии, и все сорок секунд сайт отдавал ошибки. Теперь подмена занимает миллисекунды.

После выкатки — проверка отклика

Сборка может пройти, а приложение упасть на старте: битая переменная окружения, ошибка в серверном коде. Мы ждём ответа тридцать секунд.

Откат автоматический

Если новая версия не ответила, возвращается предыдущая — без участия человека и без звонка среди ночи.

05

История изменений

В журнале написано «почему», а не «что»

«Улучшена стабильность» — это не запись, а её отсутствие. Мы пишем, какая проблема была, чем она проявлялась и что изменилось; спорные решения объясняем отдельно.

Версия говорит о характере изменения

Исправление, новая возможность или несовместимое изменение различаются номером версии, а не настроением.

Отдельно — что сделано намеренно не так

В журнале есть раздел «не сделано намеренно»: он объясняет, почему очевидная на первый взгляд правка была бы ошибкой. Это экономит следующему человеку недели.

06

Передача

Код и доступы — ваши

Исходники, инфраструктура и документация передаются заказчику. Мы не оставляем себе ничего, без чего продукт перестанет работать.

Конфигурация сервера лежит в репозитории

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

Секреты не ходят в мессенджерах

Ключи и пароли передаются через хранилище или ваш контур, а на сервере лежат в файлах с закрытыми правами вне репозитория.

Чего мы не делаем

Правила без запретов ничего не значат: любой согласится с «пишем хороший код». Вот от чего мы отказываемся, даже когда так быстрее.

Не переписываем на новый фреймворк ради новизны

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

Не прячем плохие новости

О сорванном сроке и о найденной у себя ошибке сообщаем сразу. Разбор нашего собственного провала опубликован в блоге вместе с цифрами до и после.

Не берёмся, если не потянем

Отказ на созвоне дешевле для заказчика, чем срыв через три месяца. Иногда честный ответ — «эту систему выгоднее переписать, чем чинить».

Не оставляем «временных» решений без записи

Временное живёт дольше постоянного. Если сделано наспех — это записано в журнале с объяснением, что и когда должно быть переделано.

Проверить это можно на самом сайте

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