This guide collects common Java interview questions with detailed answers you can use to prepare for phone screens and onsite rounds. Each section explains the underlying concept, trade-offs interviewers expect you to mention, and short code where it helps. Use it as a structured checklist alongside coding practice and system-design study.
JVM, JRE, and JDK
What is the JVM, and why does Java use bytecode?
The Java Virtual Machine (JVM) is the runtime that executes compiled Java bytecode. Source code is compiled to platform-independent .class files; the JVM loads classes, manages memory, performs JIT compilation to native code, and provides threading and garbage collection. This separation is why Java uses the slogan “write once, run anywhere”: the same bytecode runs on any OS with a compatible JVM implementation.
What is the difference between JDK, JRE, and JVM?
JVM is the abstract machine and runtime engine. The JRE (Java Runtime Environment) bundles the JVM plus standard libraries and resources needed to run applications. The JDK (Java Development Kit) adds compilers (javac), debuggers, packaging tools like jar, and other developer utilities so you can build applications. For development you install a JDK; on a server that only runs prebuilt jars, a JRE (or a minimal runtime image) may suffice.
Object-oriented programming in Java
Explain encapsulation, inheritance, polymorphism, and abstraction.
Encapsulation hides internal state behind methods and accessors so invariants are enforced in one place. Inheritance models “is-a” relationships and reuses behavior via superclass contracts. Polymorphism lets you treat objects through a common supertype while runtime dispatch selects the correct override (dynamic binding). Abstraction focuses on what an object does rather than how, often via abstract classes and interfaces. Interviewers often follow up with when inheritance hurts (fragile base classes) and why composition is frequently preferred.
What is the difference between method overloading and overriding?
Overloading is compile-time polymorphism: multiple methods share a name but differ in parameter lists (types, count, or varargs). The compiler picks the best match. Overriding is runtime polymorphism: a subclass provides a method with the same signature as a superclass or interface method; the JVM resolves the implementation based on the actual object type. Mention @Override for clarity and that overriding requires compatible return types (covariant returns allowed since Java 5).
equals() and hashCode()
Why must you override hashCode() when you override equals()?
equals() defines logical equality. hashCode() maps an object to a bucket in hash-based collections (HashMap, HashSet, etc.). The contract requires that if two objects are equal per equals(), they must return the same hash code. If you break this, equal objects can appear in different buckets, breaking maps and sets. Also state the converse: unequal objects may collide (same hash) but collections handle that with equals() on bucket entries.
Good answers mention using the same fields in both methods, handling null in equals(), and choosing a stable, distributed hash (IDEs can generate reasonable implementations).
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person p = (Person) o;
return Objects.equals(id, p.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}Strings and memory
Why are Java strings immutable?
The String class stores characters in a final array and provides no mutators. Immutability enables safe sharing across threads without locks, allows string literals to be interned in the string pool, and makeshashCode cacheable. Mention that string concatenation in loops creates many intermediate objects and that StringBuilder is preferred for repeated assembly.
What is the difference between == and equals() for strings?
== compares references (same object in memory). equals() compares character content. Two string literals with the same text may reference the same interned instance, so == can accidentally appear to work in demos; in production code, use equals() for value comparison unless you intentionally compare identity.
Exceptions: checked vs unchecked
What are checked and unchecked exceptions?
Checked exceptions extend Exception but not RuntimeException. The compiler requires you to catch them or declare them in a throws clause (e.g. IOException). They signal recoverable conditions the caller should handle. Unchecked exceptions extend RuntimeException (or Error); they are not required to be declared and usually indicate programming bugs or unrecoverable states. Modern APIs often prefer unchecked exceptions for cleaner signatures, but checked exceptions remain common in I/O and JDBC.
What is the difference between throw and throws?
throw is a statement that actually raises an exception object. throws appears in a method signature to declare that the method may propagate checked exceptions to its caller.
Collections framework
Explain the difference between List, Set, and Map.
List is an ordered sequence with indexed access; duplicates allowed (ArrayList, LinkedList). Set models a mathematical set: no duplicates, may be ordered or unordered (HashSet, LinkedHashSet, TreeSet). Map stores key-value pairs; keys are unique (HashMap, TreeMap). Maps do not extend Collection but are part of the collections framework.
When would you choose ArrayList over LinkedList?
ArrayList offers O(1) indexed access and typically better cache locality; resizing has amortized cost. LinkedList offers O(1) insert/delete at known node positions but poor random access (O(n)) and higher pointer overhead. In practice ArrayList is the default choice; LinkedList is niche (e.g. frequent middle inserts with iterators). Mention that big-O alone is not the whole story: constants and hardware matter.
How does a HashMap work at a high level?
HashMap uses an array of buckets. The key's hashCode() is transformed to an index; collisions are handled by chaining (linked lists or trees when buckets grow). Get/put average O(1) with a good hash function and load factor; worst case degrades if many keys collide. Java 8+ converts long bucket chains to balanced trees under certain conditions to keep performance predictable.
Concurrency basics
What does the synchronized keyword do?
synchronized provides mutual exclusion and visibility: only one thread at a time can execute a synchronized block or method on the same monitor, and memory effects ensure writes are visible to subsequent lock holders. You can synchronize on this, a dedicated lock object, or static locks for class metadata. Drawbacks include potential contention and the risk of deadlocks if locks are acquired in inconsistent order.
What is the volatile keyword?
volatile marks a field so reads and writes go directly to main memory with defined ordering relative to other volatiles, preventing certain stale reads. It does not replace synchronization for compound actions (like count++). Use it when one thread writes and others read a simple flag or reference, or when documenting happens-before for framework code.
What is a race condition?
A race condition occurs when the outcome depends on the interleaving of threads accessing shared mutable state without proper coordination. Fixes include locks, atomic classes, immutability, confining state to one thread, or using concurrent collections.
Java 8+ features interviewers love
What are lambdas and the Stream API?
Lambdas are concise syntax for single-method interfaces (functional interfaces). The Stream API processes sequences of elements in a fluent, often lazy pipeline: source, zero or more intermediate operations (map, filter, sorted), and a terminal operation (collect, reduce, forEach). Mention that streams are not data structures, parallel streams have overhead, and side effects in streams should be avoided unless carefully controlled.
Optional — what problem does it solve?
Optional<T> is a container that may or may not hold a non-null value, encouraging callers to handle absence explicitly instead of relying on null. It is intended for return types, not fields or parameters, and should not replace all null checks indiscriminately.
How to answer under interview pressure
Start with a one-sentence definition, then add one example or trade-off. If you are unsure, say what you would verify (documentation, JDK source, JLS) rather than guessing edge cases. Connect answers to experience: “In our service we used…” beats abstract textbook repetition. For senior roles, expect follow-ups on performance, failure modes, and API design—not only definitions.