awesome-everything EN
↑ Обратно к восхождению

Инженерная практика

Code review: что ловит человек, что должна тулза, и почему латентность — настоящая цена

Суть Ревью существует, чтобы ловить дизайн и замысел, не стиль — стиль автоматизируй. Главная цена — латентность: PR, ждущий день, блокирует автора. А детект дефектов рушится за парой сотен строк, так что большие диффы штампуют не глядя.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 16 min

PR на 1800 строк падает в пятницу в 17:00: новый биллинг-флоу, миграция схемы и рефакторинг — всё одним диффом. Два ревьюера оставляют четыре комментария — переименование, пропущенная точка с запятой, «нит: лучше const» — и аппрувят. Три недели спустя миграция дважды списывает деньги с когорты клиентов, потому что путь ретрая не был идемпотентным. Никто не увидел. Дифф был слишком велик, чтобы его реально прочесть, так что ревьюеры отревьюили то, что легко увидеть: мелочь. Настоящий изъян сидел в дизайне, а дизайн — ровно то, что гигантский LGTM-нутый PR и прячет.

Ревью ловит то, чего не может тулза

Дефицитное внимание сеньора-ревьюера должно идти на то, что машина судить не может: правильный ли это дизайн, делает ли он то, что задумывал тикет, поймёт ли это следующий инженер, корректен ли путь ошибки, не открывает ли он дыру в безопасности. Собственный стандарт Google ставит дизайн первым — «самое важное, что нужно покрыть в ревью», — потому что дизайн-решения накапливаются и дорого откатываются позже, тогда как неуместная скобка не стоит ничего.

Всё, что тулза может решить детерминированно, не должно никогда доходить до человека. Форматирование, порядок импортов, конвенции именования, lint-правила, неиспользуемые переменные — гоняй форматтер и линтер в CI и сделай их блокирующими. В тот момент, когда человек печатает «нит: пробелы», ты потратил самый дорогой ресурс ревью (суждение сеньора) на самую дешёвую возможную проблему, и научил автора, что ревью — про поверхность. Инженерная культура Google проговаривает это явно: автоматизируй принуждение стиля, чтобы стиль не доходил до ревью, потом тренируй ревьюеров тратить внимание на корректность, безопасность и архитектуру.

ЗаботаКто должен пойматьПочему
Форматирование, порядок импортов, пробелыФорматтер (CI)Детерминированно; ноль суждения; не должно доходить до человека
Неиспользуемые переменные, очевидные баги, lint-правилаЛинтер / статанализ (CI)Проверяемо машиной; блокирующий гейт до старта ревью
Правильный ли это дизайн?Человек-ревьюерНужен контекст, замысел, знание системы — ни одна тулза не рассудит
Совпадает ли с замыслом тикета?Человек-ревьюерКорректный код, решающий не ту задачу, всё равно шипит баг
Поддерживаемость, именование-ради-смыслаЧеловек-ревьюер«Поймёт ли это следующий разработчик?» — вопрос суждения

Латентность — цена, которую никто не меряет

Число, что значит больше всего, — не количество дефектов, а время оборота. PR — это заблокированная работа: автор не может смержить, часто не может чисто начать следующее, и каждый час простоя — это час чьего-то замороженного прогресса. Данные суровы. Анализ примерно 8 миллионов pull request’ов нашёл, что элитные команды закрывают полный цикл ревью меньше чем за 26 часов, тогда как отстающие дают PR простоять неделю до того, как ревью вообще начнётся. Самый большой кусок этого времени — не ревью, а первичный подхват, разрыв до того, как кто-то взглянет. Распределённые команды платят ещё 8–16 часов за раунд просто на разрыв часовых поясов.

У этого простоя есть цена. Тот же анализ оценил стоимость ожидания на бутылочном горлышке ревью примерно в 5,8 часа на разработчика в неделю — около $238K/год замороженного времени для команды из десяти человек, и это только ожидание, не само ревью. Вот почему DORA трактует lead time как ключевую метрику здоровья: медленное ревью напрямую деградирует пропускную способность, и команда, оптимизирующая чисто «тщательное ревью» и игнорящая латентность, меняет малый выигрыш по дефектам на большой проигрыш по потоку.

Почему это работает

Самый быстрый фикс латентности ревью почти никогда не «ревьюить быстрее» — это «делать PR меньше». PR на 50 строк подхватывают за минуты, потому что в него дёшево переключиться; PR на 1500 строк простаивает, потому что ни у кого нет свободного часа. Маленькие PR бьют по обеим проблемам разом: быстрее подхват и выше детект дефектов. Латентность и качество обычно — один рычаг, а не трейдофф.

Экономика маленьких PR: детект дефектов падает с обрыва

Исследование SmartBear в Cisco — 2500 ревью на 3,2 миллиона строк кода, крупнейшее в своём роде — нашло, что сладкая точка — 200–400 строк кода на ревью. Внутри этой полосы, при ревью, растянутом не больше чем на 60–90 минут, ты получаешь около 70%+ выхода дефектов. Перевали за 400 строк, и детект резко падает; человек перестаёт читать и начинает скользить. Темп тоже важен: ревьюеры, идущие медленнее ~400 LOC/час, были выше среднего в нахождении дефектов, но за ~500 LOC/час плотность дефектов оказалась ниже среднего в 87% случаев.

