Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Разрешение конфликтов
conflict_resolution

Разрешение конфликтов

Disagreement, escalation, RFC процесс, принятие решений

Разрешение конфликтов в Code Review

Конфликт в ревью почти никогда не про код. Он про то, что нет договорённости, кто принимает решение, — и оба участника считают, что это они.

#Результат урока

Вы научитесь различать три типа разногласий, каждый из которых решается по-своему; определять момент, когда переписку надо прекратить; и вводить в команде правило принятия решений, после которого спор становится процедурой, а не противостоянием.

#1. Три типа разногласий

Половина затяжных споров возникает потому, что участники решают разные типы вопроса, не заметив этого.

Разногласие о факте. «Этот запрос будет медленным» — утверждение, которое можно проверить. Решается измерением, а не аргументацией. Правильный ход: не спорить, а замерить.

Ревьюер: «Кеш здесь избыточен, БД справится» Автор: «Замерил на копии прода: без кеша 180 мс на p95, с кешем 12 мс. Требование — до 50 мс.»

Спор закончен. Данные снимают вопрос быстрее любых доводов, и первым делом стоит спросить: а это вообще проверяемое утверждение?

Разногласие о вкусе. «Мне не нравится такое именование», «я бы разбил на две функции». Проверить нельзя, потому что нет критерия. Правило: в вопросах вкуса решает автор. Ревьюер, продавливающий свои предпочтения, тратит время команды на переносимость собственных привычек.

Это правило работает только если оно объявлено заранее. Иначе каждый такой спор превращается в состязание упорства, и побеждает тот, кому важнее.

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

Проверьте себя. Возьмите последний затянувшийся спор в PR и определите его тип. Совпадает ли способ, которым его пытались решить, с типом?

Частая ошибка. Спорить фактами о вкусе и вкусом о фактах. Первое выглядит как придирка, второе — как упрямство.

#2. Признаки, что пора остановиться

Затяжной тред стоит дороже, чем кажется: он тратит время двоих, блокирует работу, читается всей командой и портит отношения тем сильнее, чем длиннее.

Останавливаться пора, когда:

  • Прошло три-четыре сообщения без сдвига позиций. Дальше каждый защищает не решение, а себя.
  • Появились обобщения. «Ты всегда так делаешь», «у нас в команде принято» без ссылки на договорённость.
  • Аргументы пошли по кругу. Одно и то же в разных формулировках.
  • Подключились наблюдатели с «+1». Спор перестал быть техническим и стал счётом голосов.
  • Разговор переехал на компетентность. «Это же базовая вещь» — точка, после которой обсуждать код уже невозможно.

Три способа выйти:

Разделить решения. Часто спорят о двух вещах сразу: «здесь баг» и «архитектура неудачная». Первое решается в этом PR, второе — тикетом. Смешение делает разговор безвыходным, потому что согласие по одному пункту воспринимается как проигрыш по другому.

Перейти в синхронный разговор. Пятнадцать минут голосом закрывают то, на что уходит два дня переписки, — в основном потому, что в разговоре быстро выясняется: один из двоих не знал важной детали. Результат обязательно фиксируется в PR.

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

Проверьте себя. Найдите в репозитории тред длиннее двадцати комментариев. На какой реплике надо было остановиться?

Частая ошибка. Продолжать, потому что «осталось немного, сейчас я его убежу».

#3. Кто принимает решение

Главная причина затяжных конфликтов — отсутствие ответа на этот вопрос. Пока его нет, каждый спор решается упорством.

Работающее распределение, которое стоит объявить в команде:

ВопросКто решает
Вкус, стиль, именованиеАвтор
Наличие бага, уязвимости, потери данныхРевьюер: это blocker, обсуждается только факт
Локальное архитектурное решение внутри модуляАвтор, с учётом возражений
Решение, влияющее на несколько модулейВладелец области или тимлид
Приоритет: выпустить сейчас или доделатьТот, кто отвечает за приоритеты, не участники спора
Общая договорённость командыКоманда, через изменение CONVENTIONS.md

Ключевая строка — вторая. Наличие бага не является предметом переговоров: спорить можно о том, есть он или нет (факт), но не о том, стоит ли его исправлять. Если это разделение не проведено, ревьюер вынужден каждый раз заново отстаивать право блокировать.

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

