Das Arbeitsprinzip von HashMap ist in den letzten Jahren eine gemeinsame Frage des Java -Interviews. Fast jeder Java -Programmierer kennt Hashmap, weiß, wo man HashMap benutzt, und kennt den Unterschied zwischen Hashtable und HashMap. Warum ist diese Interviewfrage so besonders? Dies liegt daran, dass diese Frage sehr tief ist. Diese Frage erscheint häufig in Interviews mit fortgeschrittenem oder mittlerer Ebene. Investmentbanken stellen es vor, diese Frage zu stellen, und bitten Sie möglicherweise sogar, HashMap zu implementieren, um Ihre Programmierkenntnisse zu untersuchen. Die Einführung von Concurrenthashmap und anderen synchronen Sätzen macht dieses Problem komplizierter. Beginnen wir die Reise der Erkundung!
Lassen Sie uns zuerst einige einfache Fragen haben
"Hast du HashMap benutzt?" "Was ist HashMap? Warum hast du es benutzt?"
Fast jeder antwortet "Ja" und dann einige Funktionen von HashMap, z. HashMap ist nicht synchronisiert; Hashmap ist schnell; Und HashMap speichert Schlüsselwertpaare usw. Dies zeigt, dass Sie HashMap verwendet haben und damit vertraut sind. Der Interviewer nahm jedoch eine kurze Wendung und stellte von nun an einige schwierige Fragen, über grundlegende Details von HashMap. Der Interviewer kann die folgenden Fragen stellen:
"Weißt du, wie HashMap funktioniert?" "Wissen Sie, wie die Get () -Methode von Hashmap funktioniert?"
Sie könnten antworten: "Ich habe die Standard -Java -API nicht im Detail nachgeschlagen. Sie können sich den Java -Quellcode oder den JDK öffnen." "Ich kann die Antwort mit Google finden."
Einige Interviewer können jedoch in der Lage sein, die Antwort zu geben: "Hashmap basiert auf dem Prinzip des Hashing. Wir verwenden Put (Schlüssel, Wert), um Objekte in HashMap zu speichern und GET (Schlüssel) zu verwenden, um Objekte von HashMap zu erhalten. Wenn wir Schlüssel und Werte an die Put () -Methode rufen. Der wichtigste Punkt hier ist, dass Hashmap Schlüsselobjekte und Wertobjekte im Bucket als map.Entry speichert. Dies hilft, die Logik des Erhalts von Objekten zu verstehen. Wenn Sie dies nicht merken oder fälschlicherweise glauben, dass Sie nur Werte in Eimer speichern, werden Sie nicht die Logik beantworten, wie Objekte von HashMap abgerufen werden können. Diese Antwort ist recht korrekt und zeigt auch, dass der Interviewer das Hashing kennt und wie HashMap funktioniert. Aber dies ist nur der Beginn der Geschichte. Wenn der Interviewer sich einigen tatsächlichen Szenen anschließt, denen Java -Programmierer jeden Tag begegnen müssen, treten häufig falsche Antworten auf. Die nächste Frage kann sich um die Kollisionserkennung in HashMap und die Lösung für die Kollision handeln:
"Was passiert, wenn der HashCode von zwei Objekten gleich ist?" Von hier aus beginnt die wirkliche Verwirrung, und einige Interviewer werden antworten, dass der HashCode der gleiche Objekt gleich ist und der HashMap Ausnahmen werfen wird oder sie nicht gespeichert werden. Dann kann der Interviewer sie daran erinnern, dass es zwei Methoden gibt: Equals () und Hashcode () und ihnen sagen, dass der HashCode auch dann nicht gleich ist. Einige Interviewer können aufgeben, während andere weiter voranschreiten können. Sie antworteten: "Da der HashCode der gleiche ist, ist ihre Bucket-Position gleich, und" Kollision "wird geschehen. Da HashMap eine verknüpfte Liste verwendet, um Objekte zu speichern, wird dieser Eintrag (das MAP.Entry-Objekt, das Schlüsselwertpaare enthält) in der verknüpften Liste gespeichert." Diese Antwort ist sehr vernünftig. Obwohl es viele Möglichkeiten gibt, mit Kollisionen umzugehen, ist diese Methode am einfachsten und es ist die Verarbeitungsmethode von HashMap. Aber die Geschichte ist noch nicht fertig, und der Interviewer wird weiterhin fragen:
"Wenn der HashCode der beiden Schlüssel gleich ist, wie erhalten Sie das Wertobjekt?" Der Interviewer antwortet: Wenn wir die Get () -Methode aufrufen, verwendet HashMap den HashCode des Schlüsselobjekts, um den Bucket -Speicherort zu finden und dann das Wertobjekt zu erhalten. Der Interviewer erinnert ihn daran, dass wenn zwei Wertobjekte im selben Eimer gespeichert sind, er die Antwort gibt: Die verlinkte Liste wird durchquert, bis das Wertobjekt gefunden wird. Der Interviewer wird fragen, da Sie kein Wertungsobjekt haben müssen, wie Sie festgestellt haben, ob Sie das Wertobjekt finden sollen? Sofern der Interviewer nicht in der verlinkten Liste Schlüsselwertpaare speichert, bis HashMap sie in der verlinkten Liste speichert, können sie diese Frage nicht beantworten.
Einige der Interviewer, die sich an diesen wichtigen Wissenspunkt erinnern, werden sagen, dass sie nach dem Finden des Bucket -Standorts die Keys aufrufen. Ausgleich () Methode, um den richtigen Knoten in der verlinkten Liste zu finden und schließlich das zu findene Wertobjekt zu finden. Die perfekte Antwort!
In vielen Fällen machen Interviewer Fehler in diesem Link, weil sie die Methoden von HashCode () und Equals () verwechseln. Denn bevor dieser HashCode () wiederholt erscheint und die Equals () -Methode nur beim Erhalten des Wertobjekts angezeigt wird. Einige hervorragende Entwickler weisen darauf hin, dass die Verwendung unveränderlicher, deklarierter Objekte als endgültig und angemessene Methoden Equals () und Hashcode () das Auftreten von Kollisionen verringern und die Effizienz verbessern. Durch die Unveränderlichkeit kann der Hashcode verschiedener Schlüssel zwischengespeichert werden, wodurch die Geschwindigkeit des gesamten Objekts erhöht wird. Die Verwendung von Wrapper -Klassen wie String und Interger als Schlüssel ist eine sehr gute Wahl.
Wenn Sie der Meinung sind, dass es hier vorbei ist, werden Sie überrascht sein, wenn Sie die folgende Frage hören. "Was ist, wenn die Größe von HashMap die vom Lastfaktor definierte Kapazität überschreitet?" Wenn Sie nicht wirklich wissen, wie HashMap funktioniert, werden Sie diese Frage nicht beantworten. Die Standardlastfaktorgröße beträgt 0,75. Das heißt, wenn eine Karte 75% Eimer füllt, wie andere Sammlungsklassen (wie ArrayList usw.), wird ein Eimer -Array, das doppelt so groß ist wie die Größe des ursprünglichen Hashmap, erstellt, um die Größe der Karte zu ändern und das ursprüngliche Objekt in das neue Bucket -Array zu setzen. Dieser Vorgang wird als Aufermaschinen bezeichnet, da er die Hash -Methode nennt, um den neuen Bucket -Standort zu finden.
Wenn Sie diese Frage beantworten können, stellt sich die folgende Frage: "Verstehen Sie, welche Probleme bei der Größenänderung von Hashmap sind?" Möglicherweise können Sie es nicht beantworten. Zu diesem Zeitpunkt wird der Interviewer Sie daran erinnern, dass es beim Multi-Threading eine Rennbedingung geben kann.
Bei der Größenänderung von HashMap gibt es tatsächlich bedingte Konkurrenz, denn wenn beide Threads feststellen, dass Hashmap die Größe der Größe verändert werden muss, werden sie gleichzeitig versuchen, die Größe zu ändern. Während der Größe des Größengrößenverfahrens wird die Reihenfolge der in der verknüpften Liste gespeicherten Elemente umgekehrt, da HashMap beim Umzug in die neue Bucket -Position die Elemente nicht am Ende der verknüpften Liste, sondern am Kopf nicht platziert. Wenn eine bedingte Konkurrenz auftritt, gibt es einen Teufelskreis. Zu diesem Zeitpunkt können Sie den Interviewer fragen, warum es so seltsam ist, dass Sie HashMap in einer Umgebung mit mehreren Threaden verwenden müssen? :)
Enthusiastische Leser tragen weitere Fragen zu HashMap auf:
1. Warum sind Wrapper -Klassen wie String und Interger als Schlüssel geeignet? Die Wrapper -Klasse wie Zeichenfolge und Interger ist als Hashmap -Schlüssel am besten geeignet, und die Zeichenfolge wird am häufigsten verwendet. Da String unveränderlich und endgültig ist und die Methoden Equals () und HashCode () umgeschrieben wurden. Andere Wrapper -Klassen haben ebenfalls diese Funktion. Unmutabilität ist erforderlich, da Sie zur Berechnung von HashCode () verhindern müssen, dass sich der Schlüsselwert ändert. Wenn der Schlüsselwert beim Einsetzen und Erhalten einen anderen HashCode zurückgibt, können Sie das gewünschte Objekt nicht von der HashMap finden. Die Unveränderlichkeit hat andere Vorteile wie die Sicherheit von Threads. Wenn Sie garantieren können, dass der HashCode nur durch das endgültige Deklarieren eines Feldes unverändert bleibt, dann tun Sie dies bitte. Da die Methoden Equals () und HashCode () beim Erhalten von Objekten verwendet werden, ist es sehr wichtig, diese beiden Methoden korrekt neu zu schreiben. Wenn zwei ungleiche Objekte unterschiedliche Hashcodes zurückgeben, ist die Wahrscheinlichkeit einer Kollision kleiner, was die Leistung von HashMap verbessern kann.
2. Können wir benutzerdefinierte Objekte als Schlüssel verwenden? Dies ist eine Erweiterung der vorherigen Frage. Natürlich können Sie jedes Objekt als Schlüssel verwenden, solange es den Definitionsregeln von Equals () und HashCode () Methoden folgt, und ändert sich nicht erneut, nachdem das Objekt in die Karte eingefügt wurde. Wenn dieses benutzerdefinierte Objekt unveränderlich ist, erfüllt es die Bedingung bereits als Schlüssel, da es nach dem Erstellen nicht geändert werden kann.
3. Können wir Cocurrenthashmap verwenden, um Hashtable zu ersetzen? Dies ist eine weitere sehr beliebte Interviewfrage, da immer mehr Menschen eine Concurrenthashmap verwenden. Wir wissen, dass Hashtable synchronisiert ist, aber die Synchronisation der Concurrenthashmap ist besser, da sie einen Teil der Karte basierend auf der Synchronisationsebene sperrt. Concurrenthashmap kann sicherlich Hashtable ersetzen, aber Hashtable bietet eine stärkere Sicherheit. Schauen Sie sich diesen Blog an, um den Unterschied zwischen Hashtable und Concurrenthashmap zu erkennen.
Ich persönlich mag diese Frage sehr, weil die Tiefe und Breite dieser Frage nicht direkt unterschiedliche Konzepte beinhaltet. Schauen wir uns an, in welchen Wissenspunkten diese Fragen entworfen werden:
Zusammenfassen
Wie funktioniert Hashmap
HashMap basiert auf dem Hashing -Prinzip, und wir speichern und erhalten Objekte über Put () und Get () Methoden. Wenn wir das Schlüsselwertpaar an die Put () -Methode übergeben, ruft es die HashCode () -Methode des Schlüsselobjekts auf, um den HashCode zu berechnen, und findet dann die Bucket-Position, um das Wertobjekt zu speichern. Beim Erhalten des Objekts wird das korrekte Schlüsselwertpaar durch die Equals () -Methode des Schlüsselobjekts gefunden, und dann wird das Wertobjekt zurückgegeben. HashMap verwendet verknüpfte Listen, um das Kollisionsproblem zu lösen. Wenn eine Kollision auftritt, wird das Objekt im nächsten Knoten der verknüpften Liste gespeichert. HashMap speichert Schlüsselwertpaarobjekte in jedem verknüpften Listenknoten.
Was passiert, wenn der HashCode von zwei verschiedenen Schlüsselobjekten gleich ist? Sie werden in der verknüpften Liste am selben Bucket -Ort gespeichert. Die Equals () -Methode des Schlüsselobjekts wird verwendet, um Schlüsselwertpaare zu finden.
Da HashMap viele Vorteile hat, habe ich HashMap als Cache in E-Commerce-Anwendungen verwendet. Da Java im Finanzbereich und für Leistungsüberlegungen häufig verwendet wird, verwenden wir häufig Hashmap und Concurrenthashmap. Sie können weitere Artikel über HashMap anzeigen:
Der Unterschied zwischen Hashmap und Hashtable
Der Unterschied zwischen Hashmap und Hashset
Original -Link: Javareviehed Übersetzung: ImportNew.com - Tang Xiaojuan Übersetzung Link: http://www.importnew.com/7099.html