👶

Googleソフトエアエンジニアリング 読書メモ

2022/01/17に公開

図書館で "Googleソフトエアエンジニアリング(649ページ)[1]"を借りたので、段落要約(段落ごとに要約する読み方)したのでメモしておく📘
本書は、各章に結論要約があるので、これらだけを読んでもいいもしれない。

Googleのソフトウェアエンジニアリング

第1部 主題

1章 ソフトウェアエンジニアリングとは何か

「ソフトウェアエンジニアリング」は「プログラミング」とは全く違って、長期間のシステム運用保守を考える。プログラミングはコードを作ることであり、短いライフサイクル(サンプルや検証など)の場合も多い。サンプルや検証で使うコードは、商用で使うコードとは次元が違うということである。なるほど。

第2部 文化

2章 チームでうまく仕事をするには

ソフトウェアエンジニアリングはチーム戦。チームは良い人たち(謙虚、尊敬、信頼が実践できる人)の集まりでないと良いチームは生まれない(もちろん、自分もそうあるべき)。

3章 知識共有

知識共有の難しさは経験済み。ちょっとしたことを質問できる仕組み(または検索できる仕組み)が必要。SlackやTeamsなどで履歴を残せれば、あとでドキュメントしやすい。

4章 公正のためのエンジニアリング

バイアスことがデフォルトであるとのこと。グローバルにサービスを提供している企業は特に、多様性をもってユーザをことを考え設計をすべし。

5章 チームリーダー入門

  1. エンジニアリングマネージャ: 人の管理(一般的にエンジニアリングの知識はあまりない)を担当
  2. テックリード(TL):技術的な決定(アーキ、製品、優先度、開発速度、プロジェクト管理補佐)を担当
  3. テックリードマネージャ(TLM):1.2.の両方を担当(小規模の場合)

アンチパターンの1つに「全員の友人になる」があるが、若いころはやっていた。リーダは管理というなの"ケツたたき"ではなく、リーダーシップ、影響力、チームに仕えることに集中せよ
そして、メンバができることは仕事を移譲すべしともあるが、これは状況に応じてかな。

6章 スケールするリーダー

いつでも決定せよ。トレードオフ、メリット/デメリットを整理して方向性を定めるべきということだろう。
いつでもスケールせよ。自分の時間、注意力、フィジカル、メンタルなどを自己管理し、いつ責務(作業)が増やせる状態にしておく。

7章 エンジニアリング生産性の計測

生産性を計測できても、その結果(OK/NGでも)を受けてどういった行動をするのか?が不明である場合は、計測の意味はあまりない。

メトリクス(評価項目)を選択し、定性的、定量的に生産性を測定する。
定性的な内容はアンケート調査メカニズムを備える。

第3部 プロセス

8章 スタイルガイドとルール

可能な限りルールの強制は自動化する。ただし、全てがルールとなるべきではない。

9章 コードレビュー

コードレビューは知識共有など多くの恩恵がある。自動化がとても重要であり、変更自体が小さい規模(200ステップ程度)にすることでデビュー負荷が軽減される。これは github のコミットの単位を小さくし、かつコメントの内容を読者に伝わるように意識して書くことが重要だと思った。

10章 ドキュメンテーション

ドキュメンテーションはとても重要である。様々なドキュメンテーションが存在するが、自分自身のために書くべきではなく対象読者に向けて書くべき。

11章 テスト概観

自動テストはテストをスケールするために必須である。Google では E2Eテスト5%、インテグレーションテスト15% 、ユニットテスト 80%の割合で実施されているようだ。

12章 ユニットテスト

ユニットテストはクラス、メソッドなど小さい単位で実施し、公開API(publicメソッドなど)経由でテストする。
理想的には変化しないテストコードを書くこと。すなわち、1. 純粋なリファクタリング 2.新機能 3.バグ修正 4.挙動の変更 でテストコードの修正が不要であることが理想的。
挙動を強調するテスト構成を意識する。

// XXX という前提条件下で
// XXX の場合は、
// XXX すべきである。

テストコードは(多少冗長的でも)説明的かついみがわかりやすい言い回しにしたほうが良い。

13章 テストダブル

テストダブルとは、本物の実装をつとめる代役を務めることができるオブジェクトまたは関数のこと。
テストコードはテストダブルより本物の実装が優先されるべき。本物の実装が利用できないなら、モックなどでフェイク(本物と同じ挙動をするオブジェクト)が理想的な解法である場合が多い。

14章 大規模テスト

大規模テストはユニットテストが扱えないものを扱う。
大規模テストには、ブラウザ、デバイス(スマホなど)のテスト、パフォーマンステスト、リグレッションテスト、ユーザ受け入れテスト、障害復旧(異常系)テスト、カオスエンジニアリング、ユーザ評価などがある。

15章 廃止

コードは債務であり資産ではないという基本的前提からはじまる。
旧システムをメンテするほうが低コストであるが、世の中の変化に応じて
新システムを構築するほうがメリットがでるタイミングが来ることが多いが
何かを撤去するのは構築するより難しい。(設計者の意図をくむ必要があるため)

第4部 ツール

16章 バージョンコントロールとブランチ管理

バージョンコントロールはあらゆるソフトウェア開発プロジェクトで用いられるべきである。
単一バージョンルールは有効な手段であり、「どこにマージすべきか?」、「そのリポジトリに依存すべきか?」についての選択の余地を無くすことで
単純化に結びつく(非生産的な作業を軽減できる)。

google では Code Searchを使用し、開発者による高度の理解を支援している。 これによってエンジニアの生産性が大きく押し上げられる。

18章 ビルドシステムとビルド哲学

エンジニアの権力と柔軟性を制限することを生産性が向上する場合がある(CI/CDの仕組みである程度制限をかけるということか?)
アーティファクト中心に構成されているビルドシステムのほうが信頼性も高い傾向にある。

19章 GoogleのコードレビューツールCritique

信頼とコミュニケーションこそがコードレビュープロセスにとって中核となるもの。

20章 静的解析

静的解析ツールを突っ込み従わせるのではなく開発者の幸福(作業が楽になること)を重視すべき。
静的解析を中心的な開発者ワークフローの一部とする。
開発者に静的解析ツールのルール変更などをさせる権限をもたせるべき。

21章 依存関係管理

依存関係管理の問題より、組織のコードが協調できることが大切。
セマンティックバージョニング(1.5.3 のように メジャー、マイナー、パッチとするやり方)が一般的。

22章 大規模変更

大規模変更:LSC(large-scale change)は、習慣になるほど常々行うことになる。
リファクタリングの伝統的なモデルはスケールが大きくなると破綻する。

23章 継続的インテグレーション

  • コード変更ライフサイクル

コードの存在期間が長くなる/スケールするについて、CIは必要性を増す。
CIはアラートであり、早い段階で問題を見つけ出す。
アクセス可能かつ行動可能なフィードバックがあれば、CIを更に効率化できる。

24章 継続的デリバリー

継続的デプロイを可能にする構造を単に設置しておくだけで、例え継続的デプロイによるリリースをユーザーに対して実際には出さないとしても、価値の大部分が発生する。
変更は分離して評価すべきである。
より早いほうがより安全である。

25章 サービスとしてのコンピュート

スケールするには共通インフラストラクチャー(kubernetesなど)が必要。
これは標準化され安定した抽象化と環境とを提供する。
ただし、提供される抽象化のレベルが適切なものとなるよう考慮が必要。

脚注
  1. https://www.oreilly.co.jp/books/9784873119656/ ↩︎

Discussion