Google SWEインターンに応募する

2024年度のGoogleSWEインターンの募集が開始されていたので、応募・選考フローについてまとめました。 私は過去に2回参加していますが、それから時間を置いての執筆なためうろ覚えな部分があることや、年によって詳細やフローに変化があることを踏まえて目安程度に読んでください。

Googleでのインターン参加経験は以下のとおりです。

目次

SWEインターンとは

Googleにおける就業型インターンです。 実際の開発チームに参加して実務的なプロジェクトを行います。 プロジェクトによりますが、実装だけでなくDesign Doc(仕様書・設計書的なもの)の執筆やDesign Reviewなども行う、ちゃんと「ソフトウェアエンジニアリングをする」インターンです。 インターンの成果が評価されると本選考の選考フローのスキップなどを得られることがあります。

Googleでは職種名の「SWE(ソフトウェアエンジニア)」と、SWEを目指している学生向けのインターンである「SWEインターン」の両方の募集があります。 ブログなどの情報が多いのは「SWE」の方なので、情報の参照時には注意してください。

応募時期

ここ数年では2月の上旬~中旬くらいに募集が開始されています。

このフィルター条件で引っかかるはず。 https://www.google.com/about/careers/applications/jobs/results/?degree=PURSUING_DEGREE

見逃さないよう、「この検索に関する求人情報のアラートを有効」にしておくと良いかもしれません。

募集要項は募集期間のみしか掲示されないため、基本的に過去のものを見ることはできません。 参考までに2024年2月の募集要項ページのアーカイブを貼っておきます。 https://web.archive.org/web/20240220122719/https://www.google.com/about/careers/applications/jobs/results/78352561104396998-2024

締め切りは例年3月の中旬頃ですが、応募者が多数の場合は当初の締め切りよりも前に受付を終了することがあります。 なるべく早めに応募しましょう。

インターンの実施スケジュール

SWEインターンは10~12週間の週5フルタイムの形式です。 インターン期間中は基本的に授業には出れません。 実施時期はかなり自由に設定できるので、夏休みか春休みに行きましょう。 ほとんどの人は夏休みに実施しています。

ところでこの指定、「最低10週間」で「基本は12週間」が実態です。 希望すれば最大で17週間までできます。 が、日本の大学の長期休暇って12週間もないんですよね……。 前後どちらかをはみ出す前提で授業の履修スケジュールとの兼ね合いをつける必要があります。 研究室所属後であれば指導教員との相談もするべきでしょう。

私はB4とM1で参加したので、こんな感じで対応をしました。

  • B4時(2021)
    • 9/6~12/3
    • 院試があったため9月以降に
    • 必要単位は揃っていたので授業は取らない
    • 卒論の研究スケジュールは指導教員と相談して前倒しに
      • ゼミはオンライン参加
  • M1時(2022)
    • 7/11~9/30
    • 夏休み前の授業を出席不要&レポート提出のものだけにし、インターン開始以降は欠席
    • 指導教員と相談して研究は休止
      • ゼミはオンライン参加

▶なんでこんなに長いの?

夏休みが3ヶ月以上あるような欧米でのインターンスケジュールがベースになっているからです。

日本の大学に在学していてこの長期間スケジュールが厳しいことは人事の方も把握しているようです。 インターンの成果の評価軸はどの国のオフィスでのインターンでも共通なため、より短い期間でやると「成果が足りない」と評価される可能性が高まってしまう、ということで同じくらいの長さで行うことが推奨されています。

選考フロー

  1. サイト上でエントリー
  2. ResumeとTranscriptの提出
  3. Web上でのCoding Test
  4. ビデオ通話でのCoding Interview
  5. Hiring Committee
  6. ビデオ通話でのHost Matching
  7. 結果通知

サイト上でエントリー

エントリーではGoogleアカウントと紐づけて登録&エントリーをします。 ずっと使い続ける&人事と連絡を取るのに問題ないGoogleアカウントを使ってください。

Resume

resumeはresumeです。 雑に調べると履歴書と出てきますが、いわゆる「履歴書」ではありません。

自分の所属や経歴のほか、「何ができるか」「何に興味があるか」をアピールするためのものです。 Googleでは1ページのPDFとしての提出が求められます。 サイズはA4で作れば問題ありません。 全文英語で作成します。

Googleが「こういうresumeを出してね」という情報の発信をしているので、一通り目を通してから作成することをおすすめします。

作り方

resumeは決まったフォーマットというものはありません。 作成に使用するツールも自由です。

「resume template」で検索すると色々出てくるので使いやすそうなものを選ぶといいと思います。

