web-dev-qa-db-ja.com

ハッシュ衝突とは何ですか

HashMapのHash CollisionまたはHashing Collisionは新しいトピックではありません。HashCollisionを作成する方法、またはHash Collisionを曖昧で詳細な方法で回避する方法を説明するいくつかのブログやディスカッションボードに出会いました。最近、インタビューでこの質問に出会いました。説明することがたくさんありましたが、正確に説明するのは本当に難しいと思います。ここで私の質問が繰り返される場合は申し訳ありませんが、正確な答えを教えてください:

  1. ハッシュ衝突とは正確に何ですか-それは機能、または誤って行われているが回避するのが一般的な現象ですか?
  2. ハッシュ衝突の正確な原因-カスタムクラスのhashCode()メソッドの定義が悪い、ORがequals()メソッドをオーバーライドせずに、オーバーライドしないままにするhashCode()メソッドのみ、ORそれは開発者次第ではなく、多くの一般的なJavaライブラリにはハッシュ衝突を引き起こす可能性のあるクラスがありますか?
  3. ハッシュコリジョンが発生すると、何か問題が発生したり、予期しない結果が生じたりしませんか?ハッシュ衝突を避けるべき理由はありますか?
  4. Javaを生成するか、少なくともオブジェクトの開始時にクラスごとに一意のhashCodeを生成しようとしますか?いいえの場合、Javaのみを使用して、プログラムはJREクラスのHash Collisionに実行されませんか?そうでない場合、キーとしてStringなどの最終クラスを持つハッシュマップのハッシュ衝突を回避する方法は?

これらの質問の1つまたはすべてに対する回答を共有していただければ幸いです。

15
sribasu

ハッシュ衝突とは正確に何ですか-それは機能、または誤って行われているが回避するのが一般的な現象ですか?

これは機能です。これは、hashCodeの性質、つまり大きな値空間からより小さな値空間へのマッピングから生じます。設計と意図により、衝突が発生します。

ハッシュ衝突の正確な原因-カスタムクラスのhashCode()メソッドの不適切な定義、

悪い設計はそれを悪化させる可能性がありますが、それは概念の風土病です。

または、equals()メソッドをオーバーライドせずに残し、hashCode()メソッドのみを不完全にオーバーライドするには、

いや.

または、開発者次第ではなく、多くの一般的なJavaライブラリには、ハッシュ衝突を引き起こす可能性のあるクラスがありますか?

これは本当に意味がありません。ハッシュは遅かれ早かれ衝突することになり、貧弱なアルゴリズムは遅らせることができます。それについてです。

ハッシュコリジョンが発生すると、何か問題が発生したり、予期しない結果が生じたりしませんか?

ハッシュテーブルが適切に記述されている場合は別です。ハッシュ衝突とは、hashCodeが一意ではないことを意味するだけです。これにより、equals()が呼び出され、重複が多いほどパフォーマンスが低下します。

ハッシュ衝突を避けるべき理由はありますか?

計算のしやすさと値の広がりのトレードオフが必要です。単一の白黒の答えはありません。

Java generateまたはatleastは、オブジェクトの開始時にクラスごとに一意のhasCodeを生成しようとしますか?

いいえ。「一意のハッシュコード」は用語の矛盾です。

「いいえ」の場合、Javaのみを使用して、プログラムがJREクラスのHash Collisionに実行されないようにしますか?そうでない場合、最終クラスとのハッシュマップのハッシュ衝突を回避する方法キーとして文字列のような?

質問は無意味です。 Stringを使用している場合、ハッシュアルゴリズムについて選択する余地はありません。また、hashCodeが20年以上にわたって専門家によって奴隷にされているクラスも使用しています。

9
user207421

実際、ハッシュ衝突は正常だと思います。考えるべきケースについて話しましょう。 1000000の大きな数(xの集合S)があります。たとえば、xは2 ^ 64にあります。次に、この番号セットのマップを作成します。この数値をSを[0,1000000]に設定してマップします。

しかし、どのように?ハッシュを使う!!

ハッシュ関数を定義しますf(x) = x mod1000000。Sのxは[0,1000000)に変換されます。しかし、Sの多くの数字は1つの数値に変換します。例えば。 (k * 1000000 + y)%x = yであるため、数k * 1000000 + yはすべてyに配置されます。これはハッシュ衝突です。

そして、衝突に対処する方法は?この場合、上で説明したように、数学計算にはいくつかの可能性があるため、衝突を区切ることは非常に困難です。より複雑で、より良いハッシュ関数を見つけることができますが、衝突を排除することを明確に言うことはできません。ハッシュの衝突を減らすためにより良いハッシュ関数を見つける努力をすべきです。ハッシュ衝突は時間コストを増加させるため、ハッシュを使用して何かを見つけます。

