Onboarding, менторство, распространение знаний о кодовой базе
Ревью — единственный процесс в разработке, где обучение происходит побочным продуктом основной работы. Это делает его самым дешёвым каналом передачи знаний и самым легко ломающимся.
Вы научитесь превращать замечания в обучение, не удлиняя ревью; выстраивать онбординг так, чтобы новый человек становился самостоятельным за недели, а не месяцы; измерять фактор автобуса по данным репозитория; и распознавать момент, когда наставничество превращается в диктовку.
Замечание может передать знание или только правку. Разница в одном элементе — причине.
❌ «Добавь select_related»
Автор добавит. В следующий раз напишет так же, потому что
не знает, что именно он предотвращает.
✅ «`order.user` в цикле — это отдельный запрос на каждый заказ.
На странице из 50 заказов будет 51 запрос вместо двух.
Лечится `select_related("user")` — он подтянет пользователей
одним JOIN. Проверить можно `assertNumQueries` в тесте.»Второе длиннее на четыре строки и экономит десятки будущих замечаний. Это и есть вся арифметика обучения в ревью: одно объяснение против повторяющейся правки.
Признак того, что обучение не происходит: вы пишете одно и то же замечание одному и тому же человеку третий раз. Это не проблема автора — это значит, что первые два раза вы передали правку, а не понимание.
Обратная крайность тоже существует. Замечание-лекция на два абзаца к nit про имя переменной раздражает и тратит время. Объём объяснения соразмеряется с ценой ошибки: blocker объясняется подробно, nit — не объясняется вообще.
Проверьте себя. Найдите замечание, которое вы писали одному человеку несколько раз. Была ли в первом из них причина?
Частая ошибка. Давать готовый код в комментарии. Автор применит и ничему не научится — а вы напишете это же замечание снова.
Приём, который работает лучше остальных, и у него есть предел применимости.
Вместо: «Здесь нужен индекс»
Спросить: «Какой план будет у этого запроса на таблице
в миллион строк? Посмотри EXPLAIN.»Вопрос заставляет автора пройти путь самостоятельно, и найденное таким образом запоминается. Плюс иногда обнаруживается, что индекс уже есть или запрос выполняется раз в сутки.
Где приём перестаёт работать:
select_related».Проверьте себя. Переформулируйте своё следующее обучающее замечание как вопрос — и проверьте, знает ли автор, где искать ответ.
Частая ошибка. Задавать вопрос, ответ на который очевиден вам и недоступен автору. Это ощущается как экзамен.
Ревью — главный инструмент онбординга, и его настройка на первые недели отличается от обычной.
Первый PR должен быть крошечным. Опечатка в тексте, добавление лога, тест на существующую функцию. Цель — не польза, а прохождение всего пути: локальный запуск, коммит, PR, ревью, CI, мерж, деплой. Каждый шаг здесь может занять день, если что-то настроено не так, и лучше выяснить это на опечатке.
Каждая заминка нового человека — дефект документации. Не смог поднять проект локально — README неверен. Не понял, куда положить файл — структура не описана. Ценность нового сотрудника в первую неделю в том, что он видит эти дефекты; через месяц он к ним привыкнет и перестанет замечать. Поэтому первая задача часто формулируется как «поднять проект и исправить README там, где он врёт».
Постепенное снижение подробности. В первую неделю объясняется всё, включая то, что кажется очевидным. К концу первого месяца — только содержательное. Резкий переход воспринимается как потеря интереса, поэтому его стоит проговорить: «дальше буду писать короче, спрашивай, если что-то непонятно».
Явное разрешение на вопросы. Новый человек по умолчанию считает, что вопросами отвлекает. Это надо снять словами и, что важнее, реакцией на первый вопрос.
Обратный поток. Новичок обязан ревьюить чужой код с первой недели — даже если находит немного. Во-первых, так он читает кодовую базу. Во-вторых, «я не понимаю этот фрагмент» от нового человека — самое ценное замечание, какое может получить команда.
Проверьте себя. Сколько времени прошло от прихода последнего сотрудника до его первого смерженного PR? Сколько из этого — настройка окружения?
Частая ошибка. Дать новому человеку большую «настоящую» задачу, чтобы он сразу приносил пользу. Первые две недели уйдут на выяснение того, что выяснилось бы за час на маленькой задаче.
«Только Алексей разбирается в биллинге» — обычно правда, но никто не знает масштаба. Между тем это измеримо по данным репозитория.
Что считать: для каждого каталога — распределение авторов коммитов за год и распределение ревьюеров. Если 80 % изменений в модуле сделал один человек и ревьюил тоже преимущественно он, фактор автобуса равен единице.
Что с этим делать:
CODEOWNERS назначает компетентного, плюс один случайный из команды. Второй сначала не находит проблем — зато читает код и через квартал становится вторым компетентным.Важная деталь: узкое место обычно осознают, но не устраняют, потому что «сейчас некогда, потом». Единственный способ — сделать распространение знаний частью процесса, а не отдельной инициативой. Случайный второй ревьюер работает именно потому, что не требует ничьего решения каждый раз.
Проверьте себя. Посчитайте по git log долю коммитов одного автора в самом критичном модуле проекта.
Частая ошибка. Решать проблему документацией. Документация помогает разобраться тому, кто уже примерно понимает; она не заменяет опыт изменения кода.
Ценное объяснение, написанное в комментарии к PR, исчезает: через месяц его не найти, а следующий человек задаст тот же вопрос.
Что работает:
CONVENTIONS.md, меняется через PR. Правило, которого нет в репозитории, не существует.Практический признак: если вы написали в PR объяснение длиннее абзаца, спросите себя, где оно должно жить постоянно.
Проверьте себя. Вспомните хорошее объяснение, полученное в ревью полгода назад. Сможете сейчас его найти?
Частая ошибка. Заводить вики для знаний о коде. Вики не открывают при работе с кодом, поэтому она устаревает первой.
Разработчик с семилетним опытом пришёл в команду и стал самостоятельным только к четвёртому месяцу. На разборе восстановили хронологию по репозиторию.
Неделя 1 Выдана задача: «добавить экспорт отчётов в Excel»
(оценка тимлида — 3 дня)
Три дня ушло на локальный запуск: в README не хватало
шага с миграциями, о нём знали все, кроме него
Неделя 2 Первый PR: 400 строк. 34 комментария от четырёх ревьюеров,
часть противоречит друг другу
(«выноси в сервис» / «зачем сервис, это простая функция»)
Неделя 3 Переписал. 21 комментарий. Появился вопрос:
«а зачем вообще Excel, у нас же CSV?»
Выяснилось, что задача обсуждалась год назад
и была отложена
Неделя 4-6 PR висит. Автор берёт другую задачу, потом третью.
Ни одна не смержена
Неделя 7 Первый смерженный PR (правка текста в письме, 2 строки)
Месяц 2-3 Постепенно разбирается сам, читая код по вечерам.
Вопросы в чат почти не задаёт
Месяц 4 Работает нормальноЧто видит опытный участник. Ни один из участников не сделал ничего плохого. Результат — потерянные три месяца работы опытного специалиста и человек, который почти перестал задавать вопросы.
Разберём по шагам.
Первая задача — на 400 строк с неясной постановкой, выданная в первую неделю. Это ошибка выбора: первая задача должна быть тривиальной, потому что её цель — проверить путь, а не принести пользу. Три дня на локальный запуск при этом не потеряны, а полезны — они выявили дефект README, но никто его не исправил, и следующий человек потратит те же три дня.
Четыре ревьюера с противоречащими замечаниями. Это симптом отсутствия калибровки: у команды нет согласия, что считать нужным. Для опытного разработчика противоречащие требования — сигнал, что процесс сломан, и он начинает решать не задачу, а угадывать ожидания.
34 комментария на первом PR. Даже если все справедливы, такой объём читается как «всё сделано неправильно». Разумный подход к первым PR нового человека: два-три главных замечания, остальное — следующим разом.
Вопрос «зачем вообще Excel» на третьей неделе — провал постановки задачи, который стоил двух недель. Он должен был возникнуть при выдаче задачи, а не в ревью третьей версии.
Первый смерженный PR на седьмой неделе. До этого момента человек ни разу не прошёл полный путь до прода и не знает, работает ли его код вообще.
И самое дорогое: к третьему месяцу он перестал задавать вопросы и стал разбираться сам по вечерам. Это выглядит как самостоятельность, а на деле — потеря канала обучения. Спрашивать оказалось дороже, чем выяснять самому.
Что нужно было сделать:
День 1 Задача: поднять проект и исправить README везде, где он врёт.
Первый PR к концу дня, мерж в тот же день
Дни 2-3 Задача на 20-50 строк с ясной постановкой: тест на существующую
функцию или мелкое улучшение. Один ревьюер — наставник.
Мерж и деплой в течение дня
Неделя 1 Ревью чужого PR с явной установкой: «пиши, где непонятно,
это самое полезное, что ты можешь сейчас сделать»
Неделя 2 Первая содержательная задача, ≤ 200 строк, постановка проверена
до начала. Один ревьюер, максимум три замечания за раунд
Месяц 1 Постепенно снижаем подробность объяснений — проговорив это вслухЧем закончилось. Команда изменила онбординг: первая задача — всегда исправление README и документации по запуску, наставник назначается один и остаётся единственным ревьюером первые две недели, постановка любой задачи для нового человека проверяется до начала работы.
Следующий пришедший сделал первый мерж в первый день и работал самостоятельно через три недели. README к тому моменту был исправлен дважды подряд двумя новыми людьми — и после второго раза перестал врать.
git log для трёх критичных модулей.ПРИЧИНА обучающее замечание содержит следствие, а не только правку
СОРАЗМЕРНОСТЬ объём объяснения соответствует уровню замечания
ВОПРОС задаётся, когда автор знает, где искать ответ
ПЕРВЫЙ PR тривиальный, мержится в первый день
README исправляется руками нового человека, пока он видит дефекты
НАСТАВНИК один ревьюер в первые недели; замечаний не больше трёх за раунд
ОБРАТНО новичок ревьюит с первой недели; «не понимаю» приветствуется
ФАКТОР АВТОБУСА измерен по репозиторию; случайный второй ревьюер настроен
ЗНАНИЯ объяснения переезжают в код, договорённости — в репозиторий
ПОВТОР одно и то же замечание третий раз — повод для правила или разговораУсловия, при которых вопросы вообще задают, — Культура review. Как фиксировать решения, чтобы их не обсуждали заново, — Remote и асинхронность. Формулировки для обучающих замечаний — Soft skills.
Ключевая мысль: если вы пишете одно и то же замечание третий раз, обучение не произошло ни в первый, ни во второй. Передавали правку, а не понимание.
Далее: Разрешение конфликтов