company_banner

Чему я научился у ведущего программиста

Автор оригинала: Neil Kakkar
  • Перевод

Год назад я начал работать на полную ставку в Bloomberg. И тогда же задумал написать эту статью. Я думал, что буду полон идей, которые смогу выплеснуть на бумагу, когда придёт время. Но уже через месяц понял, что всё будет не так просто: я уже начал забывать то, чему научился. Либо знания настолько хорошо усвоились, что мой разум заставил меня поверить, будто я всегда это знал, либо они просто вылетели у меня из головы.1

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

Я год просидел рядом с ведущим программистом. Вот чему я научился.

Содержание



Написание кода


Как называть вещи в коде


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


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

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

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

То же самое относится и к функциям. doEverything() — ужасное название с многочисленными последствиями. Если функция делает всё, то будет чертовски сложно тестировать отдельные её части. Какой бы большой ни стала такая функция, вам это никогда не покажется слишком странным, ведь она же должна делать всё. Так что поменяйте название. Отрефакторьте.

У осмысленного наименования есть и обратная сторона. Вдруг название будет слишком осмысленным и скроет какой-то нюанс? Например, закрытие сессий не закрывает подключение к базе данных при вызове session.close() в SQLAlchemy. Мне следовало прочесть документацию и предотвратить этот баг, подробнее об этом рассказано в разделе Байка.

С этой точки зрения именование функций как x, y, z вместо count(), close(), insertIntoDB() не позволяет вкладывать в них определённый смысл и заставляет меня внимательно следить, что же делают эти функции.2

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

Унаследованный код и следующий разработчик


Бывало ли, что вы смотрите на код и он вам кажется странным? Почему так написали? Это же не имеет смысла.

Мне довелось поработать с унаследованной кодовой базой. Такой, знаете, с комментариями вроде «Раскомментировать код, когда Мухаммед разберётся в ситуации». Что вы тут делаете? Кто такой Мухаммед?

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

Если я забуду этот код, вернусь к нему позднее и не смогу восстановить контекст, то скажу: «Какого хрена они так сделали? Это же глупость… А, погодите, это я так сделал».

И здесь в игру вступают документация и комментарии в коде.

Документация и комментарии в коде


Они помогают сохранить контекст и передать знания. Как сказал Ли в How to Build Good Software

Главная ценность ПО не в созданном коде, а в знании, накопленном людьми, которые создали это ПО

У вас есть открытый для клиентов эндпойнт API, которым, похоже, никто ни разу не пользовался. Нужно ли его просто удалить? Вообще говоря, это технический долг. А если я скажу вам, что в одной из стран 10 журналистов раз в год отправляют свои отчёты на этот эндпойнт? Как это проверить? Если в документации об этом не упомянуто (так и было), то никак не проверить. Мы и не проверили. Удалили, а через несколько месяцев наступил тот самый ежегодный момент. Десять журналистов не смогли отправить свои важные отчёты, потому что эндпойнта больше не существовало. А люди, обладавшие знаниями о продукте, уже покинули команду. Конечно же, теперь в коде есть комментарии, объясняющие, для чего это нужно.

Насколько мне известно, каждая команда сражается с документацией. Причём с документацией не только по коду, но и по связанным с ним процессам.

Мы ещё не придумали идеального решения. Лично мне нравится, как Антирез разделил комментарии в коде по разным типам ценности.

Атомарные коммиты


Если вам нужно откатиться (а вам это понадобится. См. главу Тестирование), то будет ли этот коммит иметь смысл как единый модуль?

Как уверенно удалять паршивый код


Мне было очень неприятно удалять паршивый или устаревший код. Мне казалось, что всё написанное века назад является священным. Я думал: «Они же что-то имели в виду, когда так писали». Это противостояние между традицией и культурой с одной стороны, и мышлением в стиле «первичного принципа» с другой стороны. Это то же самое, что и в случае с удалением ежегодной-конечной-точки. Я усвоил особенный урок.3

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

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

Ревью кода


