日記とアメリカのソフトウェアエンジニア面接で聞かれたテクニカルな質問メモ

備忘録です。アメリカの中小IT企業を2社受けて、結果的に両者からオファーを頂けました。

私のスペック

最終学歴は国際信州学院大学理学部電子機械学科卒業です。大学入学時のセンター試験の英語の点数は196点で、国際信州学院大学に合格したのも英語の試験でほぼ満点を取れたことが大きいと思います。大学在学中は、大学で独自に行われた英語のテストで1番上のクラスに分類されたため、英語の授業は帰国子女と一緒に受けていました。TOEICやTOEFLは必要に駆られなかったため受けたことがありませんが、周りの人を見ているとTOEIC800点くらいなのかな?と思います。当然ですが、日本で上の方の英語力だったからと言って、アメリカでネイティブとバリバリ話せるわけがありません。アメリカでお仕事をする際に英語力の欠乏にはかなり苦労を強いられましたが、幸いエンジニア職の面接では英語力はそこまで問われませんでした。なんとなく考えていることが伝えられれば大丈夫なようで、重要なのは技術力の面なのだと感じました。

中学生の頃には将来プログラマ〜になりたいな〜と考えていましたが、わかりやすく言うと両親が毒親で家庭が終焉(オワ)っていたので、本当にComputer Scienceを学び始めたなという実感が持てるようになったのは大学3年生の頃です。もちろんそこから満足にコーディングインタビュー対策をすることはできず、大学在学中にはデータ構造やアルゴリズムをほとんど理解することができませんでした。競技プログラミングもかじりましたが、なにせ前提知識がなく、数学的な閃き力もなかったため自分なりにいくら頑張っても上手くはなりませんでした。過去問を解きまくっても自分が成長している実感がわかず、競技プログラミングが嫌いでした。競技プログラミングくらいできろよ、みたいな圧力がとても不快だった記憶があります。延々と身長190cmのバスケ選手とバスケをさせられている気分でした。

日本でのコーディングインタビュー経験

日本ではコーディングインタビューを受けたことは1度しかありません。大学3年生時に、国際信州学院大学に広報に来ていたIT企業の方が「バイト感覚でインターンに来てくれたらいい」と宣伝していたのを鵜呑みにして面接を受けにいった結果、普通に落ちました。問題を与えられて何も思い付かずに面接官3人と自分全員が無言の状態でただ時間が過ぎていくあの経験はトラウマです。

私も単純にコーディング能力が足りなかったのと、何も思い付かなくても自分の思考プロセスを口に出す等のセオリーを知らなかったのも悪かったと思いますが、今考えると面接官の方々も不慣れだったのかなと思います。出された問題が、All or Nothing型の問題で、部分点が存在しなさそうなものでした。私経験・調査上、実装できるか実装できないかの問題を出されることは稀だと思っていて、例えばO(n^2)で全探索できるけれども、それをもっと速くO(nlogn)やO(n)にするにはどうしたらいいか面接官とやりとりをしていく中で答えにたどり着くような問題が好まれていると感じています。また、私が発言しなかったのも今思えば悪かったのですが、コーディングインタビューは基本的に対話なので面接官側からの発言が普通ならもっとあるだろうなと思います。

なんにせよ、この経験でコーディングインタビューへのトラウマが植え付けられました。

コーディングインタビュー対策

皆さん「Leet Code」か「Cracking the Coding Interview」でコーディングインタビュー対策をするとおっしゃるので真似してみるのですが、さっぱり自分が前に進んでいる気がしません。色々模索したところ、やはり基本的なデータ構造とアルゴリズムの知識がないとそれらを活用できないと思い、基礎がために注力しました。他にも色々あるのですが、割愛します。時系列が分からなくなっていると思うのですが、コーディングインタビュー対策を真面目にやり始めた時点で大学を既に卒業しており、アメリカの非エンジニア職で食いつないでいました。なので、コーディングインタビュー対策は働きながら17時くらいに仕事が終わってから喘ぎながらしていました。

ビザとか

