新卒のソフトウェアエンジニアとして Google に入社して丸 6 年が過ぎました。「若者は 3 年で辞める」という話があるけど、その二倍も働いていることになります。当時の気持ちを忘れないうちに今までの振り返りをしてみようと思います。

(2019/04/04 追記) 入社までの話を「新卒のソフトウェアエンジニアになるまで」という記事に書きました。

なお、すべて個人的な体験談であって会社の見解等を表しているわけではありません。

きっかけ

Google を意識したきっかけは大学一年生の頃に読んだ梅田望夫さんの『ウェブ進化論』でした。多分同世代の多くの人がこの本に影響を受けたんじゃないかと思います。私も「これからネットの世界はどんどん変わっていくんだ!」と興奮し、その中心的な会社だった Google に憧れを持ったことを覚えています1

直接的なきっかけは修士一年生の頃。そろそろ就活に向けて動かないとまずいかなと思ってぼんやりインターン情報を眺めていたら、Google の募集がたまたま目に留まりました。ちょうど締め切り最終日だったので慌てて申し込みました。

面接場所は渋谷のセルリアンタワーにある旧オフィス。コーディングを含む技術面接を受けたのはこれが初めてでとても緊張しました。

インターン

幸いにも面接を通過して二ヶ月間東京オフィスで働くことになりました。インターンが始まる頃には六本木ヒルズの新オフィスに移転済みでした。六本木ヒルズといえばバブリーなヒルズ族の印象が強かったので服装をどうしたもんかと悩んだのですが、人事の方に聞いてみたら「服を着てれば何でも良いです」と言われてそんな馬鹿なと思いながら出社したら、みんな T シャツ・ジーンズ・サンダルというラフなスタイルでした。会社というより研究室みたい。

インターン貼り紙

プロジェクトは Chrome OS のチームで Mozc を使った文字入力 UI の改善をやりました。Chrome OS は C++ で書かれています。インターンに来た頃はバージョン管理ツールを使ったチーム開発の経験はないし、C は書けるけど C++ は全然みたいな感じで、本当にやっていけるのか不安でした。

インターン中は色々なことを経験しました。例えば Chrome OS 内で使われていた独自 UI コンポーネントの使い方がいくらネット検索しても出なくて、検索エンジンの会社で働いてるのに検索しても解決法が出てこないことにちょっとした衝撃を受けました。開発中の独自の仕組みなので情報が少ないのは当たり前ではあるのですが、検索して見つけたパーツを組み合わせてプログラミングをするのが普通だった当時の自分にとっては考え方が変わる出来事でした。おかげで自分で道を切り拓きながら開発をしていく逞しさのようなものが身につきました。これは今の仕事にも大いに役立っています。

もちろん社内には詳しい人がたくさんいるのでその人たちに聞けば解決することも多くあります。最初は誰に聞けばいいのか分かりませんでしたが、メンターにいろんな人を紹介してもらって、誰がコンタクトパーソンなのかちょっとずつ分かるようになりました。チームで働くには誰がどんな情報を持っているのか把握しておくことも大切なんだと学びました。社員の人達は質問すると「Good question!」と言ってくれるので、何だか自分が承認されているようでとても気分良く質問できました2

他にも色々ありました。コードレビューはコメントの量に圧倒されて、コードレビューの夢を見るほどでした。初めてのパッチをコミットしたらチームメンバーが「おめでとう!」と祝福してくれて嬉しかった。海外の人とのミーティングでは “Daemon” の発音が聞き取れなくて何度も聞き返したのが悔しかった。生まれて初めて英語の夢を見ました。

インターンはとても楽しかったです。お金を貰って3楽しくコードを書いて著名なエンジニアにコードレビューしてもらえるのは控えめに言って最高の体験でした。

最初の三ヶ月

インターンが終わり、その後の入社面接も通過して晴れて正社員として働き始めました。最初はクローズドソースのチームに配属されました。

アメリカ本社

