Practice questions and answer explanations
Try an answer before reading the explanation. These are practice examples; adapt them to your own experience and expect different questions in an actual interview.
Why must equals() and hashCode() agree in Java?
If two objects are equal according to equals(), they must return the same hash code. HashMap uses the hash to locate candidate entries and equals() to identify a matching key. Different objects can share a hash code, so a matching hash alone does not establish equality. Override both methods when defining value equality, and avoid changing fields used by either method while an object is a map key.
Try this next: What could happen if an Employee key changes its employeeId after being inserted into a HashMap?
When would you choose ArrayList over LinkedList?
ArrayList provides constant-time indexed access and amortized constant-time appends, making it a useful default for many lists. Inserting near the start requires shifting elements. LinkedList must traverse nodes to reach an index; linking or unlinking is constant time only once the relevant position is already available, such as through an iterator. Compare the actual access pattern and memory overhead instead of assuming all LinkedList inserts are faster.
Try this next: For a queue that only adds at the back and removes from the front, how would ArrayDeque change your choice?
Does volatile make a shared counter thread-safe?
No. A volatile field provides visibility guarantees, but counter++ is a read, an increment, and a write. Two threads can read the same old value and lose an update. AtomicInteger.incrementAndGet() can perform an atomic increment; synchronized can protect a larger operation involving several fields. Choose the protection around the invariant you need to preserve, not just around one variable.
Try this next: Would an atomic counter alone safely coordinate a counter and a separate list that must always have the same size?
How would you make a Java class immutable?
Set the state during construction, keep fields private and final, provide no mutating methods, and prevent subclasses from weakening the contract. Copy mutable constructor inputs and avoid returning mutable internal objects directly. A final List reference only prevents reassignment; it does not freeze its contents. If list elements are mutable, decide whether they also need copying or an immutable representation.
Try this next: Why is returning an unmodifiable view insufficient when the original list can still be changed elsewhere?