Русский
Русский
English
Статистика
Реклама

Код-ревью

Хороший, плохой, злой комментарий

03.04.2021 08:20:33 | Автор: admin

Зачем нужны комментарии, правда ли, что хороший код можно прочитать без них и как перфекционизм замедляет разработку в 4 раза. Новичкам, командам, профи.

"Хороший, плохой, злой", 1966 г."Хороший, плохой, злой", 1966 г.

Интуитивное знакомство

с комментариями как и в любых отношениях создаёт скрытые проблемы. Со stackoverflow или от своего творческого начала мы неосознанно формируем манеру комментирования. Кто-то излишне подробную, кто-то с юморком, а кто-то вообще пишет "без комментариев" и через пол года даже не пытается понять, как работает его код.

П.С. Если ты тот человек, который узнал о комментариях в коде из книги, дай знак) Если тебе сразу нужны ответы они в конце.

В маленькой веб-студии или в соло-проектах мы сами себе указ и можем писать там хоть анекдоты, вопрос о "технологии" комментирования возникает при переходе к командной разработке, особенно если есть сопровождение продукта. Чтение чужого кода становится не наказанием, а ежедневным занятием... Но сначала и наказанием, пока не наступает момент Х, момент обратиться за знанием.

Особенно важно, когда этот момент наступает для целой команды или даже отдела. Ни в коем случае нельзя его упускать это шанс дружно изменить ситуацию к лучшему, другой момент такого "вскипания" в маленьком проекте может и не наступить, т.к. код копится, как и отчаяние.

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

http://personeltest.ru/aways/shoot-photo.com/desktop-wallpaper-zen.htmlhttps://shoot-photo.com/desktop-wallpaper-zen.html

Совершенный код

это перевод названия книги*. Из 950 страниц осмысленного текста, популярность обрела одна фраза: "хороший код является самодокументированным". А к ней пояснения в виде: "хорошему коду не нужны комментарии", "называй переменные и методы понятно, тогда комментарии не нужны".

Круто быть столь категоричным, а главное просто. Но к чему это приводит? Часть превращает комментарии в искусство, стремится к идеалу, размышляет по 20 минут над названиями. Другая часть формирует чек-листы, правила оформления, требует соблюдения шаблонов. И то, и другое полезно, вот только они забывают о "смысле жизни" комментариев.

Из возможных 20% времени программирования, которые есть у соло-разработчика, в команде остаётся всего 5.

Творчество и точность это очень красиво, но когда помогает достичь цель. Понятные имена, комментарии и другие инструменты нужны чтобы снизить неопределенность.

В примере выше, 20% времени уделяется программированию и 80% решению того, что и как программировать, изучению контекста, ТЗ. Это бОльшая часть работы по умолчанию. И чем больше проект, тем ближе к 100% можно "страдать" / "ничего не делать" (нужное подчеркнуть). Чтение даже идеального кода == не программирование.

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

Всё остальное лишь форма. Помните о смысле, тогда она будет руслом, а не плотиной из ограничений и бюрократии.

*Code Complete, Стив Макконнелл, 1993. Для сохранения смысла точнее будет перевести как "Завершение кода" или "Завершенный код". Комментарии то, что делает код завершенным, готовым к "эксплуатированию" пользователями, разработчиками, а также обеспечивает комфорт его доработок.

Ответы

П.С. По оформлению кода и комментариев есть много руководств, вместо очередного, здесь тезисы для размышлений.

  1. Существуют разные варианты "использования" кода и комментарии для них отличаются.

    1. Подключение по типу "чёрный ящик" пользователя интересует только что на входе/выходе. Обычно в виде шапки в файле класса и около методов. Хорошо указывать в шапке дату актуализации, перечень методов (содержание). Идеальное использование: за минуту прочитал и пользуешься.

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

    3. Разработка комментарии в коде, короткие, описывающие этапы, группы/блоки операций, а так же комментарии вида TODO (сделать), FIX (исправить) и т.д. Они не дублируют код, а иллюстрируют, как краткое содержание параграфов. В идеале: посмотрел шапку, пробежался по описаниям и нашел нужное место за пару минут работаешь.

  2. Неопределенность и навигация. Можно прочитать 10 000 строк идеального кода, понять его и исправить 3 строчки. Хорошие комментарии те, что позволят сделать это "сразу", а не к обеду. Плюсом будет документирование архитектуры (хотя бы), но это другая история.

  3. Красота единообразие не только красиво, но и понятно. Привычное быстрее воспринимается. Определите удобные для себя правила оформления в команде.

  4. Шаблоны упрощают жизнь, но без фанатизма, у функций бывают необязательные параметры.

  5. Незавершенность буквально. Пока код используется - он не завершен. Не относитесь к нему, как к памятнику, "камню, из которого убрали всё лишнее". Искусственные блоки для кода, лишние строки для визуального отделения, рабочие комментарии, идеи... Всё это может быть, если оно соответствует духу вашей команды.

На этом у меня всё, успехов!

П.С. Буду рад дополнить статью идеями из... комментариев.

Подробнее..

Разработка интерфейса Драйва отзапуска стартапа доглубокого анализа UI. Доклад Яндекса

07.11.2020 12:07:53 | Автор: admin
Первая версия сервиса Яндекс.Драйв была запущена за два месяца после начала разработки, а затем практики пришлось постепенно менять. Руководитель мобильной разработки Драйва Кирилл Кожухар обсудил все шаги при создании и проработке дизайна, поделился своим видением того, как приложение должно эволюционировать, и проанализировал, как менялся UI.

Всем привет, меня зовут Кирилл, я занимаюсь iOS-версией Яндекс.Драйва. Мы решили подготовить не совсем технический доклад, обсудить то, как развивается проект на самых ранних этапах, когда только все начинается, закладывается. Это так называемый этап MVP.

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

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

Стоит рассказать для тех, кто не в курсе, что такое Яндекс.Драйв. Это такой сервис каршеринга, который сейчас работает в трех городах России в Москве, Санкт-Петербурге и Казани. (...)



Россия сейчас является самым быстрорастущим рынком каршеринга в мире. На Москву приходится порядка 77% всего российского автопарка. То есть 77% автомобилей каршеринга сконцентрировано в России. И чтобы построить такой сервис, требуется очень много времени и огромное количество ресурсов, как человеческих, так и финансовых.



У нас ни того, ни другого, ни третьего не было. Мы запустили весь сервис за два месяца с нуля. Стоит сказать, что наша команда изначально состояла из двух частей. Первая часть офлайн. В нее входили люди, которые отвечали за обслуживание автопарка, занимались мойкой, заправкой, ремонтом машин, выводом машин на линию. Сюда же входили люди, которые отвечали за саппорт решали спорные ситуации у клиентов.

Саппорт это, на самом деле, одна из самых важных частей нашего сервиса, потому что люди непосредственно взаимодействуют с офлайновыми объектами, с машинами, и для них очень важно куда-то обратиться в случае чего.

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

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



В любую команду, которая запускает стартап, входит product owner. Он отвечает за весь стартап, отвечает перед инвесторами либо перед материнской компанией, олицетворяет стартап и несет ответственность. У него есть помощники, менеджеры. В эту категорию входят технические и не технические менеджеры, продуктовые менеджеры и так далее. Это люди, которые помогают продакту при планировании, при разработке фич.

И сама разработка. Тут все понятно, это люди, которые непосредственно реализовывают все на практике и гарантируют, что все будет работать. У команды, которая онлайн, как правило, вырабатывается классический подход. Мы так его называем, это подход к разработке продукта, который практикуется, наверное, в процентах 90 всех компаний.



Это примерная схема, не надо воспринимать ее строго. Product owner все планирует и отвечает за продукт. Помощники, то есть менеджеры, разрабатывают фичи, придумывают, как это будет работать, занимаются планированием. И есть сама мобильная разработка.

Процесс происходит так: product owner общается с менеджерами, обсуждает что-то, занимается долгосрочным и краткосрочным планированием. После этого каждый менеджер берет себе по кусочку фичи, спускается на уровень ниже и непосредственно назначает встречи, выполняет планирование, общается со всеми, кто непосредственно реализовывает фичу и доводит ее до продакшена. А потом ребята из разработки делают свою магию и выпускают приложение или фичу в релиз.

У этой системы, наверное, все хорошо, раз она применяется в 90% стартапов и сервисов. Но нам примерно полтора года назад, когда мы запускались, это не подходило. У нас было крайне мало времени, два месяца, и 18 человек в команде. Из них пять человек отвечали за разработку. Нам нужно было запустить сервис с нуля.

Мы поняли, что нужно как-то это оптимизировать. У нас на старте не было менеджеров как таковых. Product owner взаимодействовал сразу с мобильной разработкой, с дизайном, с серверной разработкой. Таким образом мы экономили на общении, это нам помогало.

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



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