入社してすぐにアメリカのマウンテンビュー本社に一ヶ月間出張しました。入社前から知らされていたので、パスポートや国際運転免許証などを用意して準備はしてありましたが、いざその時が来るととても不安でした。案の定アメリカでの生活は苦労の連続で、特に不慣れな車の運転と食事の注文が大変でした。車は到着初日にレンタカーをポールにぶつけました。大変だったけど、観光に行ったりご飯を食べ歩いたり、色々経験できました。初給料日はアメリカにいたので銀行口座が確認できず、帰国するまで本当に給料が払われてるのか心配でした。

新入社員的なやらかしとしては、入社して早々に検索チームの超偉い人に間違ってコードレビューを頼んで冷や汗をかいたのが思い出です。チームにいる同名の人に頼むつもりがオートフィルで違う人に頼んでました。「間違えました」ってメールを送ったらとてもフレンドリーなメールが返ってきました 4

Chrome チームへの異動 - Filesystem API

インターン時の経験からオープンソースのチームで働きたいという気持ちが高まり、Chrome ブラウザのチームへ異動しました5。最初に関わったのは Filesystem API のプロジェクトです。Filesystem API はウェブページからユーザのローカルのサンドボックス化された領域にファイルを読み書きできる API で、その名の通りファイルだけでなくディレクトリ操作も行えるものです。ディレクトリと言っても、ネイティブのファイルシステムのディレクトリではなく、LevelDB を使って inode のようなものを作って疑似的に実装されています。

これはかなり面白い API でした。Windows のファイルシステムの挙動に悩まされたり、Mac OS X のファイルシステムのユニコード正規化で苦しめられたり、いろいろな OS のファイルシステムについて学べました。残念ながら Filesystem API は deprecated になってしまったけれど、ネイティブにあってウェブにない機能を作っていく流行のさきがけだったように思います。

Filesystem API チームでは他に Quota Management API を作っていました。Filesystem API などのストレージ系 API はディスクに書き込める容量 (クォータ) が制限されているのですが、それを追加で要求したり情報を取得するための機能が Quota Management API です。私は残念ながらお蔵入りになってしまったバージョン 2 の実装をやっていました。バージョン 2 は当時としては超最新の Promise を使った API で、Promise の挙動に悩みながらちょっとずつ実装していました。ちなみに Quota Management API も既に deprecated になっていて、現在は Storage API でクォータ使用量などの確認が行えます。

その他にも Native Client などで使われていた Pepper API 用のファイルシステムを作ったりもしていました。はまじさんが書いていたとおり、ARC が POSIX に沿った API を必要としてたこともあってバックエンドは Filesystem API のまんまで POSIX をエミュレートできるような API を書きました。これも POSIX の仕様書とにらめっこしたり、Pepper API 特有のリソース管理を学びながら実装してなかなか楽しかったです。

そんなこんなでパッチ数を稼ぎ、誕生日に Chromium のコミッターになりました。

状態同期との戦い - Sync Filesystem API

次に Sync Filesystem API の実装に関わりました。Sync Filesystem API は Chrome Apps 固有の API で、ざっくり言うと Filesystem API でローカルに書き込むと自動的に Google Drive に同期してくれるという代物です。自分は主にローカルからリモートへのファイル同期の部分を担当しました。これはかなり苦心した API でした。Google Drive が同名のファイルやディレクトリを許すのでローカルのファイルシステムのツリー構造をリモートにマッピングするのに手間がかかったり、ファイルが消えるのはまずいので不測の事態には安全側に倒すように調整したり、それらをカバーするテストケースを頑張って書いたり、サーバとマルチクライアント間での状態同期にはかなり手こずりました。

この機能は Google IO 2013 (Video, Video) といったイベントや、TechCrunch といった外部のニュースメディアなどでも取り上げられて、自分たちが作った機能が世界中で使われていることにとても興奮しました。このプロジェクトを通して、Web API の仕組みや複数クライアント間のファイル同期の難しさなどを学びました。あとローカルのメタデータの管理に LevelDB を使っていて、その辺りを色々いじる経験が後になって役立ちました。残念ながら Chrome Apps が deprecated になってしまったため、この機能も現在はアクティブな開発は行われていません。

プライベートでは、このプロジェクトをやってる頃に結婚しました。同居に向けた準備や結婚式の準備でかなり忙しかった記憶があります。

