---
# System prepended metadata

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

---

# Googleのソフトウェアエンジニアリング
### 近況報告
仕事は相変わらずボチボチやってます。
会社の組織が大きく変わりました。
部長、課長も変わりました。

プライベートでは、何か熱中できる趣味を探してます。
しいて言えばサウナですが、ここ最近行けてない......


### 紹介する書籍
https://www.oreilly.co.jp/books/9784873119656/

全体的に、Googleの考えに関する話が多いです。
明日からすぐに使える技術的なネタがないので、ふーん程度に聞いていてください。
※Googleだからできること。自分たちには応用できないことも多かったです。

### 本書で扱われていないもの
以下の項目はソフトウェア開発上の重要な問題も多いが，本書では扱わない
* プロジェクトマネジメント
* ソフトウェア設計
* セキュリティ強化
* 国際化
* ユーザーインターフェースフレームワーク
* プログラミング言語特有の懸念点

## プログラミング vs ソフトウェアエンジニアリング
プログラミングとは、コードを生産する即時的行動である。
ソフトウェアエンジニアリングとは、コードを一定期間保守性高く保ち、チームを横断した共同作業を可能とする、ポリシー、プラクティス、ツールのセットである。




* 時間
    * プログラミング
        * 新しいソフトウェアを作成する方法。
        * 一度書いたら終わり
        * 動作することを目指す
    * ソフトウェアエンジニアリング
        * 「開発」「保守」「修正」と、プログラミングに時間軸を加えたもの
        * 一定期間ソフトウェアは維持される
        * 保守性が高いことを目指す

* スケールと効率
    * プログラミング
        * 個人の作業
        * 1台のワークステーション
    * ソフトウェアエンジニアリング
        * 複数人での作業
        * 複数台のワークステーション


* トレードオフ（意思決定の複雑さ）
    * プログラミング
        * ベストプラクティスがわかりやすい
    * ソフトウェアエンジニアリング
        * ある判断とそれに伴う作用が複雑であり、トレードオフを評価して判断する
        * 資金、CPU時間、人件費、処理コスト、機会コスト、社会コストなど様々な観点をもとに判断する

## 本書の構成
文化、プロセス、ツールの3部に分かれて構成される
* 文化
    * チームで働くとは、心理的安全性、知識共有、多様性理解、**チームリーダー論**、エンジニアリング生産性
* プロセス
    * スタイルガイド、コードレビュー、ドキュメンテーション、**テスト**（単体テスト、ダブルテスト、大規模テスト）、廃止
* ツール
    * **バージョン管理システム**、Code Search、ビルドシステム、コードレビューツール、静的解析、依存関係管理、大規模変更、CI/CD、サービスとしてのコンピュート

## チームリーダー入門
### マネージャーとテックリード
#### エンジニアリングマネージャー
人員管理を専門に行うマネージャーを、ピープルマネージャーという。
多くの企業が、エンジニアリングチームの運営にピープルマネージャーを置いている。
しかし、Googleは早い段階からエンジニアリング経験を積んだ者をマネージャーに採用、もしくは訓練してマネージャーとしている。

#### テックリード
多くのテックリードは、管理職ではなく、部下を持たない。
しかし、技術的な決定、選択、アーキテクチャ、優先度、開発速度、プロジェクト管理全般に責任を持つ。
作業を他人にアサインすることもあるし、自分で手を動かすこともある。


### マイクロマネジメンとは絶対ダメ
#### サーバントリーダーシップ
人間はマネージャーになると部下を管理したくなるのが性。
伝統的な「管理」をしてはいけない。
「サーバントリーダーシップ」として、リーダーシップ、影響力、チームに仕えることに集中すべし。
チームがうまく仕事できるように、執事や家政婦の気持ちでチームに使えることである。
煩雑な事務手続き、チームの合意形成の手伝い、残業しているチームメンバーの夕食を買ってくるなど、なんでもやることだ。

### リーダーのアンチパターン
* 押しに弱いものを採用する
* 成績の悪いものを無視する
* 人間的問題を無視する
* 全員の友達になる
* 採用基準で妥協する
* マイクロマネジメントする

### 建設的パターン

* チームメンバーに対して謙虚であり、信頼し、尊敬する
* 平静を保ち続ける（アンガーマネジメントする）
* 合意形成の触媒となる（ファシリテーションする）
* 自前作業はやらず、可能な場合は委譲、必要であれば育成する
* 明確なゴールを設定する

## テスト
テスト規模
* 小テスト（ユニットテスト、単体テスト）
    * 単一のプロセス内で実行する
    * ビジネスロジックを検証する
    * テストの80%は小テスト
    * DBアクセスできない、ネットワークアクセスできない、Sleepできない、IO操作を実行できない
        * これらの操作が必要な際は、テストダブル（モック）を使用する
* 中テスト（インテグレーションテスト、結合テスト）
    * 単一のマシン内で実行する
    * 2つ以上のコンポーネント間の連携を検証する
    * テストの15%は中テスト
    * ネットワーク呼び出し、DB呼び出しが可能
    * 例
        * DBインスタンスとの連携テスト
        * ウェブUIとサーバの連携テスト
* 大テスト（エンドツーエンドテスト、システムテスト）
    * 複数マシンにわたるテスト
    * コードの機能ではなく、設定項目を検証
    * テストの5%は大テスト

