ねぎ嫌い

始業前に学んだことを小出しに。最近はHacker Newsの人気記事をまとめてみたり。

2017-09-12 How to conduct a good programming interview

原文:How to conduct a good Programming Interview

プログラマへの良い面接の実施方法のお話。
ネット上を探し回れば「どのようなインタビューを受けたか」という話は出て来るが、
「どのようにインタビューをしたか」については出てこない。
この記事ではインタビュワーへ焦点を当てている。

一般的なインタビューの目的は似通っていて、以下を見ようとしている。

  • チームに加わったとして、ちゃんと動くコードを書けるのか?
  • コードと問題点について、ちゃんとチームメンバーと話し合うことが出来るのか?
  • 任意の問題や制約について推論できるのか
  • 一緒に楽しく働けるのか

しかしながら、幾つかの理由でふさわしくないとしている。

戦術的なゴールを立てる

現実主義

インタビューの内容は、仕事内容に似通ったものにすること。
今動いているコードをよりキレイにリファクタリングしたり、デバッグして問題点を発見したりするほうがよっぽど重要。

インタビューのためのプログラミングスキルよりも、より現実的な業務に沿ったプログラミングをさせること。

成功させるために準備する

インタビューで見たいのは候補者が実際にパフォーマンスを発揮できるかどうか。
実際の業務の環境と同じようにインタビューの環境をセットアップしてあげること。

作業時間を最大化する

プログラミングやデバッグ、設計などの作業にかける時間を最大化してあげること。
作業の内容をしっかりと理解させ、目的から逸れたら訂正すること。
ディスカッションは素晴らしいが、曖昧で不十分な説明はディスカッションですらない。

禁止事項

制約

偶然

提示したタスクを早めに負えられたとしても、その人が優秀なのか、たまたま与えられたタスクの経験があったのか判断するのは難しい。
そのため、主観的な考えや、複数の解決策のうち選択した理由や、もっと基本的なコーディングやリーディングなどができるかを見る。

時間

かけられる時間は40分から1時間が基本。
それ以上かけることは候補者のためにならない。
候補者にも他の仕事はあるので与えられた時間のなかで最善を尽くすこと。

ゴールではないこと

特定のアルゴリズムを実装させる

インタビュワーが見たいのは与えられた問題を正しく解けるかどうか、ではないはず。
プログラミングのインタビューはトレッドミルのように、
どこかを目指しているわけではなくただ走り続けることに意味がある。
走り続けている最中の様子を観察することで彼らの技術を測る。

候補者に試練を与える

候補者に対して試練を与えることが一見普通に見えるかもしれないが、その考えは宜しくない。
試練を与えられた候補者は業務中にも何らかのプレッシャーを感じてしまう。

候補者に試練を与える2

挑戦的な課題や極めて困難な問題を与えることだけがインタビューの目的ではない。
インタビューの目的は候補者の能力を見極めることであり、問題はそれを達成するための手段でしか無い。

あら探し

プログラミングのインタビューはあら探しをする場所ではない。
既に記載の通り、成功させるためにインタビューを行うべき。
例えば、セミコロンの抜けやキャメルケースとスネークケースの混同などは無視しても問題ない。

インタビューの前に

乱雑で自由なタスクを選ぶ

最長増加部分列などのきれいでエレガントな問題は望ましくない。
このようなエレガントな問題はたいてい1つの最適解を持っているため、ランダム性が排除できない。
自由なタスクとはつまり人によって答えが異なるタスクを指す。
例えば、

このような偏在しているタスクは事前に勉強しておくことは不可能であるため、ラッキ-が少なくなる。
またインタビュワーは候補者の技術についてより深く理解することが出来る。

多段階のタスクを用意する

候補者が複数の段階にわけられるタスクを用意するべき。
トレッドミルのように色々と考え、実装を続けられるようなタスクによって候補者の技術力をはかる。

タスクをテストする

候補者にタスクを与える前に、同僚に問いてもらうこと。
この時自分は同僚の隣でさながらインタビューを行うときと同じように問いてもらう。
これによって、タスクの難しさが妥当か検証したり、バグの検出をしたり、
問題への異なるアプローチと解決策を明らかにすることが出来る。

インタビューを始める

開始前にインタビューの構成を計画する

最初にするべきことは、インタビューの構成を見直す。
60分のインタビューの場合、構成は

  • 何か合ったときのための5分のバッファ
  • 5分の履歴書を使った話し合い
  • 45分のコーディング
  • 5分の質問

いずれにしても、現在のインタビューの状態を明確にしておくこと。
これによって、候補者の期待を管理でき、候補者に時間の割当を計画させられる。

提供されたものから期待されることを明確に分ける

候補者に与えたものの意味を明確にし、同時に、候補者が期待されることを明確にする。
背景や制約、必須条件、スタブやAPIの使用条件を説明しておくこと。
候補者自身に考えさせることも出来るが、それは混乱を招いたりフラストレーションを感じさせる丈なのでやめる。

タスクを紙に印刷しておく

インタビューが始まる前に、問題文を印刷しておく。
候補者が必要な、背景と問題の詳細やインプットとアウトプットの例など、全てがそこに書かれるようにしておく。
候補者から何か質問があれば応えられるようにする。

インタビュー中

コードはコンピューター上に

候補者が望むに関わらず解決策はコンピューターに入力してもらう。
未だにホワイトボードを使用しているところもあるが、不十分である。

コードを実行・デバッグ可能にする

可能ならば、候補者の書いたコードが実行・デバッグ可能であるようにしておく。
バグが混在しているかどうかの不毛な論争を避けられる。
また、幾つかの利益も得られる

  • 候補者がずさんなコードを書かなくなる
  • 現実主義の項を達成できる
  • 候補者が成功しやすくなる
  • 試練を与えずにすむ

候補者がミスを犯したら

それは問題ない。
どのようにミスを探し、解決するかを見れば良い。
間違ったアプローチを炙り出せる可能性がある。

割り込みを最小化する

割り込み回数を最小にするよう意識する。
決して正しいアルゴリズムを用いて解決してほしいわけではないし、ミスを犯しても問題ない。
そこに時間を割いてもらうよりも継続的にコーディングをしてもらい、それを観察するべき。
以下のような場合には割り込みも許容される。

  • 候補者がコーディングを中断しているとき
  • 質問、懸念、指摘、コメントをまとめてするとき
  • 候補者が立ち止まったりなにも感じ取れなくなったとき

インタビューの終わりに

経過時間と共に感じたことを客観的に書き出す。
また主観的なことも別で書き出す。

理想的には主観的な点において、それを実証できるような客観的な事実と結びつけること。

結論

忘れてはいけないのは目的を明確にすること。

  • チームに加わったとして、ちゃんと動くコードを書けるのか?
  • コードと問題点について、ちゃんとチームメンバーと話し合うことが出来るのか?
  • 任意の問題や制約について推論できるのか
  • 一緒に楽しく働けるのか