Progressive Web Apps の幕開け - Service Worker API

次に Service Worker API の実装に関わりました。Service Worker は今でこそ Progressive Web Apps (PWA) の基盤として様々な使われ方をしていますが、初期の頃は「俺の考えた最強の Application Cache」という雰囲気で、私自身そういうものだと思ってたので、後々こんなに広く使われるようになるとは思いませんでした。このプロジェクトを引っ張ってきたテックリードの先見の明はすごい。Service Worker の位置づけの変化については「イベント駆動型サービス実行基盤としての Service Worker」という記事に書きました。

イベント駆動型サービス実行基盤としての Service Worker

Sync Filesystem API での経験から LevelDB の知識があったため、最初は Service Worker の登録情報を保存するバックエンド周りを担当しました。アメリカ出張した際に「LevelDB に詳しいからやらせてくれ」と言って向こうの人から仕事を引き継いできたんですが、今思うと別の人にアピールして自分でタスクを引っ張ってきたのはこれが初めてかもしれない。

Service Worker でもデータの扱いには苦心しました。クライアントサイドのデータベースを復旧するルーチンを作り込んだり、データベーススキーマを工夫してブラウザスタートアップを遅くしないように設計したり、スキーマのバージョンアップに備えてデータをマイグレーションするツールを作ったり、ストレージチームにいた知見を活かしてゴリゴリと開発しました。途中からは API 寄りの実装をしたり、別チームでやっていた CacheStorage API の実装を手伝ったりもしていました。

Service Worker を通して、Chromium のプロセスの仕組みやスレッディングなどを学びました。あと、ウェブ標準が作られる過程に関われたのがとても良い経験でした。Service Worker はいろいろな API (例えば Push API) の基盤でもあるので、別チームとの折衷をしたり、ローンチブロッカータスクの管理をしたり、サブプロジェクトのリード的なこともしました。

ウェブの概念を作り変える機能だっただけに、ローンチする時はバグがないかハラハラしたけど、無事にローンチされて今や PWA の中核機能として世界中で使われていることに感動しています。Sync Filesystem API の時は、機能のアピールや外部のデベロッパーとのコミュニケーションをあまり積極的にやらなかったことを少し後悔したので、Service Worker をローンチした時にはブログ記事を書いたり、SNS を通じて開発者のサポートをしたりと、個人で出来る限りのことをやりました。

プライベートではローンチ直前に長男が生まれて育児休暇を取りました。子どもが生まれて生活スタイルが一変しました。

並列処理 - Web Worker と Blink のスレッディング環境

Service Worker は Web Worker と同じ基盤を使って実装されています。Web Worker はスレッド並列処理を行うための API です。Service Worker が活発に開発されている一方で、Web Worker はコードオーナーが全然いなくて時々迷い込んだ人が細々とバグ修正しては立ち去る、というような状況でした。ちょうど同僚がワーカスレッドの終了バグをどうにかしようとしていて、その修正タスクを引き取る形で Web Worker 周りのオーナーシップを持つようになりました。

そもそも Blink (厳密にはフォーク時の WebKit やその前身の KHTML) はシングルスレッドを前提に作られていて、そこに Worker のようなスレッドを使った機能が後付けされたという経緯があって、色々壊れていました。例えば、GC でオブジェクトが早期に回収されたり、スレッドターミネーションが関連クラスに適切に通知されていないためにクラッシュしていたり、他にも色々大変な状況だったのを HTML 仕様とにらめっこしながら一つ一つ作り直していきました。

この辺りは自分の技術的興味ともマッチしていたので、やっていてとても楽しかったし、スレッドを意識したプログラミングを頭に叩き込む良い訓練になりました。Blink のスレッディング回りの知見は「JavaScript のスレッド並列実行環境」という記事にまとめたので、興味があったら是非読んで欲しいです。

続・並列処理とモジュール機構 - Worklet と ES Modules

Web Worker に詳しかったこともあって、次に Worklet の実装を担当することになりました。Worklet については前述の「JavaScript のスレッド並列実行環境」という記事で詳しく書きました。