### Googleにテスト文化を根付かせた小話
#### 新人研修
Googleにいた初期のエンジニアはテストを忌避する傾向にあった。
テストを根付かせたいGoogleは、当時のGoogleの事業拡大速度だと、新人エンジニアの人数が既存メンバの人数をすぐに超すという予測を利用した。
具体的には新人研修にて、テストの価値・重要性について、まるで社内標準であるかのようにレクチャーした。
研修を終えた新人は、配属後のチーム内にて自発的にテストを書くようになり、テストを書いていないエンジニアを問いただすようになった。
2年もすると、テストについて教育を受けたエンジニアの数が上回り、Googleにテストの文化が根付かせることができた。
新人たちをトロイの木馬のように扱ったのだ。

#### テスト認定プログラム
テストプロセスの成熟度診断を実施し、四半期ごとにチーム内のテスト成熟度を向上させるプログラムを実施した。
全チームのテスト成熟度をダッシュボードで可視化し、チームが互いに競って成熟度を上げていくのを促進した。

#### トイレでのポスター
全従業員が1日1度は使うトイレに、テストに関する啓発ポスターを全個室に掲示した。
社内メーリスだと大量メールに埋もれてしまうが、トイレでのポスターは効果が大きかった。

#### ツールを用いた継続的可視化
テストカバレッジやテストレイテンシーなど、プロジェクト内のテスト健全性を計測するツールを開発し、継続的に可視化する仕組みを導入した

### ユニットテスト
要約
* 変更しないテストを目指せ
* 公開API経由でテストせよ
* 相互作用ではなく、状態をテストせよ
* メソッドではなく、挙動（ビジネスシナリオ）でテストせよ
* テスト対象の挙動にちなんでテストに命名せよ
* テストにロジックを入れるな
* 明確な失敗メッセージをかけ
* テストコードはDRYよりDAMPに従え
 
#### 公開API経由のテスト
公開APIとは、Javaならpublicメソッド、Pythonなら名称の前にアンダースコアがついていないメソッドのこと。
公開API経由のテストは、実装詳細に対するテストより優れている。
たとえば、ヘルパークラスの関数は、それ自体をユニットテストすべきでない。
ヘルパー関数を利用するAPI（メソッド）を介してテストする

#### メソッドではなく、挙動をテストせよ
挙動（ビジネスシナリオ）ごとに、テストコードは書くべし

#### 
テストのメソッド名で挙動がわかるようにすべし。
    〇 口座間の送金テスト
    × テスト01
ソースコードの構造（if文など）に合わせたテストコードは、時間の経過とともに複雑性が増しやすい。

#### テストコードはDRYよりDAMPに従え
一般的にソースコードはDRY（重複を排除）が推奨される。
（ソースコード重複を検出するために、コードクローン検出という技術もある）
テストコードではDRYではなく、DAMP（説明的かつ意味が分かりやすい説明）が推奨される

## バージョンコントロールとブランチ管理
### 中央集権的VCS vs 分散VSC
#### 中央集権的VCS
単一の中央リポジトリがあるモデル
CVSやSubversionなど

#### 分散VCS
リポジトリが分散しているモデル
GitやMercurialなど

### 信頼できる情報源
中央集権的VCSは「信頼できる情報源」を技術的にサポートする。
分散VCSは「信頼できる情報源」を技術的にサポートできないため、ポリシーで解決する。
（Githubのmainブランチを信頼できる情報源とする。など）

### Googleでのバージョンコントロール
単一のリポジトリ（モノリポ）で管理されている
中央集権的集権的VCSを内製している
マイクロサービスで稼働している

80TB以上のデータを世界中のGoogleに提供
1営業日当たり6万回から7万回のコミット

#### 単一バージョン
組織の効率にとって、驚くほど重要なルール。

リポジトリ内の全依存関係について、その依存関係の選択すべきバージョンは1つしか存在しない
これにより、ライブラリの依存関係のバージョンが古い問題が発生しなくなる


#### モノリポ
2016年にモノリポに関する論文を発表
[Why Google Stores Billions of Lines of Code in a Single Repository]([https:/](https://cacm.acm.org/magazines/2016/7/204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository/fulltext#:~:text=The%20Google%20codebase%20includes%20approximately,nine%20million%20unique%20source%20files.)/)

モノリポのメリットは、単一バージョンのルール順守がやりやすくなる
単一バージョンという思想を強固に守る手段として、モノリポを採用した

モノリポのデメリットとして、スケールしにくい問題がある。
この問題を解決するため、GoogleではVCSを内製している。

モノリポとメニーレポ（多数のリポジトリ）は、一長一短である。
OSSコミュニティの場合は、メニーレポに利がある。
しかし、企業のような組織では、モノリポが扱いやすい。
モノリポの利点は、Microsoft、Netflix、Uberも公言している。
Gitの過去数年の主要な改善点を眺めると、モノリポのトレンドに追いつこうとしていることが見て取れる。

## 本を読んだ感想
Googleだからできる。といった内容が多い。
弊社で世間のデファクトスタンダードを無視して、独自のバージョン管理システム内製しはじめたら、断固反対する。
それをやってのけるGoogleの資金力と人材の技術力に感服した。

今回紹介した内容以外にも、自分の常識と全く異なる内容が多かった。
こういう海外の最先端の企業が、次の時代のデファクトスタンダードを作っているのだと感じました（こなみ）


## 参考文献
人月の神話
https://www.amazon.co.jp/dp/B0998ZTVTD/

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム
https://amazon.co.jp/dp/4873117917/