Из этого вытекает, что ваша успеваемость и синхронность должна быть абсолютно такой же, как у всех членов команды. Вы должны максимально плотно работать со всеми членами команды. Вы не можете просто отгородиться от них и сказать сейчас я тут все сделаю, выпущу что-то, и все. Такого никогда не будет, просто потому что не будет.

Из этого вытекает ответственность. На самом старте мы договорились, что ответственность за продукт мы будем между всеми членами команды. Многим это не подходит. Как правило, человек приходит в команду и говорит у меня есть свой маленький огород, фронт ответственности, и я в рамках этой ответственности развиваюсь.

В нашей команде было так, что вся ответственность разделялась между членами команды. Если что-то не работало, виноваты были все.

Из этого следует, что у нас были определенные изменения в планировании не было долгосрочного планирования.



Как правило, у команды есть релизный цикл, и чем больше команда, тем этот релизный цикл больше, гораздо больше. Есть команды, у которых релизный цикл два месяца. Они раз в два месяца выпускают обновление, пушат его в стор, и все счастливы.

У нас релизный цикл был дней пять. Мы выпускали в течение пяти дней обновление приложение для магазина. Через пять дней после этого мы опять выпускали обновление. Это позволило нам довольно часто пушить обновление и очень сильно менять приложение.

Из этого следует, что близкое взаимодействие в команде тоже играло важную роль. Нельзя было сказать я пошел, написал тикет в Трекер, мне не ответили, и я как бы забил. Такой ситуации не было, потому что если вам что-то нужно, вы как член команды должны былитупо дойти до этого человека и спросить: почему ты мне не предоставил дизайн? Или: мне нужно, чтобы ты нарисовал то-то.

Это порождает прототипирование. Оно играло очень важную роль, потому что, как я уже сказал, у нас было маленькое количество людей, один Андроид-разработчик и два iOS-разработчика. Андроидом в тот момент занимался я, а один человек из iOS-разработки занимался прототипированием.

То есть мы решили сделать такой подход, когда человек из команды iOS очень плотно взаимодействует с командой дизайна и постоянно создаются прототипы. После этого все отдается в разработку. Это было важным элементом, который позволял нам очень быстро что-то проверять на практике.

Все это повлияло на то, как мы разрабатывали одну фичу под обе платформы.



Изначально мы хотели сделать так, чтобы разработка фич на обеих платформах была параллельной.

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

После того, как мы отдаем это в iOS-разработку, фича реализовывается и отдается в Q&A. Параллельно начинается ее разработка для Андроида. Когда Q&A все протестировали на iOS, они начинают тестировать то, что сделали Андроид-разработчики. Таким образом мы оптимизировали время, это позволило нам не простаивать в плане тестирования.

Когда все завершилось, все идет в релиз. Такая схема обязывает очень тщательно следить за тем, какие изменения вы будете вносить в приложение, как вы выбираете, что сделать. Мы с самого начала решили, что все наши изменения в приложении должны быть продиктованы внешним миром. Все, что мы будем делать, должно исходить из клиентской аудитории. Мы собирали фидбек и смотрели, что происходит.



Либо это должно быть порождено самой командой. Предположим, мы выпустили фичу, сами понимаем, что эта фича не работает. После этого нам необходимо выпустить обновление. Делать так нам позволил наш релизный цикл очень последовательный и очень частый, билды были очень плотными и очень частыми. А наладить такой плотный цикл мы, в свою очередь, смогли благодаря изначально крайне маленькой, но постоянно растущей команде.

Все изменения, которые мы вносили, были свободными. Есть два типа команд, которые что-то разрабатывают.

Первая команда она бывает в основном в стартапах это когда вы собираетесь группой, закрываетесь в офисе, что-то придумываете, исследуете, рисуете и после этого выпускаете готовый продукт.

Вторая команда это когда вы точно так же собираетесь, выпускаете не совсем готовый продукт, смотрите, как на этот продукт отреагирует аудитория, и после этого выпускаете другой продукт. Затем опять смотрите на реакцию аудитории и выпускаете третий продукт. Таким образом вы последовательно прощупываете аудиторию.

Мы выбрали второй подход. Под неготовым продуктом стоит понимать вполне готовый, просто он проверял одну из теорий UI/UX или продуктовую. Таким образом мы могли на практике прощупывать идеи. Это позволяло нам выпускать продукты, довольно-таки спорные с точки зрения UI. Тут уже можно перейти к мобильному дизайну, к мобильному UI, который у нас был.



Все приложения, в основе которых лежит карта, практически одинаковые: карта занимает всю плоскость экрана. На ней есть объекты, на которые можно нажимать. Вы нажимаете, и открывается карточка с информацией об этом объекте. Вы как-то взаимодействуете с карточкой, после этого интерфейс преобразуется, чтобы вы могли взаимодействовать глубже.

Это самая первая версия дизайна, которую мы выпустили в продакшен. Просто ужасно, если сейчас посмотреть. Тогда нас это это устраивало: как уже сказал, прошло всего два месяца, мы были заняты решением проблем. Главное, что мы выпустили приложение и все замечательно, все работало, нажималось. Но как только стали появляться первые проблемы, мы поняли, что очень сильно ошиблись с UI. Как только стали получать первый фидбек, пришло осознание проблем. И проблемы, которые были у этого UI, были довольно-таки простые.

Первая проблема акцент пользователя.

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



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

На втором экране тоже слишком много синего цвета: заголовок, цена, кнопки. Пользователь просто не понимает, что же ему делать на экране, куда ему нажать, чтобы что-то произошло.



Вторая проблема масштабируемость. Слишком мало информации можно поместить на экране. Интерфейс в принципе удовлетворяет твоим текщуим потребностям, но если нужно его расширить, добавить что-то, то необходимо его усложнить, и это плохо.



Из этого вытекает еще одна проблема информативность. Невозможно слишком много информации поместить в этот интерфейс, не усложнив или кардинально не сменив его.



Последняя проблема последовательность. Пользователь, находясь на этом экране и на других также, не понимал, что ему нужно сделать. Было слишком много путей развития User flow. Это нужно было менять, преобразовывать и устранять. Решения всего этого довольно-таки банальны, мы не стали придумывать ничего нового.



Первое мы стали концентрировать внимание пользователя на том, что важно. Как правило, в мобильном дизайне это делается через выделение объектов цветом, добавление теней, бордеров, либо за счет выделения на фоне остальных элементов. Грубо говоря, все остальные элементы делаются менее заметными, чем самый главный элемент.

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

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

Морфирование интерфейса появилось совсем недавно. Это когда вы пытаетесь перевести свой интерфейс из одного состояния в другое, но переводите его не моментально, не через какой-нибудь fade in/fade out, а делаете это выделением общих элементов и переносом их из одного состояния в другое.

В Android для этого есть transition API. В iOS такого API нет, но Apple сами используют этот подход в приложении Photos. Они используют scaling: когда вы переходите от года к месяцу, от месяца к неделе и от недели ко дню, то весь интерфейс скейлится. И это было довольно забавно поначалу. Но потом все поняли, что это работает и этим удобно пользоваться. Такой же подход мы попытались использовать у себя.

Четвертое контекст действий. Это когда вы разрабатываете UI, не просто прорабатывая экраны, а решаете проблемы. Вы выделяете какие-то user flow, своеобразные user-сценарии, которые позволяют вам решать какую-то проблему.

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

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



Рассмотрим первый пример. Как я уже сказал, на этом экране все очень плохо. С точки зрения цвета экран выглядит ужасно, слишком много синего. Самое простое, что здесь можно сделать, убрать акцент с меню. Тогда концентрация пользователя больше будет сосредоточена на том, что происходит на карте.

Естественно, этот интерфейс не позволяет вам добавлять слишком много объектов на карту: если у вас больше 100 машин на карте, все превращается в кашу. Мы решили разбить уровень зума на несколько элементов, частей.

Когда пользователь находится на самом близком зуме, он видит детальное изображение машин и облака над ними, которые показывают какую-то минимальную информацию.

Как только пользователь начинает уменьшать зум, находится на уровне улицы, облака пропадают и остаются только машины. Если он продолжает уменьшать зум, все машины преобразуются в точки, позволяющие оценить скопление машин в той или иной области.

Тут возникает проблема, которая до этого уже была, масштабируемость. Если на карте слишком много объектов, например, 4 тысячи, то уже не понятно, где что находится. Самым простым решением здесь было бы добавить кластеризацию.

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

Первая как отличать кластеры друг от друга? Наверное, нужно добавить в них какой-то индикатор, показывающий, сколько объектов находится в кластере. Это не будет работать, потому что тогда у вас слишком много объектов в кластере, количество просто не будет влезать в габариты кластера.

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