私は自由にレイアウトを調整したかったのでCSS組版で作ったりしました。

Transcript

成績証明書のことです。 インターン応募では正式なものでなくてもよいです。

私は、教務web(東工大履修登録・成績管理システム)の授業と成績の一覧が閲覧できるページを英語表示モードにしてPDF印刷したものを提出した気がします。

Coding Test

専用のサイトでアルゴリズムの実装をするCoding Testを行います。 使用可能な言語はC、C++JavaJavaScriptPythonあたりだと思います。

私はSTEP教育プログラムの参加などを経由したため「SWEインターンのCoding Test」は受けたことがなく、実際のレベル感を知りません。

  • AtCoder Beginner ContestのC~Dくらい
  • LeetCodeのmediumくらい

などの説があるようです。 また、「アルゴリズムの基本的なことしか聞いてない」という話もあるとか。 とはいえここで脱落する人も沢山いるので、しっかり準備して望むとよいと思います。

なお問題は全て英語で記述されています。 LeetCodeなどの英語サイトで問題文の表現に慣れておくといいかもしれません。

Coding Interview

Google Meetでの面接で、面接官を変えて2回実施されます。 日本語で1回、英語で1回が基本らしい?(年によって変わる可能性があります)

アルゴリズム系の問題が出題されるので、それを面接官と対話/議論しながら解いて行きます。 ここではコーディング力以上に、「適切にコミュニケーションが取れるか」「コンピューターサイエンスの背景知識がちゃんとあるか」を見られます。

詳細はそのうち別記事で書きます。

Hiring Committee

今までの選考結果を元に「Hiring Committee」という社内組織が審査します。

応募者は特にやることはありません。 追加で書類の提出を求められることがあったりするとか。

Host Matching

Hiring Committeeの通過後に、「インターンで何をしたいか」のアンケートに回答します。 アンケートには興味あること全部書いておくくらいの勢いでいいです。

Tokyoオフィスにどのプロジェクトのチームがあるかはこのサイトの記述が参考になると思います。

Google 東京オフィスでエンジニアとして働くということ - Google 人材募集

インターンを受け入れるhost(メンターのような役割の人)はresumeとアンケートの記述をもとに、用意しているインターンプロジェクトと親和性の高そうな応募者を選びます。 選ばれるとビデオ通話でhostと実際に話すHost Matching Callが設定されます。 Host Matching Callではインターンプロジェクトについての説明や、応募者の経験や興味についての確認、インターンの実施スケジュールの調整などが行われます。 お互いが「ぜひここでインターンを!」と合意できればマッチング成立となり、インターンのoffer(内定)が出ます。

Host Matching Callの設定回数は1回のこともあれば、複数のこともあるようです。 また、hostから選ばれなかった場合はHost Matching Callをしないまま選考終了となります。

メルカリのインターンでGoのテストコードの雛形生成ツールを作りました

はじめまして、oribeです。

メルカリの「Online Summer Internship for Gophers 2020」に参加しました。 mercan.mercari.com

前半でGoの静的解析についての講義を受け、後半の開発期間で静的解析を行うツールの開発を行いました。
講義資料はこちらで公開されています。 engineering.mercari.com

gentest

概要

後半のツール開発ではGoの関数からテストコードの雛形を生成するツールを作りました。 github.com

gentestは対象としたい関数のファイル内でのオフセットを与えると、その関数の引数・返り値に合わせたテストコードの雛形を生成します。

package sample

func hello(s string) string {
    return "Hello " + s
}
$ go vet -vettool=`which gentest` -gentest.offset=21 sample.go

func TestHello(t *testing.T) {

        type input struct {
                s string
        }
        type expected struct {
                gotString string
        }
        tests := []struct {
                Name     string
                Input    input
                Expected expected
        }{
                // TODO: Add test cases.
        }

        for _, test := range tests {
                test := test
                t.Run(test.Name, func(t *testing.T) {

                        gotString := hello(test.Input.s)

                        assert.Equal(t, test.Expected.gotString, gotString)
                })
        }
}

Table Driven Testの雛形が生成されるので、// TODO: Add test cases.の箇所に具体的なテストケースを記述するだけでテストコードが完成します。
引数・返り値が複数ある関数や返り値にerrorを含む関数、メソッドなどにも対応しています。
具体的なケース別の出力についてはREADMEに記載しています。

なお、生成されるテストコードではtestifyのassertパッケージを使用しています。

公式の拡張機能で生成されるテストコードとの違い

