流れに便乗して私がソフトウェアエンジニアになるまでにやってきたことを書いてみます。学生を想定読者にしています。進路を考える時の参考になると嬉しいです。

私は修士一年の 2010 年に Google Japan の Chrome OS チームでインターンし、 2012 年に新卒のソフトウェアエンジニアとして入社しました。現在は東京オフィスの Chrome ブラウザの開発チームにいます。インターン中や入社後の仕事については以前「就職して 6 年過ぎた」という記事に書いたのでそちらも是非見てください。

本記事では学生時代に何を学び、それがどのように現在へと繋がっていったのか紹介します。ソフトウェアエンジニアとしての能力や経験をどのように磨いてきたかが中心です。面接を含む Google 固有の話題は他の記事で十分語られているのであまり書きません。

長文です。結論だけ読みたい人は『最後に』を読んでください。

アメリカ本社

大学

大学は慶應義塾大学の理工学部情報工学科を卒業しました。大学入学時点で入門書サンプル写経程度の Perl/CGI アプリケーション (掲示板やチャットなど) の実装と HTML や CSS によるホームページの作成はできましたが、中学高校では部活 (陸上競技部) の方が楽しかったのでそれ以上のことはやってなかったです。大学も何となく理系にしようと思い、学科紹介のパンフレットを見た中で情報工学科が一番適正ありそうだなと思って選んだ感じでわりと弱い動機づけでした。ちなみに一年浪人しています。

大学に入ってすぐの頃、梅田望夫さんの『ウェブ進化論』を読んでウェブの可能性にワクワクしたことを覚えています1。そしてその流れの中心的な企業になりつつあった Google に憧れを持ちました。

二年生の時に大学の先輩2に誘われて国際大学対抗プログラミングコンテスト (ACM-ICPC) に参加したのがコンピュータサイエンス (特にアルゴリズム) をちゃんと勉強し始めたきっかけです。「一次予選を突破すれば無料で旅行ができる」というのが当初のモチベーションでした。この当時、東大や京大といった一部の大学を除いてプログラミングコンテストはあまり盛んではなく、練習方法も今ほど広く知られていなかったので、付け焼き刃でもアジア地区予選までは進める感じでした3。私は ICPC の過去問や PKU のオンラインジャッジを通して基本的なデータ構造やアルゴリズムの使い方を学びました (もし今学生なら間違いなく LeetCode をやり込みます)。あと、オブジェクト指向言語 (Java) を初めて使ったのもこのときで、オブジェクト指向の概念に衝撃を受けたのを覚えています。

授業料が変わらないなら授業をたくさん取った方がお得だと思い、情報工学科の授業はあらかた履修し、大学院の授業も先取りし、卒業に必要な単位は余裕で超えていました。当時は大変でしたが、今は良い選択だったと思っています。選り好みせずいろんな分野を一通り学べたことは後々大いに役立ちました。専門科目は相性が良かったので、一年時に第二外国語や物理化学でズタボロになった GPA の回復を狙うという思惑もありました :p

四年生でネットワークスタックや分散システムをテーマにしている研究室に入りました。この頃に出版された『Google を支える技術』という本に影響されて、分散システムに興味を持ったのが理由です。当時は P2P の研究が盛んで P2P システムや分散ハッシュテーブルの論文を読んだり、コンピュータネットワークの古典的教科書である『Computer Networking: A Top-Down Approach』やタネンバウム先生の『Distributed Systems: Principles and Paradigms』を輪読したりしました。卒業研究では C 言語で FUSE ライブラリを使ったモバイル向けの分散ファイルシステムの実装をしました。当時はバイナリシリアライザなど全く知らず、構造化されたデータをネットワークに流す方法を調べるだけで何日もかかりました4。出来上がったものはおもちゃのようなプログラムでしたが、論文を参考に先行研究の手法を使いつつシステムをゼロから作り上げるという経験は得難いものでした。

その他には前述の先輩の紹介で、Perl や PHP を使ったツールやポータルサイトの作成などを請け負っていました。受注額を言い値で決めさせてもらったんですが、相場が分からず時給換算で適当に値段を言ったら「安すぎ」と言われて、プログラミングの生み出す価値の高さにびっくり。あと、仕様書作成や検収作業といったものも経験させてもらって「これが現実のプロダクト開発かー!」と感心しました。この頃から「将来はソフトウェアエンジニアになりたい」と思い始めました。

将来の就活に備えて、基本情報処理技術者・ソフトウェア開発技術者・情報セキュリティスペシャリスト・ネットワークスペシャリストを取りました。が、これはほとんど役に立ってない気がする。あとずっと学園祭実行委員会をやってたんですが、これはチームでプロジェクトを進める訓練になりました (そしてデスマーチの恐ろしさを知った5)。

