Interviewfrage für Java-Entwickler

Du brauchst eine Map, die sich viele Threads teilen. Was nimmst du, und was macht ConcurrentHashMap, was eine synchronized Map nicht macht?

Worauf der Interviewer abzielt, wie du deine Antwort aufbaust und ein gesprochenes Beispiel zum Anpassen.

Kurzantwort

Nimm ConcurrentHashMap. Sie sperrt pro Bin statt der ganzen Map, mit einem Compare-and-Set für leere Bins und sonst Synchronisation auf dem Bin-Kopf, Leser blockieren also nie und Schreiber in verschiedenen Bins laufen parallel. Eine synchronized Map serialisiert jede Operation über ein einziges Lock, und beim Iterieren brauchst du trotzdem externe Synchronisation. Nutz ihre atomaren Methoden wie compute und merge statt get gefolgt von put.

Warum Interviewer das fragen

Das prüft, ob du weißt, warum die Concurrent Collections existieren, statt reflexartig zu synchronized zu greifen. Der Interviewer will den Unterschied in der Granularität hören und den entscheidenden praktischen Punkt, dass das Wrappen einer Map Folgen von Operationen nicht atomar macht. Zu wissen, dass size und Iteration nur schwach konsistent sind, und wann CopyOnWriteArrayList oder eine BlockingQueue das bessere Werkzeug ist, rundet die Antwort ab.

So baust du deine Antwort auf

  • Nenn zuerst das Werkzeug, dann den Mechanismus, der es schneller macht.
  • Erklär, warum ein synchronized Wrapper für zusammengesetzte Aktionen trotzdem nicht reicht.
  • Verweis auf die atomaren Methoden für read-modify-write.
  • Erwähne die anderen Concurrent Collections und wann sie passen.

Beispielantwort

Gesprochenes Beispiel, erste Person

ConcurrentHashMap, fast immer. Der wichtige Unterschied ist die Granularität: sie sperrt auf der Ebene eines einzelnen Bins, und ein Insert in einen leeren Bin ist nur ein Compare-and-Set, unabhängige Keys konkurrieren also nicht und Lesezugriffe sind lock-frei. Eine synchronized Map legt ein Lock um alles, sie wird also zum Flaschenhals, sobald mehrere Threads beschäftigt sind. Die größere Falle bei einem synchronized Wrapper ist, dass einzelne Aufrufe atomar sind, Folgen davon aber nicht, prüfe ich also containsKey und mache dann put, kann ein anderer Thread dazwischenrutschen, und Iteration ist ohne eigenes Halten des Locks gar nicht sicher. Deshalb nutze ich die atomaren Methoden: computeIfAbsent für einen faul gebauten Cache-Eintrag, merge für Zähler, damit das read-modify-write innerhalb der Map passiert. Wissen sollte man, dass size unter nebenläufiger Änderung eine Schätzung ist und Iteratoren schwach konsistent sind, sie werfen also nicht, sehen aber vielleicht nicht die neuesten Writes. Für andere Formen nehme ich CopyOnWriteArrayList, wenn Lesezugriffe die Schreibzugriffe weit übersteigen, und eine BlockingQueue für die Übergabe zwischen Producer und Consumer.

Steht dieses Vorstellungsgespräch bald an? GhostPilot hört bei deinem Live-Call mit, erkennt die Frage in dem Moment, in dem sie gestellt wird, und bringt dir eine strukturierte Antwort in Echtzeit auf den Bildschirm. Probier es im nächsten Mock aus, oder hol dir einen $29 Session Pass, kein Abo, für den Ernstfall.

So funktioniert es

Nachfragen, mit denen du rechnen solltest

  • Welche Risiken hat teure Arbeit innerhalb von computeIfAbsent?
  • Was bedeutet schwach konsistente Iteration in der Praxis?
  • Wann ist CopyOnWriteArrayList die falsche Wahl?

Weitere Fragen für Java-Entwickler

Dein Interviewer stellt seine eigene Version davon. Kopier deine echte Stellenbeschreibung in den kostenlosen Question Predictor und bekomm die 20 Fragen, die diese Rolle am wahrscheinlichsten stellt, samt dem, worauf jede wirklich abzielt.

Meine Fragen vorhersagen

Üb die harten Fragen, bevor sie gestellt werden

Trainier mit einem Live-Copiloten und geh dann vorbereitet rein. Ein $29 Session Pass bringt dich durch das Vorstellungsgespräch, ohne Abo und ohne Bindung.

GhostPilot holen