コードの記述は、インタビュープロセスの一部にすぎません。
論理的な問題を実際に解決することは、コード作成タスクの一部にすぎません。
インタビュアーは次のことを確認したい:
コードを書くことができます。言語で10年の専門的な経験を持つ多くの候補者は、コードをまったく作成できません。このテストは、これらの候補者を拒否することを目的としています。
コードを書く前に問題について考えます。多くの人はキーボードに飛び、数十行のコードを書いて、それについて考えずに時間をかけなかったため、元の問題を誤解していることに気づきました。
コードを書くときに自分を適応させることができます。ソリューションを見つけたとしますが、それを実装し始めたとき、最初のアイデアは最良のものではないように見えました。すぐに良いものに切り替えて、最終的に作成したコードをリファクタリングできますか?
これは、そのようなインタビューがよりインタラクティブであるべきであることも意味します。片手で入力する代わりに、ハンズフリーキットを購入するか、Skypeから電話をかけてヘッドセットを使用します。職場で入力しているときに入力し、コメントを入力し、何をするのかを説明します。突然不自然になります。
ペアプログラミングをしましたか?「はい」の場合、インタビューの状況は非常に似ていますが、面接担当者があなたに意見を述べない場合があり、終了時にキーボードを交換するように頼まない点が異なります。
ここに、純粋に数学的な問題のいくつかの例と、それが開発者の非数学的なスキルをどのように示しているかを示します。
例1:簡単なコーディング演習
JavaScriptでフィボナッチ数計算機を実装する必要があります。インデックスを変更できるはずです。フィボナッチ数列はこれらの規則に従います。
- シーケンスの最初の2つの数字は0と1です。
- 後続の各番号は、前の2つの合計です。
例:F 0 = 0、F 1 = 1、F 2 = 1、F 3 = 2、F 10 = 55
3分あります。
ここで、インタビュアーは、できるだけ早く考え、解決策を見つけ、すぐにそれを実装することを望んでいます。このような演習は、実際の開発者が行うこととは無関係であり、CS学位を取得するときに見つけることができるものにはるかに近いですが、インタビュアーはこの種のことを好むので、やってみましょう。また、時間の制約により自動テストを行うことができなくなるため、インタビュアーはおそらくこれを期待しないでしょう。
「アルゴリズムの説明から、再帰について考えることができます。2番目のルールは、次の再帰関数につながります。」
var fibonacci = function (n) {
return fibonacci(n - 2) + fibonacci(n - 1);
};
console.log(fibonacci(10));
「再帰を終了するには、fibonacci
関数の本体を置き換えることで特別なケースを追加します。」
switch (n) {
case 0: return 0;
case 1: return 1;
default: return fibonacci(n - 2) + fibonacci(n - 1);
}
「できた」
結論
私が言ったように、そのような演習は開発者の実際の仕事とはまったく関係ありません。それは無意味になりますか?少なくとも、それはその人が次のことを示しているからです。
問題について考えることができます。一部の候補者は完全に失われ、ストレス下では、問題にアプローチするための可能な方法を考えるためだけに割り当てられた時間以上かかります。
再帰を知っているか、通常のループで再帰を回避できます。後で、インタビュアーは、再帰を使用する/使用しない方法があり、再帰の利点/欠点は何かを尋ねる場合があります。
プログラミング言語の基礎を知っています。人switch
がガード句、条件句、辞書のどれを使用したかは関係ありません。背景に応じて、同じ候補を達成するために異なる候補者が異なるツールを選択します。
単体テスト、スケーラビリティ、パフォーマンスなどをもたらすことなく、問題に集中し続けます。インタビュアーは、パフォーマンスに関して合理的なレベルにするために何をすべきかを候補者が説明することを期待して、パフォーマンス面で上記の機能がなぜひどいのかを尋ねるかもしれません。
例2:難しい質問
JavaScriptでフィボナッチ数計算機を実装する必要があります。できるだけ速くする必要があります。0から100の範囲のインデックスを変更できるはずです。フィボナッチ数列は次のルールに従います。
- シーケンスの最初の2つの数字は0と1です。
- 後続の各番号は、前の2つの合計です。
例:F 0 = 0、F 1 = 1、F 2 = 1、F 3 = 2、F 10 = 55
3分あります。
現在、面接担当者は候補者の問題解決能力を気にせず、どの方法が他の方法よりも速いかを推測する能力に関心があることを示す興味深い制約があります。
これらのトリッキーな質問は通常、トリッキーな答えを招きます。ここでは、時間の制約があるため、複数の実装を作成し、それらをベンチマークし、最速のものをプロファイルし、最適なソリューションを提供する方法はありません。
代わりに、何について:
「Googleに「最初のフィボナッチ数」を教えてください... これは有望に見えます。では、単純な正規表現(それは矛盾になり)、我々は、値のコンマ区切りのリストを構築することができます。」
sed -e "s;\([0-9]*\) \([0-9]*\);'\2',;g" fbncc10.txt | tr '\n' ' '
「最後に、プログラム自体。」
var map = ['0', '1', '1', '2', '3', '5', '8', '13', '21', '34', '55', '89', '144', '233', '377', '610', '987', '1597', '2584', '4181', '6765', '10946', '17711', '28657', '46368', '75025', '121393', '196418', '317811', '514229', '832040', '1346269', '2178309', '3524578', '5702887', '9227465', '14930352', '24157817', '39088169', '63245986', '102334155', '165580141', '267914296', '433494437', '701408733', '1134903170', '1836311903', '2971215073', '4807526976', '7778742049', '12586269025', '20365011074', '32951280099', '53316291173', '86267571272', '139583862445', '225851433717', '365435296162', '591286729879', '956722026041', '1548008755920', '2504730781961', '4052739537881', '6557470319842', '10610209857723', '17167680177565', '27777890035288', '44945570212853', '72723460248141', '117669030460994', '190392490709135', '308061521170129', '498454011879264', '806515533049393', '1304969544928657', '2111485077978050', '3416454622906707', '5527939700884757', '8944394323791464', '14472334024676221', '23416728348467685', '37889062373143906', '61305790721611591', '99194853094755497', '160500643816367088', '259695496911122585', '420196140727489673', '679891637638612258', '1100087778366101931', '1779979416004714189', '2880067194370816120', '4660046610375530309', '7540113804746346429', '12200160415121876738', '19740274219868223167', '31940434634990099905', '51680708854858323072', '83621143489848422977', '135301852344706746049', '218922995834555169026', '354224848179261915075'];
var fibonacci = function (n) {
return map[n];
};
console.log(fibonacci(10));
結論
トリッキーな質問はトリッキーな答えを招きます。ヒロイックにならないでください。また、わずか3分の時間でベンチマークとプロファイリングを開始しないでください。経験を活かしながら問題を解決する賢い方法を考えてください。私の経験から、マップを使用する方が数値を計算するよりも速いかもしれないというヒントが得られます。それは間違っているかもしれませんが、時間の制約を考えると、この試みは予想されるはずです。
あなたのツールを知ることも助けになり、開発者のスキルの不可欠な部分です:正規表現を知らずに、割り当てられた3分間をグーグルでコンマ区切りリストに費やすか、必要な配列を作成するパーサーの作成を開始します。
優れた開発者とは、すぐにコーディングを開始する人ではなく、より良い機会が得られたときにコーディングを回避する方法を知っていることを忘れないでください。一部のインタビュアーは、コーディングのように見えますが、ほとんどコードを必要としない割り当てを提供することをheしません。
例3:完全なアプリケーション開発
JavaScriptでフィボナッチ数列を実装する必要があります。シーケンスの長さは、プログラムの実行中に決定されます。シーケンスは次のルールに従います。
- シーケンスの最初の2つの数字は0と1です。
- 後続の各番号は、前の2つの合計です。
例:0、1、1、2、3、5、8、13、21、34、55、89
アプリケーションはWebページとして表示される必要があり、ユーザーは入力フィールドからシーケンスの長さを指定できます。
1時間あります。
始めましょう。
「例のシーケンスは非常に役立ちます。これは、実装が完全に間違っているように見えないことを確認するための一連の単体テストを可能にするためです。一般に、node.jsにはMochaを使用し、クライアント側のJavaScriptにはQUnitを使用しますが、ここでは簡単にするために、テスト関数の束を投げます。」
「私は作成することにより、起動index.htm
してfib.js
ファイル。その後、index.htm
W3Cに準拠していない最小限のコードで埋めます(私のHTMLスキルに興味がある場合は、後で説明します)。
<label>Length</label> <input id="length" value="15" />
<input id="compute" type="button" value="Compute" />
<div id="result" style="font-weight:bold;"></div>
<div id="tests"></div>
<script src="fib.js"></script>
「フィボナッチジェネレーター関数を呼び出して結果を表示するコードを作成しましょう。」
fibonacci = (function () {
var compute,
init;
compute = function (length) {
// TODO: Implement Fibonacci sequence.
return [1, 2, 3];
};
init = function () {
var button = document.getElementById('compute');
button.addEventListener('onclick', function () {
var length = parseInt(document.getElementById('length').value, 10),
result;
console.log(
'Computing Fibonacci sequence of length ' + length + '.'
);
result = compute(length);
document.getElementById('result').innerText = result.join(', ');
});
};
return {
compute: compute,
init: init
};
}());
「コードを初めて実行する時が来ました...それは機能しません。何も起こりません。なぜ?"
「OK、fibonacci.init();
最後に忘れました。追加しましたが、何も起こりませんが、少なくともコンソールにメッセージが表示されるはずです。待ってください、そうではありませんonclick
がclick
、; 私はJQueryを頻繁に使用するので、プレーンJavaScriptのイベントの名前を忘れ始めます。」
「いくつかのテストを追加しましょう。」
ensureAreEqual = function (expected, actual) {
var testResultsContainer = document.getElementById('tests');
testResultsContainer.innerText += (expected.equals(actual) ?
'.' :
('Actual [' + actual.join(', ') + '] is different from ' +
'expected [' + expected.join(', ') + '].'));
};
test = function () {
ensureAreEqual([0], compute(1));
};
「配列の比較は難しい場合があるためArray.prototype.equals
、この回答からコードをコピーして貼り付けてください 。」
「アプリケーションを実行すると、次のように表示されます。」
実際の[1、2、3]は、予想される[0]とは異なります。
「return [1, 2, 3];
フィボナッチ数列の実際の実装()を考えると、テストは失敗しました。これは非常に期待されていました。これを変更する時が来ました。」
「元のステートメントから、フィボナッチ数列はで始まる[0, 1]
ため、次のようにcompute
なります。」
compute = function (length) {
var fib = [0];
return fib;
};
「これにより、最初のテストに合格することができ、2番目のテストを作成できるようになりました。」
ensureAreEqual([0, 1], compute(2));
「失敗するので、戻ってcompute
修正します。」
compute = function (length) {
var fib = [0, 1];
return length === 1 ? [0] : fib;
};
「今、両方のテストに合格しました。今度は非エッジケースに移行します。」
compute = function (length) {
var fib = [0, 1],
i,
next,
current = 1,
previous = 0;
for (i = 2; i < length; i += 1) {
next = current + previous;
previous = current;
current = next;
fib.push(next);
}
return length === 1 ? [0] : fib;
};
「100などのより大きな長さでは結果が正しく見えないことを除いて、3つのテストはすべて合格しました。これらの結果を正しく取得するには、任意の精度ライブラリを使用する必要がありました。改善すべき点もあります。たとえば、命名規則が悪い場合があります(何fib
ですか?)。HTML関連のJavaScriptコードは、コードをテストするだけでなく、別のオブジェクトにも移動する必要があります。また、compute(0)
入力のテストも確認もしていません。」
結論
この例を見ていくと、インタビュー中に予想される相互作用を見ることができます。すべてがスムーズであったわけではありません(最初にいくつかのミスをして、アプリケーションを実行しても何も起こらない恥ずかしい状況になりました)、元のアプローチは長いシーケンスの長さをサポートする必要がある場合は不十分でしたが、達成しましたそれを示すために:
- さまざまな問題に対処できますが、
- 私はテスト駆動開発を使用しています。フィボナッチ数列はこのための絶好の機会であり、
- ソースが信頼できる場合にコードをコピーして貼り付け、ゼロから作成するのは圧倒的に複雑でエラーが発生しやすいようです。
- 私はJQueryなどのライブラリに過度に依存していません。
- 適切な範囲を選択しました:インタビュアーはJavaScriptスキルを確認したいので、完璧できれいなHTMLを書くのに時間を無駄にしません:ここに時間を費やさないことで、単体テストの作成により多くの時間を費やすことができます。
- 終了するタイミングを知っており、完了したことを伝えますが、多くのものは完璧ではないことを念頭に置いてください(
compute(0)
失敗するようなものですが、デモにとっては問題ではありません)。
これは、インタビュアーがあなたに期待すべきことです。