Ревью кода — прекрасный инструмент для самообразования. Это цикл внешней обратной связи, показывающий, как они написали бы код и как его написал ты. В чём разница? Один способ лучшего другого? Я спрашивал себя об этом при каждом ревью: «Почему они написали именно так?» И если не мог найти подходящий ответ, то шёл и спрашивал.

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

По моему опыту, не надо одобрять код, пока я не пойму, как он работает.


Моя GitHub-статистика.

Тестирование


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

Если ваше приложение делает лишь что-то одно (как все мои школьные проекты), тогда всё ещё можно тестировать вручную.4 Именно так я и делал. Но что происходит, если приложение выполняет 100 разных задач? Я не хочу тратить полчаса на тестирование, и иногда что-то упускаю из виду. Кошмар.

Здесь помогают тесты и автоматизация тестирования.

Я отношусь к тестированию как к документации. Это документация моих представлений о коде. Тесты говорят мне, как я (или кто-нибудь до меня) представляю работу кода и где что-то ожидаемо должно пойти не так. 

Сегодня, когда я пишу тесты, я стараюсь:

  1. Показать, как использовать тестируемый класс, функцию или систему.
  2. Показать, что, по моему мнению, может пойти не так.

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

В пункте 2 я не упомянул об источниках багов.

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

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

Так выглядит общая ситуация с тестированием.

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



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

  • Есть машины, на которых вы разрабатываете (источник всех мемов вроде «На моём компьютере работало!»).
  • Есть машины, на которых вы тестируете (могут совпадать с предыдущими).
  • Наконец, есть машины, на которых вы развёртываете (они не должны совпадать с машинами, на которых вы разрабатывали).

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

Мы ведём локальную разработку в Docker на своем компьютере.

У нас есть среда разработки, эти компьютеры оснащены набором библиотек (и инструментов разработки), и сюда мы устанавливаем написанный код. Здесь его можно протестировать со всеми необходимыми системами. Также у нас есть бета/стейджинговая среда, которая полностью повторяет эксплуатационную среду. Наконец, у нас есть эксплуатационная среда — машины, на которых исполняется код для наших клиентов.

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

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

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

Снижение рисков


Какие шаги вы можете предпринять, чтобы снизить риск катастрофы? Если речь идёт о новом радикальном изменении, то как можно удостовериться в минимальной длительности простоя, если что-то пойдёт не так? «Нам не нужно полностью развёртывать систему из-за всех этих новых изменений». Что, правда? И почему я об этом не подумал!

Архитектура


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

Нужно очень многое продумать при создании архитектуры.

  • Как будут использоваться числа?
  • Сколько будет пользователей? Насколько может увеличиться их количество (от этого зависит количество строк в базе данных)?
  • Какие подводные камни могут встретиться?

Мне нужно превратить это в чеклист под названием «Сбор требований». Сейчас у меня пока недостаточно опыта, постараюсь сделать это в следующем году в Bloomberg. Этот процесс во многом противоречит Agile: сколько можно проектировать архитектуру, прежде чем переходить к реализации? Всё дело в балансе, нужно выбирать, когда и что вы будете делать. Когда имеет смысл ринуться вперёд, а когда — отступить назад? Конечно, сбор требований не равносилен обдумыванию всех вопросов. Думаю, это окупается, если включить в проектирование ещё и процессы разработки. Например:

  • Как будет протекать локальная разработка?
  • Как мы будем упаковывать и развёртывать?
  • Как мы будем проводить сквозное тестирование?
  • Как мы будем проводить стресс-тестирование нового сервиса?
  • Как мы будем хранить секреты?
  • CI/CD-интеграция?

Недавно мы разработали новый поисковый движок для BNEF. Работать над ним было чудесно, я организовал локальную разработку и узнал о DPG (пакетах и их деплое), поборов деплой секретов. 

Кто бы мог подумать что деплоить секреты в прод может быть таким нетривиальным:

  1. Их нельзя поместить в код, ведь кто-то может их заметить
  2. Хранить их как переменную окружения как предлагает спека 12 факторов приложения? Неплохая идея, но как их туда положить? (Заходить на прод чтобы заполнить переменные окружения каждый раз, когда стартует машина — боль)
  3. Деплоить их как файлы? Но откуда они возьмутся и как их заполнять?

