web-dev-qa-db-ja.com

マルチスレッド同期のインタビューの質問:mスレッドが与えられたnワードを見つける

この問題が、単一のスレッドではなく、複数のスレッドを持つソリューションから利益を得る方法はありますか?


インタビューで、複数のスレッドを使用して問題を解決するように依頼されました。複数のスレッドは何のメリットもないように思えます。

ここに問題があります:

N個の単語を含む段落が与えられ、m個のスレッドが与えられます。あなたがする必要があるのは、各スレッドが1つのWordを印刷し、次のスレッドにコントロールを与えることです。これにより、各スレッドは1つのWordを印刷し続けます。最後のスレッドが来た場合、最初のスレッドを呼び出す必要があります。すべての単語が段落に印刷されるまで印刷が繰り返されます。最後に、すべてのスレッドが正常に終了します。どのような同期が使用されますか?

ここではスレッドを利用できないと強く感じますが、インタビュアーが私の同期スキルを測定しようとしていると信じています。この問題で、複数のスレッドに価値をもたらす何かが欠けていますか?

コードは必要ありません。考えてみてください。自分で実装します。

23
rplusg

彼らはあなたをセマフォソリューションに導いているように思えます。セマフォは、自分の番であることを別のスレッドに通知するために使用されます。これらは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])
21
Karl Bielefeldt

私の意見では、これは素晴らしいインタビューの質問です-少なくとも(1)候補者がスレッド処理に関する深い知識を持っていることが期待され、(2)インタビュアーも深い知識を持ち、質問を使用して候補者を調査していると仮定します。インタビュアーが特定の狭い回答を探していた可能性は常にありますが、有能なインタビュアーは以下を探しているはずです。

  • 抽象的な概念を具体的な実装と区別する能力。私はこれを主にいくつかのコメントのメタコメントとして投入します。いいえ、単一の単語リストをこの方法で処理しても意味がありません。ただし、異なる機能の複数のマシンにまたがる可能性のある操作のパイプラインの抽象的な概念は重要です。
  • 私の経験(約30年の分散、マルチプロセス、マルチスレッドアプリケーション)では、作業の分散は難しいことではありません。結果の収集と独立したプロセスの調整は、(私の経験では)ほとんどのスレッド化バグが発生する場所です。問題を単純なチェーンに蒸留することにより、面接担当者は候補者が調整についてどれほどよく考えているかを確認できます。さらに、インタビュアーは、「OK、各スレッドがそのWordを別のスレッドに送信して再構築する必要がある場合はどうなるか」など、あらゆる種類の後続の質問をする機会があります。
  • 候補者は、プロセッサのメモリモデルが実装にどのように影響するかについて考えていますか? 1つの操作の結果がL1キャッシュからフラッシュされない場合は、明らかな同時実行性がなくてもバグです。
  • 候補者はスレッド化とアプリケーションロジックを分離しますか?

この最後の点は、私の意見では、最も重要です。繰り返しますが、私の経験に基づいて、スレッド化がアプリケーションロジックと混合されると、スレッド化されたコードのデバッグが指数関数的に難しくなります(SOの例ですべてのSwingの質問を見てください)。最良のマルチスレッドコードは、明確に定義されたハンドオフを備えた、自己完結型のシングルスレッドコードとして記述されていると考えています。

これを念頭に置いて、私のアプローチは、各スレッドに2つのキューを与えることです。1つは入力用、もう1つは出力用です。スレッドは、入力キューの読み取り中にブロックし、文字列から最初のWordを取り出し、残りの文字列を出力キューに渡します。このアプローチのいくつかの機能:

  • アプリケーションコードは、キューの読み取り、データに対する処理、およびキューの書き込みを担当します。マルチスレッドであるかどうか、またはキューが1台のマシンのメモリ内キューであるか、世界の反対側にあるマシン間のTCPベースのキューであるかは関係ありません。
  • アプリケーションコードはシングルスレッドのように記述されているため、多くの足場を必要とせずに確定的な方法でテストできます。
  • 実行フェーズ中、アプリケーションコードは処理中の文字列を所有します。同時実行スレッドとの同期を気にする必要はありません。

とはいえ、有能な面接担当者が調査できる灰色の領域はまだたくさんあります。

  • 「承知しましたが、同時実行プリミティブについての知識を確認したいと思っています。ブロッキングキューを実装できますか?」もちろん、最初の答えは、選択したプラットフォームから事前に作成されたブロッキングキューを使用することです。ただし、スレッドを理解している場合は、プラットフォームがサポートする同期プリミティブを使用して、数十行のコードでキュー実装を作成できます。
  • 「プロセスの1つのステップに非常に時間がかかる場合はどうなりますか?」制限付きまたは制限なしの出力キューが必要かどうか、エラーを処理する方法、および遅延がある場合の全体的なスループットへの影響について考慮する必要があります。
  • ソース文字列を効率的にエンキューする方法。インメモリキューを処理している場合は必ずしも問題ではありませんが、マシン間を移動している場合は問題になる可能性があります。また、基礎となる不変のバイト配列の上にある読み取り専用ラッパーを探索することもできます。

最後に、並行プログラミングの経験がある場合は、すでにこのモデルに従っているいくつかのフレームワーク(たとえば、Java/ScalaのAkka)について話をするかもしれません。

22
kdgregory

インタビューの質問は、実際には、解決しようとしている問題についてのあなたを作ることを意図した、実際にはトリックの質問ですthink。質問について質問することは、現実世界であろうと面接であろうと、積分アプローチの一部任意問題です。技術面接での質問への取り組み方についてインターネットを流通しているビデオがいくつかあります(特にGoogleとおそらくMicrosoftを探してください)。

「ただ答えてみて、そこから地獄を抜け出してください。」

この思考パターンでインタビューに近づくと、働く価値のある会社のインタビューを爆破することになります。

(スレッディングから何かが)たくさん得られると思わない場合は、それを伝えてください。教えてください理由メリットはないと思います。彼らと話し合います。技術面接は、オープンなディスカッションプラットフォームであることを目的としています。あなたはそれがいかにそれについて何かを学んでしまうかもしれませんcan有用である。面接官があなたに言われたことを盲目的に実装しようとするだけではありません。

16
Demian Brecht

あなたが言ったように、私はこのシナリオがスレッド化からまったく利益を得たとしても、大きな利益をもたらすとは思いません。ほとんどの場合、シングルスレッドの実装よりも遅くなります。

ただし、私の答えは、Word配列のインデックスへのアクセスを制御するロックにアクセスしようとするタイトループの各スレッドを持つことです。各スレッドはロックを取得し、インデックスを取得し、対応するWordを配列から取得して出力し、インデックスをインクリメントしてからロックを解放します。インデックスが配列の最後にある場合、スレッドは終了します。

このようなもの:

while(true)
{
    lock(index)
    {
        if(index >= array.length())
          break;
        Console.WriteLine(array[index]);
        index++;
    }
}

これで次の要件が満たされるはずですが、スレッドの順序は保証されていません。他の解決策も聞いてみたいです。

0
ConditionRacer
  • まず、適切な区切り文字で段落をトークン化し、単語をキューに追加します。

  • N個のスレッドを作成し、スレッドプールに保持します。

  • スレッドプールを反復処理してスレッドを開始し、
    参加するスレッド。そして、最初のスレッドが終了したら、次のスレッドを開始します。

  • 各スレッドは、キューをポーリングして出力するだけです。

  • スレッドプール内ですべてのスレッドが使用されたら、プールの先頭から開始します。

0
java_mouse