Проверьте себя. Знает ли ваша команда, кто решает при несогласии автора и ревьюера? Спросите двоих отдельно — ответы могут разойтись.

Частая ошибка. Считать, что решает тот, кто опытнее. Это работает, пока не столкнутся двое равных, — и тогда спор не имеет механизма завершения.

#4. Роль тимлида: когда вмешиваться

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

Вмешиваться нужно, когда: спор перешёл на личности; тред блокирует работу дольше суток; вопрос выходит за пределы компетенции участников; один из участников явно в невыгодном положении из-за разницы в статусе.

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

Как вмешиваться:

❌ «Делаем через сервис, я так решил» ✅ «Вижу, что не сходитесь. Резюмирую: @alice беспокоит тестируемость, @bob — что абстракция преждевременна. Оба аргумента верные. Решение: в этом PR оставляем как есть, потому что срок ближе, чем цена переделки. Тикет PROJ-1902 на выделение сервиса, когда появится второй потребитель. Записал в ADR-015.»

Три элемента, без которых вмешательство не работает: обе позиции названы и признаны, решение обосновано критерием, а не властью, решение зафиксировано письменно.

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

Проверьте себя. Тимлид: в последнем споре вы высказались первым или последним?

Частая ошибка. Решать спор в личных сообщениях. Остальные видели только конфликт и не увидели, как он был разрешён, — норма не изменилась.

#5. RFC для крупных решений

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

Отсюда правило: крупные решения обсуждаются до кода. Короткий документ — проблема, предлагаемое решение, отвергнутые альтернативы, компромиссы — стоит день работы и снимает недельный спор на этапе ревью.

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

Ключевая деталь: у RFC должен быть срок сбора возражений и явное завершение. «Комментарии до пятницы, потом принимаю» — иначе документ висит месяц, а работа стоит. И принятое решение переезжает в ADR, где остаётся навсегда.

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

Частая ошибка. Требовать RFC на всё. Порог должен быть высоким — иначе процесс станет способом замедлить любую инициативу.

#6. Предотвращение: что убирает большинство конфликтов

Конфликты в ревью распределены неравномерно: большинство приходится на несколько предсказуемых причин.

Отсутствие уровней у замечаний. Автор не знает, что блокирует. Введение blocker / major / minor / nit убирает целый класс споров, потому что nit перестаёт быть предметом торга.

Отсутствие калибровки. Разные ревьюеры требуют разного. Час раз в квартал — и противоречащие требования исчезают.

Договорённости в чате. Правило, которого нет в репозитории, каждый помнит по-своему. CONVENTIONS.md превращает спор о том, «как у нас принято», в ссылку на строку.

Большие PR. Чем больше дифф, тем больше поводов для замечаний и тем дороже любая переделка. Конфликты почти линейно связаны с размером.

Отсутствие явного «кто решает». Разобрано выше — самая частая структурная причина.

Все пять — процессные. Ни один не решается призывом быть вежливее, и это главный вывод темы.

Проверьте себя. Какая из пяти причин чаще всего срабатывает в вашей команде?

Частая ошибка. Считать частые конфликты следствием характеров. Обычно это следствие того, что процесс не отвечает на вопрос, кто прав.

#7. Разбор: спор, который стоил команде двух недель

Двое senior-разработчиков, PR на 200 строк, тред на 47 комментариев. Приводим ключевые реплики.

Автор (A): Добавил обработку вебхуков платёжного шлюза. Ревьюер (B): Почему обработка внутри HTTP-хендлера? Это должно быть в очереди — вебхуки надо принимать быстро и обрабатывать асинхронно. A: Обработка занимает 30 мс, очередь тут избыточна. Добавит сложности и точку отказа. B: Дело не в 30 мс, а в принципе. Шлюз ждёт 200 мс и ретраит. Если наша БД тормозит, мы начнём получать дубли. A: Идемпотентность есть, дубли обработаются корректно. B: Всё равно это неправильная архитектура. Мы так делаем во всех остальных интеграциях. A: В остальных обработка занимает секунды. Здесь другой случай. B: Консистентность важнее. Давай как везде. A: То есть добавим Celery, Redis и мониторинг очереди ради 30 мс? [обмен репликами продолжается 6 дней] B: Я не могу это одобрить. A: Хорошо, позову @lead. [тимлид в отпуске, ещё 4 дня] Тимлид: Делайте через очередь, у нас так везде.