Мы не хотим всё делать вручную.

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

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

Создаём архитектуру, не забывая о сопровождении


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

Я знаю не меньше трёх способов снижения скорости деградации.

  1. Разделяйте бизнес-логику и инфраструктуру: обычно деградирует инфраструктура — растёт нагрузка, устаревают фреймворки, проявляются уязвимости нулевого дня и т.д.
  2. Создавайте процессы с учётом будущего сопровождения. Применяйте одинаковые обновления для старых и новых битов. Это предотвратит появление различий между старым и новым и сохранит весь код в «современном» состоянии.
  3. Убедитесь в том, что выбрасываете всё ненужное и старое.

Развёртывание


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

  • Развёртывание занимает много времени?
  • Ревью кода проходит не слишком весело?

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

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

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

Когда что-то идёт не так


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

То же самое применимо и к «испорченной» машине в вашем кластере: выключите её, пометьте как недоступную, прежде чем выяснять, что с ней произошло. Я нахожу странным, насколько моё естественное желание и инстинкты противоречат оптимальному решению.

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

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

  • Машина работает?
  • Код установлен верно?
  • Конфигурация присутствует?
  • <Характерная для кода конфигурация>, вроде того, корректно ли прописана маршрутизация?
  • Правильная ли версия схемы?
  • А потом уже погружаюсь в код.

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

Конечно, мне не нужно делать это каждый раз. Иногда достаточно лишь сообщения об ошибке, чтобы сразу заняться разбором кода. Когда я не могу определить причину, я стараюсь свести к минимуму количество изменений-в-коде-ради-того-чтобы-найти-причину. Чем меньше изменений, тем быстрее я смогу найти настоящий корень проблемы. Кроме того, теперь у меня есть памятка для багов, которая сэкономила мне больше часа на размышления «что я упустил?» Иногда я забываю о простейших проверках, вроде настройки маршрутизации, соответствия версий схемы и сервиса, и т.д. Это ещё один шаг по освоению стека технологий, который я использую, и то, что обретаешь лишь с опытом — интуицию в определении, что же именно не работает.

Байка


Эта статья не может быть полной без байки. Мне нравится их читать, и хочу одной из них поделиться с вами. Это история о поиске и SQLAlchemy. В BNEF работает много аналитиков, которые пишут отчёты об исследованиях. При публикации отчёта мы получаем сообщение. При получении сообщения мы обращаемся к базе данных через SQLAlchemy, получаем необходимые данные, преобразуем и отправляем на индексирование в экземпляр Solr. И как-то возник странный баг.

Каждое утро подключение к базе приводило к сбою с ошибкой «MYSQL server has gone away.» Иногда это случалось и днём. Машины включаются в течение дня, так что это было первое, что я проверил. Нет, при включении компьютера ошибка не возникала. Мы делали тысячи запросов к базе в течение дня, всё было в порядке. Так в чём же дело, что приводило к сбою?

Может быть, мы не закрывали сессии после транзакций? А если сессия та же, и спустя длительное время приходит запрос, то мы пропускаем таймаут и сервер исчезает. Быстро просмотрели код и убедились, что мы используем диспетчер контекста для каждой операции чтения, в ходе которой применительно к __exit__() вызывается session.close().

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

Session.close() в MySQL-диалекте SQLAlchemy не закрывает подключение к базе данных, если не используется NullPool. Это решило проблему. Забавно, что этот баг возник лишь потому, что мы не публиковали отчёты об исследованиях вечером или в обед. И отсюда проистекает ещё один урок: в большинстве ответов на StackOverflow (конечно, я там искал!) советовали настроить длительность таймаута сессии, или настроить параметр, управляющий объёмом пересылаемых в SQL-выражении данных. Всё это не имело для меня смысла, поскольку не было связано с истинной причиной. Я проверил, что размер запроса у нас не превышает ограничения, а сессии мы закрывали (хаха), так что таймаут просто отсутствовал. 

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

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