院試

学部四年生になり、院試に向けて勉強を始めました。私の研究班の先輩たちが全員卒業するため研究を続けるのが難しそうだったこと、授業料を抑えたかったこともあり別の国立大学を目指すことにしました。

受けたのは東京大学大学院の情報理工学系研究科創造情報学専攻というところです。この専攻は「情報理工学における分野融合の中核」を標榜しており、情報理工学に関する様々な研究室がごった煮になっている面白い環境でした。以下は公式ページからの引用です。

卓越した創造的アイデアを「もの」とする実践的な教育・研究を実施し、情報分野において指導的役割を果たす実践的研究者・創造的技術者を育成することを目的としています。 また、情報理工学における分野融合の中核として、新しい情報分野を切り拓くことを目指しています。

創造情報学専攻は院試も特徴的で、英語 (TOEFL) と専門科目と数学と面接が試験科目なんですが、数学のかわりにプログラミングの試験を受けることもできます。むしろプログラミングが主流です。私もプログラミングで受験しました。これに向けて院試の過去問や ICPC の問題などをひたすら解きました。

また、専門科目も「分野融合」を標榜するだけあって出題範囲が、コンピュータアーキテクチャ、データベース、自然言語処理、コンピュータビジョン、ロボット工学などなど、多岐に渡ります。過去の入試問題が公開されているので興味があればぜひ見てみてください。選択式で解答する問題を選べるとはいえ、あらゆる分野を一定レベル理解している必要があります。

おそらく院試は各教員の得意分野を中心に出題してくるだろうと推測し、理学部情報科学科のカリキュラムや教科書・参考書・講義資料をひたすら調べて出題されそうな分野を予想して対策しました。あと『アルゴリズムイントロダクション』や『コンピュータの構成と設計』 (通称パタヘネ) といった各分野の古典的教科書を演習込みで読み込み、過去問で分からない用語・分野があれば Wikipedia をひたすらチェックしていくといったことをしていました。この準備には学部で一通りの授業を履修していたことが役に立ちました。またここでインプットした知識が後々ソフトウェアエンジニアとしての基礎になりました。

ちなみにプログラミングの試験では見事に爆死し、面接官の初っ端の一言で「君の答え間違ってるけどどうしたの?」と言われたときは頭が真っ白になりました。あまりにもつらくてもはや記憶が曖昧なんですが、ひたすら間違えた理由をプレゼンして納得してもらった覚えがあります。結局専門科目の方が一通りできたおかげで事なきを得ました。

大学院

大学院では Ruby 言語処理系や仮想化技術をテーマにした研究室に入り、プログラミング言語処理系の仕組みや最適化手法について学びました。

研究では CRuby の正規表現エンジン用の Ahead-of-Time コンパイラを書いたり、共有メモリを使ったプロセス間通信機構を作ったりしました。学部ではゼロから作る研究でしたが、大学院では既存のプログラム (CRuby 処理系)をいじる研究になり、生きた大規模ソフトウェアを自分なりに要約して読み解く必要がありました6 7。実社会のソフトウェアはどれも巨大で複雑なので、このときの経験は大いに役に立ちました。

後述のインターンでの経験を通してチーム開発の修行が足りないと感じ、アシアル株式会社で一年ほどアルバイトをしました。これがインターン以外で会社に所属して開発する初めての経験でした。業務は HTML5 ハイブリッドアプリ開発プラットフォーム Monaca の開発でした。Monaca は Web IDE 上で HTML/CSS/JS を書くと、iOS と Android のネイティブアプリケーションとしてラップしてビルドしてくれるというものです (今はもっと多機能っぽい)。Cordova ベースでネイティブ機能へのブリッジも提供してくれます。私は iOS 用のリモートコンパイル環境の構築、リモートデバッガ・テンプレートエンジン・UI フレームワークの実装などをしました。スマートフォン用ネイティブアプリケーションの基礎知識や、ウェブアプリケーションとの違いを深く学ぶことができ、この経験は後にブラウザ開発に関わる上で役に立ちました。

あと、学部時代の仲間と位置情報を使ったスマートフォンアプリケーションを作ったり (ローンチできずに終わった)、オンライン学習用のウェブアプリケーションを作ったり (こっちは安く売り払った) もしました。プロジェクトがなぜ失敗するのか分かりました。今思い返すと色々失敗してるなぁ・・・。

面接・インターン・そして現在

修士一年になり、そろそろ就活に向けて動かないとまずいと思ってインターン情報を漁っていたら Google の募集がたまたま目に留まりました。『ウェブ進化論』を読んで Google に憧れたことを思い出し、ちょうど締め切り最終日だったので慌てて申し込みました。