単純に、ハッシュの衝突に対処する2つの方法があります。たとえば、リンクリストはより直接的な方法です。たとえば、上記の2つの数値がhash_functionの後に同じ値を取得した場合、この値バケットからリンクリストを作成し、すべての同じ値に値のリンクリストを入れます。そして、別の方法は、後の番号の新しい位置を見つけることです。たとえば、番号1000005が5でポジションを取った場合、2000005が値5を取得すると、ポジション5に配置できないため、先に進み、空のポジションを見つけます。

最後の質問:Javaを生成するか、オブジェクトの開始時にクラスごとに一意のhashCodeを生成しようとしますか?

objectのハッシュコードは通常、オブジェクトの内部アドレスを整数に変換することにより実装されます。したがって、オブジェクトのhashcode()を使用すると、オブジェクトごとにハッシュコードが異なると考えることができます。

3
GuangshengZuo

ハッシュ衝突とは正確に何ですか-それは機能、または誤って行われているが回避するのが一般的な現象ですか?

どちらも...両方...それは一般的な現象ですが、誤って行われたものではないため、避けるのが良いでしょう。

Hash Collisionの正確な原因-カスタムクラスのhashCode()メソッドの不適切な定義、ORは、equals()メソッドをオーバーライドせずに、hashCode()メソッドのみを完全にオーバーライドするORそれは開発者次第であり、多くの人気のJavaライブラリには、ハッシュ衝突を引き起こす可能性のあるクラスもありますか?

hashCode()メソッドを適切に設計しないと、衝突が多すぎて、メソッドをオーバーライドしないままにして衝突の数に直接影響を与えることはできません。多くの一般的なJavaライブラリには衝突を引き起こす可能性のあるクラスがあります(ほぼ実際にはすべてのクラス)。

ハッシュコリジョンが発生すると、何か問題が発生したり、予期しない結果が生じたりしませんか?ハッシュ衝突を避けるべき理由はありますか?

パフォーマンスの低下があり、それがそれらを回避する理由ですが、プログラムは引き続き動作するはずです。

Javaは、オブジェクトの開始時にクラスごとに一意のhashCodeを生成しますか、少なくとも生成しようとしますか?いいえの場合、Javaのみに依存して、プログラムがJREクラスのHash Collisionに実行されないようにするのは正しいですか?そうでない場合は、キーとして文字列のような最終クラスを持つハッシュマップのハッシュ衝突を回避する方法は?

Javaは、オブジェクトの初期化中に一意のハッシュコードを生成しようとしませんが、hashCode()およびequals()のデフォルト実装を備えています。デフォルトの実装は、2つのオブジェクト参照が同じインスタンスを指しているかどうかを知るために機能し、オブジェクトのコンテンツ(フィールド値)に依存しません。したがって、Stringクラスには独自の実装があります。

1
Maurice Perry

ハッシュ衝突とは正確に何ですか-それは機能、または誤って行われたが避けるのが一般的な現象ですか?

  • ハッシュ衝突はまさに、オブジェクト上のそのフィールドハッシュコードの衝突です...

ハッシュ衝突の正確な原因-カスタムクラスのhashCode()メソッドの不適切な定義、ORは、hashCodeを不完全にオーバーライドしている間にequals()メソッドをオーバーライドしないままにする)メソッドのみ、ORは開発者次第ではなく、多くの一般的なJavaライブラリにはハッシュ衝突を引き起こす可能性のあるクラスもありますか?

  • いいえ、衝突は数学の確率によって支配されているために発生する可能性があり、そのような場合、誕生日のパラドックスがそれを説明する最良の方法です。

ハッシュ衝突が発生すると、何か問題が発生したり、予期しないことが起こりますか?ハッシュ衝突を避けるべき理由はありますか?

  • いいえ、Javaの文字列クラスは非常によく開発されたクラスであり、衝突を見つけるためにあまり検索する必要はありません(この文字列 "Aa"および "BB"のhascodeを確認してください->両方が衝突します2112へ)

要約すると、ハッシュコードの衝突は無害です。それが何のためであり、なぜではないが等しいことを証明するために使用されるIDと同じかを知っていますか

  1. ハッシュの衝突は、2つの別々の値がご存じのように同じハッシュを生成するときに発生します。ハッシュは、特定の値に対して固定数の文字を生成するため、わずかな確率にもかかわらず、2つの値が同じハッシュを生成する可能性が常にあります。したがって、ハッシュ関数自体に付属していると言えます。それを使用するとき、2つの値が同じハッシュを生成する可能性があるという事実を理解しています。ハッシュの衝突を計算するのは難しいですが、Googleが正しく覚えていれば、数か月前にSHA-1の衝突を正常に計算しました。 https://www.theregister.co.uk/2017/02/23/google_first_sha1_collision/

  2. 私はこれに関する知識を持っているとは思わない。

  3. はい。ある種の関数について、ハッシュを計算して実行するとします。そのため、場合によっては、人が無意識のうちにハッシュ衝突を生成すると、その特定の機能が実行されます。これにより、システムに欠陥または障害が発生する可能性があります。

0
pasanMissaka