Поэтому мы просто уменьшили сами точечки. Это решило всю проблему. Сейчас этой проблемы нет: да, слишком много объектов на карте, но пользователь может оценить их плотность, и они не так сильно нагружают карту. В таком состоянии карта более разряжена, что позволяет пользователю все равно взаимодействовать с машинами, но при этом нет такой перегруженности самой карты.

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



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

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

Еще одна проблема слишком много информации нужно было поместить на довольно ограниченную плоскость. У нас стали появляться новые модели, новые машины, и пользователи должны были как-то отличать одну модель от другой. Решили мы это тоже банально: добавили стек, в который все складировалось. И выделили тарифы более ярко, чтобы пользователь понимал: есть активный тариф, который он сейчас будет бронировать, а есть не активные, которые сейчас не в его фокусе.

Карусель тарифов решила проблему, но не полностью. И информация о тарифах скидка, информация о машине также решила проблему, которая перед нами стояла. Теперь пользователь мог отличать машины друг от друга, но не до конца.

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

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

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

Это решило проблему. Мы увеличили конверсию в заказ, поскольку наша теория о том, что пользователи очень часто выбирают машину, основываясь на цене, была верной. Таким образом мы проверили ее на практике.

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

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



Мы решили, что наш язык с самого начала должен быть неформальным. Все, что мы транслируем наружу, должно быть на простом, максимально доступном и понятном языке. Это сработало. Когда пользователь начинал писать что-то негативное в саппорт, этот язык подкупал, пользователь понимал, что он общается не с какой-то мегакорпорацией или с высокомерными людьми, а абсолютно с такими же людьми, у которых такие же проблемы и которые понимают боль человека.

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

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

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



Именно поэтому мы добавляли всевозможные пасхалки в приложение. Например, добавляя слайды в поездку, мы долго спорили, как пользователь будет себя с ними вести. И не пришли к единому мнению. Поняли, что нужно просто проверить. При нажатии на слайд мы двигали его, и если человек слишком часто начинал на него нажимать, то за слайдом появлялся текст Молодец!.

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

Мы не придумали, как называть пользователей корпоративных тарифов. И просто решили, что это будет для тех, кто в теме. При нажатии на эту кнопку появлялось сообщение: Теперь ты в теме. Если ты в теме, ты понимаешь, что происходит. Если ты не в теме, то тебе это не нужно. Нажал ну и ладно, молодец, все.

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

Мы ничего не придумали и просто написали максимально официальным языком, как это делают в объявлениях: Уважаемые краткосрочные арендаторы автомобилей! Раздел будет закрыт по усмотрению администрации. И подпись Администрация. Мы еще хотели шрифт Comic Sans добавить, но это было бы слишком.



Что из всего этого получилось? Когда вы успешны как стартап либо как сервис, обычно вас ждет дальнейшее развитие и неминуемый рост. Этот рост повлечет за собой изменения внутри. Команда будет расти, интерфейс мобильного приложения будет усложняться, объектов на карте будет больше, машин будет больше.

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

У нас примерно в течение года после старта вообще не было код-ревью. Потому что не было проблем, которые это код-ревью могло решить. Вот, собственно, и всё.
Подробнее..

Энтерпрайз, который выжил. Доклад в Яндексе

04.02.2021 12:07:48 | Автор: admin
Мы часто задумываемся о том, что нужно изменить, чтобы наша жизнь стала лучше. Но меняться должны не только мы, но и компании, в которых мы работаем. И мы сами можем принимать непосредственное участие в этих положительных изменениях. Вас ждёт маленькая сказка про одну компанию, которая смогла стать лучше. И, конечно же, большие выводы.

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



Присказка


Давным-давно я был на одной замечательной конференции. Прекрасная конференция, к сожалению, больше не проводится. Был на ней спикер, который рассказал, как он пришел в новую компанию. И эта картина мне настолько в голову запала.



Итак, приходит он в новую компанию и видит, что на стене логотип компании, на котором новогодние украшения. На дворе 2 августа. Рядом кто-то заваривает Доширак. И в целом атмосфера запустения и нежелания что-то делать дальше.

А пришел он из другой компании, которая была весьма успешной. И очень ему назад захотелось. Подошел он к своему новому начальнику и говорит: Отпусти ты меня домой? А тот ему отвечает: Ты сюда пришел, не чтобы жаловаться, а чтобы всё изменить.

Сказка


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

Мечтал туда попасть и вдруг попал. Это и прекрасный большой офис в городе, прямо в центре города. Всё отлично, кофепоинт, все плюшки, всё, что надо.



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

Повели его в кабинет. А кабинет находился не на том этаже, где он проходил собеседование. Зашел он в кабинет кабинет, полный народу. И в углу стол стоит, который ему выделили. Ладно, много людей, не так красиво, как было в стартапе, но ничего, с этим тоже справимся, подумал Вася и сел за свой стол. Стол был маленький, настолько маленький, что монитор Васи стоял на столе соседа, а монитор соседа стоял на столе Васи, а иначе не помещалось. Ну ничего, с этим тоже можно справиться, подумал Вася и включил ноутбук.

А ноутбук был бывалый, на Windows, неубиваемый. Просто прекрасный, но на Windows. В те годы знаете, это происходило много лет назад Windows совсем не подходил для веб-разработки. Сейчас с этим уже можно как-то жить, а тогда нет. Ну ничего, виртуалки помогут, справимся, подумал Вася. Мониторчик плохой на ноутбуке, ужасный, маленький, ничего не видно. Ничего, дали внешний монитор, будем жить с ним.

А внешний монитор ему дали просто волшебный. Под каким углом на него посмотришь, такие цвета и видишь. И такой монитор дали верстальщику. Грустно. Чтобы шея не уставала, подложил Вася два томика Страуструпа под монитор. Стало получше. Ладно, справимся, подумал Вася, и, наконец, загрузилась операционная система. Открыл он почту



И увидел, что в этой компании принято писать очень много писем. А еще в этой компании принято проходит код-ревью в почте. Как это? А вот так. Не было у них ни GitLab, ни Bitbucket, ни GitHub. А просто брали они diff и отправляли его по почте. А потом люди начинали кусочки этого diff комментировать. И ладно, если бы комментировали про код. Очень много обсуждений было про то, что поставил пробела два, скобочки не поставил, где надо, точку с запятой забыл. И вот этим была забита почта.

Ну что, страшно? Уже очень страшно, но еще можно жить. И тогда Вася посмотрел в код. А код этот был, как водится у компании, которая не первый год работает, монолитом. А монолит это не только то, что все команды в одном коде работали, но и то, что все было жестко сцеплено. Не понятно, кто за что отвечает, циклические зависимости, все ужасно. Но не так ужасно, как то, что в этом коде еще и Node-модули лежали закоммиченные. А почему?

А потому, что нельзя код наружу отдавать. Нельзя код, который мы пишем, сказали Васе, наружу вынести. Ведь завтра там что-то сломается, а мы релиз не соберем. Однако, подумал Вася. Не знают, что ли, люди о том, что можно локально держать код? И решил поговорить об этом с тимлидом. Пошел он к тимлиду. Был ли тимлид? Был тимлид. Да вот только занимался тимлид тем, что релизы собирал.



И ладно, собирается релиз минут 40, так ведь к нему еще надо заполнить очень много бюрократии. Зайти в Confluence, завести страничку. В страничке расписать по строчкам, что у нас в этом релизе катится, какие задачи в него попали. Создать задачи на QA. Как только QA задачу проверят, создать задачу на админов. Как только админы выкатят написать, что все хорошо. На это убьешь еще час. Два релиза за день, вот и вся работа тимлида. Некогда ему еще чем-то заниматься релизы катить надо.



Понял Вася, что у него два пути: уйти из этой компании или все-таки что-то поменять. Пошел он в магазин и купил себе нормальный монитор, просто чтобы глаза свои пожалеть. Дальше пошел он к админу и попросил ноутбук, хоть какой-то, но не на Windows. Нашли ему старенький MacBook, с этим уже можно было работать. Раз к нему хотя бы в этом по-человечески отнеслись, понял Вася, то можно здесь еще что-то поменять.

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



Код в Bitbucket стал лежать, автоматизацию стал Jenkins делать, все зависимости уехали в Nexus, релизы тоже, появился docker. Тимлид делом занялся. Наконец-то у него появилось время, чтобы взглянуть на своих людей. Он начал проводить встречи one-to-one, понял, где, у кого и что болит. Команды начали переставлять местами. Зарплаты изменились. Все стало гораздо лучше.