Это механизм за штампом не глядя. Ревьюер перед диффом на 1800 строк не имеет бюджета удержать всё это в голове, так что делает единственное, что влезает: комментит локально видимое (имя, нит по стилю) и аппрувит. Гигантский PR не получает больше придирчивости за то, что большой — он получает меньше, потому что внимание не масштабируется с размером, а когнитивный предел ревьюера фиксирован. Большие диффы — это где прячутся реальные изъяны дизайна ровно потому, что это диффы, которые никто не может прочесть целиком.

Размер PRЧто реально происходитДетект дефектов
LOC < 200Читается целиком, быстрый подхват, реальное обсуждение дизайнаВысокий
200–400 LOCСладкая точка: 60–90 мин, полное внимание70–90% выхода
400–800 LOCВнимание истончается; начинается скольжениеПадает
LOC > 800Штамп: ниты + LGTM, дизайн не прочитанРушится

Трейдофф сеньора: тщательность против пропускной, обмен знанием против привратничества

Каждое ревью — ставка на то, куда потратить фиксированный бюджет. Выкрути тщательность на максимум — и затормозишь поток всей команды; оптимизируй чисто под пропускную — и дефекты протекут. Ход сеньора — тратить глубину там, где риск: дизайн, миграция данных, граница auth, путь денег, — и пропускать низкорисковые диффы быстро. Стандарт Google кодифицирует это нарочито гуманным правилом: аппрувь, как только изменение определённо улучшает общее здоровье кода, даже если оно не идеально. «Не идеально» — не повод блокировать; «делает кодбазу хуже» — повод.

Вторая ось культурная: ревью как обмен знанием против ревью как привратничества. Сделанное хорошо, ревью распространяет контекст — автор узнаёт систему, ревьюер узнаёт изменение, и bus factor растёт. Сделанное как статусная игра, оно становится бикешеддингом (закон тривиальности Паркинсона: люди бесконечно спорят о цвете велосарая, потому что это единственная часть, которую они понимают) и привратничеством, где ревьюер блокирует, чтобы утвердить контроль, а не улучшить код. Признак — тред из двенадцати комментариев об именовании на PR, чей настоящий изъян дизайна уехал нетронутым. Ревью, придирающееся к мелочи и пропускающее порочный дизайн, вывернуло наизнанку всю свою цель.

Выбери лучший вариант

Коллега открывает PR на 1400 строк, сбивший в кучу фичу, рефакторинг и миграцию. Он блокирует его следующую задачу уже два дня. Как ревьюер, каков ход сеньора?

Викторина

Ревьюер оставляет шесть комментариев о порядке импортов и пробелах в переменных, потом аппрувит. В чём корневая проблема?

Викторина

По исследованию SmartBear/Cisco, что происходит с детектом дефектов, когда одно ревью растёт за ~400 LOC?

Расставь шаги по порядку

Расставь здоровый пайплайн ревью так, чтобы внимание человека падало туда, где оно ценнее всего:

  1. 1 Форматтер + линтер гоняются в CI и блокируют — стиль/формат не доходит до человека
  2. 2 Держи PR маленьким (цель ~200–400 LOC), чтобы читался за один присест
  3. 3 Подхватывай быстро — первичная латентность — крупнейшая часть оборота
  4. 4 Трать глубину ревьюера на рискованнейшие части: дизайн, миграция, auth, путь денег
  5. 5 Аппрувь, как только определённо улучшает здоровье кода — «не идеально» не блок
Вспомните перед уходом
  1. 01
    Коллега говорит: «тщательное ревью значит ловить всё, так что большие ревью должны ловить больше багов». Объясни, почему данные говорят обратное.
  2. 02
    Почему латентность ревью, не число дефектов, часто метрика, за которой сеньор следит первой — и каков самый дешёвый способ её улучшить?
Итог

Code review окупается на том, что тулза судить не может — дизайн, замысел, поддерживаемость, корректные пути ошибки и денег, — так что выталкивай всё детерминированное (формат, lint, стиль) в блокирующий CI-гейт и никогда не трать на него человека. Цена, которую никто не меряет, — латентность: PR в ревью это заблокированная работа, элитные команды закрывают цикл меньше чем за 26 часов, тогда как отстающие дают ему простоять неделю, и одно ожидание сжигает ~5,8 часа на разработчика в неделю. Детект дефектов пикует на 200–400 LOC и рушится за ~400, и поэтому гигантские PR получают штамп ниты-и-LGTM, пока их настоящие изъяны дизайна уезжают нетронутыми. Баланс сеньора — тратить глубину там, где живёт риск, аппрувить, как только изменение определённо улучшает здоровье кода, а не гнаться за идеалом, и трактовать ревью как обмен знанием, а не статусную игру привратника. Меньшие PR — единственный ход, что улучшает качество и поток одновременно.

Связанные уроки
Продолжить восхождение ↑Размер PR задаёт латентность ревью и детект разом
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.