Знаешь, когда я работал в стартапе, у нас была такая ситуация: разработчик пушит код, три дня его никто не смотрит, потом приходят комментарии "переделай", и вот уже неделя прошла впустую. А все потому, что code review был на словах. Люди были заняты, было лень открывать PR, и в результате процесс просто развалился.
Потом мы всё переорганизовали, и код стал качественнее, а время на ревью сократилось в два раза. Вот про это и расскажу — не про теорию, а про то, как на самом деле сделать source code review, который работает.
Что такое code review и почему он не роскошь
Начнём с простого. Source code review — это просмотр и анализ кода перед тем, как он попадёт в основную ветку. Другой разработчик (или несколько) смотрит на то, что ты написал, ищет ошибки, проверяет логику, следит за стилем кода.
Звучит как лишняя работа? На самом деле — это наоборот экономия. Потому что:
Баги ловятся раньше, чем в production. На одном проекте мы поймали потенциальный race condition в ревью, которая в боевых условиях вызвала бы утечку памяти. Спасибо, что заметили до деплоя.
Новички быстрее учатся. Если грамотно делать code review, то по комментариям они сразу видят, как пишут опытные разработчики. Лучше, чем любой онбординг.
Снижается техдолг. Когда каждый коммит проходит через ревью, никто не напишет "потом переделаю" — потом никогда не наступает. Стандарты держатся.
Распределённое знание. Если только один человек знает, как работает модуль авторизации, и он уходит из команды — это проблема. При code review знание разделено.
Но вот что важно: code review работает только если его правильно организовать. Иначе это просто театр.
Как организовать процесс code review
Тут нет универсального рецепта, но есть базовые принципы, которые работают для 90% команд.
Во-первых, нужен хозяин процесса. Не обязательно отдельный человек, но кто-то должен следить, чтобы PR не висели неделю, чтобы были чёткие правила, чтобы люди не забывали ревьюить. По моему опыту, это обычно техлид или старший разработчик. У нас в Яндексе это была ответственность, закреплённая в job description.
Во-вторых, нужны правила и стандарты. Они должны быть написаны. Вот пример того, что может быть в вашем гайде:
- Минимум один ревью перед мёржем (в критичных местах — два)
- Код должен пройти автоматические проверки (линтер, типизация)
- Если меняется API — нужно обновить документацию
- Большие PR (больше 500 строк) разбивать на части
- Коммиты должны быть логичными, не "fix", "again", "oops"
Просто повесьте это в README вашего репо. Серьёзно.
В-третьих, установите SLA на ревью. Если PR висит неделю, это паралич. Я рекомендую: обычный PR должен быть заревьюирован в течение 24 часов, критичный — максимум 4 часов. Если никто не успевает, значит проблема в процессе или в нагрузке на команду.
В-четвёртых, создайте культуру, где ревью — это помощь, а не нападение. Сложная штука. Если разработчик боится, что его код будут критиковать, он либо напишет быстро и небрежно, либо вообще не будет пушить. Нужно научить людей:
- Принимать критику без обид
- Писать комментарии вежливо и конструктивно
- Объяснять свои решения, а не просто отклонять PR
Я видел команды, где после каждого ревью люди спорили в Slack и заканчивалось стеклом в стену. Это не code review, это токсичность. Нужно работать с культурой.
Как правильно делать комментарии в code review
Вот здесь много людей ошибаются. Комментарий должен быть полезным, а не просто критичным.
Плохой комментарий:
// Это неправильно
Хороший комментарий:
// Здесь может быть race condition, если несколько потоков одновременно обратятся к user_cache.
// Предлагаю добавить Lock или использовать thread-safe структуру.
// Вот пример: https://github.com/.../blob/.../cache.py#L45
Видишь разницу? В хорошем комментарии:
- Объяснено, в чём проблема
- Предложено решение
- Может быть ссылка на пример
Ещё несколько правил:
Различай blocking и non-blocking замечания. Blocking — это когда код точно нельзя мёржить ("тут уязвимость", "переменная никогда не инициализируется"). Non-blocking — это когда это больше совет ("здесь можно использовать более читаемый синтаксис", "название функции может быть понятнее"). Четко обозначай это в комментарии, иначе автор не поймёт, что менять обязательно.
Не переделывай чужой код в ревью. Если решение работает и соответствует стандартам, но ты бы написал иначе — это твоё мнение, а не факт. Пожалуйста, не требуй переписать весь алгоритм только потому, что он не совпадает с твоим стилем.
Хвали хорошие решения. Серьёзно. "Хороший паттерн с dependency injection" занимает 5 секунд, а мотивирует человека на целый день.
Типичные ошибки в организации code review
Я видел очень много команд, которые делают это неправильно. Вот самые частые грабли:
Ревью становится боттлнеком. Один человек ревьюит весь код, а его 5 PR в день. Результат: PR висят неделю, люди начинают мёржить без ревью, процесс разваливается. Решение: распредели ответственность между несколькими людьми, ротируй ревьюеров.
Ревью становятся личными. "Твой код всегда плохо пишется" — и вот уже конфликт. Нужно критиковать код, а не человека. Всегда. Я видел, как после одного едкого комментария разработчик ушёл из компании.
Нет стандартов, что проверять. Один ревьюер смотрит на архитектуру, другой на пробелы, третий на названия переменных. Результат: хаос. Нужна чеклист.
Игнорируют автоматизацию. Люди вручную проверяют, что код соответствует PEP8, что нет неиспользуемых импортов, что тесты проходят. А можно просто поставить линтер и забыть. Человеческое внимание нужно для логики и архитектуры, а не для пробелов.
PR слишком большие. Если в PR 2000 строк, никто не будет ревьюить внимательно. Люди скроллят, скроллят и в конце концов кликают "approve". Нужно требовать разбивать большие изменения на части.
Чеклист для code review
Вот что я рекомендую проверять. Можешь скопировать и адаптировать под свой проект:
Функциональность
- Код делает то, что обещает в описании PR
- Нет очевидных багов (null-pointer exceptions, off-by-one ошибки и т.д.)
- Обработаны edge cases (пустой список, null, отрицательные числа)
- Код работает с текущей версией зависимостей
Качество и читаемость
- Переменные и функции названы понятно
- Функции не слишком большие (не больше 50-100 строк в зависимости от языка)
- Нет дублирования кода
- Логика легко понять без комментариев (если нужны комментарии — переделай код)
Тесты
- Новый код покрыт тестами (минимум 80%)
- Тесты проверяют не только happy path, но и ошибки
- Тесты читаемы и не дублируются
Производительность и безопасность
- Нет N+1 запросов в базу
- Нет утечек памяти (например, циклических ссылок)
- Входные данные валидируются и санитизируются
- Нет хардкода паролей, токенов, API ключей
Документация и стиль
- Изменена документация, если нужно
- Код следует стайлгайду проекта
- Коммиты логичные с хорошими сообщениями
Не нужно проверять всё это вручную. Половину может делать автомат.
Как автоматизировать code review
Вот честно? Большинство команд тратят время на то, что может делать бот. Лучше использовать это время на настоящий review.
Линтеры и форматеры. ESLint для JavaScript, Pylint для Python, golangci-lint для Go. Они ловят синтаксические ошибки, неиспользуемые переменные, нарушения стиля. Ставишь в CI и всё.
# Пример для GitHub Actions
name: Lint
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- run: pip install pylint
- run: pylint src/
Type checking. Если пишешь на Python — mypy, если на TypeScript — встроенный checker. Много ошибок ловится просто по типам.
Тесты и code coverage. Обязательно в CI. Если PR снижает покрытие — не мёржить.
Security scanning. Bandit для Python, npm audit для JavaScript. Ищут известные уязвимости и опасные паттерны.
AI code review. Вот здесь интересно. Есть сервисы, которые анализируют код и оставляют комментарии в PR. Они ловят логические ошибки, проблемы с производительностью, нарушения best practices. На одном проекте мы внедрили Distiq — российский AI code review для GitLab и GitHub. Бот смотрит на каждый PR, находит потенциальные баги, проблемы с безопасностью, нарушения стиля, и оставляет инлайн-комментарии. Это экономит часы на manual review.
Всё это в совокупности означает, что когда человек садится ревьюить PR, он не тратит время на поиск опечаток, а смотрит на логику, архитектуру, то, как это вписывается в систему.
Как внедрить code review, если его нет
Если в команде до сих пор никто не ревьюит код, не начинай со строгих правил. Это не сработает.
Шаг 1: Объясни зачем. Собери команду, расскажи про баги, которые ловятся в ревью, про распределённое знание. Не как начальник, а как коллега. "Ребята, я вижу, что мы теряем баги, которые можно было бы поймать раньше. Давайте попробуем ревью?"
Шаг 2: Начни с себя. Не требуй от других ревьювить твой код, если сам не ревьюишь. Первый месяц просто смотри код коллег, оставляй конструктивные комментарии. Люди увидят, что это не нападение, а помощь.
Шаг 3: Установи инструменты. Линтеры, CI, автоматизация. Чтобы код review был не про пробелы, а про смысл.
Шаг 4: Документируй стандарты. Напиши, что вы проверяете, какие замечания blocking, какие нет.
Шаг 5: Отслеживай метрики. Сколько PR в очереди, как долго они висят, сколько замечаний в среднем. Если что-то идёт не так, адаптируй процесс.
Не ожидай, что за неделю всё наладится. Обычно нужен месяц, чтобы привыкнуть.
Code review в больших командах
Если у тебя 50 разработчиков, то просто "давайте все ревьювить" не сработает. Нужна структура.
Ревьюеры по модулям. Каждый модуль (auth, payment, api) имеет одного-двух владельцев, которые ревьювят PR в эту часть. Это не значит, что другие не могут смотреть код, но ответственность чёткая.
Ротация. Если всегда один и тот же человек ревьюит, он выгорает и становится боттлнеком. Ротируй. "На этой неделе Маша ревьюит PR в backend, Иван в frontend, Петя в DevOps".
Автоматизация по максимуму. В больших командах без
