Java interview questions & practice path
Collections, JVM memory, streams, and concurrency primitives. Learn what interviewers probe, drill the questions until answers come fast, then prove it in a scored mock, all in one Java path inside Round Zero.
- Concept lessons that explain the why, not just the answer
- Practice questions with adaptive follow-ups and flashcards
- A scored mock with evidence quoted from your own answers
Sample Java questions
What a strong answer covers, and the mistakes interviewers watch for. The scored path drills every one with live follow-ups.
Explain the contract between equals() and hashCode() in Java. What breaks if you override one but not the other?
easyA strong answer covers
- equals() defines logical equality; hashCode() returns an int used to bucket objects in hash-based collections
- The contract: equal objects must return equal hash codes, and hashCode should be consistent across calls while the object is unchanged
- If you override equals() but not hashCode(), two logically equal objects can land in different buckets, so a HashMap or HashSet fails to find or de-duplicate them
- Both should be built from the same immutable, identity-defining fields; Objects.equals and Objects.hash make correct implementations easy
Common mistakes
- Claiming equal hash codes imply equal objects (collisions are allowed and expected)
- Including mutable fields in the calculation, which corrupts the object's location in a hash collection when the field changes
- Forgetting the null and type checks in equals(), or using == on object fields instead of Objects.equals
What is the difference between checked and unchecked exceptions, and when would you use each?
easyA strong answer covers
- Checked exceptions extend Exception (but not RuntimeException) and must be declared or caught; the compiler enforces handling
- Unchecked exceptions extend RuntimeException and are not enforced at compile time; Errors signal unrecoverable JVM problems
- Use checked exceptions for recoverable conditions a caller can reasonably handle, such as IO failures; use unchecked for programming errors like invalid arguments or null misuse
- Good practice: do not swallow exceptions, preserve the cause when wrapping, and avoid overly broad catch blocks
Common mistakes
- Catching Exception or Throwable broadly and silently ignoring it
- Wrapping and rethrowing without passing the original cause, losing the stack trace
- Overusing checked exceptions for conditions the caller cannot act on, cluttering signatures
How does HashMap work internally, and what happens on a hash collision? How has it evolved in modern Java?
mediumA strong answer covers
- A HashMap is an array of buckets; the key's hashCode is spread and masked to an index, giving average O(1) get and put
- Collisions are handled by chaining entries in the same bucket; since Java 8 a bucket converts from a linked list to a balanced tree once it exceeds a threshold (default 8), bounding worst case to O(log n)
- When size exceeds capacity times load factor (default 0.75), the table resizes and rehashes all entries
- Keys must have stable, correct hashCode and equals; HashMap is not thread-safe, so use ConcurrentHashMap under concurrency
Common mistakes
- Saying HashMap is always O(1) and ignoring the degenerate collision case and treeification threshold
- Claiming HashMap is thread-safe or that Collections.synchronizedMap gives the same scalability as ConcurrentHashMap
- Using a mutable object as a key and mutating a field that participates in hashCode after insertion
What is type erasure in Java generics, and what practical consequences does it have?
mediumA strong answer covers
- Generics are a compile-time feature; the compiler checks types then erases them, replacing type parameters with their bounds (or Object) so the bytecode carries no generic type info at runtime
- Consequences: you cannot do instanceof on a parameterized type, cannot create arrays of a generic type directly, and List<String> and List<Integer> share one runtime class
- The compiler inserts synthetic casts and bridge methods to preserve type safety and polymorphism across erasure
- Wildcards and bounds (? extends, ? super) follow PECS, and reifiable info can be recovered via Class tokens or super-type-token tricks
Common mistakes
- Believing generic type information exists at runtime and can be reflected on directly
- Ignoring unchecked-cast or heap-pollution warnings, especially with varargs of generic types
- Confusing List<Object> with List<?> or misapplying extends vs super when producing versus consuming
Compare volatile and synchronized. When is volatile sufficient and when is it not?
hardA strong answer covers
- volatile guarantees visibility and ordering (a happens-before edge) for a single field: reads always see the latest write, and it prevents certain reorderings, but it provides no atomicity for compound actions
- synchronized provides both mutual exclusion and visibility, establishing happens-before on lock release/acquire, so it can make multi-step updates atomic
- volatile suffices for a simple flag or a single publish of an immutable reference; it is not enough for read-modify-write like counter++, which needs synchronized or an Atomic type
- Mention the Java Memory Model: happens-before is the correctness contract; AtomicInteger and friends offer lock-free compare-and-swap for single variables
Common mistakes
- Assuming volatile makes compound operations like increment atomic
- Thinking synchronized only provides mutual exclusion and forgetting its visibility (memory barrier) guarantees
- Over-synchronizing everything, causing contention, or under-synchronizing shared mutable state and relying on luck
Why are Strings immutable in Java, and how does the string pool relate to that design?
hardA strong answer covers
- String immutability means the character data cannot change after construction, which makes Strings safe to share across threads without synchronization and safe as HashMap keys since their hashCode is stable and cached
- The string pool (interned literals) lets identical compile-time literals share one instance, saving memory; immutability is what makes that sharing safe
- Literals are pooled automatically; new String("x") creates a distinct heap object, and intern() returns the pooled canonical instance
- Use == only for reference identity and equals() for content; heavy concatenation in loops should use StringBuilder to avoid creating many intermediate objects
Common mistakes
- Comparing string content with == and getting surprised by pooled versus new-allocated instances
- Claiming immutability guarantees security while ignoring that the pool can retain sensitive data in memory (char[] is preferred for passwords)
- Building large strings with + in a loop, creating quadratic allocation instead of using StringBuilder
How Java answers are scored
Language and Runtime Depth
40%Strong answers correctly explain JVM mechanics such as heap vs stack, garbage collection, class loading, and the distinction between primitives and objects, and can reason about autoboxing, immutability, and how the compiler and JVM treat generics via type erasure.
Collections and Concurrency
35%Candidate chooses the right collection for the job, explains HashMap and ConcurrentHashMap internals and Big-O tradeoffs, and reasons soundly about threads, the happens-before relationship, volatile, synchronized, and higher-level utilities like ExecutorService and atomic types.
Practical Idioms and Pitfalls
25%Candidate writes idiomatic modern Java, correctly implements equals and hashCode, uses Optional, streams, and try-with-resources appropriately, and anticipates real pitfalls like mutable shared state, resource leaks, and NullPointerException.
Related Programming Languages skills
All skills →No spam. Unsubscribe anytime.
Ready to master Java?
Sign up free. Your Java path includes lessons, drills, flashcards, and a scored mock with feedback on what to fix.
- ✓ Concept lessons plus practice questions
- ✓ Flashcards for spaced repetition
- ✓ A scored mock with evidence quotes
Questions & answers
- What Java interview questions should I practice?
- Start with the core areas Java interviewers probe: Explain the contract between equals() and hashCode() in Java. What breaks if you override one but not the other; What is the difference between checked and unchecked exceptions, and when would you use each; How does HashMap work internally, and what happens on a hash collision? How has it evolved in modern Java. This page outlines strong answers and common mistakes, and the scored path drills each one with follow-ups.
- Is the Java practice free?
- Yes, you can start a Java path free inside Round Zero. It generates lessons, practice questions, flashcards, and a scored mock. Sign up to unlock the full drills and your evidence-backed scorecard.
- How is this different from a Java question list?
- A static list gives you questions with no feedback. Round Zero runs a live scored practice that probes your actual answers, rotates difficulty, and tells you exactly what to fix, grounded in a Java rubric.
- How should I prepare for a Java interview?
- Learn the concepts, drill the questions until answers come fast, then prove it in a scored mock. Round Zero sequences all three so you know you are ready, not just that you read about Java.
- How is a Java answer scored?
- Java answers are scored on language and runtime depth, collections and concurrency, practical idioms and pitfalls, with evidence quoted from what you actually said, so feedback is specific instead of generic praise.