私は幸運にもグリーンカードを所持しているため、ビザには困りませんでした。どの企業に連絡しても、アメリカで合法で働ける資格を持っているのか確認されました。日本人向けに就労ビザを発行するのは骨が折れるようですね。私は就労資格で振るいに落とされる可能性がなかったのはかなり幸運でした。身の回りのアメリカへの移住に成功した人は、私の観測範囲内では(偽装も含め)結婚という手段で永住権を獲得しているので、アメリカに移住する場合はまず留学か短期の駐在でアメリカに来て配偶者を獲得するのが主な手段かと思われます(ちなみに私に配偶者はいません)。米系企業にスポンサーしてもらえるような天才気質の方は、そちらで良いと思われますが、スポンサーしないといけないような日本人とスポンサーが必要ないアメリカ人では後者の方が優遇されやすいのは想像に難くなく、実際に米系大企業に入社できたものの、数年でスポンサーを解除されてしまった方を2人知っています。日本の企業からの出向で、グリーンカードを得て、アメリカに永住という方は個人的な経験では見たことがないですね。

とにかく、私はビザの面では運が良かったと言えます。なので日本人の方が私以上の実力を持っていたとしても、私よりも就職するのは難しいと思われます。

というか、日本良い国ですよ。医療制度やらなんやらが確立していて、普通に暮らす分には申し分のない国だと思います。あと、多分ご飯が世界で1番美味しいです。あの値段であの美味しさのものが買える国はまぁないと思います。丸亀製麺、てんや等、びっくりするくらいコスパが良いご飯が少し出歩けばあるのはやばいです。犯罪率も低く、アメリカにいると子供が誘拐される事件を結構耳にしたりし、近所のモールで銃発砲事件があったり、夜に出歩かないように親戚に注意されるなど、日本って安全だったんだなという気持ちによくなります。多分日本にいたのが人生で1番長かったからなのかもしれませんが、日本人の感覚がとても好きで、例えばアメリカ人はガンガンごみをポイ捨てするので(体感、ポイ捨てする人の比率が日本より多いという意味)道路脇はかなりゴミだらけです。日本ではあまりそのような光景を見ません(高速道路付近を除く)。アメリカだと本当に関わったらヤバイやつもよく見かけますし、日本良いですよ。確かに日本には、ちゃんと利益を出して成長している会社が少なく、私たちの下の世代が苦労しそうな感じはしますが、今生きている人たちが安全に死ぬくらいまではなんとかなりそうな気がします。

アメリカで出会う日本人の方が「アメリカLOVE」な人ばかりなのは、アメリカが合わなかった人が日本に帰っちゃうからなんだろうなと思います。

面接まで

Resume(日本で言う履歴書、ただしフォーマットが決まっていないのでやりたい放題)、LinkedIn(転職のデファクトスタンダード)を(自称)プロにお金を払って見てもらったりして準備しました。私はエンジニア職の経験が少ないので、Junior Software Engineerというjob titleに絞りLinkedInで片っ端から応募してみたのですが、Resumeの時点で落とされて不採用メールが来るのはまだマシで、だいたいの場合は音信不通でした。LinkedInのDMでそれなりの大企業に「あなたの経歴に興味があるから履歴書を送って」と言われて、メールを送ったらそのまま音信不通になったのはなかなか印象深いものでした。生活がかかってる+誰からも必要とされていない感覚はかなりメンタルに来ましたね。

IndeedやMonsterという就活サイト?にも登録していて、よくそこから翻訳の仕事の声がかかりました。エンジニア志望とはっきり書いてあり、Resumeもエンジニアに絞ったものにしてあるのに非エンジニア職の求人ばかりが来るのはなかなか精神にこたえました。日本人の人材仲介会社みたいなのからもよくお声がかかり、全体的に応対が高圧的で不快だったのを記憶しています。不快だったなと思ってレビューを見て見ると案の定レビューがボロクソ書かれています。特にActiv8という会社は、希望の職ではない求人を断り、Activ8さんに掲載されている求人に現時点では興味がない旨を伝えたところ、「年収1000万超えのソフトウェアエンジニアの求人もあったのですが、残念ですね(あ〜あ)」のようなメールが送られてきて、私はかなりlevel-headedな人間なので憤ることはしないのですが、すごい会社だなと思いました。逆にやりとりが好印象だったのはQuick USAという会社さんですね。そこでの機会には恵まれませんでしたが。

そんな中、Indeed経由で初めてJunior Software Engineerの募集を送ってきた仲介会社さんがあったので、そちら求人に応募してみる運びとなりました。

また、LinkedInは、DMに返信をちゃんとしていると「DMに応答しやすい人」みたいなタグ?が裏でつくことを知っていたので、どんなDMでも返信するようにしていました(こっちが返信したら音信不通の場合が多い)。そんな中、ある企業からお声がかかって、「どうせ音信不通になるんだろうな」と思いつつホイホイ返信していたら、いつの間にか面接の日程が決まっていました。これにはかなり驚きましたね。