インターン採用のときに電話面接とオンサイト面接を受けました。面接に向けた準備はネット上の面接体験記 (海外のものも含む) を参考にしました。また院試のときと同じように、Google という会社がどういう事業をしていて、そこでソフトウェアエンジニアとして働くにはどういった能力が求められそうか、それらを踏まえて面接でどんなことが聞かれそうか推測して準備しました。恐らく技術的な知識は十分に持っているだろうと判断し、コーディングやアルゴリズムの復習を一通りして面接に望みました。

インターン貼り紙

インターン終了後に正社員採用のためのオンサイト面接を受けました。インターン採用のときと基本的に同じ面接でした。そして現在は Chrome ブラウザチームでウェブブラウザの開発をしています。不思議なことに、学生時代に学んだこと (ネットワーク・並列分散システム・ファイルシステム・言語処理系など) はもれなく現在の仕事に役立っています。

(インターン中や入社後の話は「就職して 6 年過ぎた」を見てください。社内には楽しいプロジェクトがいっぱいあります!)

英語

大学入学直後に初めて受けた TOEIC が 615 で、大学院入学直後が 725、入社時は 750、現在は 965 です。年に 1 回くらいは TOEIC を受けてます。学生の頃は「申し込んで満足して気づいたら勉強時間ゼロで試験当日」の繰り返しでスコアが全然上がらず。入社後は何冊か問題集を繰り返し解いてから受けたら一気にスコアが上がりました。当たり前ですが、ほぼ全問正解できるまで同じ問題集を何度も解きまくるのが TOEIC のスコアを上げる手っ取り早い方法だと思いました。

他に会社の補助を受けながら英会話教室やオンライン英会話を受講しています。リーディングとライティングに関しては特に不便を感じていませんが、リスニングとスピーキングは悩みの種です。多分一生悩みの種だと思います・・・

最後に

これは Google に限らず一般的な話なんですが、もしなりたい自分や目指してみたい環境があるなら、そこに至りそこで活躍するために必要な知識・能力・経験を早い段階で精査し、現在の自分とのギャップを整理して、その差を埋めるための戦略を練ることをおすすめします。私が院試や面接をくぐり抜けることができたのは (運の要素が大きいながらも) 自分に足りないものを自覚してそれを少しでも減らすための目標設定をうまくできたからだと思っています8

入社面接に関していうと、最近は求人票に qualification や job description がしっかりと書かれている会社が増えてきているので、それを参考にすると良いです。もちろんそんなものを気にせず好きなことをがむしゃらにやって強みを伸ばすことも重要ですが、自分の強みだと自負していることと周りが求めていることは往々にしてずれがあるので、それを認識することは必要だと思います。


  1. 梅田望夫さんは慶應義塾大学理工学部から東京大学大学院情報理工学系研究科へと進まれていて、それも私の進路選択に影響を与えました (Wikipedia)。 

  2. この先輩は中学時代の同級生で、中学時代に Perl のことを色々教えてもらいました。大学でもプログラミングコンテストに参加するきっかけを作ってくれてとても感謝しています。 

  3. 2007 年の東京大会と 2008 年の会津大会に出ました。 

  4. 学生の頃は無知無能だと思われるのが怖くて、分からないことを人に聞いてみることがうまくできませんでした。インターンや業務という知らないことがあるのが当たり前な環境で経験を積む中で人に質問する術を学びましたが、できればもっと早く身につけたかったことの一つです。 

  5. 学園祭は教室を含むキャンパス全体を使って行われるんですが、前日 (一部当日の午前中) まで授業があるため、それが終わってから夜通し設営をする必要があってデスマーチ化しやすかったです。また、片付けも週明けの授業までに終わらせる必要があり、これもデスマーチを助長する要因になっていました。お祭りという高揚感から疲れていても意外と動き続けられるし、終わった後も爽快感を覚えてまたやってもいいかなと思ってしまうのが悪い意味での学びでした。これを仕事で常習的にやるような会社は避けようと固く誓いました。 

  6. 東大には実利用されている大規模ソフトウェアを読み解いて機能拡張を加えてみる「大規模ソフトウェアを手探る」という授業があるそうです。私は受けていませんが、授業の説明書きを読んで素晴らしい試みだなと思いました。 

  7. 著名なカーネルハッカーである小崎資広さんが大規模なソースコードを読み解く力を「数の暴力に対する耐性」と表現していて面白いなと思いました。 

  8. 目標設定のやり方については以前「日々の進捗の出し方」という記事に書いたので参考になると幸いです。