最近の傾向として、ブラウザの様々な処理をフックしてカスタムスクリプトを仕込めるような仕組みが次々と作られています。例えば、Service Worker はネットワークリクエストをフックして任意のレスポンスを返すことができます。Service Worker ではカスタムスクリプトの実行環境として、独自の Worker を定義しました。このようなカスタムスクリプトの実行環境を各 API でそれぞれ独自に定義するのは大変なので、ベースとなる実行環境を定義し、それを各 API が自由に拡張して使える仕組みが提案されました。それが Worklet です。

Worklet はあくまでもベースとなる実行環境であり、それ単体では使用することはできません。Worklet を拡張してカスタムスクリプトを提供している API には、Paint Worklet、Animation Worklet、そして Audio Worklet があります。

ユースケースとしては上述の通りで、内部実装的な視点からざっくりいうと Worklet は軽量な Web Worker です。Web Worker はスレッドと実行コンテキストが 1:1 モデルを取るのに対し、Worklet は 1:N モデルを取るので、その拡張を行いました。先ほどの Blink スレッディング環境を整備したプロジェクトはこの布石でもありました。

Worklet スレッドモデル

あと、Worklet は ES Modules としてロードされるのでその実装も行いました。Worklet の実装が始まったときには ES Modules の実装も並行して行われていたため思っていた以上に長期のプロジェクトになりましたが、Chrome 65 で一つ目の Worklet 実装 (Paint Worklet) が無事ローンチできてホッとしています。今後 Worklet を使った API が色々でてくるので是非使って欲しいです。最近は Web Worker でも ES Modules が使えるように実装を行っています。

プライベートではまたまたローンチ直前に次男が生まれて育児休暇を取りました。このときの経験は「育児休暇で二ヶ月会社を休んだ話」という記事に書きました。

振り返り

この 6 年間、目の前の面白そうなことをがむしゃらにやってるだけでキャリアパスとかは正直全然考えてこなかったけど、振り返ると前のプロジェクトの知識を活かしつつうまくカバー範囲を広げてこれたかなと思います。もちろんリードやマネージャーがそういう戦略を取ってスコープを広げてきたからこそなので、とても感謝しています。

ソフトウェアエンジニアとして 6 年間も働いていると自分なりの哲学みたいなものが出来上がってきます。その中でもとりわけ重視してきたことは、自分が少しでも関わった部分は徹底的にコードを綺麗にしていくこと、そしてその過程で得られた知見はなるべく体系化してコメント・文書・ブログ記事などに残すことでした。コードを綺麗にすることはプログラムの全体像や動作を理解する助けになり、それを体系化して整理することで周りの人や将来の自分のためになります。体系化するところが特に重要で、断片的な知識をつなぎ合わせることは経験のある人じゃないとできないことだし、実用的にも史料的にも価値のあることだと思っています。

次の 6 年は何をやってるのか全く分かりませんが、楽しくて誰かが喜んでくれる仕事ができればいいなと思っています6

注釈

  1. この他に大学三年生の頃に「Google を支える技術」を読んで分散システムに興味を持ち、学部の研究室では P2P や分散ファイルシステムの勉強をしていました。 

  2. 余談ですが「Good question」という返答には様々な意味が込められます。一つは文字通り「良い質問だね」と相手を褒めている場合。他には「私には答えが分からない」や「それに気づいてしまったか・・・」といった意味の場合もあります。いずれにせよ聞き手にポジティブな印象を与えるので便利な言葉です。 

  3. 私はインターンの給料で初めてのスマートフォン (iPhone 4) を買いました。ちなみにこの iPhone 4 は正社員入社後の初アメリカ出張で紛失し、初任給で iPhone 4S を買うことに・・・。 

  4. この会社に入って驚いたことの一つは偉い人との距離感が近いことで、VP レベルの人でもメールを送ったらきちんと返信をくれるし、逆に「余暇に Chromium のパッチを書いたからレビューして」ってメールが飛んできたりします。 

  5. Chrome ブラウザはオープンソースのブラウザ実装である Chromium をベースに作られています。 

  6. あわよくばシステム寄りで、オープンソースで、外の開発者とインタラクションが取りやすい仕事だと嬉しい。