Мониторинг


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

Поработав с двумя системами, одна из которых обладала замечательным мониторингом, а другая не могла этим похвастаться, я начал очень высоко ценить мониторинг. Я не могу исправить баги, если не знаю об их существовании. Хуже всего, когда узнаёшь о багах от клиентов. «Чем я занимаюсь?! Я даже не знаю о проблемах в системе, которой владею?».

Я считаю, что мониторинг складывается из трёх компонентов: журналирования, метрик и оповещений. Журналирование в коде, как и дневник, процесс эволюционный. Вы прикидываете, что вам нужно будет мониторить, начинаете журналировать и запускаете систему. Со временем находите несколько багов, для исправления которых у вас мало информации. Пришло время расширить журналирование — чего не хватает вашему коду? Думаю, вы интуитивно понимаете, что важно журналировать. Я и тот ведущий программист журналировали очень разные наборы данных. Я считал, что достаточно будет логов запросов-ответов, а он фиксировал кучу метрик, вроде длительности исполнения запроса, некоторые внутренние вызовы, сделанные кодом, и т.д. А при ротации логов ещё и сортировал статистику.

Практически невозможно заниматься отладкой без логов. Если вы не знаете, в каком состоянии была система, как вы можете её воссоздать? Метрики можно извлекать из логов или выделять в коде (например, отправку событий в AWS CloudWatch и Grafana). Вы сами определяете набор метрик и отправляете информацию по мере исполнения кода.

Оповещения соединяют все элементы в замечательную систему мониторинга. Если одной из метрик является количество серверов, работающих в данный момент в эксплуатации, то когда её значение падает до 50 %, это должно быть поднимать настоящую тревогу — возникла серьёзная проблема. Количество сбоев превысило порог? Ещё одно оповещение. Я крепко сплю по ночам, потому что знаю — в случае чего меня разбудят (погоди, что?).

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

Я ещё не придумал, как мониторить интерфейс. Тестировать наличие компонентов мало для того, чтобы определять возникновение проблем. Обычно клиенты приходят и говорят — у вас тут что-то выглядит криво.

Заключение


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

Сейчас я сижу рядом с двумя ведущими разработчиками. Посмотрим, к чему это приведёт!

Хорошие инженеры самостоятельно проектируют системы, которые получаются более надёжными и лёгкими для понимания. Это приводит к мультипликативному эффекту, позволяя их коллегам опираться на их работу и решать свои задачи гораздо быстрее и надёжнее — How to Build Good Software.

В чём я не уверен


Я ещё не познал всех тайн программного инжиниринга. Так что эта глава служит мне напоминанием: я ещё многого не знаю! Если я всё делаю правильно, то в следующем году этот список должен стать длиннее.

  1. Мыслить абстракциями или реализациями?
  2. Должен ли я иметь твёрдое мнение относительно способов решения задач? Например, как следствие набитых шишек? Достаточно ли я сделал, чтобы иметь мнение?
  3. Продумывание рабочих процессов. Если нужно срочно или ситуативно поменять подход, то можно ли считать процесс нарушенным? Нужно ли его исправлять?
  4. Являются ли вспомогательные классы (utils) (папка, в которую ты складываешь то, что не знаешь, куда деть) признаком того, что код «с душком»?
  5. Как работать с документацией по коду и рабочим процессам?
  6. Как мониторить интерфейс так, чтобы замечать, когда что-то выглядит неправильно?
  7. Что лучше — потратить время на проектирование идеального API или контракта в коде, или хакинг и многократное итерирование в поисках лучшего решения?
  8. Легкий способ или правильный? Не уверен, что правильный способ всегда лучше.
  9. Делать самостоятельно или показывать тем, кто не знает, как сделать. Первое быстрее, а второе означает, что вам редко придётся делать это самостоятельно.
  10. Когда рефакторишь и избегаешь больших PR: «Если бы я сначала изменил все тесты, то я бы увидел, что у меня изменилось 52 файла, и это, очевидно, слишком много, но я сначала занялся кодом, а не тестами». Стоит ли оно того?
  11. Дальнейшее исследование снижения рисков. Какие существуют стратегии для уменьшения рисков в проектах?
  12. Эффективные способы сбора требований?
  13. Как снизить скорость деградации системы?

