Googleのソフトウェアエンジニアリング ――持続可能なプログラミングを支える技術、文化、プロセス (Titus Winters, Tom Manshreck, Hyrum Wright)
書籍情報
- 著者:Titus Winters(著), Tom Manshreck(著), Hyrum Wright(編), 竹辺靖昭(監訳), 久富木隆一(訳)
- 発行日:2021-11-26
- ISBN:9784873119656
- URL:https://www.oreilly.co.jp/books/9784873119656/
書籍目次
- 監訳者まえがき
- 序文
- はじめに
- 第1部 主題
- 1章 ソフトウェアエンジニアリングとは何か
- 1.1 時間と変化
- 1.1.1 Hyrumの法則
- 1.1.2 例:ハッシュの順序付け
- 1.1.3 「何も変化しない」状態をとにかく目指すのはどうか
- 1.2 スケールと効率
- 1.2.1 スケールしないポリシー
- 1.2.2 よくスケールするポリシー
- 1.2.3 例:コンパイラーのアップグレード
- 1.2.4 左への移動
- 1.3 トレードオフとコスト
- 1.3.1 例:ホワイトボードマーカー
- 1.3.2 意思決定への入力
- 1.3.3 例:分散ビルド
- 1.3.4 例:時間とスケールの間での決定
- 1.3.5 決定を再考すること、間違うこと
- 1.4 ソフトウェアエンジニアリング対プログラミング
- 1.5 結論
- 1.6 要約
- 1.1 時間と変化
- 1章 ソフトウェアエンジニアリングとは何か
- 第2部 文化
- 2章 チームでうまく仕事をするには
- 2.1 自分のコードを隠すのを手伝ってはくれないか
- 2.2 天才神話
- 2.3 隠蔽は有害とみなされる
- 2.3.1 早期発見
- 2.3.2 バス係数
- 2.3.3 進捗ペース
- 2.3.4 要するに、隠れるな
- 2.4 チームが全て
- 2.4.1 社会交流の三本柱
- 2.4.2 何故三本柱に意味があるのか
- 2.4.3 謙虚、尊敬、信頼の実践
- 2.4.4 非難なきポストモーテム文化
- 2.4.5 Google的であること
- 2.5 結論
- 2.6 要約
- 3章 知識共有
- 3.1 学びを阻む課題
- 3.2 哲学
- 3.3 舞台を整える:心理的安全性
- 3.3.1 メンター制度
- 3.3.2 大規模集団での心理的安全性
- 3.4 自分の知識を発展させる
- 3.4.1 質問を尋ねよ
- 3.4.2 文脈を理解せよ
- 3.5 質問をスケールさせる:コミュニティへの質問
- 3.5.1 グループチャット
- 3.5.2 メーリングリスト
- 3.5.3 YAQS:Q&Aプラットフォーム
- 3.6 自分の知識をスケールさせる:教えられるものは常にある
- 3.6.1 オフィスアワー
- 3.6.2 テックトークと講習
- 3.6.3 ドキュメンテーション
- 3.6.4 コード
- 3.7 組織の知識をスケールさせる
- 3.7.1 知識共有の文化を養う
- 3.7.2 カノニカルな情報源の確立
- 3.7.3 情報の輪に参加し続ける
- 3.8 リーダビリティ:コードレビューを通じての標準化されたメンター制度
- 3.8.1 リーダビリティプロセスとは何か
- 3.8.2 何故このプロセスがあるのか
- 3.9 結論
- 3.10 要約
- 4章 公正のためのエンジニアリング
- 4.1 バイアスこそがデフォルト状態である
- 4.2 ダイバーシティの必要性を理解する
- 4.3 多文化理解の能力を育む
- 4.4 多様性を行動可能なものにする
- 4.5 一本槍のアプローチは退けよ
- 4.6 確立されたプロセスを疑え
- 4.7 「価値観」対「結果」
- 4.8 好奇心を持って突き進め
- 4.9 結論
- 4.10 要約
- 5章 チームリーダー入門
- 5.1 マネージャーとテックリード(とその両方)
- 5.1.1 エンジニアリングマネージャー
- 5.1.2 テックリード(TL)
- 5.1.3 テックリードマネージャー(TLM)
- 5.2 IC役職からリーダーシップ役職への異動
- 5.2.1 恐れるべき唯一のものは……えっと、全てだ
- 5.2.2 サーバントリーダーシップ
- 5.3 エンジニアリングマネージャー
- 5.3.1 マネージャーとは四文字単語である
- 5.3.2 今日のエンジニアリングマネージャー
- 5.4 アンチパターン
- 5.4.1 アンチパターン:押しに弱い者を採用する
- 5.4.2 アンチパターン:成績の悪い者を無視する
- 5.4.3 アンチパターン:人間的問題を無視する
- 5.4.4 アンチパターン:全員の友人になる
- 5.4.5 アンチパターン:採用基準で妥協する
- 5.4.6 アンチパターン:自分のチームを子供のように扱う
- 5.5 建設的パターン
- 5.5.1 エゴを捨てよ
- 5.5.2 禅の老師となれ
- 5.5.3 触媒となれ
- 5.5.4 障害を取り除け
- 5.5.5 先生かつメンターになれ
- 5.5.6 明確なゴールを設定せよ
- 5.5.7 正直であれ
- 5.5.8 満足度を追跡調査せよ
- 5.6 予期しない質問
- 5.7 他のヒントや秘訣
- 5.8 人は植物のようなものである
- 5.8.1 「内発的動機付け」対「外発的動機付け」
- 5.9 結論
- 5.10 要約
- 5.1 マネージャーとテックリード(とその両方)
- 6章 スケールするリーダー
- 6.1 いつでも決定せよ
- 6.1.1 飛行機の比喩
- 6.1.2 目隠しを特定せよ
- 6.1.3 鍵となるトレードオフを特定せよ
- 6.1.4 決定し、それから反復せよ
- 6.2 いつでも立ち去れ
- 6.2.1 あなたのミッション:「自動運転」チームを構築せよ
- 6.2.2 問題空間の分割
- 6.3 いつでもスケールせよ
- 6.3.1 成功の周期
- 6.3.2 「重要」対「緊急」
- 6.3.3 ボールを落とすことを学べ
- 6.3.4 自分のエネルギーを保護する
- 6.4 結論
- 6.5 要約
- 6.1 いつでも決定せよ
- 7章 エンジニアリング生産性の計測
- 7.1 何故エンジニアリング生産性を計測すべきなのか
- 7.2 トリアージ:そもそも計測するほどの価値があるか
- 7.3 ゴールとシグナルを伴う、意味のあるメトリクスを選ぶ
- 7.4 ゴール
- 7.5 シグナル
- 7.6 メトリクス
- 7.7 メトリクスの検証にデータを用いる
- 7.8 行動に出ることと結果の追跡
- 7.9 結論
- 7.10 要約
- 2章 チームでうまく仕事をするには
- 第3部 プロセス
- 8章 スタイルガイドとルール
- 8.1 何故ルールを設けるのか
- 8.2 ルールを作る
- 8.2.1 指導原則
- 8.2.2 スタイルガイド
- 8.3 ルールを変更する
- 8.3.1 プロセス
- 8.3.2 スタイル調停者
- 8.3.3 例外
- 8.4 ガイダンス
- 8.5 ルールを適用する
- 8.5.1 エラーチェッカー
- 8.5.2 コードフォーマッター
- 8.6 結論
- 8.7 要約
- 9章 コードレビュー
- 9.1 コードレビューのフロー
- 9.2 Googleでのコードレビューはどのように機能しているか
- 9.3 コードレビューの恩恵
- 9.3.1 コードの正しさ
- 9.3.2 コードの意味の把握
- 9.3.3 コードの一貫性
- 9.3.4 心理的ならびに文化的な恩恵
- 9.3.5 知識共有
- 9.4 コードレビューのベストプラクティス
- 9.4.1 礼儀正しく、かつプロフェッショナルになれ
- 9.4.2 小さな変更を書け
- 9.4.3 良い変更説明を書け
- 9.4.4 レビュアーの人数は最小限にとどめよ
- 9.4.5 可能な場合は自動化せよ
- 9.5 コードレビューの類型
- 9.5.1 グリーンフィールドコードレビュー
- 9.5.2 挙動の変更、改善、最適化
- 9.5.3 バグ修正とロールバック
- 9.5.4 リファクタリングと大規模変更
- 9.6 結論
- 9.7 要約
- 10章 ドキュメンテーション
- 10.1 何がドキュメンテーションとして適格か
- 10.2 何故ドキュメンテーションが必要なのか
- 10.3 ドキュメンテーションはコードのようなものである
- 10.4 対象読者を認識せよ
- 10.4.1 対象読者の類型
- 10.5 ドキュメンテーションの類型
- 10.5.1 リファレンスドキュメンテーション
- 10.5.2 デザインドック
- 10.5.3 チュートリアル
- 10.5.4 概念的ドキュメンテーション
- 10.5.5 ランディングページ
- 10.6 ドキュメンテーションのレビュー
- 10.7 ドキュメンテーション哲学
- 10.7.1 誰が、何を、いつ、どこで、何故
- 10.7.2 始まり、中盤、終わり
- 10.7.3 優れたドキュメンテーションの特徴的要素
- 10.7.4 ドキュメントを廃止する
- 10.8 テクニカルライターが必要なのはどんなときか
- 10.9 結論
- 10.10 要約
- 11章 テスト概観
- 11.1 何故テストを書くのか
- 11.1.1 Googleウェブサーバーの物語
- 11.1.2 現代的開発速度でのテスト
- 11.1.3 書き、実行し、反応する
- 11.1.4 コードをテストする利点
- 11.2 テストスイートを設計する
- 11.2.1 テスト規模
- 11.2.2 テスト範囲
- 11.2.3 Beyoncéルール
- 11.2.4 コードカバレッジについてのメモ
- 11.3 Google規模でのテスト
- 11.3.1 大規模テストスイートの落とし穴
- 11.4 Googleでのテストの歴史
- 11.4.1 オリエンテーション講習
- 11.4.2 テスト認定プログラム
- 11.4.3 トイレでのテスト
- 11.4.4 今日のテスト文化
- 11.5 自動テストの限界
- 11.6 結論
- 11.7 要約
- 11.1 何故テストを書くのか
- 12章 ユニットテスト
- 12.1 保守性の重要さ
- 12.2 脆いテストを防ぐ
- 12.2.1 変化しないテストを目指す
- 12.2.2 公開API経由のテスト
- 12.2.3 相互作用ではなく、状態をテストせよ
- 12.3 明確なテストを書く
- 12.3.1 テストは完全かつ簡潔にせよ
- 12.3.2 メソッドではなく、挙動をテストせよ
- 12.3.3 テストにロジックを入れるな
- 12.3.4 明確な失敗メッセージを書け
- 12.4 テストとコード共有:DRYではなくDAMP
- 12.4.1 共有値
- 12.4.2 初期設定の共有
- 12.4.3 ヘルパーメソッドと検証メソッドの共有
- 12.4.4 テストインフラストラクチャーを定義する
- 12.5 結論
- 12.6 要約
- 13章 テストダブル
- 13.1 テストダブルの、ソフトウェア開発への影響
- 13.2 Googleでのテストダブル
- 13.3 基本概念
- 13.3.1 テストダブルの例
- 13.3.2 シーム
- 13.3.3 モッキングフレームワーク
- 13.4 テストダブル利用のためのテクニック
- 13.4.1 フェイキング
- 13.4.2 スタビング
- 13.4.3 インタラクションテスト
- 13.5 本物の実装
- 13.5.1 分離より現実に即することを優先せよ
- 13.5.2 いつ本物の実装を使うべきか決める方法
- 13.6 フェイキング
- 13.6.1 何故フェイクが重要なのか
- 13.6.2 どんな場合にフェイクが書かれるべきか
- 13.6.3 フェイクの忠実性
- 13.6.4 フェイクはテストされるべきである
- 13.6.5 フェイクが利用できない場合はどうすべきか
- 13.7 スタビング
- 13.7.1 スタビングを使いすぎることによる危険
- 13.7.2 スタビングが適切なのはどんな場合か
- 13.8 インタラクションテスト
- 13.8.1 インタラクションテストよりステートテストを優先せよ
- 13.8.2 インタラクションテストが適切なのはどんな場合か
- 13.8.3 インタラクションテストのベストプラクティス
- 13.9 結論
- 13.10 要約
- 14章 大規模テスト
- 14.1 大規模テストとは何か
- 14.1.1 忠実性
- 14.1.2 ユニットテストでよくある不足部分
- 14.1.3 何故大規模テストを備えないのか
- 14.2 Googleの大規模テスト
- 14.2.1 大規模テストと時間
- 14.2.2 Googleスケールでの大規模テスト
- 14.3 大テストの構造
- 14.3.1 テスト対象システム
- 14.3.2 テストデータ
- 14.3.3 検証
- 14.4 大規模テストの類型
- 14.4.1 相互に作用し合う1つ以上のバイナリの機能テスト
- 14.4.2 ブラウザーとデバイスのテスト
- 14.4.3 パフォーマンス、負荷、ストレスのテスト
- 14.4.4 デプロイ設定のテスト
- 14.4.5 探索的テスト
- 14.4.6 A/B差分リグレッションテスト
- 14.4.7 ユーザー受け入れテスト(UAT)
- 14.4.8 プローバーとカナリア分析
- 14.4.9 障害復旧とカオスエンジニアリング
- 14.4.10 ユーザー評価
- 14.5 大テストと開発者ワークフロー
- 14.5.1 大テストの作成
- 14.5.2 大テストの実行
- 14.5.3 大規模テストのオーナーとなる
- 14.6 結論
- 14.7 要約
- 14.1 大規模テストとは何か
- 15章 廃止
- 15.1 何故廃止するのか
- 15.2 何故廃止はこれほど難しいのか
- 15.2.1 設計中の廃止
- 15.3 廃止の類型
- 15.3.1 勧告的廃止
- 15.3.2 強制的廃止
- 15.3.3 廃止の警告
- 15.4 廃止プロセスを管理する
- 15.4.1 プロセスのオーナー
- 15.4.2 マイルストーン
- 15.4.3 廃止ツール環境
- 15.5 結論
- 15.6 要約
- 8章 スタイルガイドとルール
- 第4部 ツール
- 16章 バージョンコントロールとブランチ管理
- 16.1 バージョンコントロールとは何か
- 16.1.1 何故バージョンコントロールが重要なのか
- 16.1.2 「中央集権的VCS」対「分散VCS」
- 16.1.3 信頼できる情報源
- 16.1.4 「バージョンコントロール」対「依存関係管理」
- 16.2 ブランチ管理
- 16.2.1 進行中の作業はブランチに似ている
- 16.2.2 開発ブランチ
- 16.2.3 リリースブランチ
- 16.3 Googleでのバージョンコントロール
- 16.3.1 単一バージョン
- 16.3.2 シナリオ:複数の利用可能バージョン
- 16.3.3 「単一バージョン」ルール
- 16.3.4 存続期間の長いブランチを(ほとんど)なくす
- 16.3.5 リリースブランチについてはどうか
- 16.4 モノリポ
- 16.5 バージョンコントロールの未来
- 16.6 結論
- 16.7 要約
- 16.1 バージョンコントロールとは何か
- 17章 Code Search
- 17.1 Code SearchのUI
- 17.2 グーグラーはどのようにCode Searchを使うか
- 17.2.1 どこに
- 17.2.2 何を
- 17.2.3 どのように
- 17.2.4 何故
- 17.2.5 誰が、いつ
- 17.3 何故独立したウェブツールなのか
- 17.3.1 スケール
- 17.3.2 設定作業不要のグローバルコードビュー
- 17.3.3 専門化
- 17.3.4 他の開発者ツールとの統合
- 17.3.5 API公開
- 17.4 設計上でのスケールの影響
- 17.4.1 検索クエリーのレイテンシー
- 17.4.2 インデックスのレイテンシー
- 17.5 Googleの実装
- 17.5.1 検索インデックス
- 17.5.2 ランキング
- 17.6 選択されたトレードオフ
- 17.6.1 完全性:ヘッドにあるリポジトリー
- 17.6.2 完全性:「全部」対「最も関連性の高い結果」
- 17.6.3 完全性:「ヘッド」対「ブランチ」対「全履歴」対「ワークスペース」
- 17.6.4 表現力:「トークン」対「部分文字列」対「正規表現」
- 17.7 結論
- 17.8 要約
- 18章 ビルドシステムとビルド哲学
- 18.1 ビルドシステムの目的
- 18.2 ビルドシステムがないと何が起こるか
- 18.2.1 でも必要なのはコンパイラーだけ!
- 18.2.2 シェルスクリプトは救援となるか
- 18.3 現代的ビルドシステム
- 18.3.1 依存関係こそ全て
- 18.3.2 タスクベースのビルドシステム
- 18.3.3 アーティファクトベースのビルドシステム
- 18.3.4 分散ビルド
- 18.3.5 時間、スケール、トレードオフ
- 18.4 モジュールと依存関係を扱う
- 18.4.1 粒度の細かいモジュールの利用と1:1:1ルール
- 18.4.2 モジュールの可視性の最小化
- 18.4.3 依存関係の管理
- 18.5 結論
- 18.6 要約
- 19章 GoogleのコードレビューツールCritique
- 19.1 コードレビュー用ツール環境の原則
- 19.2 コードレビューのフロー
- 19.2.1 通知
- 19.3 第1段階:コード変更を作成する
- 19.3.1 差分作成
- 19.3.2 解析結果
- 19.3.3 緊密なツール統合
- 19.4 第2段階:レビューをリクエストする
- 19.5 第3段階と第4段階:コード変更の理解と、コード変更へのコメント付加
- 19.5.1 コメント付加
- 19.5.2 コード変更の状態を理解する
- 19.6 第5段階:コード変更の承認(コード変更のスコア付け)
- 19.7 第6段階:コード変更のコミット
- 19.7.1 コミット後:履歴の追跡
- 19.8 結論
- 19.9 要約
- 20章 静的解析
- 20.1 効果的な静的解析の特徴
- 20.1.1 スケーラビリティ
- 20.1.2 ユーザビリティ
- 20.2 静的解析を機能させる際に鍵となる教訓
- 20.2.1 開発者の幸福を重視せよ
- 20.2.2 静的解析を中心的な開発者ワークフローの一部とせよ
- 20.2.3 ユーザーにコントリビュートする権限を与えよ
- 20.3 Tricorder:Googleの静的解析プラットフォーム
- 20.3.1 統合されているツール
- 20.3.2 統合されているフィードバック経路
- 20.3.3 修正提案
- 20.3.4 プロジェクトごとのカスタマイズ機能
- 20.3.5 リポジトリー提出前処理
- 20.3.6 コンパイラー統合
- 20.3.7 コードの編集中と閲覧中の静的解析
- 20.4 結論
- 20.5 要約
- 20.1 効果的な静的解析の特徴
- 21章 依存関係管理
- 21.1 何故依存関係管理がそれほど難しいのか
- 21.1.1 競合する要件群とダイアモンド依存関係
- 21.2 依存関係のインポート
- 21.2.1 互換性の約束
- 21.2.2 インポートを行う際に考慮すべき事項
- 21.2.3 Googleはどのように依存関係のインポートを扱っているか
- 21.3 理論上の依存関係管理
- 21.3.1 何も変化しない(別名:静的依存関係モデル)
- 21.3.2 セマンティックバージョニング
- 21.3.3 バンドルされたディストリビューションのモデル
- 21.3.4 リブアットヘッド
- 21.4 SemVerの制限
- 21.4.1 SemVerは過大に制約を課す可能性がある
- 21.4.2 SemVerは過大に約束をする可能性がある
- 21.4.3 動機
- 21.4.4 最小バージョン選択
- 21.4.5 では、SemVerは機能するのか
- 21.5 無限のリソースがある場合の依存関係管理
- 21.5.1 依存関係のエクスポート
- 21.6 結論
- 21.7 要約
- 21.1 何故依存関係管理がそれほど難しいのか
- 22章 大規模変更
- 22.1 大規模変更とは何か
- 22.2 誰がLSCを扱うのか
- 22.3 アトミックなコード変更への障壁
- 22.3.1 技術的制約
- 22.3.2 マージ競合
- 22.3.3 幽霊の出る墓場をなくす
- 22.3.4 異種多様性
- 22.3.5 テスト
- 22.3.6 コードレビュー
- 22.4 LSCインフラストラクチャー
- 22.4.1 ポリシーと文化
- 22.4.2 コードベースの内部的知識
- 22.4.3 コード変更の管理
- 22.4.4 テスト
- 22.4.5 言語サポート
- 22.5 LSCプロセス
- 22.5.1 認可
- 22.5.2 コード変更の作成
- 22.5.3 シャード分割とリポジトリーへのコード提出
- 22.5.4 クリーンアップ
- 22.6 結論
- 22.7 要約
- 23章 継続的インテグレーション
- 23.1 CIの概念
- 23.1.1 高速なフィードバックループ
- 23.1.2 自動化
- 23.1.3 継続的テスト
- 23.1.4 CIの課題
- 23.1.5 密閉されたテスト
- 23.2 GoogleにおけるCI
- 23.2.1 CIケーススタディ:Google Takeout
- 23.2.2 だがCIを行う余裕がない
- 23.3 結論
- 23.4 要約
- 23.1 CIの概念
- 24章 継続的デリバリー
- 24.1 Googleでの継続的デリバリーのイディオム
- 24.2 速度はチームスポーツである:デプロイを管理可能な部分へ分割する方法
- 24.3 変更を分離して評価する:フラグによる機能の保護
- 24.4 アジャイル性を目指す:リリーストレインの構成
- 24.4.1 完璧なバイナリなどない
- 24.4.2 リリースの締め切りは守れ
- 24.5 品質とユーザー重視:使われるものだけをリリースせよ
- 24.6 左への移動:データ駆動の決定を早期に行う
- 24.7 チームの文化を変える:デプロイに規律を組み込む
- 24.8 結論
- 24.9 要約
- 25章 サービスとしてのコンピュート
- 25.1 コンピュート環境を手なずける
- 25.1.1 トイルの自動化
- 25.1.2 コンテナ化とマルチテナンシー
- 25.1.3 まとめ
- 25.2 マネージドコンピュート用ソフトウェアを書く
- 25.2.1 障害に備えたアーキテクチャー設計
- 25.2.2 「バッチ」対「提供」
- 25.2.3 状態管理
- 25.2.4 サービスへの接続
- 25.2.5 単発コード
- 25.3 長期的にスケールするCaaS
- 25.3.1 抽象化としてのコンテナ
- 25.3.2 1つのサービスは全てを統べる
- 25.3.3 リポジトリーへ提出される設定
- 25.4 コンピュートサービスを選択する
- 25.4.1 「中央集権化」対「カスタマイズ」
- 25.4.2 抽象化のレベル:サーバーレス
- 25.4.3 パブリック対プライベート
- 25.5 結論
- 25.6 要約
- 25.1 コンピュート環境を手なずける
- 16章 バージョンコントロールとブランチ管理
- 第5部 結論
- あとがき
- 訳者あとがき
- 索引