ハッシュマップの実用的な原則は、近年の一般的なJavaインタビューの質問です。ほぼすべてのJavaプログラマーがHashmapを知っており、Hashmapの使用場所を知っており、HashtableとHashmapの違いを知っています。では、なぜこのインタビューの質問がそんなに特別なのですか?これは、この質問が非常に深いためです。この質問は、多くの場合、高度なまたは中級レベルのインタビューに表示されます。投資銀行はこの質問をすることを好み、プログラミングスキルを調べるためにハッシュマップを実装するように依頼することさえできます。同時ハッシュマップやその他の同期セットの導入により、この問題はより複雑になります。探検の旅を始めましょう!
最初にいくつかの簡単な質問をしましょう
「ハッシュマップを使用しましたか?」 「ハッシュマップとは?なぜそれを使ったのですか?」
ほぼ全員が「はい」と答え、ハッシュマップなど、ハッシュマップのいくつかの機能に答えます。ハッシュテーブルはできません。ハッシュマップは非同期です。ハッシュマップは高速です。 Hashmap Storeキー価値ペアなど。これは、ハッシュマップを使用しており、非常に精通していることを示しています。しかし、インタビュアーはすぐにターンし、これからいくつかのトリッキーな質問をし始めました。ハッシュマップのより基本的な詳細について。インタビュアーは次の質問をすることができます。
「ハッシュマップがどのように機能するか知っていますか?」 「HashmapのGet()メソッドがどのように機能するか知っていますか?」
「標準のJava APIを詳細に検索しなかったので、JavaソースコードまたはJDKを開くことができます。」と答えるかもしれません。 「Googleで答えを見つけることができます。」
しかし、一部のインタビュアーは、「ハッシュマップはハッシュの原則に基づいています。Put(Key、Value)を使用してHashmapにオブジェクトを保存し、Hashmapからオブジェクトを使用してオブジェクトを取得します。ここでの重要なポイントは、Hashmapがバケツ内の重要なオブジェクトと値オブジェクトをmap.entryとして保存することを指摘することです。これは、オブジェクトを取得するロジックを理解するのに役立ちます。これに気付いていない場合、またはバケツに値を保存するだけだと誤って考えている場合、Hashmapからオブジェクトを取得する方法のロジックには答えません。この答えは非常に正しいものであり、インタビュアーがハッシュとハッシュマップの仕組みを知っていることも示しています。しかし、これは物語の始まりに過ぎません。インタビュアーがJavaプログラマーが毎日遭遇しなければならないいくつかの実際のシーンに参加すると、間違った答えが頻繁に現れます。次の質問は、ハッシュマップでの衝突検出と衝突の解決策に関するものかもしれません。
「2つのオブジェクトのハッシュコードが同じである場合はどうなりますか?」ここから本当の混乱が始まり、一部のインタビュアーは、ハッシュコードが同じであるため、2つのオブジェクトが等しく、ハッシュマップが例外をスローするか、保存されないと答えます。その後、インタビュアーは、equals()とhashcode()の2つの方法があることを彼らに思い出させ、ハッシュコードが同じであっても、それらは等しくないかもしれないことを伝えます。一部のインタビュアーはあきらめるかもしれませんが、他の人は前進し続けることができます。彼らは答えました、「ハッシュコードは同じであり、バケットの位置は同じであり、「衝突」が起こります。ハッシュマップはリンクされたリストを使用してオブジェクトを保存するため、このエントリ(キー価値ペアを含むMap.Entryオブジェクト)はリンクリストに保存されます。」この答えは非常に合理的です。衝突に対処するには多くの方法がありますが、この方法は最も簡単で、ハッシュマップの処理方法です。しかし、話はまだ終わっていません、そして、インタビュアーは次のように尋ね続けます。
「2つのキーのハッシュコードが同じ場合、どのように値オブジェクトを取得しますか?」インタビュアーが回答します:get()メソッドを呼び出すと、ハッシュマップはキーオブジェクトのハッシュコードを使用してバケットの場所を見つけてから値オブジェクトを取得します。インタビュアーは、2つの値オブジェクトが同じバケツに保存されている場合、答えを与えることを彼に思い出させます。値オブジェクトが見つかるまでリンクされたリストが横断されます。インタビュアーは、あなたが比較する値オブジェクトを持っていないので、尋ねます、あなたはどのように値オブジェクトを見つけるかどうかをどのように決定しましたか?インタビュアーがリンクリストにキー価値のペアをリンクリストに保存するまで保存しない限り、この質問に答えることができません。
この重要な知識ポイントを覚えているインタビュアーの何人かは、バケットの場所を見つけた後、keys.equals()メソッドを呼び出して、リンクリストに正しいノードを見つけ、最後に値オブジェクトを見つけると言うでしょう。完璧な答え!
多くの場合、インタビュアーは、HashCode()とEquals()メソッドを混乱させるため、このリンクで間違いを犯します。なぜなら、このhashcode()が繰り返し表示され、equals()メソッドが値オブジェクトを取得するときにのみ表示されるためです。優れた開発者の中には、不変の宣言されたオブジェクトを最終的に使用すると、適切なequal()およびHashCode()メソッドを使用すると、衝突の発生が減少し、効率が向上することを指摘します。不変性により、さまざまなキーのハッシュコードをキャッシュできます。これにより、オブジェクト全体を取得する速度が向上します。 StringやIntergerなどのラッパークラスをキーとして使用することは非常に良い選択です。
ここにあると思うなら、次の質問を聞くと驚くでしょう。 「ハッシュマップのサイズが荷重係数によって定義される容量を超えた場合はどうなりますか?」 Hashmapがどのように機能するかを本当に知らない限り、この質問には答えません。デフォルトの負荷係数サイズは0.75です。つまり、マップが他のコレクションクラス(アレイリストなどなど)と同様に75%のバケットを埋めると、元のハッシュマップの2倍のサイズのバケットアレイが作成され、元のオブジェクトを新しいバケットアレイに入れるために作成されます。このプロセスは、新しいバケットの場所を見つけるためのハッシュメソッドを呼び出すため、再ハッシュと呼ばれます。
この質問に答えることができれば、次の質問があります。あなたはそれに答えることができないかもしれません。この時点で、インタビュアーは、マルチスレッドの場合、人種状態があるかもしれないことを思い出させます。
ハッシュマップを変更するとき、実際には条件付き競争があります。両方のスレッドがハッシュマップのサイズを変更する必要があることがわかった場合、同時にサイズ変更を試みます。サイズ変更プロセス中、リンクリストに保存されている要素の順序は逆になります。これは、新しいバケット位置に移動すると、ハッシュマップはリンクリストの最後に要素を配置するのではなく、テールの移動を避けるためです。条件付き競争が発生した場合、悪循環があります。現時点では、インタビュアーに、なぜマルチスレッド環境でHashmapを使用する必要があるのかが非常に奇妙な理由を尋ねることができますか? :)
熱狂的な読者は、ハッシュマップについてより多くの質問を提供します:
1.文字列やインターガーなどのラッパークラスがキーとして適しているのはなぜですか? StringやIntergerのようなラッパークラスは、ハッシュマップキーとして最も適しており、文字列は最も一般的に使用されています。文字列は不変で最終的であり、equals()およびhashcode()メソッドが書き換えられているためです。他のラッパークラスにもこの機能があります。 HashCode()を計算するには、キー値が変更されないようにする必要があるため、不変性が必要です。キー値が、入力して取得するときに別のハッシュコードを返す場合、ハッシュマップから必要なオブジェクトを見つけることができません。不変性には、スレッドの安全性などの他の利点があります。フィールドをファイナルとして宣言するだけでハッシュコードが変わらないことを保証できる場合は、そうしてください。 equals()およびhashcode()メソッドはオブジェクトを取得するときに使用されるため、これら2つのメソッドを正しく書き換えることが非常に重要です。 2つの不均等なオブジェクトが異なるハッシュコードを返すと、衝突の可能性が小さくなり、ハッシュマップの性能が向上します。
2。カスタムオブジェクトをキーとして使用できますか?これは前の質問の拡張です。もちろん、equals()およびhashcode()メソッドの定義ルールに従う限り、任意のオブジェクトをキーとして使用でき、オブジェクトがマップに挿入された後、再び変更されません。このカスタムオブジェクトが不変の場合、作成後に変更できないため、キーとして条件をすでに満たしています。
3. CocurrentHashmapを使用してハッシュテーブルを置き換えることはできますか?これは、ますます多くの人々が同時ハッシュマップを使用しているため、もう1つの非常に人気のあるインタビューの質問です。ハッシュテーブルは同期されていることはわかっていますが、同期レベルに基づいてマップの一部をロックするため、同時ハッシュマップの同期が優れています。 Concurrenthashmapは確かにハッシュテーブルを置き換えることができますが、ハッシュテーブルはより強力なスレッドの安全性を提供します。このブログをチェックして、ハッシュテーブルと同時ハッシュマップの違いを確認してください。
この質問の深さと幅が直接関係していないため、私はこの質問が非常に好きです。これらの質問の設計に関する知識ポイントが何であるかを見てみましょう。
要約します
ハッシュマップの仕組み
HashMapはハッシュ原理に基づいており、put()およびget()メソッドを介してオブジェクトを保存して取得します。キー値ペアをput()メソッドに渡すと、キーオブジェクトのハッシュコード()メソッドを呼び出してハッシュコードを計算し、値オブジェクトを保存するバケット位置を見つけます。オブジェクトを取得すると、正しいキー値ペアがキーオブジェクトのequals()メソッドを介して見つかり、値オブジェクトが返されます。 HashMapは、リンクされたリストを使用して衝突問題を解決します。衝突が発生すると、オブジェクトはリンクリストの次のノードに保存されます。 HashMapは、リンクされた各リストノードにキー値ペアオブジェクトを保存します。
2つの異なるキーオブジェクトのハッシュコードが同じである場合はどうなりますか?それらは、同じバケットの場所にリンクリストに保存されます。キーオブジェクトのequals()メソッドは、キー値のペアを見つけるために使用されます。
HashMapには多くの利点があるため、HashMapをeコマースアプリケーションのキャッシュとして使用しました。 Javaは金融分野で多く使用されているため、パフォーマンスに関する考慮事項のために、HashMapとConcurrenthashmapを使用することがよくあります。ハッシュマップに関するより多くの記事を見ることができます。
ハッシュマップとハッシュテーブルの違い
ハッシュマップとハッシュセットの違い
オリジナルリンク:JavareVisited翻訳:Importnew.com -Tang Xiaojuan翻訳リンク:http://www.importnew.com/7099.html