面接の流れ

A社は(イントロ+面接+技術面接:2時間)+(最終面接:40分)で内定をいただける運びとなりました。

B社は(イントロ:20分)+(技術面接+イントロ:2時間)+(技術面接:2時間)+(最終面接:30分)でofferをいただける運びとなりました。

流石にコーディングインタビューまで詳細に書いていたら気が触れてしまうので、コーディングインタビューは触りだけで、テクニカルな質問を中心に覚えている限りまとめたいと思います。

コーディングインタビューの方針

これは私の方針であって正解ではありません。

基本方針として、まずは全探索(brute force)の解法に最初に言及するようにしました。そうすることで、最悪ブリリアントな解答が思いつかなかった場合も1番簡単な全探索と実装してお茶を濁すことができます。

また、自分の思考プロセスを逐一口に出すことを徹底しました。そこで面接官との対話が産まれます。

分からないことは分からないときちんと言うようにしました。どうしてもとっかかりが分からない時は「何かヒントをくださいませんか?」と正直に聞きました。この姿勢の良し悪しは企業にもよるのでしょうが、2社からかなり評価されたようです。(そもそも私は嘘をつくのが嫌いで、証券マンになってお客さんを騙してこれ絶対儲からないだろって金融商品を売りつけるみたいなことは多分できません)

気をつけたのはこんなところでしょうか。

テクニカルな質問集

自分の回答をメモ書きしておきます。回答であって解答ではないので、厳密には正しくなかった可能性が高いです。Junior Software Engineerだったらこのくらいで受かるのか、というくらいの参考にして頂ければと思います。これはもっとこう言った方が良かったかもね、という指摘を歓迎します。

A社

O記法とはなんですか?

  • 入力されたデータサイズに対して計算時間がどのように変化するかを表す指標、みたいに答えた記憶があります。どう説明したら良かったのでしょうかね

What is the object oriented programming?

  • 関数型プログラミング言語では、プログラムが関数で構成されている。それと同様で、オブジェクト指向ではプログラムがオブジェクトという箱の組み合わせで表現されている

ErrorとExceptionの違いを教えてください

  • これは正直分からなかったので、今まで書いてきたコードを思い出して、I guess exceptionはコード中でcatchできるある意味dynamicなもので、Errorはある種staticなもの、と苦し紛れに回答しました。
  • ExceptionはrecoverbleでErrorはunrecoverbleなものだね、と面接官の方が教えてくださいました。

HTTPについて知っていることを教えてください

  • 「正直に申し上げるとあまりプロトコルについて詳しくないのですが、ユーザがリクエストをサーバーに送ってサーバーがユーザにリクエストされたコンテンツを送り返す際に使用するもの」、と回答しました。
  • 今考えると、最初に公開鍵暗号で共通鍵を交換して、共通鍵暗号でデータのやりとりを行う、みたいなことは言えたのかなと思います。

GETメソッドとPOSTメソッドの違いについて教えてください

  • GETメソッドはサーバーの状態に影響を与えないが、POSTメソッドはユーザーデータの登録等でサーバーの状態を変更しうる、と回答しました。

B社

StackとHeapについて説明してください

  • StackはFILOで、データにアクセスする時には1番上の値にしかできない。Heapは、min-heapの場合は、1番小さい値がHeapの頂上に残り続け、新たに値を挿入する等してHeapの状態が崩れた場合も、その形を変えて1番小さな値を頂上に残し続けるデータ構造です。みたいに回答したと思います。
  • StackとHeapが実際に使われている例を思いつきますか?
  • StackとHeap両方が使用されている例を思いつかなかったので、Stackが使われていそうなBrowser Historyを挙げました。Browser Historyは、ここではブラウザ左上のページに戻るボタンと前に進むボタンのことです。訪れたURLをStackに積んでいくことで後ろに戻るボタンを実装できると考えたのでそのように回答しました。面接官に言い忘れていたのですが、もう一つStackを用意して、後ろに戻るボタンが押された時に後ろのURLを保持しているStackからpopしてもう片方にpushすれば前後移動が可能になるのかなとも考えていました。
  • Stackだと後ろに戻ることはできるが、後ろに戻った時に前にもいけるデータ構造を思いつきますか?(話題がBrowser Historyに移行)
  • (沈黙)
  • Linked Listについて説明してください
  • 値を保持したNodeが次のNodeへのポインタを持つことでNodeが繋がっており、全体の走査等が可能なデータ構造
  • Doubly Linked Listについて説明してください
  • Nodeが次のNodeへのポインタだけでなく、前のNodeへのポインタも保持することでNode間の行き来ができるデータ構造
  • Doubly Linked ListからNodeを削除する時はどのようにすれば良いですか?(1,2,3,4,5のNodeがあるとする)
  • 2のnextを4に、4のbackを2に付け替えてから、3を削除する
  • Browser HistoryをDoubly Linked Listでどう実装すれば良いですか?
  • あるNodeへのポインタをユーザが保持し、後ろに戻る時は後ろむきのポインタを辿り、前に進む時は前向きのポインタを辿れば良い。
  • Googleで何かを検索する時、今までの履歴からvisit回数が多い順?にURLが表示されます。これはどのように実装すれば良いですか?
  • (沈黙)
  • keyとvalueをpairにして保持するデータ構造を知っていますか?
  • (Pythonで言う)dictionary(HashMapと回答すべきでした)
  • HashMapですね、HashMapとDoubly Linked Listを併用すれば良いです。