Конец ли это сказки? В нашей сказке это конец. Но на самом деле здесь есть еще много чего менять. И, наверное, компания, в которой Вася остался работать, еще многое изменит, станет лучше.

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

Жизнь


Я составил несколько советов, которые мы и рассмотрим по порядку.

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

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

А чтобы им было удобнее работать, нужны микросервисы или микрофронтенды. Вспомним закон Конвея, который говорит, что каждая организация стремится в архитектуре отразить свою структуру. То есть нужно каждой команде дать кусочек кода.



Мы возьмем наш сложный монолит и разобьем его на отдельные части. Каждая команда будет отвечать за свою часть. И им будет проще. Они смогут релизиться, не затрагивая других. Они смогут лучше знать свой код, потому что он не переплетен с чужим кодом. Мы разорвем эти порочные связи, которые были у нас изначально, и у нас наконец-то начнет получаться нечтт более красивое.

Ладно. Что еще можно добавить? Правила ветвления кода. Очень часто мы сталкиваемся с тем, что в компании нет никаких правил. Люди просто создают какие-то ветки, как-то это назад вливают. Главное, что есть одна ветка, с которой они как-то собирают релизы, но никаких правил нет. Поэтому рассмотрим два популярных варианта.



Более старый, но известный GitFlow. Посмотрим, что это.

GitFlow говорит нам, что нужно завести две ветки master и dev и работать с ними. Все разработчики работают с веткой dev. Они не имеют права туда коммитить напрямую. У нас есть только механизм ветвления и пул-реквест.

Итак, мы делаем задачу, ответвляемся от ветки dev, делаем коммиты по нашей задаче. Эта ветка называется feature-ветка, или feature branch. Как только мы решили, что все доделано, тестировщик проверил, мы создаем пул-реквест и вливаемся обратно в ветку dev. Как только мы захотим релизиться, мы с ветки dev срезаемся и получаем релизную ветку.

В этой релизной ветке снова проходит тестирование, и если нашли какие-то проблемы, вносят исправления. Появляется еще коммит в релизной ветке.

Дальше, если все хорошо, мы вливаем релизную ветку в master. Это наша версия 2.0, которую мы и отправляем в продакшен. И одновременно доставляем этот код назад в dev. Теперь наш dev равен мастеру и все могут работать дальше.

Чем хороша эта система? В ней нам всегда понятно, что делать.

Вот очень сложный кейс: нам нужно быстро зарелизить hotfix. Все очень просто.



Мы с ветки master, предыдущей версии, срезаем веточку, которая теперь у нас называется hotfix. Делаем в ней исправления. Вливаем назад в master и релизимся. Это наша версия 1.1, которую мы, конечно же, отправляем в dev. Чтобы наш код доехал в dev, наши релизы тоже должны пересобраться, переподтянуть наш dev. Но в целом все будет хорошо.

Таким образом мы можем очень быстро внести исправления и при этом не подтянуть новый код, который появился в dev с момента прошлого релиза. Мы сделаем только hotfix на конкретное состояние релиза.

Здесь вы можете увидеть, что ветка master становится несколько редуцированной. Мы можем от нее избавиться и превратить наш dev в master. Такая схема и называется GitHub Flow, давайте на нее посмотрим.



Когда уже нет отдельной ветки master, это значит, что наш dev переименовался в master. Получается, что наш релиз идет из dev, но опирается на теги. Мы у каждого релиза проставляем теги и всегда можем срезать hotfix с тега. В остальном это тот же самый GitFlow.

Все это отлично автоматизируется, с этим удобно работать. Вот такие у нас есть правила ветвления кода, если мы хотим избавляться от хаоса.



Что мы еще можем сделать? Добавить обсуждение наших решений. Почему это важно?

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

Хорошо, мы немножко разгребли хаос, который творился у нас в компании. Что дальше? Мы скажем нет рутине и добавим автоматизации. Потому что мы же ленивые люди, любим все автоматизировать. А что можно автоматизировать? Конечно, надо разобраться с код-ревью. Не должно быть споров о том, что здесь пробел не поставили или еще что-то. Код-ревью должно быть автоматизировано. Как это сделать?



Отдадим весь код-стайл линтеру. Пусть линтер проверит. Если все хорошо, только тогда люди будут смотреть в этот код. Пусть заранее исчезнут все спорные вопросы, их решит линтер.

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

И мы не должны разрешать вливать код, который не прошел QA. Почему это важно? Потому что dev должен оставаться рабочим. Если человек вольет туда что-то сломанное, мы можем этого не заметить. Мы можем об этом спорить, но QA нам скажет, что он, как минимум, все кейсы уже проверил и оно работает. Мы должны это понимать, это должно быть не на словах, а запрещено автоматически.

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

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

Но тут же возникают вопросы: а что делать в тех случаях, когда люди просто не смотрят в код-ревью? Вот оно висит и висит целыми днями. Здесь один из вариантов указывать размер нашего пул-реквеста. Срабатывает не всегда, но часто. Потому что если пул-реквест маленький, очень атомарный, то на него стоит размер S. На S и SLA маленький, люди должны быстро реагировать на эти пул-реквесты. Скорее всего, он будет рассмотрен быстрее.

Еще можно добавить к нему огонек, показать, что это hotfix, и люди тоже посмотрят в него еще быстрее. Плюс они будут стараться не делать очень большие пул-реквесты. Тоже помогает.

С код-ревью разобрались. Что мы еще можем сделать лучше? Релизный цикл. Чаще всего он весь хорошо описывается. Это некий пайплайн, который можно автоматизировать целиком.



Как только в dev пришел свежий код, можно срезать релиз. Пусть он будет максимально атомарным. Влили одну фичу отправляем её в релиз, чтобы, если что-то сломалось, мы сразу поняли: эта маленькая фича, влитая час назад, сломала прод. Так бывает, недосмотрели. Но мы знаем, куда нам откатываться и что чинить.

У вас в коде могут быть переводы, их нужно выгружать из какого-то хранилища. Пожалуйста, автоматизируем.

Нужно пройти интеграционное тестирование? Автоматизируем создание задач на интеграционное тестирование. Оно у себя делает ботов, которые разворачивают этот релиз, весь его тестируют, отписываются, что с ним все хорошо, и релиз автоматически едет дальше по пайплайну.

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

Дальше нужно проверить, что за то время, пока мы катили релиз, у нас не влился hotfix. Поэтому ветки надо, например, актуализировать. Это всё тоже нужно сделать автоматом. И если мы всё прошли, то автоматом выкатываемся на прод, потому что, еще раз, любой релиз это набор стандартных операций, если только что-то не пошло не так. Тогда уже нужно подключать человека. Таким образом мы можем релизиться чаще. А чем чаще мы релизимся, тем проще разбирать проблемы.



В этом нам поможет CI/CD. Для реализации есть много разных тулзов, тот же самый Jenkins, TeamCity. TeamCity платный. Но его любят за более человечный интерфейс, чем у Jenkins.

У GitLab есть GitLab CI. Да и, на самом деле, есть множество новых решений, которые тоже можно использовать. Пожалуйста, используйте, никто не запрещает. Здесь, наверное, самые заметные на рынке, но я уже слышу, как кто-то говорит: А как же вот это решение? Оно же самое лучшее! Пожалуйста. Главное, чтобы оно было. Но мы должны и подстелить себе соломки, максимально уменьшить стоимость нашей ошибки, потому что ошибки будут всегда.



Как я уже сказал, чем чаще мы релизимся, тем более атомарны наши релизы, тем легче откатываться, тем легче чинить. Поэтому стараемся релизиться максимально часто.

Релиз всегда должен быть воспроизводимым то есть когда в момент релиза что-то выкачивается из хранилища Node-модулей. Итак, мы решили откатиться, у нас сейчас версия 2.0.0. Мы откатываемся на версию 1.9.0. Мы снова пошли в хранилище и выкачали ту же самую версию Node-модулей, которые уже стояли в версии 2.0.0. И у нас снова все сломалось. Поэтому наш релиз собирается со всеми зависимостями, упаковывается и только так едет на прод.

И мы при откатывании снова берем весь собранный релиз в том виде, в котором он был раньше, и разворачиваем его на прод. Он должен храниться в таком виде. Это либо контейнер, либо деb-пакет. Но это очень важно. Мы должны уметь воспроизводить то, как выглядел наш релиз вчера, в том же самом состоянии.

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

За выкладку на прод тоже не должны отвечать разработчики, ни фронтендеры, ни бэкендеры. Есть люди, которые отвечают за сервер. Это админы, это эксплуатация. Везде их называют по-разному, например, Ops. Пусть они отвечают за то, что это раскатывается на prod. Пусть они пишут скрипты для этого. Мы на прод не лазаем, только под присмотром Ops.

