インタビューで、複数のスレッドを使用して問題を解決するように依頼されました。複数のスレッドは何のメリットもないように思えます。
ここに問題があります:
N個の単語を含む段落が与えられ、m個のスレッドが与えられます。あなたがする必要があるのは、各スレッドが1つのWordを印刷し、次のスレッドにコントロールを与えることです。これにより、各スレッドは1つのWordを印刷し続けます。最後のスレッドが来た場合、最初のスレッドを呼び出す必要があります。すべての単語が段落に印刷されるまで印刷が繰り返されます。最後に、すべてのスレッドが正常に終了します。どのような同期が使用されますか?
ここではスレッドを利用できないと強く感じますが、インタビュアーが私の同期スキルを測定しようとしていると信じています。この問題で、複数のスレッドに価値をもたらす何かが欠けていますか?
コードは必要ありません。考えてみてください。自分で実装します。
彼らはあなたをセマフォソリューションに導いているように思えます。セマフォは、自分の番であることを別のスレッドに通知するために使用されます。これらはmutexよりも使用頻度がはるかに低いため、インタビューの質問として適切だと考えているのはこのためでしょう。これは、この例が不自然に思われる理由でもあります。
基本的には、m
セマフォを作成します。各スレッドx
はセマフォx
を待機し、処理を行った後、セマフォx+1
にポストします。疑似コード:
loop:
wait(semaphore[x])
if no more words:
post(semaphore[(x+1) % m])
exit
print Word
increment current Word pointer
post(semaphore[(x+1) % m])
私の意見では、これは素晴らしいインタビューの質問です-少なくとも(1)候補者がスレッド処理に関する深い知識を持っていることが期待され、(2)インタビュアーも深い知識を持ち、質問を使用して候補者を調査していると仮定します。インタビュアーが特定の狭い回答を探していた可能性は常にありますが、有能なインタビュアーは以下を探しているはずです。
この最後の点は、私の意見では、最も重要です。繰り返しますが、私の経験に基づいて、スレッド化がアプリケーションロジックと混合されると、スレッド化されたコードのデバッグが指数関数的に難しくなります(SOの例ですべてのSwingの質問を見てください)。最良のマルチスレッドコードは、明確に定義されたハンドオフを備えた、自己完結型のシングルスレッドコードとして記述されていると考えています。
これを念頭に置いて、私のアプローチは、各スレッドに2つのキューを与えることです。1つは入力用、もう1つは出力用です。スレッドは、入力キューの読み取り中にブロックし、文字列から最初のWordを取り出し、残りの文字列を出力キューに渡します。このアプローチのいくつかの機能:
とはいえ、有能な面接担当者が調査できる灰色の領域はまだたくさんあります。
最後に、並行プログラミングの経験がある場合は、すでにこのモデルに従っているいくつかのフレームワーク(たとえば、Java/ScalaのAkka)について話をするかもしれません。
インタビューの質問は、実際には、解決しようとしている問題についてのあなたを作ることを意図した、実際にはトリックの質問ですthink。質問について質問することは、現実世界であろうと面接であろうと、積分アプローチの一部任意問題です。技術面接での質問への取り組み方についてインターネットを流通しているビデオがいくつかあります(特にGoogleとおそらくMicrosoftを探してください)。
「ただ答えてみて、そこから地獄を抜け出してください。」
この思考パターンでインタビューに近づくと、働く価値のある会社のインタビューを爆破することになります。
(スレッディングから何かが)たくさん得られると思わない場合は、それを伝えてください。教えてください理由メリットはないと思います。彼らと話し合います。技術面接は、オープンなディスカッションプラットフォームであることを目的としています。あなたはそれがいかにそれについて何かを学んでしまうかもしれませんcan有用である。面接官があなたに言われたことを盲目的に実装しようとするだけではありません。
あなたが言ったように、私はこのシナリオがスレッド化からまったく利益を得たとしても、大きな利益をもたらすとは思いません。ほとんどの場合、シングルスレッドの実装よりも遅くなります。
ただし、私の答えは、Word配列のインデックスへのアクセスを制御するロックにアクセスしようとするタイトループの各スレッドを持つことです。各スレッドはロックを取得し、インデックスを取得し、対応するWordを配列から取得して出力し、インデックスをインクリメントしてからロックを解放します。インデックスが配列の最後にある場合、スレッドは終了します。
このようなもの:
while(true)
{
lock(index)
{
if(index >= array.length())
break;
Console.WriteLine(array[index]);
index++;
}
}
これで次の要件が満たされるはずですが、スレッドの順序は保証されていません。他の解決策も聞いてみたいです。
まず、適切な区切り文字で段落をトークン化し、単語をキューに追加します。
N個のスレッドを作成し、スレッドプールに保持します。
スレッドプールを反復処理してスレッドを開始し、
参加するスレッド。そして、最初のスレッドが終了したら、次のスレッドを開始します。
各スレッドは、キューをポーリングして出力するだけです。
スレッドプール内ですべてのスレッドが使用されたら、プールの先頭から開始します。