タイトルのとおり、ホワイトボードの面接で一番好きな問題は何ですか。また、なぜそれが効果的であると判明したのですか。
ジュニア、シニア、Java、C、Javascript、PHP、SQL、疑似コードなど.
私は候補者に実際に遭遇した問題の解決策を設計するを私の日常業務で求めます。そうすることで、私と候補者の間に対話を作ろうとします。私は彼が構築しているデザインについて、これまで問題について考えたことがないかのように話し合うようにしています。
私が評価しようとしているのは、お互いを理解できるかどうか、技術的な問題について混乱なく話せるかどうかです。
(Javaデスクトップ開発者向け)
Webブラウザーのナビゲーション履歴(前のページ、次のページ、前の10ページをリスト)を処理するAPIを設計します。これは、アプリケーションの多くの部分で再利用できます(ここでは具体的な例を示します)私たちのアプリで)。次に、実装をスケッチします。
私はこれが好きです、それは十分に単純で、簡単に説明でき、段階的に解決でき(すべてを壊すことなく追加の動作を追加できます)、エッジのケースやエラー処理について話したり、データについて話したりすることができます構造。
候補者を面接し、そこに何のビジネスもない候補者を除外するときに、これは非常に明るいと思いました。複雑さはFizz Buzzに似ていますが、データベースのスキルに重点を置いています。
Assuming the following basic table structure
Documents (DocID, DocDate)
Keywords (KeyWordID, KeyWord)
DocumentKeywords (DocID,KeywordID)
Write a query to return the following:
Part 1: Documents with a DocDate after 4/1/1995
Part 2: Documents that contain the keyword "Blue"
Part 3: Documents that contain the either the keyword "Blue" or "Yellow"
Part 4: Documents that contain the both the keywords "Blue" and "Yellow"
私は、彼らに彼らが望むどんなSQLバリアントでもそれを書くようにさせました、そして、軽微な構文問題にはあまりうるさくありません。主に、彼らがリレーショナルDBの基本的な概念を理解していることを知りたいです。
ほとんどの受験者は、パート3をまったく問題なくクリアできます。パート4の答えは、where句の演算子をORからANDに変更するだけであると考える人がどれだけ多いと思うか、驚くでしょう。
「ホワイトボードに、あなたが最後に取り組んだプロジェクトのデザインを、細かいところまで明かさずに描いてください。」
strcpy
、strcmp
などを実装します。
いくつかの専門分野を含む私のお気に入りは、インターフェイス(C#の場合)を指定して、バイナリツリーのノード数をカウントすることです。
public interface IBinaryTree<T>
{
IBinaryTree<T> Left
{
get;
}
IBinaryTree<T> Right
{
get;
}
T Data
{
get;
}
// Other properties and methods not germane to this problem.
}
面白さのために、ここに実装がありますが、インタビュー対象者はこれを見る必要はありません。
public sealed class BinaryTree<T> : IBinaryTree<T>
{
private readonly IBinaryTree<T> left;
private readonly IBinaryTree<T> right;
private readonly T data;
public BinaryTree(
IBinaryTree<T> left,
IBinaryTree<T> right,
T data)
{
this.left = left;
this.right = right;
this.data = data;
}
public IBinaryTree<T> Left
{
get
{
return this.left;
}
}
public IBinaryTree<T> Right
{
get
{
return this.right;
}
}
public T Data
{
get
{
return this.data;
}
}
// Other properties and methods not germane to this problem.
}
アシスタントクラス:
public static class BinaryTreeNodeCounter
{
public static int CountNodes<T>(this IBinaryTree<T> tree)
{
// TODO: What goes here?
}
}
私が見たい解決策はこれです:
public static class BinaryTreeNodeCounter
{
public static int CountNodes<T>(this IBinaryTree<T> tree)
{
return tree == null
? 0
: 1 + tree.Left.CountNodes() + tree.Right.CountNodes();
}
}
それは次の知識を示しています。
私にとって興味深いホワイトボードの議論を引き出した2つの質問は、
彼らは単純なものから始めて、それからさらに複雑になっていきます。
パズルやデザインの質問をホワイトボードの質問として使いたくありません。私は、候補者がコードを書く能力をテストする、単純明快な質問を好む。私のお気に入りは:
1)単一リンクリストを逆にする関数を記述します。 (3つのポインターが必要であることに気づくまでに少し時間がかかります。)
2)二分木を与えられて、二分木の深さを見つけなさい。 (この質問は、再帰的なコードを書く能力をテストします。ベースケースが損なわれていないかどうかを確認できます。)
3)整数の配列を二分探索するための手続きを書いてください。 (Jon Bentleyが(Programming Pearlsで)言うように、多くの人はバイナリ検索の作成を間違える傾向があります。その後、バグの発見、テストケースの作成、コードの実行などをフォローアップできます。)
私が働いていたある会社でこれを使用しました。
時間の追跡に使用する紙を候補者に渡しました。これは、1つまたは私たちの部門で使用される実際のタイムシートでした。候補者に、より良い時間追跡ツールを作成するための設計プロセスについて説明するよう依頼しました。境界はなく、どの言語なども言わず、候補者が「フルライフサイクル」でどれだけ優れているかを確認したいだけです。彼らが要件をどのように収集したかについての真の洞察が得られました。彼らがどのようにデータベーステーブルを構造化したか、どのようなUIをしたか。このタスクには明らかにコミュニケーションスキルが必要でした。これは通常、いくつかの大きなホワイトボードのある部屋で行われ、2時間も続きました。
私たちはこのプロセスを使用して何人かを雇いました、そして彼らが仕事で本当にうまくいったなら、彼らは私たちにとって本当によくやった。それらが限界的であり、私たちがとにかくそれらを雇うことにした場合(別のトピック)、彼らは限界的なプログラマーでした。
自分のプログラミングドメインに関連する問題を使用しています。
Webアプリケーションを開発する場合、たとえば、レコードを削除するWebフォームを作成する方法や、データベースからレコードを削除する方法などを確認したいと思います。これにより、基本的なデータベースの原則を知っているかどうか、削除を確認するためにユーザーとどのように対話するか、およびソフト削除とは何かを知っているかどうかがわかります。
お気に入りはありません。私が選ぶ問題は、仕事によって大きく異なります。
彼らがインタビューで問題を完全に解決できるかどうか、彼らが使用するテクノロジーと言語、またはホワイトボードでコードがいかに粗末に見えるかは気にしません。私は思考パターンを探しています。彼らが問題を考え、解決する方法を彼らが知っているかどうかを見たいです。
私のお気に入りは私の友人が使用したものでした。
最初の「n」個の素数を生成/印刷/保存する関数を書いて、それがどのように機能し、どれほど効率的かを説明します。
次の理由でうまく機能します。
これはアルゴリズム的な質問なので、面接対象者が考え、次にその考えを説明できる必要があります。そうすれば、彼らの脳がどのように機能するかを確認できます。
言語に依存しません。
誰もがそれを完全に正しく理解することはほとんどありません(通常、Edgeのケースで見落とす(通常は1または2)か、負の数を処理しないため、バグの処理方法とそれらが間違っていると言われるのを確認できます。
ほとんどは単純ですが非常に遅いふるいとしてそれを行います(たとえば、80%の人がnをn未満のすべての整数で除算することによりnが素数かどうかをチェックします)。これにより、アルゴリズムベースをどのように改善できるかについての会話の多くのスコープが得られます空間/時間のトレードオフなど「2で割り切れないことがわかっているのに、なぜ4で割っているのですか?」または「sqrt(n)未満のすべての素数で除算する必要があるだけでなく、どこかにそれらの数値を格納する必要があることを理解したので、その意味は何ですか?」)
彼らが正解する必要はありません。誰かが考え、自分の考えを説明できれば、彼らは良い候補者になるための道のりはかなり遠いでしょう。
それは本当にあなたが探しているものに依存します。画像を含む多くの動的なWeb作業を行う組織として、私はその仕事に関連するジオメトリの質問をする傾向があります。いずれにせよ、幾何学的な質問をする傾向があります。それは、素晴らしく視覚的な優れた数学のテストであり、候補者の能力を視覚的に提示し、問題を通して体系的に機能する能力を示すことができるからです。
高度な候補者のために、私は時々次の質問をします:
この画像は三日月を示しています。三日月のBからDまでの幅は9cmで、EとFの間は5cmです。 Cは大きな円の中心です。
a)三日月の面積を計算してください。
b)任意のサイズから内側の円に収まるように画像のサイズを変更するために必要な計算を説明し、中心点がわかっている場合は円内に配置します。
より簡単な質問の場合、私は通常同じ種類の質問をしますが、「正方形内の円内の正方形」の例を使用します。これは非常に簡単ですが、完全な代数を期待します。
それ以上に、可変長データセットのすべての組み合わせを生成するアルゴリズムを作成するように依頼する傾向があります。
私が見た中で最高のFizzBuzz答えは次のとおりです。
SQL Server 2008
;WITH mil AS (
SELECT TOP 100 ROW_NUMBER() OVER ( ORDER BY c.column_id ) [n]
FROM master.sys.all_columns as c
CROSS JOIN master.sys.all_columns as c2
)
SELECT CASE WHEN n % 3 = 0 THEN
CASE WHEN n % 5 = 0 THEN 'FizzBuzz' ELSE 'Fizz' END
WHEN n % 5 = 0 THEN 'Buzz'
ELSE CAST(n AS char(6))
END + CHAR(13)
FROM mil
C#(シンプル)
foreach (int number in Enumerable.Range(1, 100))
{
bool isDivisibleBy3 = (number % 3) == 0;
bool isDivisibleBy5 = (number % 5) == 0;
if (isDivisibleBy3)
Console.Write("Fizz");
if (isDivisibleBy5)
Console.Write("Buzz");
if (!isDivisibleBy3 && !isDivisibleBy5)
Console.Write(number);
Console.WriteLine();
}
C#(賢い)
Enumerable
.Range(1, 100)
.Select(i =>
i % 15 == 0 ? "FizzBuzz" :
i % 5 == 0 ? "Buzz" :
i % 3 == 0 ? "Fizz" :
i.ToString())
.ToList()
.ForEach(s => Console.WriteLine(s));
Aff_zと呼ばれるもの。これは私の工学部のC試験の一部であり、休日から戻ったときに生徒が失敗するようにする「ダミー」テストとして使用されました(私たちのマーキングシステムは、テストに失敗するとマーキングが停止したため、ダミーテストに失敗するとテスト全体を無効にします。モロニックの詳細に注意を払うように強制します)。面接で一、二回再利用しました。
とにかく...正確な定式化を忘れたけどこんな感じだった...
Write a function taking a single char parameter named c and returning nothing (void).
You function must satisfy the following requirements:
- if c is bigger or equal to 0, then print 'z' to standard output
- if c is stricly smaller than 0 , then print 'z' to standard output
- in any other case, print the letter 'z' to standard output
悲しいことに、答えが明らかな場合、一部の学生は非常に複雑な解決策を思い付くだけでなく、失敗することさえあります。
信じられないかもしれませんが、それはインタビュー中にも起こりました。
面接でそれを実行することはかなり楽しかったです、なぜならいくつかの申請者は可能な枝を書き始め、それから何が悪いのかを理解するでしょう(明らかに、あなたが口頭で尋ねるだけなら、あなたが話すときにそうすることは非常に理解できます...しかしあなたが書面でそれを与えてください、私はそれが不可解だと思います...)
それはばかげていますが、私はそれが最小限のスクリーニングだと思います(同様に、JSプログラマーを雇うとき、私は常に変数を宣言する方法を尋ね、次にvarを使用することがまったく違いがあるかどうかの回答に応じて、かなり悲しい瞬間、正直なところ。)
私は面接した候補者の中からいくつかのものを探します。オンラインで説明できない理由で、私たちはかなり貧しい候補者を得て、私はそれを期待するようになったので、私は彼らにかなり簡単です。それでも、私は探します:
デザインへの意識。
「番号の説明(cell/home/work/etc。)を持つ複数の電話番号を持つことができる、姓と名の連絡先を持つアドレス帳プログラムのテーブル構造を見せて」
ここでUML 2.0仕様図を探しているわけではありません。ここでは単純なバブル図で十分です。それが合理的である限り。
データベースの操作に関する知識(SQLなど)
テストの知識
以前のクエリの結果を返すシグネチャpublic IEnumerable<PhoneNumber> GetPhoneNumbers(string lastName)
を持つメソッドが存在するとします。メソッドにnullを渡すと、NullReferenceExceptionがスローされると仮定します。この機能を示すテストを作成します。
GetPhoneNumbersが姓が "smith"である人の自宅の電話番号(123)456-7890を返すことを示すテストを記述します。
コードの記述方法に関する知識
作成したテストの要件を満たすメソッドを実装します。
得られた応募者の数と質を考慮して、真剣に応募したすべての人にインタビューしました。私は誰も雇いませんでした。
次の問題のアルゴリズムを記述します:指定された数n、-nノードを持つ(一意の)バイナリツリーの総数を出力します。
したがって、n= 0およびn= 1の場合、答えは1です。n= 2の場合、2になります。ルートノード、次に、2番目のノードを左側または右側に配置します。
設計手法を理解し、再帰やメモ化、または動的プログラミングソリューションについて彼らが考えているかどうかを確認できます。
[このStackOverflow discussion も参照してくださいが、バイナリ検索ツリーの関連しているが異なるケースについては。]
ソフトウェア開発者にインタビューする場合、ソフトウェアを設計し、各行にフルネームを含む任意の大きなファイルから重複したエントリを削除するためのハードウェア要件を説明するように彼に依頼します。問題の説明の一部を意図的にあいまいにしています。次に、要件の分析と明確化、さまざまなトレードオフ、データ構造とアルゴリズム、I/O(セカンダリストレージ)、ソフトウェアとハードウェアのテクノロジー、スケーラビリティなどを理解しているかどうかを確認するように彼に要求します。
これは、小さいながらも挑戦的な問題であり、多くのコンピューティング領域における申請者の知識と能力を明らかにしています。
私のお気に入りのC++ホワイトボードの問題は、候補者が実装することです
Vector3 a(1, 0, 0), b(0, 1, 0); // Mathematical 3D vectors
double c = 7.0;
double d = a * c;
Vector3 e = a * b;
これから学ぶことができます
Implement function/method(on c/c++/c# whatever), which calculates n-th item of Fibonacci sequence
多くの人がこれにこだわることができました。何らかの解決策が与えられた場合-通常、それは再帰を使用します。その後:
Implement the same via 'for'-loop
両方のタスクを完了できなかったフェローの数-候補者の50%。
それが私がそれを気に入っている理由です:)
私が行くデータベースについて:
テーブル:モノ ID名 1ボドキンヴァンホーン 2フーフーズ 3フーフー 4ホット-ショット 5マービンオグレイルバルーンフェイス 6スリム 7マーヴィンオグレイルバルーンフェイス 8マーヴィンオグレイルバルーンフェイス 9デイブ
名前に基づいてこのようなテーブルの重複を排除するSQLをいくつか書いてください(どのIDを取得してもかまいませんが、返されるIDはその名前に対して有効でなければなりません)。したがって、正しいSQLが適用されると、テーブルは次のようになります。
テーブル:モノ ID名 1ボドキンヴァンホーン 2フーフーズ 4ホットショット 5マービンO 「砂利風船の顔 6 Snimm 9 Dave
私はそれが好きです:
(これは、これを行うには完全に些細な方法があり、私はここ数年それを複雑にしすぎていることに気づくところです)。
私は通常、最後に作業したシステムのブロック図をスケッチして、ブロック間の関係について尋ね、作業していた/担当しているブロックについて詳しく説明させます。このエクササイズから多くのことを学ぶことができます。たとえば、彼の小さな領域を超えてどのように見えるか、彼が「どこで」行動しているかを知ることは彼にとってどのくらい重要であるか、また、彼が果たしていた役割、それが鍵だったか側面だったかを知ることができます役割。
標準の52枚のカードデッキをどのように表現しますか?どのプログラミング言語でも問題ありません。どのようにカードをシャッフルしますか?
200匹の魚が入ったボウルがあります。これらの魚の99%はグッピーではありません。残っている魚の2%がグッピーになるように、いくつの魚を取り除くべきか。あなたの仕事を見せてください。
これは、混乱を招く要件についてです。このように、同じ質問の中で視点を複数回変更すると言われています。彼らが実際に何が起こっているのかを理解できるかどうかを確認することを意図しています。
多くの人がそれを誤解していることに驚くでしょう。
それが私に使用されて以来ずっと使用してきた1つの質問は次のとおりです。
1から100までのすべての数値を出力する関数を記述します。
私がそれを使用している理由の大部分は、そこに解決策を取り、さまざまな方向に移動できるという事実によるものです。
1から1000、10000、またはnの間のすべての数値を出力するように関数をどのように変更しますか?
これらの質問に対する回答は、変化する要件への対応方法や、パフォーマンスの考慮事項を認識できるかどうかについての洞察を提供します。有力な候補者は、関数が呼び出される頻度に必要な関数についての質問で応答する場合があります。
別の方向に移動する:
この関数が1分間に数回呼び出され、パフォーマンスが問題になることがわかっている場合、どのように変更しますか?
私はこれを彼らの側方思考をチェックする方法として使用します。最大値が大きくなると素数の計算が遅くなる可能性があるため、解決しようとしている問題に基づいて調整されたある種の計算済みまたは事前計算済みのルックアップテーブルを使用する方が理にかなっている場合があります。
ここにいくつかの考えを誘発するものがあります-それは簡単で、少しの数学を含み、基本的なコンピューター設計(オーバーフロー、数値表現など)の候補者の知識をチェックします:
X、Yの整数のペアを入力として受け取り、X * Yが10で割り切れるかどうかを判別するプログラム(またはプロシージャ)を記述します。あなたのマシンで。
T_BOOL MultipleOfTen(int x, int y)
{
return((x%2==0 || y%2==0) && (x%5==0 || y%5==0));
}
私のお気に入りは、printfのプロトタイプを尋ねることから始めることです。次に、1文字を出力する低レベルAPI printc(char c)を指定して、printfを実装します。スタックがCPUの一部であるなど、あらゆる種類の興味深い応答を提供します。ご想像のとおり、私はCと組み込みの背景の出身です。
私はいくつかのお気に入りがありますが、ほとんどいつも出てくるカップルがあります。ほとんどの場合、私は最終ラウンドのテクニカル(C++)インタビューを行っているので、関心のある新しい分野につながる、より長く、よりオープンな質問を支持します。 「正しい」答えはありません。他の会話への入り口です。
1)基本的な共有ポインターの実装、tr1またはboostの共有ポインターと比較して不足している箇所の説明、それらの実装での使用方法など。
2)コードレビュー。経験豊富な採用者には、設計上の問題、エラー、コーディングの恐ろしさ、潜在的な保守性の問題について、提供されたコードを自信を持ってレビューできることが期待されます。また、もちろん、どのように修正するか。そして時々彼らが彼らが撃墜しているジュニア開発者にそのメッセージをどのように与えるか。
次のメソッドを入力します。[〜#〜] ps [〜#〜]数値のモードは、(リスト内の)最も多く出現する数値です。
public int getMode(List<Integer> numberList) {
}
これは、コードが効率的であることを確認するためです。