ソートアルゴリズムを可能な限り列挙してください

  • shell sort、insertion sort、selection sort、merge sort、quick sort、bubble sort(shell sortだけは理解してなくて実装できないので、shell sortには触れないで欲しいなぁと思っていました)
  • それらのソートアルゴリズムで1番速いのはどれですか?
  • merge sort、quick sort。間があいたので、説明しろとのことかと思い、merge sortはin-placeなソートアルゴリズムで、quick sortはin-placeではないソートアルゴリズムです。quick sortはextra spaceが必要なくて、merge sortはspaceが必要です、と説明した記憶があります。今考えたら下手すぎますね。
  • 英語が下手すぎて、イヤイヤ、quick sortはspaceはいらないんだよ、値を交換していくだけだから、と面接官の方に言われ、誤解を与えたと思って「quick sortはspace必要ないですよね、値を交換するだけなので」とかぶせに?いったけど、ちゃんと伝わったか不明。
  • merge sort とquick sortの計算量は?
  • O(nlogn)
  • Quick sortがnlognの理由を説明してください
  • Quick sortは配列をどんどん半分にしていって処理します。半分の半分の半分の半分の...と続けていくと、その半分にする回数はlogn(基数2)です。そして一回ごとに値の走査O(n)が必要なのでn*lognでO(nlogn)です。

Gitのコマンドを可能な限り列挙してください

  • (最初質問が分からなくて、他のVersion Control Systemとの違いを説明しろとのことかと思って、Gitでは全てのファイルをハッシュで〜みたいに回答したところで止められました。add とか〜と言われて、なるほど理解)
  • add commit stash reflog branch checkout switch pull merge fetchあたりを答えた気がします
  • fetchとpullの違いはなんですか?
  • pullは他のブランチをmerge commitでもって取り入れることで、fetchは現在の作業ディレクトリに影響を出さずにremote repositoryの状態(なんとも歯切れの悪い)をlocal repositoryに反映させること、みたいに回答しました。
  • cherry-pickとはなんですか?
  • 特定のcommitだけを取り入れること(フワフワした回答)

AuthenticationとAuthorizationについて説明してください

  • Authorizationはユーザになんらかの権限を与えることで、Authenticationはユーザが権限をもっているか確認すること

InheritenceとCompositionについて説明してください

  • InheritenceはIs-A relationshipとして知られているように他のクラスから要素を継承することで、CompositionはHas-A relationshipと知られているように他のクラスを内部にattribute(という表現を使ってしまったが厳密には違うかも)として持つこと、と答えました。
  • InheritenceとCompositionのどちらが良いと思いますか?
  • InheritenceとCompositionのことを、どちらの方が良いか判断できるほど理解していません、すみません
  • Singleton Patternについて何か知っていますか?
  • デザインパターンの記事において読んだことはあるのですが...(思い出し中)...すみません、忘れてしまいました。

Web ApplicationにおけるEncryptionとHashについて説明してください

  • ユーザのパスワードをデータベースに保持する際に、データベースを見られたら危険なため、パスワードをそのまま保持するのではなくそのハッシュを保持する。インターネット経路は傍受可能で安全ではないため、ユーザとデータをインターネットを介してやりとりする際には暗号化が必要になる。基本的に、最初に公開鍵暗号で秘密鍵を交換してから、もっとデータ交換に効率の良い共通鍵暗号でデータのやりとりを行う。
  • 公開鍵・共通鍵のくだりは、そうだね、それがHTTPで行われていることだね、と教えていただきました。

