Java is one of the most asked languages in Indian IT and product company interviews. These Java interview questions cover OOP, JVM, strings and exceptions for freshers, then collections, HashMap internals, multithreading, Java 8+ streams, memory management and garbage collection for experienced Java developers.
40 questions · Updated
Reading answers is not the same as saying them.Practise Java questions out loud and get a score, what you missed and a model answer for each one.
Practise free with AIJava Interview Questions: 40 questions with model answers on this page.
Basic Java interview questions
Fundamentals, definitions and simple scenarios. Good for freshers and warm-ups.
1. What is the difference between JDK, JRE and JVM?
Answer flow · 4 steps
1
The JVM (Java Virtual Machine) runs Java bytecode and makes Java platform-independent.
2
The JRE (Java Runtime Environment) contains the JVM plus the core libraries needed to run Java programs.
3
The JDK (Java Development Kit) contains the JRE plus development tools such as the javac compiler and debugger.
4
Since Java 11, the JDK is the standard download.
2. Why is String immutable in Java?
Answer flow · 3 steps
1
Immutability makes strings safe to share: they can be stored in the string pool and reused, used as HashMap keys because their hash code never changes, and passed between threads without synchronisation.
2
It also improves security, because values like file paths or URLs cannot be changed after validation.
3
StringBuilder is used when a string is modified many times.
3. What is the difference between == and equals()?
== compares references for objects, checking whether two variables point to the same object, and compares values for primitives. equals() compares logical content when a class overrides it, as String does. When you override equals(), you must also override hashCode() so equal objects have the same hash code, otherwise they behave incorrectly in HashMap and HashSet.
4. Why is Java platform-independent?
Answer flow · 4 steps
1
The Java compiler turns source code into bytecode (.class files) rather than machine code for one processor.
2
Any device with a Java Virtual Machine can run that bytecode, and the JVM translates it into native instructions, using a just-in-time compiler for speed.
3
So the same compiled program runs on Windows, Linux or macOS: "write once, run anywhere".
4
The JVM itself is platform-specific.
5. Explain public static void main(String[] args).
It is the entry point the JVM calls to start a program. public lets the JVM call it from outside the class, static means it can be called without creating an object, void means it returns nothing, main is the name the JVM looks for, and String[] args holds command-line arguments. Since Java 21 there is a preview of simpler instance main methods for beginners.
6. What are wrapper classes and autoboxing?
Answer flow · 4 steps
1
Each primitive type has a wrapper class: int has Integer, double has Double, boolean has Boolean and so on.
2
Collections can only store objects, so wrappers are needed for a List<Integer>.
3
Autoboxing converts a primitive to its wrapper automatically, and unboxing does the reverse.
4
Watch out for NullPointerException when unboxing null, and for comparing Integer objects with ==, which only works reliably for small cached values (-128 to 127).
7. What is the difference between String, StringBuilder and StringBuffer?
Answer flow · 4 steps
1
String is immutable, so every change creates a new object; it suits values that do not change.
2
StringBuilder is mutable and fast, and is the right choice for building strings in loops.
3
StringBuffer is also mutable but its methods are synchronized, which makes it thread-safe but slower; it is rarely needed today.
4
The compiler already optimises simple string concatenation with +.
8. What is the difference between final, finally and finalize?
final is a keyword: a final variable cannot be reassigned, a final method cannot be overridden and a final class cannot be extended. finally is a block after try/catch that always runs, used for cleanup. finalize was a method called by the garbage collector before removing an object; it is unreliable, deprecated since Java 9 and should not be used. try-with-resources and Cleaner replace it.
9. What does the static keyword mean?
Answer flow · 4 steps
1
static members belong to the class rather than to any object.
2
A static variable is shared by all instances, such as a counter of created objects.
3
A static method can be called without an object, such as Math.max, but cannot use instance variables or this.
4
Static blocks run once when the class loads, and static nested classes do not need an outer instance.
10. What is the difference between method overloading and method overriding in Java?
Answer flow · 3 steps
1
Overloading means several methods in the same class with the same name but different parameter lists, chosen by the compiler at compile time, such as add(int, int) and add(double, double).
2
Overriding means a subclass redefines a parent method with the same signature, chosen at runtime based on the actual object.
3
Overriding methods should use @Override, cannot reduce visibility and cannot throw broader checked exceptions.
11. What is the difference between an abstract class and an interface in Java?
Answer flow · 3 steps
1
An abstract class can have instance fields, constructors, and both abstract and concrete methods, and a class can extend only one.
2
An interface defines a contract; since Java 8 it can have default and static methods, and since Java 9 private methods, but no instance state, and a class can implement many.
3
I use interfaces for capabilities, such as Comparable or Runnable, and abstract classes for shared base code.
12. What is constructor chaining?
Constructor chaining means one constructor calling another, so initialisation code is not duplicated. this(...) calls another constructor in the same class, and super(...) calls a parent constructor; either must be the first statement. If you do not call super explicitly, the compiler inserts super() to call the parent's no-argument constructor.
13. What is the difference between an array and an ArrayList?
Answer flow · 3 steps
1
An array has a fixed size set when it is created, can hold primitives or objects, and is accessed with [].
2
An ArrayList is a resizable list from the Collections Framework that grows automatically, holds only objects (so primitives are boxed), and offers methods such as add, remove and contains.
3
Arrays are slightly faster and lighter; ArrayList is more convenient for most code.
Intermediate Java interview questions
Applied problems, trade-offs and questions about your own projects.
14. What is the difference between checked and unchecked exceptions?
Answer flow · 3 steps
1
Checked exceptions, such as IOException and SQLException, are checked at compile time and must be caught or declared with throws.
2
Unchecked exceptions extend RuntimeException, such as NullPointerException and IllegalArgumentException, and usually indicate programming errors.
3
Errors like OutOfMemoryError are serious problems that applications should not try to catch.
15. How does HashMap work internally?
Answer flow · 5 steps
1
HashMap stores entries in an array of buckets.
2
It calculates the key's hashCode, spreads it and uses it to find a bucket index.
3
Entries in the same bucket form a linked list, which turns into a balanced red-black tree when it has more than eight entries (Java 8+).
4
When the size exceeds capacity times the load factor (0.75 by default), the array doubles and entries are rehashed.
5
Lookups are O(1) on average.
16. What is the difference between ArrayList and LinkedList?
Answer flow · 3 steps
1
ArrayList uses a resizable array, so access by index is O(1) and it is cache-friendly, but inserting or removing in the middle shifts elements.
2
LinkedList is a doubly linked list, so inserting or removing at a known node is O(1) but access by index is O(n) and it uses more memory.
3
In practice ArrayList is the better default almost always.
17. What are the main Java 8 features?
Lambda expressions and functional interfaces, the Stream API for processing collections with map, filter and collect, Optional to represent values that may be missing, default and static methods in interfaces, method references, and the new java.time date and time API. Later versions added var, records, switch expressions, text blocks, sealed classes and virtual threads (Java 21).
18. What is the difference between HashMap, Hashtable and ConcurrentHashMap?
Answer flow · 4 steps
1
HashMap is not thread-safe and allows one null key and null values.
2
Hashtable is a legacy class where every method is synchronized, so it is thread-safe but slow, and allows no nulls.
3
ConcurrentHashMap is thread-safe with high concurrency: reads do not lock and writes lock only a small part of the map, using CAS operations; it allows no nulls.
4
For multi-threaded code, ConcurrentHashMap is the right choice.
19. How does HashSet work internally?
Answer flow · 4 steps
1
HashSet is backed by a HashMap.
2
Each element you add is stored as a key in that map with a constant dummy value, so uniqueness comes from the map's keys, using hashCode and equals.
3
That is why objects stored in a HashSet must implement hashCode and equals correctly.
4
LinkedHashSet keeps insertion order and TreeSet keeps elements sorted.
20. What is the difference between Comparable and Comparator?
Answer flow · 3 steps
1
Comparable defines a class's natural ordering through its own compareTo method, such as String sorting alphabetically, so it is implemented by the class itself.
2
Comparator defines an external ordering in a separate object, so you can sort the same class in many ways without changing it.
3
Java 8 made comparators easy to build, such as Comparator.comparing(Employee::getSalary).reversed().thenComparing(Employee::getName).
21. What are fail-fast and fail-safe iterators?
Answer flow · 3 steps
1
Fail-fast iterators, used by ArrayList and HashMap, throw ConcurrentModificationException if the collection is structurally changed while iterating, except through the iterator's own remove method.
2
Fail-safe (weakly consistent) iterators, used by concurrent collections such as CopyOnWriteArrayList and ConcurrentHashMap, work on a snapshot or tolerate changes and never throw that exception.
3
To remove items while looping, use iterator.remove() or removeIf.
22. What is try-with-resources?
Answer flow · 3 steps
1
Introduced in Java 7, try-with-resources automatically closes any resource that implements AutoCloseable, such as files, streams and database connections, when the block ends, even if an exception is thrown.
2
It replaces error-prone finally blocks.
3
If closing also throws, that exception is added as a suppressed exception instead of hiding the original one.
Extend Exception for a checked exception that callers must handle, or RuntimeException for an unchecked one, which is more common for business rule violations.
2
Provide constructors that accept a message and a cause, so the original exception is not lost.
3
Give it a clear name, such as InsufficientBalanceException, and in Spring map it to the right HTTP status in a global exception handler.
24. What are the ways to create a thread, and what is the difference between Runnable and Callable?
Answer flow · 3 steps
1
You can extend Thread, or better, implement Runnable and pass it to a Thread or an executor, which keeps the task separate from the threading mechanism.
2
Callable is like Runnable but returns a result and can throw checked exceptions; submitting it to an ExecutorService gives a Future to get the result.
3
In Java 21, virtual threads are created with Thread.ofVirtual() or Executors.newVirtualThreadPerTaskExecutor().
25. What is an ExecutorService, and why use thread pools?
Answer flow · 4 steps
1
Creating a new platform thread for every task is expensive and uncontrolled.
2
An ExecutorService manages a pool of reusable threads and a task queue, created through Executors or ThreadPoolExecutor.
3
You submit tasks and get Futures back, and you must shut the executor down when finished.
4
In production I size pools deliberately and use bounded queues so the system degrades gracefully under load.
26. How should Optional be used?
Answer flow · 3 steps
1
Optional is a container that may or may not hold a value, used as a method return type to make "no result" explicit and avoid returning null, such as Optional<User> findByEmail(String email).
2
Use map, filter, orElse, orElseGet and orElseThrow rather than calling get() without checking.
3
It should not be used for fields, method parameters or collections, where an empty collection is better.
27. What is the difference between map and flatMap in streams?
map transforms each element into exactly one new element, such as mapping users to their names. flatMap transforms each element into a stream and flattens all those streams into one, such as turning a list of orders into a single stream of all their items. With Optional, flatMap is used when the mapping function itself returns an Optional.
28. What is the difference between intermediate and terminal stream operations?
Answer flow · 4 steps
1
Intermediate operations such as filter, map, sorted and distinct return a new stream and are lazy: nothing runs until a terminal operation is called.
2
Terminal operations such as collect, forEach, reduce, count and findFirst produce a result or side effect and end the stream.
3
Laziness allows short-circuiting, so findFirst can stop after the first match.
4
A stream can be used only once.
29. What is serialization in Java?
Answer flow · 3 steps
1
Serialization converts an object into a byte stream so it can be saved or sent over a network, and deserialization rebuilds it.
2
A class opts in by implementing Serializable, fields marked transient are skipped, and serialVersionUID controls version compatibility.
3
Java's built-in serialization has serious security risks when reading untrusted data, so modern systems usually use JSON (Jackson), Protocol Buffers or similar formats instead.
High level Java interview questions
System design, deep internals, leadership and tough follow-ups.
30. What is the difference between synchronized, volatile and the java.util.concurrent locks?
synchronized ensures only one thread runs a block at a time on a given lock and also guarantees memory visibility. volatile guarantees visibility of a variable's latest value across threads but does not make compound actions like count++ atomic. ReentrantLock offers more control, such as tryLock, timeouts and fairness, and atomic classes like AtomicInteger give lock-free thread-safe operations.
31. How does garbage collection work in Java?
Answer flow · 4 steps
1
The JVM automatically frees objects that are no longer reachable from GC roots, such as thread stacks and static fields.
2
The heap is divided into generations: most objects die young in the young generation, which is collected often and quickly, and survivors move to the old generation.
3
G1 is the default collector; ZGC and Shenandoah offer very low pause times.
4
Tuning involves heap size and choosing the right collector.
32. What are virtual threads in Java 21?
Answer flow · 4 steps
1
Virtual threads are lightweight threads managed by the JVM rather than the operating system.
2
Millions can exist at once, and when one blocks on I/O, the JVM parks it and frees the carrier thread.
3
This lets you write simple blocking, thread-per-request code that scales like asynchronous code.
4
They are best for I/O-bound workloads and should not be pooled.
33. What are the JVM memory areas?
Answer flow · 4 steps
1
The heap stores all objects and is shared by threads; it is managed by the garbage collector and split into young and old generations.
2
Each thread has its own stack holding method frames, local variables and references; deep recursion causes StackOverflowError.
3
Metaspace (which replaced PermGen in Java 8) stores class metadata in native memory.
4
There is also the program counter register per thread and the native method stack.
34. How does class loading work in Java?
Answer flow · 4 steps
1
Classes are loaded lazily when first used, by a hierarchy of class loaders: the bootstrap loader for core Java classes, the platform loader, and the application loader for your classpath.
2
They use parent delegation, asking the parent first, so core classes cannot be replaced.
3
Loading is followed by linking (verification, preparation and resolution) and initialisation, which runs static blocks.
4
Custom class loaders enable plugins and hot reloading.
35. What is a deadlock, and how do you prevent it?
Answer flow · 4 steps
1
A deadlock happens when two or more threads each hold a lock and wait for a lock another holds, so none can continue.
2
It needs mutual exclusion, hold and wait, no pre-emption and circular wait.
3
I prevent it by always acquiring locks in the same global order, holding locks for as short a time as possible, using tryLock with a timeout, and preferring higher-level concurrency utilities.
4
Thread dumps from jstack show deadlocked threads.
36. What is CompletableFuture?
Answer flow · 3 steps
1
CompletableFuture represents an asynchronous computation that you can chain and combine without blocking. supplyAsync starts a task, thenApply transforms the result, thenCompose chains another async call, thenCombine and allOf combine several tasks, and exceptionally or handle deal with errors.
2
It is useful for calling several services in parallel and combining their results.
3
Pass your own executor rather than relying on the common pool for I/O work.
37. What are records, sealed classes and pattern matching?
Answer flow · 3 steps
1
Records (Java 16) are concise immutable data classes: record Point(int x, int y) {} generates the constructor, accessors, equals, hashCode and toString.
2
Sealed classes (Java 17) restrict which classes can extend them with permits, so the compiler knows every subtype.
3
Pattern matching for instanceof and for switch (Java 21), including record patterns, lets you test a type and extract its fields in one step, and the compiler checks that a switch over a sealed type covers every case.
38. How do you create an immutable class in Java?
Answer flow · 3 steps
1
Make the class final so it cannot be subclassed, make all fields private and final, set them only in the constructor, provide no setters, and make defensive copies of mutable inputs and outputs such as lists and dates, or use List.copyOf.
2
Immutable objects are thread-safe without synchronisation and safe to use as map keys.
3
Records give most of this automatically, but still need defensive copies for mutable components.
39. How do you implement a thread-safe singleton?
Answer flow · 4 steps
1
The simplest and safest way is an enum with a single INSTANCE, which the JVM guarantees is created once and which resists reflection and serialization attacks.
2
Another common way is the initialisation-on-demand holder idiom, a private static nested class holding the instance, which is lazy and thread-safe without locks.
3
Double-checked locking needs a volatile field to be correct.
4
In Spring applications, beans are singletons by default, so hand-written singletons are rarely needed.
40. What are generics, and what is type erasure?
Answer flow · 3 steps
1
Generics let classes and methods work with any type while keeping compile-time type safety, such as List<String> instead of a raw List that needs casting.
2
Bounded types such as <T extends Number> and wildcards such as ? extends and ? super (remember PECS: producer extends, consumer super) add flexibility.
3
Type erasure means generic type information is removed at compile time for backward compatibility, so at runtime List<String> and List<Integer> are the same class, and you cannot create new T() or check instanceof List<String>.
Java machine coding round questions
Tasks you build live in 30 to 60 minutes. What interviewers look for, plus a compact solution to compare with yours.
Reverse a string without using StringBuilder.reverse().
Answer flow · 3 steps
1
A very common fresher question.
2
Use a char array with two pointers swapping from both ends.
3
Mention that StringBuilder.reverse() exists and handles surrogate pairs correctly.
static String reverse(String s) {
char[] chars = s.toCharArray();
for (int i = 0, j = chars.length - 1; i < j; i++, j--) {
char tmp = chars[i];
chars[i] = chars[j];
chars[j] = tmp;
}
return new String(chars);
}
Count the frequency of each character in a string using streams.
Tests the Stream API and collectors. groupingBy with counting builds the map in one expression; use a LinkedHashMap to keep the order of first appearance.
Interviewers check handling of duplicates and short lists. A stream solution is short; a single loop tracking the top two values is O(n) with no sorting.