Когда я впервые начал изучать Software Engineering at Google, я подумал, что это еще одна из тех дурацких книг, полных уроков, которые не имеют смысла в человеческом масштабе. Я был удивлен, что уроки применимы к командам размером всего 5 человек. Эта статья — резюме книги. Так сказать, уроки, которые остались в памяти через несколько недель после прочтения.

Разработка программного обеспечения vs Программирование

Разница между разработкой (Software Engineering) и программированием лежит в основе этой книги. Титус Уинтерс, автор первой главы, наконец ответил на этот вопрос.

Разработка — это программирование в течении долгого времени (Software engineering is programming over)

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

Разработка — это когда вы берете фрагмент кода и рассматриваете его под микроскопом:

  • Как будет развиваться эта задача?

  • Как этот код будет адаптироваться к изменениям?

  • Что этот код побуждает делать другие части программы?

  • Как этот код побуждает других программистов использовать его?

  • Я буду понимать этот код через 5 месяцев?

  • Как другие участники команды смогут понять мой код, например, в аврале?

  • Что происходит, когда бизнес вырастет?

  • Когда этот код превратится в легаси?

  • Как его масштабировать?

  • Какие скрытые зависимости существуют?

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

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

Правило Бейонсе и закон Хайрама

Если вам понравился результат — проверьте еще раз.

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

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

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

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

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

Правило Бейонсе гласит, что если Джо понравилась эта ошибка, он должен был проверить ее. Когда вы исправляете ошибку, его тест прерывается, и вы говорите: «О черт, нужно исправить код Джо тоже».

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

Сдвиг влево

Чем раньше вы обнаружите ошибку, тем легче ее исправить.

Используйте:

Статический анализ, например, в редакторе: находит опечатки, неправильные вызовы функций, автозаполняет код.

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

Интеграционные тесты — занимают несколько минут, но проверяют работоспособность вашей системы. 

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

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

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

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

Автоматизируйте общие задачи

Масштабируемость
Масштабируемость

Масштабирование организации во многом похоже на масштабирование программной системы. Сколько ресурсов требуется для онбординга нового инженера?

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

Как насчет ревью?

Объяснить нормы кодовой базы 1 инженеру проще, чем 10. Если 5 инженеров присоединяются каждый квартал, сможете ли вы идти в ногу со временем? Как насчет 5 в неделю?

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

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

Меньше гибкости, больше автоматизации, более простая кодовая база.

Заглушки и моки = плохие тесты

Большие разделы разработки ПО в Google посвящены автоматизированному тестированию. Это единственный способ масштабирования до организации такого размера.

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

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

Но это сработало с моей издевательской базой данных ????

Google рекомендует вместо этого использовать fakes instead. Упрощенные реализации реальной вещи, поддерживаемые той же командой для обеспечения четности API.

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

Небольшие частые релизы

Небольшим релизом легче управлять, его легче отменить и легче понять.

Продолжайте доставку.

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

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

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

Обновляйте зависимости на ранней стадии, быстро и часто

То же самое, что и релизы. Чем меньше изменений, тем легче управлять.

Обновление с 4.3.7 до 4.3.8 не имеет большого значения. Переход с 4.3.7 на 4.4.0 может потребовать нескольких изменений.

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

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

Небольшое обновление? Вы можете сделать это за день.

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

Эксперт делает обновления для всех

Рука об руку с обновлением вашего кода — это как.

Вы можете обновить зависимость или фрагмент кода или сделать функцию устаревшей. Затем скажите всем: «Привет, пожалуйста, обновитесь».

Они этого не сделают.

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

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

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

Комментарии (2)


  1. emaxx
    18.07.2022 15:38
    +4

    Перевод как-то хромает... Издевательская база данных - это что за зверь?

    А насчёт космитов в секунду в Google - одно дело агитировать, а другое - воплощать. Вот Chrome OS развивается в публичном репозитории, и любопытствующие могут поглядеть, по скольку дней коммит залендиться не может; мой рекорд - около 2 недель.


    1. marxfreedom
      18.07.2022 21:48
      +7

      Это походу зверь для обеспечения четности api)