こんにちは。AlphaDrive アプリケーションエンジニアの芥川です。
弊社では選考フローにモブプロ形式のライブコーディング面接を取り入れています(記事内では省略して「コーディング面接」と呼びます)。
私も昨年コーディング面接を受けて AlphaDrive に入社し、この 1 年くらいは面接官を担当するようになりました。
この記事では面接官としてコーディング面接をする上で意識していることを紹介したいと思います。主に「進め方」「フィードバック」「評価観点」について話します。
これから弊社の採用を受けようとしている方はもちろん、採用に携わっていてコーディング面接を導入・検討している方にも参考になればと思います。
本記事は、 NewsPicks Advent Calendar 2022 の 12/24 公開分の記事になります。
- 前日の記事からの連作です
- 目次
- コーディング面接で使用する問題について
- 面接の進め方と評価ポイント
- 候補者へのフィードバックで意識しているところ
- 実際にフィードバックで送っている内容の例
- 候補者に期待していること(評価観点)
- 「自走して働いてもらえるか」が大事
- まだプログラミング経験が浅い方へ
- 面接官としてのメリット・デメリット
- さいごに
前日の記事からの連作です
本記事は前日の CTO の赤澤による 面接の感想はお互い「楽しかった!」に。モブプロ型のコーディング面接で「候補者体験」と「内定承諾率」を両方向上した話 からの連作です。
コーディング面接を実施する理由やその効果を知りたい方は是非読んでみてください!
目次
- コーディング面接で使用する問題について
- 面接の進め方と評価ポイント
- 候補者へのフィードバックで意識しているところ
- 実際にフィードバックで送っている内容の例
- 候補者に期待していること(評価観点)
- 「自走して働いてもらえるか」が大事
- まだプログラミング経験が浅い方へ
- 面接官としてのメリット・デメリット
- さいごに
コーディング面接で使用する問題について
問題は弊社オリジナルのものをいくつか用意しており、候補者の経歴や希望ポジションを事前に確認した上で選んでいます。
今回は弊社で一番多く使われていて候補者を見極める際のベースとして使用している問題(ベース問題と呼びます)について説明します。
ベース問題に問題文のようなものはなく、候補者には 1 つのソースファイルが共有されます。
このソースコードは架空の製品の一機能を想定したものになっており、 60% くらいの完成度になっています。いわゆる Draft PR のような状態です。
読みにくかったり正しく動作しなかったりと改善ポイントがたくさんあるコードを制限時間内で可能な限り良いものに修正してもらうという内容になっています。
初めは JavaScript しかありませんでしたが、現在は弊社のプロダクトで採用されている TypeScript / Go にも移植されたため、候補者の方にはこの中から希望言語を選択してもらいます。
アイスブレイクやコードリーディング、質疑応答などの前後時間を抜くとコーディングに使える時間は 30 分ほどしかありません。
その短い時間で候補者のコーディングスキルや課題解決能力を判断できるような問題になっています。
面接の進め方と評価ポイント
コーディング面接はモブプロの形式で進行します。
候補者にはドライバーとしてコーディングを行ってもらいます。
弊社からはエンジニア 2 名がナビゲーターとして参加し、それぞれ進行役とサポート役に役割を分担しています。(スケジュールが空いている時は CTO も参加することがあります)
ナビゲーターの 2 人が同時に意見を出して候補者を混乱させてしまう可能性を考慮し、候補者とのコミュニケーションは進行役が行います。
進行役とサポート役はお互いテキストチャットで繋がっています。サポート役は候補者の行動で良い点や気になる点をリアルタイムに記録していきます。
また進行役に対して進行に関するアドバイスを随時送ります。タイムマネジメントをしたり進行役の方針を修正したりするのもサポート役の役割です。
アイスブレイク〜画面共有
挨拶と簡単なアイスブレイクを済ませたあと、候補者に問題ファイルを共有して好きなエディタや IDE で開いてもらいます。
普段のパフォーマンスを出してもらうため、コーディング環境の制限はかけないようにしています。
候補者に画面共有をしてもらいますが、途中でインターネットで検索する様子も観察したいため、エディタのみでなくデスクトップ全体を共有してもらうようにしています。
この際、急にデスクトップの共有をお願いすることで関係のないアプリが映ってしまい候補者の方を焦らせてしまうことがあったので、最近では事前の案内で画面全体を共有して欲しい旨を連絡しておくようになりました。
シチュエーション説明
開始準備ができたらまずはシチュエーションの説明を行います。
下記のような感じで、なるべく簡単に面接の趣旨が伝わるように説明します。
私達はとあるプロダクトの開発・運用を行っています。新人君にお願いしていたタスクのプルリクエストが上がってきましたが、上手く動作しなかったりと改善点が見つかりました。このコードに対して修正や改善を行ってください。
コードリーディング
次に 5 分の時間を取り、ソースコードの確認をしてもらいます。修正はまだ控えてもらうよう伝え、気になるところにはコメントでメモを残してもらうようにお願いしています。
候補者の邪魔にならないように、モブプロ面接の中でここだけは無言の時間になっています。
ここから評価は既に始まっていて、候補者がどういうところに注目しているか、どんなメモを残すか、何を調べるかなどを見させてもらっています。
処理内容の説明
リーディングが終了したら処理内容の説明を行ってもらいます。
コードブロック単位で要点を抑えて簡潔に説明できるとより評価が高いです。
多くのコードに触れていないとそういった説明をすることは難しく、候補者の経験を判断する材料になります。
コーディング開始
ここから 30 分を目安にコーディングを行ってもらいます。
候補者には次のように伝えています。
まずは実行エラーになる不具合がいくつかあるので、その調査・修正を行ってください。 全ての動作不具合を解消できたらコードに対して自由に改善を行ってください。
時間配分については、目安として経験 5 年の方で 10-15 分程度で不具合の修正を完了し、残りを改善に費やしていただけるくらいになっています。
ここからは基本的には候補者のコーディングを見ながら質問やアドバイスを行っていきます。
正解のコードというものは存在しませんので、我々の主観で実装された内容が趣旨に沿っているかを判断します。
正しい修正と判断した場合
修正した理由を尋ねて、不具合の原因と直した結果結果どうなったかを説明してもらいます。
ここで言語仕様に対する理解度を確認することができます。
間違った修正と判断した場合
修正の間違いに自ら気づくことができるか、少し様子を見ます。
しばらく待ってから「その修正で先ほどの問題は解決されましたか?」と気づきを与えるようにし、「エラーメッセージを読み直す」「調査範囲を広げてみる」「処理を再度トレースしてみる」「ログを挟んでみる」などから適切な提案をします。
修正が的外れだった場合は、「何が起こっているか」「どう解消するべきか」といった質問を行い、候補者との間で認識を揃えるようにします。
手が止まった場合
手が止まってしばらく経過した場合は何に困っているか質問し、アドバイスするための手がかりを探ります。
この際に候補者が何か仮説を持っているかを確認することが重要だと考えています。
「疑わしいところはあるけど自信がないから手を付けず考えていた」ようなケースもあり、それも考慮して候補者の考えを引き出します。
仮説が合っている場合はもう少しで解決できるため、検索して自分で解決してもらうように誘導します。
仮説が間違っている場合は「間違った修正と判断した場合」と同じように思い込みを捨てて考え直してみるよう誘導します。
コード改善・リファクタリング
修正が全て完了し正しく動作するようになれば、残り時間でコードの改善を行ってもらいます。
この改善には特にルールを設けていません。候補者のこれまでの経験や得意分野をアピールできるポイントなので自由に行ってもらいます。
可読性や運用保守を想定したリファクタリング・パフォーマンス改善などを行ってもらうことが多いです。(たまに面白い改善を行う方もいますが、答えになってしまうため紹介できないのが残念です。)
実際に修正できるほど時間が余っていない方には、どういうところを改善したかったか口頭で確認させてもらいます。
フィードバック・質疑応答
コーディングが終わったら候補者に感想を尋ね、こちらからのフィードバックも共有します。
候補者に「楽しかった」と言って貰える時はやはり嬉しいですが、一方で落ち込んだ感想を聞くこともあります。
どちらにせよ今後のために自信を持って面接を終えて欲しいため、こちらからのフィードバックで「良かった点」と「改善すると良くなる点」を共有します。
ここではそれぞれのエンジニアから 1,2 点ほど簡潔に伝えるようにしています。
また、興味深いところがあれば履歴書やフィードバックの内容を深掘って技術質問を行ったりもします。
最後に候補者からの質問に答え、面接を終了します。
評価の相談・記入
面接終了後、エンジニア 2 人で候補者の評価を相談し採用ツールに記入します。ここはお互いのスケジュールが空いている場合は音声通話を開いてペアワークで行います。
合否の意見がズレることはあまりないです。これはメンバー間で評価基準の認識が揃っているからかなと思います。
また合否結果のメールに改めて面接でのフィードバックを添えるため、それも考えます(次の章で説明します)。
評価やフィードバックの清書作業も含めて、この作業にはいつも 30 分から 1 時間ほどかかります。
候補者へのフィードバックで意識しているところ
フィードバックは候補者体験に大きく関わり、オファー承諾率やひいては今後の弊社の採用にも影響してくると考えています。その分丁寧に行うよう心がけています。
オファー承諾率を上げる
選考が終了しオファーを出した時点で立場が変わります。今度は私達が候補者に選んでもらう側になります。
コーディング面接の体験とフィードバックの内容が候補者に印象づいていれば、他の内定企業の中から自社を選んでもらう理由が一つ増えると考えています。
今後の採用応募にも良い影響を与える
フィードバックを丁寧に送ることは今後の自社の採用にも少なからず良い影響をもたらすと考えています。
候補者はそれぞれが他の候補者になる可能性のある人と繋がりを持っており、選考の結果に関わらず候補者を満足させることができていれば「AlphaDrive のコーディング面接は良かったよ」「ちゃんとフィードバックがもらえるから受けてみるといいよ」と口コミで紹介してもらうことができます。
特にエンジニアを目指している学生は大学や SNS でコミュニティを作って情報交換をしているとインターン生からも耳にしています。
そこで自社の名前を挙げてもらうことは選考の応募数にも良い影響が出ると考えています。
丁寧なフィードバックを心がける
これは自分自身の経験に基づいていますが、就職活動をしている際は複数の企業の選考を並行して受けると思います。
落選が続いた場合はどうしてもメンタルが通常よりも弱ってしまうと思います。その状態でフィードバックを目にする可能性を想定して、追い討ちになってしまわないように気をつけます。
考え過ぎかも知れませんが、最悪のパターンとして「指摘を重く受け止めすぎて候補者がエンジニアの道を諦める」可能性もあると思っていて、そのための配慮は少し過剰なくらいにしておくのが良いと考えています。
実際にフィードバックで送っている内容の例
実際に送っているフィードバックの内容を例として紹介します。候補者や問題内容の特定に繋がらないように加工しています。
素晴らしかった点
まず良かった点を 3 個以上記載し、細かなことでもちゃんと伝えて自信を持ってもらいます。
例:
- 思考を言語化し、修正理由を説明しながらコーディングできていたため、ペアプロが得意そうな印象を受けました。
- 考えや修正内容を言語化してしっかりと説明いただき、リモートワークでもコミュニケーションを取って活躍されておられると感じました!
- 問題に直面した時に仮説を立てながら修正できていた点も拝見し、普段から自走して開発を楽しんでおられるのだなと思いました。
- コードリーディングの時点でエラーに気付いたり、エラーメッセージを見ただけでバグの特徴を判断できたところなど、しっかりとプログラミングを学ばれているように感じました。
- コードをシンプルに書き換えて可読性を向上できており、仕様や背景を確認した上で不要な処理を消せていたのも良かったです。
- 既存実装のアルゴリズムや変数名を変更するときにちゃんと意図を説明した上で、確認をとりながら改善してくれました。
- オブジェクト操作を Immutable に書き換えることができており、日頃から不具合を生みにくいコードを意識している印象を受けました。
- 必要に応じてログ出力とデバッガーを使い分けて問題を調査していたところも良かったです。
最近は通過した候補者に対しては「〇〇だから一緒に働いていただけると思った・弊社で△△してくれそうと思った」と候補者に対して一緒に働いてほしい熱意を伝えるようにもしています。
改善するともっと良くなる点
ここは先ほども述べたように、ダメ出しやマウンティングにならないように言葉のニュアンスに気をつけます。
またどうすると良くなるかを明記し、なるべく短期で実践できる内容に留めておくようにします。
例:
- for 文を map に置き換えようとしていましたが、JavaScript には他にも filter,reduce,some など様々な配列操作関数があります。それぞれの仕様を把握し、場合によって最適な関数を使い分けることができると良いと思いました。
- 不具合箇所を特定しないまま直そうとするのはあまり良くないと感じました。(実際にあった具体的なシーンも一緒に送ります)
- JavaScript の〇〇の仕様ついて、覚えておくとこれからの開発にも役に立つと思います!
- こちらのページに〇〇について書かれているので参考にしてみてください。(MDNなどリファレンスのリンクを添える)
- 処理内容が複雑な関数には、他のチームメンバーのために説明や参考元の情報などをコメントとして残しておくと良いです。
- コードから実装者の意図が読み取れるようになるとコードレビューする時によい意見を出せるようになると思います。
- 仮説通りに行かなかった時に一旦落ち着いて状況を整理し直すと良かったと思いました。
- プログラムは書いてある通りにしか動かないので、思い込みや前提を捨てて関数の先頭から処理をトレースし直せばもう少し早く解決できていたかも知れません。
- 検索結果など、外部に記載されているコードはバグを含んでいたりパフォーマンスが悪かったりすることがあります。
- その点も含めて判断した上でコードを採用することができれば良いと思いました。
- 〇〇について検索をした時に複数の対応パターンがヒットしましたが、各処理の内容を理解した上でどれが適切か比較検討できるとより良いコードが書けるようになると思いました。
通過した方に対しては入社するまでにできるようになっていて欲しいことを書いたりもします。
結果がどちらであれ、候補者の方の次に繋げられるようなフィードバックを送るように意識しています。
候補者に期待していること(評価観点)
私達はコーディング面接で「一緒に働いてもらえるか」「入社してから AlphaDrive で成長・活躍してもらえるか」といった軸で候補者の方を評価させていただくため、そのために必要な観点を用意しています。
以降に具体的な評価ポイントをいくつか挙げます。
候補者の経験により求めるスキルの度合いも変わってきます。「ジュニア」「シニア」といったワードが出てきますが、明確な基準はなく経験年数から大まかに分類しているとご理解ください。
- ジュニア:1-3 年
- シニア :4-10 年
- ベテラン:10 年以上
コミュニケーションスキル
弊社は親会社であるユーザベースの「スーパーフレックス制度」に則り、出社場所や勤務時間が制限されていません。
そのため普段の連絡は基本的には Slack や GitHub による非同期のテキストコミュニケーションが主流となっています。
(誤解がないように補足しますが、普段から必要に応じてビデオ会議やペアプロといった同期的なコミュニケーションも行なっています。)
そのためコミュニケーションが適切に取れることは重要な評価ポイントです。
より具体的な観点をいくつか記載します。
プログラムの処理内容を説明できるか
進行のところでも書きましたが、コードブロック単位で要点を抑えて簡潔に説明できると、多くのコードに触れてきた印象を受けます。
ジュニアの方は 1 行ずつトレースしながら読み上げてもらっても大丈夫です!処理を理解し、説明できることがまず大事です。
修正した理由を説明できるか
修正した内容について尋ねられた時にしっかりと説明できると、言語化能力に加えてその仕様を理解していることも確認できます。
逆にうまく説明できないとチーム内でコミュニケーションが取れないと感じてしまいますし、その仕様についても理解していない印象を受けてしまいます。
難しい問題に直面した時に状況を説明できるか
何が起きているか、何に困っているかを自分の中で整理して助けを求めることが大事です。
ジュニアの方は特に実際の業務でもチームメンバーに質問することが多いと思いますので、とても必要なスキルです。
不明な仕様に直面した時に質問や議論を適切に行うことができるか
ベース問題には仕様書はありませんので、実装を進めていく上でどういった制御を行うかの分岐点がいくつかあります。
対応パターンが複数あることに自発的に気付けるか、仕様・方針を確認するために質問してもらえるかというところも見ています。
またシニア以上の人には適切な仕様を提案することも期待し、逆質問で返すこともあります。
コードから実装者の意図を汲み取れるか
実務のコーディングでは参考にできるドキュメントやコメントがないソースコードに遭遇することがよくあり、実装者が既に退職しているケースもあります。
その場合目の前のコードにある情報が全てで、その処理内容を理解するためにはコードから実装者の意図を読み取る必要があります。
例えば変数に代入しているコードを見たときに、単に代入しているという事実で終わらせるのではなく、目的を想像し実装者の意図を考えると「入れ替えのためのバックアップ」だったり「可読性を高めるために変数の命名を変更しているだけ」だったりします。
ここまで実装者の意図を読み取ることでコードへの理解が深まり、より適した修正を施すことができます。
論理的思考ができているか
ベース問題にはうまく動作しないコードが紛れ込んでおり、不具合を調査して修正する必要があります。
ここで論理的思考ができていれば、エラーに対して仮説を立て、問題箇所を絞りこむことを繰り返して原因を特定することができます。
この解決までの過程を重要と考えて観察させてもらっています。
調査スキル
実務を想定した面接ですので、インターネットで検索することを許可しています。
普段のコーディングにおいても分からないことに直面するとインターネットや書籍を活用して調査して解決すると思います。
業務ではこれを自走して行うことが求められるため、外から得られる知識を活用して効率よく実装を進めることができるかを見ています。
気になったことはなんでも調べてもらって大丈夫です。その際どんな情報ソースを参考にしているかも評価ポイントとして見ています。
まだ実際にそんな人を見たことはないですが、お手持ちの参考書を開いてもらっても大丈夫です。
また外部のサイトからコードブロックをコピーしてきた場合には、よく分からないコードをコピペしてとりあえず動いたという結果で終わって欲しくないため、効率性や安全性について質問させてもらいます。
コーディングスキル
コーディングスキルももちろん重要なスキルとして評価しています。
パフォーマンスを意識しているか
処理を実装する時やインターネット上の外部コードを採用する時に、メモリや処理コストを意識できているかを見させてもらいます。
厳密に実行時間を計測したりまではしません。コードを見てスマートな処理を実装できていれば高評価となります。
シニア以上のエンジニアで明らかに無駄な処理が多い場合は低評価となってしまいます。
可読性を意識しているか
可読性の良いコードを書くことができるかも見させていただいています。
チーム開発をしているとお互いに毎日のようにコードレビューを行いますので、他人が見ても理解しやすいコードを実装することが大事です。
また時にはパフォーマンスと可読性のどちらかを優先するためにもう一方を犠牲にすることもあります。
一概にどちらを優先するべきか決めることはできません。その場面でどういった理由を持ってその選択をしたかが大事で、そこを評価させてもらいます。
運用保守を想定したリファクタリングができるか
プロダクトを長く運用していると、自分の実装したコードの面倒を最後まで自分が見るということはまずありません。
つまり何もコンテキストを知らない他人が見ても処理内容を理解できるようにする必要があります。
可読性を意識したコードを実装することはもちろん、適切にコメントを付けたり、関数に分割して変数のスコープを狭くしたりなど気をつけることはたくさんあります。
事前にシチュエーションは伝えているので、コーディング面接の書き捨てのコードと思わずに長く運用することを意識して実装していただきたいです。
これはシニア以上の方には必須スキルで、後を気にしないコーディングをされていると低評価となります。
ジュニアの方はまだ運用保守を経験したことがない場合もあると思いますので、あまりマイナス評価にはなりません。現時点で自分の考える良いコードに直していただければと思います。
「自走して働いてもらえるか」が大事
ここまで色々と評価観点を記載しましたが、まとめると最終的には「自主的に・自走してタスクをこなしていただけるか」という点に収束します。
我々にはユーザベースのバリューである「自由主義で行こう」の文化が根付いており、受け身で他人に管理をゆだねるのではなく、自発的に行動してくれる方を求めています。
そのためには困難な課題に直面した時に様々な方法を駆使して解決できる必要があります。
ジュニアの方にも初めから全て自己完結することを求めているわけではありません。
コーディングにおいてはインターネットや書籍で調べたり、周りに現在困っていることと自分の考えを伝えた上でアドバイスを求めたりすることが大事です。
先ほどの評価観点は周りに助けを求めることも含めて、全て自走する上で必要なスキルになっています。
まだプログラミング経験が浅い方へ
今回はジュニアからベテランまで全ての候補者を対象としたコーディング面接の記事を書きました。
新卒やインターンで AlphaDrive の選考を検討されている方には難しそうな印象を与えてしまったかも知れませんが、もちろん候補者の経験に応じた評価を行いますので、弊社に興味を持っていただいた方は是非気軽に選考に応募してください!
経験が浅い方には即戦力になることは求めていません。
AlphaDrive は人の可能性を信じる企業です。最後まで自力で解くことができなくても、我々がアドバイスを挟んで最低限正しく動くところまでサポートします。
その過程を見させていただいた上で将来性があり成長いただけると判断した場合は通過となるケースも多くあります。
将来性を判断するために重要なスキルが「コミュニケーション」と「論理的思考」です。
論理的に考えることができ、チームメンバーに適切にヘルプを求めることができる方はある程度自走して働くことができ、弊社で成長していただけると考えています。そのため問題が難しいと思っても途中で諦めず、最後まで頑張ってください。
最後のフィードバックも候補者の今後に役立つように本当に丁寧に考えています。面接に落ちてしまっても「丁寧にフィードバックを受けることができて無料でメンタリングを受けた気分」と前向きに捉えて次に活かして欲しいと思います。
面接官としてのメリット・デメリット
最後にコーディング面接をやってみて自分自身が感じていることを書いてみます。
メリット
自分自身にも気づきがある
自分よりも優れた候補者の面接を担当する機会も多くあります。自分が知らなかった手法を見せられた時は学びになりますしワクワクします。
ペアプロに活かせる
私は黙々とコーディングするタイプなので、実況さながらにスラスラと説明しながら問題を解いている方は本当に凄いと思います。
そういった方の行動を参考にすることで社内でのペアプロにも活かすことができます。
また最近は比較的ジュニア層の候補者の面接を担当することが多いですが、その方々の考え方や躓きポイントを知ることで社内のジュニアエンジニアやインターン生の教育にも活かすことができます。
楽しい
上記で述べたように新しい発見が自分自身の学びになるし、候補者にアドバイスして解決に導くことは自分にも達成感があり、純粋に楽しいです。
面接よりも相手の情報を引き出せる
慣れの問題もあるとは思いますが、私は一般的な面接で面接官をするのが苦手です。何度か参加していますが、相手の情報を上手く引き出すことが難しく感じます。
コーディング面接であれば自分と相手の間にコードがあり、その事実を基に話を引き出したり議論したりできるため、評価の軸がブレないと考えています。
この点については前日の記事で赤澤がまとめてくれていますので、是非そちらもご確認ください。
デメリット
逆にデメリットも少しあると感じています。
面接官への負荷が高い
コーディング面接は通常の面接と比較して面接官への負荷が高いと感じています。
例えば普通の面接であればエンジニア一人にかかる時間は
- 事前の資料確認:10 分
- 面接:60 分
- フィードバック:20 分程度
で 90 分くらいかと思います。
対してコーディング面接では、「問題の選定・準備」で 10 分、「メールで送るためのフィードバック記入(丁寧に考える)」で 20 分ほど追加でかかります。合計してエンジニア一人にかかる時間が 30 分ほど多くなります(実際にはもう少しかかっているかも)。
ここは頑張ってもなかなか短縮できないと考えていますが、候補者体験向上のための必要コストかなと考えています。
属人化しやすい
これは通常の面接にも当てはまることではありますが、人が進行するのでなかなか属人化しやすい部分があると思います。
進行手順などはドキュメント化されていますが、それでも全ての面接官で同じ候補者体験を届けることはできないと思っています。
ただメリットのところでお伝えしたようにコーディングをベースに評価することができるため、評価判断の属人化については解消されているとも思えてきました。
この辺りに関してはなるべく仕組み化できるように今後もチャレンジしていきたいです。
さいごに
以前からコーディング面接についての記事を書いてみたいと思っていたのですが、実際に書いてみると伝えたいことがたくさんあってかなり長くなってしまいました…
ここまでお読みいただきありがとうございます。
再度になりますが、弊社のコーディング面接についてもっと知りたい方は前日の赤澤の記事も是非読んでみてください。
また、 AlphaDrive ではエンジニアを絶賛募集中です!興味を持っていただいた方は是非選考に応募してください 🙏
私はフロントエンドを主に担当しており、一緒に開発してくれるメンバーを求めています。是非ご応募お願いします!
フロントエンド以外の領域でも募集を行なっています。とりあえず話を聞いてみるだけでも構いませんので、下記のフォームからご連絡ください。
では、コーディング面接でお会いしましょう!