24×7 Proxy Interview Support · Proxy Job Support · Profile Engineering | USA · Canada · UK · Europe · Australia · Singapore · Japan · New Zealand · Gulf · India

Backend · Mid–Senior · Updated Jul 2026

Java Interview Questions

Java interviews test core language, collections, concurrency, the JVM and design — current to Java 25 LTS. Each question is answered with the depth panels expect.

Q1. How does the JVM manage memory, and what changed you should know in Java 25 LTS?

Short answer: Heap + stack + metaspace, managed by a garbage collector; Java 25 continues generational ZGC and virtual-thread maturity.

Strong answer: Objects live on the heap (young/old generations), method frames on the stack, class metadata in metaspace. Collectors like G1 (default) and ZGC/Shenandoah trade throughput for pause time. Java 25 LTS ships mature virtual threads (Project Loom) and generational ZGC, so high-concurrency services scale without tuning huge thread pools.

Likely follow-up: When would you pick ZGC over G1?

What the interviewer is checking: Do you understand memory regions and modern collectors, not just "the GC frees memory".

Common mistake: Saying the JVM has no stack, or that finalizers are how you free memory.

Q2. What is the difference between == and equals(), and how does hashCode() fit in?

Short answer: == compares references (or primitives); equals() compares logical value; hashCode() must be consistent with equals().

Strong answer: For objects, == checks identity; equals() checks logical equality if overridden. If you override equals(), you must override hashCode() so equal objects share a hash bucket — otherwise HashMap/HashSet break. The contract: equal objects → equal hash codes (not vice versa).

Likely follow-up: What breaks if hashCode() is inconsistent with equals()?

What the interviewer is checking: Understanding of identity vs equality and the collections contract.

Common mistake: Overriding equals() but not hashCode().

Q3. Explain the Java Collections hierarchy and when you would use each core structure.

Short answer: List (order), Set (uniqueness), Map (key→value), Queue/Deque (ends); pick by access pattern.

Strong answer: ArrayList for indexed access, LinkedList rarely (poor cache locality), HashMap/HashSet for O(1) lookup, TreeMap/TreeSet for sorted order, ArrayDeque for stacks/queues, ConcurrentHashMap for concurrent access. Choose by the operations you do most and thread-safety needs.

Likely follow-up: ArrayList vs LinkedList for a queue?

What the interviewer is checking: Practical data-structure judgment, not memorized definitions.

Common mistake: Defaulting to LinkedList or Vector out of habit.

Q4. How do virtual threads change concurrency in modern Java?

Short answer: Lightweight threads scheduled by the JVM; blocking is cheap, so you can have millions.

Strong answer: Virtual threads (stable since Java 21, matured in 25) let you write simple blocking code that scales like async. The JVM parks a virtual thread on blocking I/O without pinning an OS thread, so thread-per-request models scale massively. Avoid pooling virtual threads and be careful with synchronized blocks that pin carriers.

Likely follow-up: What still pins a carrier thread?

What the interviewer is checking: Awareness of current concurrency direction, not just old thread pools.

Common mistake: Treating virtual threads as a drop-in for CPU-bound parallelism.

Q5. What are checked vs unchecked exceptions, and how should you use them?

Short answer: Checked = recoverable, must handle/declare; unchecked = programming errors, runtime.

Strong answer: Checked exceptions (extends Exception) force handling — use for recoverable conditions callers can act on. Unchecked (RuntimeException) signal bugs like NPE or illegal args. Modern practice leans toward unchecked for most app errors to avoid boilerplate, wrapping causes and failing fast with clear messages.

Likely follow-up: When would you create a custom exception?

What the interviewer is checking: Judgment about error design, not dogma.

Common mistake: Catching Exception broadly and swallowing it.

Q6. How does the Stream API work, and what is lazy evaluation?

Short answer: A pipeline of intermediate (lazy) + terminal (eager) operations over a source.

Strong answer: Streams build a pipeline: intermediate ops (map, filter) are lazy and only run when a terminal op (collect, reduce) executes. This enables fusion and short-circuiting (findFirst, limit). Use them for readable transformations, but avoid them in hot loops where the overhead matters, and never reuse a consumed stream.

Likely follow-up: What is a stateful vs stateless intermediate operation?

What the interviewer is checking: Understanding laziness and pipeline mechanics.