Что произошло. Оба аргументировали разумно, никто не грубил, и результат — две недели и решение, принятое по признаку «как везде», а не по существу.

Разберём по типам разногласий. Первая реплика B — утверждение о факте: «если БД тормозит, будут дубли». Проверяемо. Ответ A — тоже о факте: «идемпотентность есть». Эти две реплики могли закрыть вопрос: достаточно было проверить, действительно ли идемпотентность покрывает случай медленного ответа.

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

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

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

Отсутствие резервного арбитра: тимлид в отпуске, и процесс остановился на четыре дня. Эскалация должна вести к роли, а не к человеку.

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

Как это должно было идти:

A: Добавил обработку вебхуков. Обработка 30 мс, поэтому синхронно; идемпотентность по event_id. Знаю, что в остальных интеграциях очередь — там обработка секундная, здесь случай другой. B: major: если БД замедлится, шлюз отретраит по таймауту. Идемпотентность покрывает дубли? Проверь случай, когда первый запрос ещё в транзакции, а второй уже пришёл. A: Проверил — не покрывала: уникальный индекс срабатывал, но ошибка возвращалась шлюзу как 500, и он ретраил снова. Поправил: на конфликт отвечаем 200. B: Хорошо. Остаётся вопрос единообразия — у нас правило про очередь для вебхуков не записано, но фактически так везде. Это не blocker для твоего PR. Давай вынесу в обсуждение команды: нужно ли правило и с каким порогом. Одобряю.

Полтора дня. Замечание о факте проверено и обнаружило настоящий баг — которого в реальном споре так и не нашли, потому что обсуждали принципы. Вопрос о единообразии отделён от PR и адресован туда, где решается, — команде.

Чем закончилось в реальности. Очередь добавили. Через месяц на разборе процесса восстановили хронологию и внесли изменения:

  • В CONVENTIONS.md записали правило: вебхуки с обработкой дольше 100 мс — через очередь, короче — синхронно с идемпотентностью. Спор больше не возникал.
  • Договорились: эскалация после третьего сообщения без сдвига, и эскалация ведёт к роли (дежурный senior), а не к конкретному человеку.
  • Добавили правило: возражение «так принято» без ссылки на записанную договорённость не является blocker.

Баг с ответом 500 на конфликт нашли позже, в проде, — он давал по три дубликата уведомления на каждый платёж.

#8. Внедрите у себя

  • Объявите, кто решает в каждом типе разногласий. Самое дешёвое изменение с самым большим эффектом.
  • Договоритесь об эскалации после третьего сообщения без сдвига позиций — и о том, что она ведёт к роли, а не к человеку.
  • Введите правило: «так принято» без ссылки на CONVENTIONS.md не блокирует. Это заставит записывать правила.
  • Проверьте, есть ли резервный арбитр, когда тимлид в отпуске.

#9. Чек-лист

ТИП определён: факт, вкус или ценности — и способ решения соответствует ФАКТЫ проверяются измерением, а не аргументацией ВКУС решает автор; это объявлено заранее РЕШЕНИЕ известно, кто принимает, для каждого типа вопроса ОСТАНОВКА эскалация после 3–4 сообщений без сдвига РАЗДЕЛЕНИЕ баг решается в PR, архитектура — тикетом ФИКСАЦИЯ итог созвона и решение арбитра записаны в PR или ADR АРБИТР эскалация ведёт к роли, есть резерв на время отпуска ПРАВИЛА «так принято» подкреплено записанной договорённостью ПОВТОР спор, случившийся дважды, превращается в общую договорённость ТИМЛИД вмешивается по признакам, высказывается последним, обосновывает критерием

#Что дальше

Условия, при которых спор не превращается в конфликт, — Культура review. Личные формулировки в споре — Soft skills. Где фиксировать решения — Remote и асинхронность.


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