Interview replay
Full round replay — hashCode/equals
Timed verbal replay with pass/fail criteria per follow-up.
How to run this
The opener
“What is the contract between hashCode() and equals()?”
Budget: 45 seconds. Going long here is itself a fail signal.
Follow-ups
1. “Must two unequal objects have different hash codes?”
Testing: Do they know the implication runs one way only?
Scoring
Pass: No — only equal implies equal hash. Collisions are legal and unavoidable; int has 4.3 billion values and there are more Strings than that.
Fail: Yes, or 'ideally yes' with no mention of the counting argument.
2. “So is a hashCode() that returns a constant broken?”
Testing: Separating correctness from performance.
Scoring
Pass: Contract-legal and still correct. Every key collides into one bin, so O(n) degrading to O(log n) after treeify. Slow, not wrong.
Fail: Says the map breaks, throws, or loses entries.
3. “I override equals() and not hashCode(). What do I see at runtime?”
Testing: The single most common real-world instance of this bug.
Scoring
Pass: Nothing thrown. Equal objects hash to different buckets, so get/contains miss while size() still counts them — apparent duplicates in a HashSet.
Fail: Expects an exception or a compiler warning.
4. “Does javac warn you about that?”
Testing: Whether they have actually hit it, or only read about it.
Scoring
Pass: No. Some linters and IDE inspections do; the compiler says nothing.
Fail: Believes the compiler catches it.
5. “Is it legal for hashCode() to read fewer fields than equals() compares?”
Testing: Whether they can reason from the contract rather than recite it.
Scoring
Pass: Yes. Equal objects still agree on the hash, so the contract holds. You get more collisions, that's all. The reverse — hashing a field equals() ignores — is the violation.
Fail: Says both must read exactly the same fields as an absolute rule.
6. “Why must a map key be immutable?”
Testing: The third rule, which most candidates never quote.
Scoring
Pass: The hash has to stay stable while the object is in the map. Mutate a hash-bearing field and the entry stays in its old bucket: unreachable by get, unremovable by remove, still counted by size.
Fail: 'Good practice' or 'thread safety' with no mechanism.
7. “Why is a record a better key than a hand-written class?”
Testing: Structural vs local fixes.
Scoring
Pass: Both methods are generated from all components, so they cannot drift when a field is added. Final class sidesteps the subclass symmetry problem; final components satisfy stability.
Fail: 'Less boilerplate' and nothing else.
Score yourself
← Back to What is the contract between hashCode() and equals()?