VSCodeのGoの公式拡張機能でも関数を指定してのテストコードの雛形生成が行えます。(Golandでも同様の機能があるそうです)
私は普段VSCodeで開発しているのですが、この雛形生成機能の存在はこのツールがある程度形になってきた段階で初めて知りました。
こういったツールを開発している人はすでにいるだろう、とは思っていたものの公式で存在していたとは……と少々落ち込みました。
ので、「この公式の拡張機能よりも使いやすいものを!」という目標を途中から追加しました。
具体的にどのような違いがあるのかを紹介します。

testifyを使用

上述の通りgentestで生成されるコードはtestifyを使用しています。
対して公式の拡張機能で生成されるコードは標準パッケージのみで構成されています。
テストコードにtestifyを使用するべきか否かは主義が別れるところになりそうですが、testifyを使用したテストコードを書きたい人にはgentestがオススメです。

並行実行されるテストコードを生成できる

実行の際に-gentest.parallel=trueを追加すると、t.Parallelt.Cleanupを追加した並行に実行されるテストコードが生成されます。

package sample

func hello(s string) string {
    return "Hello " + s
}
go vet -vettool=`which gentest` -gentest.offset=21 -gentest.parallel=true sample.go

func TestHello(t *testing.T) {
        t.Parallel()
        type input struct {
                s string
        }
        type expected struct {
                gotString string
        }
        tests := []struct {
                Name     string
                Input    input
                Expected expected
        }{
                // TODO: Add test cases.
        }

        for _, test := range tests {
                test := test
                t.Run(test.Name, func(t *testing.T) {
                        t.Parallel()
                        t.Cleanup(
                        // TODO: Add function.
                        )
                        gotString := hello(test.Input.s)

                        assert.Equal(t, test.Expected.gotString, gotString)
                })
        }
}

ポインタレシーバを変更するメソッドに対応

ポインタレシーバのフィールド、またはポインタレシーバそのものの値を変更するメソッドが対象となった場合、変更後のレシーバの状態を記述するUsedExpectedが自動で追加されます。
なおメソッド内で呼び出される関数やメソッドによる変更の有無までは追いません。

package sample

type T struct {
    Hoge string
}

func (t *T) Method() string {
    t.Hoge = "hoge"
    return t.Hoge
}
func TestT_Method(t *testing.T) {

        type expected struct {
                gotString string
        }
        tests := []struct {
                Name        string
                Use         *sample.T
                Expected    expected
                UseExpected *sample.T
        }{
                // TODO: Add test cases.
        }

        for _, test := range tests {
                test := test
                t.Run(test.Name, func(t *testing.T) {

                        gotString := test.Use.Method()

                        assert.Equal(t, test.Expected.gotString, gotString)
                        assert.Equal(t, test.UseExpected, test.Use)
                })
        }
}

ツールの仕組み

まず与えられたoffsetに対応する関数のast.FuncDeclast.FileのフィールドDeclsの中から探します。
ast.FuncDeclに対応するtypes.Signatureを取得し、そのフィールドから引数や返り値、レシーバの情報を取得します。
そうして得られた情報を元にtext/templateなどを使用した文字列処理でコード生成を行い、最後にgo/formatの関数Sourceでフォーマットをかけてから出力します。

実装したコードの雛形はskeletonで生成しました。 github.com skeletonで雛形を生成すると、メインの静的解析を行う部分を書くだけでツールが完成させることができます。

今後の展望

実行時に対象としたい関数のオフセットがわかっている必要があるため、そのままCLIツールとして使用するにはやや不便であるというのが現状です。
いずれgentestを組み込んだVSCode拡張を作ってその点を解消できればいいなと考えています。

終わりに

Goの静的解析を行うことが初めてだったため、前半の講義で学んだことを組み合わせて作り上げて行きました。
Goは標準パッケージで得られる情報が大変豊富なので、ある程度使い方を習得してからは快適に実装を進めることができました。
最終的には自分でも「今後使って行きたい」と思えるようなツールになったのでとても嬉しいです。

講義資料の内容は初めはわからないことだらけでしたが、わかりやすい講義と合間に挟まれる演習のおかげで段々と理解できるようになっていったのが楽しかったです。
開発中はメンターさんに的確なアドバイスや質問対応、丁寧なコードレビューをしていただけました。
またコードレビューの際にはgolden testingといったコード生成のためのテストを行いやすくする手法なども教えていただき、静的解析以外の領域の学びも多く得ることができました。

たった5日間だったとは信じられないほど密度の高い、充実したインターンでした。
社員の皆さん、ありがとうございました!!!