2017年フロントエンド面接体験記
はじめに
ようやく最近の面接の振り返りをまとめる時間ができた。まず見えてきたことをいくつか総括しておく:
- 通常、企業の面接では Javascript の習熟度ばかりが問われ、その多くはアルゴリズムやプロトタイプチェーンの解説などであり、DOM や Event の操作が問われることは滅多にない。
- CSS はほぼ出題されない。あっても class や ID の優先順位を判定するようなごく基本的な問題程度だ。
- semantic tag や accessibility、input type の使い分けといった HTML を問う面接は皆無だった。
- React、Redux、ES6 の構文はフロントエンドの必須スキルとなりつつあり、Angular を採用している企業は比較的少なかった。
- 全体的にヘッドハンターの専門性が物足りない印象を受けた。僕がまだ未熟で、優秀なヘッドハンターに巡り合えていないだけかもしれないが。
今回面接を受けた企業は以下の通りだ:
- Accupass
- Codementor
- Linker Network Inc.
- 台湾楽天市場
- 17 media
バックグラウンド
国立科技大学の情報管理学科卒、現時点で2年の実務経験がある。普段はフロントエンド開発に注力しており、React や Redux を使った開発経験は約2年。一般的なフロントエンド「エンジニアリング」だけでなく、UIの実装やインタラクションを作るのも好きだ。また、個人の小さなプロジェクトを通じて AWS、Lambda、Node.js、データベース、機械学習といったバックエンド関連の知識も学んでいるが、やはり一番得意なのはフロントエンド領域だ。
期待する職場環境
- フロントエンドチームと一緒に開発ができること。これまでの職場ではフロントエンド担当が僕一人しかいなかったため、フロントエンド特有の技術的な議論が難しかった。
- 突発的な事態が少ないこと。急な仕様変更、開発中プロダクトの中止、人間関係のしがらみで仕方なく開発する案件などがない環境。
- 自社プロダクトと明確なサービスがあること。
- 技術力が高く、優秀なチームと一緒に仕事ができること。
求人探しのチャネル
- inside jobboard
- yourator
- 104 人力銀行
- f2e jobs
- PTT Soft_Job 板
1. Accupass 活動通
応募職種:Frontend Developer
イベントチケットを扱うWebサイト。最近、アーキテクチャを Angular から React へリプレイス中とのことだった。元の Angular コードは保守が難しく、一部の変更が全体に影響を及ぼしやすい状態になっていたのが理由らしい。
面接前
104 人力銀行を通じて、PM から直接オファーメッセージをいただいて面接に進んだ。
面接中
チームを拡大しているフェーズだった。面接では主に過去の実務経験や小さなプロジェクトについて話した。当日面接を担当してくれたフロントエンドエンジニアは日本人の方だった(笑)。ただ中国語がとても流暢で、面接は全編中国語で行われた。
Accupass の開発状況、機能開発の進め方、スケジュール管理などについて話し、フロントエンドエンジニアとは CSSModules や RxJS、CycleJS に至るまで技術トークで盛り上がった。フロントエンド技術に対して非常に情熱を持っているエンジニアだと感じた。
面接結果
内定辞退。
PM は僕が Accupass チームに加わることを強く望んでくれていたようで、辞退後にも電話で理由を尋ねられ、また機会があればぜひ一緒に働きましょうと言ってくれた。ただ、他により魅力的なポジションがあったため、今回は Accupass のオファーを辞退することにした。
2. Linker Network Inc. 美商寶蘊凌科網路科技
応募職種:Frontend Developer
IoT、AI、機械学習向けのクラウドコンピューティングプラットフォームを開発している企業。これらのプラットフォームには UI が不可欠なため、フロントエンドエンジニアを募集していた。公式サイトはかなり簡素で全貌が掴みにくかったが、手がけている技術の難易度は非常に高い。
面接前
104 から自主応募し、電話で面接に招待された。高度な技術を扱っており、オフラインでコミュニティイベントなども主催している企業だ。
面接中
技術的な土台が非常にしっかりしている企業だと感じた。自己紹介ではこれまでの実務経験や、React・Redux の使用経験について話した。
後から知ったのだが、面接を担当してくれたのはなんと c9s 氏だった。どこかで見た顔だとは思っていたが、やはり技術への深い理解を持つ大物エンジニアだった(ただ、本人は少々疲れ気味に見えた)。
面接では最適化寄りの問題がいくつか出題された:
- JS はどのように minify(圧縮)されるか? JS の minify プロセスを大まかに説明させられ、最終的にはコード内の不要な空白をどうやって除去するかという議論になった。アイデア自体はシンプルだが、実装には注意すべき細かな点がある。当時はそこまで深く考えておらず、何度もヒントをもらってようやくコードを書くことができた。
- フロントエンドのパフォーマンスチューニングはどのように行うか? リクエスト数を減らすための Base64 エンコード、キャッシュ、ServiceWorker など一般的な手法を挙げたが、面接官の琴線にはあまり触れなかったようだ。
- もし SPA のフレームワークを自作するなら、どう設計するか? 僕ならまず router の処理を考える。SPA はフロントエンド側でルーティングを制御する必要があるからだ。その後、ライフサイクルの考慮も必要だと指摘された。
- Javascript の基礎的な質問
- プロトタイプチェーンの仕組み
newの裏側で何が起きているか?- 継承はどのように実装するか
thisは何を指すか
最後にマネージャーらしき方から、会社の現状や今後の展望などについての話があった。
面接結果
サイレントお祈り(3週間経過しても音沙汰なし)。僕の実力不足だったのだろう。
3. 台湾楽天市場
応募職種:Frontend Developer
以前一度面接を受けたことがあったが、当時はフルタイムでの勤務が難しかった(それが理由かは定かではないが)。そのため今回再応募した。オフィスの雰囲気は一般的な大企業そのもので、社員証がないと執務室には入れない。
面接前
HR から連絡があり、身上書とコーディングテストが送られてきた。フォーマットは 104 の履歴書とほぼ同じだった。ここで特筆したいのは、面接の案内メールだ。
一般的な企業はメールに住所を載せるだけだが、楽天市場は「◯◯番出口」「◯◯銀行の上」「エレベーターを出て右」など、重要な目印を細かく記載してくれていた。些細な気配りだが、応募者にとっては非常にありがたい。炎天下で Google マップを見ながら逆方向に歩いてしまうリスクを避けられるからだ。
面接中
今回の面接は以前よりも形式化が進んでいたようで、知能テストや適性検査のペーパーテストまであった。四則演算のような問題だったが、何問か間違えた気がする(笑)。その分、面接全体のプロセスも少し長くなった。
エンジニアとの面接は終始和やかで、主に実務経験や技術への理解について語り合った。面接官のエンジニア2名も非常に技術力の高いベテランだと感じられた。そのうち1人は以前僕を面接してくれた方で、「技術力に関しては何の問題もないと思っているよ」と言ってくれたのだが、当時は兵役のタイミングが合わずに不採用になっていた経緯があり、その言葉には胸が熱くなった。
後で知ったのだが、もう1人の面接官はなんと react-bootstrap-table の作者だった。
面接では主に Javascript に関する問題が出された:
- 再帰とその実践的な応用 例えば文字列を反転させる問題を再帰で実装するよう指示され、そのメリットを問われた。頭を抱えて考えたが思いつかず、ネットで調べても答えは見つからなかった。
- クロージャと開発における実践的な活用法
- IIFE(即時実行関数)のメリット いくつか例を挙げたところ、エンジニアの一人が jQuery のソースコードを例に、IIFE は minify にも有効(window などを引数化して短縮できるため)だと教えてくれた。その視点は今まで考えたこともなかった。
- React、Redux の開発ユースケース Redux でよくある開発シナリオ、store の管理方法、React のライフサイクルの活用など。
- (追記)
+を使わずに加算機能を実装する方法 ビット演算子の理解を問う問題。XORを使えば実装可能で、高校の加算器の授業で習った内容だったが、真理値表を描く必要があった。 - (追記)台湾楽天市場で非常に印象に残った標語がある:「複雑なものを単純化し、単純なものをプロセス化し、プロセス化したものを標準化し、標準化したものを自動化する。」(原文ママかは定かではないが)
その後、CI/CD や開発プロセスの回し方など、エンジニアリング寄りの質問を受けた。楽天市場の技術スタックは幅広く、Angular、React、Ruby on Rails、GraphQL など多岐にわたっていた。
面接結果
やはり採用要件を満たしきれなかったようで、実質的にお見送りとなった。しかしフロントエンドチームの地盤は極めて強固だと感じた。2人のエンジニアはフロントエンド以外にも幅広い領域の開発経験があり、とても親切だった。面接終了時にはドリンクをご馳走してくれ(オフィスの自動販売機だが・笑)、キャリアについてのアドバイスもたくさんくれた。
4. Codementor
応募職種:Frontend Developer
1対1のオンラインメンターサービスを展開している企業。そこから派生して、オンラインコードレビュー、デバッグ、ペアプログラミングなどのサービスも手がけている。
面接前
技術レベルが高く、相手にするユーザーもエンジニアであるため、良い修行の場になると思い 104 から応募した。翌日には HR からオンライン面接の案内が届いた。個人的にオンライン面接は非常にありがたい。わざわざ会社まで出向かなくて済むのは、エンジニアにとって大きなメリットだ。
面接中
一次面接 — エンジニア面接
チームリードとの面接。これまでの実務経験や開発上の課題について話し、口頭で Javascript と React の理解度を問う質問を受けた。
- クロージャについて
- Flux vs MVC。何が解決されたのか:正直、Flux を実務で使ったことはなく、アーキテクチャ図とコードを見たことがある程度だったため、自分なりの理解で答えた。
- Javascript はどのように非同期処理を実現しているか?コールスタックとイベントループについての理解。
二次面接 — 共同創業者(Co-founder)面接
同じくオンラインで共同創業者と対談。このフェーズでは技術的な質問は少なく、自己紹介の後に僕のサイドプロジェクトにとても興味を持ってくれた。立ち上げの動機や、なぜそれを本格的なサービスまで育てなかったのかなどを聞かれた。面接の多くの時間をこの小さなプロジェクトの話に費やし、Codementor 側でも似たようなコンテンツプラットフォーム事業を展開していることなどを話してくれた。
その後、Codementor の沿革やチームカルチャーについて質問した。所要時間は30〜40分ほどだった。
三次面接 — CEO 面接
CEO はカリフォルニア在住のため、同様にオンラインで実施。主にこれまでの業務内容、開発経験、そしてパーソナリティに関する質問が中心だった。対話を通じてカルチャーマッチを見極めようとしていたのだと思う。時間は30〜40分程度。
Codementor の共同創業者も CEO もエンジニア出身であるため、上から目線のような威圧感が一切なく、非常に心地よく話すことができた。
最後に「君は自分のことを頭が良い人間だと思うか?」と聞かれた。僕は「いいえ」と答えた。より多くのコードやアルゴリズムに触れれば触れるほど、自分の至らなさを痛感するからだ。
自分には React のような巨大なアーキテクチャを設計することも、各種の高度なソートアルゴリズムを生み出すことも一生できないかもしれない。どう考えても自分が聡明だとは思えなかった。
面接後
約5日後にお祈りの連絡があった。よりシニアなフロントエンドエンジニアを採用したとのことだった。Codementor は非常に好印象な会社で、CEO もチームリードも自社プロダクトに対して深い情熱を持っていることが伝わってきた。将来また機会があればぜひ一緒に仕事をしてみたい。
5. 17 media
応募職種:Frontend Developer
今回受けた中で、おそらく最も面接が楽しかった企業だ。f2e jobs で求人情報を見かけ、応募を迷っていたところ、知人の推薦で面接の機会を得た。
面接中
チームリードの終業後の時間に合わせて 18:30 からのスタートだった。僕が時間通りにオフィスに到着すると、チームリードもぴったり時間通りに現れた。この時間への誠実さにはとても好感が持てた。
企業によっては応募者がいつ来るか把握しておらず、エンジニアが作業中に突然呼び出されて慌てて準備したり、その場で履歴書に目を通したりすることも少なくない。これまで何人面接したのか尋ねてみると、彼は Slack の履歴を見せてくれ、遅刻した人数までしっかりメモしてあった。時間を極めて大切にする人だった。
最初は HR の案内でオフィスを一周した。オフィスはかなり広く、スナックコーナーや冷蔵庫の充実ぶりが凄まじかった。コーヒーマシンや豆、電子レンジなども揃っていた。開発チームには別の執務室もあるらしいが、当日見た限りではやや手狭そうだった。
続いてチームリードによる面接。まずは自己紹介とこれまでの実務経験を話した。
対話を通じて会社やチームの現状についても教えてくれた。チームのメンバーをとても大切に守っている人だという印象を受けた。その後、ライブコーディングへ。現場のリアルな環境を再現するためネット接続は遮断されず、主に Javascript の一般的な開発パターンや組み込み関数の実装が問われた。
コードを書き終えると、チームリードは僕が書いたコードをもとに技術的な議論を始めた。「なぜここはこのように書いたのか」「より良い書き方はあるか」など、彼は議論や質問、コードに対する意見出しに多くの時間を割いてくれた。まさに実際のコードレビューそのものだった。ここに最も時間がかかり、約1.5時間ほど費やした。
最後に、乱雑なコードを渡されてコードレビューとバグ修正を行い、ディスカッションを終えて面接は終了した。
オフィスを出た時にはすでに 21:50 頃になっていた。彼は非常に辛抱強く、ずっと傍で付き合ってくれた。特に印象的だったのは、正規表現の \B の使い方について議論したことだ。普段あまり意識して使われない正規表現だったため、本来の課題の議論が終わった後、僕から \B の使い方について質問してみた。
すると彼は \b や \w から \B に至るまで、一つひとつ丁寧に解説してくれた。長年抱いていた疑問が一瞬で解消された(ネット上でも \b をわかりやすく解説している記事は少ない)。
彼に対して感じた魅力は以下の通りだ:
- リアルであること:会社の現状を包み隠さず話してくれるため、入社後にギャップを感じることがない。また、会話の端々で仕事上の苦労や葛藤についても飾らずに話してくれ、酸いも甘いも噛み分けてきた経験を感じさせた。
- 誠実であること:奇をてらった難問でマウントを取るようなことはせず、コードの品質や改善策について対等に議論してくれた。これは面接において非常に貴重な体験だった。また、オフィスが広すぎて受付で誰を呼べばいいか迷ったと伝えたところ、HR にフィードバックしておくと言ってくれた。社交辞令かと思っていたが(多くの企業は聞き流すだけだからだ)、彼は本当に HR に伝えてくれており、非常に感動した。
面接結果
内定獲得。HR から電話があり、入社に関する手続きの説明を受けた。
面接の振り返り
面接は本当に疲れる。可能ならあちこち移動せず、すべてオンライン面接で完結させたいところだ。ものぐさなエンジニアにとってはそれが一番だ。
今回の面接を通じて、「仕事探し」以外にも多くの素晴らしい開発者たちに出会えた。彼らは必ずしも各種コミュニティで目立っているわけではないが、その実力と見識の深さは、コミュニティで誇張して振る舞う一部の開発者よりもはるかに勝っている。コミュニティ活動を否定するつもりはないし、コミュニティに多大な貢献をしている人も大勢いるが、オフラインの現場で黙々と力を尽くしている人たちもたくさんいる。露出の多さだけでエンジニアの実力を測るべきではない。
今回の面接で僕が「転職活動」を通して学んだこと、それは――「謙虚さ」だ。ソフトウェア開発の世界にはあまりにも多くの優秀な人間がいて、自分がどれほど無知であるかを絶えず思い知らされる。
1. 履歴書の準備
僕は普段から Medium や個人ブログを書く習慣があったため、履歴書にそれらのリンクを載せることができた。また、履歴書を GitHub 上で管理していたため、更新も非常にスムーズだった。
2. 実務経験の書き方
実務経験は単に会社名、役職、勤続年数を書くだけでは不十分だ。自分がどんな業務を担当し、会社で何を成し遂げたのかをできるだけ具体的に書くべきだ。例えば:
- React、Redux を用いた複雑な画面開発の管理
- トップページのローディングパフォーマンス最適化
こうした書き方の方が、単に「フロントエンド開発を担当」と書くよりもはるかに伝わりやすい。
3. サイドプロジェクト
仕事以外に、個人のサイドプロジェクトがあればなお良い。エンジニアであれば、自分で手を動かして解決したい課題が必ずあるはずだ。
サイドプロジェクトを見せることで、自分が興味を持っている領域や技術スタックを面接官に伝えることができる。どのプロジェクトにも、自分が深く悩んだり、解決に多くの時間を費やした特定の課題があるはずだ。
4. 逆質問を積極的に行う
面接とは本来、お互いに対話を交わす双方向のコミュニケーションであるべきで、一問一答の儀式であってはならない。相手に的確な質問を投げかけることで、その会社への理解をより深めることができる。
僕は普段、社内の開発体制について以下のような切り口から質問するようにしている:
- 自動化はされているか? いまだに手動で SSH ログインしてデプロイしている会社は少なくない。こうした開発体制は、予算申請のプロセスが煩雑だったり、自動化できる作業を放置していたりといった、企業カルチャーを間接的に反映していることが多い。
- バグはどのように解決しているか? バグへの対処法を見れば、その会社がどのようにタスクの優先順位を決めているかがわかる。例えば、バグは誰が報告し、誰が優先度を決定するのか。相手の回答を聞けば、スケジュール管理に一定の明確なルールが存在するかどうかを判断できる。
- 仕様変更は頻繁に発生するか? 仕様変更に関する質問には様々な切り口がある。「頻繁」とはどの程度か?どのタイミングで発生するのか?何をもって仕様変更と定義しているのか?これらを聞くことで、開発着手時は A と言っていたのに納品時には B を要求されるような理不尽な環境かどうかが浮き彫りになる。
あとはこれらの回答から深掘りして質問を重ねていけば、面接官の受け答えから会社の内部事情が自ずと見えてくるはずだ。
関連記事
- Three.js で僕の部屋を表現する 僕が React Three Fiber を使って実際の自分の部屋をブラウザ上に再現し、実世界のオブジェクトを目録に見立て、空間の記憶を通してここ数年の生活と仕事について語った話。
- フロントエンドで画像を扱う際に注意すべきこと Jake Archibaldの記事を起点に、現代のレスポンシブ画像の書き方を整理する。なぜwidth/heightを付ける必要があるのか、CSSのaspect-ratioはいつ使うべきか、AVIFとWebPの選び方、そしてpicture/source/srcsetを使ったモバイル向け画像の切り替えについて。
- CSS field-sizing — たった1行のCSSでフォーム要素を自動リサイズする かつてtextareaの自動高さ調整は、JavaScriptでscrollHeightを監視するしかなかった。しかしCSSのfield-sizing: contentなら、わずか1行で代替でき、textarea、input、selectに対応している。本記事では従来のやり方のペインポイントと、field-sizingの使い方をまとめる。
- リンクの下線をもっと見栄え良くする:text-underline-offset デフォルトでは下線と文字が近すぎて、このスタイルを好まないデザイナーもいるし、僕自身もあまり綺麗ではないと感じていた。