Олег Сафонов — Decode review: как ревью кода помогает улучшать процессы

Информация о загрузке и деталях видео Олег Сафонов — Decode review: как ревью кода помогает улучшать процессы
Автор:
DotNext — конференция для .NET‑разработчиковДата публикации:
28.06.2024Просмотров:
1.4KОписание:
Транскрибация видео
И еще раз здравствуйте, коллеги.
Напоминаю, что тема этого трека «Расширяем горизонты».
Мы сегодня с вами узнали очень много новых подходов, изучили, как расширять возможности приложения, ограничивать возможности приложения, пользоваться новой периферией и компьютерами.
А теперь давайте послушаем Олега.
Он нам поможет не запутаться во всем том, что мы узнали, и свободно распределять знания по команде и обмениваться ими, чтобы у нас не было одного хранителя, а команда отвечала за это.
Спасибо, Олег, тебе слово.
Большое спасибо.
Всех приветствую.
Меня зовут Олег.
Собственно, я люблю код-ревью, и я сегодня хотел бы поговорить про него, потому что я его люблю.
И доклад мой называется Decode Review.
Я очень долго думал, как его назвать на самом деле.
И суть в том, что мы сейчас постараемся немножко расшифровать, а что вообще скрывается на самом деле за ревью, что там за ним находится.
Представлюсь еще раз.
Меня зовут Олег.
Я работаю ведущим разработчиком в компании Тинькофф.
У меня примерно 12 лет практического опыта.
Это не весь .NET, но...
Большая часть.
И у меня есть профильное образование по разработке ПО, что, надеюсь, тоже поможет мне немножко сделать мой доклад более интересным.
План сегодняшнего доклада следующий.
Вначале будет небольшая вводная.
Ну, как бы мы немножко синконимся с вами, чтобы мы все на одной волне были.
Потом я расскажу историю, которая вообще сподвигла меня к сегодняшнему докладу.
Расскажу, почему я люблю код-ревью.
Я на самом деле признаюсь, да, это клуб анонимных разработчиков.
Я прихожу и говорю, я люблю код-ревью, и все говорят, ну и ублюдок же ты.
Потом я расскажу про проблемы код-ревью.
Не, ну, без шуток сейчас, ладно, с шутками тоже будет.
Расскажу про проблемы код-ревью, которые бывают, да, и как бы, вот, что они под собой скрывают, то есть, наверное, основная часть доклада будет.
Расскажу, как правильно готовить код-ревью, и расскажу, подведем выводы небольшие.
Собственно, ну, вводная часть, давайте немножко синканемся, чтобы мы были на одной волне, да.
То есть, определимся с вами, что код-ревью — это процесс согласования кода, да, не будем там углубляться в инструменты там, то есть, вот есть человек, который принес,
Что-то, да, код, и говорит, посмотрите.
И есть человек, который сказал ок или не ок, и почему не ок.
И, соответственно, в зависимости от выхлопа второго человека, первый либо переделывает, либо нет.
Такое определение сейчас возьмем за основу.
И что я хочу рассказать вообще, изначально, зачем я к вам пришел.
На самом деле я считаю, что во многих командах есть проблема ревью.
То есть там не получается поставить ревью, оно долго идет и так далее.
И на самом деле все эти проблемы, это не проблема ревью, это проблема процесса.
Либо команда плохая, либо процесс плохой, либо инструменты плохие.
Вот мы сейчас рассмотрим.
А что вообще я хочу поменять?
То есть я хочу рассказать, что ревью на самом деле нужно.
А что я хочу поменять?
На самом деле хочется поменять отношение к код-ревью.
Потому что среди разработчиков очень часто бытует мнение, что ревью это там...
Ну, такая второсортная немножко работа, хотя по факту, на самом деле, это очень крутой инструмент, крутая деятельность.
И начнем мы с вами со следующей веселой картинки.
Наверное, многие видели такую шуточку, да, то есть если вы встречаете в лесу медведя, ну, опасность, да, она вот на вас движется, вы такие «братан, посмотри пул реквест», он такой «о, я пошел дальше».
Эта шутка, на самом деле, очень, она очень старая, на самом деле.
Я ее в первый раз увидел, ну, может быть, лет, я не знаю, сколько лет назад, но много лет назад.
И на тот момент у меня было такое мнение, что, типа, блин, да, в натуре, ну, то есть, я разделяю мнение медведя, да, потому что, когда приходят код-ревью, я раньше тоже думал, да елки-палки, код-ревью надо делать, ну, неохота, да, бессмысленно.
И, с другой стороны, я тоже так же думал, что...
Если я не ревьюер, а автор кода, я тоже думал, черт, нужно нести на код ревью и как-то, ну не то чтобы я там страдал и плакал, но немножко это там фрустрация и демотивация была, да, то есть не было такого воодушевления, как от написания кода, потому что, ну все там, я не знаю, разработчики, наверное, любят писать код, а вот ревью как-то не особо.
Но недавно случилась история такая, я эту картинку снова вспомнил, точнее мне ее ребята скинули в тему.
Я ее пересмотрел и подумал, что, блин, я не понимаю, почему медведь проходит мимо.
В моей ситуации он бы, наверное, съел скорее всего меня, потому что я люблю pull request, он бы скорее всего подошел ко мне, если бы я предложил ему pull request, ревью точнее.
А что меня сподвигло?
Почему я вообще всю эту историю вспомнил?
У нас недавно было обсуждение с соседней командой, и ребята такие говорят, мы не ревьюем баги.
Я такой сижу, думаю, так, ребят, стоп.
Баг — это место, где мы налажали, короче.
То есть мы уже облажались.
Это может быть баг с продой, это может быть баг разработки, но в целом мы уже там накосячили где-то, да?
И мы такие говорим, окей, братан, ты один на вас накосячил, мы тебе доверяем, делай дальше, что хочешь.
Хотя, казалось бы, немножко контраинтуитивно, да, то есть мы уже ошиблись, давайте мы лишний раз потратим время здесь и сейчас и проверим этот кусок кода еще раз.
Возможно, это будет более продуктивно.
Вот.
Это, собственно, небольшая такая вводная.
Теперь, прежде чем я расскажу, какие проблемы бывают во время код-ревью и о чем они нам говорят, я расскажу, почему я люблю код-ревью, да.
Потому что иначе, ну, типа, не работает код-ревью, не работает, ну и черт с ним, выкинем его, ну нет.
На самом деле это не так.
Почему я люблю код-ревью?
Смотрите, с одной стороны, я люблю делать ревью.
На самом деле я очень люблю делать ревью.
Я могу залезть в ревью, который меня не звали, и посмотреть, что там вообще обсуждает.
Мне это интересно.
Почему?
Потому что ревью — это вообще на самом деле способ быть в курсе происходящего.
То есть вы командой работаете над каким-то проектом.
Вы пилите свою фичу, кроме вас еще есть несколько других разработчиков, которые пили другие части проекта.
И с этими частями проекта, скорее всего, вам придется когда-то работать.
И вот в момент, когда вы приходите, вам падает новая задача, да, вы отправляетесь в какую-то неизведанную часть проекта, в этот момент у вас может возникнуть такое, ну, как бы, ощущение, что что-то тут не то.
Ну, я этот код вижу впервые, как вообще он работает, да, может даже какой-то негатив быть, типа, блин, кто это написал?
Поэтому вот код-ревью, на самом деле, это способ вообще быть, ну, понимать вообще, что происходит над проектом, да, то есть видеть не только свою задачу, которую ты делаешь, но и такой некий, ну, объем такой,
продукта, как он развивается, как он растет.
Далее это способ обмена знаниями.
На самом деле в больших компаниях чаще всего разработчики, у всех разработчиков свой стэк, свой вектор развития, кто-то там
Кто-то лекции читает, кто-то доклады читает, кто-то инерсорсит, кто-то там суперлибу какую-то пилит.
И вот на код-ревью как раз таки очень часто, ну по крайней мере в нашем случае, возникает ситуация, когда приходит ревьюер и говорит, блин, знаете, ребята, вот в соседней команде недавно такое же делали и сделали вот так вот.
И в этот момент можно действительно синкануться с каким-то разработчиком другим и немножко обменяться знанием.
Причем оно работает в обе стороны.
Далее очень интересный такой поинт, который я хотел бы рассказать.
Представим ситуацию, что к нам приходит какой-нибудь, допустим, безопасник.
Безопасники часто к нам приходят и говорят, ребята, с сегодняшнего дня логи не пишем, например.
То есть какая-то технически сложная задача.
Или там делаем сервис, который будет за одну миллисекунду обрабатывать 10 миллиардов сексиллионов запросов.
Ну что-то сложное.
Вот такая технически сложная задача.
Она у меня, как у инженера, вызывает интерес.
То есть, когда я приду вечером с работы, даже если эта задача достанется не мне, я лягу спать, и знаете, как в мемчике, чувак глаза открывает и говорит, так, как это сделать нужно?
Все равно для меня это будет некий челлендж, типа, а как бы я это сделал?
И, скорее всего, я у себя в голове сформирую какое-то видение, как такую задачу, в принципе, можно решить.
И вот когда я приду на код-ревью...
к человеку, которому эта реальная задача досталась, я смогу увидеть кардинально другое решение.
То есть у меня будет одна задача, которую мы решаем, и будет два кардинально, скорее всего, разных решения.
Мое, которое я придумал себе в голове, с моими ограничениями, проблемами, решениями.
И решение другого человека.
И вот такой подход, когда у нас есть два решения одной проблемы, на самом деле, он очень хорошо помогает, во-первых, почелленджить свое решение, почелленджить чужое решение.
Ну и в целом чуть-чуть более гибко смотреть на подобные проблемы, когда они встретятся в будущем.
Далее.
Код-ревью позволяет нам повлиять на итоговое решение.
Это в целом пересекается с самым первым пунктом.
То есть я работаю над продуктом, и, конечно же, у меня есть некие ожидания от кода.
Очень часто бывает такое, наверное, у многих такое бывает, что ты открываешь код, начинаешь работать и думаешь, блин, ну что это такое?
Как так можно?
И тебе говорят, это легоси, братан, это легоси.
Иногда на код-ревью такой легоси можно повлиять
преодолеть на этапе, когда оно внедряется к вам.
Вот оно сегодня внедряется, да, и ты знаешь, что этот код, завтра посмотрят и скажут, это Legacy.
Нет, вот я могу сейчас повлиять, сказать, ребят, вот так мы делать не будем, давайте мы соберемся, обсудим и сделаем нормально, да, то есть иначе, если как бы код-ревью как, ну, в этом месте не сделать, то действительно, ну, такая фактически защита, да, от плохого кода в нашем проекте.
Ну, не только от плохого кода, может быть, там просто от неподходящего в данный момент.
Далее, почему еще я люблю делать ревью?
Я люблю искать ошибки.
То есть я такой человек, что если я вижу, когда кто-то что-то пишет, я думаю, так, братан, ты по-любому где-то налажал.
Сейчас я найду, где ты налажал.
Причем это относится не только к коду.
Ну и в продукте у меня еще есть такая идея, что, ну не то что идея, я болею за свой продукт, я знаю, что мы катим продукт, я не хочу, чтобы в нем были баги.
Очевидно, я не хочу, чтобы он развалился.
А если он еще развалится, допустим, ну, на клиенте, то у клиента это совсем плохо, но он еще может этот баг найтись у тестировщика, да, у нас там цикл обратной связи, он будет долгим, то есть разработчик переключится с текущей задачи, там, обратно вернется поправить баг, опять его нужно будет ревьюить, то есть вот помочь как можно раньше найти ошибку, да, это тоже одна на самом деле из целей, которую я преследую, когда смотрю чужой код.
Именно по этой причине, кстати, я иногда смотрю чужой ревью, да, которое для меня не предназначено.
Почему?
Потому что у меня есть...
Некие знания о проекте, некий бэкграунд, с которым я уже работал.
Я в целом там уже везде побывал по всему проекту, по нашему, потому что я в том числе там постоянно везде все ревью и смотрю.
И в целом там есть какие-то, ну, Legacy Code, он все еще есть, есть какие-то скрытые знания, про которые я тоже могу рассказать на ревью.
Ну и последнее – это возможность переключиться.
То есть писать 8 часов или 9 часов в день код, или 24 часа в день код – это так себе, потому что со временем нужно переключаться.
Переключаться на ревью, на самом деле, это одна из таких валидных идей для разработчиков.
Потому что просто встать и пойти там… Ну, иногда, конечно, можно, но просто встать и пойти погулять, например, я не всегда могу.
Все-таки у меня есть рабочий график, у меня есть режим и так далее.
А вот переключиться от написания, чтобы мозг немножко разгрузить и почитать немножко, иногда бывает тоже полезно.
Но на самом деле это ещё не всё.
Почему я делаю код-ревью?
Я действительно люблю по этим причинам.
Но я люблю не только делать код-ревью.
Я люблю, когда
меня ревьюит.
То есть иногда я могу принести код, и я его несу не с мыслью, что, блин, сейчас меня будут ревьювить.
Я его несу с мыслью, что, блин, меня сейчас будут ревьювить.
И смотрите, у меня недавно был кейс, то есть вот я хочу рассказать, что код ревью это способ предложить решение.
У меня недавно был кейс, когда нам там дали на поддержку продукт отдельный, но его продолжали ревьювить старая команда.
То есть мы там что-то делали, они ревьювили, ну там переходный период был.
И я, значит, сел такой и думаю, так, тут используется вот такая либо, вот такие подходы, да, но мне это не нравится.
Я знаю, что это там плохо, я могу сделать лучше.
Я думаю, так, пойду, наверное, узнаю, кто этим занимается.
Потом думаю, какого черта, зачем я буду ходить, да?
Я взял, сделал pull-request со своим решением там за полдня, отдал и говорю, ребят, давайте делать так.
Они, конечно же, пришли в...
в мярший квест встали, чувак, мы так не делаем.
Я говорю, ребят, давайте обсудим, может, будем делать.
В итоге мы обсудили, поговорили, там что-то взяли, что-то нет.
Но в целом, то есть код-ревью, да, это способ предложить какое-то решение.
Оно может отличаться кардинально от того, что сейчас используется в продукте, да, но одно дело, когда я приду и скажу, ребят, давайте делать там на декораторах сюда, например, или без декораторов.
Другое дело, когда я принесу конкретный код, который можно будет конкретно пощупать, там, показать преимущество, там, что там тесты легче пишутся, да, или он же там быстрее стал, или что кода меньше и так далее.
С другой стороны, код-ревью, когда меня ревьюют, для меня это способ убедиться в решении.
Какой бы я код ни написал, я пишу код, я люблю, который код, я пишу, я уверен в нем.
И я его еще тестами покрываю, чтобы быть еще более уверенным.
Но вот этот стул, который стоит на трех ножках, моя уверенность в тесте, у него не хватает третьей ножки, это взгляд человека другого.
То есть мне иногда очень важно, чтобы кто-то еще пришел и сказал, да, блин, действительно, это там будет работать так круто.
Собственно, это мой второй поинт, что на код-ревью очень полезно бывает получить какой-то аппрув, то есть не просто галочку, а что действительно человек посмотрел и сказал, да, это будет работать, у меня там уверенность в том, что мой код завтра не развалится.
на проде или сегодня не развалится у тестировщика, моя уверенность растет.
И третий тоже очень немаловажный пункт, я думаю, многим будет близок, это возможность вовремя остановиться.
Все знают, что лучше — это враг хорошего.
Иногда бывает такое, что я в какой-то момент осознаю, что я там какой-то кусок кода переписываю пятый раз и пытаюсь сделать лучше.
Вот мне субъективно не нравится что-то, да, там много абстракции, или там мало абстракции, или там имена непонятные, или еще что-то, да.
В таких случаях, если я понимаю, что как бы вот мой...
Затраченное время, оно гораздо уже возрастает, при этом профит уже особо не меняется, то есть там какие-то субъективные вещи.
Я могу честно прийти в команду и сказать, ребят, я сделал код, вот я там написал код, он мне не нравится на 100%.
Ну чисто я могу лучше, я могу потратить еще два дня и сделать лучше.
Вроде как это не нужно, вот ребят, посмотрите кто-нибудь, кто готов там, да, и ну...
Подскажите, ок или не ок.
И вот момент я могу себя ограничить от того, чтобы тратить лишнее время на то, чтобы написать лишний код, который может быть будет лучше, а может быть нет.
Может быть я напишу, а потом пойму, что еще нужно два дня, чтобы сделать еще лучше.
И вот код-ревью, когда я несу свой код на код-ревью, это способ как раз-таки бороться с лучшим и добиваться хорошего.
Вот.
Но это, конечно, все хорошо, да, код-ревью хорошо с обоих сторон, но на самом деле во время код-ревью очень часто возникают проблемы.
Ну, без шуток, мы вот недавно обсуждали кейс, когда я вот говорил, да, что пришли коллеги с другой команды, говорят, мы не ревьюем баги.
На самом деле то, что мы не ревьюем баги, блин, это очень большой показатель того, что есть какая-то проблема, да.
И я их немножко так...
категоризировал, систематизировал, какие вообще есть проблемы у код-ревью.
Ну, как бы, если отбросить там множество моментов, то в целом, ну, ревью либо не всегда проводится, ну, никогда, это тоже не всегда, по сути, да, либо ревью занимает много времени.
То есть это, в принципе, две проблемы глобальные, которые могут очень сильно повлиять на
На то вообще будем мы пользоваться ревью или нет.
Потому что многие команды от него могут отказаться.
И давайте рассмотрим их по очереди.
То есть первая проблема, которую я вижу, ревью проводится не всегда.
Причины могут быть разными.
Точнее не причина, а форма, как это выглядит.
Кто-то вообще отказывается от ревью.
Кто-то говорит, давайте баги не ревьювить.
Кто-то говорит, давайте там меньше пяти строк мы не ревьювим.
То есть какие-то, ну есть...
Какие-то факторы, какие-то есть признаки, что мы не ревьюим что-то.
Хотя, по моему мнению, это полнейшая дичь, и ревьюить нужно всегда.
Но, например, давайте я покопался немножко в голове и подумал, а по какой причине вообще люди отказываются от ревью?
Вот у нас был такой кейс, когда мы на ревью не находили никаких замечаний, у нас не было никакого обсуждения.
То есть ревью прошло, типа галку поставили.
Прошло, галку поставили.
Прошло, галку поставили.
И получается, что код ревью превращается в некий такой карго-культ.
Ты просто взял, таску передвинул по джерри, поставил галку.
И в какой-то момент мы такие думаем, ну ладно, ребят, раз типа ревью как бы ничего не находится, ну это не мы подумали, да, может, я не помню откуда это была инициатива, типа зачем мы тратим на это время, давайте мы не будем его делать.
И мы перестали его делать.
Но есть на самом деле такая более глубокая проблема, что если замечаний на ревью нету, возможно, мы просто их не нашли.
Возможно, у нас просто действительно каргокульт.
Мы подвинули, пошли и пошли дальше.
То есть у нас проблем не нет, они есть, но мы их не нашли просто.
Как мы это можем найти?
На самом деле, тут тоже еще можно глубже копнуть, в чем есть проблема.
Возможно, у нас в процессе отсутствует процесс анализа багов в нашем процессе разработки.
Я сейчас объясню, как это работает.
Когда мы наткнулись на то, что...
У нас в какой-то момент было очень много багов.
Мы начали думать, а что с этим делать?
И мы такие, давайте мы категоризируем баги.
Мы посмотрим, в какой момент времени у нас эти баги возникают.
Точнее, на каком этапе разработки.
Большинство багов можно категоризировать.
Можно понять, что вот этот баг аналитики профокапились, не учли, и потом, конечно, мы это не учли дальше.
Есть баг, который возник на этапе разработки.
Мы понимаем, что тут разработчик накосячил, какой-нибудь ивчик перепутал или еще что-то.
И это этап разработки.
И вот если у нас много багов на этапе разработки, и при этом у нас на ревью ничего не находится, это косяк.
То есть нужно что-то с этим делать.
Нужно больше внимания уделять на ревью, потому что эти баги мы могли найти.
И могли сэкономить время на анализ этих багов, на анализ всей этой проблемы.
Возможно, есть проблема в коммуникациях.
В одно время такая была история, в интернете я прочитал, не ручаюсь за правдивость, но звучит правдоподобно.
Что в Японии когда-то была такая проблема, что, ну, недавно относительно, когда начали там то ли падать самолеты, то ли там что-то такое, и выяснилось, что, ну, все знают, да, в Японии у них там очень такая классовая, молодые, очень уважают старших и не позволяют там, ну, ничего поперек сказать.
И что многие летчики, которые там пилоты в Японии, они все взрослые.
А вторые пилоты, они молодые, и они даже когда видели проблему, они не могли сказать ничего, да, то есть, ну как бы не принято так.
Из-за этого там возникали какие-то то ли аварии, то ли еще что-то в этом деле, в этом духе, и ну там даже была какая-то акция, чтобы ребята, давайте там, ну это традиции хорошо, но тут безопасность, бла-бла-бла.
Такое на самом деле может происходить и в команде разработки, да, когда есть сеньор, которому там
Либо в штыки воспринимает, либо негативит резко, если ему что-то говорят.
То есть, если на ревью нет замечаний, то, возможно, есть какая-то проблема, что, возможно, автор кода, который пишет код, он не принимает их.
Он говорит, ребят, я сеньор, вы все тут жены, давайте делайте, как я говорю.
А, возможно, человек, который делает ревью, он стесняется.
Возможно, он... Это тоже ненормально.
Если человек стесняется, поедет дойти и что-то спросить.
Потому что я помню впервые, когда я делал ревью, у нас был сеньор, он принес свой код, я увидел у него...
в коде такую конструкцию, как знаете, можно generic ограничить через new, да, чтобы конструктор пустой у него был.
И для меня это было дико, потому что я пришел там с какого-то, я не знаю, с Python или с PHP, и я говорю, что это такое, да, типа, хотя, ну, по идее, как бы глупый вопрос, да, ну, типа, я мог пойти и документацию почитать, что это.
И он мне не сказал, типа, блин, братан, ну, иди почитай, да, то есть как-то токсично не ответил, не убил мое желание там пытаться понять.
Он мне сказал, да вот, типа, док, вот, почитай вот тут вот.
Отлично, то есть проблемы нету.
Поэтому, возможно, есть проблемы в коммуникации.
Что с этим делать, я не скажу.
Очевидно, мы сейчас с вами попытаемся определить проблемы, которые могут быть.
А вот как их решать, это уже вопрос чуть посложнее.
Может быть отсутствует мотивация.
Опять же, это очень важный, на самом деле очень важный такой качество у разработчика, это мотивация дотолкнуть свой продукт до прода, сделать его.
То есть не просто отдать код в ревью, а именно до прода дотолкнуть до конечного пользователя.
Возможно, у нас нет мотивации делать ревью, и у автора кода нет мотивации просить сделать ревью.
Еще интересный момент, что отсутствует понимание цели ревью.
То есть нету замечаний, возможно, потому что мы не знаем, для чего вообще мы делаем ревью.
То есть я иногда слышу такое мнение, что на ревью нельзя... То есть ревьюер не должен запускать код, или он должен посмотреть с точки зрения модулей, но не должен смотреть функционально, что типа этот тестировщик будет делать.
Я с этим категорически не согласен.
У меня есть такой частично связанный с этим контрпример, который я недавно...
Ну ладно, я недавно его придумал, на самом деле я с ним давно сталкивался, который в целом может немножко, ну если у нас ревью поставлено нормально, да, и человек в принципе понимает, что мы делаем, а он может нам немножко помочь.
Вот смотрите, у нас есть такой код, и как вы думаете, есть, ну типа ок или не ок, пропускаем его, ставим его опруф или не ставим?
Ну такой в вакууме, понятно, да, тут как бы особо придраться можно много к чему.
Кто против кода?
Поднимите руку, кто не нравится кому-то.
Смотрите, я сейчас не буду спрашивать, почему, но в целом я тоже против такого кода.
Я сейчас объясню, почему.
Во-первых, я сейчас немножко контекста добавлю, на самом деле, может быть, он другой будет.
Аргумент exception, который мы бросаем, чаще всего мы его никому не показываем.
То есть конечную пользователю, скорее всего, он не улетит.
Возможно, мы его залогируем.
И мы его логируем с текстом, некорректный формат номера документа.
На самом деле, это вот этот текст, который в exception.
Единственное, чем он мне поможет, это увидеть в логах эту запись.
Все.
Потому что если его выкинуть, у меня информации меньше не станет.
Я буду дольше эту запись в логах искать, но у меня все равно есть тег trace, я знаю, что в документ number на пятой строке, если аргумент exception, это проблема с номером.
И когда я приду эти логи анализировать, я столкнусь с тем, что некорректный номер, конечно, это хорошо, ребят, но что с этим делать?
А что туда пришло?
Пустая строка пришла?
Или там пришел какой-то кривой номер.
Давайте мы это запишем.
И когда я буду этот лог анализировать, то мне будет чуть проще разобраться.
Я смогу, возможно, понять, что с внешней системы мне пришла какая-то ерунда.
А проблемы, на самом деле, могут быть очень хитрыми.
Я однажды очень долго разбирал баг, когда нам с внешней системы приходила аббревиатура.
Я не помню аббревиатуру, но что-нибудь типа там FBR, например.
И там вместо русской R была английская P.
И вот пока и даже, ну, типа, и что вот очень долго я потратил, очень много времени, чтобы разобраться.
Но при этом, если бы она у меня условно была в логах, да, я мог бы ее посмотреть и понять конкретно, что же там происходит.
Потому что мне внешняя система говорит, вот мы отправили ФБР, там, да, где-то они говорят там у себя в логах.
А у нас падает ошибка.
Собственно...
Это один из примеров, который в целом можно найти на ревью.
И тут именно фокус на том, что мы не просто код смотрим, мы смотрим, что код еще делает, какую-то его логику просматриваем.
Ну и самый, наверное, неприятный момент, это когда замечания не правятся.
Ты пишешь замечание, говоришь, ребята, давайте так не делать, а после этого ничего не меняется, и код вливается как есть.
Вот еще один пример.
Тоже относительно недавно у меня был, когда мне пришел такой код на ревью.
У нас есть автомобиль, у него может быть бензиновый двигатель, электрический двигатель или и то, и другое сразу.
Но он не может быть вообще без двигателя.
И, соответственно, разработчик принес такой код, в котором есть конструктор, там на самом деле, по-моему, не конструктор был, там, наверное, метод был.
Конструктор, который принимает два двигателя, они оба помечены nullable, как вы видите.
Но при этом, если передать оба null, он разваливается.
Я подошел и говорю, слушай, мне такое решение кажется нелогичным, потому что если я вижу метод, который принимает два нал, я хочу вызвать этот метод и передать ему два нал.
Если он так не может принимать, то зачем ты такой метод сделал?
Я не так сказал, конечно, это все должно быть вежливо.
И он мне сказал, что слушай, я пометил, что может быть, но внутри обработка-то есть, что ты от меня хочешь?
Он нормально работает.
Я такой, ну я не нашелся, что на это ответить, и на тот момент я еще там только-только условно начал работать в этой команде, и как-то оно проскочило так, что это попало в прот.
Оно на самом деле сразу не развалилось, какое-то время оно обрастало мясом, и в какой-то момент возникла проблема, что у нас там ошибка начала сыпаться.
И мы там в окружающем коде удалось найти, что откуда-то что-то приходит, проваливается вот этот метод и разваливается.
И когда до меня дошел этот баг, и я начал разбирать, наткнулся на эту проблему, да, и мне в итоге пришлось потратить там два дня, чтобы все это переписать, потому что вокруг наросло немерено кода, много интеграций каких-то еще чего-то, да.
И, конечно, это очень сильно демотивирует, потому что я об этом говорил, да, типа, а я же говорил, да.
Но это не было поправлено, и в итоге мне все равно пришлось с этим сражаться.
Поэтому когда замечание с ревью не правится, это на самом деле очень плохо.
Ну и оно мотивирует, с одной стороны, на то, чтобы в будущем замечание как бы не писать, да, ну типа зачем.
А, ну есть и другая проблема, на самом деле.
У нас был кейс, когда было слишком много замечаний, да, и в какой-то момент Team Lead сказал, ребят, да хорош уже, ну типа, что вы там, блин, ну сколько можно, да, давайте уже, двигайте ревью, типа, что вы там делаете, у нас прод горит или там, у нас клиенты ждут, да, у нас сроки горят, у нас эта рация заканчивается.
И, соответственно...
Это тоже на самом деле проблема, когда слишком много замечаний, может прийти такое гениальное решение, ревью не делай.
Хотя проблема тоже на самом деле не в ревью как таковом.
Возможно, есть проблема в коммуникациях.
Иногда бывает такое, что в ревью кто-то заходит и говорит, давайте сделаем так.
А другой говорит, не, не буду так делать.
Ну давай сделаем.
Нет, не буду.
И какое-то такое неконструктивное обсуждение возникает.
То есть в действительности, если возникает в код ревью какой-то такой конфликт менее, единственное правило привлечь третьего человека.
Следующее правило — команду привлечь, потому что вдвоем холивар устраивать в код-ревью как будто бессмысленно на самом деле.
Возможно, есть проблемы в процессе разработки.
Почему может быть много замечаний?
Да потому что все замечания могут состоять в том, что у тебя тут пробел лишний, у тебя тут пробел лишний.
То есть у нас не настроен линтер или форматор какой-то, еще что-то.
И где-то там пробелы у кого-то, табы у кого-то пробелы.
Вроде сейчас в прошлое ушло.
Или кто-то переносит строки, кто-то не переносит.
Если мы не можем настроить наш инструмент, чтобы он нас избавил от этого, то как команда сможем ли мы вообще продукт хороший выпустить?
Возможно, много замечаний, они мусорные, поправь, перенос добавь и так далее.
Проблема не в том, что много замечаний, а в том, что у нас процесс плохо поставлен.
Один из примеров – это такой код.
Он делает примерно следующее.
Мы принимаем пачку юзеров.
мапим их в пачку, ну точнее коллекцию принимаем, прошу прощения, юзеров в task.dto, да, мапим ее в коллекцию task-моделей, потом в каждую task-модель что-то докидываем.
Вот такой код, он плохой.
Давайте так, кто видит проблему в этом коде?
Кто-нибудь?
Можете сказать, что там?
Ну, Реф, ты сказал.
Ага, а вы что сказали?
Да, да, абсолютно верно.
Тут, во-первых, 0RF смежная тема.
То есть у нас как бы мы что-то смапили, но мы не до конца смапили.
И вот если в другом месте я захочу замапить, мне нужно знать, что где-то там в коде есть такой кусок, который мапит, но не все.
Если я захочу переиспользовать маппинг, я не смогу его переиспользовать.
Это первая проблема.
Вторая, что вот этот вот юзер, который в таске на восьмой строке, скорее всего, аналабл.
Хотя на выходе из метода он не должен быть nullable, но скорее всего внутри этой модели он сделан nullable.
Либо он заглушен компилятором, либо там какое-то дефолтное значение.
Потому что иначе, если он там не nullable, не заглушен компилятором, он обманывает меня, потому что на строках с 4 по 6 его там нету.
То есть он в какой-то момент может быть nullable, и скорее всего он так помечен.
Но при этом при выходе из метода, еще раз, он не nullable уже.
То есть у нас вот этот вот маппинг размазался, и за счет этого у нас код немножко становится нечитабельным.
Более того, такой код, его потом тяжело переиспользовать.
Потому что очень часто бывает такое, что есть какие-то скрытые знания.
Я в другом месте этот код переиспользую, ко мне придет, ну не этот код, а маппинг конкретно.
Ко мне придет товарищ и скажет, так делать нельзя, есть скрытые знания, нужно еще добавить юзера.
Блин, братан.
Откуда я должен это знать, да, типа, ну, давайте писать код, чтобы такого не было.
Это тоже реальный кейс, у нас как-то было такое, улетал запрос во внешнюю систему, там тоже был маппинг такой, я такой, ну, думаю, маппинг есть, как бы все так делают, не буду сражаться с этим, да, сделал, отправил, и потом оно там где-то свалилось на тестирование, оказалось, что после этого маппинга нужно еще там прописать какую-то версию, короче, блин, вот это меня прям пригорело, конечно, от такой ситуации, поэтому да, то есть лучше все-таки, так, что-то у меня тут...
Я был, наверное, на эйфории еще от того, не отошел.
На самом деле, да, нужно сделать маппинг нормально, в одно действие, не так, что мы потихоньку разматываем-разматываем.
Но вообще, да, слишком много замечаний.
Вот эту тему продолжим, что слишком много замечаний, может быть, не потому, что там у нас проблема в коммуникациях, на самом деле может быть плохой код.
Блин, давайте это признаем, да, если у нас во время обсуждения там куча-куча-куча возникает нюансов, что я поправил в одном месте, да, на ревью говорят, чувак, у тебя вот тут сейчас развалится, но очевидно, у нас может быть плохой код.
То есть от этого не нужно там, не ревью должно страдать, да?
Не должно быть такое, что типа, ребят, что у вас там на ревью?
Да мы сейчас правим баги.
Ребят, вы уже два дня правите, давайте быстрее.
Блин, давайте код тогда лучше писать, да, условно.
То есть это может быть действительно показателем того, что у нас плохой код на самом деле.
Либо у нас, может, нет тестов, да?
Все, не знаю, все ли любят тесты?
Я вообще обожаю тесты.
Я постоянно пишу тесты, и они, блин, они мне сегодня жизнь спасли практически, да, на самом деле.
У меня, я вчера пришел, у нас было там, нужно было срочно докатить ветку.
Я вчера приехал в Москву, значит, достаю ноутбук, мне пишет тестировщик, говорит, слушай, там баг небольшой нашелся, баг, ну, прям совсем крош, там с округлением, да, типа, нужно поправить.
Я такой, да не вопрос.
Я приезжаю в офис, сажу, включаю ноутбук, у меня ноутбук не работает.
Точнее, у меня включается и ломается он, да.
И...
И он мне, короче, там все глухо, вообще развалился.
Я думаю, что делать?
Я подошел к товарищу и говорю, слушай, можешь поправить, пожалуйста?
Ну, типа, возьми, пожалуйста, бак на себя.
И самое интересное, что я говорю, там есть тесты.
Ты допишешь два кейса, и если ничего не развалится, значит, все хорошо.
То есть вот эти тесты, которые я написал, они мне дают уверенность, что код, который написал я и который сейчас будет править человек, который в целом вообще не в контексте, что происходит, он его не сломает.
Если тестов нет, то это, конечно, плохо, да, то есть вот, например, тоже один из примеров с код-ревью, который я восстановил по памяти, да, то есть есть такой код, он что-то делает со строкой, вот, ну давайте вы его прочитайте, и вот кто найдет какую-то проблему, кто может там предложить проблему, да, вот руку поднимите так, озвучьте там словом, словами, предложением, идеей, что тут не так.
Да, да, вот еще был комментарий с дейт таймом, хороший, что дейт тайм нау, да, во время тестов он принимает значение нау и проверить на выходе, что там корректно сформировалось, например, имя файла невозможно, да, скорее всего, потому что дейт тайм не замокаешь.
И тут, ну вот, две проблемы, которые мы подчеркнули.
Первое, что в принципе используется статика, да, на самом деле статика как таковая неплохая, но вот в данном случае я бы ее всю замокал, честно скажу, да.
Я как-то предложил такое сделать тут на чатике.
А, не, не так даже было.
Там было обсуждение.
Мне сказали, блин, ты что, еще и дейтайм будешь мокать, что ли?
Ты что, совсем, что ли?
Да, конечно, буду мокать.
Блин, я хочу проверить, что все работает.
Более того, Microsoft в одной из последних версий тоже выпустила какой-то там дейтайм провайдер или что-то в этом духе.
То есть они тоже в ту сторону, чтобы сделать какую-то обертку.
Но это не единственная проблема.
То есть, во-первых, тут тяжело что-то замокать, тут тяжело протестировать.
И как-то мне попал такой код.
И разработчик проверил часть кейсов, но он не смог все проверить.
То есть тестами можно покрыть кейсы, которые ты не можешь воспроизвести в реальном приложении.
Например, фронт у меня не пускает три цифры, какой-то валидатор.
Но на бэк-то они могут прилететь, эти три цифры условные, а не четыре.
Поэтому тестами я могу покрыть любые кейсы, быть уверенным, что если на фронте что-то поменяется, то у меня бэк не развалится.
Вот тут была аналогичная ситуация, то есть разработчик у себя на компьютере это проверил, но он там не учел, что у него тут, кстати, опечатка есть.
На шестнадцатой строке перед JSON отсутствует точка.
И вот у него была подобного рода отпечатка в коде, которая в итоге приводила к тому, что у него просто замусоривался каталог и не очищалось ничего.
Вот такие вещи очень легко находить тестами.
Поэтому если тестов нет, блин, это тоже плохо.
Это рано или поздно все равно выльется на ревью.
В том числе на ревью.
Потому что... Ну да, почему, расскажу потом.
Следующее еще, что фокус не на скорости, а на качестве.
На самом деле, молодые разработчики, я сужу по себе, я когда пришел в команду, я думал, блин, ребята, сейчас я наделаю кучу там реквестов, тестировщик их быстренько найдет, я их быстро поправлю, да.
И у меня был фокус на том, чтобы сделать быстро, и казалось, что быстро это хорошо, да, типа, ну баги в любом случае будут, если я их быстрее принесу, мне их быстрее вернут, да.
И я думал, что все хорошо, пока ко мне не пришел тимлит и не сказал, что тестировщики жаловаться начали на меня, что я какую-то дичь гоню.
И я пересмотрел и понял, что человек, который условно сидел рядом со мной, и он писал код медленно, я думал, блин, братан, ты так, типа, что ты там делаешь?
У него в итоге суммарное время фичи, оно выходило быстрее, чем у меня, за счет того, что он больше тратил время на первом этапе написания, но зато у него не было кучи возвратов и кучи багов.
А куча багов, она же как снежный ком, там один баг пришел, ты его поправил, а тестировщику нужно желательно все перепроверить, а не то, что ты там один баг поправил.
Возможно, есть проблемы с декомпозицией или анализом.
Почему может быть много багов?
Почему может быть много замечаний на CodeReview?
Да потому что у нас задача занимает 10 тысяч строк.
В любом случае будет много замечаний.
Давайте мы ее разделим на части и будем катить частями, а не вот так, как есть сейчас.
Это что касается, что ревью в целом иногда не делается.
Почему?
Я свел это к тем, что либо слишком мало замечаний, и мы решаем, что оно не нужно, либо слишком много, и решаем, что оно отнимает много времени.
Обе идеи в целом контринтуитивны немножко, но на практике я такое встречал, честно скажу.
Но есть другая сторона.
То есть то, что ревью мы не делаем, ну ладно, Олег, успокойся, мы его делаем, но мы его долго делаем.
Такое на самом деле тоже часто встречается.
Я их разбил тоже на несколько категорий.
Первое, что долгое ожидание ревью.
То есть что я подразумеваю?
Я принес задачу, говорю, ребят, она в ready for review, да?
И вот она висит в ready for review несколько дней.
У вас было такое, что задача на доске несколько дней в ready for review висит?
ладно, не так много, как я ожидал, но я еще две руки подниму.
В целом, на самом деле, тоже, ну, типа, это очень хороший показатель процесса нашего, да, то есть, если у нас задачи висят в Ready for Review несколько дней, то, возможно, у нас, блин, разработчики загружены, возможно, у нас никто не может эту задачу взять в Review, да, то есть, возможно, разработчик реально сидит, у него, блин, задача на 4 дня, и он просто не может там поднять голову, да, и посмотреть, что происходит вокруг.
Вполне может быть.
А может быть, у нас просто много задач, да, и когда я сажусь...
Когда я закончил свою задачу и вижу, что там лежит ревью, да, параллельно я вижу, что ещё завтра конец там итерации или там, я не знаю, как что угодно, у меня ещё пять задач, я думаю, так, ревью подождёт, вот задачи нужно точно делать, да, потому что я не знаю, чем я руководствуюсь в этот момент.
Но на самом деле тоже часто встречается, что именно задача толкается вперёд, а ревью как будто бы начинает немножко пробуксовывать.
И тут возникает следующая проблема, вообще есть ли понимание, что ревью приоритетнее разработки, да?
То есть если работать по Kanban, например, ну или по здравому смыслу, да, то ревью, оно как бы, ну по Kanban оно правее находится, да, ревью, то есть мы его уже почти дотолкали до прода, и по Kanban мы должны уделить ему больше внимания.
Если при прочих равных я вижу задачу на разработку и задачу на ревью, я должен сделать ревью, потому что, ну это как бы последний пинок, да, до тестировщика и потом до прода.
А вот если я начну делать новую задачу, у меня получается две задачи, которые непонятно, что еще, чем занимаются.
Поэтому, на самом деле, возможно, просто в команде не принят, или там явно не проговорен процесс.
Мы пока не проговорили с командой все это.
Это не моя инициатива была, не то, что я такой молодец пришел и рассказал.
Но пока мы не проговорили, я тоже об этом не задумывался.
На самом деле, если ты видишь задачу на ревью, и у тебя сейчас нет текущей активной задачи, не начинай новую, помоги дотолкать хоть что-то до прода.
Иначе это все потом скопится в итоге все равно.
Возможно, отсутствует командная работа.
То есть я, когда вижу, что мой товарищ потратил много времени и сделал суперкрутую фичу, я хочу помочь ему.
Я вижу, что его там мячик катится к воротам, я хочу его пнуть посильнее, а не такой, типа, ну ладно, докатится, докатится.
И это, на самом деле, тоже очень важно.
Все-таки мы работаем в команде, то есть я молодец, я пишу хороший код, но я вижу, что там кто-то что-то сделал, и я как бы, ну, фактически я намеренно игнорю, говорю, я смотреть не буду.
Ну, такое, какое-то не очень хорошее отношение.
Возможно, есть проблема коммуникации.
Все проблемы из-за коммуникации или мотивации, по сути.
То есть отсутствует мотивация закончить задачу.
Бывает такое, что разработчик реально отправил задачу в ревью, а другие фактически тоже не заинтересованы.
Нам вообще все равно.
Закончится, докатим, докатим.
Не докатим, не докатим, соберемся на ретро, обсудим, почему не докатили, будем катить пытаться по новой.
Может быть, проблема в том, что отсутствует обратная связь от бизнеса.
Вот смотрите.
У нас очень часто приходят наши аналитики, технологи, кто-то, кто близок к конечному пользователю, они нам могут сказать, знаешь, Олег, например, мне, ты вот на той неделе пилил фичу А, и мы получили 10 обрадованных отзывов, или 50% отказов меньше стало.
Вот что-то такое.
Вот эта обратная связь от бизнеса, она очень мотивирует на самом деле.
Потому что я понимаю, что я делаю не в стол все это.
То есть я делаю фичу, и мне как бы больше мотивация дотолкать реально ее.
Потому что я понимаю, что она кому-то нужна, а не просто так.
Потому что когда ты делаешь просто так задачу, и нету фидбэка со временем, то есть первое время ты там сидишь такой на эйфории, пишешь код, а потом ты понимаешь, что вообще всем по сути-то по барабану что-то там пишешь.
И если обратной связи нет, то это тоже...
Одна из мотиваций, в принципе, не пытаться задачу протолкнуть дальше, не участвовать в ревью.
Ну или опять же присутствует проблема коммуникации внутри команды, куда же без них.
То есть на самом деле такое может быть, что я как разработчик, я не вижу, что там пришло что-то на ревью.
Ну типа доска большая, я там не сижу на нее постоянно, не смотрю, такое может быть.
Но что мешает автору коду написать, ребят, у меня там задача на ревью, там день висит, посмотрите, пожалуйста.
Вот если такого не происходит, то есть если я там условно,
Вижу, что задача висит три дня, и автор при этом никому не сходил, не попросил посмотреть, то получается, автор-то тоже не особо заинтересован в том, чтобы протолкнуть ее дальше.
Тут я бы хотел еще упомянуть такой момент.
Знаете, есть такой закон конвея.
Кто слышал про него?
Или конвея знаете?
Поднимите руку.
Одну только вижу.
Ну ладно.
В общем, есть закон конвея такой, который гласит, что структура организации, которая разрабатывает программный продукт, вот ее структура, она находит свое отражение в продукте.
То есть, ну, своими словами объясню, как я это понимаю.
Что если, допустим, в компании много маленьких отделов, то, скорее всего, и в коде будет много маленьких модулей.
Если компания — это такой огромный монолит, ну, скорее всего, в коде тоже будет монолит.
Там были какие-то экспериментальные доказательства в целом.
И у меня такая мысль, что...
То, как мы делаем в коде что-то, наш датафлоу, он в целом, возможно, тоже находит свое отражение в процессах, которые приняты в компании или внутри команды.
Такой код я встретил тоже относительно недавно.
Это скорее пример того, что мы можем обнаружить именно в процессе ревью.
Что тут происходит?
Мы принимаем сущность, мы мутируем частично ее, потом мы отправляем эту мутированную сущность, получаем в ответ что-то еще.
У этой полученной сущности
мы опять отправляем куда-то и переписываем еще раз одно из свойств.
Ну, короче, на самом деле это звучит хуже, лучше, чем на самом деле происходит там, да, потому что там еще была куча кода.
Но основная идея в том, что тут вообще нихера не понятно, честно, да, когда я увидел это, я подумал, что это за дичь, да, и когда я пошел к ребятам, спросил, что это за дичь, они сказали, да, действительно, это дичь, но это Legacy, типа, да, с этим ничего не поделаешь.
Если хочешь, можешь переписать, да, ну, как бы это хорошо, вот.
Тут немножко упрощен пример, но вообще в целом, да, вот такая вот...
Такой пример кода, он говорит, что, возможно, у нас процессы поставлены так, да, мы что-то сделали, но мы не закончили.
Вот давайте еще что-то сделаем, но опять не закончим, и вот тут мы уже сделаем и закончим.
Вишенка еще тут сверху есть на торте, да, на торте, что вот этот вот реквест на пятой строке, да, вот смотрите, мы реквест-энричер, отправляем туда реквест, получаем в ответ enriched, вот этот enriched,
Это просто ссылка на тот же request.
То есть под капотом он его мутирует и возвращает его уже.
И у нас в моменте есть две переменные, которые указывают на одну область памяти, о чем я не знаю.
Более того, я могу поменять местами даже несколько методов, у меня все скомпилится, возможно, что-то заработает, возможно, нет, непонятно.
То есть код очень хрупкий и очень непонятный.
Возможно, у нас и в процессе такие в команде поставлены.
Собственно, выглядит сложно сказать, что это совсем плохо, я не могу.
На самом деле понятно, что я не могу прийти и сказать «Ребят, что за дичь вы написали?» Потому что я такую же дичь пишу иногда тоже.
И я могу, как бы знаете, что если ты смотришь на код месячной давности, который ты написал, и тебя там не тошнит от него условно, то скорее всего ты не вырос.
Поэтому нет такой претензии, что «Кто это написал?» Такого тоже не должно быть.
Но есть претензии, что «Код не очень хороший, может мы с этим что-то сделаем».
Такие вещи очень хорошо тоже на ревью на самом деле можно найти.
Но смотрите, долгое ожидание это хорошо, есть еще более такая проблема, на которую я еще хотел бы обратить внимание, почему-то она называется мне тоже долгое ожидание, это долгое ожидание уже не того, как моя задача пойдет в ревью, а долгое ожидание самого ревью.
То есть задача ушла в ревью, уже ее начали ревьюить, и она очень долго проходит.
Долгий процесс ревью.
И тут, может быть, такая проблема, на которую я хотел бы очень сфокусироваться, это ревьюер не в контексте.
Бывает такое, что человек садится такой, что там на ревью, что-то нужно было сделать, он садится, и он реально тратит много времени, потому что он не понимает вообще, что там происходит.
Почему это плохо?
То есть, смотрите, у нас есть некий такой финальный этап нашей разработки фичи.
Это некий такой acceptance.
Вот задача нам пришла, и человек такой сел, такой типа так, я вообще ничего не понимаю.
У него там вопросительный знак нарисован, это он не понимает, что происходит.
При этом до этого, скорее всего, по этой задаче велась разработка.
У нас были daily, самое важное.
У нас были митинги, возможно, вопросы.
То есть, если это какая-то действительно технически сложная задача, на которой требуется контекст, наверное, по ней была проработка, обсуждение вопросов, митинги, трейдить и еще что-то.
До этого, скорее всего, если у нас процесс поставлен опять же, у нас был, наверное, анализ, спецификация, неважно как называется, груминг какой-то был, планирование было.
То есть в целом по этой задаче велась какая-то активность.
Если человек, который пришел на ревью вообще не в контексте задачи, это все прошло мимо него.
То есть это как бы выглядит странно на самом деле.
То есть по какой причине вообще это может быть?
И тут я бы хотел такой момент подчеркнуть, что ревью, на самом деле, оно начинается не после разработки.
Это не то, что мы закончили разработку, начали ревью.
К нему нужно готовиться.
То есть вот этот человек к нему не готовился, хотя у него были все шансы.
У него была некая постановка задачи, некая сама задача, разработка, какой-то статус по задаче, который, в принципе, мог наполнить его...
Ну, информационное пространство, чтобы он хотя бы понимал, что вообще происходит, что он вообще ревьюит, в принципе, да?
Вот.
А ревьюер не в контексте.
По какой причине это может быть?
Да, банально, отсутствует проработка задачи.
Возможно, нам задача упала сверху, нам говорят, ребят, нет времени, давайте делать, да?
Разработчик, который ее делал, у него не было времени, он начал делать.
И, конечно, когда человек придет на ревью, он вообще не будет понимать, что происходит.
Хорошо это, но, очевидно, это плохо, да?
То есть, как бы, ну, тут корень нужно найти, что все-таки задача должна проходить нормально все этапы, мы должны ее анализировать, обсуждать и так далее.
Если это не там...
бак с прода какой-то, который развалился, нужно срочно поправить.
Но если такое происходит, обычно мы там команды собираемся, в моменте все делаем, и все равно мы все в контексте.
А, далее важный момент, инструменты не работают.
Да, ну смотрите, я сказал, что до этого были дейли, груминги, планинги, да, я часто слышу такое, что типа, блин, зачем мне дейли, да, типа, ну вот я если захочу, я пойду к этому человеку, чего я буду ждать там, не знаю, 9 утра, когда у нас дейли, да.
У дейли, блин, очень много на самом деле целей.
Одна из целей, это как раз таки вот это вот создавать, заполнять вакуум, да, потому что когда я прихожу,
И слышу, как другой разработчик говорит, я делаю фичу A и напоролся на то, что там JSON, который приходит с сервиса B, он там невалидный, например, у меня появляется некий контекст.
Я понимаю, что в этой фиче есть какая-то интеграция с сервисом B. Возможно, я знаю, что можно сделать.
Возможно, я могу даже помочь ему.
Но когда я приду условно ревьюить код, я буду примерно понимать, что вообще там происходило.
Если же я это все пропустил, скорее всего, человек действительно приходил на ревью, на ревью на daily и просто говорил, я занимаюсь фичой, а все хорошо.
Очевидно, бессмысленная daily, которая не добавляет ничего.
Ну и последний пункт — это низкая вовлеченность.
Возможно, действительно, у нас был грубинг, планирование было, люди ходили, активно участвовали, на daily все рассказывали, а вот ревьюер, он пришел, он ничего не знает, да потому что он ничего не слушал, условно.
Он пришел на daily, камеру выключил, он сидит, ясно, условно.
То есть тут еще есть такой фактор, что все равно рано или поздно мы можем упереться в то, что там конкретно человек, не то что косячит, но может он недостаточно мотивирован, недостаточно вовлечен.
Вот.
Это все, что я хотел практически сказать по поводу вот этой вот части с вовлечением.
Но, смотрите, на самом деле, да, задача действительно может быть сложной.
Действительно может быть такое, что я пришел, сел делать ревью, и там что-то гиперсложное, да, что я не понимаю.
То есть я слышал, что там на daily обсуждали, что там на груминге обсуждали, но я не понимаю, что происходит, да.
И тут я бы хотел донести такую мысль, что ревью на самом деле задача не только ревьюера, потому что не нужно писать код с тем, что типа ладно, ревьюер посмотрит, сам разберется.
Конечно же нет, ревью нужно готовить.
Почему?
Потому что смотрите, по мере вот этого вот...
В процессе жизни вот этого цикла у нас у автора кода происходит, прошу прощения, у ревьюера происходит некое наполнение контекста.
Вначале он ничего не знает, потом он что-то понимает, и на код ревью он уже там супер профи вообще в целом в контексте фичи.
Но у нас есть второй человек, да, это все два человека, один наверху, второй внизу.
У нас есть человек, который разрабатывал код.
И у него вот это просветление наступает чуть раньше.
На этапе разработки он в целом уже очень хорошо погружен в фичу.
И если он понимает, что там есть какие-то сложности, он может помочь ревьюеру справиться с ними.
То есть долго ревью может быть потому, что ревью не подготовлено.
То есть автор кода просто написал код и просто сказал «насмотри».
То есть никак не помог ему разобраться, что происходит.
То есть опять же отсутствует мотивация.
Тут как бы особо не...
От этого и не уйдешь, то есть проблема вполне может быть, как бы с ней нужно что-то делать.
Отсутствует командная работа, то есть тут все больше упирается уже именно в команду, что типа ты смотри мой код как хочешь, я туда заходить не буду.
А как готовить ревью?
Кто-нибудь готовит свою ревью специально?
Поднимите руку, кто там предварительно как-то ревью готовит, кроме того, что отправить его и запушить.
Ну, смотрите, вот я разработал фичу, вот я отправил, что значит готовить?
Это значит, что я не просто нажал push, create merge request и save.
Вот кроме этого, есть какая-то активность, которая направлена именно на то, чтобы облегчить код-ревью.
Тесты.
Это отличный пример, кстати, да.
Один из поинтов, я думаю, будет.
Смотрите, на самом деле я предложу более простые еще немножко способы.
Посмотрите в интерфейсе GitLab.
Блин, я в интерфейсе GitLab каждый раз смотрю свое ревью и каждый раз что-то нахожу.
Я написал код, я захожу, я вижу, что я там какую-нибудь консольку пропустил или пробел лишний поставил.
А еще бывает более критично.
Я вчера смотрел, я вижу, что я там в контроллере добавил две строки логики.
Я такой думаю, по-любому меня спросят, зачем это в контроллере.
Ну я отвечу, что там вот сервис.
Потом думаю, так, ну отвечу, что там сервис есть, да, его трогать не хочется.
Но это как бы неубедительный аргумент.
Мне скажут, ты что, да?
Я такой, блин, ладно, я лучше это поправлю и вопросов избегу.
На самом деле это очень сильно помогает.
Я очень часто сам себе задаю вопрос во время ревью, да, своего же кода, который я правлю и становится лучше.
Один из примеров, это код, который тоже можно увидеть на ревью и немножко от него подгореть.
У нас есть метод, который называется getOrders, и он принимает сущность с типом user, которая почему-то названа currentUser.
То есть, казалось бы, мелочь, но по факту возникает вопрос, почему currentUser?
Что будет, если я передам мне currentUser?
То есть, это будет работать или не будет?
Небольшой спойлер, работать не будет, потому что там внизу была внутри проверка.
И тогда возникает вопрос, какого черта я вообще передаю туда юзеру,
То есть давайте назовем метод getCurrentUserOrders и не будем вообще ничего принимать.
В чем смысл передавать туда юзера, который внутри проверяет, что это конкретно.
То есть вот этот код вводит в заблуждение.
И такой код очень легко найти при просмотре его в GitLab, потому что ты его видишь изолированно, условно, без всяких подсказок, без вот этой всей лабуды, которая в VDE обязательно присутствует.
Собственно, да, предлагаю изменить название метода.
То есть если он только для текущего юзера, давайте переименуем.
Если же не для текущего, давайте currentUser переименую в user.
Тогда вопросов будет меньше, и в будущем это вызовет меньше потенциальных проблем.
Проверить, что вообще работает.
Тоже банальность банальностью.
Недавно у меня был кейс, когда мне принесли тоже на ревью, я смотрю, я понимаю, что он скомпилится, на JS не будет работать, потому что там круглые скобки забыли для вызова метода, там просто метод отправлен.
Я пишу, типа, оно работает?
Он такой, а блин, сейчас поправлю.
Приносит второй раз, я смотрю, а там в одном месте нужно было FIO вывести, а там не FIO, а FFO, вместо имени в фамилию второй раз.
Я такой пишу,
Чувак, что-то не то, короче.
Он такой, да блин, у меня локально не получилось запустить, поэтому я его не запускал.
Я такой, ну, типа, давай разбираться, в чем проблема.
То есть запустить на самом деле проверить, а еще лучше сделать скрины.
Я в последнее время люблю сделать, если я там какую-то опиху прорабатывал, я могу там приложить из посту на какого-то там JSON.
Если я делаю что-то на интерфейсе с фоткой, да и приложить в комментариях задачи, очень сильно помогает.
Потому что у меня было такое, что я сфоткал и понимаю, что там отступ кривой.
Кажется мелочь, но я думаю, блин, ну выглядит так себе.
Я там зашел, поменял быстренько, сфоткал хорошо, поправил, запушил, отдал.
То есть, ну как бы все равно помогает писать более качественно, продукт делать более качественно.
Собственно, один из примеров еще у нас тоже как-то выстрелил.
У нас был такой feature flag config некий, у которого было такое булевое значение use old form.
Знаете, где он может развалиться?
Кто знает, где он может развалиться?
Что может пойти не так?
Давайте так.
Знаете, в чем проблема?
То есть
Ну, да, это какая-то более глобальная проблема.
Проблема в том, что если по какой-то причине конфиг не подтянется у нас, ну, всякое бывает, то есть там среду не завели там сеттинги и так далее, use old form примет значение false, то есть он скажет старую не использовать, используем новую.
То есть поведение изменится.
То есть если вдруг я катну это на prod и забуду проставить настройку, у меня поведение изменится.
Поэтому как будто бы лучше сделать явно use new form, чтобы мы явно флаг поставили, а если вдруг мы забыли флаг, у нас ничего не поменяется, оно ничего не развалится.
То есть тут скорее такой...
Неожиданный эффект, может быть, когда мы это отправим на прот, и у нас по той или иной причине не подтянется там.
Опечатались где-то, да?
Возможно, в коде где-то опечатались.
И одно дело, когда мы не сможем откатить новый функционал, другое дело, когда мы не сможем включить его.
Пусть уж лучше мы его включить не сможем, чем он выкатится, и будет неконтролируемо там работать, неконтролируемо.
Далее нужно найти и описать потенциально непонятные места.
Я очень часто в своем ревью могу зайти и сказать, ребята, вот тут вот ничего не понятно, вот тут я поставил проверку наив больше 7, потому что внешняя система так возвращает, но с этим пока ничего не поделать, да, у них там баг, ну, например.
Или во внешней системе есть баг, да, вот на JavaScript если кто-то работает, там очень часто все обмазывают тайм-аутами, да, в любой непонятной ситуации ставишь сет тайм-аут, оно работает.
И вот иногда бывает такое, что действительно я ставлю setTimeout 30, да, например.
Я понимаю, что ко мне придут.
Я написал, ребят, тут вот любая используется, у нее есть баг, вот это ищу, да у них там 20 стоит.
Я поставил 30, чтобы они точно успели отработать, например.
Ну и добавить тесты.
Хорошее было замечание про тесты.
Блин, спасает в миллионе случаев.
Очень часто бывает такое, что я смотрю код и думаю, так...
Может развалиться в каких-то ситуациях.
И я говорил, что тестами можно покрыть ситуации, которые тяжело воспроизвести.
У меня бывает такое, что я смотрю код, и я хочу написать, чувак, слушай, развалится вот в такой конфигурации, развалится.
Я понимаю, что человеку, чтобы это проверить, нужно будет потратить тюрьму времени.
Особенно, если на это нет тестов.
И иногда поэтому я вытягиваю код себе и пытаюсь это воспроизвести сам, и не заставляю человека делать это.
Ну и выводы, собственно, давайте подведем выводы, да, что код-ревью это показатель, на самом деле, зрелости процесса и команды, да, если у вас код-ревью спотыкается, хромает и падает, ну, тут не в код-ревью, скорее всего, дело, да, то есть это один из простейших инструментов.
Во-первых, это один инструмент, да, то есть он работает с синергией с другими, вот я сказал, планирование, ну, в частности, daily, да, я упоминал больше всего, и это простой инструмент, то есть если у команды не получается, блин, сесть, посмотреть код и запрубить его, то как бы в состоянии ли вы вообще ваш продукт, да, дотолкнуть там до проды, сделать что-то хорошее.
И это не только про код.
Не только качество кода, там нужно посмотреть иногда и с позиции функционала.
Код-ревью это не после разработки, он должен начинаться заранее, к нему нужно готовиться.
Причем это не ответственность одного человека, готовиться нужно и тому, кто пишет код.
Ну и код-ревью помогает делиться знаниями и влиять на итоговое решение.
Но и это еще не все, на самом деле.
Небольшой чек-лист.
Типа, как убедиться, что ваше код-ревью хорошее.
Во-первых, нет задач, которые идут в код-ревью.
Не должна быть такого, да, там, ни одна строка, ни две, ни три.
Неважно.
Есть код, давай, есть там одна строка, тем более, да, я, значит, быстро ее подвину, и времени мне это не займет.
Задачи не должны скапливаться вроде в код-ревью, очевидно.
Не должно такого быть давления, там, прэша, да, от, не знаю, тимлида, например.
У меня был такой кейс, когда тимлид, ну, как-то форсил, чтобы ребята быстрее, там, строки горят.
Ну, не должно быть такого.
Мы не просто так сидим, мы действительно пытаемся сделать хорошо.
Замечания с ревью должны решаться обязательно.
Ну, желательно, чтобы все члены команды участвовали.
Бывает такое, что тут один участвует, да, и в итоге он такой бас-фактор возрастает, да, потому что он знает все, а другие как бы ничего не знают.
Общение должно быть экологично, да, то есть какие-то там переходы на личности, очевидно, ну, бессмысленно, да, я не скажу, типа, блин, ты там плохой человек, я могу сказать, что ты плохой разработчик, может быть, ну и так я, скорее всего, не скажу, я скажу, что вот этот код не очень удачный, да, например.
Приоритету ревью должен быть выше, чем разработки.
Если я вижу две задачи, при прочих равных я все-таки посмотрю ревью, да, и помогу хоть что-то, ну, грубо говоря, довести до проду, нежели я пойду что-то делать свое.
Ну, и не должно быть много ритуалов, да, то есть у нас был кейс, когда нужно было там галку проставить, задачу там подвинуть, завести, там затрекать время, там куча всего.
Такого быть не должно.
Более того, должна быть гибкость.
Ко мне недавно пришел тестировщик на школу инженера, да, и говорит, слушай, там у тебя ревью висит, там одна строчка, давай я его сам опробую.
Я такой, блин, да, конечно, без проблем, типа, да.
Это у нас нигде прописано не было, но мы вот в моменте решили, что это сработает, потому что действительно там строка поменялась.
При этом, если бы там что-то было сложное, мне нету цели протолкнуть быстрее ревью, я бы сказал, братан, нет, давай не надо, давай вот там коллега посмотрит и из разработчиков кто-нибудь, и он точно убедится.
С чего начать?
Наверняка у многих из вас есть задачи, которые вы сейчас делаете, которые готовитесь отправить на ревью.
Я рекомендую все-таки посмотреть их в интерфейсе GitLab и GitHub и понять, действительно оно готово или нет, ревью, объективно.
Нет такого, что строки поехали, опечатки, какие-то консольные выводы достались и так далее.
Написаны ли там тесты, например, чтобы убедиться, что это действительно работает.
Если вы хотите кого-то ревью, ведь, блин,
Поревьюйте нормально, да, то есть не просто галку поставьте, а посмотрите.
Причем в ревью, на самом деле, знаете, что интересно, да, у нас бывает, что не обязательно искать проблемы.
У нас бывает, кто-то зайдет и напишет, блин, чувак, очень круто, да, я вот в это место в прошлый раз потратил 3 часа, ничего не смог сделать, хорошо, что ты его зарифачил и поправил.
Очень круто.
Это тоже, на самом деле, мотивирует, когда ты делаешь что-то хорошее, да, там какие-то практики, и тебе это, ну, как бы, это замечает тоже.
Это все должно быть обязательно в Task Manager.
Почему в Task Manager?
В Task Tracker, наверное, да?
В Task Tracker должно быть.
То есть бывает такое, что есть статус Dev, и потом сразу тест.
И мы как бы договариваемся, что между ними ревью.
Да нет, должна быть задача явно столбец отдельно, ready for review, все должно быть прозрачно.
Ну и договориться, что ревью приоритетней разработки.
То есть с этим нужно жить.
Спасибо за внимание.
Я очень рад.
Спасибо большое, Олег, за доклад.
Я очень быстро позволю себе кое-что дополнить.
Во-первых, я уже, наверное, лет 5 или 6 коллегам всем говорю, что мы пишем человекочитаемый исходный код.
Это способ трансляции наших мыслей для машины.
Если это не читается в переводе на русский как законченная, корректная семантическая конструкция, скорее всего, это и работать будет плохо.
Насчет нескольких строк есть один большой подвох.
Зачастую 5 строк ревьюить сложнее, чем 50.
Это когнитивное искажение.
Олег приготовил награду за лучший вопрос.
Кто чувствует силу?
А можно сидя?
Да, конечно.
Спасибо, было очень интересно слушать.
Вы сказали, что у вас в ревью может находиться до 4 дней.
Вам не кажется, что это неразумный срок?
Я сказал, что у нас были такие случаи, когда ревью могло так висеть.
Возможно, я там оговорился.
В целом, это скорее к тому, что если задача в ревью висит несколько дней, это уже показатель, что что-то пошло не так.
Такого быть не должно.
Поэтому задача в идеале попала в ревью, ну и там на следующий день или в этот же день улетела дальше, собственно.
А у вас не ограничен срок, что на ревью у тебя максимум 4 часа нет аппрува, оно автоматически может вмешаться?
Нет, нет.
Ну это кажется тоже немножко скорее как костыль, который подпирает.
Мы не заревьюли все равно.
То есть он автоматом улетит, как бы аппрув.
Ну как будто бы это скорее деструктивное решение.
Окей, у тебя ход фикс, у тебя на проде проблема.
Не упал, но там серьезная проблема.
На проде обычно мы в моменте решаем.
Вот мы не то, что там один человек сел и порешал.
Скорее всего мы созвонимся там где-то там, я не знаю, в каком-то голосовом чате будем сидеть вместе.
И мы вместе вот там решим, что сделать, поправим и запруем тут же.
Не то, что я такой поправил, да, и такой, ребята, типа, я, во-первых, не смогу даже сам approve поставить, потому что у меня нет прав на это.
То есть у нас настроен так, что должен approve другой человек ставить обязательно.
А в Prod'е чаще всего проблема потому, что предыдущий hotfix пролетел автоматически, к сожалению.
Кстати, да, я могу, это прям очень в точку, потому что у нас был такой кейс, когда у нас друг за другом три hotfix'а поехали вот так вот.
Один сломал один, поправил что-то, но сломал там другой кейс вот так вот.
Не скажу, что мы бы это 100% обнаружили на ревью, но, по крайней мере, это случилось без ревью у нас.
Ваш коллега отправил маленький кусочек кода, пока у вас компьютер не работал, а у другого коллеги на ваших изменениях, ну, следующая задача базируется на этих изменениях.
То есть без этого изменения маленького у следующего коллеги не получит нормальный функционал реализовать, либо он будет с ошибкой.
Что ему делать?
Сидеть ждать?
Нет, обычно мы стараемся планировать задачи так, чтобы у нас не было такого, что код мой основан на коде еще не закомиченном.
Скорее всего, это какая-то исключительная ситуация.
Ну, может быть такое, что вот нам прям, не знаю, сроки горят.
Ну, даже не сроки горят, а какой-то внешний закон какой-то вышел.
Не то, что нам Team Lead сказал, завтра выпускаем версию.
Нет, а там закон вышел, что там с завтрашнего дня нужно что-то по-другому считать.
То есть какое-то действительно ограничение.
И в этом случае мы можем взять две задачи параллельно, что одна на другой основана.
Но это скорее исключение.
В данном конкретном случае у меня еще была перестраховка, потому что я покрыл тестами это.
Поэтому я знаю, что там от права коллеги глобально ничего не развалится.
Подгорало хоть раз на ревью у вас?
Часто.
Как решали?
Как успокоиться в моменте?
Обычно я иду к Тиму Люду, говорю, слушай, ну что-то у меня этот не нравится, это подгорает, давай что-то с этим делать.
Я часто могу пойти, вот я недавно говорил, да, я принес...
Код сказал, ребят, давайте так не будем делать, ну, типа, давайте делать так, как вот у меня, потому что я в коде разбирался очень долго.
У меня бывает такое, как бы, какой показатель, да, я вот сел писать фичу какую-то, я понимаю, что фича простая, там, отсюда взять JSON, переложить сюда, но я трачу, ну, это там три дня, например, да, я понимаю, что я большую часть времени потратил на то, чтобы разобраться, что происходит в коде.
А еще бывает такое, ну это скорее не к ревью, да, а именно к разработке.
А вот на ревью прям такого подгорает, что было один раз, когда я сейчас триггер на ноги, да, когда чувак взял, вместо того, чтобы вызвать конструктора в простом месте, написал маппинг и использовал автомаппер, да, и с одним полем.
То есть вот у него есть свойство, да, он взял его смаппил, короче, точнее, есть перемена, он взял ее смаппил, вместо того, чтобы вызвать конструктора с одним параметром, он ее через маппер пропустил.
Я пришел, говорю, блин, чувак, зачем?
Он такой, так удобней.
Аргументация.
Я такой говорю, чем удобней?
Он такой, ну мы так всегда делаем.
Я такой говорю, блин, давай так не делать, давай нормально переложим и сделаем хорошо.
Вот такое бывает иногда.
У нас нет кнопки заблокировать, но пока никто не поставит approve, оно не пойдет дальше.
Ну, в этом случае, скорее, это тоже деструктивное какое-то поведение, нужно разбираться.
Я, возможно, пойду к коллеге и спрошу, блин, так, а, у нас еще нужно, чтобы все треды были... Ну, то есть, гипотетически такое может быть, да?
То есть, гипотетически я могу подойти к чуваку и сказать, там, не смотри и поставь мне, да?
То есть, возможно, это сделать, я не знаю.
То есть, на 100% мы никак сегодня не защитимся.
Тут много на взаимоотношениях, на коммуникации внутри команды играет.
То есть, конечно, есть способ...
Там доставить плохой код до проду.
Типа 100% есть такой способ.
Тут вопрос в том, что будем мы целенаправленно это делать, мой коллега или я, или не будем.
Спасибо за доклад.
Артем, Аптека.ру.
Вопрос такой полухоливарный.
Многократно раз ты упоминал, что у тебя идет код, ревью, тестировщики.
Нюанс в том, что тестировщики дешевле разработчиков.
И когда у нас прошло ревью, дошло до теста, тестеры нашли багу, это возвращается на разработку, и получается, ревьюер делает двойную работу, и мы платим два раза разработчику.
Почему бы не поменять местами?
Почему ревью не делать после теста?
Опять же, тестировщик, если два раза протестит, это будет дешевле с финансовой точки зрения, чем разработчик два раза проревьюет.
Дело в том, что любая правка review, она в любом случае, ну, в большинстве случаев, во-первых, она может заставить тестировщика пересматривать все, и, возможно, это будет дороже.
Сейчас у нас мы заставляем reviewer дважды переревьюивать в случае нахождения бага, а если мы применяем их местами, то у нас тестировщик будет дважды перетестировать, если мы на review что-то исправили.
Но при этом, если мы прошли тестирование, все баги, по идее, ну, большинство багов очевидных выявлено, скорее всего, и на review будет намного меньше находиться.
Не соглашусь, потому что часто бывают концептуальные проблемы на уровне кода, что давайте делать не так, а давайте сделать по-другому.
Я могу всегда захардкодить тысячу строк, которые невозможно будет поддерживать, но оно будет работать.
И оно тестирование пройдет.
А потом я скажу, давай поправим, он переделает, и все равно тестировщику нужно будет заново этот цикл.
А еще будут баги, которые тестировщик найдет, их нужно будет править.
А ревьюер их не увидит, потому что до него не дойдут эти баги.
Ну, они дойдут, в любом случае, до него итоговый код дойдет.
И когда он скажет, итоговый код поменяли, у нас цикл замкнется опять с тестирования начнется.
То есть, кажется, в моменте, пока код еще... Смотри, когда я делаю код ревью, я смотрю не так, как тестировщик, потому что тестировщик там смотрит на все сразу, и не так, как разработчик, который пишет.
Я смотрю некий гиф.
И вот в моменте, кажется, мне дешевле его тут же поправить, нежели сначала протестировать, а потом поправить.
Ну, типа...
И я понял идею, но как будто бы, если мы действительно будем делать так, у нас время только вырастет еще сильнее.
То есть понятно, когда ты захароткодил много, некрасивый код, но это разовая операция, то есть мы опять же джумов наняли, напинали, они выучились, и все мы так или иначе пишем хороший код, стараемся, да?
Мы же все любим свою работу, и мы же говорим о том, что код в принципе каждый старается написать хороший, и вот этих проблем глобальных, ну их не должно быть, это разовый все-таки, это исключение из правила, чем основа.
Смотри, если мы просто отдаем в тестирование сразу задачу, у нас возникает еще такой момент, что в этот момент разработчик переключился на что-то другое.
К нему приходит этот в тестирование баг, он переключается обратно.
То есть у него все равно время уходит.
И причем это время может быть больше, чем если он единоразово придет, поправит все замечания с ревью и сразу отдаст.
То есть каждый баг, он как бы отъедает время от задачи, которую разработчик уже делает, потому что он уже эту запушил и пошел следующей заниматься.
И вот эти переключения занимают очень много времени.
Поэтому
На тестировании до ревью, в любом случае, будет больше багов, чем на тестировании после ревью.
И если посчитать, то, скорее всего, нам выгодней, я не знаю, финансово, насколько я могу подтвердить, в большинстве случаев, я думаю, что выгодней потратить там время разработчика, там, не знаю, полчаса.
На самом деле, если ревью длится 8 часов или там день целый, ну это тоже, ну это, конечно, тоже неэффективно.
То есть ревью должно достаточно быстро проходить.
Вы знаете, возможно, те тестировщики, которые сильно менее квалифицированы, чем разработчики, то есть тестировщики, которые занимаются машинерией по большому счету, то есть машинным тестированием, не думая о том, как на это смотрит пользователь, повлияет ли это на этот сценарий и так далее, таких тестировщиков проще заменить автотестами, это будет еще дешевле и нанять QA.
Спасибо большое.
Давайте мы переместимся в дискуссионную зону вместе с Олегом, и там его приз найдет.
Спасибо всем.
Похожие видео: Олег Сафонов

Константин Владимиров — Каша из топора: модули в C++, проблемы и решения

Анатолий Кулаков — Build as Code

Марк Шевченко — Воркшоп «Практические задачи решаем функционально» (Часть 1)

Марк Шевченко — Воркшоп «Практические задачи решаем функционально» (Часть 2)

Дмитрий Сошников — Введение в теорию функционального программирования с примерами на F#

