[Перевод] Обзор книги «README. Суровые реалии разработчиков»
Недавно я прочитал книгу «README. Суровые реалии разработчиков» Криса Риккомини и Дмитрия Рябого. Я сам в чем-то похож на новичка, поэтому решил попробовать. Эта книга полна хороших советов для разработчиков, начинающих свою карьеру и серьезно об этом задумывающихся. Каждая глава полна примеров поведения и практики. У авторов есть большой опыт, которым они делятся с инженерами.
Эта книга на самом деле имеет довольно глубокий смысл, и я тоже кое-что почерпнул из нее. Несмотря на более чем 15 лет работы в этой отрасли. Если вы только начинаете, это определенно книга для вас. Неважно, какой язык или технологию вы выбрали. Книга применима к любой платформе. Кроме того, каждое предложение имеет значение. Даже на короткое время книга не показалась мне раздутой.
Поэтому вместо обычной рецензии я поделюсь несколькими яркими моментами. Это цитаты, которые показались мне особенно интересными, с моими комментариями. Короче говоря, я жалею, что эта книга не существовала, когда я начинал. Очень рекомендую!
Глава 1: Предстоящее путешествие
Вы создаете ценный продукт, решая задачи с помощью кода
Возможно, это лучшее объяснение того, что на самом деле означает программная инженерия. Обратите внимание на порядок:
1. Ценность
2. Решение проблем
3. Код
Убедитесь в том, что руководитель включил вас в число участников всех встреч и совещаний
Звучит очевидно. Но сколько раз я пропускал встречу только потому, что был новым членом команды, а встречи в календаре не отображались?
Напомните своему руководителю о назначении личной встречи, если это практикуется в вашей компании
Сейчас я работаю менеджером и обязательно провожу встречи 1:1 в среднем раз в 2–3 месяца. У меня есть простая электронная таблица с условным форматированием. Люди, у которых встреча 1:1 была давно, отмечены красным цветом. Просто и эффективно.
Глава 2: Достижение осознанной компетентности
Установите лимит до начала исследования, чтобы поддержать дисциплину и предотвратить уменьшение доходности
Легко попасть в глубокую кроличью нору. Установите для себя крайний срок для проведения исследований или создания пробных вариантов концепции. Продлевайте эти сроки только в случае значительного прогресса.
Глава 3: Работа с кодом
Нарушение инкапсуляции увеличивает область воздействия, которую вы должны гарантировать в течение всего срока службы проекта.
В Java есть запечатанные типы, и я также использую ArchUnit там, где этого недостаточно. Кроме того, тщательно проектируйте свои модули и зависимости.
Используйте скучные технологии, когда это возможно. Не игнорируйте традиции, даже если вы с ними не согласны, и избегайте форков кода.
Да! Некоторое время назад я провел презентацию, в которой утверждал, что лучший код… скучный. Дело не в тестируемости, низкой связности, SOLID. Сделайте его скучным. Настолько легко читаемым, что вы даже не задумываетесь об этом.
Виды отказов скучной технологии хорошо изучены
Всем понятны таймауты с обширными стековыми трассировками в блокирующем Java-коде. Тайм-аут в сложном реактивном приложении или системе акторов может привести к часам мучительного расследования. Насколько хорошо вы умеете устранять неполадки в новых технологиях?
Глава 4: Написание работоспособного кода
Дмитрий был слишком ленив, чтобы правильно обработать входные данные. Не будьте 20-летним Дмитрием. Этим он мог сорвать создание лекарства от рака.
«Лекарство от рака» здесь не метафора. Это реальный случай, упомянутый одним из авторов. Плохой пользовательский интерфейс в некотором медицинском программном обеспечении привел к многолетнему разочарованию и недопониманию среди персонала.
Откат увеличивает время сна нелинейно (обычно используется экспоненциальный откат, например (число повторных попыток)^2). Если вы используете этот подход, убедитесь, что величина отката ограничена некоторым максимумом, чтобы она не стала слишком большой. Однако, если на сервере сети произойдет сбой и все клиенты одновременно ощутят этот сбой, то откат будет осуществляться по тому же алгоритму; все они повторно отправят свои запросы в одно и то же время. Это называется «громогласное стадо»; множество клиентов, одновременно выдающих повторные запросы, могут привести к падению восстанавливающегося сервиса. Чтобы справиться с этим, добавьте джиттер в стратегию отката. При использовании джиттера клиенты добавляют случайное, ограниченное количество времени на обратный отсчет. Внесение случайности распределяет запросы, снижая вероятность возникновения очереди.
Это удивительное явление в распределенных системах. Я говорил об этом в своем подкасте о повторных сбоях. Это действительно ценный, практичный совет.
Помните, что изменение многословности и конфигурации логов может устранить состояние гонки и ошибки, поскольку это замедляет работу приложения.
Изменение многословности логов имеет и другие последствия. Однажды я вывел из строя всю инфраструктуру электронной почты в своей компании, увеличив уровень логов на сервере Nexus. Nexus не имеет ничего общего с электронной почтой. Это хранилище артефактов. Но случилось так, что он делил сервер и диск с демон-мэйлером. Nexus заполнил весь диск и обрушил электронную почту для всех. Извините…
Перезапуск процесса для получения новой конфигурации обычно лучше с операционной и архитектурной точки зрения.
Я тоже усвоил этот урок. Spring имеет несколько сложных механизмов для динамической перезагрузки свойств. Бины проксируются и перезагружаются без перезапуска всего приложения. В целом, я предпочитаю перезапустить все приложение, чем иметь дело с несоответствиями, ошибками и неочевидным поведением при динамической перезагрузке. Перезапуск происходит быстро, особенно с GraalVM и современными фреймворками, такими как Quarkus или Micronaut. Не переусердствуйте.
Глава 5: Управления зависимостями
Добавление одной зависимости кажется небольшим изменением, но если эта библиотека зависит от 100 других, то ваш код теперь зависит от 101 библиотеки
Мне еще предстоит написать скрипт, который подсчитывает строки кода в типичных небольших микросервисах. Но! Такой скрипт будет включать исходники всех JAR-зависимостей. Внезапно ваш «крошечный 500-строчник» превратится в многомиллионного монстра.
Глава 6: Тестирование
Посмотрите, можете ли вы перестроить тест так, чтобы все выполнялось детерминированно. Если нет, ничего страшного, но приложите усилия
Речь идет о тестировании конкурентного кода, который быстро становится недетерминированным. Скорее всего, вы можете переписать свой код так, чтобы пулы потоков были инжектированы. Внутри модульных тестов вы можете инжектировать поддельные пулы потоков с помощью только одного потока. Это немного изменит ситуацию. Но, по крайней мере, ваш тест будет детерминированным.
Глава 8: Доставка программного обеспечения
Шаги между git-коммитом и живым трафиком не должны быть тайной
Убедитесь, что вы понимаете, как это происходит:
• Как выполняются сценарии сборки?
• Как упаковывается приложение?
• Как пакеты развертываются в производство?
• Как трафик перенаправляется на новые пакеты развертывания?
Быстрые циклы релизов создают более стабильное программное обеспечение, которое легче исправить при обнаружении ошибок. За один цикл выходит меньше изменений, поэтому каждый выпуск несет меньший риск. Когда ошибка попадает в производство, при отладке приходится обращать внимание на меньшее количество изменений. Код остается свежим в памяти разработчиков, поэтому ошибку легче и быстрее исправить.
При подборе персонала или оценке компании важным фактором является время между фиксацией в git и запуском в производство с живым трафиком.
• «Часы» здоровые и очень подвижные.
• «Недели» подразумевает унылую, медлительную корпоративную среду.
Это не всегда плохо, в некоторых отраслях требуются недели ручного тестирования и проверок. Но возможность развертывания в производство за 15 минут — это счастье.
При «темном» запуске между живым трафиком и приложением располагается прокси-сервер приложения. Прокси дублирует запросы к темной системе. Ответы на эти идентичные запросы от обеих систем сравниваются, и различия фиксируются.
Кроме того, это отличная архитектурная схема, если вы заменяете старый компонент на новый. Убедитесь, что оба компонента выдают одинаковые ответы, не влияя на живой трафик. Как правило, это включает в себя некоторую большую фоновую работу для сравнения и поиска расхождений.
Глава 9: Дежурство
Будьте терпеливы и вежливы, отвечая на запросы службы поддержки. Хотя это может быть ваше десятое вмешательство в работу за день, это первое взаимодействие с вами со стороны запрашивающего.
Такие советы работают и в личной жизни. Не грубите случайным людям только потому, что у вас был плохой день.
Общайтесь лаконичными предложениями. Бывает неловко говорить прямо, но быть прямым — не значит быть грубым.
Действительно, люди с гораздо большей вероятностью воспримут ваше сообщение, если оно будет коротким и простым. «Биллинговая система не работает, расследуем» — это гораздо лучше, чем: «В связи с непредвиденными обстоятельствами, мы испытываем кратковременный сбой в работе одного из наших основных компонентов биллинга. Наша опытная команда инженеров начала проверку и работает круглосуточно, чтобы проанализировать первопричину проблемы, с которой вы столкнулись в данный момент».
Каждый пункт, над которым вы работаете во время дежурства, должен быть занесен в трекер проблем или лог дежурств команды
Очень хороший совет. Каждое неконтролируемое изменение в производственной среде, каждого запроса, каждой мысли или идее, которую вы пробуете. Помогайте другим людям, которые могут попытаться повторить вашу работу. Кроме того, это отличный материал для будущих постмортемов и runbook’ов.
Смягчение проблемы — это не устранение проблемы, а уменьшение ее серьезности. Устранение проблемы может занять много времени, в то время как смягчение ее последствий обычно происходит быстро.
На самом деле, я никогда не думал об этом в таком ключе. Действительно, немедленное смягчение последствий гораздо важнее, чем поиск первопричины и принятие всех мер безопасности. Это может показаться непрофессиональным, но, возможно, стоит начать с быстрого исправления, развернутого прямо на производстве. Затем переходите к тщательному автоматизированному тестированию. Конечно, это может привести производство к еще большему сбою, когда поспешное устранение небольшой ошибки приведет к гораздо большему сбою. Поэтому действуйте осторожно.
НЕ оставляйте проблему без решения, пока вы ищете ее первопричину
Сначала убедитесь, что люди могут пользоваться вашей системой, чего бы это ни стоило. Затем подумайте о долгосрочных стратегиях.
Глава 10: Процесс технического проектирования
«Что произойдет, если мы не решим эту проблему?» — это мощный вопрос. Когда заинтересованная сторона ответит, спросите, приемлем ли результат. Вы увидите, что многие проблемы на самом деле не требуют решения.
Это правда. Некоторые ошибки или отсутствующие функции не стоят того, чтобы их исправлять. Если это влияет только на 0,001% пользователей самого дешевого тарифного плана или существует обходной путь, может быть, ваше время можно потратить на что-то другое? Иногда лучше запустить в производство с ошибкой, чем развернуть идеальное программное обеспечение спустя несколько недель после окончания срока. На самом деле, идеальное программное обеспечение требуется довольно редко.
Глава 11: Создание эволюционной архитектуры
Если ваша компания все еще использует REST API вручную, а интерфейсы JSON развиваются в коде без официальной спецификации, лучшим выбором для вас будет OpenAPI
Отсутствие схемы или формальной спецификации RESTful API меня беспокоит. Существуют такие подходы, как OpenAPI или, с совершенно другой точки зрения, Consumer-Driven Contracts. Я достаточно стар, чтобы помнить использование SOAP. Может быть, поэтому я с некоторой надеждой смотрю на GraphQL.
Бессхемный подход имеет значительные проблемы с целостностью и сложностью данных
Да! Утверждение, что у MongoDB нет схемы, неверно. У нее есть неявная схема, разбросанная по всем приложениям, работающим с разными версиями, которые используют базу данных. Схема находится в вашей голове, и каждый раз, когда вы хотите изменить модель данных, вам нужно быть очень осторожным. Как и в случае с API без схемы, я бы предпочел иметь строгую схему, которая весьма хлопотна поначалу, но позволяет избежать множества проблем на этапе обслуживания.
Не связывайте жизненные циклы баз данных и приложений. Связывать миграцию схем с развертыванием приложений опасно.
Отчасти я согласен, хотя это действительно удобно. В небольших проектах я использовал Flyway, выполняющий миграции при запуске, и это было очень просто. Но я понимаю последствия, например, неожиданно долгая миграция, которая мешает запуску приложения. Если вы выполняете развертывание «синих/зеленых» или «канареек», это меньшая проблема. Поэтому вам придется выбирать между простотой развертывания и надежностью.
Глава 13: Взаимодействие с менеджментом
Вы определяете повестку дня в беседе 1:1, а беседы 1:1 не предназначены для обновления статуса
Под «вами» авторы подразумевают обычных разработчиков, а не их менеджеров. Но это ценный совет для обеих ролей. Относитесь к 1:1 как к честной сессии обратной связи, времени для обсуждения проблем и планов. Никаких недомолвок.
Система «Ситуация-поведение-воздействие» (SBI) при предоставлении обратной связи
Я слышал это много раз. Когда даете обратную связь, начинайте с реальной ситуации, а не с какого-то общего наблюдения.
• Плохо: «ты не помогаешь товарищам по команде».
• Хорошо: «Помните тот случай в апреле, когда у вас не было времени на устранение неполадок в продакшене Джейн?»
Хороший способ понять своего руководителя — читать книги, которые читают они
Хорошая мысль! Я могу сказать то же самое о маркетинге. Если вы хотите быть неуязвимым для дешевых маркетинговых трюков, научитесь этим приемам!
Глава 14: Навигация по карьерной лестнице
Если ваш товарищ по команде не знает, что такое монада, это не значит, что нет случая, в котором монады могут пригодиться
Синдром самозванца во всей его полноте. У людей разные навыки и опыт. Вы отлично разбираетесь в функциональном программировании. Алиса — нет. Но она исключительна в смягчении производственных проблем любого рода. Примите это!
Продвижение по службе не зависит от времени: неважно, проработали ли вы на своем рабочем месте один год или пять, важна отдача
Помните ли вы определение понятия «разработчик программного обеспечения»? «Вы создаете ценность, решая проблемы с помощью кода». Именно так вы оказываете влияние, решая проблемы. Слишком часто я обнаруживаю, что пишу код для решения воображаемых проблем, не создавая никакой ценности. Не будьте таким, как я…
Надеюсь, эти цитаты убедили вас в том, что это ценная книга. Я с большим удовольствием читал ее на протяжении всего отпуска.