SQLインジェクションの(自分でどこかで言及済み)他に知っているサイバー攻撃をできるだけ列挙してください

  • DoS・DDoS攻撃(しかその場では思いつかなかった)
  • 今考えると、有名どころだとクロスサイトスクリプティングって言えば良かったなと思います。

プログラミング以外の趣味はなんですか?

  • これは本当に困りました。最近何をしても人生おもんないな〜という感覚が拭えなかったので、特に趣味という趣味はありませんでした。趣味を聞かれて即答できる人っているのでしょうか?そんなに全人類土日になったらやりたいことが決まっているようなものなのでしょうか?
  • 全く役に立たない・非論理的だと分かっていながらも余暇で自己啓発本を読んでいること、ゲームも結構やっていてSkyrimは500時間以上遊んだ、と回答しました。

インタビューにおける誠実さについて

前職を辞す際に上司の方から「アメリカでの就職はかなり自分の能力を大袈裟に言わなければならない」とアドバイスをいただきました。例えば「フランス語を少し勉強したことがあるならフランス語ができるって言ってしまう」みたいな感じです。もはやアメリカ人みんなそんな感じで大袈裟にアピールするので、HR(人事)もそれもそれを分かっててResumeを見たりするらしいです。これは前職の先輩方からのアドバイスだけではなくて、アメリカに無数に散らばっている親戚や知人(元Apple、Tesla、IBM等がいる。プレッシャーかけてくんな。)にアメリカでの就職のアドバイスをもらいにいくとみんな口を揃えて「自分を大きく見せろ」「ハッタリをかませ」と言ってきました。

私はこの風潮が嫌いです。10の仕事しかできないのに100の仕事ができると言って会社に入り、後々問題になったらどうするのでしょうか?就職はそういうゲームなんだと言われればそれまでですが、単純に誠実でない人と仕事したくないと思うのは私だけでしょうか?

エンジニア就職だと、面接でいくら天才アピールをしたってコーディングインタビューでほとんどバレると思うので、上記のアドバイスは無視しました。私はまだ精神的に幼稚なので、人を騙してお金を稼ぐような行為が全体的に嫌いです。まだ社会経験が少ないよちよち歩きの赤ちゃんなので、他人に対しても自分に対してもできるだけ誠実に生きたいと思ってしまうのです。

後からわかったのは、この私のできる限りの誠実さは2社のソフトウェアエンジニア職で非常に評価された点だったとのことです。文系就職のことはさっぱり分からないのですが、エンジニア職ならどうせハッタリはバレるので、実力で勝負した方が良いんじゃないかなというのが私の個人的な考えです。といっても、私はJunior Software Engineerのポジションを、それも2社というごく少ないサンプル数受けただけなのでmid-levelから上の世界は全く分かりませんし、Resumeスクリーニングで落とされないように自分がやってきたことを少し良い感じに書いているのは私も同じなので、そこも含めて嘘ついているじゃないかと言われると苦しいところがあります。このへんは人によって信念があるでしょうから、私が何かを断言することはできません。

結果

2社両方からofferを頂くことができました。2社ともかなり良い条件(当社比)をご提示頂いたので、あとは色々と条件を比較して結論を出そうと思います。すぐさまクビになるんじゃないかとビクビクしているのですが、私を面接で通した会社の方が悪いと思って、自分なりに頑張っていきたいと思います。

nere9について

私がいくら内向的な人間で、四六時中他人と過ごすことを嫌っていたとしても、アメリカで孤立している中、どうしても微かでも良いから人との繋がりが必要でした。前職を辞すタイミングでmastodonを始め、LTLを眺めているだけでまだ社会から隔絶されていないと思うことができました。

妹とパブに行った際に、1人で来ていたおじいさんが周りの家族連れ・カップルを眺めながらお酒をちびちび煽っていた光景をよく思い出します。あのおじいさんの心情を完全に推し量ることはできないのですが、私にはあの光景は、まだ社会の一部に自分が存在してる実感を得たかったように見えました。

私にとってLTLは、あのおじいさんにとってのパブみたいなものでした。本当にありがとうございました。(と書くとラブレターを書いているみたいでなんだか恥ずかしいのですが)

その他

まだ人生経験が豊富ではないのですが、何か個人的な質問等があればいつでも受け付けております。

You are using an unsupported browser and things might not work as intended. Please make sure you're using the latest version of Chrome, Firefox, Safari, or Edge.