Une HashMap contient un tableau de buckets. Le hash de la clé est étalé en y mélangeant ses bits de poids fort, puis l'index est ce hash masqué par la taille de la table, toujours une puissance de deux. Les collisions forment une liste chaînée dans le bucket, et un bin d'au moins huit entrées dans une table d'au moins soixante-quatre se convertit en arbre rouge-noir. Au-delà du facteur de charge de 0,75, la table double et les entrées sont réhachées.
Pourquoi les recruteurs posent cette question
Le recruteur teste si vous comprenez la structure de données que vous utilisez dans chaque classe, plutôt que de réciter qu'elle est rapide. Les détails sur la treeification et le redimensionnement montrent des connaissances à jour, puisque l'implémentation a changé en Java 8. Cela mène aussi naturellement à la raison pour laquelle les clés doivent être immuables, à l'effet d'un mauvais hash sur les performances, et au fait que HashMap n'est pas sûre en écriture concurrente.
Comment structurer votre réponse
- Décrivez le tableau de buckets et la façon dont un index est dérivé.
- Expliquez la gestion des collisions et le passage de la liste à l'arbre.
- Couvrez le facteur de charge, le redimensionnement et le coût du réhachage.
- Tirez les conclusions pratiques sur la conception des clés et la sûreté vis-à-vis des threads.
Exemple de réponse
En interne, c'est un tableau de bins. Le hashCode de la clé est étalé par un ou exclusif qui redescend les bits de poids fort, ce qui compte parce que l'index n'est que le hash masqué par la taille de la table moins un, donc sans ce mélange seuls les bits de poids faible serviraient. Les entrées en collision se chaînent dans ce bin, et depuis Java 8 un bin qui dépasse huit entrées, quand la table fait au moins soixante-quatre, devient un arbre rouge-noir, si bien que la recherche dans le pire cas est logarithmique au lieu de linéaire. C'était une réponse aux attaques par déni de service via collisions de hash. La croissance est pilotée par le facteur de charge, donc à 0,75 d'occupation la table double et tout est redistribué, ce qui explique pourquoi dimensionner la map à l'avance compte si je sais qu'elle contiendra un million d'entrées. Les conséquences pratiques qui m'intéressent : les clés doivent être immuables, un mauvais hashCode fait tout atterrir dans un seul bin, et les écritures concurrentes peuvent corrompre la table, donc les maps partagées passent à ConcurrentHashMap plutôt qu'à un verrouillage externe.
Vous passez cet entretien bientôt ? GhostPilot écoute votre appel en direct, repère la question dès qu'elle est posée et affiche une réponse structurée à l'écran en temps réel. Essayez-le lors de votre prochain entretien blanc, ou prenez un Session Pass à $29, sans abonnement, pour le jour J.
Voir comment ça marcheQuestions de relance à prévoir
- Pourquoi la taille de la table est-elle toujours une puissance de deux ?
- Que fait ConcurrentHashMap de différent pour permettre des écritures concurrentes ?
- Quand préféreriez-vous LinkedHashMap ou TreeMap ?
Autres questions pour Développeur Java
Votre recruteur posera sa propre version de celle-ci. Collez votre véritable fiche de poste dans le Question Predictor gratuit et obtenez les 20 questions que ce poste a le plus de chances de poser, avec ce que chacune cherche vraiment à sonder.
Prédire mes questions