Top Java Interview Questions & Answers (Freshers to Senior)
A senior-level Java interview guide covering JVM/JRE/JDK internals, memory areas, String immutability and pooling, the equals/hashCode contract, pass-by-value, final/finally/finalize, static init order, autoboxing caches, type erasure, and hard predict-the-output problems.
This is a deep, no-fluff Java interview guide — the core questions you'll face from fresher rounds up to senior interviews, answered properly. Not one-line definitions, but the why behind each: how the JVM manages memory, why String is immutable, the real equals()/hashCode() contract, what "pass-by-value" actually means in Java, and the output-prediction traps interviewers use to separate people who memorised Java from people who understand it. Each specialised area (collections, multithreading, exceptions, OOP) has its own dedicated deep-dive linked below; this page is the backbone.
JVM, JRE, JDK & memory
Q1. Difference between JDK, JRE and JVM?
| Term | What it is | Contains |
|---|---|---|
| JVM | Runs bytecode; platform-specific | Class loader, execution engine, JIT, GC |
| JRE | Runtime to run Java apps | JVM + core libraries |
| JDK | Full kit to develop | JRE + compiler (javac), tools |
Full breakdown: JDK vs JRE vs JVM.
Q2. Explain JVM memory areas.
Heap — all objects and their instance fields; shared across threads; GC-managed (young gen = Eden + survivor, old gen). Stack — one per thread; holds stack frames with local variables and partial results; a deep recursion overflows it (StackOverflowError). Metaspace (replaced PermGen in Java 8) — class metadata, off-heap. PC register and native method stack per thread. An OutOfMemoryError usually means the heap is full and GC can't reclaim enough.
Q3. What is the JIT compiler?
The Just-In-Time compiler watches which bytecode runs often ("hot spots") and compiles it to native machine code at runtime, so hot paths run at near-native speed instead of being interpreted every time. It's why a long-running Java service gets faster after warm-up.
Strings
Q4. Why is String immutable in Java?
Once created, a String's value never changes. Reasons: security (strings are used for file paths, URLs, DB credentials — mutability would allow tampering after validation), the string pool (safe sharing requires immutability), thread safety (immutable = inherently safe to share), and caching the hashCode (computed once, reused — great for HashMap keys).
Q5. Predict the output — string pool vs new.
String a = "hi"; String b = "hi"; String c = new String("hi"); System.out.println(a == b); // true — same pooled object System.out.println(a == c); // false — new heap object System.out.println(a.equals(c)); // true — same characters System.out.println(a == c.intern()); // true — intern() returns the pooled ref
Q6. String vs StringBuilder vs StringBuffer?
String is immutable — concatenation in a loop creates many objects (O(n²)). StringBuilder is mutable and not thread-safe (fast, the default for building strings). StringBuffer is mutable and synchronised (thread-safe, slower — rarely needed).
equals(), hashCode() & ==
Q7. Difference between == and equals()?
== compares references (do both point to the same object) for objects, or raw values for primitives. equals() compares logical equality as defined by the class. See == vs equals().
Q8. Explain the equals()/hashCode() contract. What breaks if you override only one?
The contract: if a.equals(b) is true, then a.hashCode() == b.hashCode() must also be true. (The reverse need not hold — equal hashes don't imply equal objects.) If you override equals() but not hashCode(), two "equal" objects can land in different HashMap buckets, so map.get(key) fails to find an entry you just put in. Always override both together. Deep dive: equals() & hashCode().
Language mechanics interviewers probe
Q9. Is Java pass-by-value or pass-by-reference?
Always pass-by-value. For objects, the value of the reference is copied — so the method can mutate the object the reference points to, but reassigning the parameter doesn't affect the caller's variable.
void change(StringBuilder sb, String s) { sb.append(" world"); // mutates the caller's object → visible s = "new"; // reassigns local copy → NOT visible } // after change(sb, "hi"): sb = "hi world", s still "hi"
Q10. final vs finally vs finalize?
final — a modifier (constant variable, non-overridable method, non-extendable class). finally — a block that always runs after try/catch (cleanup). finalize() — a deprecated Object method the GC might call before reclaiming an object; never rely on it — use try-with-resources instead.
Q11. Predict the output — static vs instance initialisation order.
// Order when 'new Child()' runs: // 1. static blocks (parent, then child) — ONCE, at class load // 2. parent instance initialisers + parent constructor // 3. child instance initialisers + child constructor
This "static first (once), then super, then child" order is a classic trap.
Q12. Autoboxing gotcha — predict the output.
Integer a = 127, b = 127; Integer c = 128, d = 128; System.out.println(a == b); // true — Integer cache (-128..127) reuses objects System.out.println(c == d); // false — outside cache, two new objects
Lesson: never use == on boxed types — use .equals() or unbox to int.
Generics, Comparable & Comparator
Q13. What is type erasure?
Generics exist only at compile time; the compiler checks types then erases them, replacing type parameters with Object (or the bound). At runtime List<String> and List<Integer> are the same class. Consequences: you can't do new T[], can't use instanceof List<String>, and can't overload on List<String> vs List<Integer>.
Q14. Comparable vs Comparator?
// Comparable: the class's OWN natural order (compareTo) class Emp implements Comparable<Emp> { public int compareTo(Emp o) { return id - o.id; } } // Comparator: external, multiple orderings, composable emps.sort(Comparator.comparing(Emp::getName) .thenComparing(Emp::getSalary).reversed());
Java 8+ (expected in every modern interview)
Be ready to discuss lambdas & functional interfaces, the Streams API, Optional, default/static methods on interfaces, method references, and the new Date/Time API. For the deep streams round, see the dedicated advanced Streams interview questions. Know which features arrived when via the Java version history.
Q15. Functional interface — what and why?
An interface with exactly one abstract method (SAM), e.g. Runnable, Comparator, Function. The @FunctionalInterface annotation makes the compiler enforce that. It's what lets a lambda be assigned to it — the lambda is the implementation of that single method.
Go deeper by topic
Each of these areas is its own interview round — study the dedicated advanced set:
- OOP interview questions — four pillars, SOLID, abstract vs interface, polymorphism rules
- Collections interview questions — HashMap internals, fail-fast, ConcurrentHashMap
- Multithreading interview questions — JMM, volatile, locks, deadlock
- Exception-handling interview questions — checked vs unchecked, try-with-resources
- Streams interview questions — Collectors, reduce, parallel internals
- Spring Boot interview questions — IoC, autoconfig, @Transactional
- DSA interview questions — patterns, complexity, coding rounds
Rapid-fire predict-the-output
System.out.println(0.1 + 0.2 == 0.3); // false — floating-point rounding System.out.println(1 / 0); // ArithmeticException (int) System.out.println(1.0 / 0); // Infinity (double, no exception) System.out.println(10 + 20 + "cm"); // "30cm" (left-to-right) System.out.println("cm" + 10 + 20); // "cm1020" int[] arr = new int[3]; System.out.println(arr[0]); // 0 (default), not null
Here's what actually moved the needle for me in interviews: I stopped collecting question lists and started asking "why?" of everything I already knew. Why is String immutable? Why does hashCode matter for a map? Why is Java pass-by-value even for objects? Every one of those has a real, mechanical answer, and once you can give it, the interviewer's inevitable follow-up doesn't rattle you — because you're reasoning from the model, not reciting a memorised card. So use this page as a map, not a script: for each answer, close your eyes and re-derive the why. Then go one level deeper into the specialised sets linked above, because that's where senior interviews actually live. Do that, and you'll walk in able to handle questions nobody put on any list. Good luck — you've got this.