Еще одна маленькая штучка, которая поможет сделать наши релизы стабильнее: релиз можно раскатить не на всех пользователей. Можно применить то самое A/B-тестирование, раскатить на маленький процент пользователей, так называемый канареечный хост. Canary release, знаете, да? Канарейка в шахте. Ее использовали те же самые шахтеры и проверяли, нет ли углекислого газа в шахте. Если канарейке плохо, надо уходить. Отсюда и пошло понятие канареечного релиза.

Мы должны точно так же релизиться, проверять, что все хорошо, что ничего не отравляет наш релиз. Внешняя среда ведь легко его может отравить. И если мы видим, что ошибок много, мы всегда можем откатиться. Как это сделать? Проще всего автоматически. А если мы видим, что ошибок мало, мы можем автоматически задеплоить везде, даже не подключая человека.

Смотрим дальше. Что еще нужно автоматизировать?

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



Это значит, что никаких конфигураций мы руками не пишем. Все конфигурации у нас должны лежать в Git или d любой другой вашей любимой системе контроля версий. Но главное, что конфигурации лежат в виде шаблонов или даже в виде скриптов, генерирующих конфигурацию. Но это не ручное настраивание.

И мы всегда можем сделать шаблонизацию кода под dev-окружение, под прод-окружение, под тестинг-окружение. Это всё шаблоны, не ручное изменение конфигов. А все изменения идут через пул-реквесты. И мы видим глазами, что именнно решили изменить везде в конфигурации. То есть мы видим, что прилетел пул-реквест, который говорит о том, что, например, какой-то наш бэкенд переезжает на другой адрес. Мы должны подтянуть этот конфиг, запродить, что с ним все хорошо. И, конечно, все эти изменения должны раскатиться везде автоматически, тогда тоже будет лучше.


Что еще можно автоматизировать? Много чего. Наверное, тут уже не будем разбирать каждое. Например, обновления зависимостей. Можно всегда сигнализировать, что зависимости устарели, и автоматически создавать для команд задачи о том, что нужно обновить зависимости.

Версионирование. Не нужно руками поднимать версии пакетов. Можно тоже добавить автоматизацию. Например, вы вносите изменение, в каком-то файлике пишете changelog и указываете, что вот здесь были минорные изменения или мажорные. И в момент вливания вашего пул-реквеста у этой библиотеки автоматически растет версия на нужную циферку, потому что вы сказали: я довез сюда мажорных изменений.

То же самое с любой другой рутину. Если видите, что что-то можно автоматизировать, автоматизируйте это.

Также важно понимать: то, что мы делаем, мы должны делать хорошо. Но завтра оно уже может измениться, потому что внешняя среда изменчивая, бизнес должен под нее подстраиваться. И иногда это может случиться просто за ночь, с утра прибегут и скажут: Наша компания совершает поворот, мы начинаем разрабатывать совершенно другое. Давайте менять наш код.

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

Давайте подумаем, какие базовые ограничения можно сделать?

В первую очередь сильная статическая типизация. Без этого, кажется, сейчас никуда. На чистом JavaScript писать большие решения может быть очень больно. Это требует очень высокого уровня разработчиков, очень высокого уровня код-ревью. Наверное, я бы не рекомендовал.



Хотя мы говорим о бизнес-коде, а не о том, что должно быть максимально эффективно на уровне инфраструктуры или рендера, Для себя я уже выбрал только статическая типизация. А мы пишем то, что должно приносить деньги. Лучше типизировать.

как только у нас появляется типизация, мы можем делать контракты. То есть мы должны описывать контракты нашего общения между нашими частями. Вот есть система, мы ее разбили на кучу маленьких микросервисов. Они между собой общаются. И это общение должно быть зафиксировано в контрактах, чтобы контракт не был сломан.

Когда у нас все это есть, мы можем построить поверх этого архитектуру. И эта архитектура даст нам надежность. Архитектура это ограничение.



Давайте быстренько посмотрим на коде, как они добавляются, ограничения. Вот обычный JavaScript. Никаких ограничений. В виде сервиса может прилететь что угодно. Мы где-то ошиблись у нас что-то сломается. Мы добавляем ограничения, добавляем TypeScript и говорим, что в виде сервиса прилетает только то, что соответствует типу класса сервиса. Вот класс service все хорошо. Мы статически типизировали наш код.

А теперь мы добавляем сюда архитектуру и говорим, что нам неважно, что прилетает на вход, лишь бы оно соответствовало контракту. Любой сервис, который имплементирует этот контракт, подойдет.

Здесь мы сделали наш код гибким. То есть мы уже можем вынуть один сервис и вставить другой, вставить mock, сделать какую-то фабрику со стратегией, которая позволит нам менять эти сервисы на лету. Тогда все станет лучше.

Хорошо? Идем дальше. Теперь мы можем собрать вместе весь наш код, который мы разбили по куче маленьких репозиториев: с автоматизацией, линтерами в каждом отдельном репозитории.

Это, наверное, самый тяжелый, самый опасный и самый интересный совет.

Да, мы можем добавить монорепозиторий или монорепозитории. Как ни странно, очень многие крупные компании приходят к этому, и люди удивляются, зачем они нужны, эти ваши монорепозитории, и почему об этом говорит Яндекс? Почему об этом говорит Google? Почему об этом говорит Facebook, и каждый пилит свое решение? Потому что в рамках большой компании это дает свой профит. Но, конечно, мы можем говорить о маленьких монорепозиториях, в которые складываем отдельные части кода. Это тоже будет хорошо.

У нас появляется единая точка входа в код. Мы знаем, где искать. Нам не нужно искать во множестве разных репозиториев у нас есть один большой.

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

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

Это, конечно, грозит тем, что придется чинить упавшие тесты. И здесь уже зависит от компании. Либо есть правило кто сломал тесты, тот их и чинит, и это может быть больно. Или мы создаем каждой команде отдельную задачу на починку тестов, и она уезжает на предыдущую версию зависимости временно. Чинит тесты и поднимается за всеми. Но мы сразу видим, если что-то не так.

А если все хорошо, то зависимости всегда вечнозеленые. Изменили в одном месте, доехало до всех.

Ну и, конечно, намного проще все это автоматизировать, когда оно лежит в одном месте, а не нужно собирать из множества репозиториев, где каждый может что-то забыть, изменить настройки, как-то все сломать.

И можно сказать, что монорипозиторий это очень много отрицания, гнева, торга и депрессии. А потом наступает принятие. Или не наступает. Да, это правда. В компаниях, где вводят монорепозитории, они не нравятся очень многим. Почему? Потому что заставляют писать в едином стиле кода. Они делают всё тяжелее, потому что кода становятся больше. Нужно придумывать скрипты. Чаще всего это какие-то самописные решения, которые могут падать. То есть боли бывает много.

Какой у нас выход? Маленькие монорепозитории. Мы можем взять код одного вида и собрать его в небольшой монорепозиторий, который решает маленькую задачу. Вот посмотрите на Babel, для которого придумали lerna. Отличное решение. И очень часто оно решает многое.

Получается, что вы начинаете чувствовать от этого профит. Вам уже не нужно делать много маленьких пул-реквестов в куче библиотек. У вас есть монорепозиторий. Вы делаете в него один пул-реквест, который доезжает сразу до всех необходимых библиотек, и быстрее ревьюится, потому что ревьювер сразу видит все, что затронется этим пул-реквестом, и быстрее едет на prod.

И это был мой самый страшный и самый последний совет. Поэтому перейдем к выводам.



Да, сказка ложь, да в ней намек. Думаем.

Изменения это хорошо. Если компания не хочет меняться, вот тогда нужно думать, что что-то здесь не так. Если компания готова меняться, ищите в этом возможности, потому что всё плохое, что вы видите, это шанс проявить себя. Если вам это дают, то вы можете подняться в глазах людей, которые с вами работают. Подняться в глазах ваших начальников.

Вы видите, что какой-то кусочек не автоматизирован вы его автоматизируете. Экономите себе пять минут, а если распространить на 50 разработчиков? Уйма времени. И это каждый день. Если вы видите, что что-то сломано, почините это, всем станет лучше и вам это зачтется.

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

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

А в стартапе все классно, у них есть смузи, самые лучшие ноутбуки, но завтра стартап может закрыться.

Есть энтерпрайзы, в которых прекрасно налажены процессы, современные технологии. Да, есть ограничения. Вам понадобится VPN, вам понадобятся корпоративные ноутбуки. Но это окупается тем, что вы работаете с мощнейшими системами, к которым доступ вы в стартапе, пока он не превратится в энтерпрайз, никогда не получите. Так что всегда взвешивайте здраво.

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

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

Код-ревью в Практикуме как мы делаем его быстрее и эффективнее