Примечания


  1. Такое происходит со многими знаниями. Вы знаете, как ездить на велосипеде? Можете кого-нибудь научить? Опишете им конкретные этапы, как вы это делали?
  2. Я имею в виду, что нужно не писать код с именами x(), y() и z(), а думать о них как о x(), y() и z(). Не думайте, что это WYSIATI.
  3. Классический барьер Честертона.
  4. Но я больше так не поступил бы. Однажды перейдя на сторону автоматизированных тестов, обратного пути нет?
  5. Есть мнение, что ситуация выходит из-под контроля, если провести миллион тестов на всё, что может пойти не так. Судя по тому, это не верно.
  6. Я давно этого не делал, так что не знаю, насколько легко найти или создать конкретные Docker-образы для AWS.
  7. Здесь в качестве среды может выступать ваш стек технологий.
Mail.ru Group
882,80
Строим Интернет
Поделиться публикацией

Похожие публикации

Комментарии 37

    +4
    Главная ценность ПО не в созданном коде, а в знании, накопленном людьми, которые создали это ПО

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

      +6
      Комментарии нужны в тех местах где они нужны :)

      Просто есть другая крайность когда абсолютно все методы, проперти, филды и конструкторы «комментируются» каким-нибудь автодоком. И если где-то среди этого и есть полезные комментарии, то ты их просто не видишь.
        +1
        Хорошо если автодоком, а когда на каждую строчку кода, несколько строк комментариев?
        Я и такое видел, это реальный ад, когда код просто не прочитать из за кучи комментов.
          +1

          Ide не умеют сворачивать блоки коментариев? Думаю должно такое быть

            0

            И комментарии разные бывают и IDE разные бывают. XCode, например, через версию отламывал сворачивание КОДА, а уж сворачивание комментариев, даже многострочных, для него видимо какая-то темная магия и работает только в виде "свернуть все от сих и до сих".


            Да и те для разных ситуаций поди догадайся как сворачивать
            // one line

            /// multicomment
            /// of one line 

            /** docstring
            * @brief - with some extras
            */

            void doSomething(int x /*inline multistring comment about default*/)
          • НЛО прилетело и опубликовало эту надпись здесь
            0
            Однажды пришлось рефакторить код, в котором докстринги были у каждого класса и каждой функции, но содержали в себе глубокомысленные высказывания великих людей или просто смешные шутеечки программиста и не имели ни малейшего отношения к коду.
              0
              Тут появляется человеческая проблема – кто будет решать, нужно ли тут комментарий, или нет? Одному всё очевидно, а другой вообще ничего не поймёт.
              Я по разному пробовал решить эту проблему, пока идеального решения так и не нашлось.
                +1
                Ну если я считаю что комментарий нужен, то я его пишу. Если я натыкаюсь на кусок кода, который я не понимаю, то я разбираюсь что он делает, и либо переписываю чтобы было понятно, либо пишу комментарий.

                И автодоки вашу проблему всё равно не решат. Потому что сгенерированные комментарии обычно ещё меньше понятны чем сам код по которым их генерируют.
                И даже если заставить людей писать абсолютно везде комментарии вручную, то вы скорее всего получите комментарии а ля «главное чтобы от меня отстали».
                  0
                  Ревью кода. Если твой код посмотрело 5 коллег, и ни у кого не возникло мысли «а неплохо бы тут откомментить», значит скорее всего не нужны. (подразумевается что они все разного опыта, конечно).
                  Не то чтоб гарантия, но вполне хороший критерий.
                    +1

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

                      0
                      Блин, я 4 года своей жизни отработал в утопическом коллективе.

                      p.s. некоторые мои ревью по крайне критичным кускам кода смотрело 12-15 человек.
                        0

                        Критические куски я ещё понимаю. Но абсолютно все чекины? Серьёзно? Или вы какую-нибудь медицинскую технику делаете или ещё что-то в этом роде?

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

                          Но каждый кусок кода должен быть отревьюен, да.

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

                            И если честно то на мой взгляд этого вполне достаточно и ревью по 12-15 человек это однозначный перебор от которого пользы уже не будет. Тогда уж логичнее взять 2-3 экспертов и дать ревьюить им.

                            П.С. Либо просто сесть и уже нормально без всяких ревью обсудить проблему и решение.
                              0
                              между 3 и 5 настолько радикальная разница для вас? Хорошо, пусть будет 4 человека, вообще была ветка не про организацию ревью в фирме, а про способ как понять что комменты не нужны) имхо, это напоминает придирки, простите.

                              сколько человек «достаточно» в ревью — это критерий, который будет зависеть от того какие цели ставятся перед ревью.
                              Если цель одна — чтобы снизить количество ОЧЕВИДНЫХ косяков, которые я допустил в коде (и возможно услышать 1-2 альтернативных способа решения какой-то проблемы) 3 разработчика средней или высокой квалификации более чем достаточно.
                              Но могут быть еще 3 или даже 4 цели ревью. Не помню ни единой претензии в свой адрес «на кой черт ты столько народу добавил», как и от других разработчиков в подобных случаях. Повторюсь, такое случалось не каждый день и не каждую неделю.
                                0
                                Скажем так: проверять необходимость комментариев во время ревью идея хорошая, но если ревьюят один-два человека, то это не всегда срабатывает. Хотя бы потому что обычно ревьюер сам в теме и ему аблсоютно всё в коде понятно. А вот другим людям через пару-тройку лет уже может быть и непонятно.

                                А привлекать к ревью дополнительных людей исключительно ради проверки комментариев я уже считаю лишним.
                                  0
                                  С вами согласен полностью: это базовый критерий, не дающий полную гарантию. Для компании, которой важны качественные всесторонние комменты в коде, например, которая продает софт, который поставляет в исходниках, это не подойдет.
                                  Но для обычного коммерческого софта работает неплохо. Я залазил в участки кода которые писались задолго до меня, и комментов в них мне хватало (естественно они писались по примерно таким же принципам, как и сейчас).
                                  А, да
                                  Хотя бы потому что обычно ревьюер сам в теме и ему аблсоютно всё в коде понятно

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

                                  В общем, я не спорю что это не серебряная пуля, просто довольно простой способ, не требующий каких-то радикальных дополнительных затрат)
                          0
                          хмм… а это точно было «код ревьювило 12-15 человек» а не «в кодревьюверы было добавлено 12-15 человек»?
                          Потому что у меня в мерж реквесте нотификация рассылается в 20+ человек, но ревьювит — дай бог полтора: собсно техлид-архитектор и еще очередной индус (тут много индусов и они часто меняются).
                          По итогу, вполне может быть что-то в моем коде посмотрят все эти 20 девелоперов (если это была фича, которая аффектит их всех — например логи или авторизация), но ревьювить — это крайне сомнительно…
                            +1
                            Ревьюило. По 1 замечанию хотя бы каждый написал.
                        0
                        В ревью тоже огромный человеческий фактор. Кто-то смотрит уставший, кто-то спешит, кто-то ещё что-то. Выделять больше двух людей на ревью кода – это много, код писать некому будет.
                        Нет, сложные задачи – возможно, но все реквесты по всем таскам…
                          0
                          habr.com/ru/company/mailru/blog/465561/#comment_20573005

                          Как правило никто не заставляет смотреть «здесь и сейчас», нормально на это иметь несколько дней. Если у человека крайне плотный график, и он из другой команды — вполне допустимо удалиться из ревью. А внутри моей команды — кхм, ну так-то ревью большого объема изменений и так закладывается в спринт в нормальном объеме. Я помню периоды когда с несколькими разработчиками несколько дней подряд занимались только ревью друг друга. Это нормально.
                          Так можно сказать «зачем писать тесты, код некогда писать будет» и «зачем дебагать баги, код некогда писать будет».

                          Если компания в которую я устраиваюсь, скажет, что ревью кода проводится, но на него выделяется время, и я должен на него тратить как можно меньше времени — я ОЧЕНЬ сильно задумаюсь.
                        0
                        Подход такой: человек вообще со стороны сможет сходу понять, что тут делается, а главное — зачем? или нет. Если нет, писать.
                    +13
                    Я год просидел рядом с ведущим программистом. Вот чему я научился.
                    А дальше идет список с умозаключениями, но причем тут ведущий программист, а точнее его влияние не описаны вообще никак.
                    Странная статья, както ожидалось что то новое, что тут будут какие то примеры касающиеся именно ведущего программиста. Может быть нехватает какого то диалога… на одном подглядывании конечно можно себя построить но ведь подглядывать можно и в гугле.
                      0
                      Хорошую идею для статьи мне подсказали. Написать «чему я научился у Джеффа Дина» и далее 10 всем известных истин)
                        0
                        Типичная англоязычная статья: много воды, мало смысла
                        +12
                        Это противостояние между традицией и культурой с одной стороны, и мышлением в стиле «первичного принципа» с другой стороны. Это то же самое, что и в случае с удалением ежегодной-конечной-точки. Я усвоил особенный урок.3

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

                        Вроде по отдельности слова знакомые, а в сумме какая-то белиберда. Трудночитаемый перевод…
                          0

                          В оригинале тоже не понятно. Перечитывал этот параграф, перечитывал и решил пропустить.

                            0
                            НЯП имелось в иду противстояние «сохраним культурный слой» с «перепишем все заново с нуля». И автор пишет, что он чаще склоняется к первому (например я видел тех кто любит писать if(0){… старый код ...}), но иногда нужно себя пересиливать и просто удалять этот код.
                              +1
                              Рекомендуемый перевод:

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

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


                              1. Более литературно — слова в тексте не всегда переводятся именно так, как записано в словаре.
                              2. «первичного принципа» — необходима ссылка из оригинала, она и поясняет смысл этого выражения.
                              3. «ежегодной-конечной-точки» — автор ссылается на предыдущую историю о том, как он удалил «эндпойнт API», который тоже выглядел как неиспользуемый, а на самом деле его использовали раз в год. Мне не нравится слово «эндпойнт», но такое уже использовано ранее в этом переводе, поэтому данная часть должна использовать его же, чтобы читатель четко увидел отсылку к той истории.
                              4. «пройти сквозь него» — имеется в виду, что ведущие разработчики прочитали бы код, мысленно прошли его пошагово / разобрались в нем, и тогда смогли бы уверенно сделать нужные изменения или удаления.
                              +4
                              По-моему в статье несколько преувеличена роль ведущего программиста. Его нужно просто опустить за скобки. Вместо названия «Чему я научился у ведущего программиста» можно было написать «Чему я научился». И вместо фразы «Я год просидел рядом с ведущим программистом. Вот чему я научился» написать «Я год просидел. Вот чему я научился.»
                              Автор описывает свой опыт от первого лица и роль ведущего программиста здесь не совсем ясна.
                                0

                                Сидел бы он один — за год бы столько не освоил. Да и феномен признания авторитетом кого-то более опытного налицо. Позитивно. А то вы знаете, какие бывают джуны…

                                  0
                                  Я год просидел. Вот чему я научился.
                                  — как правильно входить в хату
                                  — как быть с полотенцем
                                  — как отвечать на пробивоны
                                  — как вычислить наседку
                                  — как достать бухло
                                  +3
                                  Отличная статья, чтобы понять, что творится в голове у индуса, обучающегося программированию по традиционной системе — посредством заглядывания через плечо.
                                    0
                                    По количеству постов, OP занимается не совсем кодингом…
                                      0
                                      OP просто переводчик этой статьи.
                                    +1
                                    кое-кто читает теги

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

                                    Самое читаемое