Common mistake: Assuming streams are always faster than loops.

Q7. Explain the volatile keyword and the Java Memory Model briefly.

Short answer: volatile guarantees visibility and ordering for a field, not atomicity of compound actions.

Strong answer: volatile ensures reads/writes go to main memory and establishes happens-before ordering, so one thread sees another’s write. It does not make count++ atomic — that needs AtomicInteger or synchronization. The JMM defines when writes by one thread become visible to others.

Likely follow-up: Why is count++ not thread-safe even if count is volatile?

What the interviewer is checking: Real concurrency understanding vs keyword-dropping.

Common mistake: Thinking volatile provides mutual exclusion.

Q8. What is dependency injection and why does it matter in Java apps?

Short answer: Providing a class its dependencies from outside rather than constructing them itself.

Strong answer: DI inverts control: instead of new-ing collaborators, a class receives them (constructor injection preferred). This decouples code, eases testing with mocks, and lets frameworks like Spring manage lifecycles. It underpins testable, modular architectures.

Likely follow-up: Constructor vs field injection — which and why?

What the interviewer is checking: Design maturity and testability awareness.

Common mistake: Confusing DI the pattern with Spring the framework.

Need Proxy Interview Support?

Share your JD on WhatsApp and clear these rounds with a stack expert.

Q9. How would you debug a memory leak in a Java service?

Short answer: Reproduce, capture a heap dump, analyze dominators, find retained references.

Strong answer: Watch heap and GC logs for a rising baseline after GC. Capture a heap dump (jmap/JFR) and open it in a tool like Eclipse MAT to find dominator trees and what retains large object sets — often static collections, unbounded caches, or listeners never removed. Fix the reference and add a bound or cleanup.

Likely follow-up: What common patterns cause leaks in long-running apps?

What the interviewer is checking: Practical production debugging skill.

Common mistake: Guessing at code instead of taking a heap dump.

Q10. What are records and sealed classes, and when are they useful?

Short answer: Records = immutable data carriers; sealed = restricted inheritance hierarchies.

Strong answer: Records auto-generate constructor, accessors, equals/hashCode/toString for immutable data — great for DTOs and value objects. Sealed classes/interfaces restrict which types can extend them, enabling exhaustive pattern matching in switch. Together they make modeling domains safer and more concise.

Likely follow-up: How do sealed types improve switch pattern matching?

What the interviewer is checking: Familiarity with modern Java, not just Java 8.

Common mistake: Never having used features past Java 8.

Q11. Explain the difference between synchronized and a ReentrantLock.

Short answer: Both provide mutual exclusion; ReentrantLock adds features like tryLock, fairness, interruptibility.

Strong answer: synchronized is simple and JVM-managed with automatic release. ReentrantLock is explicit (must unlock in finally) but supports tryLock with timeout, fairness policies, condition variables, and interruptible acquisition. Use synchronized by default; reach for ReentrantLock when you need those capabilities.

Likely follow-up: Why must you unlock in a finally block?

What the interviewer is checking: Correct concurrency primitives usage.

Common mistake: Forgetting to release the lock, causing deadlock.

Q12. How do you design a REST API in Spring Boot for scalability?

Short answer: Stateless endpoints, proper status codes, pagination, caching, and async where needed.

Strong answer: Keep endpoints stateless so you can scale horizontally, use correct HTTP verbs/status codes, paginate large collections, add caching (ETags, cache headers), validate input, and offload slow work to async/queues. Add observability (metrics, tracing) so you can find bottlenecks under load.

Likely follow-up: How would you handle a slow downstream dependency?

What the interviewer is checking: System-level thinking beyond a single controller.

Common mistake: Returning unbounded lists with no pagination.

Clear your interview with proxy interview support

Share your JD on WhatsApp and we’ll match you with a stack expert for round-wise support.

Frequently asked questions

How should I prepare for a Java interview?
Map your JD to the likely rounds, practise the questions on this page out loud, and get real-time proxy interview support for the areas you’re unsure about.
Can I get proxy interview support for Java?
Yes — share your JD on WhatsApp and we’ll match you with a stack expert for round-wise support.
Are these real interview questions?
They are real-style questions modelled on what US and global panels ask in 2026 — written fresh, not copied from anywhere.

Related pages

Talk on WhatsApp Call