12.02.2021 14:21:36 | Автор: admin
Код-ревью полезный инструмент для командной разработки и для прокачки собственных навыков. Код-ревью помогает обнаружить недочёты в коде: как синтаксические или стилистические ошибки, так и неоптимальные или неэффективные подходы. В командной разработке, когда команда делает большой проект, код-ревью также помогает оставаться в курсе изменений в разных частях кода.

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



Меня зовут Артём Коломацкий, я старший ревьюер бэкенд-факультета в Яндекс.Практикуме. Я расскажу про практики, которые мы используем в код-ревью наших студентов. Часть из них наши внутренние правила, а часть универсальные советы, которые вы легко сможете применить у себя в команде.

Код-ревью в Практикуме


В Практикуме мы проводим ревью кода на собственной онлайн-платформе, которая называется Ревизор. Туда попадают все сданные студентами работы. Платформа работает по аналогии с интерфейсами в Gitlab/Github/Bitbucket: можно просмотреть список файлов, изменения между версиями, а также оставить комментарии к определённым строкам.

Кроме того, код студента можно скачать, чтобы запустить и проверить на локальной машине, а также при желании оставить комментарии непосредственно внутри файлов, чтобы потом импортировать их обратно на платформу. Это сделано для тех, кому удобнее смотреть код в собственном редакторе или IDE.



Так выглядит страница, на которую попадает ревьюер, когда начинает проверять работу. Тут мы видим вкладку Задание в ней приведён текст задания. Папки и файлы студента можно увидеть и прокомментировать на вкладке Код-ревью, а во вкладке История посмотреть предыдущие варианты этой работы студента.



Во вкладке Код-ревью можно оставлять разные типы комментариев к коду.



Ну а в последней вкладке видно все предыдущие варианты с комментариями.



Интерфейс у студента очень похож на интерфейс ревьюера: видно комментарии к файлам и общий комментарий. Также есть возможность оставить отзыв на работу ревьюера. Всю обратную связь мы внимательно обрабатываем и разбираем вместе с ревьюерами.

Главное отличие Ревизора от других платформ в том, что у нас комментарии делятся на три типа: Надо исправить, Отлично и Можно лучше.

Что значат эти типы комментариев? Надо исправить это обязательные правки. К ним относятся несоответствия заданию, грубые стилистические ошибки, неверное использование тех или иных инструментов и подходов.

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

Отлично это комментарии, которыми мы хвалим студентов за то, что они верно справились с заданием или использовали нестандартные и интересные подходы.

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

Например, в случае спринта по ООП итоговый проект это калькулятор валют. Так как в начале пути программиста очень важно привить культуру красивого кода, мы особенно внимательно относимся к стилистическим ошибкам соблюдению стайлгайда и повышению читаемости кода. Помимо этого мы следим за эффективностью и оптимальностью решения, например, что функция не потребляет лишней памяти или не делает запросов в базу, которых можно было бы избежать.

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

По нашим правилам один раз за отправку проекта на ревью студент может обращаться к ревьюеру с вопросами. Обычно таких отправок за проект получается от трёх до пяти штук. Так мы учим студентов правильно подходить к вопросам: прежде чем что-то спросить, нужно обработать проблему самостоятельно, разобраться в ней, подготовить вопрос и уже потом обратиться к ревьюеру. Вопросы к ревьюеру должны касаться только самих правок, например, если студент не понял, что именно требует ревьюер.

Если студент не понимает, как исправлять ошибку, он может обратиться к наставнику. Они занимаются помощью с решением финальных проектов и прохождением остальной теоретической части курса. Бывают ситуации, когда студент считает, что ревьюер не прав или что правка, которую он требует, некритичная. Поэтому обязательное требование к ревьюеру уметь грамотно объяснить необходимость того или иного исправления.

Формула идеального комментария


Постепенно мы пришли к внутренней формуле идеального комментария.

Идеальный комментарий содержит:

  • ссылки на дополнительные материалы и/или документацию;
  • развёрнутые объяснения;
  • пояснение необходимости выбора иного решения;
  • мягкие формулировки (лучше вместо нужно и вместо повелительного наклонения сделай так);
  • альтернативные примеры кода такого, который студент не сможет бездумно скопировать и сдать, в нём придется разобраться и отредактировать;
  • наводки на решение. Лучше не давать готовое решение, а дать студенту возможность дойти до него самостоятельно.

Вот пример комментария:



А вот пример комментария Отлично за выбор эффективного решения:



Или пример необязательной правки:



Вот так выглядит хороший абстрактный комментарий, написанный по такой формуле:
Здесь лучше использовать кое-что другое, что реализует такой-то функционал, потому что вот это работает медленнее. Пример кода. Ссылка на бенчмарк, ссылка на пояснение этого.
Эта формула позволяет вынести максимум пользы из ревью. Мы помогаем студенту найти правильную идею для реализации исправления, при этом он понимает, зачем нужна эта правка.

Но бывают случаи, когда студент и ревьюер всё равно не могут договориться. В продакшн-разработке тоже случаются такие случаи. Там принято обсудить проблему в комментариях к пулл-реквесту, затем обсудить её в личной переписке и, если не удается достичь консенсуса, привлечь старшего коллегу. Для ревьюеров старший коллега это старший ревьюер, человек, который управляет всеми процессами, которые касаются ревью на факультете. В случаях недопонимания между ревьюером и студентом он включается в диалог и разрешает конфликт.

Принципы код-ревью


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

Если работа кажется идеальной и хочется сразу её принять, нужно очень внимательно проверить её ещё раз мы всегда стараемся предложить улучшения кода сверх программы курса и посоветовать что-то новое. Это помогает студентам получить больше полезной развивающей обратной связи.

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

По схожей причине мы закрепляем студентов за одним ревьюером на весь срок обучения. Это нужно, чтобы студент и ревьюер привыкли к друг другу, открылись, ведь живой диалог позволяет генерировать более продуктивный фидбек. А ещё чтобы избавить студентов от стресса, ведь программирование очень субъективная вещь, у каждого ревьюера свой бэкграунд, и некоторые подходы могут различаться.

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

Мы стараемся переключать фокус внимания ревьюеров с незначительных ошибок на более крупные, для этого у нас есть так называемые чеклисты. Чеклисты это текстовые описания возможных частых ошибок, которые допускают студенты в определённых проектах, с пояснениями, какие из них считать обязательными к исправлению, какие нет, и где нужно дать студентам дополнительные материалы.

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

Недавно в пайплайн тестов, которые прогоняются на платформе при сдаче студентом работы, был добавлен линтер теперь студентам недостаточно прогнать его локально. Пока все тесты на платформе не пройдут, работа не попадёт к ревьюеру.

За счёт всех этих факторов у ревьюеров появляется больше времени на более качественный фидбек студенту.

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

Что почитать


Для тех, кто хочет повысить качество своего кода, я могу посоветовать книги Стива Макконнелла Совершенный код и Антона Спрола Думай как программист.

Как сделать код-ревью быстрее и эффективнее


  1. Используйте мягкие формулировки и чёткие пояснения в комментариях.
  2. Комментарии должны быть подкреплены ссылками на дополнительные материалы и/или документацию.
  3. Не давайте готовое решение, а подталкивайте к нему.
  4. В сложных ситуациях обращайтесь к человеку, который управляет всеми процессами в ревью.
  5. Используйте автотесты и линтеры. Это поможет не допустить до ревью неработающий код и сместить фокус проверки со стилистики на эффективность и оптимальность решения.
  6. В учебных проектах используйте чеклисты возможных ошибок. В реальной работе заранее договоритесь об общих подходах к разработке, задокументируйте их и применяйте на ревью.
Подробнее..

Перевод Код-ревью в IDE интеграция между Space и IntelliJ IDEA 2021.1

08.04.2021 20:08:42 | Автор: admin

Привет, Хабр!

Вчера вышло обновление IntelliJ IDEA 2021.1. В него вошла интеграция с JetBrains Space, которая позволяет использовать любую IDE на платформе IntelliJ для код-ревью: назначать ревью и управлять ими, просматривать и добавлять комментарии, принимать изменения. Как это работает, мы подробно расскажем в этом посте.

Space предоставляет командам разработчиков удобный способ проверять код друг друга и обсуждать изменения. После внесения изменений вы можете попросить одного или нескольких коллег выполнить ревью вашего кода. При работе над функциональной веткой ее можно заново объединить с базовой веткой прямо из Space.

Доступ к код-ревью и мердж-реквестам можно получить из браузера и десктопного приложения Space. А теперь также из IDE! Нативная интеграция между Space и нашими IDE на базе IntelliJ открывает много новых возможностей, и код-ревью это только первый шаг. Мы планируем развивать и улучшать эту интеграцию.

