アメリカのグーグル本社に就職するまで

2020年３月末に、アメリカのグーグルにソフトウェア開発職で入社しました。
アメリカでは「How I got into Google!」みたいな投稿が流行っているので、自分も書いてみたいと思います。
## Background
アメリカの４大卒。専攻はコンピュータサイエンス。
女性エンジニア。東京の外資系IT企業で４年ほど働いた経験あり。
外資系IT企業のL1ビザで日本からアメリカに移住。その後結婚を通してグリーンカード取得。
在米合計１２年くらい。シリコンバレー在住。
英語は普通に話せる。むしろ日本語が怪しい。
Cracking the Coding Interviewの本は数年前に一通り勉強済み。
頭はあまり良い方ではないと思う。Slow thinker。新しいものを学ぶのに時間がかかる。
既婚で子持ち(３歳)。
Googleに入る前はスタートアップでData Engineering関係の仕事をしてた。

## 面接準備
シリコンバレーでソフトウェアエンジニアの面接を受けるなら、まずは[Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850)という本がおすすめ。シリコンバレーのテック企業はほとんどこの本で説明されている戦略に沿って面接をしているので。数年前に一通り解いたけど、結構難しくて３ヶ月くらいかかったと思う。

### コーディング面接
[leetcode.com](https://leetcode.com/)
ソフトウェア開発職のコーディング面接の練習といえばこれ。
2020年現在、合計1000問以上のコーデイング問題が投稿されていて、実際の面接でもほとんどこの中から同じ問題が出される。しかし全問解くのは非現実的なので、Leetcodeのサブスクリプションを払い、高確率で出題されている問題を解くのが醍醐味。
(2022年追記)ただしグーグルの面接ではLeetcodeと同じ問題はほぼ出ない。しかし過去に頻繁に出題された問題を対策してどんな問題にも対応できるようにしておけば大丈夫。

目標は45分以内にMediumレベルを２問、もしくはHardレベルを１問。
最初はMedium１問だけで１〜２時間かかるけど、慣れてくるとスラスラ解けるようになる。
しかしスラスラレベルに到達するまでの時間は人によってまちまち。自分は４ヶ月ほどかかったけど、友人の超天才頭の人は１ヶ月だとか。

自分は結局、完全に準備万端と思えるレベルに到達するまで300問解いた。Easy 80問、Medium 170問、Hard 50問くらい。
シニアレベルだとHardレベルの問題がよく出される。

#### 基本的なアルゴリズム
Binary Search, Recursive Tree Traversal (Inorder, postorder, etc), BFS, DFS, Quick Sort, Merge Sort
Must knowなアルゴリズム。３分以内でバグ無しで書けるのがマスト。

#### 基本ではないけども実はマストなアルゴリズム
Sliding Window, Iterative Tree Traversal, Quick Select, Union Find, Topological Sort
出題確率がとても高く、基本よりもやや難しいアルゴリズム。５分以内にバグ無しで書けるのがマスト。

#### 上級アルゴリズム
KMP, Dijakstra, Bellman-Ford, Largest Rectangular Area in Histogram
実装が難しく、どんなアルゴリズムか説明を求められたらやや苦戦するアルゴリズム。しかし出題確率が高く、これらを使えたら採用に王手がかかる。５分以内にバグ無しで書けると良い。

上級アルゴリズムは、シニアレベルだとマストかなと思う。
例えばグラフ関連の問題で、weightがnegativeだと使えるアルゴリズムはBellman-Fordしかない。

コーディングの練習する際、warm-upとしてランダムにアルゴリズムを選択し、どんなアルゴリズムか、BigO(計算量)を一通り言葉で説明。そして３分以内にアルゴリズムを実装する、という練習を毎日していました。

アルゴリズムを実装出来るのは前提条件として、自分のソルーションを明確に説明でき、面接官と討論してベストなソルーションを考え出して、お互いが納得してからコードを書き出すのがコーディング面接なので、会話力も必要。自分は[interviewing.io](https://interviewing.io/)という無料の面接練習サービスで何度も何度も練習した。(２０回くらい)

### 分散システムデザイン
大規模システムをデザインしろ、という面接。例えば一番簡単な例は[bitly.com](https://bitly.com)のシステムをデザインせよ。難しい問題だとFacebookのNewsfeedや[ticketmaster.com](https://www.ticketmaster.com/)など。シニアエンジニアとして応募するとより難しい問題が出されるらしく、きちんと面接官から問題のスコープを聞き出してベストなシステムをデザインするスキルが求められる、とても難しい面接。

仕事上、日頃から分散システムのデザインをする人に取っては良いけれど、ほとんどのエンジニアにはそんな機会がなく、とても対策がしづらい面接。お勧めの勉強方法は、
- [Designing Data-Intensive Application](https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321)という本
- Youtube (Gaurav Sen, System Design Interview, Tech Dummies) 自分は全部のビデオをみた笑
- [Grokking the System Design Interview](https://www.educative.io/courses/grokking-the-system-design-interview) 分散システムデザイン面接用の有料オンラインコース。どうアプローチすればよいか詳細を説明しているのでとても役立つ勉強ツールだけれども、2020年現在ソルーションが古いかなと思う。
- 有料の面接練習サービス。自分はExpertMitraというサービスを使った。

面接でのディスカッションポイントとしては、
-　DBはリレーショナルDBかNoSQL、どちらを使うか。
-　DBのインデックスをどう組むか(2022年追記)
-　どうスケールアップするか
-　どうFault Tolerenceにするか
-　どうパフォーマンスを向上させるか
-　Cloud nativeの設計(2022年追記)

具体的には、DBはMySQL, MongoDB, Cassandora, ElasticSearchなど、キャッシュはRedis、Messaging QueueはKafkaなど、一通り使って特徴を説明できるようにした。
あとはMapReduceやApache Spark、Load Balancerなども勉強した。

自分の知識が十分なのか分からずとても不安な分野なので、有料の面接練習サービスがとても役立った。

## グーグルのソフトウェアエンジニアの採用について
大卒すぐなら、コーディング面接とBehavioral(性格や行動分析)面接のみ。
職務経験有りでシニアを目指すならコーディング面接＋分散システムデザイン＋Behavioral面接。

コード面接が一番重要で、シリコンバレーのテック企業の中で最も難しいと思われる。

## 自分の準備期間
合計６ヶ月。
フルタイムで開発職をしていて、３歳児をもつワーキングマザーなのでそれはもう大変な毎日。
平日は子供が就寝後に３時間勉強、休日は３〜４時間。
娘の寝かしつけをほぼ６ヶ月間してくれた夫には大感謝。

## 挑戦してみたい方
日本のグーグルにも開発チームがあり、アツいです。
もし海外で働いてみたいなら日本支社に入社して海外に移籍するという方法もあり。
アメリカで既にH1ビザもしくはグリーンカード・アメリカ国籍所持の方は、是非挑戦してみてください。準備をしっかりすればそんなに難しくないと感じたので。
ちなみにAmazonとFacebookも受けましたが、システムデザイン面接が難しすぎて落ちました笑