3

最近、就職面接のコーディング演習の 1 つを完了する必要がありました。基本的に、次のようなメッセージ キュー クラスを実装する必要がありました。

  • 受信メッセージの優先度フィールドに基づいてアイテムを維持します。
  • メッセージは、message.priorityField 値の範囲によって制御される、高、中、低の 3 つの優先度カテゴリのいずれかになります。
  • getSize および isEmpty メソッドがあります。
  • place(message) メソッドがあります。
  • remove メソッドがあります。
  • getFront() メソッドがあります (最も優先度の高いメッセージを返します)

あまり詳しく説明せずに最後に行ったことは、メッセージを保持するために ConcurrentSkipListMap (並行して順序付けられたマップ) を内部的に使用する MessageQueue クラスを実装することです。

また、基本的なビジネス要件をテストする基本的な JUnit テスト ケースも実装しました。

これはメッセージング キューであり、メッセージが同時に着信する可能性があるため、もちろん、実装のオカレンスの側面をテストする必要があります。

私は今、質問の核心に近づいています。

私の考えでは、基本的な JUnit テスト ケースでは、単一のスレッドが実装と対話しているときにコードが機能することを確認する必要があります。

次に、実装の発生する側面を検証する必要がある並行テスト ケースを実装しました。

ここで質問があります。どのような並行側面をテストする必要がありますか?

私が考えることができる唯一のことは、キューにメソッドを注入する複数のプロデューサースレッドと、メッセージを削除する複数のコンシューマースレッド ( getFront() を介して) を持つことです。ここで検証されているのは、キューに入ったメッセージは最終的に出てくるということです。

しかし、それで十分ですか?ここでテストできる他の同時の側面は何ですか?

また、私はすでに解決策を提出しているため、あなたが提案したことが、私が応募したこの仕事の可能性に影響を与えることはありません.

4

1 に答える 1

2

スレッドセーフのテストは、基本的に、最終的な同時実行ごとにプログラムの正当性を証明しようとしているため、面倒です。これについては、いくつかの方法があります。

  1. JMMの観点から、プログラムの正当性を正式に証明します。これには、プログラム内の明示的な「発生前」の各エッジと、それらのエッジに基づいて一貫性がどのように維持されるかについて説明する必要があります。これはキューのような基本的なものでは可能ですが、より多くの機能とエッジが投入されると非常に複雑になります。いずれの場合もこのプロセスを実行し、並行コードを作成するときに意図/仮定を文書化することをお勧めします。

  2. カウントダウンラッチまたはプログラムの特定のポイントで実行スレッドを一時停止する他の手段を使用して、上記の意図された動作を示すテストケースを作成し、競合を強制します。これは、行き過ぎた場合にコードをひどい混乱に変える可能性がありますが、非常に役立つテクニックになる可能性があります。

  3. 十分な期間にわたってコードを実行することにより、統計的に正確性を示します。これは、JMMに関するJVM実装の正確さを検証するために使用される並行性拷問スイートの背後にある原則です。これには、参加しているスレッドの合法/違法状態についての期待を形成し、十分な並列スレッドを備えたマシンで十分長い時間プログラムを実行する必要があります。違法な状態に陥ったことがない場合、プログラムは正しいです:)。違法な状態に陥ることなく十分に長く実行すれば、おそらく正しいです。

于 2013-02-04T08:10:49.507 に答える