Видео

Если вы предпочитаете видео, смотрите обзор этой функциональности от Триши Ги:

Space-плагин встроен в свежую версию IntelliJ IDEA 2021.1. Для других наших IDE плагин нужно установить вручную.

Прежде чем приступить к ревью кода, войдите в Space из IDE. Это можно сделать в настройках: Tools | Space. Введите URL-адрес своей организации Space, нажмите Log In, и ваш дефолтный браузер попросит вас предоставить доступ из IDE.

После этого в Get from VCS появится список всех проектов и репозиториев в вашей организации Space. Найдите и выберите Git-репозиторий, с которого вы хотите начать, и нажмите Clone.

У Space-плагина есть свое окно, в котором можно просматривать задания в Space Automation. Плагин также обеспечивает автодополнение и подсветку синтаксиса для файлов .space.kts.

Но мы здесь из-за код-ревью, так что перейдем к делу.

Окно Code Reviews

Окно Space Code Reviews открывается с боковой панели или через меню Tools | Space | Code Reviews. В нем вы увидите все ревью, относящиеся к текущему проекту. В окне работает поиск и фильтры.

Фильтры помогут отсортировать:

  • Открытые и закрытые ревью;

  • Ревью, в которых содержатся ваши изменения;

  • Ревью, требующие вашего внимания;

  • Изменения, которые вам нужно просмотреть;

  • Ревью, назначенные на вас.

Хронология код-ревью

Из списка ревью можно перейти к информации о каждом из них. Вы увидите основные сведения о ревью, например, кто является автором и ревьюером. Вы можете сделать checkout ветки мердж-реквеста, если хотите, чтобы код был у вас под рукой.

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

В Space важное место занимают чаты. Комментарии к код-ревью это тоже чат: оставляйте дополнительные комментарии и отвечайте коллегам в тредах. Все это не выходя из IDE.

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

Ревью кода в IDE

Открыв ревью в IDE, вы увидите список файлов, которые были добавлены, изменены или удалены. Вы можете открыть их и посмотреть, что изменилось, в интерфейсе просмотра различий. В нем можно оставлять комментарии к любым строкам кода.

Комментарии сохраняются как черновик и публикуются, только когда вы завершите код-ревью. При необходимости используйте опцию Post now, чтобы сразу же отправить комментарий.

Принять изменения или дождаться ответа

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

  • Accept Changes, то есть принять изменения, если на ваш взгляд с кодом все в порядке.

  • Wait for Response, то есть подождать ответа, если вы ознакомились с изменениями, но у вас остались вопросы или в коде есть нерешенные проблемы.

В любом случае ваш этап проверки будет завершен и ваши комментарии будут опубликованы.

Заключение

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

Space-плагин встроен в IntelliJ IDEA 2021.1, а для других наших IDE его можно установить вручную.

Вы можете бесплатно зарегистрироваться в Space и легко создать зеркало существующего Git-репозитория, чтобы пользоваться всеми возможностями Space для код-ревью в IntelliJ IDEA.

Конечно же, в дальнейшем мы будем расширять функциональность плагина. Что бы вы хотели в нем увидеть? Расскажите нам об этом в комментариях.

Подробнее..

Перевод Совместная игра в Factorio лучшее техническое собеседование, что мы проводили

09.04.2021 14:13:02 | Автор: admin
В последнее время много копий сломано вокруг технических собеседований. Очевидно, что инвертирование двоичного дерева на доске практически никак не связано с практическими навыками реального программиста. Примитивный Fizzbuzz по-прежнему остаётся самым эффективным тестом. Как следствие, выросло внимание к опенсорсным проектам, но оказалось, что это тоже не очень хороший показатель, потому что у большинства профессионалов нет на них времени.

У нас в компании самое эффективное собеседование по программированию на сегодняшний день это обычно какое-то домашнее задание на несколько дней, в котором кандидата просят исправить баг или реализовать небольшую функцию. Это не очень хорошо, потому что занимает много времени, и человек может получить внешнюю помощь (или погуглить, если функция достаточно распространённая). С другой стороны, некоторые крупные компании вместо этого удвоили количество собеседований с доской (и алгоритмами), подвергая будущих инженеров многочасовым сессиям онлайн-программирования с различным уровнем инвазивного наблюдения.

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

Factorio?


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

Начинаете с нуля. Добываете вручную железную руду и камень, строите плавильную печь, чтобы плавить руду в железные пластины, из которых можно скрафтить автоматический твёрдотопливный бур. Можно самостоятельно забирать железную руду из бура и закладывать её в плавильню, но более эффективно использовать автоматический конвейер. Потом можно использовать полученное железо, чтобы сделать другой бур, который автоматизирует добычу угля. Затем строится конвейер для забора угля и конвейер для его передачи в бур. Эта крошечная фабрика производит железные пластины, из которых можно сделать третий бур и начать добычу медной руды, которая позволяет крафтить медные плиты, а из них можно сделать медный провод, необходимый для работы погружного насоса. В сочетании с паровым котлом и паровым двигателем это даёт нам первую электроэнергию. Её можно использовать для исследовательского центра и изобретения новых технологий, таких как сборочный автомат. Как только разблокируете сборочные автоматы, можете использовать сделанный вручную провод для создания сборочной машины, которая будет автоматически изготавливать эти провода.

В конце концов вы разблокируете поезда, роботов и логистические системы, которые помогут справиться с растущей логистической сложностью игры. Ну и в итоге сможете запустить ракету в космос.

Выбор направления


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

Конкретные ожидания можно сформулировать так:

  • Стажёр, как правило, должен быть в состоянии разместить чертёж и соединить его с чем-то ещё, например, с месторождением руды.
  • От джуниоров ожидают самостоятельного строительства производственной линии, пусть и не оптимальной. Им может понадобиться помощь старшего разработчика в том, как правильно направить конвейеры ко всем промежуточным сборочным автоматам.
  • Как только получено задание, миддл должен спроектировать почти оптимальную производственную линию (без маяков) с минимальным контролем.
  • Ведущий программист не нуждается в руководстве, способен сам определить цели и разработать план действий, а затем делегировать эти задачи другим программистам.

Командная работа


Важнейшим аспектом разработки программного обеспечения является умение работать в команде. Это означает координацию усилий с другими людьми, удовлетворение потребностей чужих проектов и сотрудничество с командой, а не самостоятельную работу, когда вы отказываетесь изменить свой дизайн, чтобы помочь интегрировать его с чьей-то работой. Естественно, такие ситуации всё время возникают в Factorio, потому что стандартные чертежи ограничены физическим пространством. В результате нужно тщательно изучить действия других людей, а иногда скорректировать свой дизайн, чтобы вписаться в ограничения по размеру или приспособиться к какому-то чужому чертежу, который занял больше места, чем ожидалось.

Если игрок уйдёт в себя, начнёт делать всё сам или молча исправлять проблемы, это быстро навлечёт на него гнев команды по тем же самым причинам, по которым коллеги злятся на программистов-ковбоев. К счастью, в Factorio есть встроенный эквивалент git blame: он показывает последнего игрока, который изменил любую сущность. Таким образом, если кто-то поставил костыль и не сообщил команде о проблеме, то когда этот костыль наконец сломается все узнают, кто виноват. Если хотите выиграть, придётся плотно сотрудничать с товарищами по команде.

Отладка


Одним из главных навыков для программиста является отладка. Это, пожалуй, самая очевидная параллель между Factorio и реальной разработкой ПО. Что-то может сломаться очень далеко от фактического источника проблемы. Способность быстро выяснить реальную проблему это критический навык, и процесс мышления почти идентичен отслеживанию причины сбоя в реальной программе. Если перестал работать сборочный автомат, сначала нужно проверить выходящие потоки. Потом проверить, какого ингредиента не хватает на входе. Затем проследить ингредиент по фабрике, чтобы узнать, где он производится. И повторять процесс снова и снова, до тошноты.

Отладка в Factorio быстро усложняется. Как только вы построите нефтеперерабатывающий завод, то займётесь крекингом, где на выходе три разных трубы (мазут, дизельное топливо и попутный нефтяной газ), и если какая-то из них по какой-то причине стопорится, то весь завод прекращает работу.

