КулЛиб электронная библиотека
Всего книг - 604516 томов
Объем библиотеки - 922 Гб.
Всего авторов - 239612
Пользователей - 109520

Впечатления

kiyanyn про Грицак: Когда появился украинский народ? (Альтернативная история)

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

Именно он - по делам, а не по словам - лучший друг бандеровцев :(

Рейтинг: 0 ( 0 за, 0 против).
pva2408 про Грицак: Когда появился украинский народ? (Альтернативная история)

Конечно не существовало. Если конечно не читать украинских учебников))
«Украинский народ – самый древний народ в мире. Ему уже 140 тысяч лет»©
В них древние укры изобрели колесо, выкопали Черное море а , а землю использовали для создания Кавказских гор, били др. греков и римлян которые захватывали южноукраинские города, А еще Ной говорил на украинском языке, галлы родом из украинской же Галиции, украинцем был легендарный Спартак, а

подробнее ...

Рейтинг: +5 ( 7 за, 2 против).
Дед Марго про Грицак: Когда появился украинский народ? (Альтернативная история)

Просто этот народ с 9 века, когда во главе их стали норманы-русы, назывался русским, а уже потом московиты, его неблагодарные потомки, присвоили себе это название, и в 17 веке появились малороссы украинцы))

Рейтинг: -6 ( 2 за, 8 против).
fangorner про Алый: Большой босс (Космическая фантастика)

полная хня!

Рейтинг: +3 ( 3 за, 0 против).
Stribog73 про Тарасов: Руководство по программированию на Форте (Руководства)

В книге ошибка. Слово UNLOOP спутано со словом LEAVE. Имейте в виду.

Рейтинг: +2 ( 2 за, 0 против).
Дед Марго про Дроздов: Революция (Альтернативная история)

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

Рейтинг: +1 ( 3 за, 2 против).
Сентябринка про Орлов: Фантастика 2022-15. Компиляция. Книги 1-14 (Фэнтези: прочее)

Жаль, не успела прочитать.

Рейтинг: 0 ( 1 за, 1 против).

Делай как в Google. Разработка программного обеспечения [Титус Винтерс] (pdf) читать онлайн

-  Делай как в Google. Разработка программного обеспечения  (и.с. Бестселлеры o’reilly) 4.91 Мб (скачать pdf) (скачать pdf+fbd)  (читать)  (читать постранично) - Титус Винтерс - Том Маншрек - Хайрам Райт

Книга в формате pdf! Изображения и текст могут не отображаться!


Настройки текста:



Beijing

Boston Farnham Sebastopol

Tokyo

Делай как

в

Google

Разработка
программного
обеспечения
Титус Винтерс, Том Маншрек, Хайрам Райт

2021

ББК 32.973.2-018
УДК 004.4
В50

Винтерс Титус, Маншрек Том, Райт Хайрам
В50

Делай как в Google. Разработка программного обеспечения. — СПб.: Питер,
2021. — 544 с.: ил. — (Серия «Бестселлеры O’Reilly»).
ISBN 978-5-4461-1774-1
Современные программисты должны не только эффективно программировать, но и знать надлежащие инженерные практики, позволяющие сделать кодовую базу стабильной и качественной. В чем же
разница между программированием и программной инженерией? Как разработчик может управлять
живой кодовой базой, которая развивается и реагирует на меняющиеся требования на всем протяжении
своего существования? Основываясь на опыте Google, инженеры-программисты Титус Винтерс и Хайрам Райт вместе с Томом Маншреком делают откровенный и проницательный анализ того, как ведущие
мировые практики создают и поддерживают ПО. Речь идет об уникальной инженерной культуре, процессах и инструментах Google, а также о том, как эти аспекты влияют на эффективность разработки.
Вы изучите фундаментальные принципы, которые компании разработчиков ПО должны учитывать при
проектировании, разработке архитектуры, написании и сопровождении кода.

16+ (В соответствии с Федеральным законом от 29 декабря 2010 г. № 436-ФЗ.)
ББК 32.973.2-018
УДК 004.4

Права на издание получены по соглашению с O’Reilly. Все права защищены. Никакая часть данной книги не может
быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.

ISBN 978-1492082798 англ.

ISBN 978-5-4461-1774-1

Authorized Russian translation of the English edition
of Software Engineering at Google
ISBN 9781492082798 © 2020 Google, LLC.
This translation is published and sold by permission of O’Reilly Media, Inc.,
which owns or controls all rights to publish and sell the same.
© Перевод на русский язык ООО Издательство «Питер», 2021
© Издание на русском языке, оформление ООО Издательство «Питер», 2021
© Серия «Бестселлеры O’Reilly», 2021

Краткое содержание
Предисловие...................................................................................................................................14
Вступление.......................................................................................................................................15

Часть I. Тезисы................................................................................................................. 21
Глава 1. Что такое программная инженерия?.....................................................................................................22

Часть II. Культура............................................................................................................ 43
Глава 2. Успешная работа в команде.......................................................................................................................44
Глава 3. Обмен знаниями..............................................................................................................................................59
Глава 4. Инженерия равенства..................................................................................................................................82
Глава 5. Как стать лидером в команде....................................................................................................................93
Глава 6. Масштабируемое лидерство.................................................................................................................. 116
Глава 7. Оценка продуктивности инженеров.................................................................................................. 132

Часть III. Процессы........................................................................................................ 147
Глава 8. Правила и руководства по стилю......................................................................................................... 148
Глава 9. Код-ревью........................................................................................................................................................ 169
Глава 10. Документация............................................................................................................................................. 186
Глава 11. Основы тестирования............................................................................................................................. 206
Глава 12. Юнит-тестирование.................................................................................................................................. 231
Глава 13. Тестирование с дублерами................................................................................................................... 256
Глава 14. Крупномасштабное тестирование.................................................................................................... 279
Глава 15. Устаревание................................................................................................................................................. 308

Часть IV. Инструменты................................................................................................. 321
Глава 16. Управление версиями и ветвями....................................................................................................... 322
Глава 17. Code Search.................................................................................................................................................. 346
Глава 18. Системы и философия сборки............................................................................................................ 366
Глава 19. Critique: инструмент обзора кода в Google................................................................................... 394
Глава 20. Статический анализ.................................................................................................................................. 411
Глава 21. Управление зависимостями................................................................................................................. 424
Глава 22. Крупномасштабные изменения.......................................................................................................... 452
Глава 23. Непрерывная интеграция..................................................................................................................... 472
Глава 24. Непрерывная поставка........................................................................................................................... 497
Глава 25. Вычисления как услуга........................................................................................................................... 509

Часть V. Заключение..................................................................................................... 539
Послесловие..................................................................................................................................540
Об авторах.....................................................................................................................................542
Об обложке....................................................................................................................................543

Оглавление
Предисловие.......................................................................................................... 14
Вступление............................................................................................................. 15
Программирование в долгосрочной перспективе...................................................... 15
Точка зрения Google................................................................................................. 16
Что не отражено в книге.......................................................................................... 17
Заключительные примечания................................................................................... 17
Условные обозначения............................................................................................. 17
Благодарности.......................................................................................................... 18
От издательства....................................................................................................... 20

ЧАСТЬ I. ТЕЗИСЫ....................................................................................... 21
Глава 1. Что такое программная инженерия?............................................................... 22
Время и изменения................................................................................................... 24
Масштабирование и эффективность......................................................................... 30
Компромиссы и затраты............................................................................................ 36
Программная инженерия и программирование......................................................... 41
Заключение.............................................................................................................. 42
Итоги........................................................................................................................ 42

ЧАСТЬ II. КУЛЬТУРА................................................................................. 43
Глава 2. Успешная работа в команде............................................................................ 44
Помоги мне скрыть мой код...................................................................................... 44
Миф о гениальности................................................................................................. 45
Сокрытие вредно...................................................................................................... 47
Весь секрет в командной работе............................................................................... 50
Заключение.............................................................................................................. 58
Итоги........................................................................................................................ 58

Оглавление   7

Глава 3. Обмен знаниями............................................................................................. 59
Сложности в обучении.............................................................................................. 59
Философия............................................................................................................... 60
Создание условий: психологическая безопасность................................................... 61
Расширение знаний.................................................................................................. 63
Масштабирование вопросов: вопросы к сообществу................................................. 65
Распространяйте знания: вам всегда есть чему научить других................................ 67
Распространение знаний с ростом организации........................................................ 71
Удобочитаемость: наставничество через обзоры кода.............................................. 77
Заключение.............................................................................................................. 81
Итоги........................................................................................................................ 81
Глава 4. Инженерия равенства..................................................................................... 82
Предвзятость — это проблема.................................................................................. 82
Понимание необходимости разнообразия................................................................. 84
Выстраивание мультикультурного потенциала......................................................... 85
Сделать разнообразие действенным......................................................................... 87
Отказ от единых подходов........................................................................................ 87
Бросьте вызов устоявшимся процессам.................................................................... 89
Ценности и результаты............................................................................................. 90
Оставайтесь любознательными, двигайтесь вперед.................................................. 91
Заключение.............................................................................................................. 91
Итоги........................................................................................................................ 92
Глава 5. Как стать лидером в команде......................................................................... 93
Руководители и технические лидеры (и те и другие)................................................ 93
Переход от роли разработчика к роли лидера.......................................................... 95
Руководитель........................................................................................................... 97
Антипаттерны......................................................................................................... 100
Положительные паттерны...................................................................................... 104
Неожиданный вопрос............................................................................................. 111
Другие советы и рекомендации.............................................................................. 111
Люди похожи на растения...................................................................................... 113
Заключение............................................................................................................ 115
Итоги...................................................................................................................... 115

8  

Оглавление

Глава 6. Масштабируемое лидерство.......................................................................... 116
Всегда принимайте решение.................................................................................. 116
Всегда уходи.......................................................................................................... 121
Всегда масштабируйте себя.................................................................................... 125
Заключение............................................................................................................ 131
Итоги...................................................................................................................... 131
Глава 7. Оценка продуктивности инженеров.............................................................. 132
Зачем оценивать продуктивность инженеров?........................................................ 132
Расстановка приоритетов: что измерять?............................................................... 133
Выбор значимых метрик с использованием целей и сигналов................................. 137
Цели....................................................................................................................... 138
Сигналы................................................................................................................. 140
Метрики................................................................................................................. 140
Использование данных для проверки метрик......................................................... 141
Принятие мер и оценка результатов....................................................................... 145
Заключение............................................................................................................ 145
Итоги...................................................................................................................... 145

ЧАСТЬ III. ПРОЦЕССЫ............................................................................ 147
Глава 8. Правила и руководства по стилю.................................................................. 148
Зачем нужны правила?........................................................................................... 149
Создание правил.................................................................................................... 149
Изменение правил.................................................................................................. 159
Руководства........................................................................................................... 162
Применение правил................................................................................................ 164
Заключение............................................................................................................ 168
Итоги...................................................................................................................... 168
Глава 9. Код-ревью.................................................................................................... 169
Поток обзора кода.................................................................................................. 170
Как проводятся обзоры кода в Google.................................................................... 170
Преимущества обзоров кода................................................................................... 172
Передовые практики обзора кода........................................................................... 178
Виды обзоров кода................................................................................................. 182

Оглавление   9

Заключение............................................................................................................ 185
Итоги...................................................................................................................... 185
Глава 10. Документация............................................................................................. 186
Что считается документацией?............................................................................... 186
Зачем нужна документация?................................................................................... 187
Документация как код............................................................................................ 188
Знание своей аудитории......................................................................................... 190
Виды документации................................................................................................ 192
Обзоры документации............................................................................................ 199
Философия документирования............................................................................... 201
Когда привлекать технических писателей?............................................................. 204
Заключение............................................................................................................ 204
Итоги...................................................................................................................... 205
Глава 11. Основы тестирования................................................................................. 206
Почему мы пишем тесты?....................................................................................... 207
Проектирование набора тестов.............................................................................. 213
Тестирование в масштабе Google........................................................................... 222
История тестирования в Google.............................................................................. 224
Ограничения автоматизированного тестирования.................................................. 228
Заключение............................................................................................................ 229
Итоги...................................................................................................................... 230
Глава 12. Юнит-тестирование.................................................................................... 231
Важность удобства сопровождения........................................................................ 232
Как предотвратить хрупкие тесты.......................................................................... 232
Создание ясных тестов........................................................................................... 239
Повторное использование тестов и кода: DAMP, не DRY......................................... 247
Заключение............................................................................................................ 254
Итоги...................................................................................................................... 255
Глава 13. Тестирование с дублерами......................................................................... 256
Влияние тестовых дублеров на разработку ПО....................................................... 256
Тестовые дублеры в Google.................................................................................... 257
Базовые понятия.................................................................................................... 258

10  

Оглавление

Приемы использования тестовых дублеров............................................................ 261
Реальные реализации............................................................................................. 263
Имитации............................................................................................................... 267
Заглушки................................................................................................................ 271
Тестирование взаимодействий............................................................................... 273
Заключение............................................................................................................ 278
Итоги...................................................................................................................... 278
Глава 14. Крупномасштабное тестирование............................................................... 279
Что такое большие тесты?...................................................................................... 279
Большие тесты Google............................................................................................ 284
Структура большого теста...................................................................................... 287
Типы больших тестов............................................................................................. 294
Большие тесты и рабочий процесс разработчика.................................................... 302
Заключение............................................................................................................ 307
Итоги...................................................................................................................... 307
Глава 15. Устаревание............................................................................................... 308
Почему необходимо заботиться об устаревании?.................................................... 309
Почему устаревание вызывает такие сложности?................................................... 310
Подходы к прекращению поддержки...................................................................... 313
Управление процессом прекращения поддержки.................................................... 316
Заключение............................................................................................................ 319
Итоги...................................................................................................................... 320

ЧАСТЬ IV. ИНСТРУМЕНТЫ....................................................................... 321
Глава 16. Управление версиями и ветвями................................................................ 322
Что такое управление версиями?............................................................................ 322
Управление ветвями............................................................................................... 331
Управление версиями в Google............................................................................... 335
Монолитные репозитории....................................................................................... 340
Будущее управления версиями............................................................................... 342
Заключение............................................................................................................ 344
Итоги...................................................................................................................... 345

Оглавление   11

Глава 17. Code Search................................................................................................ 346
Пользовательский интерфейс Code Search.............................................................. 347
Как гуглеры используют Code Search?.................................................................... 348
Зачем понадобился отдельный веб-инструмент?.................................................... 350
Влияние масштаба на дизайн................................................................................. 353
Реализация в Google............................................................................................... 356
Некоторые компромиссы........................................................................................ 361
Заключение............................................................................................................ 365
Итоги...................................................................................................................... 365
Глава 18. Системы и философия сборки.................................................................... 366
Назначение системы сборки................................................................................... 366
Так ли необходимы системы сборки?...................................................................... 367
Современные системы сборки................................................................................. 370
Модули и зависимости............................................................................................ 386
Заключение............................................................................................................ 392
Итоги...................................................................................................................... 393
Глава 19. Critique: инструмент обзора кода в Google.................................................. 394
Принципы оснащения обзора кода инструментами................................................. 394
Процесс обзора кода.............................................................................................. 395
Этап 1: добавление изменений............................................................................... 397
Этап 2: запрос на рецензирование......................................................................... 401
Этапы 3 и 4: исследование и комментирование изменения..................................... 403
Этап 5: одобрение изменений (оценка изменений)................................................. 406
Этап 6: фиксация изменения.................................................................................. 408
Заключение............................................................................................................ 409
Итоги...................................................................................................................... 410
Глава 20. Статический анализ.................................................................................... 411
Характеристики эффективного статического анализа............................................. 411
Ключевые уроки внедрения статического анализа................................................. 413
Tricorder: платформа статического анализа в Google.............................................. 415
Заключение............................................................................................................ 422
Итоги...................................................................................................................... 422

12  

Оглавление

Глава 21. Управление зависимостями........................................................................ 424
Почему управлять зависимостями так сложно?....................................................... 425
Импортирование зависимостей............................................................................... 428
Теория управления зависимостями......................................................................... 433
Ограничения SemVer.............................................................................................. 438
Управление зависимостями с бесконечными ресурсами.......................................... 443
Заключение............................................................................................................ 450
Итоги...................................................................................................................... 450
Глава 22. Крупномасштабные изменения................................................................... 452
Что такое крупномасштабное изменение?.............................................................. 452
Кто занимается крупномасштабными изменениями?............................................... 454
Препятствия к атомарным изменениям................................................................... 456
Инфраструктура для крупномасштабных изменений............................................... 461
Процесс крупномасштабных изменений.................................................................. 465
Заключение............................................................................................................ 471
Итоги...................................................................................................................... 471
Глава 23. Непрерывная интеграция........................................................................... 472
Идеи непрерывной интеграции............................................................................... 474
Непрерывная интеграция в Google......................................................................... 487
Заключение............................................................................................................ 496
Итоги...................................................................................................................... 496
Глава 24. Непрерывная поставка............................................................................... 497
Идиомы непрерывной поставки в Google................................................................ 498
Скорость — это командная победа: как разделить процесс развертывания
на управляемые этапы........................................................................................... 499
Оценка изменений в изоляции: флаги управления функциями............................... 500
Стремление к гибкости: создание серии выпусков.................................................. 501
Качество и ориентация на пользователя: поставляйте только то,
что используется.................................................................................................... 503
Сдвиг влево: раннее принятие решений на основе данных..................................... 504
Изменение культуры команды: дисциплина развертывания.................................... 506
Заключение............................................................................................................ 507
Итоги...................................................................................................................... 507

Оглавление   13

Глава 25. Вычисления как услуга............................................................................... 509
Приручение вычислительной среды....................................................................... 510
Написание ПО для управляемых вычислений......................................................... 515
CaaS во времени и масштабе.................................................................................. 522
Выбор вычислительной услуги................................................................................ 528
Заключение............................................................................................................ 537
Итоги...................................................................................................................... 538

ЧАСТЬ V. ЗАКЛЮЧЕНИЕ.......................................................................... 539
Послесловие......................................................................................................... 540
Об авторах............................................................................................................ 542
Об обложке.......................................................................................................... 543

Предисловие
Я всегда восхищался тем, как в Google все устроено, и мучил своих друзей-гуглеров (сотрудников Google) расспросами. Как им удается поддерживать такое огромное
монолитное хранилище кода? Как десятки тысяч инженеров согласованно работают
в тысячах проектов? Как они поддерживают качество систем?
Сотрудничество с «экс-гуглерами» только усилило мое любопытство. Если в одной
команде с вами работает бывший инженер Google, вы будете часто слышать: «А вот
мы в Google...» Переход из Google в другие компании кажется шокирующим опытом,
по крайней мере для инженера. Человек со стороны считает системы и процессы
разработки кода в Google одними из лучших в мире, учитывая масштаб компании
и то, как часто люди хвалят ее.
В книге «Разработка ПО. Делай как в Google» группа гуглеров (и экс-гуглеров)
раскрывает обширный набор практик, инструментов и даже культурных аспектов,
лежащих в основе программной инженерии в Google. Но эта книга не ограничивается простым описанием инструментария (о котором можно говорить бесконечно)
и дополнительно описывает философию команды Google, которая помогает сотрудникам адаптироваться к разным обстоятельствам. К моему восхищению, несколько
глав книги посвящены автоматизированному тестированию, которое продолжает
встречать активное сопротивление в отрасли.
Самое замечательное в программной инженерии — это возможность добиться желаемого результата несколькими способами. В каждом проекте инженер должен учитывать
множество компромиссов. Что можно заимствовать из открытого исходного кода? Что
может спроектировать команда? Что имеет смысл поддерживать для масштаба? У своих
друзей-гуглеров я хотел узнать, как устроен гигантский мир Google, богатый талантами и средствами и отвечающий высочайшим требованиям к программному обеспечению (ПО). Их разнообразные ответы познакомили меня с неожиданными аспектами.
В этой книге изложены эти аспекты. Конечно, Google — уникальная компания, и неверно считать ее способ управления разработкой ПО единственно верным. Цель этой
книги — помочь вам организовать работу и аргументировать принятие решений, связанных с тестированием, обменом знаниями и совместной деятельностью в команде.
Возможно, вам никогда не придется создавать свой Google и вы не захотите использовать методы этой компании. Но, отказавшись от знакомства с практиками, разработанными в Google, вы лишите себя богатого опыта, накопленного десятками тысяч
инженеров, совместно работающих над разработкой софта более двух десятилетий.
Это знание слишком ценно, чтобы закрывать на него глаза.
Камиль Фурнье,
автор книги «От разработчика до руководителя» (М.: МИФ, 2018)

Вступление
Что именно мы подразумеваем под программной инженерией? Что отличает «программную инженерию» от «программирования» или «computer science»? И как подход Google связан с другими подходами в этой области, описанными во множестве
книг в последние пятьдесят лет?
Термины «программирование» и «программная инженерия» используются в отрасли
взаимозаменяемо, хотя каждый из них имеет собственное значение. Студенты университетов, как правило, изучают computer science и работают как «программисты».
Но «инженерия» подразумевает применение теоретических знаний для создания
чего-то реального и точного. Инженеры-механики, инженеры-строители, авиационные инженеры и специалисты в других инженерных дисциплинах — все они
занимаются инженерным делом: используют теоретические знания для создания
чего-то реального. Инженеры-программисты также создают «нечто реальное», но
это «нечто» неосязаемо.
В отличие от других инженерных сфер, программная инженерия более открыта для
вариантов. Авиационные инженеры должны следовать стандартам, поскольку ошибки в их расчетах могут нанести реальный ущерб. Программирование традиционно
не имеет жестких ограничений, но, поскольку ПО интегрируется в нашу жизнь,
мы должны определить и использовать более надежные методы его разработки.
Надеемся, что эта книга поможет вам увидеть путь к созданию современного ПО.

Программирование в долгосрочной перспективе
На наш взгляд, программная инженерия охватывает не только написание кода, но
и все инструменты и процессы создания и дальнейшей поддержки этого кода. Какие
методики может внедрить организация, занимающаяся разработкой ПО, чтобы сохранять ценность кода в долгосрочной перспективе? Как инженеры могут сделать
кодовую базу более устойчивой, а саму дисциплину программной инженерии более
строгой? У нас нет конкретных ответов на эти вопросы, но мы надеемся, что командный опыт Google, накопленный за последние два десятилетия, поможет нам их найти.
Одна из ключевых идей, которой мы делимся в этой книге, заключается в том, что
программную инженерию можно рассматривать как «программирование, интегрированное во времени». Какие практики сделают код устойчивым — способным реагировать на изменения — в течение его жизненного цикла (от проекта его создания
и внедрения до его устаревания)?
В этой книге подчеркиваются три фундаментальных принципа, которые, по нашему
мнению, следует учитывать при проектировании, разработке и написании кода.

16  

Вступление

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

Точка зрения Google
В компании Google сложился свой уникальный взгляд на рост и развитие устойчивого
ПО, основанный на его масштабе и долговечности. Надеемся, что уроки, которые мы
извлекли, найдут отражение и в вашей компании, которая тоже развивается и использует все более устойчивые практики.
Темы, обсуждаемые в этой книге, мы разделили на три основных аспекта ландшафта
программной инженерии, сложившихся в Google:
y культура;
y процессы;
y инструменты.
Культура Google уникальна, но опыт, который мы получили, изучая ее, широко применим. В главах, посвященных культуре (часть II), мы подчеркнули коллективный
характер разработки ПО и необходимость культуры сотрудничества для развития
организации и сохранения ее эффективности.
Методики, описанные в части III «Процессы», знакомы большинству инженеров-программистов, но мы отметили, что большой размер кодовой базы Google и долгий срок
ее действия обеспечивают надежную основу для выработки оптимальных практик.
Мы научились учитывать время и масштаб, а также определили области, где у нас
пока нет удовлетворительных ответов.
Наконец, в части IV «Инструменты» мы использовали инвестиции в инфраструктуру инструментов, чтобы получить дополнительные преимущества по мере роста
и устаревания кодовой базы. Некоторые из этих инструментов специфичны для
Google, но по возможности мы даем ссылки на их альтернативы. Мы полагаем, что
основные идеи с успехом можно применять в большинстве инженерных организаций.
Культура, процессы и инструменты, представленные в этой книге, описывают уроки,
которые типичный инженер-программист извлекает в процессе работы. Конечно,
Google не обладает монополией на полезные советы, и мы делимся своим опытом

Условные обозначения   17

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

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

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

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

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

18  

Вступление

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

Благодарности
Эта книга является результатом труда множества людей. Все представленное здесь
является квинтэссенцией знаний, накопленных нами и другими сотрудниками Google
за долгие годы. Мы лишь передаем вам опыт, которым поделились с нами старшие
коллеги из Google и других компаний. Перечислить их всех трудно, но мы выражаем
им свою благодарность.
Также мы благодарим Мелоди Мекфессель (Melody Meckfessel) за поддержку этого
проекта на начальном этапе, а также Дэниела Джаспера (Daniel Jasper) и Дэнни
Берлина (Danny Berlin) за помощь в его завершении.
Эта книга была бы невозможна без колоссальных совместных усилий наших кураторов, авторов и редакторов. Авторы и редакторы указаны в каждой главе или врезке,
а здесь мы отметим всех, кто внес вклад в каждую главу, участвуя в обсуждении
и подготовке к печати.
y

Что такое программная инженерия? Санджай Гемават (Sanjay Ghemawat), Эндрю
Хаятт (Andrew Hyatt).

y

Успешная работа в команде: Сибли Бэкон (Sibley Bacon), Джошуа Мортон
(Joshua Morton).

y

Обмен знаниями: Дмитрий Глазков, Кайл Лимонс (Kyle Lemons), Джон Риз (John
Reese), Дэвид Симондс (David Symonds), Эндрю Тренк (Andrew Trenk), Джеймс
Такер (James Tucker), Дэвид Колбреннер (David Kohlbrenner), Родриго Дамацио
Бовендорп (Rodrigo Damazio Bovendorp).

y

Инженерия равенства: Камау Бобб (Kamau Bobb), Брюс Ли (Bruce Lee).

y

Как стать лидером в команде: Джон Уили (Jon Wiley), Лоран Ле Брун (Laurent
Le Brun).

y

Масштабируемое лидерство: Брайан О’Салливан (Bryan O’Sullivan), Бхарат Медиратта (Bharat Mediratta), Дэниел Джаспер (Daniel Jasper), Шайндел
Шварц (Shaindel Schwartz).

y

Оценка продуктивности инженеров: Андреа Найт (Andrea Knight), Коллин
Грин (Collin Green), Кетлин Садовски (Caitlin Sadowski), Макс-Канат Александер (Max-Kanat Alexander), Илай Янг (Yilei Yang).

y

Правила и руководства по стилю: Макс-Канат Александер (Max-Kanat Alexander),
Титус Винтерс (Titus Winters), Мэтт Аустерн (Matt Austern), Джеймс Деннетт
(James Dennett).

Благодарности   19

y

Код-ревью: Макс-Канат Александер (Max-Kanat Alexander), Брайан Ледгер
(Brian Ledger), Марк Баролак (Mark Barolak).

y

Документация: Йонас Вагнер (Jonas Wagner), Смит Хинсу (Smit Hinsu), Джеффри Ромер (Geoffrey Romer).

y

Основы тестирования: Эрик Куфлер (Erik Kufler), Эндрю Тренк (Andrew Trenk),
Диллон Блай (Dillon Bly), Джозеф Грейвс (Joseph Graves), Нил Норвитц (Neal
Norwitz), Джей Корбетт (Jay Corbett), Марк Стрибек (Mark Striebeck), Брэд
Грин (Brad Green), Мишко Хевери (Miško Hevery), Антуан Пикар (Antoine Picard),
Сара Сторк (Sarah Storck).

y

Юнит-тестирование: Эндрю Тренк (Andrew Trenk), Адам Бендер (Adam Bender),
Диллон Блай (Dillon Bly), Джозеф Грейвс (Joseph Graves), Титус Винтерс (Titus
Winters), Хайрам Райт (Hyrum Wright), Оги Факлер (Augie Fackler).

y

Тестирование с дублерами: Джозеф Грейвс (Joseph Graves), Геннадий Цивил
(Gennadiy Civil).

y

Крупномасштабное тестирование: Адам Бендер (Adam Bender), Эндрю Тренк
(Andrew Trenk), Эрик Кюфлер (Erik Kuefler), Мэтью Бомонт-Гай (Matthew
Beaumont-Gay).

y

Устаревание: Грег Миллер (Greg Miller), Энди Шульман (Andy Shulman).

y

Управление версиями и ветвями: Рейчел Потвин (Rachel Potvin), Виктория
Кларк (Victoria Clarke).

y

Code Search: Дженни Ван (Jenny Wang).

y

Системы и философия сборки: Хайрам Райт (Hyrum Wright), Титус Винтерс
(Titus Winters), Адам Бендер (Adam Bender), Джефф Кокс (Jeff Cox), Жак Пиенаар (Jacques Pienaar).

y

Critique: инструменты обзора кода в Google: Миколай Додела (Mikołaj Dądela),
Герман Луз (Hermann Loose), Ева Мэй (Eva May), Элис Кобер-Соцек (Alice
Kober-Sotzek), Эдвин Кемпин (Edwin Kempin), Патрик Хизель (Patrick Hiesel),
Оле Ремсен (Ole Rehmsen), Ян Мацек (Jan Macek).

y

Статический анализ: Джеффри ван Гог (Jeffrey van Gogh), Сиера Джаспан (Ciera
Jaspan), Эмма Седерберг (Emma Söderberg), Эдвард Афтандилиан (Edward
Aftandilian), Коллин Винтер (Collin Winter), Эрик Хо (Eric Haugh).

y

Управление зависимостями: Расс Кокс (Russ Cox), Николас Данн (Nicholas
Dunn).

y

Крупномасштабные изменения: Мэтью Фаулз Кулукундис (Matthew Fowles
Kulukundis), Адам Зарек (Adam Zarek).

y

Непрерывная интеграция: Джефф Листфилд (Jeff Listfield), Джон Пеникс (John
Penix), Каушик Шридхаран (Kaushik Sridharan), Санджив Дханда (Sanjeev
Dhanda).

20  

Вступление

y

Непрерывная поставка: Дэйв Оуэнс (Dave Owens), Шери Шипе (Sheri Shipe),
Бобби Джонс (Bobbi Jones), Мэтт Дафтлер (Matt Duftler), Брайан Шутер (Brian
Szuter).

y

Вычисления как услуга: Тим Хокин (Tim Hockin), Коллин Винтер (Collin Winter),
Ярек Кузьмиерек (Jarek Kuśmierek).

Также мы хотим поблагодарить Бетси Бейер за то, что поделилась опытом работы
над книгой «Site Reliability Engineering. Надежность и безотказность как в Google»1.
Спасибо Кристоферу Гузиковски (Christopher Guzikowski) и Алисии Янг (Alicia
Young) из O'Reilly, которые запустили наш проект и довели его до публикации.
Кураторы также хотели сказать отдельное спасибо:
Том Маншрек (Tom Manshreck): «Маме и папе за то, что помогли мне поверить
в себя и решали со мной домашние задания за обеденным столом».
Титус Винтерс (Titus Winters): «Папе за мой путь. Маме — за мой голос. Виктории —
за мое сердце. Рафу — за мою спину. А также мистеру Снайдеру, Ранве, Зеду (Z),
Майку, Заку, Тому и всем Пейнам, Меку (mec), Тоби, Кгд (cgd) и Мелоди за уроки,
наставничество и доверие».
Хайрам Райт (Hyrum Wright): «Маме и папе за поддержку. Брайану и завсегдатаям
Бейкерленда за мое первое погружение в мир ПО. Дюэйну (Dewayne) за продолжение этого путешествия. Ханне, Джонатану, Шарлотте, Спенсеру и Бену за их дружбу
и интерес. Хизер за то, что все это время была рядом».

От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com
(издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информа­цию о наших книгах.

1

Бейер Б., Джоунс К., Петофф Д., Мёрфи Н. Р. Site Reliability Engineering. Надежность и безотказность как в Google. СПб.: Питер, 2021. 592 с.: ил.

ЧАСТЬ I

Тезисы

ГЛАВА 1

Что такое программная инженерия?
Автор: Титус Винтерс
Редактор: Том Маншрек
Ничто не строится на камнях; все построено
на песке, но мы должны строить так, как если
бы песок был камнем.
Хорхе Луис Борхес
Программирование и программная инженерия имеют три важных отличия: время,
масштаб и компромиссы. В отличие от обычных программистов, инженеры-программисты должны больше внимания уделять течению времени и необходимости
внесения изменений, больше заботиться о масштабе и эффективности как самого ПО,
так и организации, которая его производит. Инженеры-программисты принимают
более сложные решения, дороже платят за ошибки и часто опираются на неточные
оценки времени и роста.
Мы в Google иногда говорим: «Программная инженерия — это программирование,
интегрированное во времени». Программирование, безусловно, является важной
частью программной инженерии: в конце концов, именно в процессе программирования создается новый софт. Но если мы разделяем понятия, то нужно разграничить
задачи программирования (разработку) и программной инженерии (разработку, изменение, сопровождение). Время — это новое важное измерение в программировании.
Куб — это не квадрат, расстояние — это не скорость. Программная инженерия — это
не программирование.
Чтобы понять, как время влияет на программу, задумайтесь: «Как долго будет жить1
код?» Крайние оценки в ответах на этот вопрос могут отличаться в 100 000 раз.
Легко представить код, который просуществует несколько минут, или другой код,
служащий десятилетиями. Как правило, короткоживущий код не зависит от времени:
едва ли нужно адаптировать утилиту, которая проживет час, к новым версиям базовых библиотек, операционной системы (ОС), аппаратного обеспечения или языков
1

Мы не имеем в виду «продолжительность выполнения», мы имеем в виду «продолжительность поддержки» — как долго код будет продолжать развиваться, использоваться и поддерживаться? Как долго это ПО будет иметь ценность?

Глава 1. Что такое программная инженерия?   23

программирования. Недолговечные системы фактически являются «мимолетными»
задачами программирования и напоминают куб, который сжат вдоль одного измерения до вида квадрата. Но с увеличением продолжительности жизни кода изменения
становятся более важными для него. За десяток лет большинство программных
зависимостей, явных или неявных, почти наверняка изменятся. Понимание этого
явления помогает отличать программную инженерию от программирования.
Это отличие лежит в основе устойчивости в мире ПО. Проект будет более устойчив,
если в течение ожидаемого срока его службы инженер-программист сможет сохранить способность реагировать на любые важные технические или коммерческие
изменения. Именно «сможет» реагировать в том случае, если обновление будет
иметь ценность1. Когда вы теряете способность реагировать на изменения в базовых
технологиях или развитии продукта, не надейтесь, что такие изменения никогда не
превысят критического уровня. В условиях проекта, развивающегося несколько
десятилетий, такие надежды обречены на провал2.
Взглянуть на программную инженерию можно со стороны оценки масштаба проекта.
Сколько людей вовлечено в разработку? Как меняются их роли при разработке и сопровождении проекта с течением времени? Программирование часто является актом
индивидуального творчества, но программная инженерия — это командная работа.
Одно из первых и самых точных определений программной инженерии звучит так:
«Разработка многоверсионных программ для большого числа людей»3. Оно означает,
что различие между программной инженерией и программированием определяется
количеством пользователей и сроком действия продукта. Командная работа создает
новые проблемы, но также открывает такие возможности для создания систем, какие
не может предложить один программист.
Организация команды, состав проекта, а также стратегия и тактика его развития — важные компоненты программной инженерии, которые зависят от масштаба
организации. Растет ли эффективность производства софта по мере увеличения
организации и расширения ее проектов? Растет ли эффективность рабочего процесса по мере развития организации и насколько пропорционально этому растет
стоимость стратегий тестирования и управления версиями? Проблемы масштаба,
связанные с увеличением числа сотрудников и налаживанием коммуникации между
ними, обсуждались с первых дней программной инженерии, начиная с появления

1

2
3

Это вполне точное определение технического долга: он возникает тогда, когда что-то «должно» быть сделано, но еще не сделано, и является разницей между текущим кодом и будущим
желаемым кодом.
Тут вполне уместен вопрос: как заранее узнать, что проект будет долгосрочным?
Сейчас трудно установить авторство определения: одни считают, что впервые оно было
сформулировано Брайаном Рэнделлом (Brian Randell) или Маргарет Гамильтон (Margaret
Hamilton), другие — что автором является Дейв Парнас (Dave Parnas). Это определение
часто приводят как цитату из отчета «Software Engineering Techniques: Report of a conference
sponsored by the NATO Science Committee», Рим, Италия, 27–31 октября 1969 г., Брюссель,
отдел по научным вопросам, НАТО.

24  

Глава 1. Что такое программная инженерия?

мифического человеко-месяца1. Часто они имеют политический характер, и от их
решения во многом зависят устойчивость ПО и ответ на вопрос: «Как дорого обойдется то, что придется делать снова и снова?»
Еще одно отличие программной инженерии от программирования заключается
в сложности принятия решений и цене ошибок. Постоянная оценка компромиссов
между несколькими путями движения вперед часто основана на несовершенных
данных, и иногда цена ошибки очень высока. Работа инженера-программиста или
лидера команды инженеров состоит в стремлении к устойчивости организации,
продукта и процесса разработки, а также в управлении ростом затрат. Иногда
можно откладывать технические изменения или даже принимать плохо масштабируемые политики, которые потом придется пересмотреть. Но, делая такой
выбор, инженер-программист должен понимать, к каким затратам эти решения
приведут в будущем.
Универсальные решения в программной инженерии встречаются редко, как вы
увидите и в этой книге. Учитывая разброс в 100 000 раз между ответами на вопрос
«Как долго будет жить ПО?» и в 10 000 раз — между ответами на вопросы «Сколько
инженеров работает в компании?» и «Сколько вычислительных ресурсов доступно
для проекта?», опыт Google почти наверняка не будет соответствовать вашей ситуации. Поэтому в этой книге мы постарались показать, как в Google искали правильные
пути в разработке и сопровождении ПО, рассчитанного на десятилетия, имея десятки
тысяч инженеров и вычислительные ресурсы мирового масштаба. Большинство
методов, применение которых мы считаем обязательным в таком масштабе, также
хорошо подойдут для меньших организаций: считайте эту книгу отчетом одной
инженерной экосистемы, который может вам пригодиться. Иногда сверхбольшие
масштабы связаны с повышенными расходами, и, возможно, благодаря нашим предупреждениям, когда ваша организация вырастет до таких масштабов, вы сможете
найти более удачное решение по издержкам.
Прежде чем перейти к обсуждению особенностей командной работы, культуры, политики и инструментов, давайте подробнее рассмотрим время, масштаб и компромиссы.

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

Брукс Ф. Мифический человеко-месяц, или Как создаются программные системы. СПб.:
Питер, 2021. — Примеч. пер.

Время и изменения   25

меняющиеся требования, но маловероятно, что он будет зависеть от более широких
изменений в его окружении.
Разработчиков короткоживущего кода можно также найти в некоторых отраслях.
Мобильные приложения, например, обычно имеют довольно короткий срок действия1
и часто переписываются заново. На ранних стадиях развития стартапов инженеры
могут вполне обоснованно сосредоточиться на ближних целях в ущерб долгосрочным
инвестициям, поскольку сама компания, в которой они работают, может просуществовать недолго. Разработчик серийного стартапа вполне может иметь десятилетний
опыт разработки и почти или совсем не иметь опыта поддержки ПО, которое должно
работать дольше одного-двух лет.
С другой стороны, есть успешные проекты с практически неограниченным сроком
службы: трудно предсказать, когда прекратит свое существование Google Search, ядро
Linux или Apache HTTP Server. Большинство проектов Google должны существовать неопределенно долго и периодически претерпевать обновления зависимостей,
языковых версий и т. д. С течением времени такие долгоживущие проекты рано
или поздно начинают восприниматься иначе, чем задачи по программированию или
развитию стартапа.
На рис. 1.1 показаны два программных проекта на противоположных концах спектра
«ожидаемого срока службы». Как обслуживать проект с ожидаемым сроком службы,
измеряемым часами? Должен ли программист бросить все и заняться обновлением,
если во время работы над сценарием на Python, который будет выполнен всего один
раз, вышла новая версия ОС? Конечно, нет: такое обновление некритично. Но если
проект Google Search, находящийся на противоположном конце спектра, застрянет
на версии ОС 1990-х годов, обслуживание станет проблемой.

Важность обновлений

Высокая

Низкая
Минуты

Часы

Дни

Месяцы

Годы

Десятилетия

Рис. 1.1. Срок жизни и важность обновлений
1

Как заявляют в компании Appcelerator, «ничто в мире не определено, кроме смерти, налогов и короткого срока службы мобильных приложений» (https://oreil.ly/pnT2_, блог Axway
Developer, 6 декабря 2012 года).

26  

Глава 1. Что такое программная инженерия?

Наличие точек на спектре сроков службы, соответствующих низкой и высокой
важности обновлений, предполагает, что где-то есть переход. Где-то на линии, соединяющей одноразовую программу и проект, развивающийся десятилетиями, есть
этап появления реакции проекта на изменение внешних факторов1. Любой проект,
в котором изначально не планировались обновления, переживает переход болезненно
по трем причинам, каждая из которых усугубляет две другие:
y обновления еще не выполнялись в этом проекте: по ним есть только предположения;
y инженеры едва ли имеют опыт проведения обновлений;
y большой объем обновлений: одномоментно приходится применять обновления,
накопившиеся за несколько лет, вместо постепенного применения небольших
обновлений.
Далее, выполнив такое обновление один раз (полностью или частично), вы рискуете
переоценить стоимость следующего обновления и решить: «Никогда больше». Компании, которые приходят к такому выводу, заканчивают тем, что просто выкидывают
старый код и пишут его заново или решают никогда не обновлять его снова. Вместо
того чтобы поддаться естественному желанию избежать болезненной процедуры,
часто полезнее инвестировать в этот процесс, чтобы сделать его менее болезненным.
Впрочем, выбор зависит от стоимости обновления, его ценности и ожидаемого срока
службы проекта.
Суть устойчивости проекта заключается не только в преодолении первого крупного
обновления, но и в достижении уверенности, что проект идет в ногу со временем.
Устойчивость требует оценки влияния необходимых изменений и управления ими.
Мы считаем, что достигли такой устойчивости во многих проектах в Google, в основ­
ном путем проб и ошибок.
Итак, чем отличается программирование короткоживущего кода от производства
кода с более долгим ожидаемым сроком службы? С течением времени мы стали намного четче осознавать разницу между «работающим по счастливой случайности»
и «удобным в сопровождении». Не существует идеального решения вышеназванных
проблем. Это прискорбно, потому что длительное сопровождение ПО — это постоянная борьба.

Закон Хайрама
Если вы поддерживаете проект, который используется другими инженерами, то
между «работающим по счастливой случайности» и «удобным в сопровождении»
есть одно важное отличие, которое мы назвали законом Хайрама:
1

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

Время и изменения   27

Если число пользователей API достаточно велико, неважно, что вы обещаете
в контракте: любое наблюдаемое поведение системы будет зависеть от чьих-то
действий.
По нашему опыту, эта аксиома является доминирующим фактором в любом обсуждении изменения ПО. На концептуальном уровне ее можно сравнить с энтропией:
закон Хайрама обязательно должен учитываться при обсуждении изменений и сопровождения1, так же как при обсуждении вопросов эффективности или термодинамики
должна учитываться энтропия. Тот факт, что энтропия никогда не уменьшается, не
означает, что мы не должны стремиться к эффективности. То, что закон Хайрама будет
действовать применительно к сопровождению ПО, не означает, что мы не должны
планировать или пытаться лучше понять это сопровождение. Можно смягчить последствия проблем, даже если мы знаем, что они никогда не исчезнут.
Закон Хайрама основан на практическом понимании, что даже при наличии самых
лучших намерений, лучших инженеров и широкого круга методик проверки кода
нельзя надеяться на полное соблюдение опубликованных контрактов или передовых практик. Как владелец API вы имеете некоторую свободу, четко понимая возможности интерфейса, но на практике сложность изменения также зависит от того,
насколько полезным для пользователя является наблюдаемое поведение API. Если
пользователи не зависят от него, изменить API будет легко. Но с течением времени
и при достаточном количестве пользователей даже самые безобидные изменения обязательно что-то нарушат2. Анализируя ценность изменений, учитывайте трудности,
связанные с поиском, выявлением и устранением нарушений, которые они вызовут.

Пример: упорядоченный хеш
Рассмотрим пример упорядочения итераций по хешу. Если вставить в хеш пять
элементов, в каком порядке мы их получим?
>>> for i in {"apple", "banana", "carrot", "durian", "eggplant"}: print(i)
...
durian
carrot
apple
eggplant
banana

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

2

Надо признать, что сам Хайрам собирался назвать этот закон «законом неявных зависимостей», но в Google предпочли более краткое название «закон Хайрама».
См. комикс «Workflow» (http://xkcd.com/1172) на сайте xkcd.

28  

Глава 1. Что такое программная инженерия?

y Атаки переполнения хеша (hash flooding)1 стимулируют недетерминированный
характер хранения данных в хеше.
y Потенциальный выигрыш от поиска усовершенствованных алгоритмов хеширования или хеш-контейнеров требует изменения порядка итераций в хеше.
y Согласно закону Хайрама, программисты по возможности пишут программы,
зависящие от порядка обхода хеш-таблицы.
Если спросить эксперта: «Можно ли положиться на конкретный порядок обхода
элементов в хеш-контейнере?» — он наверняка ответит: «Нет». Это правильный
ответ, но слишком упрощенный. Более точный ответ мог бы звучать так: «Если код
недолговечный и не предполагает будущих изменений в аппаратном или программном окружении или структуре данных, то это вполне допустимо. Но если известно,
что код будет жить долго или нельзя гарантировать, что зависимости никогда не
изменятся, то предположение неверно». Более того, даже если ваша собственная
реализация не зависит от порядка хранения данных в хеш-контейнере, этот порядок может использоваться другим кодом, неявно создающим такую зависимость.
Например, если ваша библиотека сериализует значения перед вызовом удаленной
процедуры (RPC, remote procedure call), вызывающая сторона может оказаться в зависимости от порядка следования этих значений.
Это очень простой пример различия между «это работает» и «это правильно». Зависимость недолговечной программы от порядка хранения данных в контейнере не
вызывает технических проблем. С другой стороны, для проекта, срок жизни которого преодолевает некоторый порог, такая зависимость представляет значительный
риск: по прошествии времени кто-то или что-то может сделать этот порядок ценным.
Ценность проявляется по-разному: как эффективность, безопасность или просто
пригодность структуры данных для изменения в будущем. Когда ценность очевидна,
взвесьте все за и против, выбирая между этой ценностью и проблемами, с которыми
могут столкнуться разработчики или клиенты.
Некоторые языки намеренно изменяют порядок хеширования в каждой следующей
версии библиотеки или при каждом запуске программы, чтобы предотвратить появление зависимости от этого порядка. Но даже в этом случае закон Хайрама преподносит сюрпризы, поскольку такое упорядочивание происходит с использованием
генератора случайных чисел. Устранение случайности может нарушить работу кода
пользователей, полагающихся на него. В любой термодинамической системе энтропия увеличивается, и точно так же к любому наблюдаемому поведению применим
закон Хайрама.
Между кодами, написанными для «работы сейчас» и для «работы всегда», можно
выделить четкие взаимосвязи. Рассматривая код как артефакт с переменным (в ши1

Разновидность атак типа «отказ в обслуживании» (DoS, denial-of-service), при которых
злоумышленник, зная внутреннюю организацию хеш-таблицы и особенности хеш-функции,
может сформировать данные таким образом, чтобы снизить алгоритмическую производительность операций над таблицей.

Время и изменения   29

роких пределах) временем жизни, можно определить стили программирования:
код, зависящий от хрупких и недокументированных особенностей, скорее всего,
будет классифицирован как «хакерский» или «хитрый», тогда как код, следующий
передовым практикам и учитывающий возможность развития в будущем, вероятно, будет считаться «чистым» и «удобным для сопровождения». Оба стиля имеют
свои цели, но выбор одного из них во многом зависит от ожидаемого срока службы
кода. Мы привыкли использовать термин программирование, если характеристика
«хитрый» — это комплимент, и программная инженерия, если слово «хитрый» имеет
отрицательный оттенок.

Почему бы просто не «отказаться от изменений»?
Все наше обсуждение времени и реакции на изменения связано с неизбежностью
изменений. Верно?
Как и все остальное, о чем говорится в книге, принятие решения об обновлении
зависит от обстоятельств. Мы готовы подтвердить, что «в большинстве проектов,
существующих достаточно долго, рано или поздно возникает необходимость обновления». Если у вас есть проект, написанный на чистом C и не имеющий внешних
зависимостей (или имеющий только зависимости, гарантирующие стабильность
в течение долгого времени, такие как стандарт POSIX), вы вполне можете избежать
рефакторинга или сложного обновления. Разработчики языка С прикладывают
значительные усилия, чтобы обеспечить его стабильность.
Но большинство проектов подвержены изменениям в базовой технологии. В основном языки программирования и среды выполнения меняются активнее, чем язык C.
Даже библиотеки, реализованные на чистом C, могут меняться для поддержки новых
функций и тем самым влиять на пользователей. Проблемы безопасности есть во
всех технологиях, от процессоров до сетевых библиотек и прикладного кода. Каждый элемент технологии может стать причиной критической ошибки и уязвимости
безопасности, о которых вы не узнаете заранее. Если вы не применили исправления
для Heartbleed (http://heartbleed.com) или не смягчили проблемы с упреждающим выполнением, такие как Meltdown и Spectre (https://meltdownattack.com), потому что полагали (или были уверены), что ничего не изменится, последствия будут серьезными.
Повышение эффективности еще больше осложняет картину. Мы стараемся оснастить
вычислительные центры экономичным оборудованием, разумно использующим
процессоры. Но старые алгоритмы и структуры данных на новом оборудовании
работают хуже: связанный список или двоичное дерево поиска продолжают работать, но растущий разрыв между скоростями работы процессора и памяти влияет
на «эффективность» кода. Со временем ценность обновления аппаратного обеспечения может уменьшаться в отсутствие изменений в архитектуре ПО. Обратная
совместимость гарантирует работоспособность старых систем, но не гарантирует
эффективности старых оптимизаций. Нежелание или неспособность воспользоваться
новыми аппаратными возможностями чреваты большими издержками. Подобные

30  

Глава 1. Что такое программная инженерия?

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

Масштабирование и эффективность
Как отмечается в книге Бетси Бейер и др. «Site Reliability Engineering. Надежность
и безотказность как в Google» (СПб.: Питер, 2019) (далее Site Reliability Engineering —
SRE), производственная система в компании Google относится к числу самых сложных систем, созданных человеком. Формирование такой машины и поддержание ее
бесперебойной работы потребовали бесчисленных часов размышлений, обсуждений
и проектирования с участием экспертов со всего мира.
Большая часть этой книги посвящена сложностям, связанным с масштабированием
в организации, которая производит такие машины, и процессам поддержания этой
машины в рабочем состоянии в течение долгого времени. Давайте снова вернемся
к понятию устойчивости кодовой базы: «База кода организации является устойчивой, если вы можете без опаски изменять то, что нужно, в течение срока ее службы».
В данной формулировке под возможностями также понимаются издержки: если
обновление чего-либо сопряжено с чрезмерными затратами, оно, скорее всего, будет
отложено. Если со временем затраты растут сверхлинейно, это значит, что выполняемая операция не масштабируется1 и наступит момент, когда изменения станут
неизбежными. Когда проект вырастет вдвое и понадобится выполнить эту операцию
снова, окажется ли она вдвое более трудоемкой? Найдутся ли человеческие ресурсы
для ее выполнения в следующий раз?
Люди — не единственный ограниченный ресурс, который необходимо наращивать.
Само ПО должно хорошо масштабироваться в отношении традиционных ресурсов,
таких как вычислительная мощность, память, объем хранилища и пропускная способность. Разработка ПО также должна масштабироваться с точки зрения количества
участвующих в ней людей и объема вычислительных ресурсов. Если стоимость вы1

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

Масштабирование и эффективность   31

числений на тестовом кластере растет сверхлинейно и на каждого человека в квартал приходится все больше вычислительных ресурсов, это значит, что положение
неустойчиво и скоро придется что-то изменить.
Наконец, самый ценный актив организации, производящей ПО, — кодовая база —
тоже нуждается в масштабировании. При сверхлинейном росте системы сборки или
системы управления версиями (VCS, version control system) (возможно, в результате
увеличения истории изменений) может наступить момент, когда работать с ней станет
невозможно. Многим аспектам, таким как «время для полной сборки», «время для
получения новой копии репозитория» или «стоимость обновления до новой языковой версии», не уделяется должного внимания из-за того, что они меняются очень
медленно. Но они с легкостью могут превратиться в метафорическую сварившуюся
лягушку (https://oreil.ly/clqZN): медленно накапливающиеся проблемы слишком легко
усугубляются и почти никогда не проявляются в виде конкретного момента кризиса.
Только имея полное представление об организации в целом и стремясь к масштабированию, вы, возможно, сможете оставаться в курсе этих проблем.
Все, что организация использует для производства и поддержки кода, должно быть
масштабируемым с точки зрения издержек и потребления ресурсов. В частности,
все операции, которые организация должна выполнять снова и снова, должны быть
масштабируемыми относительно человеческих усилий. С этой точки зрения многие
распространенные политики не могут считаться хорошо масштабируемыми.

Плохо масштабируемые политики
Даже небольшой опыт разработки позволяет легко определять политики, плохо
поддающиеся масштабированию, чаще всего по изменению объема работы, приходящемуся на одного инженера, при расширении компании. Если организация увеличится в 10 раз, увеличится ли в 10 раз нагрузка на одного инженера? Увеличится
ли объем работы, которую он должен выполнять, при увеличении кодовой базы?
Если на какой-то из этих вопросов будет дан положительный ответ, найдутся ли
механизмы для автоматизации или оптимизации работы этого инженера? Если нет,
значит, в организации есть явные проблемы с масштабированием.
Рассмотрим традиционный подход к устареванию (подробнее об устаревании в главе 15) в контексте масштабирования. Представьте, что принято решение использовать
новый виджет вместо старого. Чтобы мотивировать разработчиков, руководители
проекта говорят: «Мы удалим старый виджет 15 августа, не забудьте перейти к использованию нового виджета».
Такой подход хорошо работает в небольших проектах, но быстро терпит неудачу
с увеличением глубины и широты графа зависимостей. Команды зависят от постоянно растущего числа виджетов, и любое нарушение в сборке может повлиять на
рост компании. При этом вместо перекладывания хлопот, связанных с миграцией
нового кода, на клиентов команды могут сами внедрить все необходимое, используя
преимущества экономии от масштабируемого решения.

32  

Глава 1. Что такое программная инженерия?

В 2012 году мы начали смягчать проблему обновления и поручили командам, отвечающим за инфраструктуру, переводить внутренних пользователи на применение новых
версий или выполнять обновление на месте с обеспечением обратной совместимости.
Эта стратегия, которую мы назвали «правилом обновления», хорошо масштабируется: зависимые проекты перестали тратить все больше и больше усилий, чтобы
просто не отстать. Мы также выяснили, что специальная группа экспертов внедряет
обширные изменения намного лучше, чем пользователи: эксперты некоторое время
изучают всю глубину изменения, а затем применяют полученные знания в каждой
подзадаче. Внедрение изменений пользователем вызывает замедление в работе: он
вынужден решать проблему непосредственно у себя, а затем выбрасывать ставшие
бесполезными знания. Опыт экспертов масштабируется лучше.
Еще один пример плохо масштабируемой политики — традиционное использование
ветвей разработки. Если слияние крупных изменений с главной ветвью дестабилизировало продукт, можно сделать вывод: «Нужно более жесткое управление
слиянием. Слияния должны производиться реже!» и для каждой команды (или
функциональной возможности) создать отдельные ветви разработки. Когда такая
ветвь достигнет конечной точки разработки, она будет протестирована и объединена
с главной ветвью, из-за чего другие инженеры, работающие над другими ветвями,
будут вынуждены повторно синхронизировать репозитории и проводить тесты.
Такой способ управления ветвями можно использовать в небольшой организации, где одновременно разрабатывается 5–10 подобных ветвей. Но по мере роста
организации (и количества ветвей) этот подход увеличивает накладные расходы
на многократное выполнение одной и той же задачи. Более эффективный подход
обсудим в главе 16.

Хорошо масштабируемые политики
Какие политики помогают оптимизировать затраты по мере роста организации?
Точнее, какие виды политики можно внедрить, чтобы обеспечить суперлинейный
рост ценности при росте организации?
Одна из наших любимых внутренних политик позволяет командам поддержки инфраструктуры безопасно вносить изменения в инфраструктуру. «Если в работе продукта
есть сбои или другие проблемы после изменений в инфраструктуре, но их причины
не выявлены тестами в системе непрерывной интеграции (CI, continuous integration),
значит, эти причины не связаны с изменениями». Другими словами: «Если вам что-то
понравилось, добавьте соответствующий тест в систему непрерывной интеграции».
Мы называем это «правилом Бейонсе»1. С точки зрения масштабирования правило Бейонсе подразумевает, что сложные одноразовые специализированные тесты,
которые не запускаются системой непрерывной интеграции, не нужно учитывать:
1

Это отсылка к популярной песне «Single ladies», в которой рефреном звучит фраза: «If you
liked it then you shoulda put a ring on it». («Если я тебе нравилась, так надел бы мне на палец
колечко».)

Масштабирование и эффективность   33

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

Пример: обновление компилятора
Рассмотрим сложную задачу обновления компилятора. Теоретически обновление
компилятора не должно вызывать сложностей, учитывая, сколько усилий прилагают разработчики языков, чтобы сохранить обратную совместимость. Но насколько
простым является это обновление на практике? Если прежде вам никогда не приходилось выполнять такое обновление, как бы вы оценили его совместимость с вашей
базой кода?
По нашему опыту, обновление языка и компилятора — тонкая и сложная задача, даже
если ожидается, что новая версия сохранит обратную совместимость. Обновление
компилятора почти всегда приводит к незначительным изменениям в его поведении
и требует исправления ошибок компиляции, настройки флагов оптимизации или
других ранее не выявленных изменений. Как оценить исправность всей кодовой
базы, учитывая все потенциальные проблемы обновления компилятора?
Самое сложное обновление компилятора за всю историю Google было проведено
в 2006 году. На тот момент мы уже несколько лет имели в штате тысячи инженеров
и не обновляли компиляторы около пяти лет. Большинство инженеров не имели
опыта смены компилятора, а большая часть кода компилировалась только одной
версией компилятора. Обновление стало трудной и утомительной задачей для
(в основ­ном) добровольцев, которая в конечном итоге свелась к поиску коротких путей обхода изменений с проблемами адаптации1. Внедрение изменений происходило
болезненно: многие проблемы, согласно закону Хайрама, проникли в кодовую базу
и углубили его зависимости от конкретной версии компилятора, сломать которые
было очень трудно. Инженеры пошли на риск и применили изменения, четко не
представляя последствия и не зная правила Бейонсе и вездесущей системы непрерывной интеграции.
Этот опыт не был чем-то необычным. Инженеры многих компаний могут рассказать похожие истории. Необычность заключается в нашем осознании сложности
1

В частности, на интерфейсы из стандартной библиотеки C++ нужно было ссылаться с использованием пространства имен std, а изменения в оптимизациях для std::string отрицательно повлияли на производительность кода, что потребовало искать дополнительные
обходные пути.

34  

Глава 1. Что такое программная инженерия?

задачи. Благодаря тому опыту мы стали уделять больше внимания изменениям
в технологиях и организации, чтобы потом менее болезненно преодолевать проблемы масштабирования и находить в нем преимущества. Мы стали развивать
автоматизацию (чтобы один человек мог сделать больше), согласованность (чтобы
ограничить влияние проблем на низком уровне) и обмен опытом (чтобы несколько
человек могли сделать больше).
Чем чаще вы вносите изменения в инфраструктуру, тем меньше проблем они вызывают. Мы обнаружили, что в большинстве случаев код, переживший обновление,
становится менее хрупким и его легче обновлять в будущем. В экосистеме, где большая часть кода прошла несколько обновлений, он перестает зависеть от нюансов базовой реализации и начинает зависеть от фактических абстракций, гарантированных
языком программирования или ОС. Независимо от того, что именно обновляется,
первое обновление всегда будет обходиться базе кода значительно дороже, чем последующие, даже с учетом других факторов.
Мы выявили множество факторов, влияющих на гибкость кодовой базы.
Опыт
Мы знаем, как это сделать. Для некоторых языков мы провели сотни обновлений
компиляторов на множестве платформ.
Стабильность
Благодаря регулярному обновлению версий нам приходится вносить меньше
изменений. Для некоторых языков мы внедряем обновления компиляторов раз
в 1–2 недели.
Согласованность
Объем кода, не прошедшего обновление, постоянно уменьшается, опять же благодаря регулярным обновлениям.
Осведомленность
Поскольку обновления происходят достаточно регулярно, мы можем выявить
избыточные операции в процессе обновления и попытаться их автоматизировать.
Это в значительной степени совпадает со взглядом SRE на рутину1.
Стратегия
У нас есть процессы и политики, такие как правило Бейонсе, применяя которые
мы делаем обновления выполнимыми. Команды поддержки инфраструктуры
беспокоятся не о каждом неизвестном случае использования, а только о том, что
видно в системе непрерывной интеграции.
Мы осознали не частоту или сложность обновления компилятора, а необходимость
обновлений и проводим их с постоянным числом инженеров даже при постоянном

1

Site Reliability Engineering. Надежность и безотказность, как в Google, глава 5 «Избавляемся
от рутины». — Примеч. пер.

Масштабирование и эффективность   35

росте кодовой базы1. Если бы мы решили, что эта задача слишком дорогостоящая
и ее следует избегать в будущем, мы могли бы до сих пор использовать версию компилятора десятилетней давности и из-за упущенных возможностей оптимизации
заплатить за вычислительные ресурсы на 25 % больше. А наша центральная инфраструктура могла бы подвергнуться значительным рискам безопасности, поскольку
компилятор 2006 года, безусловно, не смягчил бы уязвимости упреждающего выполнения. Стагнация — это вариант, но не самый разумный.

Сдвиг влево

Цена ошибки

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

Идея Проектирование Разработка Тестирование Фиксация Интеграция Эксплуатация
в репозитории

Рис. 1.2. Временная шкала процесса разработки

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

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

36  

Глава 1. Что такое программная инженерия?

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

Компромиссы и затраты
Если вы умеете программировать, знаете, как долго будет служить ПО и как его
поддерживать с увеличением штата инженеров, производящих и сопровождающих
новые функциональные возможности, вам остается только научиться принимать
правильные решения. Очевидно, что в программной инженерии, как и везде, хороший выбор ведет к хорошим результатам. Однако на практике эту истину легко
упустить из виду. В Google неприемлема фраза: «Потому что я так сказал». В любом
нашем обсуждении по любой теме участвуют человек, принимающий решения,
и люди, не согласные с этими решениями. Наша цель — согласие, а не единогласие.
Это нормально, и я привык слышать фразу: «Я не согласен с вашими метриками/
оценками, но я понимаю, как вы могли прийти к такому выводу». В основе этого
подхода лежит идея, что всему должна быть причина, а аргументы «просто потому»,
«потому что я так сказал» или «потому что все так делают» — это признаки плохих
решений. Мы всегда должны уметь объяснить и обосновать выбор между затратами
двух инженерных решений.
Что мы подразумеваем под затратами? Не только деньги, а сумму издержек, включающую любые или все следующие факторы:
y финансовые затраты (например, деньги);
y затраты ресурсов (например, процессорное время);
y затраты на персонал (например, инженерный труд);
y операционные издержки (например, стоимость принятых мер);
y издержки упущенных возможностей (например, стоимость непринятых мер);
y социальные издержки (например, влияние нашего выбора на общество в целом).

Компромиссы и затраты   37

Традиционно легче всего игнорировать социальные издержки. Тем не менее Google
и другие крупные технологические компании сегодня могут с уверенностью развертывать продукты с миллиардами пользователей. Масштаб этих продуктов не
только открывает возможности, но и усиливает последствия даже небольших проблем в удобстве использования, доступности, справедливости, особенно в отношении
маргинализованных групп. ПО проникает во многие аспекты общества и культуры,
поэтому с нашей стороны полезно осознавать как достоинства, так и недостатки
продукта и его технической стороны при его обсуждении (глава 4).
Затраты также зависят от предубеждений: стремления сохранить текущее положение дел, нежелания что-то потерять и др. Оценивая затраты, мы должны
иметь в виду все перечисленные факторы. Здоровье организации — это не только наличие денег в банке, но также осознание ее сотрудниками своей ценности
и продуктивности. В творческих и прибыльных областях, таких как программная
инженерия, в первую очередь нужно оценивать не финансовые затраты, а затраты
на персонал. Увеличение эффективности труда от того, что инженеры довольны,
сосредоточены и вовлечены, требует контроля, потому что показатели сосредоточенности и продуктивности настолько изменчивы, что легко представить себе
разницу от 10 до 20 %.

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

38  

Глава 1. Что такое программная инженерия?

В конце концов, выбор решения в группе инженеров должен сводиться к одному из
двух вариантов:
y мы будем делать так, потому что обязаны (по требованиям законодательства или
клиента);
y мы будем делать так, потому что это лучший вариант (как определено кем-то, наделенным правом решения), в чем можно убедиться, основываясь на текущих данных.
Решения не должны обосновываться фразой: «Мы будем делать так, потому что
я так сказал»1.

Основа для принятия решений
Оценивая данные, мы используем два основных сценария:
y Все учитываемые величины измеримы или, по крайней мере, могут быть оценены.
Обычно это означает возможность оценки компромиссов между процессорами
и сетью, деньгами и оперативной памятью или двумя неделями труда инженеров
и экономией N процессоров в вычислительных центрах.
y Некоторые величины незначительны или мы не знаем, как их измерить. Например, иногда «мы не знаем, сколько времени нужно инженерам». Работать
с такими величинами иногда сложнее, чем «оценить затраты на разработку плохо
спроектированного API» или «оценить влияние выбора продукта на общество».
В первом случае не должно быть недостатка в исходных данных. Любая организация,
занимающаяся разработкой ПО, может и должна контролировать текущие затраты
на вычислительные ресурсы, трудозатраты инженеров и др. Если вы не хотите публиковать точные суммы финансовых затрат, создайте таблицу для пересчета: какое
количество процессоров стоит столько же, сколько стоит данный объем ОЗУ или
данная пропускная способность сети.
Имея согласованную таблицу пересчета, каждый инженер сможет провести собственный анализ: «Если я потрачу две недели на преобразование связного списка
в структуру с более высокой производительностью, то использую на 5 ГБайт больше оперативной памяти, но сэкономлю две тысячи процессоров. Стоит ли овчинка
выделки?» Ответ на этот вопрос зависит не только от относительной стоимости
оперативной памяти и процессоров, но и от затрат на персонал (две недели поддержки инженера-программиста) и стоимости упущенных возможностей (что еще
этот инженер мог бы произвести за две недели?).
Выбрать решение во втором случае сложнее. Обсуждая трудноизмеримые величины,
мы полагаемся на опыт, лидерство и прецедент и вкладываем средства в исследования,
которые помогут количественно оценить то, что трудно поддается количественной
1

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

Компромиссы и затраты   39

оценке (глава 7). Главное, осознавать, что не все измеримо или предсказуемо, и подходить к решениям с осторожностью. Часто трудноизмеримые величины не менее
важны, чем измеримые, но сложнее в управлении.

Пример: распределенная сборка
Рассмотрим пример сборки. Согласно ненаучным опросам в Twitter, 60–70 % разработчиков выполняют сборку ПО (даже большого и сложного) на локальном компьютере. Это стало предметом множества шуток, как в комиксе «Compiling» (https://
xkcd.com/303). Сколько рабочего времени вы теряете в ожидании окончания сборки?
Сравните это с затратами на использование чего-то вроде distcc в небольшой группе
или с затратами на создание маленькой сборочной фермы для большой группы.
Сколько недель/месяцев потребуется, чтобы эти затраты окупились?
Еще в середине 2000-х сборка (проверка и компиляция кода) в Google выполнялась
исключительно на локальных компьютерах. Да, были огромные локальные компьютеры (позволяющие собирать Google Maps!), но с ростом кодовой базы время
компиляции все росло и росло. Неудивительно, что увеличивались затраты на персонал (из-за потерянного времени), а также на ресурсы (из-за закупки более мощных
локальных машин). Затраты на ресурсы были особенно заметны, поскольку большую
часть времени высокопроизводительные машины простаивали. Мы посчитали неправильным вкладывать деньги в невостребованные ресурсы.
Так в Google была создана своя система распределенной сборки. Разумеется, разработка этой системы потребовала определенных затрат: инженерам понадобилось время на
разработку, изменение привычек и рабочих процессов, освоение новой системы, и, конечно, были задействованы дополнительные вычислительные ресурсы. Но общая экономия того стоила: сборка ускорилась, трудозатраты на разработку окупились, а инвестиции в оборудование были направлены на общую инфраструктуру (подмножество
нашего производственного парка), а не на приобретение все более мощных настольных компьютеров. Подробнее о нашем подходе к распределенной сборке в главе 18.
Итак, мы создали новую систему, внедрили ее в производство и ускорили процесс
сборки для всех. Можно ли назвать это счастливым концом истории? Не совсем: со
временем распределенная сборка стала замедляться, поскольку в граф сборки стали
бесконтрольно проникать лишние зависимости. Раньше каждый отдельный инженер
страдал от неоптимальной сборки, был заинтересован в ее ускорении и стремился
что-то улучшить. Избавив инженеров от проблемы оптимизации процесса сборки,
мы создали ситуацию, в которой потребление ресурсов вышло из-под контроля. Это
было похоже на парадокс Джевонса1 (https://oreil.ly/HL0sl): потребление ресурса может
увеличиться в ответ на повышение эффективности его использования.
В целом затраты, связанные с внедрением распределенной системы сборки, намного
перевесили расходы, связанные с ее созданием и обслуживанием. Но мы не преду­
1

https://ru.wikipedia.org/wiki/Парадокс_Джевонса. — Примеч. пер.

40  

Глава 1. Что такое программная инженерия?

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

Пример: выбор между временем и масштабированием
Часто темы, связанные со временем и масштабированием, пересекаются и дополняют друг друга. Хорошо масштабируемые стратегии, такие как правило Бейонсе,
помогают управлять ситуацией с течением времени. Изменение интерфейса ОС
одинаково влияет на все проекты, поэтому мелкие изменения в проектах, вызванные
изменениями в ОС, хорошо масштабируются.
Но иногда время и масштабирование вступают в конфликт, и особенно четко это проявляется в базовом вопросе: лучше добавить зависимость или создать (заимствовать)
новую ветвь, чтобы удовлетворить локальные потребности?
Этот вопрос может возникнуть на разных уровнях стека, поэтому обычно индивидуальное решение для узкой предметной области бывает эффективнее более
общего решения. Ветвление действующего решения и его подгонка под свои нужды
упрощает добавление новых возможностей и дает больше уверенности при его оптимизации, будь то микросервис, кеш в памяти, подпрограмма сжатия или что-то еще
в программной экосистеме. При этом вы получаете контроль: изменения в базовых
зависимостях не будут определены другой командой или сторонним поставщиком,
и вы сами решите, как и когда реагировать на возникающую необходимость перемен.
С другой стороны, если вместо повторного использования каждый разработчик будет
создавать новые версии всего, что нужно проекту, пострадают масштабируемость
и устойчивость. Реагирование на проблему безопасности в базовой библиотеке перестанет быть вопросом обновления отдельной зависимости: оно потребует определить
все уязвимые версии этой зависимости и их пользователей.
И снова программная инженерия не дает универсального ответа, что выбрать. Если
проект имеет небольшую продолжительность жизни или ветвление имеет ограниченный объем, применение ветвления уместно. Но избегайте ветвления интерфейсов,
которые могут жить дольше проекта (структур данных, форматов сериализации,
сетевых протоколов). Согласованность имеет большое значение, но она тоже имеет
цену, и часто выгоднее создавать свои решения, если делать это осторожно.

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

Программная инженерия и программирование   41

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

Программная инженерия и программирование
Узнав, по каким признакам мы различаем программную инженерию и программирование, вы можете спросить, есть ли у нас какие-то внутренние суждения об их
ценности. Можно ли сказать, что программирование хуже программной инженерии?
Или утверждать, что проект, который, как ожидается, будет развиваться сотнями
людей в течение десятилетий, ценнее проекта, который просуществует месяц и будет
создан двумя людьми?
Конечно нет. Мы не считаем, что программная инженерия лучше программирования.
Это две разные предметные области с разными ограничениями, ценностями и методами. Мы осознаем, что некоторые инструменты хороши в одной области и непригодны в другой. Едва ли имеет смысл внедрять интеграционные тесты (глава 14)
и непрерывное развертывание (continuous deployment, глава 24) в проект, который
просуществует несколько дней. Точно так же наши достижения в области семантического управления версиями (SemVer) и управления зависимостями в программной
инженерии (глава 21) не применимы к краткосрочным проектам, в которых можно
смело использовать все, что доступно.
Научитесь различать схожие термины «программирование» и «программная инженерия». Большая часть их различий заключается в подходах к управлению
кодом, влиянии времени на масштабирование и особенностях принятия решений.
Программирование — это непосредственный акт создания кода. Программная инженерия — это набор стратегий, методов и инструментов, помогающих сохранить
полезность кода в течение всего времени его использования и обеспечить возможность совместной работы в команде.

42  

Глава 1. Что такое программная инженерия?

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

Итоги
y «Программная инженерия» более широкое понятие, чем «программирование».
Программирование — это создание кода. Программная инженерия добавляет
к этому понятию обслуживание кода для увеличения срока его использования.
y Продолжительность жизни короткоживущего и долгоживущего кода может отличаться как минимум в 100 000 раз. Было бы неправильно полагать, что одни
и те же практики применимы на обоих концах спектра.
y ПО устойчиво, если в течение ожидаемого срока его службы мы сохраняем способность реагировать на изменения в зависимостях, технологиях или требованиях
к продукту. Мы можем ничего не менять, но должны быть готовы к изменениям.
y Закон Хайрама: при достаточно большом количестве пользователей API не имеет
значения, что вы обещаете в контракте: любое наблюдаемое поведение системы
будет зависеть от чьих-то действий.
y Каждая задача, которую организация должна выполнять снова и снова, должна
масштабироваться (линейно или еще лучше) в отношении участия человека. Политики — прекрасный инструмент для масштабирования процесса.
y Проблемы, обусловленные неэффективностью процесса, и некоторые другие
имеют свойство накапливаться медленно. Они с легкостью могут превратиться
в метафорическую сварившуюся лягушку.
y Опыт окупается особенно быстро в сочетании с экономией за счет масштабирования.
y «Потому что я так сказал» — это плохое обоснование решения.
y Принятие решений на основе данных — хорошее правило, но на практике большинство решений основывается на сочетании данных, предположений, прецедентов и аргументов. Лучше всего, когда объективные данные составляют большую
часть основы для принятия решений, но не всегда есть возможность опираться
только на них.
y Принятие решений на основе данных подразумевает необходимость изменения
направления, если данные изменились или предположения были опровергнуты.
Ошибки и пересмотр планов неизбежны.

ЧАСТЬ II

Культура

ГЛАВА 2

Успешная работа в команде
Автор: Брайан Фитцпатрик
Редактор: Риона Макнамара
В этой главе рассмотрены культурные и социальные аспекты программной инженерии в Google, и сначала мы сосредоточимся на изменяемой величине, которую вы
можете контролировать, — на вас самих.
Люди по своей природе несовершенны. Мы любим говорить, что люди — это комплекс
периодически возникающих ошибок. Но прежде чем искать ошибки в своих коллегах, научитесь распознавать ошибки в себе. Подумайте о своих реакциях, поведении
и отношениях и получите более или менее полное представление о том, как стать
более эффективным и успешным инженером-программистом, который тратит меньше энергии на решение проблем с людьми и больше — на создание отличного кода.
Главная идея этой главы в утверждении, что разработка ПО — это командная работа.
Чтобы добиться успеха в команде инженеров или другом творческом коллективе,
нужно организовать свое поведение в соответствии с основными принципами: смирением, уважением и доверием.
Но не будем забегать вперед и начнем с наблюдения за обычным поведением инженеров-программистов.

Помоги мне скрыть мой код
За последние двадцать лет мы с моим коллегой Беном1 не раз выступали на разных
конференциях по программированию. В 2006 году мы в Google запустили услугу
хостинга для проектов с открытым исходным кодом (OSS, open source software)
(в настоящее время не поддерживается) и получали много вопросов и просьб.
Но примерно в середине 2008 года мы начали замечать определенную направленность запросов:
«Не могли бы вы добавить в поддержку Subversion в Google Code возможность
скрывать определенные ветки?»
«Не могли бы вы добавить возможность создать проект с открытым исходным
кодом, который изначально закрыт, а потом открывается, когда будет готов?»
1

Бен Коллинз-Сассмэн, один из авторов этой книги.

Миф о гениальности   45

«Привет, я хочу переписать весь свой код с нуля, не могли бы вы стереть всю
историю?»
Заметили, что объединяет эти просьбы?
Ответ: неуверенность. Люди боятся, что другие увидят и оценят их работу. С одной
стороны, неуверенность — это часть человеческой натуры, никто не любит, когда
его критикуют, особенно за то, что еще не закончено. Осознание этого помогло нам
заметить более общую тенденцию в разработке ПО: неуверенность на самом деле
является признаком более серьезной проблемы.

Миф о гениальности
Многие неосознанно творят себе кумира и поклоняются ему. Для инженеров-программистов это могут быть: Линус Торвальдс, Гвидо Ван Россум, Билл Гейтс — все они
выдающиеся личности, изменившие мир. Линус в одиночку написал Linux, верно?
На самом деле Линус написал всего лишь начальную версию Unix-подобного ядра
для проверки идей и опубликовал его код в списке рассылки. Безусловно, это большое
и впечатляющее достижение, но оно было только началом. Современное ядро Linux
в сотни раз больше той начальной версии и разрабатывается тысячами умных людей.
Настоящее достижение Линуса в том, что он сумел взять на себя руководство этими
людьми и скоординировать их работу. Linux — блестящий результат, но не его первоначальной идеи, а коллективного труда сообщества. (И ОС Unix была написана не
только Кеном Томпсоном и Деннисом Ритчи, а группой умных людей из Bell Labs.)
Аналогично: разве Гвидо Ван Россум один создал весь Python? Да, он написал
первую версию. Но в разработке последующих версий, реализации новых идей
и исправлении ошибок принимали участие сотни других людей. Стив Джобс руководил командой, которая создавала Macintosh. И хотя Билл Гейтс известен тем,
что написал интерпретатор BASIC для первых домашних компьютеров, его самым
большим достижением стало создание успешной компании вокруг MS-DOS. Все
они стали лидерами и символами коллективных достижений своих сообществ. Миф
о гениальности — это общая тенденция, следуя которой мы, люди, приписываем
успех команды одному человеку.
А что насчет Майкла Джордана?
Та же история. Мы идеализировали его, но он не сам выиграл каждый баскетбольный матч. Его истинная гениальность в том, как он взаимодействовал с командой.
Тренер Фил Джексон был чрезвычайно умен, и его приемы стали легендарными. Он
понимал, что один игрок никогда не выигрывает чемпионат, и поэтому собрал целую
«команду мечты» вокруг Майкла. Эта команда работала как исправный механизм —
играла столь же впечатляюще, как и сам Майкл.
Итак, почему мы постоянно стремимся найти кумира? Покупаем товары, одобренные знаменитостями, хотим купить платье, как у Мишель Обамы, или обувь, как
у Майкла Джордана?

46  

Глава 2. Успешная работа в команде

Тяга к известности — вот одна из причин. У людей есть естественный инстинкт находить лидеров и образцы для подражания, преклоняться перед ними и пытаться
подражать им. Нам всем нужны герои для вдохновения, и в мире программирования
тоже они есть. Феномен «технократической знаменитости» почти перетек в мифологию. Мы все хотим написать что-то, что изменит мир, как Linux, или спроектировать
еще один потрясающий язык программирования.
В глубине души многие инженеры хотят, чтобы их считали гениями. Эта фантазия
выглядит примерно так:
y у вас возникает потрясающая новая идея;
y вы запираетесь в своем убежище на несколько недель или месяцев, создавая совершенное воплощение этой идеи;
y затем «выпускаете» в мир готовое ПО и шокируете всех своей гениальностью;
y ваши коллеги преклоняются перед вашим умом;
y люди выстраиваются в очередь, чтобы заполучить ваше ПО;
y слава и удача преследуют вас.
А теперь остановимся и посмотрим, что мы имеем в реальности. Вы, скорее всего,
не гений.
Не обижайтесь! Конечно, мы верим, что вы очень умный человек. Но понимаете ли
вы, насколько редки настоящие гении? Конечно, вы пишете код, и это сложный навык. Но даже если вы гений, этого для успеха недостаточно. Гении, как и все, делают
ошибки, а блестящие идеи и редкие навыки программирования не гарантируют, что
ваш софт станет хитом. Хуже того, вы можете обнаружить, что способны решать
только аналитические проблемы, но не человеческие. Быть гением не означает быть
«не от мира сего»: любой человек — гений он или нет — с плохими социальными навыками, как правило, является плохим партнером по команде. Для работы в Google
(и в большинстве других компаний!) не требуется иметь гениальный интеллект, но
точно требуется обладать минимальным уровнем социальных навыков. Взлет или
падение вашей карьеры, особенно в такой компании, как Google, во многом зависит
от того, насколько хорошо вы умеете сотрудничать с другими людьми.
Оказывается, этот миф о гениальности — еще одно проявление нашей неуверенности. Многие программисты боятся выкладывать на всеобщее обозрение свою работу,
которую только начали, потому что тогда коллеги увидят их ошибки и поймут, что
автор кода не гений.
Вот что однажды сказал мой друг:
«Я знаю, что КРАЙНЕ не уверен в людях, и опасаюсь показывать им что-то, что
еще не закончено, как будто они осудят меня или подумают, что я идиот».
Это чрезвычайно распространенное чувство среди программистов, и естественной
реакцией на него становится желание спрятаться в своем убежище, чтобы работать,
работать, работать, а затем полировать, полировать, полировать и пребывать в уве-

Сокрытие вредно   47

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

Сокрытие вредно
Работая все время в одиночку, вы увеличиваете риск ненужных неудач и мешаете
росту своего потенциала. Даже при том что разработка ПО — это интеллектуальная
работа, требующая глубокой концентрации и уединения, вы не должны забывать
о ценности (и необходимости!) совместной работы и анализа.
Подумайте сами: как, работая в одиночку, вы сможете понять, что выбрали верный
путь?
Представьте, что вы увлекаетесь проектированием велосипедов и однажды вам
в голову пришла блестящая идея совершенно нового механизма переключения
передач. Вы заказали детали и закрылись на несколько недель в гараже, пытаясь
создать прототип. Когда ваш сосед — также конструктор-энтузиаст — спросил вас,
почему вы избегаете встреч, вы решили не рассказывать ему о своей идее, пока она
не воплотится. Проходит еще несколько месяцев; вы не можете заставить прототип
правильно работать и не спрашиваете совета у друзей.
И вот в один прекрасный день сосед показывает вам свой велосипед с радикально
новым механизмом переключения передач. Оказывается, он конструировал что-то
похожее на ваше изобретение, но с помощью друзей из магазина велосипедов. Вы
испытываете удар по самолюбию и показываете ему свой результат. Он быстро
находит простые недостатки вашего дизайна, которые можно было исправить
в первую неделю работы. Из этой истории можно извлечь несколько поучительных уроков.

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

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

48  

Глава 2. Успешная работа в команде

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

Фактор автобуса
Фактор автобуса определяет, сколько участников проекта должно попасть под
автобус, чтобы проект провалился.
Насколько рассеяны знания и опыт между участниками проекта? Если вы единственный, кто понимает, как работает прототип, вам должна быть обеспечена особая
безопасность — если вас собьет автобус, проект прогорит. Но, взяв кого-нибудь
в напарники, вы удвоите фактор автобуса. А если с вами будет работать небольшая команда специалистов, вместе создающих и разрабатывающих прототипы,
ситуация улучшится еще больше — проект будет продолжен после ухода одного
члена команды. Сотрудники могут жениться, уехать, уйти из компании или взять
отпуск по уходу за родственником. Даже простое наличие хорошей документации
и одного-двух ведущих специалистов в каждой области поможет обеспечить успех
проекта в будущем и увеличит фактор автобуса проекта. Надеемся, что большинство
инженеров понимают, что лучше быть частью удачного проекта, чем критической
частью неудачного.
Помимо фактора автобуса существует проблема общего темпа развития. Легко
забыть, что работа в одиночку — это сложная задача, которая решается гораздо
медленнее, чем хотелось бы. Как много вы узнаете, работая в одиночку? Как быстро
вы движетесь к цели? Google и Stack Overflow являются отличными источниками
мнений и информации, но они не могут заменить реальный человеческий опыт.
Работа с другими людьми напрямую увеличивает коллективные знания. Когда вы
остановились из-за абсурдной проблемы, сколько времени вы потратите, чтобы вытащить себя из ямы? Подумайте, насколько изменится ваш опыт, если пара коллег
будет смотреть вам через плечо и сразу указывать на ошибки и варианты их устранения. Именно поэтому в компаниях, занимающихся разработкой ПО, члены одной
команды часто сидят вместе (или даже занимаются парным программированием).
Программирование — сложная наука. Программная инженерия — еще сложнее. Вам
нужна эта вторая пара глаз.

1

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

Сокрытие вредно   49

КЕЙС: ИНЖЕНЕРЫ И ОФИСЫ
Двадцать пять лет назад считалось, что единственный способ работать над решением задачи, не отвлекаясь на посторонние дела, — иметь отдельный кабинет с закрытой дверью.
Думаю, большинству инженеров1 не только не нужно находиться в отдельном кабинете, но
и вредно. Современное ПО создается командами, а не одиночками, и постоянный контакт
с другими членами команды ценнее соединения с интернетом. В отдельном кабинете вы
будете иметь массу времени для обдумывания своих решений, но, двигаясь в неправильном
направлении, вы потратите это время впустую.
К сожалению, многие современные технологические компании (включая Google) качнули
маятник в другую крайность. Зайдите в их офисы — и найдете сотни инженеров, сидящих
вместе в огромных залах. В настоящее время ведутся жаркие споры о целесообразности
опен-спейсов и, как следствие, растет неприятие их. Там, где самый малозначительный
разговор становится публичным, люди перестают общаться, чтобы не раздражать соседей.
Это так же плохо, как отдельные кабинеты!
Мы считаем, что лучшее решение — золотая середина. Сгруппируйте команды по четыревосемь человек в небольших комнатах (или больших офисах), чтобы упростить случайное
общение между ними.
Конечно, инженерам нужна возможность фильтровать шум. И они придумывали способы
сообщить, что их не следует прерывать. Например, использовали протокол голосового
прерывания — фразу «Прервись, Мэри», где Мэри — имя человека, с которым нужно поговорить. По возможности Мэри поворачивалась лицом и слушала. Если она была занята,
то отвечала: «Не сейчас».
Также они ставили на свои мониторы флажки или игрушки, чтобы показать, что прерывать
их можно только в случае крайней необходимости. В некоторых командах инженерам выдавались наушники с шумоподавлением. К слову, во многих компаниях сам факт ношения
наушников обычно расценивается как сигнал, означающий «не беспокой меня, если это не
очень важно». Многие инженеры, приступая к написанию кода, переходят в режим работы
«в наушниках», что может быть полезно, если период изоляции длится недолго и не создает
в офисе глухих стен.
Не поймите нас неправильно — мы все еще считаем, что инженеры должны иметь возможность сосредоточиться на написании кода, но мы думаем, что им также необходимо беспрепятственное общение с командой. Если коллега не может просто задать вам вопрос — это
проблема, а найти правильный баланс — это искусство.

Темп развития
Еще одна аналогия. Вспомните, как вы используете компилятор. Тратите несколько
дней, чтобы написать 10 000 строк кода, а затем нажимаете кнопку «компилировать».
Так? Конечно нет. Представьте неприятные последствия такого подхода. Программисты увереннее работают, когда пишут код небольшими фрагментами, используя
1

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

50  

Глава 2. Успешная работа в команде

короткие циклы с обратной связью: написали новую функцию — скомпилировали,
добавили тест — скомпилировали, выполнили рефакторинг участка кода — скомпилировали. Это позволяет быстро выявлять и исправлять опечатки и ошибки в коде.
Компилятор нужен нам для проверки каждого маленького шага. Некоторые среды
программирования могут даже компилировать код сразу после ввода. Современная
философия DevOps, направленная на повышение продуктивности, четко говорит
о целях: получать отзывы как можно раньше, тестировать как можно раньше и начинать думать о безопасности в продакшене как можно раньше. Все это связано с идеей
«сдвига влево» в рабочем процессе разработчика и удешевлении устранения ошибки.
Короткий цикл обратной связи необходим не только на уровне кода, но и на уровне
всего проекта. Амбициозные проекты развиваются быстро и должны адаптироваться
к меняющимся условиям. Они могут сталкиваться с непредсказуемыми архитектурными ограничениями, политическими препятствиями или техническим несоответствием. Требования могут меняться неожиданно. Как обеспечить быструю обратную
связь, чтобы вовремя узнавать, когда следует менять планы или решения? Ответ:
работать в команде. Большинству инженеров известна истина: «Чем больше глаз,
тем заметнее ошибки». Но ее можно перефразировать иначе: «Чем больше глаз, тем
успешнее проект справляется с вызовами». Люди, работающие в затворничестве,
рискуют однажды обнаружить, что мир изменился, и несмотря на полноту и правильность первоначальных представлений, проект стал неактуальным.

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

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

Весь секрет в командной работе   51

людьми. Поделитесь своим видением. Разделите труд. Учитесь у других. Создайте
блестящую команду.
Подумайте, сколько есть примеров широко используемого ПО, написанного одним
человеком? (Кто-то вспомнит «LaTeX», но вряд ли этот продукт «широко используется», если только вы не считаете, что число людей, пишущих научные статьи,
является статистически значимой частью всех пользователей компьютеров!)
Высокоэффективные команды — это золотая жила и верный ключ к успеху. Приложите все силы, чтобы создать такую команду.

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

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

1

Это невероятно сложно, если в прошлом вы погорели, передав управление некомпетентным
людям.

52  

Глава 2. Успешная работа в команде

проще пустить все на самотек. Работать с предсказуемым компилятором намного
проще, не так ли? Зачем вообще погружаться в социальную сферу?
Вот цитата из известной лекции Ричарда Хэмминга (http://bit.ly/hamming_paper):
«Взяв за правило рассказывать секретарям анекдоты и проявлять немного дружелюбия, я получал от них очень ценную помощь. Например, однажды по какой-то
дурацкой причине все копировальные службы в Мюррей Хилл оказались заняты.
Не знаю почему. Надо было что-то делать. Моя секретарша позвонила кому-то
в Холмдел, прыгнула в служебный автомобиль, провела час в дороге, скопировала
материал и вернулась. Это стало мне наградой за то, что я не ленился приободрять ее, шутил и вообще был дружелюбен. Мне это ничего не стоило, но позже
такое мое поведение окупилось. Столкнувшись с необходимостью использовать
систему и изучая возможные способы заставить систему делать вашу работу, вы
учитесь менять систему под себя».
Вывод прост: не стоит недооценивать социальные игры. Это не обман или манипулирование, а выстраивание отношений, помогающих достичь цели. Отношения
всегда живут дольше, чем проекты. При хорошем отношении коллеги будут готовы
пройти лишнюю милю, если вам это потребуется.

Смирение, уважение и доверие на практике
Все эти речи о смирении, уважении и доверии звучат как проповедь. Давайте
спустимся на грешную землю и подумаем, как применить эти идеи в жизни. Для
начала рассмотрим список конкретных моделей поведения и примеры. Многие из
этих моделей покажутся очевидными, но вскоре вы заметите, как часто вы (и ваши
коллеги) не следуете им — мы заметили это в себе!
Усмирите свое эго
Если вы замечаете, что кому-то не хватает смирения, проще всего попросить этого
человека быть скромнее. Никто не горит желанием работать с тем, кто постоянно
ведет себя как самый важный человек в комнате. Даже если вы уверены в своем превосходстве, не показывайте этого. Подумайте, так ли необходимо, чтобы последнее
слово всегда оставалось за вами? Так ли важно комментировать каждую деталь
в предложении или обсуждении? Вы знаете людей, которые так себя ведут?
Скромным быть важно, но это не значит, что можно показывать слабину — в уверенности в себе нет ничего плохого. Просто не стройте из себя всезнайку. Думайте
о «коллективном» эго — старайтесь поддерживать командный дух и коллективную
гордость. Например, Apache Software Foundation имеет долгую историю создания
сообществ вокруг программных проектов. Эти сообщества отличает невероятно
сильное самосознание: они отвергают людей, озабоченных саморекламой.
Эго имеет множество проявлений и часто мешает работать. Вот еще одна замечательная история из лекции Хэмминга, которая прекрасно иллюстрирует проявление
личного эго (выделение наше):

Весь секрет в командной работе   53

«Джон Тьюки почти всегда одевался очень небрежно. Когда он приходил в офис,
руководители не сразу понимали, что перед ними первоклассный специалист,
к мнению которого стоит прислушаться. Джон тратил много времени и сил на
преодоление такого неприятия! Я не говорю, что вы должны соответствовать
окружению, но обращаю ваше внимание, что “видимость соответствия здорово
помогает”. Если вы будете утверждать свое эго, заявляя: “Это будет по-моему”,
то будете расплачиваться за это на протяжении всей своей карьеры. И в других
сферах жизни это будет приводить к огромному числу ненужных неприятностей.
Столкнувшись с необходимостью использовать систему и изучая возможные способы заставить систему делать вашу работу, вы учитесь менять систему
под себя. В противном случае вам придется бороться с ней постоянно и всю свою
жизнь вести маленькую необъявленную войну».
Учитесь критиковать и принимать критику
Несколько лет назад Джо устроился на новую работу программистом. Спустя неделю он начал копаться в кодовой базе. Его заинтересовало, какой вклад в код внес
каждый член команды. Он стал отправлять им простые обзоры кода по электронной
почте, вежливо спрашивая о проектных решениях или указывая места, где можно
улучшить логику. Через пару недель его вызвали в кабинет директора. «В чем проблема? — спросил Джо. — Я сделал что-то неправильно?» «У нас было много жалоб
на ваше поведение, — сказал директор. — По-видимому, вы были очень резки по
отношению к своим товарищам по команде, критикуя их налево и направо. Они расстроены. Вам следует быть вежливее». Джо был совершенно сбит с толку. Конечно,
он думал, что коллеги оценят и с радостью примут его обзоры кода. Однако Джо
должен был проявить большую осторожность и уважительность к членам команды
и использовать более тонкие средства для внедрения код-ревью в культуру — возможно, предварительно обсудить идеи с командой и предложить попробовать новый
подход в течение нескольких недель.
В профессиональной среде программной инженерии критика почти никогда не
бывает личной — обычно она просто является частью процесса улучшения проекта. Хитрость в том, чтобы убедиться, что вы (и те, кто вас окружает) понимаете
разницу между конструктивной критикой творческих результатов и откровенным
оскорблением чувств. Последнее — мелочно и недейственно. Первое может (и должно!) быть полезным, если содержит рекомендации по улучшению. И самое главное,
конструктивная критика проникнута уважением: человек, выступающий с такой
критикой, искренне заботится о других и хочет, чтобы они совершенствовали себя
или свой труд. Научитесь уважать своих коллег и вежливо подавать конструктивную
критику. Если вы действительно уважаете кого-то, у вас будет мотивация выбирать
тактичные и понятные формулировки — навык, приобретаемый с опытом (глава 9).
С другой стороны, нужно учиться принимать критику. Не только скромнее оценивать
свои навыки, но и верить, что в глубине души коллеги действуют в ваших интересах (и в интересах проекта!) и на самом деле не считают вас умственно отсталым.

54  

Глава 2. Успешная работа в команде

Программирование — это обычный навык. Если коллега указал вам пути улучшения
мастерства, разве вы воспримете это как оскорбление и принижение вашего достоинства? Надеемся, что нет. Точно так же ваша самооценка не должна быть связана
с кодом, который вы пишете, или любым творческим проектом, над которым вы
работаете. Вы — это не ваш код: повторяйте это снова и снова. Вы — это не то, что
вы делаете. Поверьте в это сами и заставьте коллег считать так же.
Например, если у вас есть неуверенный в себе коллега, вам точно не следует говорить ему: «Дружище, ты совершенно неправильно понял поток управления в этом
методе. Ты должен использовать стандартный шаблон xyzzy, как и все остальные».
Так поступать не следует: говорить человеку, что он «не прав» (как если бы мир
был черно-белым), требовать изменений и заставлять его чувствовать себя хуже
других. Коллега вне всяких сомнений обидится, и его реакция наверняка окажется
чрезмерно эмоциональной.
То же самое можно сказать более тактично: «Знаешь, меня смущает поток управления в этой части. Интересно, сможет ли применение шаблона xyzzy сделать его
понятнее и проще в поддержке?» Обратите внимание, как в этом случае проявляется
смирение, как акцент ставится на себе, а не на собеседнике. Вы утверждаете, что не
коллега ошибся, а вы не поняли код. Этой фразой вы предлагаете лишь прояснить
ситуацию для вас, что, возможно, поспособствует достижению цели устойчивого
развития проекта в долгосрочной перспективе. Вы также ничего не требуете — даете
коллеге возможность мирно отклонить предложение. Обсуждение сосредоточено на
коде, а не на чьих-то умственных способностях или навыках.
Получив отрицательный результат, повторите попытку
В деловом мире существует городская легенда о менеджере, который допустил
ошибку и потерял 10 миллионов долларов. На следующий день он уныло входит
в офис и начинает собирать свои вещи, а когда ему звонят с неизбежной фразой:
«Генеральный директор хочет видеть вас в своем кабинете», он тащится в кабинет
директора и тихо кладет заявление на стол.
«Что это?» — спрашивает директор.
«Мое заявление об уходе, — говорит менеджер. — Полагаю, вы вызвали меня,
чтобы уволить».
«Уволить? Вас? — отвечает директор недоверчиво. — Зачем мне вас увольнять?
Я только что заплатил 10 миллионов долларов за ваше обучение!»1
Конечно, это весьма необычная история, но генеральный директор в ней понимает,
что увольнение менеджера не возместит потерю 10 миллионов долларов, а только
усугубит ситуацию потерей ценного работника, который, в чем можно не сомневаться,
не повторит своей ошибки.
1

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

Весь секрет в командной работе   55

Один из наших любимых девизов в Google: «Неудача — тоже вариант». Как известно,
«не ошибается тот, кто ничего не делает» и «кто не рискует, тот не пьет шампанское».
Неудача — это прекрасная возможность учиться и совершенствоваться1. На самом
деле Томас Эдисон часто повторял: «Если я попробую 10 000 способов, которые не
сработают, я не потерплю неудачу. Я не отчаюсь, потому что каждая неудачная попытка — это еще один шаг вперед».
В Google X — подразделении, занимающемся прорывными технологиями, такими
как беспилотные автомобили и ретрансляторы для доступа в интернет на воздушных
шарах, — неудачи намеренно встроены в систему стимулирования. Люди придумывают диковинные идеи, а их коллегам активно рекомендуется как можно быстрее
доказать невозможность их воплощения. Люди получают вознаграждение (и даже
соревнуются) за опровержение определенного количества идей или одной идеи
в течение определенного времени. И только когда никому не удалось опровергнуть
идею, она переходит на первую стадию создания прототипа.

Культура подробного анализа причин неудачи
Извлечению уроков из ошибок главным образом способствует документирование
неудач с помощью анализа основных причин и описания «результатов вскрытия»
проблем (как это называют в Google и многих других компаниях). Будьте особенно
внимательны: документ с описанием результатов вскрытия не должен быть бесполезным списком оправданий — он должен содержать объяснение причин проблем
и план дальнейших действий и быть доступным всем, чтобы команда действительно
следовала предложенным изменениям. Правильное документирование ошибок помогает сохранить понимание того, что произошло, и избежать повторения истории.
Не стирайте следы — освещайте их, как взлетно-посадочную полосу, для тех, кто
следует за вами!
Хорошее описание результатов вскрытия должно включать:
y краткое описание события;
y историю развития события от его обнаружения до расследования и получения
выводов;
y основную причину события;
y оценку влияния события и ущерба;
y перечень действий и мероприятий, предпринятых для немедленного исправления
проблемы;
y перечень действий и мероприятий, направленных на предотвращение повторения
события;
y уроки и выводы.
1

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

56  

Глава 2. Успешная работа в команде

Учитесь терпению
Несколько лет назад я работал над инструментом для преобразования репозиториев
CVS в Subversion (а позже в Git). Из-за капризов CVS я все время натыкался на
странные ошибки. Поскольку мой давний друг и коллега Карл хорошо знал CVS,
мы решили поработать вместе и исправить эти ошибки.
Когда мы начали парное программирование, возникла проблема: я предпочитал
восходящий способ и погружался в самый низ, быстро выискивая варианты пути наверх, минуя детали. Карл, напротив, отдавал предпочтение нисходящему способу: он
стремился получить полную картину о ландшафте и погрузиться в реализацию почти
каждого метода в стеке вызовов, прежде чем приступить к устранению ошибки. Это
приводило к межличностным конфликтам, разногласиям, а иногда и ожесточенным
спорам. Дошло до того, что мы просто не могли программировать вместе — это было
слишком сложно для нас обоих.
Тем не менее мы давно питали безграничное доверие и уважение друг к другу. Небольшая доля терпения помогла нам выработать новый метод сотрудничества. Мы
садились вместе за компьютер, выявляли ошибку, а затем разделяли ее и атаковали
сразу с двух сторон (сверху вниз и снизу вверх), а потом объединяли полученные
результаты. Наши терпение и готовность экспериментировать с новыми стилями
работы спасли не только проект, но и дружбу.
Будьте открыты для сотрудничества
Чем больше вы открыты для сотрудничества, тем выше ваша способность влиять
на других и тем сильнее вы кажетесь. Это заявление выглядят противоречивым.
Но практически каждый может вспомнить коллегу-упрямца — кто бы что ему ни говорил, он еще больше запирался в своем упрямстве. Что в итоге происходит с такими
членами команды? Люди перестают прислушиваться к их мнению или возражениям,
начинают «обходить» таких коллег как препятствие, от которого никуда не деться.
Вы наверняка не захотите быть таким человеком, поэтому помните: это нормально,
когда кто-то хочет вас переубедить. В первой главе этой книги мы говорили, что
инженерия — это компромиссы. Нельзя быть правым во всем и всегда, если у вас нет
неизменного окружения и совершенных знаний. Поэтому вы должны менять свою
точку зрения, когда вам представят новые доказательства. Тщательно расставляйте
свои приоритеты: чтобы быть услышанным, сначала выслушайте других. Соберите аргументы коллег, прежде чем остановить обсуждение и твердо объявить свое
решение, — если вы будете постоянно колебаться, меняя свою точку зрения, люди
подумают, что вы слабовольный и нерешительный.
Идея уязвимости может показаться странной. Если кто-то признается в своем незнании
рассматриваемой темы или путей решения проблемы, на какое доверие он может рассчитывать? Уязвимость — это проявление слабости, которое разрушает доверие, верно?
Неверно! Признание, что вы допустили ошибку или просто не подтвердили свой
уровень, может в долгосрочной перспективе повысить ваш статус. На самом деле
готовность показать уязвимость — это внешнее проявление смирения, которое

Весь секрет в командной работе   57

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

Действовать по-гугловски
У нас в Google есть собственная внутренняя версия принципов «смирения, уважения
и доверия».
С самого начала существования нашей культуры мы называли действия «по-гуг­
ловски» (googley) или «не по-гугловски». Ни в одном словаре вы не найдете это слово,
но оно означает «не будь злым», «поступай правильно» или «будь добр к другим».
Со временем мы начали использовать термин «по-гугловски» как неформальный
признак соответствия нашей культуре у кандидатов на должность инженера или
у коллег. Люди часто выражают мнение о других, используя этот термин, например
«человек пишет хороший код, но действует не совсем по-гугловски».
В конце концов, мы поняли, что термин «по-гугловски» перегружен смыслом и может
стать источником неосознанной предвзятости при найме или оценке работы. Если
для каждого сотрудника выражение «по-гугловски» будет означать что-то свое, есть
риск свести его к «совсем как я». Очевидно, что это не лучший тест для найма новых
сотрудников — мы не хотим нанимать людей, которые «совсем как мы», нам нужны
люди из разных слоев общества, с разными мнениями и опытом. Личное желание
интервьюера выпить пива с кандидатом (или коллегой) никогда не должно рассматриваться как признак, что кто-то является хорошим кандидатом или сотрудником
и сможет добиться успеха в Google.
В конечном итоге мы в Google решили эту проблему, явно определив, что под «погугловски» подразумевается набор черт характера, которые мы ищем, включающие
сильные лидерские способности и приверженность «смирению, уважению и доверию».
Развитие в неопределенности
Умение, имея дело с противоречивыми сообщениями или указаниями, достичь
согласия и добиться прогресса в решении проблемы, даже если окружающая
среда постоянно меняется.
Бережное отношение к обратной связи
Умение уважительно принимать критику и давать обратную связь и понимание
ценности обратной связи для личного (и командного) развития.

58  

Глава 2. Успешная работа в команде

Стремление изменить текущее положение вещей
Умение ставить амбициозные цели и достигать их, даже когда коллеги сопротивляются или проявляют инертность.
Пользователь прежде всего
Понимание пользователей продуктов Google, уважительное отношение к их
мнению и готовность предпринять действия, отвечающие их интересам.
Заботливое отношение к команде
Сочувственное и уважительное отношение к коллегам, готовность оказывать
им активную помощь без лишних вопросов и улучшать сплоченность команды.
Правильные поступки
Соблюдение этических норм во всем и готовность принимать сложные или неудобные решения для защиты целостности команды и продукта.
В настоящее время, определив желательные черты характера и образ поведения
сотрудника, мы начали уходить от использования термина «по-гугловски». Всегда
лучше четко обозначать свои ожидания!

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

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

ГЛАВА 3

Обмен знаниями
Авторы: Нина Чен и Марк Баролак
Редактор: Риона Макнамара
Искать ответы на вопросы, связанные с вашей предметной областью, лучше внутри организации, а не в интернете. Но для этого организации нужны эксперты и механизмы
распространения знаний, о которых мы поговорим в этой главе. Эти механизмы могут
быть очень простыми (задать вопрос и написать ответ) и более структурированными,
такими как учебные пособия и классы. Самое главное — в организации должна поддерживаться культура обучения, которая требует создания чувства психологической
безопасности, позволяющего людям признавать недостаток собственных знаний.

Сложности в обучении
Обмен опытом между организациями — непростая задача, особенно при отсутствии
устойчивой культуры обучения. Компания Google уже сталкивалась с рядом проблем, главным образом в период роста.
Отсутствие чувства психологической безопасности
Среда, в которой люди боятся рисковать или совершать ошибки из страха наказания. Часто проявляется как культура страха или стремление избегать прозрачности.
Информационные островки
Фрагментация знаний, возникающая, когда разные подразделения организации
не общаются друг с другом или не используют общие ресурсы. В такой среде
каждая группа создает свой способ действий1. Это часто приводит к следующему:
Фрагментация информации
Каждый островок представляет лишь часть общей картины.
Дублирование информации
На каждом островке изобретается свой способ решения одной и той же задачи.

1

Другими словами, вместо того чтобы разрабатывать один глобальный максимум, в организации создается множество локальных максимумов (https://oreil.ly/6megY).

60  

Глава 3. Обмен знаниями

Информационный перекос
На островках по-разному используется одно и то же решение.
Единая точка отказа (ЕТО)
Узкое место, возникающее, когда важная информация поступает только от одного
человека (вспомните фактор автобуса (https://oreil.ly/IPT-2) из главы 2).
Она может появиться из самых благих намерений вроде предложения «давай
я сделаю это вместо тебя» и давать кратковременное увеличение эффективности («так быстрее») в ущерб долгосрочной перспективе развития (команда не
учится выполнять работу). ЕТО приводит к победе принципа «все или ничего».
Принцип «все или ничего»
Команда, в которой проведена грань между теми, кто знает «все», и новичками.
Если эксперты всегда и все делают сами, не тратя времени на подготовку новых
экспертов путем наставничества или создания инструкций, знания и обязанности
продолжают накапливаться у тех, кто уже имеет опыт, а новые члены команды
брошены и развиваются медленно.
Попугайство
Повторение без понимания сути. Обычно характеризуется бездумным копированием паттернов или кода без понимания их цели на основе предположения, что
это необходимо по неизвестным причинам.
Кладбища с привидениями
Места, обычно в коде, которых люди стараются не касаться, потому что боятся,
что что-то может пойти не так. В отличие от вышеупомянутого попугайства,
для кладбищ с привидениями характерно отсутствие каких-либо действий из-за
страха и суеверий.
В оставшейся части главы мы рассмотрим успешные политики преодоления этих
сложностей, обнаруженные инженерами Google.

Философия
Программную инженерию можно определить как командную разработку многоверсионного ПО1, в центре которой находятся люди. Да, код — это важный результат, но
лишь малая часть создания продукта. Необходимо отметить, что код не возникает
сам по себе из ничего, равно как и опыт. Каждый эксперт когда-то был новичком:
успех организации зависит от роста ее сотрудников и инвестиций в них.
Совет эксперта всегда неоценим. Члены команды могут разбираться в разных областях, поэтому выбор товарища по команде, которому можно задать любой вопрос,
1

Parnas D. L. Software Engineering: Multi-person Development of Multi-version Programs.
Heidelberg: Springer-Verlag Berlin, 2011.

Создание условий: психологическая безопасность   61

очень важен. Но если эксперт уходит в отпуск или переходит в другой коллектив,
команда может оказаться в беде. И хотя один человек может оказать помощь многим,
эта помощь не масштабируется и ограничивается числом «многих».
Документированные знания лучше масштабируются не только в команде, но и во
всей организации. Такие механизмы, как командная электронная база знаний (wiki),
позволяют множеству авторов делиться своим опытом с большими группами людей.
Но масштабируемость документации сопровождается компромиссами между ее
обобщенностью и применимостью к конкретным ситуациям, а также требует дополнительных затрат на обслуживание и поддержание ее актуальности.
Между знаниями отдельных членов команды и задокументированными знаниями
находятся коллективные знания. Эксперты часто знают то, что нигде не задокументировано. Если задокументировать эти знания и поддерживать их, они станут
доступными не только тем, кто имеет возможность общаться с экспертом, но и всем,
кто сможет найти и прочитать документацию.
Получается, что в идеальном мире, где все всегда и сразу документируется, нет нужды консультироваться с человеком, верно? Не совсем. Письменные знания имеют
преимущества масштабирования, но целевая личная помощь ничуть не менее ценна.
Человек-эксперт может синтезировать свои знания, оценить, какая информация
применима к конкретному случаю, определить актуальность документации и знать,
где ее найти или к кому обратиться.
Коллективные и письменные знания дополняют друг друга. Даже идеальная команда экспертов с совершенной документацией должна общаться друг с другом,
координировать действия с другими командами и адаптировать свои политики.
Никакой подход к обмену знаниями не может быть правильным сразу для всех
типов обучения, и лучшее сочетание, скорее всего, будет зависеть от особенностей
организации. Организационные знания, вероятно, будут меняться по мере роста
организации. Тренируйтесь, сосредоточьтесь на обучении и росте и создайте свою
группу экспертов. Инженерных знаний много не бывает.

Создание условий: психологическая безопасность
Психологическая безопасность имеет решающее значение для формирования образовательной среды.
Чтобы учиться, вы должны сначала осознать, что есть что-то, чего вы не понимаете.
Мы должны приветствовать такую честность (https://xkcd.com/1053), а не наказывать
ее. (В Google эта работа поставлена довольно хорошо, но иногда инженеры не хотят
признавать, что они чего-то не понимают.)
Значительная часть обучения — это способность пробовать что-то и чувствовать
себя в безопасности. В здоровой среде люди чувствуют себя комфортно, задают
вопросы, ошибаются и приобретают новые знания. Исследование в Google (https://

62  

Глава 3. Обмен знаниями

oreil.ly/sRqWg) показало, что психологическая безопасность является самым важным

условием создания эффективной команды.

Наставничество
Мы в Google стараемся задать тон общения, когда к компании присоединяется
«нуглер» (новый гуглер). Чувство психологической безопасности мы создаем с помощью назначения наставника — человека, который не является членом команды,
менеджером или техническим руководителем, в обязанности которого входит отвечать на вопросы и оказывать помощь нуглеру. Наличие официально назначенного
наставника для обращения за помощью облегчает новичку работу и избавляет его
от страха, что он может отнимать время у коллег.
Наставник — это доброволец, работающий в Google больше года и готовый консультировать новичка по любым вопросам, от использования инфраструктуры до навигации
по культуре Google. Он поддерживает нуглера, когда тот не знает, к кому обратиться
за советом. Наставник не входит в одну команду с новичком, что позволяет второму
чувствовать себя более комфортно при обращении за помощью.
Наставничество формализует и облегчает обучение, но самообучение — это непрерывный процесс. Коллеги всегда учатся друг у друга: как новые сотрудники, так
и опытные инженеры, изучающие новые технологии. В здоровой команде коллеги
могут не только давать ответы, но и задавать вопросы, не боясь показать, что они
чего-то не знают.

Психологическая безопасность в больших группах
Обратиться за помощью к коллеге по команде легче, чем к большой группе в основ­ном
незнакомых людей. Но, как мы видели, индивидуальные решения плохо масштабируются. Групповые решения более масштабируемы, но они также более пугающие.
Новичкам может быть страшно задать вопрос большой группе, зная, что он может
храниться в архиве много лет. Потребность в психологической безопасности усиливается в больших группах. Каждый член группы должен сыграть свою роль в создании
и поддержании безопасной среды, гарантирующей, что новички не будут бояться
задавать вопросы, а начинающие эксперты будут чувствовать, что способны помочь
новичкам, не опасаясь нападок со стороны авторитетных экспертов.
Самый действенный способ создать такую безопасную и гостеприимную среду —
заменить состязательность групп их сотрудничеством. В табл. 3.1 приведены некоторые примеры рекомендуемых паттернов (и соответствующих им антипаттернов)
групповых взаимодействий.
Эти антипаттерны могут возникать непреднамеренно: кто-то, возможно, пытается помочь, но случайно проявляет снисходительность и неприветливость. Мы считаем, что
здесь уместно перечислить социальные правила сообщества Recurse Center (https://
oreil.ly/zGvAN):

Расширение знаний   63

Никакого притворного удивления («Что?! Я не могу поверить! Ты не знаешь, что
такое стек?!»)
Притворное удивление разрушает чувство психологической безопасности и заставляет членов группы бояться признаться в нехватке знаний.
Никаких «на самом деле»
Скрупулезные исправления, которые, как правило, связаны с игрой на публику,
а не с точностью.
Никаких подсказок из задних рядов
Прерывание текущего обсуждения, чтобы предложить свое мнение, без корректного вступления в разговор.
Никаких «-измов» («Это так просто, что даже моя бабушка справилась бы!»)
Выражения предвзятости (расизм, эйджизм, гомофобия), которые могут заставить людей чувствовать себя ненужными, неуважаемыми или незащищенными.
Таблица 3.1. Паттерны групповых взаимодействий
Рекомендуемые паттерны
(сотрудничество)

Антипаттерны
(состязательность)

Простые вопросы или ошибки правильно воспринимаются
и находят ответы и решения

К простым вопросам или ошибкам придираются, и человек,
задавший вопрос, наказывается

Объяснения направлены на обучение человека, задавшего
вопрос

Объяснения направлены на демонстрацию своих знаний

На вопросы даются полезные ответы с терпением и доброжелательностью

Ответы даются свысока, в язвительной и неконструктивной
форме

Взаимодействия принимают форму общего обсуждения
для поиска решений

Взаимодействия принимают форму спора между «победителями» и «проигравшими»

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

Задавайте вопросы
Главный урок этой главы: постоянно учитесь и задавайте вопросы.
Мы говорим нуглерам, что на раскачку может уйти до шести месяцев. Этот длительный период необходим для освоения большой и сложной инфраструктуры Google, но
он также подтверждает идею о том, что обучение — это непрерывный итеративный
процесс. Одна из самых больших ошибок, которую допускают новички, — не просят помощи в сложной ситуации. Возможно, вам нравится преодолевать проблемы
в одиночку или вы боитесь, что ваши вопросы «слишком просты». «Я должен по-

64  

Глава 3. Обмен знаниями

пробовать решить проблему сам, прежде чем просить о помощи», — думаете вы. Не
попадайтесь в эту ловушку! Часто ваши коллегия являются лучшим источником
информации: используйте этот ценный ресурс.
Не заблуждайтесь: день, когда вы вдруг обнаружите, что знаете все, не наступит
никогда. Даже у инженеров, годами работающих в Google, возникают ситуации,
когда они не знают, что делать, и это нормально! Не бойтесь говорить: «Я не знаю,
что это такое, не могли бы вы объяснить?» Относитесь к незнанию как к области
возможностей, а не страха1.
Неважно, кто вы — новичок или ведущий специалист: вы всегда должны находиться
в среде, где есть чему поучиться. В отсутствие такой среды неизбежен застой, при
котором вам стоит поискать новую среду.
Моделировать такое поведение особенно важно для тех, кто играет руководящую
роль: важно не приравнивать «руководство» к «знанию всего». На самом деле чем
больше вы знаете, тем больше понимаете, что ничего не знаете (https://oreil.ly/VWusg).
Открыто задавая вопросы2 или показывая пробелы в знаниях, вы подтверждаете, что
для других это тоже нормально.
Терпение и доброжелательность отвечающего способствуют созданию атмосферы,
в которой нуждающиеся в помощи чувствуют себя в безопасности. Помогите человеку, задающему вам вопрос, преодолеть нерешительность. Инженеры, вероятно,
смогли бы самостоятельно разобраться в коллективных знаниях, но они пришли не
для того, чтобы работать в вакууме. Адресная помощь помогает инженерам работать
быстрее, что, в свою очередь, повышает эффективность всей команды.

Вникайте в контекст
Обучение — это не только узнавание чего-то нового, но и развитие понимания
решений, лежащих в основе существующего дизайна и реализации. Представьте,
что вашей команде поручили развивать унаследованную кодовую базу критически
важной части инфраструктуры, существовавшей много лет. Ее авторы давно ушли,
а код непонятен. Может возникнуть соблазн переписать все заново и не тратить время
на изучение существующего кода. Но вместо того чтобы воскликнуть: «Я ничего не
понимаю», и закончить на этом, попробуйте погрузиться глубже: какие вопросы вы
должны задать?
Рассмотрим принцип «забора Честерсона» (https://oreil.ly/Ijv5x): перед тем как
удалить или изменить что-то, сначала разберитесь, зачем это «что-то» здесь находится.
1

2

Синдром самозванца (https://oreil.ly/2FIPq) не редкость среди успешных учеников, и гуглеры
не исключение. Большинство авторов этой книги тоже подвержены синдрому самозванца.
Мы понимаем, что страх неудачи пугает людей с синдромом самозванца и может затормозить
развитие.
См. статью «How to ask good questions» (https://oreil.ly/rr1cR).

Масштабирование вопросов: вопросы к сообществу   65

В деле реформирования, в отличие от деформирования, существует один простой и ясный принцип, который можно назвать парадоксом. Представьте, что
существуют определенные нормы или законы, например забор, построенный
поперек дороги. Молодой реформатор радостно подходит к забору и говорит:
«Я не вижу в нем смысла, давайте уберем его». На что более умный реформатор
вполне может ответить: «Коль скоро вы не увидите пользы, я не позволю убрать
его. Идите и подумайте. А потом скажете мне, что вы видите в нем определенную
пользу, и я позволю снести его».
Это не означает, что код не может быть лишен ясности или существующие паттерны
проектирования не могут быть неправильными, но часто инженеры склонны приходить к выводу «это плохо!» быстрее, чем нужно, особенно в отношении незнакомого
кода, языков или парадигм. Google тоже не застрахован от такого подхода. Ищите
и вникайте в контекст, особенно в решениях, которые кажутся необычными. Когда
вы поймете суть и цель кода, подумайте, имеет ли смысл ваше изменение. Если да, то
смело меняйте код. Но если нет, задокументируйте свои рассуждения для будущих
читателей.
Многие руководства по стилю в Google включают дополнительные подробности,
чтобы помочь читателям понять причины существующих рекомендаций по стилю,
а не просто запомнить список произвольных правил. Понимание причин появления
данного руководства позволяет авторам принимать обоснованные решения о том,
когда руководство должно перестать применяться и его следует обновить (глава 8).

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

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

66  

Глава 3. Обмен знаниями

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

Списки рассылки
Для большинства тем в Google есть список рассылки topic-users@ или topic-discuss@
в Google Groups, к которому может присоединиться любой сотрудник компании.
Вопросы в общедоступной рассылке задаются так же, как в групповом чате: их видят множество людей, знающих и не знающих ответ. В отличие от групповых чатов,
общедоступные списки рассылки распространяют информацию среди более широкой
аудитории: они упакованы в архивы, лучше структурированы и предусматривают
возможность поиска. В Google списки рассылки также индексируются и их легко
найти с помощью Moma — поисковой системы во внутренней сети Google.
После получения ответа на вопрос может возникнуть соблазн немедленно продолжить работу. Не торопитесь! Возможно, в будущем кому-то пригодится полученная
вами информация (https://xkcd.com/979), поэтому опубликуйте ответ в списке рассылки.
Списки рассылки не лишены недостатков. Они хорошо подходят для сложных вопросов, которые требуют описания большого количества деталей, но для быстрого
обмена информацией между участниками больше подходят групповые чаты. Тема,
посвященная конкретной проблеме, обычно наиболее полезна, когда она активно
обсуждается. Архивы электронной почты остаются практически неизменными, и порой бывает трудно определить, соответствует ли ответ в старой ветке обсуждения
текущей ситуации. Кроме того, в списке рассылки может быть больше шума, чем,
например, в официальной документации, поскольку решение, найденное в списке
рассылки, может оказаться неприменимым для вас.

Распространяйте знания: вам всегда есть чему научить других   67

ЭЛЕКТРОННАЯ ПОЧТА В GOOGLE
Google печально известна чрезмерно широким проникновением электронной почты во все
аспекты ее деятельности. Инженеры Google получают сотни (если не больше) электронных
писем каждый день с различной степенью важности. Нуглеры могут потратить несколько
дней на настройку фильтров электронной почты, чтобы справиться с объемом уведомлений,
поступающих от групп, на которые они автоматически подписаны; многие из них просто
сдаются и не пытаются успевать читать все письма. Некоторые группы по умолчанию
вкладывают большие списки рассылки в каждое обсуждение, создавая нежелательный шум.
Мы склоняемся к организации рабочих процессов с использованием электронной почты.
Электронная почта не является лучшим средством передачи информации, но к ней мы
привыкли. Обдумайте целесообразность ее использования, когда будете выбирать формы
коммуникации.

YAQS: система вопросов и ответов
YAQS (yet another question system) — это внутренняя версия Stack Overflow для
Google (https://oreil.ly/iTtbm). Она позволяет гуглерам ссылаться на существующий
или разрабатываемый код, а также обсуждать конфиденциальную информацию.
Так же как Stack Overflow, система YAQS обладает многими преимуществами списков рассылки и добавляет дополнительные достоинства: ответы, отмеченные как
полезные, продвигаются вверх в пользовательском интерфейсе, и пользователи могут
редактировать вопросы и ответы, чтобы они оставались точными и полезными при
изменении кода и фактов. Сегодня в Google одни списки рассылки заменены системой
YAQS, а другие превратились в дискуссионные списки более широкой направленности и в меньшей степени ориентированные на решение проблем.

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

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

68  

Глава 3. Обмен знаниями

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

Технические обсуждения и учебные классы
В Google выработана надежная культура внутренних и внешних1 технических обсуждений и учебных классов. Наша команда engEDU (engineering education) специализируется на организации обучения в области computer science для самой широкой
аудитории, от инженеров Google до студентов по всему миру. На более низком уровне
наша программа g2g (googler to googler) позволяет гуглерам регистрироваться и читать (или посещать) лекции и занятия от коллег в Google2. Эта программа пользуется
оглушительным успехом, и тысячи участвующих в ней гуглеров преподают самые
разные темы, от технических (например, «Понимание векторизации в современных
процессорах») до довольно забавных (например, «Танец свинг для начинающих»).
Технические обсуждения обычно проводятся лектором, выступающим непосредственно перед аудиторией. Занятия в классе, с другой стороны, могут включать
лекцию, но больше сосредоточены на упражнениях и требуют активного участия
слушателей. Как результат, занятия под руководством наставника обычно более трудоемкие и дорогостоящие в организации и поддержке, чем технические обсуждения,
и предназначены для более важных или сложных тем. Тем не менее после создания
класса его относительно легко масштабировать, потому что сразу несколько преподавателей могут читать курс, опираясь на одни и те же материалы. Мы обнаружили,
что классы предпочтительнее при следующих условиях:
y Тема достаточно сложна, из-за чего часто является источником недоразумений.
Создание классов — кропотливая работа, которая должна быть обоснована.
y Тема относительно стабильная. Обновление материалов класса — трудная задача,
поэтому, если предмет быстро развивается, используйте другие формы передачи
знаний.
y По данной теме наставники готовы отвечать на вопросы и оказывать персональную помощь. Если учащиеся легко могут самостоятельно освоить тему,
эффективнее использовать инструменты самообучения, такие как документация
или аудио- и видеозаписи. Ряд вводных курсов в Google имеет версии для самостоятельного изучения.
1
2

Вот пара примеров: https://talksat.withgoogle.com и https://www.youtube.com/GoogleTechTalks.
Программа g2g подробно описана в книге Ласло Бока «Работа рулит! Почему большинство
людей в мире хотят работать именно в Google» (М.: МИФ, 2015), которая включает описания
различных аспектов программы, а также способы оценки воздействия и рекомендации, на
что следует обратить внимание при создании аналогичных программ. — Примеч. пер.

Распространяйте знания: вам всегда есть чему научить других   69

y Спрос на регулярное проведение класса достаточно высок. В противном случае
потенциальные учащиеся могут получить необходимую информацию другими
способами. В Google классы особенно актуальны для небольших, географически
удаленных офисов.

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

Обновление документации
Когда вы узнаете что-то новое, уделите внимание улучшению существующей документации и учебных материалов. Освоив новый процесс или систему, вы забудете,
с какими сложностями сталкивались раньше и чего вам не хватало во вводной документации. Если найдете ошибку или упущение в документации, исправьте ее! Оставляйте место стоянки чище, чем оно было до вашего прихода1, и пробуйте обновлять
документацию самостоятельно, даже если она принадлежит другому подразделению.
В Google инженеры чувствуют себя вправе обновлять документацию, кому бы она
ни принадлежала, даже если исправление касается опечатки. Уровень поддержки
сообщества заметно повысился с внедрением g3doc2, значительно упростившим гуг­
лерам поиск владельца документации для передачи ему своих предложений. Кроме
того, такой подход помогает оставить след в истории изменений.
Создание документации
Наращивая мастерство, пишите новую документацию и обновляйте существующую.
Например, если вы настроили новый процесс разработки, запишите, какие шаги
выполнили. Так вы облегчите путь тем, кто следует за вами. Но еще лучше помочь
другим самостоятельно находить ваш документ. Недоступность или неизвестность
1

2

См. «The Boy Scout Rule» (https://oreil.ly/2u1Ce) и книгу Кевина Хиннея (Kevin Henney)
«97 Things Every Programmer Should Know» (Boston: O’Reilly, 2010).
Название g3doc означает «документация google3». google3 — это название текущего воплощения монолитного репозитория исходного кода в Google.

70  

Глава 3. Обмен знаниями

местоположения документации равноценны ее отсутствию. В g3doc документация
находится рядом с исходным кодом, а не в (недоступном) документе или на неизвестной веб-странице.
Наконец, убедитесь в наличии механизма обратной связи. Если у читателей не будет
простого способа сообщить, что документация устарела или неточна, они, скорее
всего, ничего и никому не расскажут и следующий новичок столкнется с той же
проблемой. Люди охотнее вносят изменения, если чувствуют, что кто-то действительно заметит и рассмотрит их предложения. В Google есть возможность отправить
сообщение об ошибке непосредственно в самом документе.
Кроме того, гуглеры могут легко оставлять комментарии на страницах g3doc. Другие
гуглеры имеют возможность читать и отвечать на эти комментарии, и поскольку
оставление комментария автоматически вызывает отправку сообщения об ошибке
владельцу документации, читателю не нужно выяснять, к кому обратиться.
Продвижение документации
Иногда бывает трудно стимулировать инженеров на документирование своих действий. Работа над документацией требует времени и сил, ее результаты неочевидны,
и ими в большинстве случаев пользуются другие. Подобная асимметрия, при которой
многие извлекают выгоду из затрат времени немногих, полезна для организации
в целом, но она требует хороших стимулов. Мы обсудим некоторые из них в разделе
«Стимулы и признание» ниже.
Тем не менее автор документа часто тоже может получить непосредственную выгоду
от написания документации. Предположим, что члены команды всегда обращаются
к вам за помощью в устранении определенных видов сбоев в работе. Документирование используемых вами процедур потребует затрат времени, но выполнив эту
работу один раз, вы сэкономите время в будущем, передав членам команды ссылку
на документацию и отвлекаясь на практическую помощь только при необходимости.
Написание документации также помогает команде и организации расширяться. Вопервых, информация в документации становится каноничной: члены группы могут
ссылаться на общий документ и даже обновлять его самостоятельно. Во-вторых, она
может распространиться за пределы команды, если некоторые части документации
не являются уникальными для команды и будут полезны для других команд, решающих подобные задачи.

Код
На метауровне код — это знание, поэтому процесс написания кода можно считать
формой описания знаний. Обмен знаниями может не являться прямым намерением
при разработке кода, но является побочным эффектом, который можно усилить
читабельностью и ясностью кода.
Документирование кода является еще одним из способов обмена знаниями. Четкая
документация приносит пользу не только пользователям библиотеки, но и тем, кто

Распространение знаний с ростом организации   71

в будущем будет ее сопровождать. Комментарии в коде тоже передают знания: они
пишутся специально для будущих читателей (включая вас в будущем!). С точки
зрения компромиссов комментарии в коде имеют те же недостатки, что и документация в целом: они должны активно поддерживаться, чтобы не устареть и не начать
противоречить коду.
Обзоры кода (глава 9) часто дают возможность обучения и авторам, и рецензентам.
Например, предложение рецензента может познакомить автора с новым паттерном
тестирования или рецензент может узнать о новой библиотеке, увидев, как автор
использует ее в своем коде. Google стандартизирует наставничество посредством
обзоров, определяя процесс повышения удобочитаемости (подробнее в конце этой
главы).

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

Развитие культуры обмена знаниями
Организационная культура — это хрупкое человеческое творение, полезность которого многие компании осознают с опозданием. Но мы в Google считаем, что внимание
к культуре и окружающей среде1 позволяет добиться большего, чем сосредоточение
на результатах этой среды, таких как код.
Крупные организационные изменения — сложная задача, и на эту тему написано
бесчисленное количество книг. Мы не претендуем на знание всех ответов в этой
области, но можем поделиться конкретными шагами, которые предпринимались
в Google для создания культуры, способствующей обучению.
Прочитайте книгу «Работа рулит!», чтобы больше узнать о культуре Google.
Уважение
Отталкивающее поведение нескольких человек может сделать неприветливыми целую команду или сообщество (https://oreil.ly/R_Y7N). В недружелюбной среде новички
учатся задавать вопросы в другом месте, а перспективные специалисты опускают
руки, не имея возможности расти. В худшем случае в группе остаются только наиболее токсичные ее члены. Выбраться из этого состояния может быть очень трудно.
Обмен знаниями может и должен осуществляться с доброжелательностью и уважением. В технологических организациях терпимость или, что еще хуже, почтение
к «блестящему ничтожеству» одновременно и распространены, и вредны, но быть
1

Бок Л. Работа рулит! Почему большинство людей в мире хотят работать именно в Google.
М.: МИФ, 2015.

72  

Глава 3. Обмен знаниями

экспертом и быть добрым — это не взаимоисключающие характеристики. В разделе
«Лидерство» корпоративного документа Google четко говорится об этом:
«Хотя некоторая степень технического лидерства приветствуется на более высоких
уровнях, тем не менее лидерство не всегда направлено на решение технических
проблем. Лидеры помогают окружающим людям расти, улучшают психологический климат команды, создают культуру командной работы и сотрудничества,
смягчают напряженность в команде, доказывают личным примером важность
культуры и ценностей Google и делают Google более динамичным и интересным
местом для работы. Хамы — плохие лидеры».
Урс Хельцле (Urs Hölzle, старший вице-президент по технической инфраструктуре)
и Бен Трейнор Слосс (Ben Treynor Sloss, вице-президент, основатель Google SRE)
написали регулярно цитируемый внутренний документ «No Jerks» («Не хами»)
о том, почему гуглеры должны заботиться об уважительном поведении на работе
и как этого достичь.
Стимулы и признание
Хорошую культуру необходимо активно развивать, и для продвижения культуры
обмена знаниями необходимо иметь систему поощрений и вознаграждений. Для
многих организаций характерна распространенная ошибка, когда на словах говорят
о наборе ценностей, а на деле активно поощряют поведение, не связанное с этими ценностями. Люди реагируют на стимулы, а не на дежурные фразы, поэтому при создании
системы поощрений и вознаграждений важно, чтобы слова не расходились с делом.
Google использует различные механизмы признания заслуг, от общекорпоративных
стандартов, таких как анализ эффективности и критерии продвижения, до взаимных
поощрений между гуглерами.
Штатное расписание, которое мы используем для измерения вознаграждений, таких
как премии и карьерный рост, побуждает инженеров делиться знаниями. На более
высоких уровнях поощряется авторитет сотрудника, который должен увеличиваться
с карьерным ростом. На высших уровнях примеры лидерства включают следующее:
y Растите будущих лидеров, служите наставниками для младших сотрудников,
помогайте им развиваться как в техническом плане, так и в корпоративном.
y Поддерживайте и развивайте сообщества разработчиков ПО в Google, выполняя
обзоры кода и дизайна, организуя инженерное образование и разработку, а также
давая экспертные рекомендации.
Подробнее о лидерстве в главах 5 и 6.

Штатное расписание — это способ управления культурой сверху. Но в Google культура
также управляется снизу, например через программу вознаграждения коллег — это

Распространение знаний с ростом организации   73

денежное вознаграждение и формальное признание, которыми любой гуглер может
поощрить другого гуглера за его работу1. Например, когда Рави предлагает дать
премию коллеге Джулии за то, что она является главным автором списка рассылки — регулярно отвечая на вопросы, чем приносит пользу многим сотрудникам, — он
публично признает ее вклад в обмен знаниями и ее авторитет за пределами команды.
Поскольку вознаграждения со стороны коллег ориентированы на сотрудников, они
интересуют всех.
Кроме вознаграждений от коллег распространено также публичное признание вклада (как правило, меньшего по отдаче или усилиям, чем те, которые заслуживают
вознаграждения от коллег), повышающее авторитет гуглера среди коллег.
Когда гуглер дает другому гуглеру вознаграждение или похвалу, он может отправить
копию наградного письма группам или отдельным лицам, способствуя увеличению
известности своего коллеги. Кроме того, руководители, получая такие наградные
письма, обычно рассылают их членам своей команды, чтобы те могли отметить достижения друг друга.
Система, в которой люди могут выражать официальное признание своим коллегам,
является мощным инструментом поощрения, стимулирующим сотрудников продолжать творить и удивлять коллег. Важно не вознаграждение, а признание.

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

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

74  

Глава 3. Обмен знаниями

Читатели могут заметить, что какая-то каноническая информация устарела, но
обычно у них нет достаточного опыта для ее изменения, даже если инструменты
позволяют это сделать.
Создание и поддержка централизованных канонических источников информации — дорогостоящий и трудоемкий процесс, и не все материалы можно совместно
использовать на уровне организации. При оценке усилий, которые придется приложить для формирования этого ресурса, учитывайте особенности аудитории. Кому
нужна информация? Вам? Команде? Всем участникам проекта? Всем инженерам?
Руководства разработчиков
В Google имеется широкий набор официальных руководств для инженеров, включая
руководства по стилю (http://google.github.io/styleguide), официальные рекомендации
по разработке ПО1, руководств по проверке кода2 и тестированию3, а также «Советы
недели» (TotW, tips of the week)4.
Объем информации чрезвычайно велик, и бессмысленно ожидать, что инженеры
прочтут ее всю от начала до конца, а тем более усвоят одномоментно. Поэтому эксперт, уже знакомый с некоторым руководством, может отправить ссылку на него
коллеге-инженеру для ознакомления. Так эксперт экономит время, которое мог
потратить на объяснение практики, принятой в компании, а учащийся узнает о существовании канонического источника информации, к которому можно обратиться
в любое время. Такой процесс масштабирует знания, поскольку позволяет экспертам
определять и удовлетворять конкретные информационные потребности, используя
общие ресурсы.
Ссылки go/
Ссылки go/ (которые иногда называют ссылками goto/) — это сокращения внутренних
URL в Google5. Большинство внутренних ссылок в Google имеют, по крайней мере,
одну внутреннюю ссылку go/. Например, «go/spanner» предоставляет информацию
о Spanner, а «go/python» ссылается на руководство Google для разработчиков на
Python. Сама информация может храниться в любом репозитории (g3doc, Google
Drive, Google Sites и т. д.), но наличие ссылки go/ обеспечивает запоминающийся
и интуитивно определяемый способ доступа к данным. Такое решение дает ряд преимуществ:
y Ссылки go/ настолько короткие, что ими легко обмениваться в разговоре («Обязательно проверь go/frobber!»). Это гораздо проще, чем искать ссылку и отправлять
ее в сообщении. Удобство обмена ссылками повышает скорость распространения
знаний.
1
2
3
4
5

Например, книги о разработке ПО в Google.
См. главу 9.
См. главу 11.
Доступны для нескольких языков. Извне доступен сборник для C++ (https://abseil.io/tips).
Ссылки go/ не имеют отношения к языку Go.

Распространение знаний с ростом организации   75

y Ссылки go/ имеют постоянный характер и будут работать, даже если изменится
базовый URL. Когда владелец перемещает контент в другой репозиторий (например, из Google doc в g3doc), он может просто обновить целевой URL ссылки
go/. Сама ссылка go/ остается неизменной.
Ссылки go/ настолько укоренились в культуре Google, что возник благоприятный
замкнутый круг: ищущий информацию о Frobber сначала проверяет ссылку go/
frobber, и если она не указывает на «Руководство разработчика Frobber» (вопреки
ожиданиям), то гуглер сам настраивает ссылку. В результате гуглеры часто угадывают
правильную ссылку go/ с первой попытки.
Лабораторные работы
Лабораторные работы (codelab) Google размещены в учебных пособиях, которые
объясняют инженерам новые идеи или процессы путем объединения теории, примеров и упражнений1. Каноническая коллекция лабораторных работ для технологий,
широко используемых в Google, доступна на go/codelab. Перед публикацией лабораторные работы проходят несколько этапов формального анализа и тестирования
и являются интересным промежуточным звеном между статической документацией
и учебными классами, однако обладают не только лучшими, но и худшими их чертами. Практический характер лабораторных работ делает их более привлекательными,
чем традиционная документация, — инженеры могут получить к ним доступ по запросу и выполнить самостоятельно, но они требуют дорогостоящей поддержки и не
учитывают индивидуальных потребностей учащегося.
Статический анализ
Инструменты статического анализа — это мощный способ обмена знаниями, которые
можно проверить в программе. Каждый язык программирования имеет свои особые
инструменты статического анализа, но все они объясняют авторам и рецензентам
кода, как можно улучшить код с помощью стиля и передовых практик. Некоторые
инструменты идут дальше и предлагают автоматически применить рекомендации.
Подробнее об инструментах статического анализа и их использовании в Google
в главе 20.

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

Извне лабораторные работы доступны по адресу: https://codelabs.developers.google.com. (Лабораторные работы на русском языке, хотя и не все, можно найти по адресу: https://codelabs.
developers.google.com/lang-ru/ — Примеч. пер.)

76  

Глава 3. Обмен знаниями

Важно оставаться в курсе событий
Есть информация, которая имеет решающее значение для работы, например знание
особенностей типичного рабочего процесса разработки. Другая информация, такая
как обновления популярных инструментов оценки производительности, — менее
критична, но все же важна. Таким образом, требования к среде обмена информацией
зависят от важности распространяемых сведений. Например, пользователь ожидает,
что официальная документация будет обновляться, но обычно не ждет того же от
информационных бюллетеней, благодаря чему владелец может уменьшить затраты
на их поддержку и обслуживание.
Новостные рассылки
В Google широко используются новостные рассылки для всех инженеров: EngNews
(технические новости), Ownd (новости, касающиеся конфиденциальности и безопасности) и Google Greatest Hits (отчеты о наиболее интересных ситуациях за
квартал). Это хороший способ передачи информации, которая представляет интерес
для инженеров, но не является критически важной. Изучив эту сторону проблемы
информирования, мы обнаружили, что новости вызывают больший интерес, когда
рассылаются реже и содержат исключительно полезные сведения. В противном
случае они воспринимаются как спам.
Большинство рассылок в Google распространяется по электронной почте, однако
создатели некоторых из них проявили креатив. «Тестирование в туалете» (советы
по тестированию) и «Обучение в уборной» (советы по повышению производительности) — это одностраничные информационные бюллетени, размещаемые в туалетных комнатах. Этот уникальный способ распространения новостей выделяется
среди других источников информации, а все выпуски бюллетеней сохраняются
в электронном архиве.
Историю о том, как появился бюллетень «Тестирование в туалете», вы найдете
в главе 11.

Сообщества
Гуглеры любят создавать сообщества, объединяющие сотрудников разных подразделений, для обмена знаниями по различным темам. Эти открытые каналы связи
позволяют учиться у коллег, находящихся за пределами вашего круга общения,
и предотвращать образование информационных островков и дублирование сведений.
Особой популярностью пользуются Google Groups: в Google есть тысячи внутренних групп, официальных, полуофициальных и неофициальных. Некоторые из них
обсуждают вопросы устранения неполадок, другие (например, Code Health) больше
ориентированы на дискуссии и оказание помощи. Внутренняя служба Google+ также
популярна среди гуглеров как неформальный источник информации, где специали-

Удобочитаемость: наставничество через обзоры кода   77

сты описывают интересные технические неполадки или подробности о проектах,
над которыми работают.

Удобочитаемость: наставничество через обзоры кода
Термин «удобочитаемость» имеет в Google более широкое толкование, чем просто
удобочитаемость кода. Это стандартизированный общекорпоративный процесс наставничества, главной целью которого является распространение передовых практик
программирования. Удобочитаемость охватывает широкий спектр знаний, включая
языковые идиомы, структуру кода, дизайн API, использование распространенных
библиотек, документацию и тестирование.
Внедрение поддержки удобочитаемости начиналось с усилий одного человека.
В самом начале существования Google Крейг Сильверстейн (идентификационный
номер сотрудника 3) лично садился рядом с каждым новым сотрудником и проводил
построчную «проверку удобочитаемости» его первого кода, отправляемого в репозиторий. Это была очень придирчивая проверка, которая охватывала все — от способов
улучшения кода до следования соглашениям об использовании пробелов и отступов.
Благодаря таким проверкам база кодов в Google приобрела единообразный вид, но,
что особенно важно, в ходе обзора новые сотрудники учились передовым практикам,
узнавали, что из общей инфраструктуры им доступно, и получали наглядное представление о том, как следует писать код в Google.
Со временем поток людей, нанимаемых в Google, вырос настолько, что один человек
уже не мог уделить внимание всем новичкам. Многие инженеры нашли прошлый
опыт настолько ценным, что добровольно приняли участие в программе. Сегодня
около 20 % инженеров Google участвуют в процессе поддержки удобочитаемости
как рецензенты или авторы кода.

В чем заключается процесс поддержки удобочитаемости?
Код-ревью обязателен в Google. Каждый список изменений (CL, changelist)1 требует
одобрения удобочитаемости владельцем сертификата удобочитаемости. Сертифицированные авторы неявно подтверждают удобочитаемость своих собственных CL,
а CL других авторов одобряют один или несколько квалифицированных рецензентов. Это требование появилось после того, как компания Google выросла до такой
степени, что стало невозможно обеспечить получение каждым инженером обзоров
кода, которые учили бы передовым практикам с желаемой степенью строгости.
Подробнее о том, как в Google осуществляются обзоры кода и что в этом контексте означает «одобрение», в главе 9.

1

Список изменений (changelist) — это список файлов в VCS, в которые вносились изменения.
Список изменений является синонимом набора изменений (changeset, https://oreil.ly/9jkpg).

78  

Глава 3. Обмен знаниями

Обладание сертификатом удобочитаемости в Google обычно называется «владением
удобочитаемостью» для некоторого языка. Инженеры, владеющие удобочитаемостью,
демонстрируют умение писать понятный, идиоматичный и легкосопровождаемый
код, который иллюстрирует лучшие практики Google и лучший стиль оформления
кода для данного языка. Для этого централизованная группа рецензентов удобочитаемости проводит CL через процесс оценки удобочитаемости, после которого
сообщает, насколько представленные изменения демонстрируют уровень мастерства
автора. По мере того как авторы усваивают рекомендации по удобочитаемости, они
получают все меньше и меньше замечаний, пока наконец сами не получат сертификат
удобочитаемости. Обладателю сертификата доверяют продолжать применять свои
знания в своем коде и выступать в роли рецензента кода другого инженера.
Примерно 1–2 % инженеров Google являются рецензентами удобочитаемости. Все
рецензенты — это добровольцы, и любой, кто получит сертификат удобочитаемости,
может выдвигать себя на роль рецензента удобочитаемости. Рецензенты придерживаются самых высоких стандартов, потому что от них ожидается не только глубокое
знание языка, но и способность обучать. Они должны воспринимать поддержку
удобочитаемости прежде всего как процесс наставничества и сотрудничества, а не
контроля или состязания. Рецензентам и авторам CL рекомендуется дискутировать
в процессе рецензирования. Рецензенты добавляют ссылки в свои комментарии,
чтобы авторы могли узнать мотивы, по которым те или иные рекомендации вошли
в руководство по стилю («забор Честерсона»). Если обоснование какой-то рекомендации неясно, авторы должны просить разъяснений («задавать вопросы»).
Поддержка удобочитаемости — это процесс, управляемый человеком, цель которого —
масштабировать знания стандартизированным и в то же время персонализированным
способом. Дополняя комплекс письменных и коллективных знаний, удобочитаемость
сочетает в себе преимущества документации, доступ к которой можно получить
с помощью ссылок, и общения с наставниками, которые знают, на какие фрагменты
руководства лучше сослаться. Канонические и языковые рекомендации полностью
документированы (и это хорошо!), но объем информации настолько велик1, что
усвоить его трудно, особенно новичкам.

Зачем нужен этот процесс?
Код читают множество людей, особенно в масштабах Google и нашего (очень большого) монолитного репозитория2. Любой инженер может заглянуть в код других
1

2

По состоянию на 2019 год одно только руководство по стилю для C++ насчитывало 40 страниц. Дополнительный документ, описывающий совокупность передовых практик, во много
раз длиннее.
Узнать, почему в Google используется монолитный репозиторий, можно здесь: https://
cacm.acm.org/magazines/2016/7/204032-why-google-stores-billions-of-lines-of-code-in-a-singlerepository/fulltext. Также имейте в виду, что не весь код в Google хранится в монолитном

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

Удобочитаемость: наставничество через обзоры кода   79

команд и извлечь нужные уроки, а мощные инструменты, такие как Kythe (https://
kythe.io), позволяют легко находить ссылки по всей кодовой базе (глава 17). Важной
особенностью документирования передовых практик (глава 8) является обеспечение согласованных стандартов для всего кода в Google. Удобочитаемость является
механизмом как соблюдения, так и распространения стандартов.
Одно из основных преимуществ программы поддержки удобочитаемости заключается в том, что она дает инженерам больше, чем просто коллективные знания, накопленные их командой. Чтобы получить сертификат удобочитаемости, инженеры
должны отправлять CL централизованной команде рецензентов, которые проверяют
код всей компании. Централизация проверки дает существенные выгоды: программа ограничена линейным масштабированием с ростом организации, но позволяет
упростить соблюдение согласованности, препятствует появлению островков и (часто
непреднамеренному) отклонению от установленных норм.
Значение согласованности всей кодовой базы невозможно переоценить: даже если
десятки тысяч инженеров будут писать код десятилетиями, согласованность гарантирует, что код на данном языке будет выглядеть одинаково во всем корпусе.
Это позволяет читателям сосредоточиться на том, что делает код, а не на том, как
он выглядит. Авторам масштабных изменений (глава 22) легче вносить изменения
по всему монолитному репозиторию для тысяч команд. Люди могут переходить из
команды в команду и быть уверенными, что способ использования языка в новой
команде не сильно отличается от способа, применявшегося в предыдущей команде.
Эти преимущества имеют свою цену: поддержка удобочитаемости — это сложный
процесс по сравнению с другими средствами распространения знаний, такими как
документация и учебные курсы, потому что она обязательна и обеспечивается инструментами Google (глава 19). Эти затраты нетривиальны и выражаются:
y в дополнительных сложностях для команд, в которых нет рецензентов удобочитаемости, потому что им приходится искать рецензентов вне своей команды,
чтобы получить одобрение удобочитаемости для CL;
y в дополнительных затратах времени на проверку кода авторов, которые сами не
являются рецензентами;
y в линейном масштабировании специфической работы узкого круга рецензентов.
Перевешивает ли выгода эти затраты? Нужно учитывать фактор времени: выгоды
и затраты имеют разный временной охват. Программа сознательно идет на краткосрочные затраты, вызванные задержками на проверку кода, чтобы получить долгосрочные выгоды в виде высококачественного кода, согласованного по всему репозиторию, и накопление опыта инженерами. Долгосрочные преимущества обусловлены
ожиданием, что написанный код будет служить годы, если не десятилетия1.
1

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

80  

Глава 3. Обмен знаниями

В большинстве инженерных процессов всегда есть возможность что-то улучшить.
Некоторые затраты можно уменьшить с помощью инструментов. Многие проблемы
удобочитаемости могут обнаруживаться статически и автоматически комментироваться с помощью инструментов статического анализа. Благодаря постоянному развитию таких инструментов рецензенты удобочитаемости могут фокусироваться на
аспектах более высокого порядка: делать код понятным сторонним читателям, зная,
что, например, пробелы в конце строки будут обнаружены автоматизированными
средствами.
Но одного стремления к лучшему недостаточно. Удобочитаемость вызывает споры:
некоторые инженеры считают, что это ненужное бюрократическое препятствие
и неэффективное использование рабочего времени инженера. Действительно ли
выгоды от программы поддержки удобочитаемости перевешивают затраты на нее?
За ответом мы обратились к нашей команде по исследованию продуктивности (EPR,
engineering productivity research).
Команда EPR провела углубленные исследования положительных и отрицательных
сторон программы поддержки удобочитаемости, в том числе выяснив, мешает ли
этот процесс людям, научились ли они чему-нибудь или изменили ли свое поведение
в ходе участия в программе. Исследования показали, что процесс поддержки удобочитаемости оказывает положительное влияние на скорость разработки. На проверку CL авторов, овладевших навыками удобочитаемости, обычно уходит меньше
времени1. Удовлетворенность инженеров качеством своего кода, по их личным
отзывам (в отсутствие более объективных показателей качества), выше среди тех,
кто участвовал в программе удобочитаемости. Значительное большинство инженеров, прошедших программу, сообщают об удовлетворенности процессом и считают
его стоящим. Они утверждают, что многому научились у рецензентов и изменили
свое поведение, стараясь избегать проблем с удобочитаемостью при разработке
и рецензировании кода.
Подробное описание этого исследования и внутреннего исследования продуктивности инженеров в Google в главе 7.

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

1

дуктах) и программа Area 120 (https://area120.google.com) — творческая мастерская для
экспериментальных продуктов Google.
На этот показатель влияет множество факторов, включая срок работы в Google и тот факт,
что для проверки списков изменений авторов, не владеющих удобочитаемостью, обычно
требуется проводить дополнительные раунды рецензирования.

Итоги   81

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

Итоги
y

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

y

Начните с малого: задавайте вопросы и записывайте ответы.

y

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

y

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

y

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

ГЛАВА 4

Инженерия равенства
Автор: Демма Родригес
Редактор: Риона Макнамара
В предыдущих главах мы исследовали различия между программированием —
процессом разработки кода, решающего текущие проблемы, и программной инженерией — подходом, предполагающим более широкое применение инструментов,
стратегий и процессов для решения текущих и будущих возможных проблем в коде,
который может служить десятилетия. В этой главе мы обсудим уникальные обязанности инженера при разработке программных продуктов для широкого круга
пользователей и оценим, как организация, используя разнообразие подходов, может
проектировать системы «для всех».
Мы все еще довольно слабо представляем, какое влияние программная инженерия
оказывает на различные группы людей и общества, и все еще учимся понимать, как
создавать продукты, которые расширяют возможности и уважают всех пользователей.
У нас было много громких неудач в отношении наиболее уязвимых пользователей,
и поэтому мы решили написать эту главу: путь к более качественным продуктам
начинается с оценки неудач и стимулирования роста.
Этой главой мы также хотим подчеркнуть растущий дисбаланс сил между теми, кто
принимает решения, и теми, на кого эти решения влияют (в частности, маргинализованные сообщества). Важно поразмыслить над тем, что мы узнали, и поделиться
идеями с инженерами-программистами следующего поколения, чтобы они работали
лучше, чем мы сегодня.
Тот факт, что вы взяли в руки эту книгу, скорее всего, означает ваше стремление
стать выдающимся инженером. Вы хотите решать проблемы. Стремитесь создавать
продукты, обеспечивающие положительные результаты для самого широкого круга
людей, включая тех, кому трудно угодить. Представьте, как будут использоваться
инструменты, созданные вами, чтобы изменить траекторию развития человечества.

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

Предвзятость — это проблема   83

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

КЕЙС: В GOOGLE НЕДОСТАТОЧНО ПОЛНО ПРЕДСТАВЛЕНЫ РАЗНЫЕ РАСОВЫЕ ГРУППЫ
В 2015 году инженер-программист Джеки Алсине (Jacky Alciné) заметил2, что алгоритмы
распознавания изображений в Google Photos классифицируют его темнокожих друзей как
«горилл». Google не спешила реагировать на эти ошибки.
Чем вызван такой феерический провал? Тому есть несколько причин:
• Алгоритмы распознавания изображений зависят от наличия «правильного» (часто имеется в виду «полного») набора данных. Набор фотографий, на которых обучался алгоритм
распознавания изображений в Google, был явно неполным — данные не представляли
всего населения планеты.
• В самой компании Google (и технической индустрии в целом) негроидная раса недостаточно широко представлена3, и это повлияло на субъективные решения при разработке
алгоритмов и сборе данных. Бессознательная предвзятость самой организации привела
к тому, что был выпущен недостаточно готовый продукт.
• Мы не включили в потенциальную целевую аудиторию Google Photos недопредставленные группы. Тесты Google не заметили ошибки, которые затем увидели пользователи
и справедливо расценили как проявление неуважения.
Даже в конце 2018 года мы в Google все еще не могли адекватно решить эту проблему4.

1
2

3

4

Ежегодный отчет о разнообразии в Google за 2019 год (https://diversity.google/annual-report).
@jackyalcine. 2015. «Google Photos, Y’all Fucked up. My Friend’s Not a Gorilla». Twitter, June 29,
2015. https://twitter.com/jackyalcine/status/615329515909156865.
Во многих отчетах за 2018–2019 годы отмечалось отсутствие разнообразия в высокотехнологических сферах. В числе наиболее известных можно назвать: National Center for Women
& Information Technology (https://oreil.ly/P9ocC) и Diversity in Tech (https://oreil.ly/Y1pUW).
Simonite T. When It Comes to Gorillas, Google Photos Remains Blind. Wired, January 11, 2018.

84  

Глава 4. Инженерия равенства

Наш продукт, упомянутый в этом примере, был неверно спроектирован и реализован,
он не учитывал должным образом все расовые группы и в результате подвел наших
пользователей и вызвал плохие отзывы о Google в прессе. Другие наши продукты
тоже страдают от подобных провалов: функция автозаполнения может вернуть
оскорбительные или расистские результаты. Рекламная система Google может
использоваться для показа расистских или оскорбительных объявлений. YouTube
может не выявить ненавистнических высказываний, которые технически запрещены
на этой платформе.
Во всех этих случаях технологии не виноваты. Например, функция автозаполнения не предназначена для каких-то конкретных групп пользователей или их дискриминации. Но ее конструкция оказалась недостаточно гибкой, чтобы исключить
дискриминационные высказывания, которые считаются языком ненависти. Вред
для самой компании Google также очевиден: снижение доверия пользователей и сокращение сотрудничества с компанией. Например, соискатели из числа темнокожих,
латиноамериканцев и евреев могут потерять веру в Google как платформу или даже
в возможность существования всеохватывающей среды, что подрывает цель Google —
достижение сбалансированного представления разных групп при найме.
Как такое могло случиться? В конце концов, Google стремится нанимать специалистов с безупречным образованием или профессиональным опытом — выдающихся
программистов, которые пишут лучший код и проверяют свою работу. Девиз Google:
«Создавай для всех», — но правда в том, что нам предстоит пройти еще долгий путь,
прежде чем мы сможем подтвердить его. Одно из решений этих проблем — помочь
самой организации, занимающейся программной инженерией, иметь в своих рядах
представителей всех групп людей, для которых мы создаем продукты.

Понимание необходимости разнообразия
Мы в Google считаем, что выдающийся инженер должен быть сосредоточен на привлечении различных точек зрения в разработку и внедрение продуктов. Это также
означает, что гуглеры, отвечающие за собеседование и прием на работу других инженеров, должны содействовать расширению представления в компании различных
групп. Например, проводя собеседование, важно выяснить, как решения о приеме
на работу влияет на баланс представленных групп. Чтобы действительно создавать
продукты для всех, мы должны поощрять более широкий спектр образовательной
подготовки у наших инженеров.
Прежде всего важно разрушить представление о том, что кандидат с ученой степенью
и/или опытом работы в области computer science по определению обладает всеми
навыками, необходимыми выдающемуся инженеру. Также важно избавиться от
идеи, что только люди с образованием в области computer science могут проектировать и создавать продукты. В настоящее время большинство программистов имеет
такое образование (https://oreil.ly/2Bu0H): они с успехом пишут код, создают теории,
изменяющие мир, и применяют методологии для решения проблем. Однако, как

Выстраивание мультикультурного потенциала   85

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

Выстраивание мультикультурного потенциала
Отличительной чертой выдающегося инженера является проницательность — способность понять, как продукты могут приносить пользу и вред различным группам
людей, и умение выявлять и отвергать функции или продукты, которые приводят
к неблагоприятным результатам. Это высокая и труднодостижимая цель, поскольку
становление высокопроизводительного инженера требует индивидуального подхода.
Тем не менее, чтобы добиться успеха, мы должны принять во внимание не только
наши сообщества, но и миллиарды новых пользователей, которые появятся в будущем, а также нынешних пользователей, которые могут быть лишены права голоса
или оставаться неучтенными в наших продуктах.
Со временем вы можете создать инструменты, которыми ежедневно пользуются
миллиарды людей, влияющие на представления о ценности человеческой жизни,
контролирующие человеческую деятельность и собирающие и сохраняющие конфиденциальные данные, например фотографии детей и близких. Как инженер вы можете
обладать большей властью, чем думаете, и прямо влиять на общество. Важно, чтобы
вы понимали ответственность и не использовали свою власть во вред кому-либо. Для
начала осознайте свою предвзятость, вызванную многими социальными и образовательными факторами. После этого вы сможете замечать упускаемые из виду варианты использования, из-за которых ваши продукты могут быть полезны или вредны.
Технологии продолжают развиваться с возрастающей скоростью, создавая почву
для новых сценариев использования искусственного интеллекта (ИИ) и машинного
об­учения. Чтобы оставаться конкурентоспособными, мы стремимся к увеличению
охвата и эффективности в создании высококвалифицированных инженерно-технических кадров. Однако обратите внимание, что в настоящее время одни имеют возможность создавать будущие технологии, а другие — нет. Нам необходимо понять,
будут ли способствовать создаваемые нами программные системы процветанию
общества и обеспечению равного доступа к технологиям.
Исторически сложилось, что компании стремятся к быстрому достижению стратегической цели, связанной с получением прибыли и доминированием на рынке,

86  

Глава 4. Инженерия равенства

отвергая исследования, которые этот процесс замедляют. Они ценят производительность и превосходство, но зачастую не могут действовать беспристрастно. Внимание
к недопредставленным группам пользователей дает нам возможность двигаться
навстречу справедливости. Чтобы сохранить конкурентоспособность в технологическом секторе, нам необходимо научиться создавать глобальное равенство.
Сегодня нас волнуют разработки технологий для сканирования, захвата и идентификации изображений людей, идущих по улице. Мы беспокоимся о конфиденциальности и о том, как правительства могут использовать эту информацию сейчас
и в будущем. Однако большинство наших специалистов не имеют необходимых
знаний о недопредставленных группах, чтобы понять влияние расовых различий
на процедуру распознавания лиц и оценить корректность результатов, полученных
от ИИ.
В настоящее время ПО для распознавания лиц по-прежнему ставит в невыгодное
положение этнические меньшинства или людей с другим цветом кожи. Наше исследование недостаточно полно и не включает весь спектр различных оттенков кожи.
Нельзя ожидать надежных результатов, если обучающие данные и создатели ПО
представляют лишь малую часть пользователей. Мы должны быть готовы отложить
разработку и попытаться получить более полные и точные данные, чтобы создать
всеобъемлющий продукт.
Однако наука о данных сама по себе сложна. Даже при наличии достаточно полного представления некой группы в команде разработчиков обучающий набор все
еще может быть предвзятым и давать неверные результаты. Исследование, завершенное в 2016 году, показало, что в базе данных по распознаванию лиц в правоохранительных органах находятся более 117 миллионов взрослых американцев1.
Из-за непропорционального внимания полиции к темнокожим при использовании
такой базы данных для распознавания лиц могут иметь место расовые ошибки.
Несмотря на то что ПО постоянно развивается и совершенствуется, независимое
тестирование фактически отсутствует. Для исправления этой вопиющей оплошности нужно иметь честность, чтобы приостановиться и сформировать входные
данные так, чтобы они были как можно менее предвзятыми. В настоящее время
Google предлагает идею статистического обучения ИИ, чтобы гарантировать непредвзятость наборов данных.
Таким образом, смещение фокуса в отраслевом опыте в сторону комплексного
мультикультурного расового и гендерного образования — это не только ваша ответственность, но и ответственность вашего работодателя. Технологические компании должны следить за тем, чтобы профессиональное развитие их сотрудников
было комплексным и многопрофильным. Требование не в том, чтобы один человек
взял на себя обязательство изучать другие культуры или демографию в одиночку.
Каждый из нас как специалист или руководитель команды должен вносить свой
1

Gaines S., Williams S. The Perpetual Lineup: Unregulated Police Face Recognition in America.
Center on Privacy & Technology at Georgetown Law, October 18, 2016.

Отказ от единых подходов   87

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

Сделать разнообразие действенным
Всеобщие равенство и справедливость достижимы, если мы готовы признать, что все
несем ответственность за постоянную дискриминацию в технологическом секторе
и провалы в системе. Откладывание или абстрагирование личной ответственности
неэффективно, а в некоторых случаях даже губительно. Также безответственно полностью приписывать динамику в компании или команде более широким социальным
проблемам, способствующим неравенству. Любимая фраза как сторонников разно­
образия, так и его недоброжелателей звучит примерно так: «Мы усердно работаем над
исправлением (вставьте сюда «проблему системной дискриминации»), но учесть все
очень трудно. Как победить (вставьте сюда «многовековую») исторически сложившуюся дискриминацию?» Это направление уводит нас в сторону философской или
академической беседы и не связано с целенаправленными усилиями по улучшению
условий или результатов труда. Для создания мультикультурного потенциала требуется более полное понимание того, как неравенство в обществе влияет на рабочие
места, особенно в технологическом секторе.
Если вы инженер-руководитель, стремящийся принимать на работу больше людей
из недопредставленных групп, то должны учитывать историческое влияние дискриминации в мире. При этом важно выйти за рамки академической беседы и сосредоточиться на количественных и практических шагах для обеспечения равенства
и справедливости. Например, занимаясь наймом инженеров-программистов, вы
несете ответственность за сбалансированность кадров. Есть ли женщины или другие
недопредставленные группы в списке кандидатов? Какие возможности для роста
вы предоставили после найма кого-то и является ли распределение возможностей
справедливым? У каждого технического лидера или управленца в сфере программной инженерии есть средства увеличения равенства в командах. Важно понимать,
что даже при наличии серьезных системных проблем мы все являемся частью этой
системы. Это наша проблема, и мы должны ее исправить.

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

88  

Глава 4. Инженерия равенства

можно устранить, только исправив процедуру найма. Да, это фундаментальный шаг,
и мы не сделаем его сразу. В наших силах признать системное неравенство и сосредоточить внимание, например, на более репрезентативном найме и образовательном
неравенстве по расовым, гендерным, социально-экономическим признакам и иммиграционному статусу.
В высокотехнологичной индустрии многие из недопредставленных групп ежедневно лишаются возможностей и продвижения по службе. Самая высокая текучесть
кадров в Google происходит среди темнокожих сотрудников (https://oreil.ly/JFbTR)
и мешает достижению целей более полного их представления. Если мы хотим добиться изменений в этой области, необходимо оценить, создаем ли мы экосистему,
в которой могут процветать все начинающие инженеры и другие специалисты
в области технологий.
Полное понимание предметной области имеет решающее значение для определения
путей исправления ситуации. Это относится ко всему — от миграции критически
важных данных до найма новых сотрудников. Например, если вы, как руководитель,
хотите нанять больше женщин, недостаточно сосредоточиться на выстраивании процесса найма. Нужно также уделить внимание другим аспектам экосистемы найма
и продвижения по службе и подумать, способны ли кадровики выявлять сильных
кандидатов, как женщин, так и мужчин. Если вы управляете разнородной командой
инженеров, сосредоточьтесь на психологической безопасности и вкладывайте средства в расширение мультикультурного потенциала в команде, чтобы новые ее члены
чувствовали себя востребованными.
Современная общепринятая методология заключается в том, чтобы сначала создать
сценарий для большинства вариантов использования, оставив улучшения на потом.
Но этот подход несовершенен: он дает преимущества пользователям, которые уже
имеют преимущества в доступе к технологиям, и увеличивает неравенство. Откладывать рассмотрение всех групп пользователей до момента завершения проектирования
означает понизить планку качества работы инженера. Вместо этого мы с самого начала создаем всеохватывающий дизайн и повышаем стандарты разработки, чтобы
сделать инструменты интересными и доступными для всех, особенно для людей,
которые борются за доступ к технологиям.
Ориентирование на пользователя, который меньше всего похож на вас, не просто
полезно — это лучшая практика. Существуют прагматичные и непосредственные
шаги, которые все специалисты независимо от предметной области должны учитывать при разработке продуктов, не сторонясь неприятных или непонятных им
пользователей. Все начинается со всестороннего исследования пользовательского
опыта. Это исследование должно проводиться с пользователями, которых отличают
язык, место жительства, культура, принадлежность к социально-экономическому
классу, возраст и способности. Сначала сосредоточьтесь на самом сложном сценарии
использования.

Бросьте вызов устоявшимся процессам   89

Бросьте вызов устоявшимся процессам
Под созданием более справедливых систем подразумевается не только разработка
всеобъемлющих спецификаций продуктов, но и вызов устоявшимся процессам,
приводящим к неверным результатам.
Рассмотрим недавний случай и оценим его с точки зрения справедливости. Несколько команд инженеров в Google работали над разработкой глобальной системы вакансий. Система поддерживала не только наем сотрудников извне, но
и перемещения внутри компании. Инженеры и руководители проекта проделали
большую работу, выслушав запросы тех, кого они считали своей основной группой
пользователей: рекрутеров. Рекрутеры хотели сэкономить время менеджеров по
персоналу и соискателей и передали команде разработчиков примеры использования, ориентированные на охват и эффективность. В частности, они попросили
инженеров добавить функцию выделения рейтингов эффективности (особенно
низких) сразу после того, как внутренний соискатель выразит заинтересованность
в работе.
На первый взгляд ускорение процесса оценки и экономия времени соискателей —
достойная цель. Так в чем же несправедливость? Были подняты следующие вопросы:
y Можно ли использовать оценки эффективности в прошлом для прогнозирования
эффективности в будущем?
y Являются ли оценки эффективности свободными от индивидуальной предубежденности?
y Стандартизированы ли оценки эффективности в разных организациях?
Ответ «нет» на любой из этих вопросов означает, что представление рейтингов
эффективности может приводить к несправедливым и, следовательно, неверным
результатам.
Когда выдающийся инженер усомнился в том, что оценки эффективности в прошлом способны предсказать эффективность в будущем, команда рецензентов решила
провести тщательный анализ. В итоге было установлено, что кандидаты, получившие низкий рейтинг эффективности, почти наверняка улучшат этот рейтинг, если
найдут новую команду. Фактически они с той же вероятностью могли бы достичь
удовлетворительного или высокого рейтинга эффективности, как и кандидаты, которые никогда не имели низкого рейтинга. Проще говоря, эти рейтинги сообщают
только, как человек выполнял свою работу на момент его оценивания, и не должны
использоваться для оценки пригодности внутреннего кандидата для работы в другой
команде. (Однако их можно использовать для оценки, насколько сотрудник подходит
для текущей команды и где он может продвинуться вперед.)
На этот анализ ушло значительное время, но в результате был реализован более
справедливый процесс внутренней миграции.

90  

Глава 4. Инженерия равенства

Ценности и результаты
Google имеет большой опыт инвестирования в сферу найма персонала. Как показывает предыдущий пример, мы постоянно оцениваем процессы, чтобы повысить их
справедливость и охват. В более широком смысле наши основные ценности основаны
на уважении и непоколебимой приверженности разнообразию работников. Тем не
менее год за годом мы упускали свой шанс принимать на работу представителей
разных групп, являющихся отражением наших пользователей по всему миру. Борьба
за улучшение справедливости результатов продолжается, несмотря на проводимую
политику и программы, направленные на поддержку инициатив по увеличению
разнообразия и совершенствованию процедур найма и продвижения по службе.
Причина неудачи не в ценностях, намерениях или инвестициях компании, а скорее
в реализации политик.
Старые привычки трудно сломать. Пользователи, которых можно привлечь для
разработки и от которых мы привыкли получать отзывы, могут не представлять
всех пользователей, с которыми мы хотим наладить контакт. Это имеет место
в отношении всех видов продуктов, от носимых устройств, которые не подходят
женщинам, до ПО для видеоконференций, которое не всегда подходит людям
с темным цветом кожи.
Так какой же вывод отсюда следует?
1. Внимательно посмотрите в зеркало. Наш девиз: «Создавай для всех». Как это
сделать в отсутствие репрезентативной рабочей силы или модели взаимодействий, централизующей отзывы сообщества? Это невозможно. Правда в том, что
иногда мы не могли публично защитить наших наиболее уязвимых пользователей
от расистского, антисемитского и гомофобного контента.
2. Не нужно создавать для всех подряд. Создавайте со всеми. Мы пока не создаем для всех. Но мы работаем не в вакууме, и, конечно, нельзя сказать, что наши
технологии не репрезентативны для общества в целом. Мы уже не можем что-то
создать и об этом забыть. Итак, как создавать для всех? Мы стараемся вовлекать
в процесс создания наших пользователей — представителей разных групп —
и ставим наиболее уязвимые сообщества в центр нашей работы. Мы не должны
учитывать их мнения по остаточному принципу.
3. При проектировании учитывайте пользователей, которые будет испытывать
наибольшие сложности при использовании продукта. Создание для тех, кто
может столкнуться с дополнительными сложностями, сделает продукт лучше
для всех. Не гонитесь за быстрой прибылью.
4. Не стройте предположений о справедливости: оценивайте ее во всех системах.
Поймите, что лица, принимающие решения, также подвержены предвзятости
и могут быть недостаточно осведомлены о причинах неравенства. У вас может не
хватить опыта, чтобы определить или оценить масштаб проблемы неравенства.

Заключение   91

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

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

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

92  

Глава 4. Инженерия равенства

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

ГЛАВА 5

Как стать лидером в команде
Автор: Брайан Фицпатрик
Редактор: Риона Макнамара
Итак, мы познакомились с культурой и составом команд, пишущих ПО, и в этой
главе мы обсудим человека, который в конечном счете несет ответственность за
выполнение работы.
Никакая команда не сможет работать слаженно без лидера, особенно в Google, где
инженерия — это почти исключительно командная работа. Мы в Google различаем
две лидерские роли: руководитель, управляющий людьми, и технический лидер, направляющий технические усилия. Обязанности в этих ролях весьма различны, но
обе они требуют определенных навыков.
Корабль без капитана — это такой плавучий зал ожидания: если кто-то не возьмет
руль и не запустит двигатель, корабль будет бесцельно плыть по течению. Разработка
ПО отчасти похожа на этот корабль: если никто не управляет ею, инженеры потратят
драгоценное время на ожидание или, что еще хуже, будут писать код, который никому
не нужен. Хотя эта глава посвящена управлению людьми и техническому лидерству,
ее стоит прочитать всем разработчикам, чтобы лучше понять руководителей.

Руководители и технические лидеры (и те и другие)
В любой команде инженеров обычно есть лидер. Иногда в команду приходит опытный
руководитель, а иногда простой разработчик продвигается на роль лидера (обычно
из небольшой команды).
В зарождающихся командах обе роли может играть один и тот же человек — технический руководитель (TLM, tech lead manager). В больших командах обязанности руководителя может выполнять опытный менеджер по персоналу, если старший инженер
с большим опытом работы берет на себя функции технического лидера. Несмотря на
то что руководитель и технический лидер играют важные роли в развитии команды,
навыки, необходимые для достижения успеха в каждой роли, совершенно разные.

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

94  

Глава 5. Как стать лидером в команде

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

Технический лидер
Технический лидер (TL, tech lead) команды — это человек, который отчитывается
перед руководителем команды, отвечает (сюрприз!) за технические аспекты продукта,
включая выбор технических решений, архитектуру, приоритеты, скорость работы
и общее управление проектом (в крупных командах ему могут помогать руководители программ). Технический лидер обычно работает рука об руку с руководителем,
чтобы укомплектовать команду кадрами и распределить задачи между инженерами в соответствии с их навыками и знаниями. Большинство технических лидеров
одновременно являются разработчиками, что часто ставит их перед выбором: что-то
быстро сделать самому или делегировать работу члену команды, который справится
с ней медленнее. Последнее чаще всего является правильным решением, поскольку
помогает увеличить уровень способностей и возможности команды.

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

Переход от роли разработчика к роли лидера   95

КЕЙС: ВЛИЯНИЕ БЕЗ ПОЛНОМОЧИЙ
Конечно, вы можете заставить подчиненных выполнять работу, но совсем другое дело
управлять теми, кто находится за пределами компании или даже занимается созданием
других продуктов. Способность «влиять без полномочий» — одно из самых сильных лидерских качеств, которое вы можете развить.
Например, в течение многих лет Джефф Дин, старший инженер-разработчик и, пожалуй,
самый известный гуглер внутри Google, возглавлял очень небольшую команду инженеров
Google, но его умение влиять на технические решения и направления развития помогало
достигать целей как внутри инженерной организации, так и за ее пределами (благодаря
его статьям и публичным выступлениям).
Другой пример: в свое время я создал команду «The data liberation front», насчитывающую
человек пять инженеров, которая смогла организовать экспорт данных более чем в 50 продуктов Google через созданный нами Google Takeout. Наши стремления не были подкреплены официальными приказами на исполнительном уровне Google. Так как же нам удалось
сподвигнуть сотни инженеров внести свой вклад в нашу идею? Стратегическая потребность
в идее, демонстрация ее связи с целями и приоритетами компании и взаимодействие с небольшой группой инженеров, занимающихся разработкой инструмента, помогли другим
группам легко и быстро интегрироваться с Takeout.

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

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

96  

Глава 5. Как стать лидером в команде

в мире разработки ПО, — необходимость тратить гораздо меньше времени на создание
кода. Это верно и для технических лидеров, и для руководителей, и я расскажу об
этом далее в этой главе, но сначала мы рассмотрим еще несколько причин, по которым
большинство из нас не горят желанием становиться руководителями.
Те, кто большую часть карьеры занимается созданием кода, обычно заканчивают
день чем-то, что можно продемонстрировать (код, документ с описанием дизайна
или целый список исправленных ошибок), и говорят: «Вот что я сделал сегодня».
Но в конце напряженного дня, посвященного «управлению», нередко возникает
мысль: «Сегодня я ни черта не сделал». Однако это равносильно тому, что, потратив
годы на подсчет яблок, которые вы собирали каждый день, и перейдя на работу по
выращиванию бананов, вы в конце каждого дня будете говорить себе: «Я не собрал
ни одного яблока», забывая про цветущие банановые пальмы рядом с собой. Оценить
количественно управленческую работу сложнее, чем подсчитать созданные виджеты, однако даже простая удовлетворенность и продуктивность команды являются
ничуть не менее важной оценкой работы лидера. Просто не попадайтесь в ловушку
с подсчетом яблок, занимаясь выращиванием бананов1.
Еще одна важная причина уклонения от руководящей работы, часто не высказываемая прямо, корнями уходит в знаменитый «принцип Питера», который гласит:
«Каждый сотрудник имеет тенденцию подняться до уровня своей некомпетентности».
Чтобы избежать этого, в Google человеку предлагается выполнять более сложную
работу (то есть «превзойти самого себя») в течение ограниченного времени, и только
потом принять решение о переходе на новый уровень. Многие из нас сталкивались
с руководителями, неспособными выполнять свою работу или просто плохо управлявшими людьми2, и мы знаем тех, кому довелось работать только с плохими руководителями. Если всю свою карьеру человек работал только с плохими руководителями,
откуда у него может возникнуть желание самому стать руководителем? Разве может
возникнуть стремление получить роль, которую вы не можете выполнять?
Есть, однако, веские причины, чтобы стать техническим лидером или руководителем.
Во-первых, это возможность масштабирования своих знаний и умений. Даже если
вы прекрасно пишете код, его объем ограничен. А теперь представьте, сколько кода
может написать команда великих инженеров под вашим руководством! Во-вторых,
вы можете открыть в себе новые таланты — многие, оказавшись втянутыми в управление проектом, обнаруживают, что прекрасно справляются с выбором решений,
оказанием помощи и обеспечением нужд команды или компании. Кто-то должен
вести за собой, так почему не вы?
1

2

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

Руководитель   97

Лидерство как служение
Иногда кажется, что руководителей поражает что-то вроде болезни, когда они забывают обо всех ужасах, которые с ними творили их руководители, и внезапно начинают делать то же самое со своими подчиненными. Вот далеко не полный список
симптомов этого заболевания: микроуправление, игнорирование неэффективных
сотрудников и прием на работу слабых специалистов. Без своевременного лечения
эта болезнь может убить всю команду. Лучший совет, который я получил, когда
впервые занял руководящий пост в Google, дал мне Стив Винтер, занимавший в то
время должность технического директора. Он сказал: «Прежде всего, сопротивляйся
желанию управлять». Одно из главных побуждений новоиспеченного руководителя — активно «управлять» своими сотрудниками, потому что именно это должен
делать руководитель, верно? Часто это устремление приводит к катастрофическим
последствиям.
Избавиться от острых форм «менеджерита» поможет мантра: «Лидерство — это
служение». Она прямо говорит, что самое ценное, что можно сделать в роли лидера, — служить своей команде, подобно тому как дворецкий или мажордом служит
своему хозяину и заботится о его здоровье и благополучии. Как лидер-слуга вы
должны стремиться создать атмосферу смирения, уважения и доверия. Это может
выражаться в устранении бюрократических препятствий, с которыми не справляются
члены команды, помощи в достижении согласия или даже покупке еды для тех, кто
допоздна работает в офисе. Лидер-слуга засыпает ямы, чтобы облегчить путь своей
команде, консультирует при необходимости, но при этом не боится испачкать руки.
Единственное, чем должен управлять лидер-слуга, — это техническое обеспечение
и социальное здоровье команды. Как бы ни было заманчиво сосредоточиться исключительно на техническом обеспечении, социальное здоровье команды столь же
важно (но управлять им намного сложнее).

Руководитель
Итак, что же должен делать руководитель в современной софтверной компании?
До эры повсеместного распространения компьютеров слова «управление» и «труд»
описывали почти противоположные понятия. Руководитель располагал всей полнотой власти, чтобы направлять коллективный труд на достижение своих целей. Но современные софтверные компании работают иначе.

«Начальник» — почти бранное слово
Прежде чем говорить об основных обязанностях руководителя в Google, обратимся
к истории. Современные представления о начальнике как об узурпаторе сформировались при военной иерархии и были подхвачены в ходе промышленной революции
более ста лет назад! В то время повсюду появлялись фабрики, для обслуживания
машин которых требовались рабочие (обычно неквалифицированные) и начальники — для управления. Спрос на работу был высок, и у начальников не было доста-

98  

Глава 5. Как стать лидером в команде

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

Современный руководитель
Большинство людей все еще используют слово «начальник», несмотря на то что его
первоначальное значение устарело. Само название часто побуждает новых руководителей управлять своими подчиненными. Руководители могут вести себя подобно
родителям2, на что сотрудники вполне естественно реагируют как дети. А теперь
сформулируем понятие «руководить» в контексте смирения, уважения и доверия:
если руководитель выказывает свое доверие сотруднику, тот испытывает позитивное
давление и старается это доверие оправдать. Это так просто. Хороший руководитель
прокладывает путь команде, заботясь о ее безопасности и благополучии, и в то же
время следит, чтобы ее потребности были удовлетворены. Если хотите вынести
какой-то общий урок из этой главы, тогда запомните следующее:
Рядовые начальники заботятся о том, как что-то сделать, а великие руководители — о том, что можно сделать (и доверяют своей команде выяснение деталей,
как это сделать).
Несколько лет назад к моей команде присоединился новый инженер Джерри. Прошлый руководитель Джерри (в другой компании) был непреклонен, заставляя
подчиненных сидеть за столами с 9:00 до 17:00 и считая, что если работник куда-то
отлучался, значит, он работал не в полную силу (что, конечно, совершенно нелепо).
В свой первый рабочий день Джерри пришел ко мне в 16:40 и пробормотал извинения
1

2

Подробнее об оптимизации передвижения работников на фабрике читайте в статьях о научной организации труда или тейлоризме, где особо подчеркивается важность влияния на
моральный дух работников.
Если у вас есть дети, то вы наверняка вспомните, когда в первый раз сказали своему ребенку
что-то, что заставило вас остановиться и воскликнуть (возможно, даже вслух): «Черт возьми,
я веду себя как мои родители!»

Руководитель   99

за то, что вынужден уйти на 15 минут раньше, так как у него запланирована встреча,
которую он не смог перенести. Я улыбнулся и сказал: «Пока вы выполняете свою
работу, мне все равно, когда вы покинете офис». На несколько секунд Джерри замер
в недоумении, затем кивнул и пошел дальше. Я относился к Джерри как ко взрослому — он всегда выполнял свою работу, и мне никогда не приходилось беспокоиться
о том, сидит ли он за столом, потому что ему не нужна нянька. Если ваши сотрудники
настолько не заинтересованы в работе, что их должен подгонять начальник-нянька,
это и есть ваша настоящая проблема.

НЕУДАЧА — ТОЖЕ ВАРИАНТ
Еще один способ стимулировать команду — дать людям почувствовать себя защищенными,
чтобы они начали рисковать. Если вам удастся создать в команде атмосферу психологической безопасности, ее члены смогут быть самими собой и не опасаться негативной реакции
от вас или коллег. Риск — захватывающая штука, но большинство людей боятся рисковать,
и во многих компаниях принято избегать риска любой ценой, выбирать консервативный
подход к работе и стремиться к небольшим успехам, даже когда больший риск может дать
многократно больший результат. В Google говорят, что, пытаясь достичь невозможного,
вы, вероятно, потерпите неудачу, но, скорее всего, такая неудача даст вам больше, чем выполнение работы, которая точно вам под силу. Чтобы создать культуру, в которой допустим
риск, команда должна знать, что неудачи — это нормально.
Итак, давайте примем раз и навсегда: терпеть неудачу — это нормально. На самом деле мы
предпочитаем думать о неудаче как о быстром способе научиться чему-то (при условии, что
одна и та же неудача не повторяется), а не обвинять в ней кого-то. Быстро потерпеть неудачу — это хорошо, потому что на карту поставлено не так много. Неудача после длительной
работы тоже может преподать ценный урок, но она воспринимается болезненно, потому
что при ней потери больше (обычно времени инженера). Таким образом, неудача, влияющая на клиентов, является самой нежелательной, но она же преподносит наиболее ценный
урок. Как упоминалось выше, каждый раз, когда в Google происходит серьезная неудача,
мы выполняем вскрытие, документируем события, приведшие к неудаче, и разрабатываем
последовательность шагов, которые предотвратят подобное в будущем. Эта процедура — не
поиск виноватых и не бюрократическая проверка: главная ее цель — сосредоточиться на
сути проблемы и решить ее раз и навсегда. Это очень сложно, но эффективно (и надежно).
Личные успехи и неудачи немного отличаются. Одно дело хвалить за личные успехи,
но стремление возложить личную вину в случае неудачи — отличный способ рассорить
команду и отбить в людях охоту рисковать. Потерпеть неудачу — допустимо, но неудачи
должны быть общими для всей команды, и вся команда должна учиться на ошибках. Если
человек добивается личного успеха, хвалите его перед командой. Если терпит неудачу —
изложите конструктивную критику в частном порядке1. В любом случае воспользуйтесь
неудачей как возможностью проявить смирение, уважение и доверие, чтобы помочь команде
учиться на ошибках.

1

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

100  

Глава 5. Как стать лидером в команде

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

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

Антипаттерн: игнорирование неэффективных сотрудников
Когда в Google я впервые раздавал премии команде, то сказал своему руководителю:
«Мне нравится быть начальником!» На что тот ответил: «Иногда ты бываешь зубной
феей, а иногда — стоматологом».
Дергать зубы не доставляет никакого удовольствия. Мы видели, как руководители
команд делают все, чтобы получить сильную команду, но эта команда терпит неудачу (и в конечном итоге разваливается) из-за одного-двух неэффективных игроков.
Мы понимаем, что человеческий фактор — самый сложный компонент в разработке
ПО, а самая трудная часть работы с людьми — это общение с человеком, который не
отвечает ожиданиям. Иногда люди не добиваются успеха, потому что работают недостаточно долго или усердно, но, возможно, человек просто не способен выполнять
свою работу, даже если очень старается.

Антипаттерны   101

У команды SRE в Google есть девиз: «Надежда — это не стратегия». И нигде надежда
так не используется в качестве политики, как в работе с неэффективным исполнителем. Большинство лидеров команд стискивают зубы, отводят глаза и просто надеются, что слабый игрок волшебным образом исправится или просто уйдет. Однако
такие надежды оправдываются очень редко.
Пока лидер надеется, а слабый сотрудник не совершенствуется (или не уходит),
высококлассные специалисты в команде тратят драгоценное время, чтобы увлечь
неэффективного коллегу, и в результате моральный дух команды иссякает. Можете
быть уверены, что команда знает о существовании неэффективного коллеги, даже
если вы его игнорируете, потому что несет часть его груза.
Игнорирование неэффективных сотрудников не только мешает присоединению
к команде новых высококлассных специалистов, но и подталкивает к уходу уже
имеющихся эффективных исполнителей. В результате в команде остаются только неэффективные работники, потому что они единственные, кто не ушел по собственному
желанию. Наконец, оставляя их в команде, вы оказываете им плохую услугу: тот, кто
плохо работает в вашей команде, может оказаться намного эффективнее где-то еще.
Чем быстрее вы выявите неэффективного работника, тем быстрее сможете помочь
ему начать расти или уйти. Если он проявил неэффективность сразу, его нужно
просто поощрить или подтолкнуть к переходу на более высокий уровень. Если же
слишком долго ждать, что неэффективный сотрудник исправится, его отношения
с командой могут испортиться до такой степени, что вы уже не сможете их наладить.
Как лучше подтягивать отстающих членов команды? Отличная аналогия — представить, что вы помогаете человеку после тяжелой болезни снова научиться ходить,
затем бегать трусцой, а потом бежать наравне с остальными членами команды. Это
почти всегда требует временного микроменеджмента и всегда — большого смирения,
уважения и доверия (уважения особенно). Установите конкретные сроки (скажем,
два месяца), в которые сотрудник постепенно должен достичь четко определенных
измеримых целей. Дайте ему возможность пройти череду маленьких успехов. Встречайтесь с ним каждую неделю, чтобы проверить, как он продвигается, и оценить успех
или неудачу. Если сотрудник не успевает, это сразу станет очевидно для вас обоих
и он либо признает, что ему лучше уйти, либо включит решимость и «улучшит свою
игру», чтобы оправдать ваши ожидания. В любом случае, работая напрямую с неэффективным сотрудником, вы поспособствуете важным и необходимым изменениям.

Антипаттерн: игнорирование личных проблем
Руководитель работает с командой по двум основным направлениям: социальному
и техническому. Обычно руководители в Google сильнее проявляют себя в техническом
направлении, и поскольку большинство из них получают повышение после технической
должности (то есть раньше основной их задачей было решение технических проблем),
они могут игнорировать человеческий фактор. Это так заманчиво — сконцентрировать всю
свою энергию на технической стороне работы команды, ведь именно этому учили в вузе.

102  

Глава 5. Как стать лидером в команде

Пример: у Джейка родился первенец. Джейк и Кэти долго работали вместе — и удаленно, и в одном офисе, поэтому несколько первых недель после рождения ребенка
Джейк работал из дома. Такой режим работы отлично подошел для пары, и Кэти была
всецело согласна с этим, потому что у них с Джейком уже был опыт удаленной работы. Они прекрасно справлялись, пока их руководитель Пабло (работавший в другом
офисе) не узнал об этом и не выразил недовольство. Джейк попытался объяснить
Пабло, что он работает так же эффективно, как в офисе, и ему с женой будет намного
удобнее работать из дома еще в течение нескольких недель. Пабло ответил: «Джейк,
у многих есть дети. Ты обязательно должен ходить в офис». Разумеется, Джейк (по
природе мягкий человек) был взбешен и потерял уважение к Пабло.
Пабло мог бы разрешить ситуацию другим способом, например выразить понимание
желания Джейка проводить больше времени дома с женой, и если его эффективность
осталась прежней и команда не пострадала, просто позволить ему продолжать работать удаленно еще какое-то время. Он мог договориться с Джейком, что тот будет
посещать офис один или два дня в неделю. Независимо от конечного результата
беседы немного сочувствия помогло бы Джейку остаться довольным в этой ситуации.

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

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

Антипаттерны   103

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

Антипаттерн: отношение к членам команды как к детям
Лучший способ показать членам команды, что вы им не доверяете, — относиться к ним
как к детям. Люди склонны вести себя так, как вы к ним относитесь, поэтому, если вы
относитесь к ним как к детям или заключенным, не удивляйтесь, что они будут вести
себя соответственно. Такое отношение проявляется, когда вы стараетесь управлять
всеми мельчайшими аспектами работы или просто неуважительно высказываетесь
о способностях сотрудников и не даете им возможности нести ответственность за свой
вклад. Если вам постоянно приходится давать подчиненным руководящие указания,
потому что вы им не доверяете, значит, вы потерпели провал (или исполнили свою
мечту создать команду, за которой надо присматривать). Если вы нанимаете людей,
достойных доверия, и демонстрируете им свое доверие, они обычно хорошо справляются со своей работой (если исходить из основной предпосылки, упоминавшейся
выше, что вы наняли хороших людей).
Доверие простирается на все уровни общения, вплоть до обыденных вещей, таких
как офисные и компьютерные принадлежности. Например, Google предоставляет
сотрудникам шкафы с различными ручками, блокнотами и прочими инструментами
для творчества, которые можно брать по мере необходимости. IT-отдел поддерживает многочисленные площадки «Tech Stop» — зоны самообслуживания, похожие
на мини-магазины электроники. В них можно найти множество компьютерных аксессуаров и компонентов (блоки питания, кабели, мыши, USB-накопители и т. д.),
которые любой может просто взять и уйти. Поскольку сотрудникам Google оказывается полное доверие, они чувствуют себя ответственными за взятые вещи. Многие
корпорации с ужасом реагируют на это, восклицая, что люди наверняка «крадут»
эти вещи, из-за чего Google теряет деньги. Такое, конечно, возможно, но как насчет
затрат на работников, которые ведут себя как дети или тратят драгоценное время,

104  

Глава 5. Как стать лидером в команде

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

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

Забудьте про эго
Мы уже говорили о необходимости «забыть про свое эго» несколько глав назад, когда
впервые рассматривали смирение, уважение и доверие, однако для лидера команды
это особенно важно. Этот паттерн часто неправильно понимается как разрешение
другим вытирать о себя ноги, но это совсем другое. Конечно, грань между смирением и позволением другим вас использовать очень тонкая, но смирение — это не то
же самое, что отсутствие уверенности. Вы можете быть уверенным в себе и в своем
мнении, не будучи при этом эгоистом. С личным эго трудно справиться в любой
команде, особенно с эго ее лидера. Поэтому вы должны работать над воспитанием
сильного коллективного эго команды и ее самосознания.
Под «забыть про свое эго» также подразумевается доверие: доверяйте команде.
Уважайте способности и прошлые достижения членов команды, даже если коллеги
недавно присоединились к вам.
Если вы не стремитесь управлять всем и вся в своей команде, то можете быть уверены,
что люди, занимающиеся практической реализацией, знают тонкости своей работы
лучше, чем вы. Вы все еще можете оставаться единственным, кто ведет команду к согласию и помогает определить цели, но детали достижения ваших целей лучше оставить людям, которые создают продукт. Это даст им не только чувство причастности,
но и ответственности за успех (или неудачу) продукта. Если у вас хорошая команда
и вы позволяете ей самой устанавливать планку качества и скорости работы, то вы
достигнете большего, чем если бы стояли над подчиненными с кнутом и пряником.
Впервые вступая в руководящую должность, большинство людей чувствуют огромную ответственность за правильность решений и считают, что должны знать ответы на все вопросы. Можем заверить, что у вас не все и не всегда будет получаться
правильно и вы не будете знать ответы на все вопросы, а стремясь к этому, быстро
потеряете уважение команды. Очень многое зависит от вашего чувства безопасности.
Вспомните время, когда вы были простым разработчиком. Вы могли почувствовать
запах неуверенности за милю. Имейте в виду, что, когда кто-то ставит под сомнение
ваше решение или заявление, часто этот человек просто пытается лучше вас понять.
Поощряя вопросы коллег, у вас будет гораздо больше шансов получить конструктив-

Положительные паттерны   105

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

Будьте мастером дзен
Как инженер вы, вероятно, отлично развили в себе скептика и циника, но эти качества
могут стать помехой, когда придет ваше время возглавить команду. Это не означает,
что вы должны быть наивно оптимистичны, просто поумерьте свой скепсис, когда
будете сообщать команде, что знаете тонкости и препятствия, связанные с работой.
Умеренность в проявлении реакций и спокойствие важны, потому что вы ведете за
собой людей и команда (осознанно или нет) будет искать в вашем поведении подсказки, как действовать и реагировать на происходящее вокруг.
Вот простой способ визуализировать этот эффект: представьте организационную
схему компании в виде цепочки шестеренок, внизу которой находятся отдельные
разработчики в виде маленьких шестеренок с несколькими зубьями, а на каждом
последующем уровне управления есть более крупные шестеренки, представляющие
руководителей и генерального директора — самую большую шестеренку с сотнями
зубьев. Когда шестеренка-руководитель (с несколькими десятками зубьев) совершает
один оборот, шестеренка-разработчик совершает два или три оборота. А генеральный
директор одним небольшим движением может заставить несчастного сотрудника
в конце цепочки, шестью-семью уровнями ниже, вращаться с бешеной скоростью!
Чем выше вы поднимаетесь в иерархии управления, тем быстрее можете заставить
вращаться шестеренки под вами, независимо от того, собираетесь вы это делать или
нет.
Ту же ситуацию можно представить иначе по принципу, что лидер всегда на виду: не
только когда проводит собрание или выступает с речью, но даже когда просто сидит
за столом и отвечает на письма. Ваши коллеги наблюдают за вами, стараясь найти
невербальные подсказки во время бесед и изучая реакции тела. Что они прочитают?
Уверенность или страх? Как лидер вы должны вдохновлять, но вдохновение — это

106  

Глава 5. Как стать лидером в команде

работа 24/7. Ваше видимое отношение ко всему — независимо от того, насколько
оно тривиально, — неосознанно замечается и влияет на команду.
Один из первых руководителей в Google, Билл Кафран, вице-президент по инженерным разработкам, по-настоящему освоил способность сохранять спокойствие в любой
обстановке. Что бы ни взорвалось, что бы ни случилось, насколько бы ни был велик
огненный шторм, Билл никогда не паниковал. Обычно он скрещивал руки на груди,
подпирал подбородок ладонью и задавал вопросы о проблеме запаниковавшему
инженеру. Это успокаивало инженера и помогало сосредоточиться на решении проблемы, а не бегать, как курица с отрубленной головой. Мы часто шутили, что если
кто-то войдет к Биллу и скажет, что 19 офисов компании подверглись нападению
космических пришельцев, тот ответит: «Есть идеи, почему не 20?»
Это подводит нас к еще одной хитрости в искусстве управления: задавать вопросы.
Когда к вам обращается член команды за советом, у вас может возникнуть неподдельное желание наконец что-то исправить. Это же именно то, что вы делали годы
и годы, прежде чем перейти на руководящую должность. В таком случае вы можете
переключиться в режим решения, но это самое последнее, что вы должны сделать.
Человек, спрашивающий совета, обычно не хочет, чтобы вы решили его проблему,
но хочет, чтобы вы помогли ему найти решение, и самый простой способ сделать
это — задать этому человеку вопросы. Вы не должны играть роль шара предсказаний (невыносимого и бесполезного). Но вы можете проявить смирение, уважение
и доверие и попытаться помочь человеку решить проблему самостоятельно, уточняя
и исследуя проблему вместе с ним. Обычно это наталкивает сотрудника на ответ1,
и это будет ответ, найденный им самим, что возвращает его к авторству и ответственности, о которых мы говорили выше в этой главе. Независимо от того, знаете вы
ответ или нет, этот прием почти всегда оставляет у сотрудника впечатление, что вы
помогли ему. Хитро, правда? Сократ гордился бы вами.

Будьте катализатором
В химии катализатором называют вещество, ускоряющее химическую реакцию, но
само не участвующее в ней. Примером катализатора (такого как ферменты) может
служить вещество, способствующее сближению реагентов: вместо случайного броуновского движения в растворе молекулы реагентов сближаются под воздействием
катализатора и взаимодействуют друг с другом. Это та роль, которую вам часто придется играть в качестве лидера, и сыграть ее можно множеством способов.
Чаще всего лидеру приходится добиваться согласия в команде. Для этого вы можете пытаться управлять процессом от начала до конца, а можете просто слегка
подтолкнуть его в нужном направлении, чтобы ускорить сближение. Работа по
формированию согласия в команде — это лидерский навык, который часто исполь1

См. также статью в Википедии «Rubber duck debugging» (https://oreil.ly/BKkvk). (Перевод
статьи на русский язык можно найти по адресу: https://ru.wikipedia.org/wiki/Метод_утенка. —
Примеч. пер.)

Положительные паттерны   107

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

Устраняйте препятствия на пути
Иногда команда приходит к согласию относительно того, что делать, но наталкивается на препятствие и останавливается. Это препятствие может быть техническим
или организационным, и умение перепрыгнуть через него, чтобы помочь команде
продолжить движение, — это обычной прием лидерства. Если препятствие непреодолимо для членов команды, то их понимание, что вы готовы (и способны) его
устранить, очень ценно.
Однажды команда потратила несколько недель, пытаясь преодолеть препятствие,
возникшее в юридическом отделе Google. Когда команда наконец исчерпала все
свои возможности и подошла к своему руководителю с проблемой, тот решил ее
менее чем за два часа, просто потому что знал, с каким человеком нужно связаться
для обсуждения вопроса. В другой раз команде потребовались дополнительные серверные ресурсы, которые трудно получить. К счастью, руководитель команды имел
дружеские связи с другими командами в компании и сумел предоставить нужные
ресурсы команде в тот же день. А когда у одного из инженеров возникли проблемы
с таинственным фрагментом кода на Java, руководитель команды, не будучи экспертом в Java, смогла связать этого инженера с другим инженером, который точно знал,
в чем проблема. Вам не нужно знать все ответы, чтобы помочь устранить препятствия,
обычно достаточно знать людей, которые могут помочь, и часто такое знание более
ценно, чем знание правильного ответа.

Будьте учителем и наставником
Одна из самых больших сложностей в работе технического лидера — наблюдать, как
джун тратит три часа на что-то, что вы могли решить за 20 минут. Поначалу обучение людей и предоставление им возможности учиться самостоятельно может быть
невероятно трудным делом, но это жизненно важный компонент эффективного лидерства. Особенно важно дать время новым сотрудникам, которые кроме технологий
и кодовой базы изучают культуру команды и ответственность, которую они могут
взять на себя. Хороший наставник должен находить компромиссы между временем
обучения подопечного и его вкладом в общее дело, одновременно прикладывая все
усилия для масштабирования команды по мере ее роста.
Большинство не стремится стать наставниками (как и руководителями) — обычно наставника для нового члена команды ищет лидер. Чтобы стать наставником,
1

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

108  

Глава 5. Как стать лидером в команде

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

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

Будьте честными
Нет, мы не предполагаем, что вы лжете команде, но этот аспект заслуживает упоминания, потому что вы неизбежно окажетесь в положении, когда не сможете сказать
что-то подчиненным или, что еще хуже, будете вынуждены сказать им что-то неприятное. Один наш знакомый руководитель говорит новым членам команды: «Я не
буду вам лгать, но буду сообщать, когда что-то не смогу вам сказать или просто не
знаю ответа».
Если член команды обращается к вам с вопросом по теме, которую вы не можете
с ним обсудить, скажите ему, что вы знаете ответ, но не имеете права говорить его.
Если же вы не знаете ответа на вопрос сотрудника (такое бывает чаще), прямо
скажите, что не знаете ответа. Это еще одна из тех истин, которые кажутся ослепительно очевидными, но, оказавшись в роли руководителя, многие почему-то
считают, что незнание ответа доказывает их слабость или оторванность от реаль-

Положительные паттерны   109

ности. На самом деле единственное, что доказывает правдивый ответ, — руководитель тоже человек.
Давать четкий ответ... ну, это сложно. В первый раз сообщить сотруднику, что он
допустил ошибку или не оправдал ожиданий, может быть очень трудно. В большинстве пособий для руководителей, чтобы смягчить удар, рекомендуется использовать
«бутерброд с комплиментами», который выглядит примерно так:
«Вы хороший сотрудник и один из наших лучших инженеров. Однако ваш код
слишком запутан и его почти никто не сможет понять. Но у вас огромный потенциал и чертовски крутая коллекция футболок».
Конечно, это смягчит удар, но после такого хождения вокруг да около большинство
людей выйдут со встречи, думая только: «Ха! У меня классные футболки!» Мы
настоятельно рекомендуем не использовать бутерброд с комплиментами, но не потому, что, на наш взгляд, вы должны быть жестким или грубым, а потому, что из-за
него люди не слышат критического сообщения. Можно проявить уважение, добрые
намерения и сочувствие и высказывать конструктивную критику без бутерброда
с комплиментами. На самом деле доброта и сочувствие имеют решающее значение,
если вы хотите, чтобы человек услышал критику, а не начал защищаться.
Несколько лет назад наш коллега принял в команду нового члена — Тима, забрав
его у другого руководителя, настаивавшего на том, что с Тимом невозможно работать, потому что тот не реагирует на критику и продолжает работать как хочет. Наш
коллега поприсутствовал на нескольких встречах того руководителя с Тимом, чтобы
понаблюдать за их общением, и заметил, что руководитель часто использовал бутерброд с комплиментами. Новый руководитель четко объяснил Тиму, как тот должен
изменить свой подход к работе, чтобы эффективно влиться в команду:
«Мы знаем, что вы не обращаете внимания на то, что ваш способ взаимодействия
с командой отталкивает и сердит коллег. Если вы хотите быть эффективным,
постарайтесь усовершенствовать свои навыки общения. Мы готовы вам в этом
помочь».
Он не высказывал Тиму никаких комплиментов и не приукрашивал проблему, но
самое главное, он не сердился, а просто изложил факты так, как он их видел, основываясь на общении Тима с предыдущей командой. И вот, спустя несколько недель
(и после нескольких «повторных» встреч) эффективность Тима значительно улучшилась. Тиму просто нужны были более четкие объяснения.
Когда вы прямо высказываете замечания или критику, это гарантирует, что ваше
сообщение будет услышано. Но если вы заставите подопечного защищаться, он
будет думать не о том, что нужно изменить, а о том, какие аргументы подобрать,
чтобы доказать вашу неправоту. Наш коллега Бен когда-то руководил инженером,
назовем его Дином, который имел свое мнение по всем вопросам и любил спорить
с командой. Он пылко критиковал все, от целей и задач команды до размещения
виджета на веб-странице, и отвергал любые возражения. После нескольких месяцев такого поведения Дина Бен решил сообщить ему, что тот слишком агрессивен.

110  

Глава 5. Как стать лидером в команде

Если бы Бен просто сказал: «Дин, не будь таким придурком», — то Дин полностью
проигнорировал бы это сообщение. Бен много думал о том, как заставить Дина понять, что его действия негативно отражаются на команде, и придумал следующую
метафору:
Принятие решения похоже на поезд, проезжающий через город. Выпрыгивая
перед поездом, чтобы остановить его, вы замедляете его и раздражаете машиниста. Каждые 15 минут прибывает новый поезд, и если вы будете выпрыгивать перед каждым из них, то не только потратите кучу времени на остановку
поездов, но в конечном итоге один из машинистов разозлится настолько, что
просто переедет вас. Нет ничего плохого, если вы будете пытаться остановить
какие-то поезда, но тщательно выбирайте поезда, которым действительно не
повредит остановка.
Эта метафора не только помогла разрядить ситуацию, но и позволила Бену и Дину
обсудить влияние остановок на команду, не переходя на личности.

Следите за удовлетворенностью
Еще один из способов сделать членов команды более продуктивными (и уменьшить
вероятность их ухода) в долгосрочной перспективе — потратить некоторое время
на оценку их удовлетворенности. Лучшие лидеры, с которыми мы работали, были
немножко психологами и время от времени оценивали моральное состояние членов
команды, следя за тем, чтобы они получали признание за свою работу и оставались
довольными ею. Один известный нам технический руководитель составлял таблицу
всех грязных, неблагодарных задач, которые необходимо выполнить, и равномерно
распределял эти задачи между членами команды. Другой технический руководитель
считал часы работы своей команды и устраивал выходные с совместными веселыми
выездами, чтобы избежать выгорания и утомления. Третий проводил встречи один
на один с членами команды и обсуждал технические проблемы, стараясь растопить
лед в отношениях, а затем узнавал, есть ли у сотрудников все необходимое для выполнения работы. После того как беседа приобретала более или менее непринужденный характер, он ненавязчиво расспрашивал инженера, насколько ему нравится
его работа, и рассказывал, что его ждет дальше.
Надежный способ оценить удовлетворенность команды1 — спрашивать в конце
личной встречи: «Что вам нужно?» Этот простой вопрос позволяет подвести итоги
и убедиться, что у каждого члена команды есть все, что ему нужно для продуктивной
работы и удовлетворенности ею, но если задавать его при каждой личной встрече,
члены команды запомнят эту особенность и начнут приходить к вам со списками
своих потребностей.
1

Каждый год в Google проводится опрос под названием «Googlegeist», в ходе которого оценивается уровень удовлетворенности сотрудников по многим параметрам. Это хорошая
обратная связь, но мы не назвали бы этот способ «простым».

Другие советы и рекомендации   111

Неожиданный вопрос
Вскоре после того как я начал работать в Google, у меня состоялась первая встреча
с генеральным директором Эриком Шмидтом. В конце Эрик спросил: «Вам чтонибудь нужно?» Я подготовил миллион защитных ответов на самые сложные вопросы, но к этому вопросу оказался не готов. Я сидел совершенно ошарашенный.
Но в следующий раз подготовился к такому вопросу!
Для лидера может быть полезно обратить внимание на удовлетворенность членов
команды вне офиса. Наш коллега Мекка начинает личные беседы с подчиненными,
предлагая им оценить свою удовлетворенность по шкале от 1 до 10, и его сотрудники
часто используют эту шкалу для обсуждения удовлетворенности в офисе и вне его.
Не нужно думать, что у людей нет жизни вне работы — нереалистичные ожидания
относительно количества времени, которое люди способны потратить на работу, могут
заставить их потерять уважение к вам или, что еще хуже, выгореть. Мы не предлагаем
вмешиваться в жизнь членов команды, но если вы будете внимательны к их личным
обстоятельствам, то сможете лучше понимать, почему их эффективность меняется
в разные периоды. Небольшие послабления сотруднику, который в настоящее время
испытывает сложности в личной жизни, могут побудить его уделять работе больше
времени потом, когда перед командой будут поставлены сжатые сроки.
В значительной степени удовлетворенность членов команды определяется их
отношением к своей карьере. Если вы спросите сотрудников, как им видится
их карьера через пять лет, многие из них просто пожмут плечами. Большинство
людей не любят распространяться о своих планах, но обычно у каждого человека
есть цель, которую он хотел бы достичь в следующие пять лет: продвинуться по
службе, узнать что-то новое, запустить какой-то важный проект или работать с умными людьми. Если вы хотите стать эффективным лидером, подумайте, как можно
помочь осуществить чьи-то мечты, и пусть сотрудники видят ваше участие в их
карьере. Самое важное — выявить их неявные цели, чтобы потом, когда доведется
представлять рекомендации сотрудникам, у вас был реальный набор показателей
для оценки их возможностей.
Однако удовлетворенность определяется не только карьерой, но и возможностью
для каждого члена команды стать лучше, получить признание за свою работу и попутно немного повеселиться.

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

112  

Глава 5. Как стать лидером в команде

передать работу другим инженерам, даже если для ее выполнения им потребуется
гораздо больше времени, чем вам. Этим вы не просто сохраните свое душевное
равновесие, но и дадите остальной команде возможность учиться. Чтобы быстро
завоевать уважение команды и ускорить работу, испачкайте свои руки, например
выполнив грязную работу, которую никто не хочет делать. Ваше резюме и список
достижений может быть длиной в милю, но ничто так ярко не продемонстрирует
команде ваши умения и преданность (и скромность), как выполнение действительно тяжелой работы.
Найдите себе замену
Если вы не хотите выполнять одну и ту же работу до конца своей карьеры, найдите
себе замену. Этот поиск начинается, как упоминалось выше, с найма: нанимайте
людей «умнее себя». Когда в команде появятся люди, способные выполнять вашу
работу, дайте им возможность взять на себя больше обязанностей или попробовать возглавить команду. Поступая так, вы скоро увидите, кто из них может
и хочет руководить. Но не забывайте, что некоторые сотрудники предпочитают
быть просто хорошими специалистами, и это нормально. Мы всегда удивлялись
компаниям, которые ставят своих лучших инженеров, вопреки их желаниям, на
руководящие должности, тем самым теряя хороших специалистов и получая посредственных руководителей.
Знайте, когда гнать волну
Часто и неизбежно у вас будут возникать трудные ситуации, когда внутренний
голос будет кричать вам, что не надо ничего делать. Вы можете быть недовольны
инженером: его навыками, склонностью выпрыгивать перед каждым поездом или
отсутствием мотивации при работе 30 часов в неделю. «Просто подожду немного,
и все наладится», — скажете вы себе. «Все пройдет само собой», — добавите вы.
Не попадайтесь в эту ловушку — это ситуации, в которых вы должны гнать самые
большие волны и делать это без промедления. Такие проблемы редко решаются
сами собой, и чем дольше вы будете ждать их исчезновения, тем негативнее они
будут влиять на команду и тем чаще вы будете думать о них по ночам. Выжидая,
вы лишь откладываете неизбежное и наносите работе серьезный ущерб. Так что
действуйте, причем быстро.
Защищайте свою команду от хаоса
Вступая в роль лидера, первое, что вы обнаружите, — мир за пределами команды
наполнен хаосом и неопределенностью (или даже безумием), которых вы не замечали, когда были разработчиком. Когда я впервые занял руководящий пост
в 1990-х годах (до того как снова стал рядовым разработчиком), я был озадачен
ужасающей неопределенностью и организационным хаосом в компании. Я спросил другого руководителя, в чем причина этой внезапной нестабильности в такой
спокойной компании, на что он посмеялся над моей наивностью и ответил, что
хаос был всегда, просто мой предыдущий руководитель ограждал от него меня
и всю нашу команду.

Люди похожи на растения   113

Прикрывайте свою команду
Важно своевременно информировать подчиненных о происходящем в компании «над ними», но не менее важно защищать их от множества необоснованных
требований и неопределенности, которые могут навязываться команде извне.
Делитесь с сотрудниками как можно большим количеством информации, но не
отвлекайте их организационным сумасшествием, которое вряд ли когда-либо на
них повлияет.
Сообщайте команде, когда все идет хорошо
Многие начинающие руководители настолько увлекаются искоренением недостатков у членов команды, что недостаточно часто дают им положительные
отзывы. Вы должны не только сообщать кому-то, что он облажался, но также
отмечать его успехи и обязательно сообщать ему (и его коллегам), что он делает
выдающуюся работу.
Наконец, вот еще один совет, который лучшие лидеры знают и часто используют,
когда в команде есть инженеры, желающие попробовать что-то новое:
Просто скажите «да», если потом это будет легко отменить
Если у вас есть член команды, желающий взять день или два, чтобы попробовать
новый инструмент или библиотеку1, которые могли бы ускорить работу над вашим
продуктом (и сроки не сильно поджимают), просто скажите: «Конечно, попробуй».
С другой стороны, если сотрудник хочет, например, запустить новый продукт, который придется поддерживать в течение десяти лет, тогда хорошенько подумайте
о целесообразности такой работы. По-настоящему хорошие лидеры понимают,
когда что-то можно отменить, но того, что можно отменить, намного больше, чем
вы думаете (это касается как технических, так и нетехнических решений).

Люди похожи на растения
Моя жена была младшей из шести детей в семье, и ее мать столкнулась с трудной
задачей вырастить шестерых совершенно разных детей, каждому из которых нужны
разные вещи. Я спросил свою тещу, как ей это удалось (заметили, что я cделал?),
и она ответила, что дети похожи на растения: одни похожи на кактусы, которым
нужно немного воды и много солнечного света; другие, как африканские фиалки,
нуждаются в рассеянном освещении и влажной почве; а третьи напоминают помидоры и превосходно растут, если дать им немного удобрений. Если у вас шестеро
детей и вы даете каждому одинаковое количество воды, света и удобрений, все они
получат одинаковое обращение, но высока вероятность, что никто из них не получит
того, что им действительно нужно.
Члены вашей команды тоже похожи на растения: кому-то нужно больше света,
кому-то — больше воды (а кому-то — больше... удобрений). Ваша задача как лидера
1

Подробнее о технических изменениях, которые можно «отменить», в главе 22.

114  

Глава 5. Как стать лидером в команде

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

Внутренняя и внешняя мотивация
Есть два типа мотивации: внешняя, которая исходит извне (например, денежная премия), и внутренняя, которая исходит изнутри. В книге «Драйв. Что на самом деле
нас мотивирует» (М.: Альпина Паблишер, 2019) Дэн Пинк объясняет, что сделать
людей самыми счастливыми и продуктивными нельзя одной только внешней мотивацией (например, засыпать их деньгами) — для этого нужно развивать еще и внутреннюю мотивацию, дав людям три вещи: самостоятельность, мастерство и цель1.
Самостоятельность появляется у человека, когда он может действовать без чьего-то
назойливого управления2. Самостоятельным сотрудникам (а Google стремится нанимать в основном самостоятельных инженеров) можно задать общее направление
развития продукта и предоставить возможность самим решать, как его делать. Это
развивает мотивацию не только потому, что сотрудники теснее связаны с продуктом (и, вероятно, лучше вас знают, как его создавать), но также и потому, что дает им
гораздо более сильное чувство владения продуктом. Чем больше их вклад в развитие
продукта, тем выше их интерес к его успеху.
Под мастерством в данном случае понимается возможность человека улучшить
имеющиеся навыки и овладеть новыми. Наличие благодатной почвы для повышения мастерства не только помогает мотивировать людей, но со временем делает
их лучше, от чего выигрывает вся команда3. Навыки подобны лезвию ножа: можно
потратить десятки тысяч долларов, чтобы привлечь в команду людей с самыми
1

2
3

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

Итоги   115

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

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

Итоги
y Не будьте «начальником» в традиционном смысле: сосредоточьтесь на лидерстве,
влиянии и служении команде.
y Делегируйте все, что сможете; не старайтесь сделать все сами.
y Обратите особое внимание на сосредоточенность, направление и скорость работы
команды.

1

Grant A. M. The Significance of Task Significance: Job Performance Effects, Relational Mechanisms,
and Boundary Conditions. Journal of Applied Psychology, 93, No. 1 (2018), http://bit.ly/task_
significance.

ГЛАВА 6

Масштабируемое лидерство
Автор: Бен Коллинз-Сассмэн
Редактор: Риона Макнамара
В главе 5 мы поговорили о том, как перейти от роли «рядового разработчика» к роли
лидера команды. В этой главе мы рассмотрим, как наиболее эффективно продолжить путь лидера и перейти от руководства одной командой к руководству группой
смежных команд.
Все лучшие практики руководства сохраняют свою актуальность по мере движения
лидера вверх по карьерной лестнице. Вы останетесь «лидером-слугой», несмотря
на увеличение числа подчиненных. Однако проблемы, которые вы будете решать,
станут более широкими и абстрактными и вынудят вас подняться на «более высокий
уровень» — меньше разбираться в технических деталях, чтобы видеть «ширину»,
а не «глубину» проблем. Вас будет огорчать невостребованность своих инженерных
знаний, а ваша эффективность начнет напрямую зависеть от общей технической
интуиции и способности побудить инженеров двигаться в правильном направлении.
Этот процесс часто деморализует до тех пор, пока вы не заметите, что оказываете
гораздо большее влияние как лидер, а не как разработчик. Это сладкое осознание
имеет привкус горечи.
Итак, учитывая, что мы понимаем основы лидерства, подумайте, что нужно, чтобы
превратить себя в действительно хорошего лидера? Об этом мы поговорим здесь
и используем то, что мы называем «три всегда в лидерстве»: всегда принимайте
решение, всегда уходите, всегда будьте масштабируемым.

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

Притча о самолете
Линдсей Джонс (http://lindsayjones.com) — наш друг, театральный звукорежиссер
и композитор. Он часто летает по США от одного производства к другому и полон

Всегда принимайте решение   117

безумных (и правдивых) историй о воздушных путешествиях. Вот одна из наших
любимых историй:
Шесть часов утра, мы сели в самолет и готовы взлетать. Вдруг командир воздушного судна включает громкую связь и сообщает, что кто-то переполнил
топливный бак на 10 000 галлонов. Я много летал на самолетах, но не знал, что
такое возможно. Я имею в виду, что если я переполню бак в машине хотя бы на
галлон, то залью бензином свои ботинки.
Как бы то ни было, командир говорит, что есть два варианта: можно подождать,
пока подъедет заправщик и откачает лишнее топливо из самолета, что займет
более часа, или двадцать человек сойдут с самолета, чтобы выровнять вес.
Но никто даже не сдвинулся с места.
В салоне был парень, сидевший через проход от меня в первом классе, невероятно
злой. Он напомнил мне Фрэнка Бернса из M*A*S*H1. Он был жутко возмущен
и, брызгая слюной, требовал назвать виновного. Это было потрясающее зрелище,
как будто он герой фильма-буффонады.
В какой-то момент он схватил кошелек и достал огромную пачку денег! И такой:
«Я не могу опоздать на эту встречу! Я дам 40 долларов любому, кто сойдет с самолета прямо сейчас!»
Конечно же, нашлись люди, решившиеся этим воспользоваться. Он выдал по
40 долларов 20 пассажирам (а это 800 долларов наличными!), и они сошли с самолета.
Теперь все в порядке и самолет начинает выруливать на взлетно-посадочную
полосу. Но тут снова включается командир и сообщает, что компьютер самолета
перестал работать и никто не знает почему. Теперь самолет нужно отбуксировать
обратно к выходу на посадку.
Фрэнка Бернса чуть не хватил удар. Серьезно! Я думал, у него случится инсульт.
Он сыпал проклятиями. Все остальные просто переглядывались между собой.
Мы вернулись к воротам, и этот парень потребовал отправить его другим рейсом.
Ему предложили место на самолете, вылетающем в 9:30. Он спросил: «Разве нет
рейса до 9:30?»
А служащий аэропорта у выхода на посадку ответил: «Ну, на 8:00 есть еще один
рейс, но он полон. Они сейчас закрывают двери».
А он такой: «Полон?! Что значит полон? В этом самолете нет ни одного свободного места?!»
А служащий аэропорта говорит: «Нет, сэр, на этом самолете были места, пока
вдруг из ниоткуда не появились 20 пассажиров и не заняли их. Это были самые
1

Американский телесериал, созданный Ларри Гелбертом, в российском прокате вышел под
названием «Чертова служба в госпитале МЭШ». — Примеч. пер.

118  

Глава 6. Масштабируемое лидерство

счастливые пассажиры, которых я когда-либо видел, они смеялись всю дорогу
до трапа».
Рейс на 9:30 был, пожалуй, самым тихим.
Эта история, как вы понимаете, о компромиссах. Большая часть этой книги посвящена различным техническим компромиссам в инженерных системах, но оказывается,
что компромиссы применимы и к поведению людей. Как лидер вы обязаны принимать решения о том, что должны делать ваши команды каждую неделю. Иногда
компромиссы очевидны («если мы будем работать над этим проектом, то задержим
другой»); иногда они имеют непредсказуемые последствия, как в той истории про
самолет.
На самом высоком уровне ваша работа как лидера состоит в том, чтобы направлять
людей к решению сложных и неоднозначных проблем. Под неоднозначностью мы
подразумеваем, что проблема не имеет очевидного решения и даже может оказаться
неразрешимой. В любом случае проблема должна быть изучена, исследована и (желательно) проконтролирована. Если сравнить написание кода с вырубкой деревьев,
то ваша задача как лидера состоит в том, чтобы «увидеть лес за деревьями», найти
правильный путь через этот лес и направить инженеров к нужным деревьям. На этом
пути вы должны сделать три важных шага: снять шоры, выявить компромиссы и, наконец, принять решение и повторить процесс.

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

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

Всегда принимайте решение   119

КЕЙС: РЕШЕНИЕ ПРОБЛЕМЫ «ЗАДЕРЖЕК» В WEB SEARCH
При управлении командой из команд возникает естественное стремление заняться развитием не одного продукта, а целого «класса» продуктов или, может быть, решением более
широкой проблемы, характерной для нескольких продуктов. Рассмотрим, например, наш
самый старый продукт — Web Search.
Десять лет тысячи инженеров в Google работали над общей проблемой улучшения результатов поиска. Но побочным эффектом этих усилий стало постепенное замедление
скорости работы продукта. Когда-то результаты поиска в Google отображались на странице в виде десятка синих ссылок на веб-сайты. И тысячи крошечных изменений добавили к ним изображения, видеоролики, блоки с фактами из Википедии и даже элементы
интерактивного интерфейса. Это увеличило нагрузку на серверы: по сети передавалось
больше байтов, а клиенту (обычно по телефону) отображалась более сложная разметка
HTML. Несмотря на то что за эти же десять лет быстродействие сети и компьютеров
заметно увеличилось, скорость работы страницы поиска только уменьшалась из-за задержки ее отображения. Кому-то может показаться, что в этом нет ничего особенного, но
задержка в работе продукта напрямую влияет (в совокупности с другими проблемами)
на вовлеченность пользователей и частоту использования продукта. Даже увеличение
времени отображения всего на 10 мс имеет значение. Задержка нарастает медленно. Это
не вина конкретной команды инженеров, скорее это длительное коллективное отравление среды. В какой-то момент общая задержка в Web Search выросла до такой степени,
что ее эффект стал сводить на нет внесенные улучшения и отрицательно сказался на
вовлеченности пользователей.
Многие лидеры долго боролись с этой проблемой, но не смогли решить ее на систематическом уровне. Шоры, которые все носили, предполагали, что единственный способ
устранить задержку — раз в два-три года объявлять «желтый код»1 и бросать все силы на
оптимизацию кода и ускорение работы продукта. Эта стратегия позволяла добиться улучшения на какое-то время, после чего задержка снова начинала расти и через месяц или два
возвращалась к прежнему уровню.
Что изменилось с тех пор? В какой-то момент мы сделали шаг назад, выявили недостатки
в работе и произвели полную переоценку компромиссов. Мы поняли, что погоня за «качеством» имеет не одну, а две разные издержки. Первая издержка — для пользователя: более
высокое качество обычно означает больший объем отправляемых данных и соответственно бˆольшую задержку. Вторая издержка — для Google: более высокое качество означает
больше работы, чтобы сгенерировать данные, и больше затрат процессорного времени на
наших серверах — того, что мы называем «пропускной способностью». Руководство очень
внимательно относилось к компромиссу между качеством и пропускной способностью, но
оно никогда не рассматривало задержку как фактор, влияющий на принятие решения. Как
гласит старая шутка, «Выбери два из хорошо, быстро и дешево». Самый простой способ
наглядно представить компромисс — нарисовать треугольник с вершинами хорошо (качество), быстро (задержка) и дешево (пропускная способность).

1

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

120  

Глава 6. Масштабируемое лидерство

Задержка

Пропускная
способность

Качество

Рис. 6.1. Компромиссы в Web Search: выбери два!
Именно это и произошло. Легко улучшить любую из этих характеристик в ущерб, по
крайней мере, одной из двух других. Например, можно улучшить качество, добавив больше данных на страницу с результатами поиска, но это уменьшит пропускную способность
и увеличит задержку. Также можно пойти на прямой компромисс между задержкой и пропускной способностью, увеличив трафик на обслуживающий кластер. Если вы передадите
кластеру больше запросов, то получите увеличенную пропускную способность, то есть
более полное использование процессоров и более быструю окупаемость средств, вложенных
в аппаратное обеспечение. Но более высокая нагрузка увеличит частоту конфликтов за
обладание ресурсами на компьютере, что усугубит среднюю задержку обработки запроса.
Намеренное уменьшение трафика (ослабление нагрузки) приведет к уменьшению пропускной способности, но при этом каждый отдельный запрос будет обрабатываться быстрее.
Главное здесь — это понимание. Понимание всех компромиссов позволило нам начать
экспериментировать с новыми способами балансировки. Теперь мы можем рассматривать
задержку не как неизбежный и случайный побочный эффект, а как типичный результат,
стоящий в одном ряду с другими нашими результатами. Мы выработали новые политики.
Например, наши специалисты по обработке данных смогли точно измерить, насколько
задержка повлияла на вовлеченность пользователей. Это помогло им определить метрику,
позволяющую сопоставить улучшения в качестве с вовлеченностью пользователей в краткосрочной перспективе, и ущерб, вызванный задержками, с вовлеченностью пользователей
в долгосрочной перспективе. Теперь, если небольшое изменение улучшает качество, но
увеличивает задержку, мы можем количественно оценить, стоит ли внедрять это изменение или нет. Мы каждый месяц определяем, насколько сбалансированы наши изменения
в качестве, задержке и пропускной способности.

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

Всегда уходи   121

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

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

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

122  

Глава 6. Масштабируемое лидерство

Распределение задач
Сложные задачи обычно состоят из множества более мелких сложных задач. Если
вы возглавляете команду из команд, вам потребуется распределить небольшие задачи между командами. Но учтите, что меньшие задачи могут меняться со временем
и жесткие ограничения по их выполнению могут помешать заметить эти изменения
и приспособиться к ним. Если есть возможность, пересматривайте организационную
структуру, пробуйте перестраивать ее, чтобы получить больше свободы: меняйте
размеры подгрупп, дайте сотрудникам возможность переходить из группы в группу, перераспределяйте задачи между группами. Назначайте не «слишком жесткие»
и не «слишком расплывчатые» границы выполнения: с одной стороны, подгруппы
должны четко понимать цель задачи и средства ее достижения, но с другой стороны,
исполнители должны иметь свободу выбора направления и пробовать что-то новое
в ответ на меняющуюся обстановку.
Пример: распределение «задачи с задержкой» в Google Search
Подходя к проблеме задержки в Google Search, мы поняли, что эту задачу можно
разделить как минимум на два основных направления: устранение симптомов
задержки и устранение ее причин. Было очевидно, что нужно создать несколько
проектов и укомплектовать их людьми, чтобы оптимизировать кодовую базу для
повышения скорости, но одного ускорения было недостаточно. Тысячи инженеров
продолжали наращивать сложность и «качество» результатов поиска, быстро сводя
на нет оптимизации скорости, поэтому нам также нужно было направить людей на
предотвращение задержки. Мы выявили пробелы в метриках анализа задержек,
обучении разработчиков и документации. Назначив разные команды для одновременной работы над причинами и симптомами задержек, мы смогли обеспечить
надежный систематический контроль над задержками. (Обратите внимание, что эти
команды занимались задачами, а не конкретными решениями!)
Делегирование подзадач лидерам
Тема «делегирования» в книгах по менеджменту — это клише, но для ее упоминания
есть причина: научиться делегированию действительно трудно. Оно идет вразрез
с нашими представлениями об эффективности по пословице: «Хочешь сделать хорошо — сделай это сам».
Но если вы согласны с тем, что ваша цель — создать самостоятельную организацию,
основным способом ее достижения является делегирование. Вы должны воспитать
плеяду самодостаточных лидеров, и делегирование — это самый эффективный способ их обучения. Вы поручаете им задание, позволяете потерпеть неудачу, а затем
даете возможность пробовать снова и снова. В Кремниевой долине широко известны
мантры о «быстрых неудачах и повторных попытках». Эта философия относится не
только к инженерному проектированию, но и вообще к обучению.
Портфель лидера постоянно пополняется важными задачами, которые необходимо
решать. Большинство из этих задач довольно просты для вас. Представьте, что вы

Всегда уходи   123

усердно разбираете свою почту, отвечая на вопросы, а затем решаете прерваться на
20 минут, чтобы устранить старую надоевшую проблему. Но прежде чем сделать это,
остановитесь и задайте себе вопрос: действительно ли я единственный, кто сможет
выполнить эту работу?
Возможно, вы справитесь с задачей намного эффективнее, чем кто-либо, но тогда ваши
лидеры ничему не научатся. Если задача не горит, тогда сделайте усилие над собой
и поручите работу кому-нибудь другому — скорее всего, тому, кто точно справится
с ней, но медленнее, чем вы. Помогайте, если понадобится. Ваши лидеры должны
научиться «повышать уровень» и выполнять работу самостоятельно, чтобы вы не
попадали в критические ситуации.
Отсюда следует, что вы должны помнить о своей цели как лидера лидеров. Приходя
утром на работу, задавайте себе важный вопрос: что я могу сделать, чего никто другой
в моей команде не сможет?
На этот вопрос есть много хороших ответов. Например, вы можете защитить команды
от организационной политики, поддержать их и создать благоприятный психологический климат, продвигая культуру смирения, доверия и уважения. Также важно
уделить внимание «управлению вверх», то есть следить за тем, чтобы вышестоящее
руководство понимало, чем занимается ваша группа, и оставаться в курсе событий
в компании. Но часто самый верный ответ на этот вопрос: «Я вижу лес за деревьями».
Другими словами, вы можете определять высокоуровневые политики. Ваша стратегия
должна охватывать не только общее техническое направление, но и организационное.
Вы определяете план решения неоднозначной проблемы и способ его претворения
в жизнь вашей организацией в течение долгого времени. Вы постоянно составляете
карту леса, а вырубку деревьев поручите другим.
Корректировка и повторение
Давайте предположим, что вы достигли момента, когда создали самодостаточную
организацию. Вы больше не единая точка отказа. Поздравляем! Чем заняться дальше?
Прежде чем ответить, обратите внимание, что вы действительно освободили себя —
теперь у вас есть свобода «всегда уходить». Вы можете заняться решением новой
или смежной проблемы или перейти в другой отдел и в другую предметную область,
освободив место для перспективных лидеров, которых вы обучили. Это отличные
способы избежать выгорания.
Простой ответ на вопрос «что дальше?»: направлять созданную организацию и поддерживать ее. Но без явной на то необходимости вы должны действовать тонко.
В книге «Debugging Teams»1 есть притча о том, как выполнять осмысленные корректировки:
Есть история о Мастере-механике, который давно вышел на пенсию. В компании,
где он раньше работал, возникла проблема, которую никто не мог решить. Со1

Fitzpatrick B. W., Collins-Sussman B. Debugging Teams: Better Productivity through Collaboration.
Boston: O’Reilly, 2016.

124  

Глава 6. Масштабируемое лидерство

трудники вызвали Мастера, чтобы узнать, сможет ли он помочь найти причину
проблемы. Мастер осмотрел сломавшуюся машину, послушал ее, вытащил кусочек
мела и нарисовал маленький крестик сбоку на ее корпусе. Затем сказал технику,
что в этом месте не закреплен провод. Техник вскрыл машину, затянул проволоку
и тем самым решил проблему. Когда Мастер предъявил счет на 10 000 долларов,
разгневанный генеральный директор потребовал объяснить, почему Мастер
требует столь высокую плату просто за то, что нарисовал мелом крестик! Тогда
Мастер предъявил другой счет, в котором указал, что 1 доллар стоит мел, которым
был нарисован крестик, и 9999 долларов — знание, где его поставить.
Это весьма поучительная история: единственная, тщательно продуманная корректировка может принести весомый результат. Это ценный прием при управлении
людьми. Мы представляем, что наша команда летит на большом дирижабле,
медленно и уверенно двигаясь в определенном направлении. Вместо того чтобы
заниматься микроменеджментом и пытаться постоянно корректировать курс,
мы большую часть недели внимательно наблюдаем и слушаем, а в конце делаем
маленькую отметку мелом в нужном месте — то есть выполняем небольшое, но
важное «действие», чтобы скорректировать курс.
Вот что такое хороший менеджмент: 95 % наблюдения и 5 % важных корректировок
в нужном месте. Слушайте своих лидеров и подчиненных. Разговаривайте со своими
клиентами и помните, что часто (особенно если ваша команда строит инженерную
инфраструктуру) ваши «клиенты» — это не конечные пользователи, а ваши коллеги. Удовлетворенность клиентов требует такого же внимательного отношения, как
и удовлетворенность подчиненных. Узнавайте, что работает, а что — нет и сохраняет
ли дирижабль правильное направление? Ваше управление должно быть итеративным, но вдумчивым и с минимальными корректировками курса. Если вы окунаетесь
в микроменеджмент, то рискуете стать единой точкой отказа! «Всегда уходи» — это
призыв к макроменеджменту.
Позаботьтесь о самоидентификации команды
Распространенная ошибка — считать, что команда должна отвечать за конкретный
продукт, а не за общую задачу. Продукт — это решение задачи. Срок службы решений
может быть коротким, и продукты могут быть вытеснены более удачными решениями.
Однако задача — при правильном выборе — может быть вечной. Самоидентификация
команды по конкретному решению («Мы — команда, управляющая репозиториями
Git») может со временем порождать всевозможные страхи ее членов. Если компания захочет использовать новую VCS, скорее всего, команда, идентифицирующая
себя по решению, будет «упорствовать», защищать свое решение, противостоять
переменам и даже начнет вредить организации. Она будет цепляться за свои шоры,
потому что решение стало ее самоидентификацией. Если, напротив, команда будет
связывать себя с задачей («Мы — команда, обеспечивающая управление версиями
для компании»), она сможет свободно экспериментировать с различными решениями,
появляющимися время от времени.

Всегда масштабируйте себя   125

Всегда масштабируйте себя
Во многих книгах о менеджменте говорится о «масштабировании» в контексте «максимизации вашего влияния» — стратегиях развития команды и вашего лидерства.
Мы не собираемся обсуждать этот вопрос здесь, потому что уже не раз затрагивали
его. Должно быть очевидно, что создание самостоятельной организации с сильными
лидерами само по себе является отличным рецептом роста и успеха.
Вместо этого мы обсудим масштабирование команды с оборонительной и личной
точек зрения, а не с наступательной. Самый ценный ресурс лидера — это ограниченный запас времени, внимания и энергии. Если вы агрессивно будете наращивать ответственность и власть своих команд, не научившись защищать свое здравомыслие,
то масштабирование вашего лидерства обречено на провал. Поэтому мы поговорим
о том, как эффективно масштабировать себя.

Цикл успеха
Команда решает сложную задачу по стандартной схеме. Вот как она выглядит:
Анализ
Вы выявляете проблему и начинаете ее решать. Вы определяете шоры, выявляете
все компромиссы и выстраиваете мнение о том, как ими управлять.
Сражение
Вы начинаете работать независимо от того, есть ли у команды все необходимое.
Вы готовитесь к неудачам и повторным попыткам. В этот период вашу работу
можно сравнить с ношением воды в решете. Вы подталкиваете своих лидеров
и экспертов к выработке мнений, а затем внимательно выслушиваете их и разрабатываете общую стратегию, пусть и не совсем верную1.
Движение вперед
Команда начнет приходить к пониманию задачи. Вы принимаете все более разумные решения, и начнется реальное движение вперед. Моральный дух коллектива
укрепляется. Вы пробуете компромиссы, и организация начинает самостоятельно
решать проблему. Отличная работа!
Награда
Внезапно ваш руководитель поздравляет вас с успехом. Вы обнаруживаете, что
ваша награда — не похлопывание по плечу, а совершенно новая задача, которую
нужно решить. Все верно: награда за успех — новая работа... и новая ответственность! Часто новая задача похожа на предыдущую, но не менее сложна.
1

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

126  

Глава 6. Масштабируемое лидерство

И вы попадаете в трудное положение. Вам дали новую задачу, но (как правило) не
дали больше людей. Теперь вам нужно каким-то образом заняться решением двух
задач, а это значит, что, скорее всего, первая задача должна быть решена вдвое меньшим количеством людей и за вдвое меньшее время. Вторая половина ваших людей
вам понадобится, чтобы заняться новой работой! Последний шаг решения задачи мы
называем стадией сжатия: вы берете все, что делали, и сжимаете до вдвое меньших
размеров.
В действительности цикл успеха — это скорее спираль (рис. 6.2). В течение многих
месяцев и лет ваша организация масштабируется, решая задачи, а затем выясняя, как
их сжать, чтобы параллельно вступить в схватку с новыми задачами. Если повезет,
вам разрешат нанять еще людей. Однако чаще расширение штата сотрудников не
будет поспевать за масштабированием. Ларри Пейдж, один из основателей Google,
скорее всего, назвал бы эту спираль «невероятно захватывающей».
БОЛЕЕ
ТЯЖЕЛОЕ
сражение

Сражение

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

Сжатие

Движение
вперед

Рис. 6.2. Спираль успеха

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

Всегда масштабируйте себя   127

Важное против срочного
Вспомните время, когда вы были простым беззаботным сотрудником. Если раньше
вы были программистом, ваша жизнь была более спокойной. У вас был список дел,
и каждый день вы методично работали по этому списку, писали код и устраняли
проблемы. Расстановка приоритетов, планирование и выполнение работы были
простыми и понятными.
Однако, став лидером, вы замечаете, что ваш режим работы стал менее предсказуемым
и больше похож на пожаротушение. То есть ваша работа стала менее проактивной
и более реактивной. Чем выше занимаемый пост, тем больше форс-мажоров возникает в работе. Вы — предложение «finally» в длинном списке блоков кода! Все
ваши средства связи — электронная почта, чаты, встречи — напоминают атаки «отказ в обслуживании» на ваши время и внимание. На самом деле, если не проявить
осторожность, вы в конечном итоге будете тратить все свое время на работу в реактивном режиме. Люди будут бросать вам мячи, а вы — отчаянно прыгать из стороны
в сторону, стараясь поймать их все.
Эта проблема обсуждалась во многих книгах. Автор книг по менеджменту Стивен
Кови известен своей идеей необходимости отличать важное от срочного. Фактически
эту идею популяризировал президент США Дуайт Эйзенхауэр в своем высказывании в 1954 году:
«У меня есть два вида задач — срочные и важные. Срочные не важны, а важные
не срочны».
Напряжение в работе представляет одну из самых больших опасностей для вашей
эффективности как лидера. Если вы позволите себе окунуться в реактивный режим (что происходит почти автоматически), вы потратите каждый момент своей
жизни на неотложные задачи, которые почти все не играют важной роли в общей
картине. Помните, что ваша работа как лидера состоит в том, чтобы делать то, что
можете сделать только вы, например прокладывать путь через лес. Выстроить такую
метастратегию невероятно важно, но почти никогда не срочно. Всегда легче ответить
на следующее срочное письмо.
Итак, как заставить себя работать преимущественно над важным, а не срочным? Вот
несколько ключевых приемов:
Делегируйте
Многие неотложные дела можно передать другим лидерам. Вас может терзать
чувство вины за делегирование тривиальной задачи или беспокойство о ее более
медленном решении. Но делегируя, вы тренируете подчиненных и освобождаете
свое время для работы над чем-то важным, что можете сделать только вы.
Планируйте время
Регулярно отводите пару часов или больше для спокойной работы только над
важным, но не срочным, например над выработкой командной политики, опре-

128  

Глава 6. Масштабируемое лидерство

делением направлений карьерного роста ваших лидеров или планированием
сотрудничества с другими командами.
Подберите хорошую систему учета
Существуют десятки систем учета, помогающих расставить приоритеты в работе.
Некоторые опираются на использование ПО (например, специальные инструменты ведения списка дел), другие — на использование ручки и бумаги (как метод
«Bullet Journal», http://www.bulletjournal.com), а третьи не зависят от реализации.
Относительно последней категории большую популярность среди инженеров завоевала книга Дэвида Аллена «Как привести дела в порядок» (М.: МИФ, 2016).
Она описывает абстрактный алгоритм работы с задачами и поддержания «почтового ящика пустым». Попробуйте разные системы и определите, какая лучше
подходит для вас. Постарайтесь найти что-то более эффективное, чем стикеры
на экране компьютера.

Учитесь ронять мячи
Есть еще один ключевой метод управления своим временем, и на первый взгляд он
выглядит чересчур радикальным. Для многих этот метод противоречит многолетним
инженерным инстинктам. Как инженер вы обращаете внимание на детали: составляете списки дел, проверяете, что в них не попало, проявляете точность и всегда
заканчиваете начатое. Вам приятно закрывать ошибки в баг-трекере или сокращать
количество необработанных входящих сообщений до нуля. Но ваши время и внимание как лидера лидеров находятся под постоянной атакой. Независимо от ваших
стараний вы, так или иначе, начнете ронять мячи на пол — их просто слишком много.
Это ошеломляет, и вы, наверное, все время чувствуете вину за это.
А теперь отступим на шаг назад и посмотрим на ситуацию беспристрастно. Если
падение каких-то мячей неизбежно, не лучше ли уронить некоторые из них преднамеренно, а не случайно? По крайней мере, тогда у вас появится ощущение контроля.
Вот отличный способ сделать это.
Мари Кондо, консультант по организационным вопросам, в книге «Магическая
уборка. Японское искусство наведения порядка дома и в жизни» (М.: Эксмо, 2017)
рассказала о философии эффективного наведения порядка в доме, которую с успехом
можно применить к любому абстрактному беспорядку.
Подумайте о своем физическом имуществе как о трех кучах. Около 20 % ваших
вещей просто бесполезны (вы попользовались ими один раз и больше никогда не
трогали), их очень легко выбросить. Около 60 % вещей представляют определенный интерес, они различаются для вас по важности, и вы используете их время от
времени. И только оставшиеся 20 % ваших вещей действительно важны для вас:
вы используете их постоянно, они имеют большое эмоциональное значение или,
как говорит мисс Кондо, вызывают глубокую «радость», когда вы просто берете их
в руки. Главная мысль ее книги состоит в том, что большинство людей неправиль-

Всегда масштабируйте себя   129

но подходят к организации своей жизни: они тратят время, чтобы выбросить 20 %
мусора, но оставшиеся 80 % вещей все еще создают ощущение загромождения. Она
утверждает, что для наведения истинного порядка нужно определить верхние, а не
нижние 20 %. Если вы сможете определить только важные вещи, вы должны выбросить остальные 80 %. Звучит экстремально, но довольно эффективно. Этот метод
позволяет радикально избавиться от хлама.
Эту философию с успехом можно применить к входящей почте или списку дел —
мячам, брошенным вам. Разделите мячи на три кучи: нижние 20 % мячей, вероятно,
не являются ни срочными, ни важными, и их можно смело удалить или проигнорировать. Средние 60 % задач, которые могут иметь ту или иную степень срочности
или важности, — это смешанная куча. На вершине остаются 20 % мячей, имеющих
неоспоримую важность.
А теперь, работая над своими задачами, не пытайтесь взяться за верхние 80 %, иначе
вы окажетесь загруженными срочными, но не важными задачами. Вместо этого внимательно определите мячи, которые попадают в верхние 20 %, — критические задачи,
которые можете сделать только вы, — и сосредоточьтесь только на них. Позвольте
себе уронить остальные 80 %.
Поначалу это может показаться ужасным, но если вы намеренно уроните так много
мячей, то обнаружите два удивительных обстоятельства. Во-первых, даже если вы
никому не будете делегировать средние 60 % задач, ваши подчиненные заметят это
и подберут их сами. Во-вторых, если что-то в этой средней куче действительно важно,
оно все равно вернется к вам, рано или поздно перейдя в верхние 20 %. Вам просто
нужно поверить, что задачи, не попавшие в верхние 20 %, будут решены другими или
вырастут до уровня действительной важности. Между тем, сконцентрировавшись
только на критически важных задачах, вы сможете распределить свое время и внимание так, чтобы верно реагировать на постоянно растущие обязанности вашей группы.

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

130  

Глава 6. Масштабируемое лидерство

Возьмите настоящий отпуск
Выходные — это не отпуск. Требуется как минимум три дня, чтобы «забыть»
о работе, и по меньшей мере неделя, чтобы почувствовать себя обновленным. Но
продолжая во время отпуска проверять рабочую почту или чаты, вы перекрываете подпитку. Поток беспокойства прорывается в ваш разум, и все преимущества
психологического дистанцирования улетучиваются. Отпуск заряжает, только если
вы действительно полностью отключаетесь от работы1. А это возможно, только
если вы создали организацию, которая может работать без вас.
Просто отключитесь
Решив отключиться от дел, оставьте свой рабочий ноутбук в офисе. Если на
вашем личном телефоне есть рабочие контакты, удалите их. Например, если
ваша компания использует G Suite (Gmail, Google Calendar и т. д.), установите
эти приложения в «рабочем профиле» на личном телефоне. У вас появятся два
приложения Gmail: одно для личной электронной почты, другое — для рабочей.
На телефоне с Android достаточно нажать всего одну кнопку, чтобы полностью
отключить рабочий профиль. Все значки рабочих приложений станут серыми,
как если бы они были удалены, и вы не сможете «случайно» проверить рабочие
сообщения, пока вновь не включите рабочий профиль.
Сделайте выходные по-настоящему выходными
Выходные не так эффективны, как отпуск, но они тоже могут немного подзарядить вас. Но имейте в виду, что подзарядка возможна только в том случае, если
вы полностью отключитесь от общения по рабочим вопросам. Попробуйте на
самом деле выйти из системы в пятницу вечером, провести выходные, занимаясь
любимым делом, и войти снова в понедельник утром, когда вернетесь в офис.
Делайте перерывы в течение дня
В естественной среде человеческий мозг работает 90-минутными циклами2. Воспользуйтесь возможностью встать и прогуляться по офису или выйти на 10 минут
на улицу. Такие маленькие перерывы, конечно, позволяют подзарядиться лишь
чуть-чуть, но они могут существенно снизить уровень стресса и улучшить ваше
самочувствие в течение следующих двух часов работы.
Дайте себе право на день психологической разгрузки
Иногда без всякой причины работа не задается. Вы могли хорошо выспаться,
хорошо поесть, позаниматься спортом, и все равно у вас плохое настроение. Если
вы лидер, то это ужасно. Ваше плохое настроение накаляет атмосферу, а это может
привести к неверным решениям (электронные письма, которые вы не должны
были отправлять, слишком суровые суждения и т. д.). Оказавшись в такой ситу1

2

Вам нужно заранее приготовить себя к тому, что во время отпуска ваша работа просто не
будет выполнена. Упорный (или энергичный) труд непосредственно перед отпуском и после
него смягчает эту проблему.
Узнать больше о циклах покоя-активности мозга можно в Википедии: https://en.wikipedia.
org/wiki/Basic_rest-activity_cycle.

Итоги   131

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

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

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

ГЛАВА 7

Оценка продуктивности инженеров
Автор: Сиера Джаспен
Редактор: Риона Макнамара
Google — компания, управляемая данными. Большинство наших продуктов и проектных решений прочно опираются на данные. Решения, принятые на основе данных
и соответствующих метрик, носят объективный, а не субъективный характер. Однако
сбор и анализ данных о человеческой натуре имеют свои проблемы. Мы в Google
обнаружили, что в сфере разработки ПО наличие команды специалистов, сосредоточенных на продуктивности труда инженеров, очень ценно и важно, потому что
компания может масштабировать и использовать идеи такой команды.

Зачем оценивать продуктивность инженеров?
Представьте, что вы владеете процветающим бизнесом (например, развиваете систему поиска в интернете) и хотите расширить его (выйти на рынок корпоративных,
облачных или мобильных приложений). Для этого необходимо увеличить размер
инженерной организации. Однако расходы на связь растут в квадратичной зависимости от роста размеров организации1. Вы можете нанять больше людей, но накладные расходы на связь не будут расти линейно с расширением персонала. Линейно
масштабировать бизнес с увеличением размеров вашей инженерной организации
не получится.
Есть другой способ решить проблему масштабирования: сделать каждого сотрудника более продуктивным. Это поможет расширить сферу бизнеса без увеличения
накладных расходов на связь.
Компании Google пришлось быстро осваивать новые сферы бизнеса и соответственно
учить инженеров работать более продуктивно. Для этого нам нужно было понять,
что делает сотрудников продуктивными, найти причины неэффективности инженерных процессов и исправить выявленные проблемы. Эти меры можно повторять при
необходимости в процессе непрерывного улучшения и тем самым масштабировать
инженерную организацию с учетом все возрастающих потребностей.
1

Брукс Ф. Мифический человеко-месяц, или Как создаются программные системы. СПб.:
Питер, 2021. — Примеч. пер.

Расстановка приоритетов: что измерять?   133

Однако этот цикл мер тоже требует человеческих ресурсов. Было бы нецелесо­
образно повышать продуктивность десяти инженеров в год за счет труда пятидесяти
инженеров в течение года, выявляющих и устраняющих препятствия, мешающие
росту продуктивности. Наша цель — не только повысить продуктивность разработки
ПО, но и сделать это эффективно.
Мы в Google достигли этой цели, создав команду исследователей, занимающихся
вопросами повышения продуктивности инженеров. В нее вошли люди, работающие
над исследованиями в области программной инженерии, инженеры-программисты
общего профиля, а также социологи из разных областей, включая когнитивную
психологию и поведенческую экономику. Добавление специалистов социальных
наук позволило нам изучать человеческий фактор разработки ПО, включая личные
мотивы, структуру стимулов и политики для управления сложными задачами. Мы
стремимся оценить и увеличить продуктивность инженерного труда, используя
подходы на основе данных.
В этой главе мы рассмотрим, как наша исследовательская группа достигает поставленной цели. Все начинается с расстановки приоритетов. В разработке ПО есть много
параметров, которые можно измерить, но что нужно измерить? Мы рассмотрим, как
после выбора проекта исследовательская группа определяет значимые метрики,
идентифицирующие проблемные этапы процесса, и как показатели для оценки
увеличения продуктивности используются в Google.
В этой главе мы исследуем конкретный пример, представленный языковыми командами C++ и Java: поддержку удобочитаемости. (Подробнее об удобочитаемости
в главе 3.) Этот процесс был введен в первые годы существования Google, еще до
того, как стали привычными средства автоматического форматирования (глава 8)
и статического анализа кода (глава 9), блокирующие его отправку. Сам процесс
обходится довольно дорого, потому что требует, чтобы сотни инженеров проверяли
удобочитаемость кода, написанного другими инженерами. Некоторые сотрудники
считали его архаичным проявлением «дедовщины», не имеющим смысла, и это была
их любимая тема в обеденный перерыв. Перед языковыми командами был поставлен
вопрос: стоит ли тратить время на повышение удобочитаемости?

Расстановка приоритетов: что измерять?
Для оценки продуктивности инженеров нужно выбрать метрики. Само измерение —
дорогостоящий процесс, включающий производство измерений, анализ результатов
и распространение полученных данных в компании. Такие мероприятия могут замедлять работу инженерной организации в целом. Даже если замедления не происходит, отслеживание прогресса может влиять на поведение инженеров и отвлекать
их от реальных проблем. Измерения и оценка должны производиться с умом — не
становиться гаданием на кофейной гуще и не отнимать время и ресурсы на измерение ненужного.

134  

Глава 7. Оценка продуктивности инженеров

Мы в Google придумали ряд вопросов, чтобы помочь командам определить, стоит ли
вообще проводить измерения. Сначала мы просим людей описать в форме конкретного вопроса, что они хотели бы измерить. Как показывает практика, чем конкретнее
человек формулирует вопрос, тем выше вероятность, что он получит пользу от ответа.
Когда к нам обратилась группа по удобочитаемости, ее вопрос был прост: окупятся
ли для компании затраты на работу инженера по повышению удобочитаемости?
Затем мы просим их рассмотреть следующие аспекты их вопроса:
Какой результат вы ожидаете получить и почему?
Не будем притворяться, что мы относимся к теме нейтрально. У нас есть свои
представления о вопросе. Признав это с самого начала, мы попытаемся устранить
предубеждения и не допустить объяснения результатов постфактум.
Команда по удобочитаемости отметила, что причина возникновения вопроса
о целесообразности дополнительной проверки кода в неуверенности. Одно время
люди были уверены, что затраты на контроль удобочитаемости окупятся, но после
появления автоматизированных инструментов форматирования и статического
анализа эта уверенность стала неполной. Развилось убеждение, что этот процесс
потерял актуальность. Он еще может давать инженерам преимущества (и результаты опроса показали, что люди стремятся их получить), но неясно, стоят ли эти
преимущества времени, затраченного авторами или рецензентами кода.
Если данные подтвердят ожидаемый результат, какие действия будут предприняты?
Бессмысленно что-то измерять, если по результатам измерений не будет предпринято никаких действий. Обратите внимание, что действием может быть «поддержание текущего положения дел», если запланировано некоторое изменение,
которое произойдет независимо от результатов измерений.
Команда удобочитаемости дала простой ответ: если подтвердится, что выгоды от
контроля удобочитаемости окупают затраты, команда сошлется на исследование
и данные в сборнике часто задаваемых вопросов об удобочитаемости и объявит
об этом, чтобы подтвердить ожидания.
Если получится отрицательный результат, будут ли приняты соответствующие
меры?
Часто отрицательный результат не так влияет на принятие решение, как другие
более важные факторы. В такой ситуации, возможно, стоит отложить измерения. Этот вопрос останавливает большинство проектов, к которым приступает
наша исследовательская группа: люди, принимающие решения, заинтересованы
в знании результатов измерений, но по каким-то причинам не хотят менять курс.
В случае с удобочитаемостью, однако, командой было твердо обещано, что если
по результатам анализа затраты перевесят выгоду или выгоды окажутся незначительными, тогда команда остановит контроль удобочитаемости. Поскольку разные
языки программирования имеют разные уровни зрелости инструментов форматирования и статического анализа, каждый язык будет оцениваться отдельно.

Расстановка приоритетов: что измерять?   135

Кто будет принимать решение по полученному результату и в какой срок?
Сотрудник, запрашивающий проведение измерений, должен быть уполномочен
принимать решения (или действовать от имени ответственного лица). Цель измерения — помочь принять бизнес-решение, и важно знать, кто сделал запрос
и данные в какой форме его убедят. Конечно, хорошее исследование должно
включать разные подходы (от структурированных опросов до статистического
анализа журналов), но время предоставления данных может быть ограничено.
Поэтому измерение полезно ориентировать на лица, принимающие решения.
Склонны ли они сопереживать историям из опросов?1 Доверяют ли они результатам опроса или данным из журналов? Могут ли они разобраться в особенностях
статистического анализа? Если лицо, принимающее решения, не верит в форму
результата в принципе, то нет смысла проводить измерение.
В случае с удобочитаемостью нам были четко названы те, кто будет принимать
решения. Две команды, Java и C++, напрямую сделали нам запрос на измерения,
а другие языковые группы стали наблюдать, что будет2. Лица, принимающие
решения, доверяли опыту своих инженеров в понимании удовлетворенности
и важности обучения, но хотели видеть «беспристрастные числа», полученные из журналов и характеризующие скорость и качество кода. Мы провели
качественный и количественный анализ. Эта работа не была срочной, но ее
завершение было приурочено к внутренней конференции, на которой можно
было бы объявить о предстоящих изменениях. В результате мы получили несколько месяцев.
Задавая эти вопросы, мы часто обнаруживаем, что проводить измерения просто нет
смысла... и это нормально! Есть много веских причин не измерять влияние инструмента или процесса на продуктивность. Вот несколько примеров:
Нет возможности изменить процесс/инструменты прямо сейчас
Этому могут мешать временные или финансовые ограничения. Представьте,
что по результатам измерения переключение на более быстрый инструмент
сборки сэкономит несколько часов в неделю. Но вы не станете его проводить,
поскольку для перехода потребуется приостановить разработку перед важным
1

2

В настоящее время в отрасли с пренебрежением относятся к «анекданным» (anecdata) —
историям из личного опыта, и все стремятся «руководствоваться данными». Однако истории
существуют, потому что имеют большую выразительную силу. Они, в отличие от чисел,
могут дать контекст и глубокое объяснение, вызывающее резонанс. Наши исследователи
не принимают решений, опираясь на истории, но мы используем и поощряем такие методы,
как структурированные опросы и тематические исследования, для глубокого понимания
явлений и описания контекста количественных данных.
Java и C++ имеют наибольшую инструментальную поддержку. Для обоих языков имеются
зрелые средства форматирования и статического анализа, улавливающие распространенные
ошибки. Также оба финансируются в основном изнутри. Несмотря на то что другие языковые команды, такие как Python, тоже интересовались результатами, очевидно, что удаление
контроля удобочитаемости для Python не даст никаких преимуществ, если мы не сможем
показать такие преимущества для Java или C++.

136  

Глава 7. Оценка продуктивности инженеров

этапом финансирования. Инженерные компромиссы не оцениваются в вакууме — более широкий контекст может полностью оправдывать задержку реакции
на результат.
Любые результаты вскоре станут недействительными из-за других факторов
В качестве примера можно привести измерение характеристик процесса разработки ПО в организации непосредственно перед запланированной реорганизацией
или измерение суммы технического долга по устаревшей системе.
Лицо, принимающее решение в этих областях, имеет твердые убеждения, и вы
вряд ли сможете представить достаточное количество доказательств нужного
вида, чтобы изменить их.
Во многом это вопрос знания аудитории. Даже в Google мы встречаем людей
с непоколебимыми убеждениями, основанными на опыте. Нам встречались и те,
кто вообще не доверяет данным опросов или поддается влиянию убедительных
повествований, основанных на небольшом количестве интервью, и, конечно же,
те, кто доверяет только результатам анализа журналов. Во всех случаях мы стараемся представить взгляд на истину с разных точек зрения, используя смешанные
методы, но если заинтересованная сторона настаивает на использовании метода
измерений, который не подходит для данной проблемы, мы откажемся в этом
участвовать.
Результаты будут использоваться, только чтобы потешить свое честолюбие
Это, пожалуй, самая распространенная причина, по которой мы отвечаем
отказом. Люди принимают решения по несколькими причинам, и совершенствование процесса разработки ПО — только одна из них. Например, команда
инструментов выпуска новых версий в Google однажды попросила оценить запланированное изменение в рабочем процессе выпуска версий. Было очевидно,
что изменение как минимум не ухудшит текущего состояния, но авторы запроса
хотели знать, будет ли это улучшение значительным или нет. Мы спросили
команду: если улучшение окажется небольшим, потратят ли они ресурсы на
запланированное изменение, даже если затраты не окупят себя? Ответ был
«да»! Как оказалось, эти изменения не только повышали продуктивность, но
также имели побочный эффект: снижали нагрузку на команду разработчиков
инструментов выпуска.
Единственные доступные метрики не позволяют достаточно точно оценить проблему и могут меняться под влиянием других факторов
В некоторых случаях необходимые метрики (см. следующий раздел) просто
недоступны, и может возникнуть соблазн провести анализ с использованием
других, менее точных метрик (например, подсчитать число строк кода). Однако
любые результаты, полученные с помощью таких метрик, не будут поддаваться
интерпретации. Если метрика подтверждает ранее существовавшее убеждение
заинтересованных сторон, они могут приступить к реализации своего плана без
учета того, что метрика не является точной мерой. Если метрика не подтверждает

Выбор значимых метрик с использованием целей и сигналов   137

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

Выбор значимых метрик с использованием целей
и сигналов
Приняв решение об измерении характеристик процесса, мы определяем, какие метрики для него использовать. Очевидно, что число строк кода — плохая метрика1,
но чем тогда измерить продуктивность инженеров?
Для создания метрик мы в Google используем модель Цели/Сигналы/Метрики
(GSM, Goals/Signals/Metrics).
y Цель — это желаемый конечный результат. Она на высоком уровне определяет, что
вы хотите понять, и не должна содержать ссылок на конкретные способы измерения.
y Сигнал — признак достижения цели. Сигналы — это то, что мы хотим измерить,
но они могут оказаться неизмеримыми.
y Метрика — это отражение сигнала, которое можно измерить. Возможно, метрика не
идеально совпадает с сигналом, но мы считаем, что она достаточно близка к нему.
Модель GSM полезна с точки зрения определения метрик. Во-первых, задавая сначала цели, затем сигналы и, наконец, метрики, мы предотвращаем эффект уличного
фонаря. Этот термин происходит от фразы «искать ключи под уличным фонарем»:
освещенные места не всегда совпадают с местом, куда упали ключи. То же верно
в отношении метрик: легкодоступные и легкоизмеримые метрики не всегда соответствуют нашим потребностям.
1

«Следующий шаг — измерение продуктивности программиста количеством строк кода
в месяц. И этот метод оценки дорого обходится, потому что поощряет писать раздутый
неэффективный код. Но сегодня меня мало интересует, насколько глупой выглядит эта
единица измерения труда даже с чисто коммерческой точки зрения. Я хочу подчеркнуть,
что если мы считаем количество строк кода, то должны рассматривать их не как доход, а как
затраты. Общепринятая практика дошла до такого маразма, что указывает нам записывать
число не в ту колонку». Эдсгер Дейкстра (Edsger Dijkstra). «On the cruelty of really teaching
computing science», EWD Manuscript 1036 (https://oreil.ly/ABAX1).

138  

Глава 7. Оценка продуктивности инженеров

Во-вторых, модель GSM помогает предотвратить искажение и смещение метрик,
вынуждая нас выбирать метрики до фактического измерения результата (использовать принципиальный подход). Рассмотрим случай, когда метрики были выбраны
без использования принципиального подхода и результаты не совпали с ожиданиями заинтересованных сторон. В такой ситуации заинтересованные стороны могут
предложить для измерения другие метрики, и мы не сможем утверждать, что новые
метрики не подойдут! Модель GSM заставляет нас выбирать метрики, способные
измерять цели. Именно такие метрики заинтересованные стороны считают самыми
подходящими.
Наконец, модель GSM может показать нам области охвата измерений. Запуская
процесс GSM, мы перечисляем все цели и для каждой определяем сигналы. Как мы
увидим в примерах, не все сигналы измеримы, и это нормально! С помощью GSM
мы определяем, что именно не поддается измерению, и принимаем решение, как
действовать дальше.
При выборе метрик важна поддержка контроля — возможность проследить каждую
метрику обратно до сигнала, который она отражает, и цели, которую она пытается
измерить. Это дает нам уверенность, что мы знаем, какие метрики измеряем и зачем.

Цели
Цель должна быть обозначена в терминах, не относящихся к метрикам. Сами по себе
цели не поддаются измерению, но хороший набор целей — это то, с чем все могут
согласиться, прежде чем переходить к сигналам, а затем к метрикам.
Определение правильного набора целей может показаться простой задачей: команда
наверняка знает цели своей работы! Однако наша исследовательская группа обнаружила, что люди часто забывают включить в этот набор все возможные компромиссы
продуктивности, которые могут привести к ошибочным оценкам.
Представьте, что команда была настолько сосредоточена на том, чтобы сделать проверку удобочитаемости быстрой, что забыла о качестве кода. Команда включила
в измерения оценки, учитывающие время, необходимое для прохождения процесса
рецензирования, и степень удовлетворенности инженеров этим процессом. Один из
членов команды даже предложил:
«Рецензирование кода можно сделать очень быстрым: надо полностью удалить
этот этап».
Конечно, это пример крайности, однако команды постоянно игнорируют компромиссы при измерении: они настолько сосредоточены на увеличении скорости, что
забывают измерить качество (или наоборот). Для борьбы с этой забывчивостью
наша исследовательская группа делит продуктивность на пять основных аспектов,
которые находятся в противоречии друг с другом. Мы призываем команды сверять
с ними свои цели, чтобы ничего не упустить. Запомнить все пять аспектов помогает
аббревиатура QUANTS:

Цели   139

Quality of the code (качество кода)
Как определяется качество кода? Достаточно ли хорошо тесты справляются
с предотвращением регрессий? Насколько хорошо архитектура способствует
снижению рисков и изменений?
Attention from engineers (внимание инженеров)
Как часто инженеры полностью включаются в работу? Как часто им приходится
отвлекаться на уведомления? Помогает ли инструмент легко переключать внимание инженера?
Intellectual complexity (интеллектуальная сложность)
Какая когнитивная нагрузка требуется для выполнения задания? Какова внутренняя сложность решаемой задачи? Приходится ли инженерам справляться
с избыточной сложностью?
Tempo and velocity (темп и скорость)
Насколько быстро инженеры справляются со своими задачами? Как быстро они
могут выпускать новые версии? Сколько задач они решают за определенный
период?
Satisfaction (удовлетворенность)
Насколько инженеры удовлетворены своими инструментами? Насколько
хорошо инструмент соответствует потребностям инженеров? Насколько инженеры удовлетворены своей работой и конечным продуктом? Чувствуют ли
они выгорание?
Для оценки процесса поддержки удобочитаемости, наша исследовательская группа
совместно с командой удобочитаемости определила несколько целей продуктивности процесса:
Качество кода
Участвуя в процессе повышения удобочитаемости инженеры пишут более качественный и более согласованный код и вносят свой вклад в культуру едино­
образия кода.
Внимание инженеров
Повышение внимания инженера в процессе контроля удобочитаемости не является целью. Это нормально! Для принятия компромиссного решения необязательно
учитывать все пять аспектов продуктивности.
Интеллектуальная сложность
Участвуя в процессе контроля удобочитаемости, инженеры изучают кодовую
базу и лучшие практики программирования в Google, а также получают советы
наставников.
Темп и скорость
Благодаря повышению удобочитаемости инженеры справляются с задачами
быстрее и эффективнее.

140  

Глава 7. Оценка продуктивности инженеров

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

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

Сигналы

Инженеры пишут более качественный код

Инженеры, получающие отзывы о своем коде, оценивают
свой код как более качественный

Инженеры изучают кодовую базу и лучшие практики
программирования в Google

Инженеры отмечают, что процесс проверки удобочитаемости дает им новые знания

Инженеры получают советы наставников

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

Инженеры справляются с задачами быстрее и эффективнее

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

Инженеры видят пользу от процесса проверки удобочитаемости и положительно оценивают свое участие в нем

Инженеры считают процесс контроля удобочитаемости
полезным

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

Использование данных для проверки метрик   141

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

Использование данных для проверки метрик
Однажды мы создали метрику для оценки средней задержки работы инженера из-за
ожидания завершения сборки. Цель состояла в том, чтобы зафиксировать «типичное»
время ожидания. Мы провели выборочное исследование. Согласно методике исследований, инженеры должны были отвлекаться от выполнения интересующей их задачи,
чтобы ответить на несколько вопросов. Как только инженер запускал сборку, мы
автоматически отправляли ему небольшой список вопросов о том, какие задержки
на сборку он ожидает, опираясь на личный опыт. Однако в нескольких случаях инженеры ответили, что еще не начали сборку! Оказалось, что инструменты запускали
сборку автоматически и инженеры не тратили время на ожидание результатов и это
не «засчитывалось» в «типичную» задержку. Затем мы скорректировали метрику,
чтобы исключить подобные сборки1.
Количественные метрики полезны, потому что позволяют оценить масштаб. Вы
можете измерить опыт инженеров по всей компании за длительный период и быть
уверенными в результатах. Однако они не предоставляют никакой контекстной
или описательной информации. Количественные показатели не объясняют, почему
инженер использовал устаревший инструмент для выполнения своей задачи, выбрал необычный рабочий процесс или отказался от стандартного процесса. Только
качественные исследования могут дать такую информацию и позволяют получить
представление о возможных шагах по улучшению процесса.
Теперь рассмотрим сигналы, представленные в табл. 7.2. Какие метрики можно было
бы использовать для измерения каждого из них? Некоторые из этих сигналов можно
1

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

142  

Глава 7. Оценка продуктивности инженеров

измерить методом анализа журналов. Другие можно измерить только с помощью
опроса. Третьи вообще могут оказаться неизмеримыми — например, как измерить
фактическое качество кода?
В итоге, исследуя влияние процесса контроля удобочитаемости на продуктивность,
мы получили комбинацию метрик из трех источников. Первый источник — результаты опроса конкретно о процессе. Вопросы задавались людям, завершившим этот
процесс. Их ответы позволили получить прямую обратную связь о процессе. Как
мы предполагали, это должно было избавить нас от предвзятости в отзывах1, хотя
и вводило некоторую предвзятость, обусловленную временем2 и ограниченностью
выборки3. Второй — результаты крупномасштабного квартального опроса, который
не был специально посвящен удобочитаемости; его целью было получение метрик,
которые должны влиять на процесс контроля удобочитаемости. И третий — детализированные метрики из журналов инструментов разработчика, помогающие
определить, сколько времени требовалось инженерам для выполнения конкретных
задач4. Полный список метрик с соответствующими сигналами и целями представлен в табл. 7.2.
Таблица 7.2. Цели, сигналы и метрики
QUANTS

Цель

Сигнал

Метрика

Качество
кода

Инженеры пишут
более качественный
код

Инженеры, получающие отзывы
о своем коде, оценивают свой код как
более качественный

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

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

Опрос о процессе: доля инженеров,
сообщивших, что проверки удобочитаемости не влияют или отрицательно
влияют на качество кода
Опрос о процессе: доля инженеров,
сообщивших, что участие в процессе
контроля удобочитаемости улучшило
качество кода их команды

1

2

3

4

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

Использование данных для проверки метрик   143

QUANTS

Цель

Сигнал

Метрика

Инженеры пишут
более согласованный код

Инженеры получают постоянную
обратную связь и рекомендации от
рецензентов

Опрос о процессе: доля инженеров,
сообщивших о несоответствии между
комментариями рецензентов и критериями удобочитаемости

Инженеры вносят
свой вклад в культуру единообразия
кода

Инженеры регулярно получают
комментарии, касающиеся проблем
в оформлении и/или удобочитаемости кода

Опрос о процессе: доля инженеров,
сообщивших, что регулярно получают
комментарии, касающиеся проблем
в оформлении и/или удобочитаемости
кода

Внимание
инженеров

Не рассмотрено

Не рассмотрено

Не рассмотрено

Интеллектуальная
сложность

Инженеры изуча­ют
кодовую базу
и лучшие практики
программирования
в Google

Инженеры отмечают, что процесс
контроля удобочитаемости дает им
новые знания

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

Темп /
скорость

Инженеры получают
советы наставников

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

Опрос о процессе: доля инженеров, сообщивших, что работа с рецензентами
является сильной стороной процесса
контроля удобочитаемости

Инженеры работают
более продуктивно

Инженеры чувствуют себя продуктивнее коллег

Ежеквартальный опрос: доля инженеров, сообщивших, что они достигли
высокой продуктивности

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

Опрос о процессе: доля инженеров,
сообщивших, что отсутствие контроля
удобочитаемости снижает скорость
работы команды

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

Данные из журналов: среднее
время обзора изменений, внесенных
инженерами, участвовавшими и не
участвовавшими в процессе контроля
удобочитаемости

Изменения, внесенные инженерами,
прошедшими проверку, легче преодолевают процесс рецензирования,
чем изменения, написанные другими
инженерами

Данные из журналов: среднее время
рецензирования изменений, внесенных инженерами, участвовавшими
и не участвовавшими в процессе
контроля удобочитаемости

144  
QUANTS

Глава 7. Оценка продуктивности инженеров

Цель

Сигнал

Метрика

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

Данные из журналов: среднее время
утверждения изменений, внесенных
инженерами, участвовавшими и не
участвовавшими в процессе контроля
удобочитаемости

Проверка удобочитаемости не
оказывает отрицательного влияния
на скорость работы

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

Удовлетворенность

Инженеры видят
пользу от процесса
контроля удобочитаемости и положительно оценивают
свое участие в нем

Инженеры считают проверку удобочитаемости в целом полезным опытом

Опрос о процессе: доля инженеров, сообщивших, что они получили в целом
положительный опыт от участия в процессе контроля удобочитаемости

Инженеры оценивают процесс конт­
роля удобочитаемости как стоящий

Опрос о процессе: доля инженеров,
сообщивших о целесообразности процесса контроля удобочитаемости
Опрос о процессе: доля инженеров,
сообщивших, что качество проверки
удобочитаемости является сильной
стороной процесса
Опрос о процессе: доля инженеров,
сообщивших, что тщательность
проверки является сильной стороной
процесса

Инженеры не считают процесс
контроля удобочитаемости раз­
очаровывающим

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

Итоги   145

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

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

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

146  

Глава 7. Оценка продуктивности инженеров

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

ЧАСТЬ III

Процессы

ГЛАВА 8

Правила и руководства по стилю
Автор: Шайндел Шварц
Редактор: Том Маншрек
В большинстве организаций, занимающихся программной инженерией, есть правила,
применяющиеся к кодовой базе. Они определяют, как в компании принято хранить
файлы с исходным кодом, форматировать код, присваивать имена, использовать
паттерны, исключения и потоки выполнения. Большинство инженеров-программистов действуют в рамках набора политик, управляющих их работой. В Google
для управления базой кода мы поддерживаем набор руководств по стилю, которые
определяют наши правила.
Правила — это не предложения или рекомендации, а обязательные для выполнения
законы. При необходимости их можно игнорировать только в особых утвержденных
случаях. Руководства, в отличие от правил, содержат рекомендации и описание передовых практик, следование которым желательно, но не обязательно.
Мы собираем правила и в наших канонических руководствах по стилю программирования определяем допустимое и недопустимое поведение. Термин «стиль» в данном
случае можно понять не совсем правильно — как набор вариантов форматирования.
В действительности наши руководства по стилю — это нечто большее: они включают полный набор соглашений, управляющих нашим кодом. Это не значит, что эти
руководства носят строго обязательный характер. Правила в них могут предлагать,
например, использовать имена «настолько описательные, насколько это возможно,
в пределах разумного» (https://oreil.ly/xDNAn). Скорее они служат основным источником правил, которым следуют наши инженеры.
Мы поддерживаем отдельные руководства по стилю для каждого языка программирования1. Все они преследуют одну цель — обеспечить устойчивость кода, но между
ними есть множество различий по охвату, длине и содержанию. Языки программирования имеют разные сильные стороны, особенности, приоритеты и причины использования в Google. Поэтому руководства для разных языков отличаются. Например,
руководства для Dart, R и Shell лаконичны и сфокусированы на нескольких общих
принципах, таких как именование и форматирование. Руководства для C++, Python
1

Многие из наших руководств по стилю имеют внешние версии, которые вы можете найти
по адресу https://google.github.io/styleguide. В этой главе мы приведем примеры из этих
руководств.

Создание правил   149

и Java включают гораздо больше деталей, углубляются в особенности языка и представлены более подробными документами. В одних руководствах больше внимания
уделяется типичному использованию языка вне Google — например, руководство для
Go очень короткое и добавляет лишь несколько правил к правилам и методам, изложенным во внешних общепризнанных соглашениях (https://oreil.ly/RHrvP). В других
содержатся правила, принципиально отличающиеся от внешних норм, — например,
наши правила для C++ запрещают применять исключения — возможность языка,
широко используемую за пределами Google.
Большая разница даже между нашими руководствами не позволяет точно описать,
что должно включать руководство по стилю. В разных организациях могут быть разные требования к устойчивости, для поддержки которой создаются правила. В этой
главе мы обсудим принципы и процессы, определившие подходы к разработке правил
и руководств в Google, и рассмотрим примеры, в основном из наших руководств по
стилю для C++, Python и Java.

Зачем нужны правила?
Итак, зачем нужны правила? Цель правил — поощрить «хорошее» поведение и препятствовать «плохому». Интерпретация понятий «хорошо» и «плохо» во многом
зависит от организации и ее целей и потребностей. В одних организациях «хорошими» могут считаться модели, предполагающие использование минимального
объема памяти или ориентированные на потенциальные оптимизации во время
выполнения. В других «хорошим» поведением считается применение новейших
возможностей языка. Третьи организации усиленно заботятся о согласованности
и считают отклонения от паттернов «плохим» подходом. Сначала мы должны понять,
что ценится в организации, а затем использовать правила и рекомендации, чтобы
поощрять желательное поведение и препятствовать нежелательному.
По мере роста организации установленные правила и руководства формируют общий словарь разработки, который помогает инженерам сосредоточиться на том, что
должен делать их код, а не на том, как заставить его это делать. Поддерживая словарь,
инженеры действуют «хорошо», даже не замечая этого. То есть правила помогают
компании развиваться в выбранных направлениях.

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

150  

Глава 8. Правила и руководства по стилю

Руководящие принципы
Рассмотрим конкретную ситуацию: в Google работает более 30 000 инженеров с разными навыками и опытом. Ежедневно в репозиторий с базой кода, насчитывающей
более двух миллиардов строк, отправляется около 60 000 изменений, которые, вероятно, будут продолжать оставаться в репозитории десятилетиями. Наши продукты
уникальны, но мы сталкиваемся с типичной организационной проблемой — как сохранить устойчивость инженерной среды при росте компании с течением времени.
В этом контексте цель наших правил — помочь нам справиться со сложной средой
разработки, обеспечить управляемость кодовой базы и поддержать продуктивность
инженеров. Здесь мы идем на компромисс: большой свод правил, помогающий достичь цели, ограничивает свободу выбора. Мы теряем некоторую гибкость и даже
можем обидеть кого-то, но мы выбираем выигрыш в согласованности и уменьшении
числа конфликтов, обеспечиваемый официальным стандартом.
Мы выработали ряд основополагающих принципов, которыми руководствуемся
при разработке правил:
y необременительность;
y оптимизация для читателя кода;
y поддержка единообразия кода;
y предотвращение использования необычных или способствующих ошибкам
конструкций;
y при необходимости — оценка практической целесообразности применения
правила.
Необременительность
Руководство по стилю не должно включать слишком много правил. Чтобы все инженеры в организации изучили и начали выполнять новое правило, требуется время.
Если правил окажется слишком много1, инженерам будет трудно их запомнить,
а новичкам — изучить. Кроме того, чем больше свод правил, тем сложнее и дороже
его поддерживать.
Мы сознательно решили не фиксировать очевидные правила. Руководство по стилю в Google не носит юридический характер: отсутствие в нем явного запрета на
действие не означает законность этого действия. Например, руководство для C++
не содержит правил, запрещающих использование goto. Программисты на C++ уже
1

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

Создание правил   151

склонны избегать этого оператора, поэтому добавление правила, запрещающего
его, приведет к ненужным накладным расходам. Один или два инженера могут по
ошибке использовать goto, но это не повод увеличивать нагрузку для всех созданием
нового правила.
Оптимизация для читателя кода
Еще один принцип, которому следуют наши правила, — оптимизация кода для
читателя, а не для автора. С течением времени код будет читаться другими людьми
гораздо чаще, чем автором. Мы предпочитаем, чтобы код был более утомительным
для ввода и менее трудным для чтения. В нашем руководстве по стилю для Python
мы отмечаем, что условные выражения короче операторов if и удобны для ввода,
но читателю кода бывает трудно разобраться в них, поэтому мы ограничиваем их
использование (https://oreil.ly/ftyvG). Это компромисс: мы понимаем, что инженерам
сложнее снова и снова вводить длинные описательные имена переменных и типов,
но готовы заплатить эту цену за удобство всех будущих читателей.
В соответствии с этими приоритетами мы также требуем, чтобы инженеры оставляли явное доказательство предполагаемого поведения кода. Читатель должен
четко понимать, что делает код. Например, наши руководства для Java, JavaScript
и C++ требуют использовать специальную аннотацию или ключевое слово всякий
раз, когда метод переопределяет соответствующий метод суперкласса. Без явного
подтверждения читатели, вероятно, могут понять намерение автора, но это займет
у них больше времени и усилий.
Предупреждение о неожиданном поведении еще более важно. В C++ бывает сложно
понять, что владеет указателем, просто прочитав фрагмент кода. Если указатель
передается в функцию, поведение которой неизвестно, мы не можем уверенно предсказать ожидаемый результат. Вызывающий код по-прежнему владеет указателем?
Ответственность за указатель взяла на себя функция? Можно ли продолжать использовать указатель после возврата из функции или он стал недействительным?
Чтобы ответить на эти вопросы, наше руководство для C++ требует использовать
std::unique_ptr (https://oreil.ly/h0lFE), когда предполагается передача права владения указателем, или конструкцию unique_ptr, когда в каждый конкретный момент
существует только одна копия указателя. Когда функция принимает аргумент типа
unique_ptr и намеревается стать владельцем указателя, вызывающий код должен
явно использовать семантику перемещения:
// Функция, которая принимает Foo*.
// По заголовку этой функции невозможно сказать, вступает ли она во владение
// указателем
void TakeFoo(Foo* arg);
// Вызов функции не позволяет читателю понять, как изменится право владения
// указателем после возврата из нее
Foo* my_foo(NewFoo());
TakeFoo(my_foo);

152  

Глава 8. Правила и руководства по стилю

Сравните этот фрагмент со следующим:
// Функция принимает std::unique_ptr.
void TakeFoo(std::unique_ptr arg);
// Любой вызов этой функции явно показывает, что ей передается право
// владения указателем и unique_ptr нельзя использовать после возврата из нее
std::unique_ptr my_foo(FooFactory());
TakeFoo(std::move(my_foo));

Данное правило в руководстве по стилю гарантируют, что все инструкции вызова
будут содержать четкие доказательства передачи права собственности, когда это применимо, и читателям кода будет не нужно понимать поведение каждого вызова. Мы
предоставляем в API достаточно информации, чтобы дать возможность рассуждать
о его взаимодействиях. Такое четкое документирование поведения в точках вызова
гарантирует, что фрагменты кода остаются читаемыми и понятными. Мы стремимся
локализовать рассуждения, касающиеся событий в точке вызова, и избавить читателей от необходимости искать и читать другой код, включая реализацию функции.
Также мы добавили в руководство по стилю множество правил комментирования.
Документирующие комментарии (блочные комментарии в начале файла, а также
перед определениями классов и функций) должны описывать структуру или назначение следующего за ними кода. Комментарии внутри реализации (разбросанные
по всему коду) должны описывать или выделять неочевидные варианты, объяснять
сложные фрагменты и подчеркивать важные части кода. У нас есть правила, охватывающие оба типа комментариев, которые требуют от инженеров давать пояснения
для читателей кода.
Поддержка единообразия кода
Наше понимание единообразия в кодовой базе похоже на философию, которую
мы применяем в офисах. Команды с большим числом инженеров часто занимают
несколько офисов, каждый из которых имеет свою уникальную индивидуальность
с учетом местного колорита, но во всех них неизменно присутствует все, что нужно
для работы. Пропуск гуглера распознается всеми считывателями, любые устройства в Google подключаются к WiFi, аппаратура для видеоконференций в любом
конференц-зале имеет одинаковый интерфейс. Гуглеру не нужно тратить время на
изучение особенностей использования устройств, и перемещаясь между офисами,
он может быстро приступать к работе.
Такого же единообразия мы стремимся добиться в исходном коде — любой инженер
должен быстро вникать в незнакомый код компании. Локальный проект может иметь
свою индивидуальность, но его инструменты, методы и библиотеки должны быть
узнаваемы и понятны.
Преимущества единообразия
Несмотря на то что запрет на настройку устройств чтения пропусков или интерфейса
аппаратуры для видеоконференций ограничивает творческую свободу, с его помощью

Создание правил   153

мы получаем преимущества единообразия. То же верно и для кода: правила, требующие обеспечивать единообразие, позволяют большему числу инженеров выполнять
больше работы с меньшими усилиями1:
y Когда база кода единообразна по стилю, инженеры, пишущие и читающие код,
могут сосредоточиться на смысле кода, а не на его оформлении. Также единообразие позволяет формировать фрагменты для экспертной оценки2. Когда мы решаем
задачи, используя одинаковые интерфейсы, и единообразно форматируем код,
эксперты быстро понимают, что этот код делает. Единообразие также упрощает
деление кода на модули и помогает избежать дублирования. По этим причинам
мы уделяем большое внимание единообразию в именовании, использовании
паттернов, форматировании и структуре. В руководстве по стилю есть множество
правил, добавленных исключительно для гарантии единообразия, например определяющих количество пробелов в отступах или ограничивающих длину строки3.
Главной ценностью таких правил является их наличие, а не содержание.
y Единообразие облегчает масштабирование. Инструменты — это ключ к масштабированию организации, а единообразный код облегчает создание инструментов,
способных понимать, редактировать и генерировать код. Представьте инструмент,
который обновляет исходные файлы, добавляя отсутствующие инструкции
импорта или удаляя инструкции включения неиспользуемых заголовков. Если
в разных проектах к спискам импорта применены разные политики сортировки,
для некоторых проектов такой инструмент может оказаться бессильным. Когда
все команды используют одни и те же правила, открывается возможность инвестировать в создание инструментов, работающих повсюду, и в автоматизацию
многих задач по обслуживанию.
y Единообразие также помогает масштабированию человеческого ресурса в компании. По мере роста организации увеличивается число инженеров. Поддержание
единообразия в коде облегчает их переход между проектами, сокращает время
на их включение в работу и дает организации возможность гибко приспосабливаться по мере изменения потребностей в численности персонала. В растущей
организации также будут появляться люди, взаимодействующие с кодом не как
разработчики, например инженеры по надежности, инженеры по библиотекам
и «уборщики» кода. Благодаря единообразию эти люди могут работать сразу над
несколькими ранее не знакомыми проектами.

1

2

3

Спасибо Х. Райту за фактическое сравнение, сделанное при посещении примерно 15 разных
офисов Google.
«Формирование фрагментов» — это когнитивный процесс группировки элементов информации в значимые «фрагменты», а не их индивидуальный учет. Напоминает рассмотрение
общей картины на шахматной доске вместо оценки позиций отдельных фигур.
См. разделы: «4.2. Block indentation: +2 spaces» (https://oreil.ly/jaf6n), «Spaces vs. Tabs» (https://
oreil.ly/1AMEq), «4.4. Column limit:100» (https://oreil.ly/WhufW) и «Line Length» (https://oreil.
ly/sLctK).

154  
y

Глава 8. Правила и руководства по стилю

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

В МАСШТАБЕ
Несколько лет назад наше руководство по стилю для C++ строго запрещало нарушения
совместимости со старым кодом: «В какой-то момент могут появиться весьма веские аргументы для изменения правил стиля, но мы постараемся сохранить все как есть, чтобы
обеспечить единообразие».
Пока база кода была небольшой и в ней почти не было старых пыльных углов, в этом запрете был смысл.
Но по мере разрастания и старения кодовой базы сохранение совместимости перестало быть
приоритетной задачей. Такое изменение было (по крайней мере, для арбитров руководства
по стилю для C++) осознанным: мы явно заявили, что база кода на C++ никогда больше
не будет полностью единообразной.
Было бы слишком обременительно обновлять правила по мере развития современных
практик и требовать применения этих правил ко всему, что когда-либо было написано.
Наши инструменты и процессы крупномасштабного изменения позволяют нам обновлять
почти весь код и приводить его в соответствие почти к каждому новому паттерну или синтаксису, поэтому большая часть старого кода соответствует самому последнему одобренному стилю (глава 22). Однако такой подход не идеален: когда база кода становится такой
большой, как наша, невозможно гарантировать, что каждый фрагмент старого кода будет
соответствовать современным практикам. Требование идеального единообразия достигло
той точки, когда оно стало обходиться слишком дорого.

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

Примером может служить использование констант (https://oreil.ly/p6RLR).

Создание правил   155

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

КОЛИЧЕСТВО ПРОБЕЛОВ
Руководство по стилю для Python в Google изначально обязывало использовать в коде на
Python отступы с двумя пробелами. Стандартное руководство по стилю для Python, используемое внешним сообществом, предлагает оформлять отступы четырьмя пробелами.
Большая часть кода на Python, написанного нами раньше, была направлена на непосредственную поддержку наших проектов на C++, а не на создание действующих приложений
на Python. Поэтому мы решили использовать отступы с двумя пробелами, в соответствии
с правилами оформления кода на C++. Шло время, и мы увидели, что это решение не
оправдало ожиданий. Инженеры, использующие Python, гораздо чаще читают и пишут код
на Python, а не на C++, и им нужно прикладывать дополнительные усилия, чтобы что-то
найти или задействовать фрагменты внешнего кода. Мы также сталкивались с большими
трудностями каждый раз, когда пытались экспортировать части нашего кода в открытый
исходный код, тратя время на согласование различий между нашим внутренним кодом
и внешними проектами, к которым мы хотели присоединиться.
Когда пришло время создать для Starlark (https://oreil.ly/o7aY9) — языка на основе Python,
разработанного в Google для описания процессов сборки — руководство по стилю, мы прописали использование отступов с четырьмя пробелами, чтобы обеспечить единообразие
с внешними правилами1.

Предотвращение использования необычных или способствующих
ошибкам конструкций
Наши руководства по стилю ограничивают использование некоторых самых необычных или сложных конструкций, содержащих малозаметные ловушки. Применение этих конструкций без глубокого понимания всей их сложности легко может
приводить к ошибкам. Даже если конструкции понятны действующим инженерам,
будущие участники проекта и специалисты, занимающиеся сопровождением кода,
могут не иметь такого же понимания.
Так, правило в руководстве по стилю для Python запрещает использование функций
рефлексии (https://oreil.ly/ooqIr), поскольку такие функции, как hasattr() и getattr(),
дают пользователю возможность обращаться к атрибутам объектов, используя
строковые имена:
if hasattr(my_object, 'foo'):
some_var = getattr(my_object, 'foo')

1

Стиль форматирования для файлов BUILD, реализованных на Starlark, используется инструментом сборки buildifier (https://oreil.ly/iGMoM).

156  

Глава 8. Правила и руководства по стилю

Казалось бы, в этом примере все в порядке. Но взгляните на следующий фрагмент:
some_file.py:
A_CONSTANT = [
'foo',
'bar',
'baz',
]
other_file.py:
values = []
for field in some_file.A_CONSTANT:
values.append(getattr(my_object, field))

При беглом просмотре не сразу видно, что здесь происходит обращение к полям
foo, bar и baz. В коде нет четких этому подтверждений. Вам придется приложить
определенные усилия, чтобы выяснить, какие строки используются для доступа
к атрибутам вашего объекта. А что, если вместо A_CONSTANT код будет читать поля из
ответа, полученного от механизма RPC, или из хранилища данных? Такой запутанный
код может проделать незаметную брешь в системе безопасности из-за неправильной
проверки сообщения. Кроме того, такой код сложно тестировать и проверять.
Динамическая природа Python допускает такое поведение и разрешает использовать
hasattr() и getattr()в очень ограниченных случаях.
Такие возможности языка помогают решать задачи эксперту, знакомому с ними, но
часто они слишком сложны для понимания и довольно редко используются инженерами. Нам нужно, чтобы с базой кода работали не только эксперты, но и начинающие программисты. Наши инженеры по надежности находят подозрительные места
в коде, даже написанном на языке, которым они владеют недостаточно свободно. Мы
придаем большое значение интерпретации кода.
Практическая целесообразность уступок
По словам Ральфа Уолдо Эмерсона, «глупая последовательность — суеверие недалеких умов» (https://oreil.ly/bRFg2). В нашем стремлении к единообразию и простоте
кодовой базы мы не стараемся слепо игнорировать все остальное. Мы знаем, что некоторые правила в наших руководствах по стилю будут сталкиваться с ситуациями,
требующими исключений, и это нормально. При необходимости мы отклоняемся от
правил в угоду эффективности и практической целесообразности.
Производительность имеет значение. Иногда есть смысл принять меры по оптимизации производительности даже в ущерб единообразию и удобочитаемости. Например,
наше руководство для C++ запрещает использование исключений, но разрешает
применение noexcept (https://oreil.ly/EAgN-) — спецификатора языка, связанного с исключениями, который может включать оптимизацию компилятора.
Совместимость тоже имеет значение. Код, предназначенный для взаимодействия
с чем-то, разработанным за пределами Google, нужно адаптировать для этой цели.

Создание правил   157

Например, наше руководство для C++ содержит исключение из общего правила по
оформлению имен с использованием ВерюблюжьегоРегистра, которое разрешает
использование змеиного_регистра, как в стандартной библиотеке, для именования
сущностей, имитирующих особенности стандартной библиотеки1. Руководство для
C++ также допускает несоблюдение некоторых правил при программировании для
Windows (https://oreil.ly/xCrwV), где совместимость с платформой требует использования множественного наследования, которое явно запрещено для всего остального
кода на C++ в Google. В наших руководствах по стилю для Java и JavaScript прямо
указано, что сгенерированный код, который часто взаимодействует с компонентами,
не принадлежащими проекту, или зависит от них, не обязан подчиняться правилам
руководств2. Единообразие является жизненно важным, а адаптация имеет ключевое
значение.

Руководство по стилю
Итак, какие правила входят в руководство по стилю языка? Все они делятся примерно на три категории:
y правила, предотвращающие опасности;
y правила, отражающие передовые практики;
y правила, обеспечивающие единообразие.
Предотвращение опасностей
Прежде всего наши руководства по стилю включают правила об особенностях языка,
которые должны или не должны использоваться по техническим причинам. У нас
есть правила использования статических членов, переменных, лямбда-выражений,
исключений, потоков выполнения, прав доступа и наследования классов. В своих
правилах мы определяем, какие особенности языка (например, стандартные типы)
можно использовать, а какие следует применять с осторожностью, чтобы избежать
появления малозаметных ошибок. В описании каждого правила мы стремимся объяснить плюсы и минусы принятого нами решения. Большинство из этих решений
основаны на необходимости обеспечить надежность кода с течением времени, а также
поощрить поддерживаемые приемы использования языка.
Отражение передовых практик
Наши руководства по стилю также включают правила применения некоторых передовых практик программирования. Эти правила помогают поддерживать работоспособ1

2

См. раздел «Exceptions to Naming Rules» (https://oreil.ly/AiTjH). Например, наши библиотеки
Abseil с открытым исходным кодом используют змеиный_регистр для именования типов,
предназначенных для использования вместо стандартных типов. См. определения типов
в https://github.com/abseil/abseil-cpp/blob/master/absl/utility/utility.h. Это C++11-реализации
типов из стандарта C++14, для именования которых использован змеиный_регистр вместо
более предпочтительного в Google ВерблюжьегоРегистра.
См. раздел «Generated code: mostly exempt» (https://oreil.ly/rGmA2).

158  

Глава 8. Правила и руководства по стилю

ность кодовой базы и простоту ее сопровождения. Например, мы указываем, где и как
авторы должны включать комментарии1. Наши правила, касающиеся комментариев,
охватывают общие соглашения о комментировании и определяют конкретные случаи
обязательного включения комментариев в код — случаи, когда намерение автора
не очевидно, такие как провалы через операторы case в инструкции switch, пустые
блоки перехвата исключений и метапрограммирование шаблонов. У нас также есть
правила, определяющие структуру исходных файлов и описывающие организацию
их содержимого. У нас есть правила именования пакетов, классов, функций и переменных. Цель всех этих правил — подталкивать инженеров к использованию практик,
помогающих писать более здоровый и устойчивый код.
Некоторые из передовых практик, предписываемых нашими руководствами по
стилю, призваны сделать исходный код более удобочитаемым, например через
правила форматирования. Наши руководства по стилю указывают, когда и как
использовать отступы и пустые строки, определяют длину строк и выравнивание
скобок. Требования к форматированию для некоторых языков мы реализовали
в инструментах автоматического форматирования: gofmt для Go и dartfmt для
Dart. Указывая подробный список требований к форматированию или называя
инструмент, который необходимо использовать, мы преследуем одну и ту же цель:
применить ко всему коду единообразный набор правил форматирования для улучшения его читабельности.

КЕЙС: ВНЕДРЕНИЕ STD::UNIQUE_PTR
Когда в C++11 появился std::unique_ptr — тип «умного» указателя, выражающий исключительное владение динамически размещаемым объектом и удаляющий объект, когда
указатель unique_ptr выходит из области видимости, — наше руководство по стилю изначально запретило его использовать. Поведение unique_ptr и связанная с ним семантика
перемещения были не знакомы большинству инженеров. Предотвращение попадания
std::unique_ptr в кодовую базу казалось нам более безопасным выбором. Мы обновили
наши инструменты, чтобы находить ссылки на запрещенный тип, и сохранили в существующем руководстве рекомендацию использовать другие типы «умных» указателей.
Время шло. Инженеры постепенно осваивали семантику перемещения, и мы все больше
убеждались, что использование std::unique_ptr прямо соответствует целям нашего руководства по стилю. Информация о владении объектом, которую сообщает std::unique_ptr
в точке вызова функции, значительно упрощает чтение кода. Дополнительная сложность,
связанная с этим новым типом и сопровождающей его семантикой перемещения, все еще
вызывала серьезную обеспокоенность, но возможность значительно улучшить общее
состояние кодовой базы в долгосрочной перспективе решила компромисс в пользу применения std::unique_ptr.

1

Основные правила комментирования для нескольких языков см. в https://google.github.io/
styleguide/cppguide.html#Comments, http://google.github.io/styleguide/pyguide#38-commentsand-docstrings и https://google.github.io/styleguide/javaguide.html#s7-javadoc.

Изменение правил   159

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

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

Такие дискуссии лишь отвлекают внимание (http://aquamarine.bikeshed.com) и иллюстрируют
закон тривиальности Паркинсона (https://oreil.ly/L-K8F).

160  

Глава 8. Правила и руководства по стилю

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

КЕЙС: ОФОРМЛЕНИЕ ИМЕН С ИСПОЛЬЗОВАНИЕМ ВЕРБЛЮЖЬЕГО РЕГИСТРА
Когда мы в Google выпустили начальный вариант руководства по стилю для Python, мы
решили использовать для имен методов ВерблюжийРегистр вместо змеиного_регистра.
В руководстве по стилю для Python (PEP 8, https://oreil.ly/Z9AA7) и в большей части сообщества Python использовался змеиный_регист, однако в ту пору в Google язык Python
использовался в основном разработчиками на C++ для создания сценариев, действующих
поверх кодовой базы на C++. Многие из определяемых ими типов на Python были обертками для соответствующих типов на C++, а поскольку соглашения об именовании для
C++, принятые в Google, отдают предпочтение ВерблюжьемуРегистру, считалось важным
сохранить единообразие между языками.
Позднее мы подошли к созданию и поддержке независимых приложений на Python силами
инженеров, работающих на Python, а не инженеров C++, пишущих короткие сценарии. Наше
руководство по стилю создавало некоторые неудобства и проблемы с удобочитаемостью
для инженеров Python, требуя придерживаться единого стандарта для нашего внутреннего
кода, из-за чего инженеры были вынуждены постоянно корректировать код под другой
стандарт, когда им приходилось использовать внешний код. Руководство также затрудняло обучение новых сотрудников, уже имеющих опыт программирования на Python, и их
адаптацию к нашим нормам оформления кодовой базы.
С развитием наших проектов на Python наш код все чаще взаимодействовал с внешними
проектами на Python. В некоторых проектах мы использовали сторонние библиотеки,
что привело к смешению в кодовой базе нашего ВерблюжьегоРегистра с внешним змеиным_регистром. Когда мы начали открывать исходный код наших проектов на Python,
необходимость их поддержки во внешнем мире, где наши соглашения считались нонконформистскими, добавило сложностей для нас и вызвало настороженность сообщества,
которому наш стиль показался непривычным и странным.
Учитывая эти аргументы и после обсуждения отрицательных (потеря единообразия
с другим кодом в Google, переобучение гуглеров, использующих наш стиль на Python)
и положительных (достижение единообразия с внешним кодом на Python, позволяющим
беспрепятственно использовать сторонние библиотеки) сторон, арбитры руководства
по стилю для Python решили изменить правило. В результате руководство по стилю для
Python в Google было обновлено и разрешило использовать змеиный_регистр в именах, но
с оговорками: этот стиль должен единообразно применяться во всем файле, разрешение не
распространяется на существующий код и команды сами могут решать, какой стиль лучше
для конкретного проекта.

Изменение правил   161

Процесс обновления правил
Понимая, что правила должны периодически изменяться, а также учитывая наше
стремление к увеличению срока службы кода и масштабированию, мы определили процесс обновления наших правил. Процесс изменения руководства по стилю
основан на решениях. Мы оформляем предложения по обновлению руководства,
идентифицируя существующую проблему и представляя предлагаемое изменение
как способ ее устранения. «Проблемы» в этом процессе не являются гипотетическими примерами того, что может пойти не так, — они подтверждены паттернами,
найденными в существующем коде Google. Рассматривая продемонстрированную
проблему и имея подробное обоснование существующего решения по стилю, мы
можем пересмотреть его, исследовав оправданность другого решения.
Сообщество инженеров, пишущих код в соответствии с руководством по стилю, часто
раньше других замечает необходимость изменить то или иное правило. Но большинство изменений в руководствах Google начинаются с обсуждения в сообществе.
Любой инженер может задать вопрос или предложить изменение в списках рассылки
по конкретным языкам, посвященным обсуждениям руководств.
Предложения по изменению руководства могут быть полностью сформированными
и включать конкретные формулировки или начинаться с вопросов о применимости
существующего правила. Поступающие идеи обсуждаются сообществом и получают
отзывы от других пользователей языка. Некоторые предложения отклоняются сообществом: признаются ненужными, слишком двусмысленными или бесполезными.
Другие получают положительные отзывы, оцениваются как заслуживающие внимания и, возможно, обрастают уточнениями. Предложения, прошедшие обсуждение
в сообществе, принимаются для выработки окончательного решения об изменении
правила.

Арбитры стилей
В Google окончательные решения в отношении руководства по стилю принимаются арбитрами по стилю. Для каждого языка программирования существует группа
опытных экспертов по языку, которые являются владельцами руководства по стилю
и назначаются на эту роль лицами, принимающими решения. Арбитрами по стилю
могут быть ведущие инженеры из команд, занимающихся разработкой библиотек
для данного языка, и другие гуглеры, обладающие соответствующим опытом.
Решение о любом изменении в руководстве по стилю принимается только после
обсуждения технических компромиссов. Арбитры принимают решение в контексте
согласованных целей, для которых оптимизируется руководство по стилю. При
принятии решения учитываются не личные предпочтения, а только компромиссы.
В настоящее время группа арбитров по стилю C++ состоит из четырех членов. Это
может показаться странным: четное число членов комитета может помешать принятию решения, если голоса разделятся поровну. Однако из-за особенностей подхода
к принятию решений, в котором никогда не используется аргумент «потому что я так

162  

Глава 8. Правила и руководства по стилю

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

Исключения
Да, наши правила — закон, и поэтому некоторые правила требуют исключений. Правила обычно рассчитаны на общий случай, а для конкретных ситуаций может быть
полезно определить исключение. Когда возникает нетипичная ситуация, проводятся
консультации с арбитрами стиля, чтобы определить, действительно ли есть веские
основания для изменения определенного правила.
Внести исключение нелегко. Если для C++ предлагается ввести макрос, руководство по стилю требует, чтобы его имя включало префикс с названием проекта. Из-за
того что макросы в C++ обрабатываются как члены глобального пространства имен,
для предотвращения конфликтов все макросы, экспортируемые из заголовочных
файлов, должны иметь глобально уникальные имена. Правило в руководстве по
стилю, касающееся именования макросов, допускает исключения, предоставленные
арбитром, для некоторых служебных макросов, которые действительно являются
глобальными. Но когда причина запроса на исключение сводится к личным предпочтениям и обусловлена чрезмерной длиной имени макроса или желанием добиться
единообразия в рамках одного проекта, такой запрос отклоняется. Целостность
кодовой базы важнее единообразия проекта.
Исключения допускаются в тех случаях, когда выясняется, что полезнее разрешить
нарушить правило, чем препятствовать этому. Руководство по стилю для C++ запрещает неявные преобразования типов, включая конструкторы с одним аргументом.
Однако для типов, предназначенных для прозрачного обертывания других типов,
где базовые данные сохраняют точное представление, вполне разумно разрешить
неявное преобразование. В таких случаях добавляется исключение из правила
неявного преобразования. Наличие четкого обоснования для исключений может
указывать на то, что данное правило необходимо уточнить или изменить. Однако
для этого конкретного правила поступает достаточно много запросов на исключения,
которые только кажутся подходящими для создания исключения, но в действительности таковыми не являются — либо потому, что конкретный рассматриваемый тип
не является прозрачным типом-оберткой, либо потому, что тип является оберткой,
но в таком исключении нет необходимости.

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

Руководства   163

и поэтому могут стать источниками путаницы. Если выполнять правила «необходимо», то руководства — «следует».
Одним из примеров сборника руководств, который мы развиваем, является набор
учебников для некоторых языков, наиболее широко используемых у нас. Если наши
руководства по стилю носят предписывающий характер и определяют, какие особенности языка разрешены, а какие запрещены, учебники для начинающих носят
более описательный характер и объясняют особенности, одобренные в руководствах
по стилю. Они освещают почти все, что должен знать инженер, плохо знакомый
с особенностями использования языка в Google, но не углубляются в каждую деталь темы, давая только объяснения и рекомендации. Если инженер хочет узнать,
как применять ту или иную особенность, учебники для начинающих послужат ему
хорошим ориентиром.
Несколько лет назад мы начали публиковать серию советов по С++, в которых предлагался комплекс общих рекомендаций по использованию этого языка в Google.
В этих советах мы рассмотрели сложные аспекты — время жизни объекта, семантику
копирования и перемещения, поиск, зависящий от аргумента. Также мы осветили
новшества — возможности C++11 в кодовой базе, типы C++17 (такие как string_view,
optional и variant) — и затронули другие аспекты, о которых стоит упомянуть;
например, что вместо использования директивы using нужно обращать внимание
на предупреждения, чтобы не пропустить неявные преобразования в тип bool. Советы основаны на реальных проблемах, возникавших при решении реальных задач,
которые не рассматриваются в каноничных руководствах по стилю. Основанные на
практическом опыте, а не абстрактных идеях, советы широко применимы и считаются
своего рода «каноном повседневной работы». Советы имеют узкую направленность
и краткую форму: каждый из них читается не более нескольких минут. Серия «Совет недели» пользуется большим успехом внутри компании и содержит ссылки на
обзоры кода и технические обсуждения1.
Инженеры-программисты приходят в новый проект или кодовую базу со знанием
языка программирования, но они не знают, как этот язык используется в Google. Чтобы восполнить этот пробел, мы поддерживаем серию курсов « @Google 101»
для каждого из используемых языков программирования. Рассчитанные на полный
рабочий день курсы посвящены обсуждению особенностей использования языка
в нашей кодовой базе. Они охватывают наиболее часто используемые библиотеки
и идиомы, внутренние настройки и применение пользовательских инструментов.
Эти курсы сделают из инженера C++ хорошего инженера Google C++.
В дополнение к обучающим курсам мы готовим справочные материалы, чтобы
быстро включить в работу нового сотрудника, совершенно незнакомого с нашей
средой. Эти справочники различаются по форме и охватывают языки, которые мы
используем. Вот некоторые полезные справочники, которые мы поддерживаем для
внутреннего использования:
1

Некоторые наиболее популярные советы можно найти по адресу: https://abseil.io/tips.

164  

Глава 8. Правила и руководства по стилю

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

Применение правил
Природа правил такова, что они приобретают ценность, если выполняются неукоснительно. Обеспечить следование правилам можно педагогическими методами или
техническими — с помощью инструментов. У нас в Google есть разные официальные
учебные курсы, охватывающие многие из лучших практик, применения которых требуют наши правила. Мы также заботимся об актуальности документации. Ключевой
частью нашего подхода к изучению правил являются обзоры кода. Процесс контроля
удобочитаемости, в ходе которого инженеры, не знакомые со средой Google, обучаются через обзоры кода, в значительной степени направлен на освоение руководств
по стилю (подробнее о контроле удобочитаемости в главе 3).
Некоторый уровень обучения всегда необходим — инженеры должны, в конце концов, выучить правила, чтобы писать адекватный код, но контроль за соблюдением
правил мы предпочитаем автоматизировать с помощью инструментов.
Автоматизация контроля за соблюдением правил гарантирует, что правила не будут
отброшены или забыты с течением времени или по мере расширения организации.
Приходят новые люди, не знающие всех правил, а правила меняются со временем,
и даже при налаженном общении люди не могут помнить текущее состояние всех
дел. Пока наши инструменты синхронизируются с изменением наших правил, мы
уверены, что правила применяются всеми инженерами во всех наших проектах.
Еще одним преимуществом автоматизации контроля за соблюдением правил является минимизация различий в интерпретации и применении правил. Когда мы
пишем сценарий или используем инструмент для проверки, то проверяем все входные
данные на соответствие правилу и не оставляем инженерам возможности интерпретировать правило по-своему. Инженеры, как и все люди, имеют свои точки зрения
и предубеждения, которые могут менять взгляд людей на вещи. Передача инженерам
права контроля за соблюдением правил может привести к непоследовательному
толкованию и применению правил с потенциально ошибочными представлениями
об ответственности. Чем больше ответственности мы возлагаем на инструменты
проверки, тем меньше возможностей для разных толкований правила мы оставляем.
Автоматизация проверки также обеспечивает масштабируемость применения правила. По мере развития организации отдельная команда экспертов может создавать

Применение правил   165

инструменты для использования в остальной части компании. Даже если размер
компании удвоится, это не потребует удвоить усилия по обеспечению соблюдения
всех правил во всей организации — они останутся примерно на прежнем уровне.
Даже с учетом преимуществ, которые мы получаем от внедрения инструментов,
автоматизация применения всех правил может оказаться невозможной. Некоторые
технические правила требуют человеческого суждения. Например, в руководстве по
стилю для C++: «Избегайте сложного метапрограммирования шаблонов»; «Используйте auto, чтобы избежать употребления имен типов, которые загромождают код,
очевидны или не важны, во всех случаях, когда тип не помогает читателю понять код»,
«Композиция часто более уместна, чем наследование». В руководстве по стилю для
Java: «Нет единого правильного рецепта (упорядочения членов и инициализаторов
класса); разные классы могут упорядочивать свое содержимое по-разному»; «Очень
редко бывает правильным ничего не делать в ответ на перехваченное исключение»;
«Крайне редко требуется переопределять Object.finalize». Для оценки соответствия всем этим правилам требуется человеческое суждение, а инструменты этого
не могут (пока!).
Другие правила являются скорее социальными, чем техническими, и решать социальные проблемы с помощью технических средств часто неразумно. Для многих
правил, попадающих в эту категорию, детали определены менее четко и инструменты,
анализирующие их, получатся слишком сложными и дорогостоящими. Контроль за
соблюдением этих правил часто лучше оставить людям. Например, когда речь заходит
об объеме изменений в коде (то есть о количестве измененных файлов и строк), мы
рекомендуем инженерам отдавать предпочтение небольшим изменениям. Небольшие
изменения легче проверить, поэтому обзоры, как правило, выполняются экспертами быстрее и тщательнее. Также небольшие изменения менее чреваты ошибками,
потому что позволяют легко рассуждать об их потенциальном влиянии и последствиях. Но что значит «небольшое изменение»? Изменения, которые выливаются
в одинаковые обновления единственной строки в сотнях файлов, на самом деле
могут легко поддаваться проверке. А изменение длиной в 20 строк может содержать
сложную логику с побочными эффектами, которые трудно оценить. Мы понимаем,
что размеры изменений можно оценивать по-разному и некоторые из этих оценок
могут быть весьма субъективными, особенно если учитывать сложность изменения.
Именно поэтому у нас нет никаких инструментов для автоматического отклонения
изменений, размер которых превышает некоторый порог, выраженный количеством
строк. Рецензенты могут (и часто делают это) отвергнуть изменение, если посчитают,
что оно слишком велико. Для этого и подобных ему правил контроль за соблюдением
целиком возложен на инженеров, которые пишут и проверяют код. Однако в отношении технических правил всегда, когда это возможно, мы выступаем за автоматизацию.

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

166  

Глава 8. Правила и руководства по стилю

исследование руководства по стилю для C++, проведенное некоторыми нашими
разработчиками библиотек на C++ в середине 2018 года, показало, что вполне можно автоматизировать проверку примерно 90 % его правил. Инструменты проверки
ошибок получают набор правил или паттернов и проверяют, насколько полно указанный образец им соответствует. Автоматическая проверка снимает с автора кода
бремя запоминания всех обязательных правил — инженеру остается только поиск
предупреждений о нарушениях (многие из которых сопровождаются предлагаемыми
исправлениями), обнаруженных анализатором кода, тесно интегрированным в процесс разработки. Когда мы начали использовать инструменты выявления фактов
использования устаревших функций, основанных на тегах в исходном коде, которые
выводили предупреждения с предлагаемыми вариантами исправления, проблема
использования устаревших API исчезла почти за одну ночь. Снижение усилий на
соблюдение правил увеличивает вероятность, что инженеры с радостью доведут
проверку до конца.
Для автоматизации процесса контроля за соблюдением правил (глава 20) мы используем такие инструменты, как clang-tidy (https://oreil.ly/dDHtI) для C++ и Error
Prone (https://oreil.ly/d7wkw) для Java.
Наши инструменты были специально разработаны и адаптированы для поддержки
определяемых нами правил. Правила должны соблюдать все без исключения, поэтому
инструментами проверки пользуются все наши инженеры. В некоторых инструментах
поддержки передовых практик, если соглашения допускают определенную гибкость,
предусмотрены механизмы исключений, позволяющие проектам приспосабливать
эти инструменты к своим потребностям.

КЕЙС: GOFMT
Самир Ажмани (Sameer Ajmani)
Компания Google выпустила язык программирования Go с открытым исходным кодом
10 ноября 2009 года. С тех пор Go стал языком для разработки служб, инструментов, облачной инфраструктуры и ПО с открытым исходным кодом1.
С первого дня мы понимали, что нам нужен стандартный формат для кода на Go, причем
после выпуска исходного кода будет почти невозможно этот формат изменить. Поэтому
в первоначальную версию Go был включен стандартный инструмент форматирования
gofmt.
Мотивация
Обзоры кода — одна из передовых практик в программной инженерии, и обсуждение вопросов, связанных с форматированием, требует слишком много времени. Конечно, стандартный формат понравится не всем, но он достаточно хорошо экономил время инженера2.
1

2

В декабре 2018 года Go стал языком № 4 в GitHub по количеству запросов на вытягивание (https://oreil.ly/tAqDI).
Доклад Роберта Гриземера (Robert Griesemer) «The Cultural Evolution of gofmt» (https://oreil.
ly/GTJRd), сделанный в 2015 году, содержит подробную информацию о мотивации, дизайне

Применение правил   167

Стандартизировав формат, мы заложили основу для инструментов, которые смогут автоматически обновлять код Go. Причем код, отредактированный инструментом, будет
неотличим от кода, созданного человеком1.
Например, несколько месяцев, предшествовавших выходу Go 1.0 в 2012 году, команда Go
использовала инструмент gofix для автоматического обновления предварительной версии кода языка и библиотек до стабильной версии 1.0. Благодаря gofmt в производимые
инструментом gofix изменения вошло только самое важное, касавшееся использования
языка и API. Это облегчило программистам обзор изменений и дало возможность учиться
на изменениях, сделанных инструментом.
Влияние
Программисты на Go ожидают, что весь код на Go будет отформатирован с помощью gofmt.
У gofmt нет настроек, и его поведение редко меняется. Все основные редакторы и интегрированные среды разработки (IDE, integrated development environment) используют gofmt или
имитируют его поведение, поэтому почти весь существующий код на Go отформатирован
идентично. Сначала пользователи Go жаловались на обязательный стандарт; теперь они
часто называют gofmt одной из причин, по которым им нравится Go. Этот формат позволяет
быстро вникать в любой код на Go.
Тысячи проектов с открытым исходным кодом используют и пишут код на Go2. Поскольку
все редакторы и IDE обеспечивают единообразное форматирование, инструменты на Go
легко переносятся между платформами и интегрируются в новые среды разработки и рабочие процессы с помощью командной строки.
Настройка
В 2012 году мы решили автоматически отформатировать все файлы BUILD в Google, используя новый стандартный инструмент форматирования buildifier. Файлы BUILD содержат правила сборки ПО в Blaze — системе сборки в Google. Стандартизация формата
BUILD должна была позволить нам создавать инструменты, автоматически редактирующие
файлы BUILD, не нарушая их формата, как это делают инструменты Go с файлами на Go.
Одному инженеру потребовалось шесть недель, чтобы переформатировать 200 000 файлов
BUILD, принятых различными командами, в течение которых каждую неделю добавлялось
больше тысячи новых файлов BUILD. Зарождающаяся инфраструктура Google для внесения
масштабных изменений значительно ускорила этот процесс (глава 22).

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

1

2

и влиянии gofmt на Go и другие языки.
Расс Кокс (Russ Cox) объяснил в 2009 году (https://oreil.ly/IqX_J), что цель gofmt — автоматизация изменений: «Итак, у нас есть все сложные части инструмента манипулирования
программами, которые просто ждут, чтобы их использовали. Согласие принять “стиль gofmt”
запустит этот инструмент в ограниченном объеме кода».
Пакеты AST (https://godoc.org/go/ast) и format (https://godoc.org/go/format) на Go импортируются тысячами проектов.

168  

Глава 8. Правила и руководства по стилю

длины строк перестала существовать1. Инженеры просто запускают программы
проверки стиля и продолжают двигаться вперед. Единый способ форматирования
устраняет циклы рецензирования, в ходе которых инженер тратит время на поиск,
маркировку и исправление незначительных ошибок в оформлении.
Управляя самой большой в истории базой кода, мы получили возможность сравнить результаты форматирования, выполненного людьми и автоматизированными
инструментами. В среднем роботы справляются с большими объемами кода лучше
людей. Но в некоторых ситуациях знание предметной области имеет значение, например человек лучше справляется с форматированием матрицы, чем универсальный
инструмент. В остальных случаях форматирование кода с помощью автоматических
инструментов редко выполняется неправильно.
Также мы автоматизировали проверку форматирования: перед отправкой кода в репозиторий служба проверяет, изменился ли код после его обработки инструментом
форматирования. Если изменился, то отправка отклоняется и сопровождается
инструкциями, как запустить средство форматирования для исправления кода.
Такой предварительной проверке подвергается большая часть кода в Google. Для
проверки кода на C++ мы используем clang-format (https://oreil.ly/AbP3F); для кода на
Python — внутреннюю обертку вокруг yapf (https://github.com/google/yapf); для кода
на Go — gofmt (https://golang.org/cmd/gofmt); для кода на Dart — dartfmt и для файлов
BUILD — buildifier (https://oreil.ly/-wyGx).

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

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

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

ГЛАВА 9

Код-ревью
Авторы: Том Маншрек и Кейтлин Садовски
Редактор: Лиза Кэри
Код-ревью, или обзор кода, — это процесс проверки внесенных в код изменений сотрудником, который не является их автором, часто до передачи кода в репозиторий.
Определение выглядит простым, но реализации процесса обзора кода сильно отличаются в индустрии ПО. В одних организациях вносимые изменения просматривает
отдельная группа «цензоров» всей кодовой базы. В других обзоры кода делегируются
небольшим командам, что позволяет разным командам требовать разные уровни
проверки кода. В Google практически каждое изменение проверяется перед его
отправкой в репозиторий и каждый инженер отвечает за инициирование обзоров
и проверку изменений.
Обзоры кода обычно представляют собой комбинацию процесса и инструмента,
поддерживающего этот процесс. Мы в Google используем для проверки кода специальный инструмент Critique1, обсуждение которого достойно отдельной главы
в этой книге. А сейчас мы представим идеи, связанные с самим процессом обзора
кода в Google, которые можно применить к любому специальному инструменту.
Дополнительная информация о Critique в главе 19.

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

1

2

Также для проверки кода в Git мы используем Gerrit (https://www.gerritcodereview.com), но
в первую очередь для проектов с открытым исходным кодом. То есть Critique — основной
инструмент типичного инженера-программиста в Google.
Макконнелл С. Совершенный код. Мастер-класс. М.: Русская редакция и Microsoft Press,
2017. — Примеч. пер.

170  

Глава 9. Код-ревью

Поток обзора кода
Обзоры кода могут выполняться на разных этапах разработки ПО. В Google обзоры
кода выполняются до того, как изменения попадут в кодовую базу, — этот этап мы
называем предварительной проверкой. Основная цель обзоров кода — получить от
инженера, который не является автором данного кода, отметку LGTM («looks good to
me» — «хорошо для меня»). Мы используем эту отметку как необходимый «элемент»
разрешения на внесение изменения (остальные элементы обсудим ниже).
Типичный обзор кода в Google включает следующие этапы:
1. Пользователь-автор вносит изменения в кодовую базу в своем рабочем пространстве. Затем он создает снимок изменений — файл исправлений (patch-файл)
и их описание — и выгружают его в инструмент обзора кода. Для выявления изменений этот инструмент создает diff-файл, содержащий отличия нового кода
от старой кодовой базы.
2. Автор может использовать diff-файл также для комментирования автоматического обзора. Убедившись, что diff-файл точно и полно отражает изменения, автор отправляет его одному или нескольким рецензентам по электронной почте. Рецензенты получают уведомление с просьбой просмотреть и прокомментировать снимок.
3. Рецензенты открывают diff-файл в инструменте обзора кода и добавляют к нему
комментарии. Некоторые комментарии явно требуют исправить выявленные
ошибки. Другие носят чисто информационный характер.
4. Автор вносит необходимые исправления, выгружает новый снимок, полученный
на основе отзывов, а затем отправляет его рецензентам. Шаги 3 и 4 могут повторяться несколько раз.
5. Если рецензенты удовлетворены состоянием изменений, они дают им отметку
LGTM. По умолчанию требуется только одна отметка LGTM, но соглашение
может потребовать, чтобы с изменениями согласились все рецензенты.
6. Автор фиксирует изменения, отмеченные LGTM, в кодовой базе при условии,
что он учел все комментарии и изменения одобрены. Процедуру одобрения мы
рассмотрим в следующем разделе.
Далее в этой главе мы обсудим этот процесс более подробно.

Как проводятся обзоры кода в Google
Мы уже рассказали, как примерно выглядит типичный процесс обзора кода, но, как
всегда, дьявол кроется в деталях. В этом разделе мы подробно опишем, как методы
обзора кода в Google позволяют масштабировать это процесс.
Процесс обзора кода в Google имеет три вида «одобрения» любого изменения.
y Проверка и оценка правильности измененного кода и его соответствия заявленным целям других инженеров — часто членам команды автора изменения.
Выражается в отметках LGTM.

Как проводятся обзоры кода в Google   171

y Одобрение одного из владельцев кода, подтверждающее, что код подходит для
конкретной части кодовой базы (и может быть сохранен в определенный каталог).
Это одобрение может быть неявным, если владельцем кода является автор изменения. База кода в Google — это древовидная структура с иерархией владельцев
каталогов (глава 16). Владельцы действуют как «цензоры» своих каталогов.
Изменение предлагает любой инженер, отметку LGTM ставит любой другой
инженер, а добавление изменения в часть кодовой базы одобряет владелец соответствующего каталога. Таким владельцем может быть технический руководитель
или инженер-эксперт в конкретной области кодовой базы. Как правило, каждая
команда сама закрепляет области кода за их владельцами.
y Одобрение от обладателя сертификата удобочитаемости для данного языка1,
подтверждающее, что код соответствует стилю языка и передовым практикам.
Это одобрение тоже может быть неявным, если автор изменения обладает сертификатом удобочитаемости, или явным, если оно получено от другого инженера,
уполномоченного проверять удобочитаемость на соответствующем языке программирования.

КОД — ЭТО ОТВЕТСТВЕННОСТЬ
Важно помнить (и понимать), что код сам по себе является ответственностью, поскольку
в будущем он обслуживается не его автором. Код похож на топливо — груз, без которого
самолет не полетит (https://oreil.ly/TmoWX).
Добавлять новые возможности стоит, только если они действительно нужны. Повторяющийся код — это не только пустая трата сил, но и лишние затраты. Изменить один паттерн
в кодовой базе намного легче, чем множество повторяющихся фрагментов. К написанию
совершенно нового кода у нас относятся настолько неодобрительно, что появилась поговорка: «Если ты пишешь код с нуля, значит, делаешь это неправильно!»
Это особенно верно для библиотечного или служебного кода. Если вы пишете утилиту,
скорее всего, учитывая размер кодовой базы Google, кто-то еще уже написал нечто подобное.
Поэтому инструменты, описанные в главе 17, имеют большое значение как для поиска повторяющегося кода, так и для предотвращения дублирования. Чтобы выявить дубликаты
как можно раньше, нужно показать проект новой утилиты ответственным командам до
того, как к ней будет написан код.
Конечно, появляются новые проекты, внедряются новые технологии, добавляются новые
компоненты и т. д. Но обзор кода не является поводом для переосмысления или обсуждения
предыдущих проектных решений. На выработку проектных решений часто требуется много
времени для обмена предложениями, обсуждения дизайна (в обзорах API или на встречах)
и, возможно, разработки прототипов. В той же мере, в какой обзор совершенно нового кода
не должен происходить внезапно, сам процесс рецензирования не должен рассматриваться
как возможность пересмотреть предыдущие решения.

1

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

172  

Глава 9. Код-ревью

Хотя такая форма контроля выглядит обременительной — и, по общему мнению,
такой и является, — в большинстве случаев все три роли принимает на себя один
человек, что значительно ускоряет процесс обзора кода. Важно отметить, что две последние роли может взять на себя сам автор кода, и ему останется только получить
LGTM от другого инженера.
Эти требования делают процесс обзора кода достаточно гибким. Технический руководитель, который является владельцем проекта и обладает сертификатом удобочитаемости для этого кода, может отправить изменение в кодовую базу на основании
LGTM от другого инженера. Инженер без таких полномочий может отправить такое
же изменение в ту же кодовую базу при условии, что он получит одобрение от владельца с сертификатом удобочитаемости для данного языка. Три вышеупомянутых одобрения могут объединяться в любой комбинации. Автор может даже запросить более
одного LGTM, явно пометив изменение как получившее LGTM от всех рецензентов.
Чаще всего обзоры выполняются в два этапа: получение LGTM от инженера-коллеги, а затем получение одобрения у соответствующего владельца(-ев) кода и/или
рецензента(-ов) удобочитаемости. Это позволяет одобряющим инженерам сосредоточиться на разных аспектах и сэкономить время, необходимое для обзора. Первый
рецензент может сосредоточиться на правильности кода, а владелец кодовой базы —
на необходимости изменения, без учета деталей в каждой строке. Другими словами,
владелец часто ищет нечто иное, чем рецензент. Наконец, тех, кто хочет принять код
в свой проект/каталог, волнуют вопросы: «Насколько сложно поддерживать этот
код?», «Увеличит ли он мой технический долг?», «Достаточно ли опыта в нашей
команде для его поддержки?»
Если все обзоры всех трех типов могут выполняться одним человеком, почему бы
просто не поручить таким сотрудникам проводить все обзоры кода? Ответ прост:
такой подход не масштабируется. Разделение ролей добавляет гибкости процессу
обзора кода. Если вы работаете с коллегой над новой функцией в библиотеке, то
можете попросить кого-то из вашей команды проверить правильность и удобочитаемость кода. После нескольких раундов (возможно, в течение нескольких дней)
ваш код удовлетворит рецензента и вы получите LGTM. После этого вам останется
только получить одобрение владельца библиотеки (часто имеющего сертификат
удобочитаемости), чтобы утвердить изменение.

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

Преимущества обзоров кода   173

ВЛАДЕНИЕ
Хайрам Райт
В небольшой команде выделенный доступ к коду в отдельном репозитории обычно распространяется на всех членов команды. В конце концов, они друг друга хорошо знают
и предметная область достаточно узкая, чтобы каждый мог быть экспертом, а небольшой
объем кода ограничивает влияние потенциальных ошибок.
По мере увеличения численности команды такой подход перестает масштабироваться.
В результате происходит беспорядочное разделение репозитория: неясно, кто и какими
знаниями обладает и какие обязанности выполняет в разных частях репозитория. Мы
в Google называем эту совокупность знаний и обязанностей владением, а ее носителей —
владельцами. Эта идея отличается от владения коллекцией исходного кода и скорее подразумевает разделение базы кода в интересах компании. (Если бы нам снова пришлось
вводить культуру владения кодом, мы наверняка выбрали бы термин «распоряжение».)
Специальные файлы с названием OWNERS содержат списки пользователей, которые несут
ответственность за каталог и его элементы. Эти файлы могут также содержать ссылки на
другие файлы OWNERS или внешние списки управления доступом, но в конечном итоге
образуют список лиц. Каждый подкаталог может содержать свой файл OWNERS, при этом
файлы в дереве каталогов связаны аддитивным отношением: файл обычно включает всех
пользователей, перечисленных в файлах OWNERS, расположенных выше в дереве каталогов. В файлах OWNERS может быть столько записей, сколько пожелает команда, но мы
рекомендуем сохранять списки относительно небольшими и точными, чтобы гарантировать
ясность разделения зон ответственности.
Владение кодом в Google дает сотруднику право на одобрение изменений в этом коде.
Владелец должен сам понимать код или знать, кому задавать вопросы по коду. В разных
командах используются разные способы передачи права владения новым членам команды,
но мы рекомендуем не использовать это право в качестве обряда посвящения и призываем
уходящих членов команд незамедлительно уступать права владения.
Распределенная организация владения позволяет использовать методы, представленные
в этой книге. Например, инженеры, перечисленные в корневом файле OWNERS, могут
выступать в роли лиц, утверждающих крупномасштабные изменения (глава 22) без привлечения членов локальных команд. Точно так же файлы OWNERS действуют подобно
документации, позволяя людям и инструментам легко находить ответственных за данный
фрагмент кода: достаточно просто пройти вверх по дереву каталогов. У нас нет центрального
органа, который регистрирует новые права владения в новых проектах: для присвоения
прав владения достаточно создать новый файл OWNERS.
Это простой, но весьма действенный механизм владения, и за последние два десятилетия
он значительно расширился. С его помощью Google гарантирует эффективную работу
десятков тысяч инженеров с миллиардами строк кода в одном репозитории.

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

174  

Глава 9. Код-ревью

мисты и практически1 все изменения в кодовой базе. Это требование влечет затраты
и влияет на скорость разработки, замедляя внедрение нового кода и его передачу
в производство. (Инженеры-программисты часто жалуются на строгость обзоров
кода.) Тогда зачем нам этот процесс? Почему мы считаем, что он приносит выгоду
в долгосрочной перспективе?
Хорошо продуманный процесс обзора кода обеспечивает следующие преимущества:
y проверку правильности кода;
y гарантию понятности изменения для других инженеров;
y обеспечение согласованности всей кодовой базы;
y воспитание командной ответственности;
y возможность обмена знаниями;
y хронологическую запись принятия решений об изменениях.
С течением времени многие из этих преимуществ приобретают особую важность
для авторов изменений, рецензентов и организации в целом. Рассмотрим указанные
преимущества подробнее.

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

2

3

Некоторые изменения в документации и конфигурациях могут добавляться без обзора кода,
но обычно мы настаиваем на прохождении этой процедуры.
«Advances in Software Inspection», IEEE Transactions on Software Engineering, SE-12(7): 744–751,
July 1986. Конечно, это исследование проводилось до появления надежных инструментов
и автоматизированных процессов тестирования в сфере разработки ПО, но его результаты
остаются актуальными и в наше время.
Rigby P. C., Bird C. 2013. Convergent software peer review practices. ESEC/FSE 2013: Proceedings
of the 2013 9th Joint Meeting on Foundations of Software Engineering, August 2013: 202–212.
https://dl.acm.org/doi/10.1145/2491411.2491444.

Преимущества обзоров кода   175

Чтобы оценка правильности была более объективной, предпочтение обычно отдается авторскому подходу к дизайну или реализации предложенного изменения.
Рецензент должен предлагать альтернативы изменения, опираясь не на личное
мнение, а на упрощение понимания кода (предлагать менее сложные варианты) или
работы с ним (предлагать более эффективные варианты). В целом же инженерам
рекомендуется одобрять изменения, улучшающие кодовую базу, даже если они не
«идеальны». Это существенно ускоряет обзор кода.
По мере развития инструментов все больше проверок правильности будет выполняться автоматически, с применением таких методов, как статический анализ
и автоматическое тестирование (подробнее о задачах, которые не могут решить
инструменты, в главе 20). Несмотря на свои ограничения, инструменты ослабили
зависимость проверки правильности кода от человека.
Проверка на наличие дефектов на начальном этапе процесса обзора кода является
неотъемлемой частью общей политики «сдвига влево», согласно которой мы стремимся выявлять ошибки как можно раньше, чтобы на их устранение ушло меньше
усилий и ресурсов. Обзор кода не является ни панацеей, ни единственной проверкой
правильности — это элемент эшелонированной обороны ПО от проблем в коде. Поэтому обзор кода необязательно должен быть «идеальным» по результативности.
Как ни удивительно, но проверка правильности — не основное преимущество, которое Google получает от процесса обзора кода. Проверка правильности гарантирует
работоспособность изменения, но гораздо важнее, чтобы изменение оставалось понятным и осмысленным с течением времени и по мере увеличения кодовой базы.
Рассмотрим проверку понятности изменения.

Понятность кода
Обзор кода обычно является первым взглядом на изменение со стороны. Рецензент
делает то, что не может сделать даже самый лучший инженер, — дает непредвзятый
отзыв. Обзор кода часто является первой проверкой понятности изменения для более широкой аудитории. Код читается гораздо чаще, чем пишется, и его восприятие
и понимание чрезвычайно важны.
Часто полезно найти рецензента, который имеет свой взгляд на изменение, отличный
от мнения автора, и, возможно, будет в своей работе поддерживать или использовать
предлагаемые изменения. Проверка кода основана как на уважении к мнению его
автора, так и на принципе «клиент всегда прав». Какое бы число вопросов автор ни
получил сейчас, оно многократно умножится с течением времени. Это не означает,
что автор должен изменить свой подход или логику в ответ на критику, но означает,
что, возможно, ему нужно объяснить свою позицию более четко.
Проверки правильности и понятности кода являются основными критериями для
получения LGTM и последующего одобрения. Когда инженер ставит отметку LGTM,
он утверждает, что код действует как требуется и он понятен. В Google изменения
в коде, который постоянно поддерживается, требуют дополнительного одобрения.

176  

Глава 9. Код-ревью

Согласованность всей базы кода
В конечном счете код, который вы пишете, будет поддерживаться кем-то еще. Многим
из тех, кто будет сопровождать ваш код, придется прочитать его и понять, что вы
хотели выразить. Другим (в том числе автоматизированным инструментам) может
понадобиться выполнить рефакторинг вашего кода, когда вы уже перейдете в другой
проект. Поэтому код должен соответствовать стандартам согласованности и не быть
чрезмерно сложным. В процессе обзора рецензенты могут оценить, насколько код
соответствует стандартам кодовой базы. Таким образом, обзор способствует поддержке работоспособности кода.
Именно для простоты сопровождения оценка LGTM (указывающая на правильность
и простоту кода для понимания) отделена от оценки удобочитаемости. Одобрения,
касающиеся удобочитаемости, могут давать только лица, успешно прошедшие процесс обучения удобочитаемости кода на определенном языке программирования.
Например, одобрить код на Java может только инженер, получивший сертификат
удобочитаемости на Java.
Проверяющему удобочитаемость поручается исследовать код и убедиться, что
он следует утвержденным передовым практикам для этого конкретного языка
программирования, согласуется с базой кода на этом языке в репозитории Google
и не слишком сложен. Согласованный и простой код легче понять и проанализировать с применением инструментов, когда придет время для рефакторинга, что
делает его более устойчивым. Если определенный паттерн в кодовой базе всегда
реализуется каким-то одним способом, это упростит создание инструмента для
его рефакторинга.
Кроме того, код может быть написан одним человеком, но будет прочитан десятками, сотнями или даже тысячами других людей. Согласованность всей базы кода
упрощает его понимание всеми инженерами и даже влияет на процесс обзора кода.
Иногда она конфликтует с функциональностью: рецензент, оценивающий удобочитаемость, может выступить за то, чтобы изменение стало менее функциональным,
но более простым для понимания.
Благодаря согласованности кодовой базы инженерам проще вникать в код других
проектов. Для обзора кода инженерам может потребоваться помощь другой команды.
Возможность обратиться к экспертам для проверки согласованности кода позволяет
инженерам сосредоточиться на правильности и простоте понимания кода.

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

Преимущества обзоров кода   177

и подходу в разработке ПО. Процесс обзора кода заставляет автора не только позволить другим вносить свой вклад в его творение, но и идти на компромиссы ради
общего блага.
Человеку свойственно гордиться своим ремеслом и не испытывать особого желания
открывать свой код для критики, а также настороженно относиться к критическим
отзывам о готовом коде. Процесс обзора кода предусматривает механизм смягчения
эмоционального напряжения его автора. Обзор кода не только ставит под сомнение
предположения автора, но и делает это предписанным нейтральным образом, чтобы
исключить «переход на личности». В конце концов, процесс требует критического
обзора (не зря мы назвали наш инструмент для обзора кода «Critique»), поэтому никто
не можете обвинить рецензента в том, что он выполняет свою работу и критикует.
Таким образом, процесс обзора кода выступает в роли «злого полицейского», тогда
как рецензент воспринимается как «добрый полицейский».
Конечно, не всем и даже не большинству инженеров нужны такие механизмы смягчения. Но создание защиты от такой критики в процессе обзора кода часто дает
большинству инженеров гораздо более мягкое представление об ожиданиях команды.
Перспектива обзора кода пугает многих инженеров, присоединившихся к Google
или перешедших в новую команду. Нетрудно понять, что любая форма критики негативно отражается на эффективности работы человека. Но со временем почти все
инженеры привыкают, что в процессе обзора их кода возникнут вопросы, и начинают
понимать ценность советов и вопросов, предложенных в ходе этого процесса (хотя,
по общему признанию, для привыкания требуется время).
Еще одним психологическим преимуществом обзора кода является признание
его пригодности. Даже самые способные инженеры могут страдать от синдрома
самозванца и быть слишком самокритичными. Процесс обзора кода действует как
подтверждение и признание их способностей. Часто этот процесс включает обмен
идеями и знаниями (подробнее об этом в следующем разделе), что приносит пользу
как рецензенту, так и рецензируемому. По мере расширения своих знаний инженерам
иногда бывает трудно получить подтверждение своего совершенствования. Процесс
обзора кода дает им такую возможность.
Процедура инициирования обзора кода также заставляет авторов уделять своим изменениям больше внимания. Многие инженеры-программисты не являются перфекционистами — большинство из них признают, что код, «выполняющий свою работу»,
лучше, чем совершенный код, разработка которого занимает слишком много времени.
В отсутствие процесса обзора кода многие авторы кода начнут срезать углы, чтобы
исправить дефекты позже. «Да, у меня нет некоторых юнит-тестов, но я потом их добавлю». Обзор кода заставляет инженера решать большинство проблем до отправки
изменений. Необходимость собрать все компоненты, составляющие изменение, для
обзора кода заставляет инженера убедиться, что код в полном порядке. Короткий
период для размышлений перед отправкой изменений — это идеальное время, чтобы
еще раз прочитать изменения и убедиться, что ничего не упущено.

178  

Глава 9. Код-ревью

Обмен знаниями
Одним из наиболее важных, но недооцененных преимуществ обзора кода является
обмен знаниями. Большинство авторов выбирают рецензентов, которые являются
экспертами или, по крайней мере, опытными специалистами в предметной области.
Процесс обзора позволяет рецензентам передавать авторам знания, давать советы,
рассказывать про новые методы или делиться рекомендациями. (Рецензенты могут
помечать некоторые свои комментарии как «FYI» — «на заметку», не требуя какихлибо действий, а просто сообщая автору некоторые сведения.) По мере накопления
опыта авторы часто становятся владельцами и затем получают возможность выступать в роли рецензентов кода других инженеров.
Кроме обратной связи и подтверждения работоспособности кода процесс обзора кода
также включает обсуждение реализации изменения, выбранной автором. Не только
авторы, но и рецензенты могут узнавать о новых методах и паттернах в процессе
обзора. В Google рецензенты могут напрямую делиться возможными вариантами
изменений с автором в самом инструменте обзора кода.
Инженер может читать не все электронные письма, адресованные ему, но, как правило, он отвечает на каждый комментарий, полученный в процессе обзора кода.
Этот обмен знаниями может выходить за рамки часовых поясов и проектов благодаря средствам быстрого распространения информации среди инженеров Google по
всей базе кода. Обзор кода обеспечивает своевременную и эффективную передачу
знаний. (Многие инженеры в Google «знакомятся» с другими инженерами при прохождении обзоров кода!)
Время, затрачиваемое на обзоры кода, позволяет инженерам накопить довольно
значительные знания. Конечно, основная задача инженеров в Google по-прежнему
заключается в программировании, но большую часть своего времени они все еще
тратят на обзоры кода. Процесс обзора кода является одним из основных способов
взаимодействия инженеров-программистов. Часто в ходе обзора кода демонстрируются
новые паттерны, например с помощью рефакторинга в крупномасштабных изменениях.
Более того, поскольку каждое изменение становится частью кодовой базы, обзоры
кода действуют как хронологические записи. Любой инженер может заглянуть в кодовую базу Google и определить, когда был принят какой-то паттерн, а также извлечь
искомый обзор кода. Часто такие «археологические изыскания» помогают вникнуть
в код не только автору и рецензентам, но и гораздо более широкому кругу инженеров.

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

Передовые практики обзора кода   179

Будьте вежливы и профессиональны
Как отмечалось в главе 2 «Культура» этой книги, Google активно развивает культуру
доверия и уважения. Эта культура избавляет нас от предвзятого взгляда на обзор
кода. Например, инженеру-программисту достаточно получить одобрение LGTM
только от одного другого инженера, чтобы удовлетворить требование к простоте понимания кода. Многие инженеры комментируют и оценивают изменения, понимая,
что эти изменения можно внести в кодовую базу без дополнительных проверок. Тем
не менее обзоры кода могут вызвать беспокойство и стресс даже у самых способных
инженеров. Поэтому крайне важно, чтобы все отзывы и критические замечания не
выходили за рамки профессиональной сферы.
В общем случае рецензенты уважают выбранные авторами подходы и предлагают
альтернативы, только если авторский подход несовершенен. Если автор сумеет
продемонстрировать, что несколько подходов одинаково верны, рецензент должен
согласиться с предпочтением автора. Даже если в выбранном подходе обнаружатся
дефекты, обзор станет платформой для обучения (для обеих сторон!). Все комментарии должны оставаться в строго профессиональных рамках. Рецензенты не
должны спешить с выводами относительно особого подхода автора: лучше сначала
спросить, почему автор сделал именно такой выбор, прежде чем предполагать, что
его подход неверен.
Рецензенты должны предоставлять отзывы максимально оперативно. Мы в Google
ожидаем, что отзывы поступят в течение 24 (рабочих) часов. Если рецензент не
укладывается в это время, ему рекомендуется ответить, что он, по крайней мере, увидел изменение и постарается подготовить рецензию как можно скорее. Рецензенты
должны избегать рецензирования кода по частям. Ничто так не раздражает автора,
как получение отзыва от рецензента, его изучение, а затем получение других отзывов.
Мы ожидаем профессионализма не только со стороны рецензента, но и со стороны
автора. Помните, что вы — это не ваш код и предложенное вами изменение — не
«ваше», а коллективное. В любом случае, как только вы отправите фрагмент кода
в репозиторий, он перестанет быть вашим. Будьте готовы объяснить, почему поступили именно так, а не иначе. Помните, что понятность кода и простота его поддержки
в будущем являются одной из зон ответственности автора.
Важно рассматривать каждый комментарий рецензента как элемент TODO («что
сделать»). Если вы не согласны с комментарием рецензента, дайте ему знать и опишите причину, но не отмечайте комментарий как решенный, пока каждая сторона
не получит возможность предложить альтернативу. Один из распространенных
способов сохранить корректность дебатов, когда автор не согласен с рецензентом, —
предложить альтернативу и попросить другую сторону рассмотреть ее. Помните, что
обзор кода — это возможность обучения не только для автора, но и для рецензента.
Такой подход часто помогает снизить вероятность разногласий.
Точно так же, если вы являетесь владельцем кода и отвечаете за обзор кода в вашей
кодовой базе, будьте готовы оценить изменения, предложенные внешним автором.

180  

Глава 9. Код-ревью

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

Пишите небольшие изменения
Пожалуй, наиболее важной практикой, обеспечивающей гибкость процесса обзора
кода, является внесение в код изменений небольшого объема. В идеале обзор кода
должен фокусироваться на одной небольшой проблеме. Процесс обзора кода в Google
не предназначен для изменений, оформленных в виде полностью сформированных
проектов, и рецензенты вправе отклонить такие изменения как слишком большие для
одного обзора. Кроме того, небольшие изменения позволяют инженерам не тратить
время на ожидание результатов обзора. Небольшие изменения также имеют свои
преимущества в процессе разработки ПО. Определить источник ошибки внутри
изменения гораздо проще, если оно достаточно мало.
Однако важно понимать, что иногда трудно согласовать процесс обзора кода, опирающийся на небольшие изменения, с внедрением новых масштабных особенностей.
Набор небольших последовательных изменений проще проверить по отдельности,
но труднее оценить в рамках более крупной схемы. Некоторые инженеры в Google,
по их признанию, не являются поклонниками практики внесения небольших изменений. Конечно, существуют методы для управления такими изменениями (разработка в интеграционных ветвях, управление изменениями с использованием базы
различий, отличной от HEAD), но эти методы влекут существенные накладные
расходы. Рассматривайте предложение вносить изменения небольшими порциями
только как оптимизацию и допустите в своем коде возможность редкого появления
больших изменений.
«Небольшие» изменения обычно ограничены примерно 200 строками кода. Небольшое изменение должно быть простым для рецензента, чтобы автору не пришлось
откладывать другие изменения в ожидании результатов обзора. Большинство изменений в Google рассматриваются в течение дня1. (По крайней мере, первичный
отзыв на изменение дается в течение дня.) Около 35 % изменений в Google затрагивают единственный файл2. Чем проще изменение для рецензента, тем быстрее оно
попадет в кодовую базу и начнет приносить пользу автору. Ожидание подробного
обзора в течение недели или около того может повлиять на последующие изменения.
Небольшой первичный обзор предотвращает затраты, которые мог повлечь выбор
неправильного подхода.
Поскольку изменения передаются обычно небольшими порциями, почти все обзоры
кода в Google выполняются одним человеком. В противном случае, если бы приходилось привлекать целую команду, чтобы оценить все изменения в общей кодовой
1

2

Sadowski C., Söderberg E., Church L., Sipko M., Bacchelli A. Modern code review: a case study at
Google (https://oreil.ly/m7FnJ).
Там же.

Передовые практики обзора кода   181

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

Пишите хорошие описания к изменениям
Описание должно сообщать тип изменения с краткой сводкой в первой же строке,
которая действует подобно строке с темой в электронных письмах — ее видят инженеры Google в сводке истории в инструменте Code Search (глава 17).
В описании следует подробно рассказать, что и почему изменяется. Описание «Исправление ошибок» не поможет ни рецензенту, ни будущему «археологу». Если
изменение содержит несколько более мелких связанных изменений, перечислите
их в виде списка (желательно короткого). Описание является хронологической записью для изменения, и такие инструменты, как Code Search, позволят вам найти,
кто и какую строку написал, в любом конкретном изменении в кодовой базе. Поиск
и исследование исходного изменения часто помогают при исправлении ошибок.
Описания — не единственное место, куда можно добавить документацию к изменению. При разработке общедоступного API вы едва ли захотите включить в общее
описание детали реализации, но непременно сделайте это в фактической реализации,
добавив соответствующие комментарии. Если рецензент не поймет вашу задумку,
даже правильную, это будет означать, что вашему коду недостает структуры и/или
более ясных комментариев. Если в процессе обзора кода будет принято новое решение, обновите описание изменения или добавьте соответствующие комментарии
в реализацию. Обзор кода — это не только набор действий, выполняемых сейчас, но
и описание ваших действий для будущих читателей.

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

Там же.

182  

Глава 9. Код-ревью

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

Автоматизируйте все, что только можно
Обзор кода — это процесс с участием человека, но если в процессе есть этапы,
которые можно автоматизировать, попробуйте это сделать. Изучите возможность
автоматизации механических задач, и инвестиции в эту автоматизацию окупятся
сторицей. Инструменты, используемые в Google в процессе обзора кода, позволяют
авторам автоматически отправлять изменения и синхронизировать их в VCS после
утверждения (обычно они применяются для наиболее простых изменений).
Одним из самых важных технологических усовершенствований в области автоматизации, сделанных за последние несколько лет, является автоматический статический
анализ изменений (глава 20). Инструмент автоматизации обзора кода в Google избавляет авторов от необходимости вручную запускать тесты и применять инструменты
форматирования и статического анализа — он автоматически выполняет большую
часть механической работы в ходе так называемой предварительной проверки перед
отправкой. Процедура предварительной проверки запускается, когда изменение
впервые посылается рецензенту. Она может обнаружить ошибки и отклонить изменения (и предотвратить отправку электронного письма рецензенту), а также
предложить автору исправить найденные недочеты. Такая автоматизация не только
ускоряет процесс обзора кода, но также позволяет рецензентам сосредоточиться на
более важных задачах, чем форматирование.

Виды обзоров кода
Обзоры кода не похожи друг на друга! Разные виды обзоров кода требуют разного
уровня внимания к различным аспектам. В Google изменения обычно попадают
в одну (или несколько) из следующих групп:
y разработка новой возможности;
y изменение в поведении, улучшение и оптимизация;
y исправление ошибок и откат к прежним версиям;
y рефакторинг и крупномасштабные изменения.

Виды обзоров кода   183

Обзоры кода новых возможностей
Реже всего проводятся обзоры совершенно нового кода — так называемые обзоры
с нуля. Самое важное для обзора с нуля — оценить, выдержит ли код проверку временем и насколько легко его будет поддерживать, потому что с течением времени
и при росте организации могут измениться предположения, на которых этот код
основывается. Конечно, появление совершенно нового кода не должно вызывать
удивления. Как упоминалось выше в этой главе, код — это ответственность, поэтому
совершенно новый код должен, как правило, решать реальную проблему, а не просто
представлять еще одну альтернативу. Мы в Google обычно требуем, чтобы новый
код и/или проект подвергались обширной проверке контекста. Обзор кода — не
лучшее пространство для обсуждения проектных решений, принятых в прошлом
(и к тому же обзор кода совершенно не подходит для представления предлагаемого
дизайна API).
Чтобы гарантировать устойчивость кода, в ходе обзора с нуля необходимо убедиться,
что API соответствует согласованному дизайну (а для этого может потребоваться
пересмотреть проектную документацию), и полностью его протестировать, причем
все конечные точки API должны быть охвачены некоторой формой юнит-тестирования и все тесты должны завершаться неудачей при изменении предположений,
сделанных в коде (глава 11). Код также должен иметь соответствующих владельцев
(в одном из самых первых обзоров нового проекта часто исследуется единственный
файл OWNERS для нового каталога), содержать достаточно подробные комментарии и при необходимости включать дополнительную документацию. Обзор с нуля
может также потребовать включения проекта в систему непрерывной интеграции
(глава 23).

Обзоры изменений в поведении, улучшений и оптимизаций
Большинство изменений в Google связаны с модификацией существующего кода.
К ним относятся изменения конечных точек API, улучшения существующих реализаций или оптимизация других факторов, таких как производительность. Подобные
изменения являются основной работой большинства инженеров-программистов.
По принципу обзора с нуля, сначала нужно узнать, необходимо ли изменение
и улучшает ли оно существующий код. Один из лучших способов улучшить общее
состояние кодовой базы — удаление мертвого или устаревшего кода.
Любые изменения поведения должны обязательно включать исправления в соответствующие тесты, проверяющие любое новое поведение API. Дополнения
к существующей реализации мы тестируем в системе непрерывной интеграции,
чтобы убедиться, что изменения не нарушают базовые предположения существующих тестов. Оптимизации должны гарантировать, что они не влияют на тесты,
и, возможно, включать критерии производительности, чтобы рецензенты могли
проверить их. Некоторые оптимизации могут также требовать наличия тестов
производительности.

184  

Глава 9. Код-ревью

Обзоры исправлений ошибок и откатов к прежним версиям
Рано или поздно вам придется исправлять ошибки. При этом вы должны не поддаваться соблазну заняться другими задачами, чтобы не усложнить обзор кода и не
затруднить регрессионное тестирование или откат ваших изменений другими пользователями. Исправление ошибки должно быть сосредоточено исключительно на
исправлении конкретной ошибки и (обычно) обновлении соответствующих тестов,
чтобы с их помощью можно было заметить ошибку.
Устранение ошибки с помощью исправленного теста часто является срочной необходимостью. Ошибка появилась, потому что существующие тесты были недостаточно
точны или код основывался на определенных предположениях, которые не были
выполнены. Рецензент, исследующий предложенное исправление ошибки, должен
запросить обновленные юнит-тесты при необходимости.
Иногда изменение в кодовой базе с размером, как в Google, приводит к нарушению
зависимости, которая либо не обнаруживается тестами, либо обнаруживается в непроверенной части кодовой базы. В Google разрешается «откатывать» такие изменения, как правило, пострадавшим нижестоящим клиентам. Откат — это по существу
изменение, отменяющее предыдущее изменение. Такие откаты могут создаваться за
считаные секунды, потому что они возвращают код в известное состояние, но они
тоже требуют обзора кода.
Также очень важно, чтобы любое изменение, способное спровоцировать потенциальный откат (включающий все изменения!), имело минимально возможный размер и было атомарным, чтобы откат не вызвал нарушений в других зависимостях.
Мы в Google видели, насколько быстро разработчики начинают зависеть от нового
кода после его принятия, в результате чего откат изменений иногда мешает работе
инженера. Чем меньше такие изменения, тем быстрее решаются связанные с ними
проблемы благодаря их атомарности.

Обзоры результатов рефакторинга и крупномасштабных изменений
В Google многие изменения генерируются автоматически: автором таких изменений
является не человек, а машина. (Подробнее о процессе крупномасштабных изменений (LSC, large-scale change) в главе 22.) Даже сгенерированные машиной изменения требуют обзора. Когда изменение сопряжено с небольшими последствиями,
оно проверяется назначенными рецензентами, имеющими право давать одобрение
для всей кодовой базы. Но когда изменение считается рискованным или требует
особых знаний в предметной области, отдельным инженерам может быть предложено просмотреть автоматически сгенерированные изменения в ходе их обычного
рабочего процесса.
На первый взгляд обзор автоматически сгенерированного изменения должен проводиться так же, как любого другого, — рецензент должен проверить правильность
и уместность изменения. Однако мы рекомендуем рецензентам ограничить добавление комментариев и отмечать только те проблемы, которые относятся к их коду,

Итоги   185

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

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

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

ГЛАВА 10

Документация
Автор: Том Маншрек
Редактор: Риона Макнамара
Особенно сильным разочарованием большинства инженеров, пишущих, использующих и сопровождающих код, является отсутствие качественной документации.
«Какие побочные эффекты имеет этот метод?», «Я столкнулся с ошибкой, выполнив
шаг 3!», «Что означает эта аббревиатура?», «Этот документ актуален?» Каждый
инженер-программист хотя бы раз высказывал претензии к низкому качеству, недостаточному объему или полному отсутствию документации, и программисты
в Google не исключение.
Несмотря на участие технических писателей и руководителей проектов, большую
часть документации приходится писать самим инженерам-программистам. Поэтому
инженерам нужны соответствующие инструменты и стимулы, чтобы эффективно
справляться с этой работой. Облегчить создание качественной документации им
поможет внедрение процессов и инструментов, которые масштабируются вместе
с организацией и связаны с текущими рабочими процессами.
По уровню развития создание технической документации в конце 2010-х годов напоминало тестирование ПО в конце 1980-х. Все понимают, что необходимо приложить
больше усилий для совершенствования процессов документирования, но пока нет
повсеместного признания их важности. Ситуация меняется, хотя и медленно. Мы
в Google добились определенного успеха в этом направлении, когда документацию
стали рассматривать как код и включили ее написание и поддержку в повседневный
рабочий процесс инженера.

Что считается документацией?
Под словом «документация» мы подразумеваем любой дополнительный текст, который инженер должен написать в процессе своей работы: не только отдельные документы, но также комментарии в коде. (Фактически большая часть документации,
которую пишет инженер в Google, имеет вид комментариев в коде.) Далее в этой
главе мы обсудим различные виды технических документов.

Зачем нужна документация?   187

Зачем нужна документация?
Качественная документация дает огромные преимущества инженерной организации.
Благодаря ей код и API становятся более понятными, что способствует уменьшению
количества ошибок. Команды действуют более эффективно, когда их цели четко
определены в документации. Ручные процессы легче выполнять, когда все шаги
четко прописаны. Вливание новых членов в команду или знакомство с новой базой
кода требует гораздо меньше усилий, если рабочий процесс ясно задокументирован.
Но поскольку все преимущества наличия документации достаются тем, кто придет
потом, они, как правило, не приносят выгоды ее автору, в отличие от тестирования
(как мы увидим). Но, как бы то ни было, документ, написанный однажды1, будет
прочитан сотни или даже тысячи раз, и первоначальные усилия на его создание будут компенсированы уменьшением усилий всех будущих читателей. Документация
масштабируется и приносит пользу не только ее будущим читателям, но и нынешним
коллегам ее автора, что не менее важно. Она помогает ответить на такие вопросы:
y Почему были приняты такие проектные решения?
y Почему код реализован именно так?
y Почему я выбрал именно такую реализацию? (Пару лет спустя спросите вы,
глядя на свой код.)
Если документация несет все эти преимущества, почему инженеры не любят писать
ее? Одна из причин, как уже упоминалось, заключается в отсутствии немедленных
выгод для автора. Но есть и другие причины:
y Инженеры часто рассматривают документирование как отдельный навык, не
связанный с программированием. (Мы попробуем показать, что это не совсем
так, даже в тех случаях, где это мнение вполне обоснованно.)
y Некоторые инженеры не считают себя хорошими писателями. Но вам не нужна
надежная команда по английскому языку2, чтобы писать хорошую документацию.
Вам просто нужно выйти за привычные рамки и посмотреть на вещи со стороны.
y Писать документацию часто труднее из-за ограниченной инструментальной поддержки или слабой интеграции в рабочий процесс.
y Документация рассматривается как дополнительная нагрузка — что-то еще, что
требует поддержки, а не средство, облегчающее сопровождение существующего кода.
Далеко не каждой команде инженеров нужен технический писатель (который все равно
не справится со всей документацией). Это означает, что в общем случае инженеры
будут писать большую часть документации самостоятельно. Поэтому вместо того
чтобы заставлять инженеров становиться техническими писателями, мы должны по1
2

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

188  

Глава 10. Документация

думать о том, как упростить написание документации. Рано или поздно организации
придется принять решение о том, сколько усилий нужно посвятить документированию.
Документация выгодна разным группам. Авторам документация дает следующие
преимущества:
y Помогает сформулировать API и оценить его пригодность. Часто документирование приводит к переоценке проектных решений, которые не вызывали сомнений.
Если вы не можете объяснить и определить что-то, то вы, вероятно, недостаточно
хорошо это проработали.
y Служит хронологической записью для сопровождающих. Хитросплетений в коде
следует избегать в любом случае, но если они есть, хорошие комментарии помогут
понять их в коде, написанном пару лет назад.
y Делает код более профессиональным и привлекательным. Среди разработчиков
бытует мнение, что хорошо документированный API — это хорошо проработанный
API. Это не всегда так, хотя часто эти два аспекта тесно связаны друг с другом:
наличие хорошей документации обычно является верным показателем того, насколько просто будет сопровождать продукт.
y Уменьшает поток вопросов от пользователей. Это, пожалуй, самое большое преимущество для тех, кто пишет документацию. Если вам приходится снова и снова
что-то объяснять, обычно имеет смысл задокументировать этот момент.
Как бы ни были велики эти преимущества для автора документации, львиная доля
выгод от нее, естественно, достается читателю. Руководство по стилю для C++
в Google особо подчеркивает принцип «оптимизации для читателя» (https://oreil.ly/
zCsPc). Этот принцип применим не только к коду, но также к комментариям в коде
и документации, прилагаемой к API. Со временем ценность документации только растет и может принести огромные выгоды для важного кода в масштабах организации.

Документация как код
Инженеры-программисты, которые пишут на одном основном языке программирования, все еще часто используют другие языки для решения узких задач. Инженер может
писать сценарии на языке командной оболочки, а для выполнения некоторых задач
в командной строке использовать Python или писать большую часть внутреннего кода
на C++, а интерфейсную часть — на Java и т. д. Каждый язык — это инструмент в наборе.
Документация — это тоже инструмент, написанный на другом языке (обычно на
английском) для решения конкретной задачи. Написание документации мало чем
отличается от написания кода. Как и программирование, этот процесс управляется
своими правилами, особым синтаксисом и соглашениями по стилю. Цель документации подобна той, что преследует код: обеспечить согласованность, повысить ясность и избежать ошибок. Грамматика в технической документации стандартизирует
изложение и предотвращает путаницу в изложенных сведениях. По этой причине
Google требует придерживаться определенного стиля в комментариях.

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

ПРИМЕР: ЭЛЕКТРОННАЯ ЭНЦИКЛОПЕДИЯ GOOGLE
Когда компания Google была намного меньше, в ней было мало технических писателей.
В ту пору самым простым способом поделиться информацией была внутренняя электронная энциклопедия GooWiki. Сначала она казалась разумным подходом: все инженеры
пользовались одним комплектом документации и могли обновлять ее при необходимости.
Но по мере роста Google проблемы с GooWiki становились все очевиднее. В отсутствие настоящих владельцев многие документы устарели1. Без четкого процесса добавления новых
документов начали появляться дубликаты. Пространство имен в GooWiki было плоским,
поэтому ни о какой иерархии в наборах документов не было и речи. Мы нашли в GooWiki
от семи до десяти документов (по разным подсчетам) с описанием настройки Borg — нашей
производственной вычислительной среды. Только некоторые из них продолжали поддерживаться, а большинство были специфичны для определенных групп.
Со временем появилась еще одна проблема: исправлять документы в GooWiki могли не те,
кто их использовал. Новые пользователи, обнаружившие ошибки в документах, либо не
могли подтвердить их, либо не имели возможности сообщить о них. И наоборот, авторам,
которые могли бы внести исправления, часто не требовалось работать с документами после
их написания. Постепенно документация ухудшилась настолько, что ее низкое качество
стало все чаще отмечаться в ежегодных опросах разработчиков Google.
Одно из решений, способствовавших улучшению документации, состояло в перемещении
важной документации в VCS, аналогичную системе для хранения кода. Документы приобрели владельцев, каноническое местоположение в дереве исходного кода и процессы
выявления и исправления ошибок. Благодаря этим мерам документация начала резко улучшаться. Кроме того, процессы написания и поддержки документации стали более похожими
на процессы написания и поддержки кода. Появилась возможность сообщать о найденных
в документах ошибках в программе отслеживания ошибок и вносить изменения в документы
в процессе обзора кода. В конце концов, инженеры начали сами исправлять документы или
посылать изменения техническим писателям (которые часто были владельцами).
На первом этапе перемещение документации в VCS столкнулось с рядом противоречий.
Многие инженеры были убеждены, что отказ от GooWiki, этого бастиона свободы информации, приведет к снижению качества документов из-за повышенных требований
к ним (требований к проведению обзоров, наличию владельцев и т. д.). Но на самом деле
документы стали только лучше.
Также помогло внедрение Markdown в роли общепринятого языка разметки для оформления документации, благодаря которому инженеры быстро освоили приемы редактирования документов без специальных знаний HTML и CSS. В итоге Google представила свой
фреймворк для встраивания документации в код: g3doc (https://oreil.ly/YjrTD), который
способствовал дальнейшему улучшению качества документации, находящейся рядом с исходным кодом в среде разработки. Теперь инженеры могут обновлять код и связанную с ним
документацию в одном изменении (мы продолжаем попытки распространить эту практику).
Главный прорыв состоит в том, что поддержка документации стала больше походить на
поддержку кода: инженеры выявляют ошибки в документах, вносят изменения, отправляют
их экспертам для обзора и т. д. Ключевым преимуществом выбранного подхода стало использование существующих рабочих процессов вместо создания новых.
1

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

190  

Глава 10. Документация

Документы, так же как код, должны иметь владельцев. Документы без владельцев
становятся устаревшими и сложными в сопровождении. Чем более ясно выражено
владение, тем проще обрабатывать документацию с использованием существующих
рабочих процессов: систем отслеживания ошибок, инструментов обзора кода и т. д.
Конечно, документы, принадлежащие разным владельцам, могут конфликтовать друг
с другом. В этих случаях важно определить каноническую документацию: найти главный
источник и объединить в него другие связанные документы (или исключить дубликаты).
Документы с прямыми ссылками go/ (глава 3) часто становятся каноническим источником информации. Еще один способ выделения канонических документов — их
размещение в VCS и рядом с соответствующим исходным кодом.
Документация часто тесно связана с кодом и рассматривается как код (https://oreil.
ly/G0LBo). Она должна:
y подчиняться внутренним правилам;
y храниться в VCS;
y иметь ясно обозначенных владельцев, ответственных за ее сопровождение и поддержку;
y подвергаться обзорам в случае изменения (и изменяться вместе с кодом, который
она описывает);
y как и код, отражаться в системе отслеживания ошибок;
y периодически переоцениваться (подвергаться своего рода тестированию);
y оцениваться на точность, актуальность и т. д. (эта сфера остается неохваченной
инструментами).
Чем чаще инженеры будут рассматривать документацию как «одну из» обязательных
задач разработки ПО, тем меньше они будут возмущаться необходимостью тратить
время и силы на ее написание и тем весомее будут долгосрочные выгоды от документирования. Кроме того, упрощение процесса документирования может помочь
снизить первоначальные затраты на него.

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

Знание своей аудитории   191

Поэтому, прежде чем начать писать, вы должны (формально или неформально) определить аудиторию документа. Проектный документ в первую очередь предназначен
для представления доказательств лицам, принимающим решения. Учебное пособие
должно содержать четкие инструкции для тех, кто совершенно не знаком с вашей
базой кода. В описании API может потребоваться предоставить полную и точную
справочную информацию для любых пользователей этого API, будь то эксперты
или новички. Всегда старайтесь определить основную аудиторию и пишите для нее.
Хорошая документация не должна быть «идеальной». Часто инженеры ошибочно
предполагают, что они должны в совершенстве владеть навыками технического
писателя. Однако мало кто из инженеров-программистов способен писать документацию на таком уровне. Подходите к написанию документации как к тестированию
или любому другому процессу — то есть как инженер. Пишите текст, используя
слог и стиль, ожидаемые вашей аудиторией. Если вы умеете читать документы, то
сможете их написать. Помните, что вы тоже когда-то находились в вашей аудитории,
только без сегодняшних знаний в предметной области. Поэтому от вас не требуется
быть великим писателем; вы просто должны познакомить читателя с предметной
областью. (И пока вы отвечаете за свою документацию, вы можете улучшать ее.)

Виды аудиторий
Как отмечалось выше, ваши документы должны соответствовать уровню навыков
и знаний аудитории. Но кто относится к аудитории? Скорее всего, у документа будет
несколько аудиторий, разделенных по следующим критериям:
y уровень опыта (опытные программисты или младшие инженеры, которые могут
даже не знать — внимание! — языка);
y уровень знания предметной области (члены команды или другие инженеры в организации, которые знакомы только с конечными точками API);
y цель (конечные пользователи, которым нужен ваш API для решения конкретной
задачи, желающие быстро найти информацию, или программисты-гуру, отвечающие за внутреннюю реализацию, которую, по вашему мнению, больше никому
не придется поддерживать).
Иногда для разных аудиторий документация должна быть написана в разных стилях,
но в большинстве случаев документация должна быть настолько универсальной,
насколько это возможно. Часто вам придется объяснять сложную тему и экспертам, и новичкам. Описывая предметную область для эксперта, хорошо знающего ее,
вы можете позволить себе срезать некоторые углы, но тогда вы запутаете новичка.
И наоборот, подробное объяснение, написанное для новичка, несомненно будет
раздражать эксперта.
Очевидно, что документирование связано с постоянным поиском баланса, и эта
проблема не имеет универсального решения, но мы уверены, что такой подход помогает сократить документы. Пишите достаточно наглядно, объясняя сложные темы

192  

Глава 10. Документация

людям, незнакомым с ними, но не отталкивайте и не раздражайте экспертов. Чтобы
написать короткий документ, часто требуется сначала написать более длинный (изложив в нем все сведения), а затем выполнить редактирование и удалить повторяющуюся информацию везде, где возможно. Это может показаться утомительным, но
имейте в виду, что эти усилия распространяются на всех читателей документации.
Как однажды сказал Блез Паскаль, «если бы у меня было больше времени, то я бы
написал короче». Стараясь сохранить документ как можно более коротким и ясным,
вы сможете гарантировать, что он удовлетворит как эксперта, так и новичка.
Не менее важно уметь различать аудиторию, основываясь на том, как пользователь
применит документ.
y Целеустремленные искатели — это инженеры, которые знают, чего хотят, и для
них важно, чтобы документ отвечал их потребностям. Ключевым приемом при
создании документации для этой аудитории является последовательность. Если
вы пишете справочную документацию для этой аудитории — например, в файле
кода, — ваши комментарии должны следовать формату справочника, чтобы читатели могли быстро просмотреть их и определить, есть ли в них искомые сведения.
y Наткнувшиеся случайно могут не знать точно, чего они хотят. Они могут иметь
лишь смутное представление о том, как реализовать необходимое. Ключ к этой
аудитории — ясность. Добавьте в документацию общий обзор или вводную
часть (например, в начале файла) с объяснением назначения кода, который
они просматривают. Также полезно указать, для какой аудитории документ не
подходит. Многие документы в Google начинаются с «аннотации», например:
«Аннотация: если вас не интересуют компиляторы C++ в Google, можете дальше
не читать».
Наконец, учитывайте разницу между потребителем (например, пользователем API)
и производителем (например, членом команды проекта) — по возможности документы, предназначенные для одной аудитории, должны отличаться от документов,
предназначенных для другой. Детали реализации важны членам команды для успешного сопровождения, а конечным пользователям не нужна эта информация. Часто
инженеры включают проектные решения в справочник по API своей библиотеки.
Описание таких решений более уместно в конкретных (проектных) документах или,
в лучшем случае, внутри реализации, скрытой за интерфейсом.

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

Виды документации   193

Существует несколько основных видов документов, которые часто приходится писать
инженерам-программистам:
y справочная документация, включая комментарии в коде;
y проектные документы;
y учебные руководства;
y концептуальная документация;
y посадочные страницы.
В первые годы существования Google для нас было обычным делом создавать
монолитные wiki-страницы с множеством ссылок (многие из которых оказывались
неработающими или устаревали со временем), концептуальной информацией о системе, справкой по API и т. д. Такие документы были очень неудобны, потому что не
служили ни одной цели (и были настолько длинными, что их никто не хотел читать;
некоторые из них занимали до нескольких десятков экранов). Не повторяйте наших
ошибок, пишите документ, преследующий одну цель, и если информация, добавляемая на страницу, не связана с ней по смыслу, подберите для нее другой документ
или даже создайте новый.

Справочная документация
Справочная документация — это наиболее распространенный вид документации,
которую приходится писать инженерам почти каждый день. К ней относятся все документы, описывающие порядок использования кода. Комментарии в коде — самая
распространенная форма справочной документации, которую должен вести инженер.
Их можно разделить на две основные категории: комментарии с описанием API
и комментарии с описанием реализации. Помните о различиях между аудиториями
этих двух категорий. Комментарии с описанием API не должны обсуждать детали
реализации или проектные решения и не могут предполагать, что пользователь
разбирается в API настолько же хорошо, как и автор. Комментарии с описанием
реализации, напротив, могут предполагать наличие у читателя глубоких знаний
предметной области, но будьте осторожны и не заходите слишком далеко в своих
предположениях: вы можете покинуть проект, поэтому должны подробно описать,
почему код написан именно так.
Большая часть справочной документации, даже если она оформляется как отдельный документ, генерируется из комментариев внутри кодовой базы. (Желательно,
чтобы справочная документация имела только один источник.) Некоторые языки
программирования, такие как Java или Python, имеют специализированные фреймворки для обработки комментариев (Javadoc, PyDoc, GoDoc), упрощающие создание
справочной документации. Другие языки, такие как C++, не имеют стандартной
реализации справочной документации, но поскольку C++ отделяет определение
API (в заголовочных файлах .h) от реализации (в файлах .cc), заголовочные файлы
часто являются естественным местом для описания API в C++.

194  

Глава 10. Документация

В Google широко используется такой подход, как размещение справочной документации с описанием API на C++ в заголовочных файлах. В других языках, таких как Java,
Python и Go, справочная документация встраивается непосредственно в исходный
код. Браузер Google Code Search (глава 17) настолько надежен, что избавляет нас от
необходимости генерировать отдельную справочную документацию. Пользователи
Code Search не только с легкостью находят нужный код, часто им удается найти
оригинальное определение в первых результатах поиска. Наличие документации
в коде также облегчает ее поиск и сопровождение.
Все мы знаем, насколько важны комментарии в коде для документирования API.
Но что отличает «хорошие» комментарии? Выше в этой главе мы определили две
основные аудитории справочной документации: целеустремленные искатели и пользователи, наткнувшиеся на документ случайно. Для первых важно, чтобы база кода
была прокомментирована последовательно для быстрого поиска искомых сведений.
Вторым важно наличие четкого определения назначения API, желательно в начале
заголовочного файла. В следующих подразделах мы подробнее рассмотрим некоторые
виды комментариев в коде. Далее представлены рекомендации документирования
для C++, которые подходят и для других языков.
Комментарии в начале файла
В Google почти все файлы с исходным кодом должны начинаться с комментариев. (Некоторые заголовочные файлы, содержащие только одну вспомогательную
функцию и т. д., могут отступать от этого стандарта.) Комментарии в начале файла
должны начинаться примерно с такого заголовка:
// -----------------------------------------------------------------------// str_cat.h
// -----------------------------------------------------------------------//
// Этот заголовочный файл содержит сигнатуры эффективных функций
// для объединения строк: StrCat() и StrAppend(). Основная работа в этих
// функциях выполняется с использованием типа AlphaNum, специально
// разработанного как тип параметров, который эффективно управляет
// преобразованием строк и позволяет избежать копирования
// в вышеперечисленных операциях.
...

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

Виды документации   195

API в кодовой базе. Все общедоступные классы (и структуры) в Google должны
сопровождаться комментарием к классу, описывающему класс (структуру), основные методы и назначение класса (структуры). Как правило, комментарии к классам
должны подчеркивать их объектную сущность, например: «Класс Foo, содержащий
x , y , z , позволяет выполнять такие-то действия и характеризуется следующими
свойствами» и т. п.
В общем случае комментарии к классам должны выглядеть примерно так:
//
//
//
//
//
//
//

-----------------------------------------------------------------------AlphaNum
-----------------------------------------------------------------------Класс AlphaNum действует в роли основного типа параметра для StrCat()
и StrAppend() и обеспечивает эффективное преобразование числовых,
логических и шестнадцатеричных значений (через тип Hex) в строки.

Комментарии к функциям
В Google все свободные функции и общедоступные методы классов тоже должны
сопровождаться комментариями, описывающими их назначение. Комментарии
к функциям должны описывать их активное состояние и начинаться с глагола в изъявительном наклонении, указывающего, что делает функция и что она возвращает.
В общем случае комментарии к функциям должны выглядеть примерно так:
// StrCat()
//
// Объединяет заданные строки или числа без использования разделителя,
// возвращает результат объединения в виде строки.
...

Обратите внимание, что начальный глагол в комментарии к функции обеспечивает
согласованность заголовочного файла. Целеустремленные искатели могут быстро
пробежать взглядом по API и прочитать только глаголы, чтобы понять, подходит ли
им та или иная функция: «объединяет, удаляет, создает» и т. д.
Некоторые стили документирования (и некоторые генераторы документации)
требуют наличия в комментариях к функциям различных шаблонов, таких как
«Returns:» (возвращает), «Throws:» (генерирует) и т. д., но мы в Google не считаем
их строго необходимыми. Часто такую информацию лучше представить в свободной
форме, не разбивая комментарий на разделы:
// Создает новую запись с информацией о клиенте, используя заданные имя
// и адрес, и возвращает числовой идентификатор записи или генерирует
// исключение `DuplicateEntryError`, если запись для клиента с именем name
// уже существует.
int AddCustomer(string name, string address);

Обратите внимание, насколько естественно выглядит совместное (в данном случае
в одном предложении) описание постусловия, параметров, возвращаемого значения

196  

Глава 10. Документация

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

Проектная документация
Для начала работы над крупным проектом большинство команд в Google должны
иметь одобренный проектный документ. Обычно проектные документы пишутся
с использованием шаблона, утвержденного командой. Они предназначены для
совместной работы и поэтому часто публикуются в Google Docs, где есть удобные
инструменты для сотрудничества. Некоторые команды требуют, чтобы проектные
документы рассматривались и обсуждались на общих совещаниях, где эксперты
могли бы подвергнуть критике наиболее важные аспекты проекта. Предварительное
обсуждение проекта действует как своеобразная форма обзора перед написанием
кода.
Поскольку разработка проектной документации осуществляется перед развертыванием новых систем, она подходит для очерчивания круга задач. Канонические
шаблоны проектных документов в Google требуют включить в описание будущего
проекта такие его аспекты, как безопасность, интернационализация, требования
к хранилищу, конфиденциальность и т. д. В большинстве случаев эти аспекты рассматривают эксперты в соответствующих областях.
Хороший проектный документ должен описывать цели проекта, стратегию его
реализации и предлагать ключевые проектные решения с акцентом на конкретные
компромиссы. Лучший проектный документ должен также охватывать альтернативные проектные решения и обозначать их сильные и слабые стороны.
После утверждения хороший проектный документ действует не только как хронологическая запись, но и как мера успеха в достижении поставленных целей. Большинство команд сохраняют проектные документы вместе с остальными своими
документами, чтобы иметь возможность периодически заглядывать в них. Часто
бывает полезно пересмотреть проектную документацию перед выпуском продукта,
чтобы убедиться, что цели, заявленные в проектном документе, актуальны (а если
это не так, то документ или продукт можно соответствующим образом скорректировать).

Туториалы
Каждый инженер-программист, присоединяясь к новой команде, должен как можно
быстрее войти в курс дела. Наличие туториала (учебного руководства), помогающего
настроить новый проект, неоценимо. Написание программы «Hello World» — это
один из лучших способов взять удачный старт в новом деле. Это касается не только
документов, но и кода. Большинство проектов стоит начать с создания документа
«Hello World», который ничего не предполагает и помогает инженеру сделать что-то
«реальное».

Виды документации   197

Часто лучшее время для создания учебного руководства, если его пока нет, — период
знакомства с новой командой. (Это также лучшее время для поиска ошибок в существующем учебном руководстве, которое вы читаете.) Откройте блокнот (или другой
инструмент для заметок) и запишите все шаги, которые нужно выполнить для входа
в курс дела, не имея знания предметной области или специальных ограничений. Закончив этот список, вы поймете, какие ошибки допускали и почему, а затем сможете
отредактировать свои записи, чтобы сформулировать последовательное учебное
руководство. Обязательно описывайте все, что вам пришлось сделать, когда вы еще
не знали конкретные настройки, разрешения или особенности предметной области.
Если для старта вам были нужны определенные настройки, четко опишите их в начале руководства в виде набора предварительных условий.
Если учебное руководство требует выполнения нескольких шагов в определенном
порядке, пронумеруйте эти шаги. В руководстве, ориентированном на пользователя (например, внешнего разработчика), нумеруйте каждое действие, которое
пользователь должен выполнить сам. Не нумеруйте действия, которыми система
отвечает на действия пользователя. Явная нумерация шагов играет важную роль.
Ничто так не раздражает, как ошибка на шаге 4 из-за неправильной авторизации.
Пример: плохой туториал
1. Загрузите пакет с нашего сервера: http://example.com.
2. Скопируйте сценарий командной оболочки в свой домашний каталог.
3. Запустите сценарий.
4. Система foobar соединится с системой аутентификации.
5. После аутентификации foobar создаст новую базу данных с именем baz.
6. Протестируйте baz, выполнив команду SQL в командной строке.
7. Введите: CREATE DATABASE my_foobar_db;.
В предыдущей процедуре шаги 4 и 5 выполняются на стороне сервера. Нужно ли
пользователю что-либо делать — неясно, в данном случае никаких действий со стороны пользователя не требуется, поэтому такие побочные эффекты лучше упомянуть
в описании шага 3. Также неясно, являются ли шаги 6 и 7 разными действиями. (Здесь
это не так.) Объедините все элементарные пользовательские операции в один шаг,
чтобы пользователь знал, что делать на каждом этапе процесса. Кроме того, если
ваше учебное руководство предлагает пользователю что-то ввести или проверить
какой-то вывод, поместите команды и примеры вывода в отдельные строки (например, используя соглашение об оформлении моноширинным жирным шрифтом).
Пример: улучшенная версия плохого туториала
1. Загрузите пакет с нашего сервера: http://example.com:
$ curl -I http://example.com

2. Скопируйте сценарий командной оболочки в свой домашний каталог:
$ cp foobar.sh ~

198  

Глава 10. Документация

3. Запустите сценарий в своем домашнем каталоге:
$ cd ~; foobar.sh

Система foobar соединится с системой аутентификации. Затем foobar создаст
новую базу данных с именем baz и откроет оболочку для ввода команд.
4. Протестируйте baz, выполнив команду SQL в командной строке:
baz:$ CREATE DATABASE my_foobar_db;

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

Концептуальная документация
Иногда требуется дать более глубокое описание кода, которое нельзя получить из
обычной справочной документации. В таких случаях мы пишем концептуальную
документацию, в которой даем обзор API или систем. Примерами концептуальной документации могут служить обзор API популярной библиотеки, описание жизненного
цикла данных на сервере и т. д. Практически во всех случаях цель концептуального
документа — дополнять, а не заменять справочную документацию. Часто это приводит к дублированию некоторой информации, но с важной целью: повысить ясность.
В концептуальном документе необязательно охватывать все худшие случаи (но они
обязательно должны быть перечислены в справочной документации). Здесь можно
пожертвовать точностью ради ясности.
«Концептуальные» документы являются наиболее сложными документами для
написания, поэтому инженеры-программисты часто пренебрегают ими. Эти документы невозможно встроить непосредственно в исходный код из-за отсутствия
канонического места для них. Наиболее подходящим местом для «концептуального»
объяснения обширного API является начальный комментарий в файле. Но нередко API используют другие API и/или модули, и единственное логичное место для
описания такого сложного поведения — отдельный концептуальный документ. Если
сравнить документирование с тестированием, комментарии будут похожи на юниттесты, а концептуальные документы — на интеграционные тесты.
Даже для узких API часто имеет смысл написать отдельный концептуальный документ. Например, библиотека Abseil StrFormat охватывает множество концепций,
которые должны понимать ее пользователи, и мы предоставляем документ с описанием концепции ее формата (https://oreil.ly/TMwSj), доступный как внутри библиотеки,
так и за ее пределами.
Концептуальный документ приносит пользу самой широкой аудитории, от экспертов
до новичков. Кроме того, он должен делать упор на ясность, поэтому для его создания
нередко приходится жертвовать полнотой сведений (описанных в справочной до-

Обзоры документации   199

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

Домашние страницы
Большинство инженеров являются членами команд, и у большинства команд есть
свои «домашние страницы» где-то в интранете компании. Часто эти страницы запутаны: типичная домашняя страница может содержать несколько интересных ссылок, иногда несколько документов под названием «Сначала прочтите это!», а также
некоторую информацию для команды и ее клиентов. Такие документы, первоначально полезные, быстро превращаются в одно сплошное бедствие; они постепенно
становятся слишком громоздкими, устаревают, и за их исправление берутся только
самые смелые или отчаянные.
К счастью, такие документы только выглядят пугающие, но на самом деле их легко
исправить: убедитесь, что домашняя страница четко сообщает о своем назначении,
и оставьте на ней только ссылки на другие страницы с более подробной информацией. Если домашняя страница выполняет какие-то дополнительные функции
кроме регулировки движения, то она явно выполняет не свою работу. Если у вас
есть отдельный документ с описанием установки, добавьте в домашнюю страницу
ссылку на него. Если на домашней странице окажется слишком много ссылок (домашняя страница не должна прокручиваться на несколько экранов), подумайте об
их классификации.
Часто домашняя страница служит двум разным целям: играет роль страницы «перехода» для тех, кто пользуется вашим продуктом или API, и является домашней
страницей для команды. Не позволяйте странице обслуживать двух хозяев — это
может сбить с толку. Создайте отдельную внутреннюю «страницу для команды» и отдельную главную домашнюю страницу. То, что нужно знать команде, часто сильно
отличается от того, что нужно знать пользователю API.

Обзоры документации
В Google весь код подвергается рецензированию, и наш процесс обзора кода вам уже
понятен. В общем случае документация также нуждается в рецензировании (хотя
это не общепринятый подход). Чтобы «проверить» качество вашей документации,
отправьте ее на обзор.
Технические документы подвергаются обзорам трех типов, каждый из которых преследует свои цели:
y Технический обзор для проверки точности обычно проводится экспертами
в предметной области или другими членами вашей команды часто в ходе обзора
кода.

200  

Глава 10. Документация

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

ПРИМЕР: РУКОВОДСТВО РАЗРАБОТЧИКА БИБЛИОТЕКИ
Как упоминалось выше, мы столкнулись с проблемами, обусловленными тем, что большая
часть (почти вся) технической документации находилась в общей электронной энциклопедии (Wiki). Среди них — отсутствие четко обозначенных владельцев, конкурирующая
документация, устаревшая информация и трудности с регистрацией ошибок. Но эти проблемы не коснулись руководства по стилю для C++, потому что арбитры стиля взяли на себя
заботу о нем. Их владение документом принималось безоговорочно. Кроме того, документ
был каноническим: в Google существовало только одно руководство по стилю для C++.
Как уже отмечалось, если документация находится рядом с исходным кодом, она обычно
является наиболее авторитетной (надеюсь) и становится канонической. В Google каждый
API обычно имеет отдельный каталог g3doc, в котором находятся канонические документы (в виде файлов в формате Markdown, доступных для чтения в нашем браузере Code
Search). Размещение документации рядом с исходным кодом не только устанавливает
фактическое владение, но и делает документацию «частью» кода.
Однако размещение некоторых наборов документов в исходном коде выглядит нелогично.
Например, для «Руководства разработчика на C++», созданного в Google, нет очевидного
места в исходном коде. Нет и главного каталога «C++». В таких случаях (и если документация выходит за рамки одного API) мы стали создавать отдельные наборы документов.
Многие из них объединяли существующие документы в общий набор с общей навигацией
и общим внешним видом. Такие документы маркировались как «Руководство разработчика» и, так же как код в кодовой базе, сохранялись в VCS, в специальном разделе для документации, причем этот раздел был организован по темам, а не по API. Поддержкой этих
руководств для разработчиков в большинстве случаев занимались технические писатели,
потому что они лучше справлялись с описанием тем, выходящих за рамки конкретных API.
Со временем эти руководства для разработчиков стали каноническими. Пользователи,
писавшие конкурирующие или дополняющие документы, начали стремиться добавлять
свои документы в канонический набор, а затем отказываться от своих конкурирующих
документов. В итоге руководство по стилю для C++ стало частью более крупного «Руководства разработчика на C++». Набор документации стал более полным и авторитетным,
и его качество улучшилось. Инженеры начали сообщать об ошибках, потому что знали
точно, что кто-то сопровождает эти документы. А поскольку документы хранились в VCS
и имели конкретных владельцев, инженеры также начали отправлять списки изменений
непосредственно техническим писателям.
Внедрение ссылок go/ (глава 3) упростило выделение каноничных документов по разным
темам. Например, наше «Руководство разработчика на C++» было опубликовано под
ссылкой go/cpp. Благодаря улучшенному внутреннему поиску, ссылкам go/ и объединению
документов наборы канонической документации со временем стали еще более авторитетными и надежными.

Философия документирования   201

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

Философия документирования
Внимание: следующий раздел — это скорее рассуждение (и личное мнение) о лучших методах написания технических документов, а не описание «как это делается
в Google». Понимание представленных идей, вероятно, поможет вам писать техническую документацию.

Кто, что, когда, где и почему
Большинство технических документов отвечают на вопрос КАК. Как это работает?
Как использовать этот API? Как настроить этот сервер? В результате инженеры-программисты склонны сразу переходить к разделу КАК в документе и игнорировать
другие вопросы: КТО, ЧТО, КОГДА, ГДЕ и ПОЧЕМУ. Да, они не так важны, как
вопрос КАК. Исключением является только проектный документ, потому что он
в большей степени посвящен ответу на вопрос ПОЧЕМУ. Но без надлежащей организации технические документы приводят к путанице. Попробуйте ответить на
другие вопросы, кроме КАК, в первых двух абзацах документа:
y КТО, как обсуждалось выше, — это аудитория документа. Иногда желательно
обозначить ее явно, например: «Этот документ предназначен для новых инженеров проекта Secret Wizard».
y ЧТО определяет назначение документа: «Этот документ является руководством
по запуску сервера Frobber в среде тестирования». Иногда раздел ЧТО помогает
правильно оформить документ. Информацию, не применимую к ЧТО, вы сможете
переместить в отдельный документ.
y КОГДА определяет дату создания, пересмотра или обновления документа. Документы в исходном коде датируются неявно, а некоторые другие схемы публикации
автоматически добавляют дату. Обязательно укажите в самом документе, когда
он был написан (или пересмотрен в последний раз).
y ГДЕ — это место хранения документа, которое часто подразумевается автором неявно. Обычно предпочтительнее использовать VCS, в идеале — рядом с исходным

202  

Глава 10. Документация

кодом, который документ описывает. Но можно использовать и другие хранилища. Мы в Google часто используем Google Docs, чтобы упростить совместную
работу, особенно с проектными документами. Однако в какой-то момент обсуждение любого общего документа заканчивается, и он становится хронологической
записью. В этот момент желательно переместить документ в более надежное
место, обеспечивающее права владения, управление версиями и ответственность.
y ПОЧЕМУ объявляет цель документа. Кратко опишите, что читатели смогут почерпнуть из документа. Хорошая практика — перечислить разные ПОЧЕМУ во
введении к документу. Когда вы будете писать заключение, проверьте, сбылись
ли ваши первоначальные ожидания (и внесите соответствующие правки).

Начало, середина и конец
Все документы — и все их части — имеют начало, середину и конец. Эти слова могут
показаться странными, но большинство документов должны содержать как минимум эти три раздела. Документ, включающий только один раздел, может охватить
только одну тему, при этом очень немногие документы действительно описывают
единственную тему. Не бойтесь добавлять разделы в документы — они разбивают
поток повествования на логические части и помогают читателям быстро оценить,
какие темы в документе представлены.
Даже в самом простом документе обычно рассматривается больше одной темы. Наши
популярные «Советы недели для C++» очень короткие и основное внимание уделяют одному небольшому совету. Однако даже в них деление на разделы приносит
дополнительные выгоды. Традиционно первый раздел описывает проблему, второй
рассматривает рекомендуемые решения, а в последнем подводятся итоги. Если бы
документ состоял только из одного раздела, читателям было бы трудно вычленить
в нем важные моменты.
Большинство инженеров ненавидят избыточность, и тому есть причины. Но в документации избыточность бывает полезна. Порой трудно заметить и запомнить важный
момент, спрятанный за стеной текста. С другой стороны, более раннее описание
такого момента в более заметном месте может привести к потере его контекста. Типичное решение этой проблемы состоит в том, чтобы кратко представить тот момент
во вступительном абзаце, а в остальной части раздела изложить свою точку зрения
более подробно. В этом случае избыточность поможет читателю понять важность
того, о чем говорится.

Признаки хорошей документации
Типичными признаками хорошей документации являются полнота, точность и ясность. Редко удается совместить все три признака в одном документе: например,
более «полный» документ, скорее всего, будет менее ясным. Документируя все варианты использования API, вы получите очень запутанный документ. В документах
с описанием языка программирования полная точность в отношении всех вариантов

Философия документирования   203

использования (и перечисление всех побочных эффектов) тоже может нанести ущерб
ясности. В других документах попытка прояснить сложную тему может повлиять на
точность. В концептуальном документе можно опустить редкие побочные эффекты,
потому что его цель — познакомить читателя с API, а не представить скрупулезный
обзор всех вариантов поведения кода.
В любом случае, «хорошим» можно считать документ, который соответствует
своему назначению. Поэтому нежелательно создавать документы с несколькими
назначениями. Определите направленность каждого документа (и каждый тип
документов) и пишите их соответствующим образом. Пишете концептуальный документ? Тогда вам не нужно расписывать API во всех деталях. Пишете справочник?
Тогда уделите внимание точности, пусть и за счет некоторой потери ясности. Пишете
домашнюю страницу? Сосредоточьтесь на ее организации и постарайтесь сократить
описательный текст до минимума. Все это — слагаемые качества, которое, по общему
признанию, трудно измерить.
Как быстро улучшить качество документа? Сосредоточиться на потребностях
ауди­тории. Часто чем меньше, тем лучше. Например, многие инженеры допускают
распространенную ошибку, добавляя описание проектных решений или деталей
реализации в документ по API. Так же как вы отделяете интерфейс API от его
реализации, избегайте обсуждения проектных решений в документе по API. Пользователям не нужна эта информация. Лучше опишите эти решения в отдельном
документе (обычно проектном).

Устаревшие документы
Проблемы может вызывать не только устаревший код, но и устаревшие документы.
Со временем документы устаревают и (нередко) забываются. Старайтесь не забывать документы, и если документ перестал служить своей цели, удалите его или
обозначьте как устаревший (и если возможно, укажите, куда обратиться за актуальной информацией). Даже добавить простое примечание «Это больше не работает!»
намного полезнее, чем оставить в неизменном виде документ, который выглядит
авторитетным, но больше не актуален.
Мы в Google часто включаем упоминание о «свежести документа». Такие упоминания
фиксируют дату, когда в последний раз документ пересматривался, и, основываясь
на ней, система сопровождения документации отправляет владельцу напоминания
по электронной почте, если документ не пересматривался, например, более трех
месяцев. Такие даты обновления, как показано в следующем примере, свидетельствующие об ошибочности документов, могут помочь упростить сопровождение
набора документации с течением времени:

204  

Глава 10. Документация

Владельцы таких документов получают стимул поддерживать актуальность даты обновления (а если документ находится под контролем VCS, еще и стимул пересмотреть
код). Это недорогое средство способствует периодической проверке документации.
Мы в Google обнаружили, что добавление в документ упоминания о его владельце
с подписью «Последний пересмотр...» также способствовало распространению практики пересмотра документации.

Когда привлекать технических писателей?
Когда Google была молодой и растущей компанией, в сфере программной инженерии
ощущалась нехватка технических писателей. (Впрочем, их не хватает и сейчас.) Те
проекты, которые считались важными, стремились привлечь к работе технического писателя независимо от того, была ли в этом необходимость. Идея заключалась
в том, что писатель должен был снять с команды часть бремени написания и ведения
документов и (теоретически) позволить важному проекту достичь более высокой
скорости разработки. Эта идея себя не оправдала.
Как показал наш опыт, большинство команд инженеров отлично справляются
с написанием документации для себя (своих команд), но когда речь заходит о документации для другой аудитории, инженеры ищут помощи технического писателя.
Петля обратной связи внутри команды при написании документов более короткая,
а знание предметной области и предполагаемые потребности более очевидны. Конечно, технический писатель часто лучше справляется с грамматикой и организацией
документов, но поддержка единственной команды — не лучшее использование такого
ограниченного и ценного ресурса, как технический писатель, поскольку такой подход
не масштабируется. В итоге появился неверный стимул: станьте важным проектом,
и вашим инженерам-программистам не придется писать документы. Отгораживание
инженеров от написания документов, как оказалось, — это совсем не то, что вам нужно.
Будучи ограниченным ресурсом, технические писатели, как правило, сосредоточены
на задачах, которые не должны выполняться инженерами-программистами в рамках
своих обязанностей. Обычно к таким задачам относится написание документов,
выходящих за рамки API. Команда проекта Foo может четко понимать, какая документация нужна, но с трудом представлять, что нужно проекту Bar. Технический
писатель лучше справится с ролью человека, не знакомого с предметной областью.
Фактически очень полезно оспаривать предположения команды относительно полезности проекта. Это одна из причин, по которой многие, если не большинство технических писателей, в сфере программной инженерии склонны концентрироваться
на конкретном типе документации по API.

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

Итоги   205

еще не является образцом для подражания. Для сравнения, инженеры постепенно
осознали, что тестировать необходимо любое изменение в коде, каким бы малым
оно ни было. Более того, в разные этапы технологического процесса были включены
разнообразные и надежные инструменты тестирования. Однако документации еще
далеко до этого уровня.
Впрочем, справедливости ради следует признать, что с документацией не обязательно
обращаться так же, как с тестированием. Тесты могут быть атомарными (юнит-тесты)
и соответствовать предписанной форме и функциям. Для документов это по большей
части невозможно. Тестирование можно автоматизировать, а методики автоматизации ведения документации часто отсутствуют. Документы всегда субъективны;
качество документа оценивается читателем, и зачастую спустя время. Тем не менее
уже есть понимание важности документации, и процессы, связанные с разработкой
документов, постепенно совершенствуются. По мнению автора этой главы, качество
документации в Google намного выше, чем в большинстве софтверных компаний.
Чтобы изменить качество технической документации, инженеры и организация
в целом должны осознать, что они одновременно являются и проблемой, и решением.
Вместо того чтобы закрывать глаза на состояние документации, они должны понять,
что создание качественной документации является частью их работы и экономит их
время и силы в долгосрочной перспективе. Документирование любого фрагмента
кода, который просуществует больше нескольких месяцев, поможет его поддерживать
не только другим, но и вам самим.

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

ГЛАВА 11

Основы тестирования
Автор: Адам Бендер
Редактор: Том Маншрек
Тестирование всегда было неотъемлемой частью программирования. Написав
свою первую программу, вы наверняка опробовали ее с несколькими примерами
данных, чтобы убедиться, что она работает так, как ожидалось. Долгое время тестирование ПО напоминало этот процесс, проводилось вручную и было подвержено
ошибкам. Однако с начала 2000-х годов подход к тестированию в индустрии ПО
претерпел значительные изменения, как того требовал рост размеров и сложности
программных систем. Центральное место в этих изменениях заняла автоматизация
тестирования.
Автоматическое тестирование способно предотвратить проникновение ошибок в дикую природу кода и их влияние на пользователей. Чем позже в цикле разработки
обнаруживается ошибка, тем дороже обходятся ее последствия, причем во многих
случаях эта дороговизна растет экспоненциально1. Однако «ловля жуков» является
лишь одним из мотивов для тестирования ПО. Независимо от того, добавляете вы
новые функции, выполняете рефакторинг для поддержки кода в здоровом состоянии или проводите переоценку ПО, автоматизированное тестирование поможет
быстро выявить ошибки и тем самым позволит с большей уверенностью вносить
изменения в ПО.
Компании вынуждены быстро адаптироваться к изменениям в технологиях, условиях рынка и вкусах клиентов. Использование надежной практики тестирования
избавит вас от страхов перед изменениями и станет для вас неотъемлемой частью
процесса разработки ПО. Чем чаще и быстрее вам потребуется менять свои системы,
тем выше будет ваша потребность иметь быстрый способ тестирования изменений.
Сам акт написания тестов способствует улучшению дизайна систем. Как первый клиент кода тест может многое рассказать о его дизайне. Не слишком ли тесно система
связана с базой данных? Поддерживает ли API требуемые варианты использования?
Обрабатывает ли система все крайние случаи? Написание автоматических тестов
помогает ответить на эти вопросы на ранних этапах разработки и делает ПО более
модульным и гибким.

1

См. статью «Defect Prevention: Reducing Costs and Enhancing Quality» (https://oreil.ly/27R87).

Почему мы пишем тесты?   207

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

Почему мы пишем тесты?
Чтобы лучше понять, как получить максимальную отдачу от тестирования, начнем
с самого начала. Что мы в действительности подразумеваем, говоря об автоматизированном тестировании?
Самый простой тест определяется:
y единственным тестируемым поведением, обычно методом или API;
y конкретными входными данными — значением, которое передается в API;
y наблюдаемым результатом или поведением;
y управляемой средой, такой как отдельный изолированный процесс.
Выполняя тест, передав входные данные в систему и проверив результат, можно
узнать, действует ли система так, как ожидается. Совокупность из сотен или тысяч
простых тестов (обычно называемая набором тестов) может поможет выявить несоответствия кода предполагаемому дизайну.
Создание и поддержка надежного набора тестов требуют больших усилий. Вместе
с ростом кодовой базы растет и набор тестов, что вызывает проблемы в их стабильности и скорости. Игнорирование этих проблем отрицательно сказывается на наборе
тестов. Имейте в виду, что главная ценность тестов заключается в доверии к ним со
стороны инженеров. Если продуктивность инженеров снижается из-за постоянной
поломки тестов и появления неопределенности, инженеры потеряют доверие к тестам и начнут пытатьс