Бывали случаи, когда весь завод останавливался, потому что вы начали исследовать что-то, не требующее жёлтой науки. В результате вы перестали использовать каркасы дронов, которым перестали поставляться электрические двигатели, где использовалась смазочная жидкость, для производства которой забирался мазут. В итоге стопорилась выходящая труба на нефтеперерабатывающем заводе, из-за чего у вас заканчивался попутный нефтяной газ (petrolium), что останавливало производство пластмассы. Как результат, прекращался выпуск сигнального красного провода и вся фабрика выходила из строя. Опытные игроки предвидят подобные сценарии и внедряют самобалансирующийся крекинг нефти, чтобы всегда гарантировать баланс системы. Такой завод остановится только при закупорке выходящей трубы с попутным газом. Если хорошему программисту дадут сломавшийся нефтеперерабатывающий завод, он обычно сможет проследить проблему до источника, понять, что произошло, и быстро попытаться найти решение. С другой стороны, если человек просто плюхает на землю пару новых резервуаров без веской причины (он абсолютно уверен, что смазочная жидкость будет нужна всегда), то это большой красный флаг на методы решения проблем в его программах.

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

Код-ревью


Часто первоначальный дизайн нужно исправить для повышения производительности или пропускной способности. Хорошие программисты не только примут критику своих чертежей, но и учтут её в будущей работе. Если они не согласны с изменением, то предоставят конкретное объяснение, чтобы команда могла более точно обдумать плюсы и минусы предлагаемого изменения.

Сопротивление фидбеку без веских причин хорошо известный красный флаг. Кроме того, настороженность вызывает программист, который неохотно принимает предлагаемые изменения и отказывается соответствующим образом корректировать будущие проекты. В итоге ему придётся постоянно напоминать о необходимости придерживаться какого-то стандартного способа решения проблемы. При этом человек не объясняет, почему ему не нравится предлагаемый метод. Это потенциально бомба замедленного действия в организации, потому что без присмотра он может быстро накопить технический долг для своих коллег. Такого рода проблемы практически невозможно уловить на традиционном собеседовании, только на стажировке.

Стиль написания кода и фреймворки


Отказ следовать советам лишь часть гораздо большей проблемы, когда программист не способен нормально интегрироваться в существующую структуру. Есть много способов построить фабрику в Factorio, и каждый требует стандартных методов сборки. Несоблюдение стандартов быстро затормозит всю фабрику, часто тонкими способами, которые не очевидны неосторожному разработчику.

Конструкция магистрального ленточного конвейера включает 4-8 конвейеров, разделённых на две секции (для подземных конвейеров). Он помещается в центре фабрики, и всё производство происходит перпендикулярно ленте. Эта конструкция опирается на несколько правил, нарушение которых может привести к полному хаосу. Во-первых, всегда следует использовать разделитель на выходе с конвейера. Никогда нельзя перенаправлять всю ленту: пустое пространство для другой ленты означает, что вы теряете целый конвейер ресурсов, даже после апгрейда. Во-вторых, все заводы должны масштабироваться перпендикулярно основному конвейеру. Невозможность быстрого масштабирования приведёт либо к огромной потере пространства, либо к невозможности масштабирования производственной линии, потому что она окружена другими производственными линиями.


Логистическая сеть

Есть разные способы построения логистических сетей. Самый простой с сундуками пассивного снабжения. Но есть другой метод сундуки хранения с фильтром, который решает проблему с мусором. Оба метода требуют правильной установки ограничителей в нужных местах. Сундуки пассивного снабжения обычно ограничены пространством сундука. К сундукам хранения нужно поставить манипулятор для подключения сундука к логистической сети. И обеспечить не менее N предметов перед установкой манипулятора. Если забыть про эти шаги, то будут впустую потрачены огромные ресурсы. Если программист постоянно забывает про ограничители на выходах это красный флаг, что человек небрежно относится к производительности в реальных приложениях.

В других случаях команда может применять заранее разработанные чертежи, такие как проект ядерного реактора или роботизированного завода на дронах (bot factory). Они могут быть крайне сложными, но если сделать над собой усилие и разобраться, то они чрезвычайно экономят время. Остерегайтесь кандидатов, которые не хотят настраивать на заводе новый элемент просто потому, что не могут отследить сложную управляющую логику. Или кто бросает попытки разобраться в алгоритме функционирования такого завода, несмотря на очевидные преимущества дронов перед конвейерами.


Неоптимальный дизайн завода на дронах, источник

Многопоточность


Поезда в Factorio прямой аналог многопоточности: один поезд это один поток выполнения, а каждое пересечение поездов или остановка место в памяти, куда два потока потенциально могут писать одновременно. Светофоры это блокировки (или мьютексы). Все баги в железнодорожной сети проявляются точно так же, как состояние гонки в ПО, потому что они буквально являются физическим состоянием гонки. Все компромиссы применимы и здесь слишком длительная блокировка уменьшает пропускную способность. Неправильное проектирование светофоров обычно вызывает взаимоблокировку, точно так же, как в программном обеспечении, потому что в итоге возникает циклическая зависимость блокировок. Самая распространённая взаимоблокировка это когда поезд слишком длинный и неожиданно блокирует второй перекрёсток, ожидая входа в первый. Затем этот второй перекрёсток препятствует отправлению другого поезда, предотвращая разблокировку первого перекрёстка.

Количество путей в железнодорожной сети соответствует количеству ядер CPU. Один железнодорожный путь трудно масштабировать больше, чем на несколько полос, потому что пропускная способность всей системы очень быстро ограничивается, даже с зонами ожидания. Наиболее распространённой конструкцией является двухполосная конструкция, по одной полосе в каждую сторону. Здесь появятся проблемы с пропускной способностью, когда возникнет необходимость постоянно разгружать поезда. Поэтому в больших железнодорожных сетях минимум по четыре полосы, причём две внешние действуют как объездные пути, чтобы избежать пересечений, когда это возможно.

Проблемы со светофорами в этих системах могут проявиться через фантастический промежуток времени. Единственный пропущенный светофор в одной железнодорожной сети однажды вызвал взаимную блокировку после корректной работы в течение двух недель. Так же и в программах состояние гонки может проявляться только раз в месяц, когда под сильной нагрузкой возникает высокая конкуренция потоков.

Масштабирование


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

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

В конце игре для управления поездами требует перехода с push-архитектуры на pull-архитектуру, поскольку push-архитектура не справляется с высокой пропускной способностью. Это неизбежно приводит к использованию функции Train Limit и изучению, как использовать логические сети для кодирования базовой логики, чтобы станция запрашивала поезд только тогда, когда действительно готова полностью заполнить его ресурсами, вместо обычной игровой тактики в начале игры, когда куче поездов просто даётся команда ехать за железом. Новая схема сводит к минимуму количество поездов и при этом гарантирует, что в сети обслуживаются все станции.

Часто бывает, что ограничения входных линий в сборочный автомат и лимиты скорости манипулятора требуют перепроектирования заводов вокруг, точно так же, как высокоскоростные вычисления требуют знания узких мест в работе CPU. Эти узкие места почти никогда не являются проблемой, пока вы не достигнете определённого масштаба, но после этого начинают ограничивать производительность.

Микросервисы и модули


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

Мегабазу на основе поездов иногда называют дизайном городских кварталов (city-block), где поезда вокруг кварталов завода контролируют все входы и выходы. Таким образом, каждый отдельный квартал изолирован от всех остальных, поскольку все входные данные чисты в том смысле, что они поступают из железнодорожной сети. Это почти идентично архитектуре микросервисов (по HTTP) или межпроцессному взаимодействию (IPC), с аналогичными потенциальными проблемами из-за задержек I/O, поскольку результаты не могут поступать постоянно, они должны передаваться в пакетах или поездах по железнодорожной сети.

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

Такие мегабазы представляют верхний уровень дефолтного сервера Factorio. Конечно, существует много модов, которые гораздо усложняют игру.

Распределённые системы


Space Exploration полностью переделанная версия Factorio для колонизации космоса. Здесь планеты становятся ограниченными ресурсами, требуя от игроков колонизировать другие миры и использовать ракеты для передачи ресурсов между планетами. Из-за огромной задержки с доставкой материалов между планетами, координация этих баз приводит к возникновению проблем, сходных с глобально распределённой системой баз данных. Даже в логической сети приходится бороться с задержкой, потому что автоматическая система теряет из виду элементы, которые запущены, но ещё не достигли целевой планеты. Если это не учитывать, возникают дубликаты запросов для всех нужных элементов. С точно такой же проблемой сталкиваются распределённые системы при попытке обеспечить согласованность между узлами.

Вывод


В целом софтверная индустрия не имеет ни малейшего представления, как находить и нанимать лучших разработчиков. Наверное, совместная игра в Factorio стала лучшим техническим собеседованием, которые мы когда-либо проводили. И это нас сильно смущает. Такое собеседование дико непрактично, занимает более 20 часов в мультиплеере с первого раза или 8 часов для команды опытных игроков. Что из этого можно извлечь? Не знаю. Мы, конечно, не можем перейти на Factorio в качестве метода собеседований с таким же успехом можно просто дать кандидату домашнее задание.

Но это уже лучше, чем собеседование на доске.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru