Java Interview Questions · India 2026

Top 80 Java Interview Questions & Answers India 2026

Most-asked Java interview questions for software engineers in India — from freshers to 5+ years experience. Core Java, OOP, Collections, Multithreading, JVM, Java 8+, Spring Boot.

✍️ Pranjal Jain, Ex-Microsoft · IIT Kanpur 📅 June 8, 2026 ⏱ 30 min read

Why Java Dominates Indian Tech Interviews

Java is the most widely used programming language in Indian software companies — from enterprise IT (TCS, Infosys, Wipro, Cognizant) to product companies (Flipkart, Paytm, PhonePe, Zepto, Amazon India). Nearly 70% of backend roles in India require Java knowledge.

This guide covers the 80 most-asked Java interview questions organized by topic and difficulty, with answers that are concise enough to say in an interview but deep enough to show you actually understand the concept.

Fresher (0–1 yr)

Core Java, OOP basics, String, basic Collections

Mid-Level (2–4 yrs)

Collections internals, Multithreading, JVM, Java 8

Senior (5+ yrs)

Concurrency patterns, JVM tuning, Spring Boot, design patterns

Core Java (Q1–Q20)

These questions are asked in virtually every Java interview — fresher to senior. Know all of these cold.
Q1 · Fundamentals
What is the difference between == and .equals() in Java?
== checks reference equality — whether both variables point to the same object in memory.

.equals() checks logical/value equality — whether the objects have the same content.

Key example: new String("hello") == new String("hello") is false (two different objects), but new String("hello").equals("hello") is true. Always use .equals() for String comparisons. For primitives, only == applies (no objects involved).
Q2 · String
Why is String immutable in Java?
String is immutable for three reasons:
1. Security: Strings are used for class names, file paths, network connections — mutable strings would be a security risk.
2. Thread safety: Immutable objects are inherently thread-safe (no synchronization needed).
3. String pool optimization: The JVM can intern strings (reuse the same object for the same literal) because the value can never change.

When you "modify" a String, a new String object is created. Use StringBuilder for mutable operations.
Q3 · String
What is the difference between String, StringBuilder, and StringBuffer?
String: Immutable. Each concatenation creates a new object. Use for string literals or infrequent modifications.
StringBuilder: Mutable, not thread-safe. Fastest for string manipulation in single-threaded code. Use in loops or heavy string building.
StringBuffer: Mutable, thread-safe (synchronized methods). Slower than StringBuilder due to synchronization overhead. Use only in multi-threaded string manipulation (rare in practice).
Q4 · OOP
What is the difference between abstract class and interface in Java?
Abstract class: Can have constructors, instance variables, concrete methods, and abstract methods. Single inheritance only (a class can extend one abstract class).

Interface: No constructors, no instance variables (only constants). Methods are public abstract by default (Java 8+ allows default and static methods). Multiple implementation allowed.

When to use: Use abstract class to share code among closely related classes. Use interface to define a contract that unrelated classes can implement (e.g., Comparable, Runnable).
Q5 · OOP
What is polymorphism? Explain with an example.
Polymorphism means "many forms" — the same method behaves differently based on the object. Two types:

Compile-time (method overloading): Same method name, different parameters — resolved at compile time.
Runtime (method overriding): A subclass overrides a parent method — the JVM decides at runtime which implementation to call based on the actual object type.
class Animal { void sound() { System.out.println("..."); } }
class Dog extends Animal { void sound() { System.out.println("Woof"); } }
Animal a = new Dog(); // Dog object, Animal reference
a.sound(); // prints "Woof" — runtime polymorphism
Q6 · OOP
What is the difference between overloading and overriding?
Overloading: Same method name, different parameter list (type, count, or order). Happens within the same class. Resolved at compile time (static polymorphism). Return type alone cannot distinguish overloaded methods.

Overriding: Subclass provides a specific implementation for a method already defined in the parent. Same signature (name + parameters). Resolved at runtime (dynamic polymorphism). The @Override annotation is best practice to catch typos.
Q7 · Exception Handling
What is the difference between checked and unchecked exceptions?
Checked exceptions: Subclasses of Exception (but not RuntimeException). The compiler forces you to handle them with try-catch or declare them with throws. Example: IOException, SQLException.

Unchecked exceptions: Subclasses of RuntimeException. Not enforced by the compiler. Example: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.

Error: Separate from both — represents JVM-level failures like OutOfMemoryError. Should not be caught.
Q8 · Static / Final
What is the difference between final, finally, and finalize?
final: A keyword. Applied to variable (constant — cannot be reassigned), method (cannot be overridden), or class (cannot be extended).
finally: A block in exception handling. Code inside finally always executes (whether exception occurred or not) — used for cleanup like closing connections.
finalize(): A method of Object class called by the GC before an object is collected. Deprecated in Java 9+, unreliable — don't use it.
Q9 · Memory
What is the difference between stack and heap memory in Java?
Stack: Stores method frames — local variables, method parameters, and references (not the objects themselves). Each thread has its own stack. LIFO order. Very fast. Fixed size — overflow causes StackOverflowError.

Heap: Where objects are allocated (new keyword). Shared across threads. Managed by the Garbage Collector. Divided into Young Generation (Eden + Survivor) and Old Generation (Tenured). OutOfMemoryError if full.
Q10 · Access Modifiers
What are the four access modifiers in Java and their scope?
private: Accessible only within the same class.
(default/package-private): Accessible within the same package (no keyword needed).
protected: Accessible within the same package AND subclasses (even in different packages).
public: Accessible from anywhere.

Collections Framework (Q21–Q35)

Collections questions are asked at every Java role in India. HashMap internals, equals/hashCode, and iterator behavior are favorite follow-ups.
Q21 · HashMap
How does HashMap work internally in Java?
HashMap uses an array of buckets (Node[] table). When you call put(key, value):
1. Calls key.hashCode(), applies a hash function → determines bucket index.
2. If the bucket is empty, a new Node is inserted.
3. If bucket has nodes (collision), Java 8+ uses a linked list up to 8 nodes, then converts to a Red-Black Tree (O(log n) lookup vs O(n) for linked list).

Default capacity: 16. Load factor: 0.75. When size exceeds capacity × load factor, HashMap resizes (doubles) and rehashes all entries — expensive O(n) operation.
Q22 · HashMap
Why must you override both hashCode() and equals() together?
The HashMap contract requires: if a.equals(b) is true, then a.hashCode() == b.hashCode() must also be true.

If you override only equals(), two "equal" objects may land in different buckets (different hash codes) — get() will return null even though the key exists.

If you override only hashCode(), two objects in the same bucket may not be recognized as equal — duplicates can be stored.

Java IDEs (IntelliJ, Eclipse) can generate both at once — always use that.
Q23 · Map Types
What is the difference between HashMap, LinkedHashMap, and TreeMap?
HashMap: No ordering guaranteed. O(1) average for get/put. Best for most use cases.
LinkedHashMap: Maintains insertion order (doubly-linked list). O(1) operations. Use when you need predictable iteration order.
TreeMap: Sorted by natural key order (or custom Comparator). O(log n) operations (Red-Black Tree). Use when you need sorted key iteration (e.g., range queries).
Q24 · List Types
What is the difference between ArrayList and LinkedList?
ArrayList: Dynamic array. O(1) random access by index. O(n) insert/delete in the middle (elements shift). Best for read-heavy, end-insert workloads.
LinkedList: Doubly-linked list. O(n) random access (must traverse). O(1) insert/delete at head or tail (given a node reference). Best when you frequently add/remove from both ends. Also implements Deque.

In practice, ArrayList is faster for most operations due to CPU cache locality.
Q25 · Set Types
What is the difference between HashSet, LinkedHashSet, and TreeSet?
HashSet: Backed by HashMap. No ordering, no duplicates. O(1) add/contains.
LinkedHashSet: Backed by LinkedHashMap. Maintains insertion order. O(1) operations.
TreeSet: Backed by TreeMap. Sorted order (natural or Comparator). O(log n) operations. Useful for floor(), ceiling(), headSet() range queries.

All three prevent duplicates — they call equals() and hashCode() (or compareTo() for TreeSet) to detect duplicates.
Q26 · Iteration
What is the difference between Iterator and ListIterator?
Iterator: Available for all Collection types. Can traverse in forward direction only. Supports remove() during iteration (avoids ConcurrentModificationException).

ListIterator: Only for List implementations. Can traverse forward and backward. Supports add(), set(), and remove() during iteration. Has nextIndex() and previousIndex().

Multithreading & Concurrency (Q36–Q50)

Concurrency is asked at every mid-level+ Java interview. Understand synchronized, volatile, wait/notify, and Java's util.concurrent package.
Q36 · Thread Basics
What is the difference between implementing Runnable and extending Thread?
Extending Thread: Your class extends Thread and overrides run(). Problem: Java doesn't support multiple inheritance, so your class can't extend anything else.

Implementing Runnable: Your class implements Runnable and defines run(). You pass it to a Thread constructor. Better: separates the task from the thread mechanism, allows the class to extend another class, and works well with ExecutorService.

Best practice: Use Callable<V> (returns a value) or Runnable with ExecutorService instead of creating raw threads.
Q37 · Synchronization
What is the difference between synchronized and volatile in Java?
synchronized: Provides mutual exclusion (only one thread can execute the synchronized block/method at a time) AND visibility (changes are visible to other threads after the lock is released). Prevents atomicity issues. Performance overhead due to locking.

volatile: Only provides visibility — tells the JVM to always read/write the variable from main memory, not thread-local cache. Does NOT provide atomicity. A volatile counter++ is still not thread-safe (it's read-modify-write: 3 operations). Use volatile for a single flag variable (e.g., volatile boolean running = true).
Q38 · Thread State
What are the different states of a Thread in Java?
A thread has 6 states in Java (defined in Thread.State):
1. NEW: Thread created but not started yet.
2. RUNNABLE: Thread is running or ready to run (waiting for CPU).
3. BLOCKED: Thread is waiting to acquire a monitor lock (e.g., another thread holds it).
4. WAITING: Thread called wait(), join(), or LockSupport.park() — indefinitely waiting.
5. TIMED_WAITING: Like WAITING but with a timeout — sleep(n), wait(n), join(n).
6. TERMINATED: Thread has finished execution.
Q39 · Deadlock
What is a deadlock? How do you prevent it?
A deadlock occurs when two or more threads are each waiting for a lock held by the other — circular wait.

Classic example: Thread A holds lock1, waits for lock2. Thread B holds lock2, waits for lock1. Both wait forever.

Prevention strategies:
1. Lock ordering: Always acquire locks in the same order across all threads.
2. tryLock() with timeout: Use ReentrantLock.tryLock(timeout) — give up if lock can't be acquired.
3. Avoid nested locks: If possible, never hold one lock while trying to acquire another.
4. Use higher-level concurrency: ConcurrentHashMap, CopyOnWriteArrayList, java.util.concurrent classes.
Q40 · ExecutorService
What is ExecutorService and why is it preferred over raw Thread creation?
ExecutorService (in java.util.concurrent) manages a thread pool — reusing threads instead of creating a new one for every task, which is expensive.

Benefits: Thread pooling (avoids overhead of thread creation/destruction), task queuing, lifecycle management, Future/Callable support for return values, scheduled execution.
ExecutorService pool = Executors.newFixedThreadPool(4);
Future<Integer> result = pool.submit(() -> compute());
pool.shutdown(); // orderly shutdown
Common factory methods: newFixedThreadPool(n), newCachedThreadPool(), newSingleThreadExecutor(), newScheduledThreadPool(n).

JVM Internals (Q51–Q60)

JVM questions are asked at senior levels and at companies like Amazon, Flipkart, and product-first companies. Know garbage collection, classloading, and JIT basics.
Q51 · JVM Architecture
Explain the JVM architecture and how Java code runs.
Java source (.java) → javac compiler → bytecode (.class) → JVM loads and executes bytecode.

JVM components:
1. Class Loader: Loads .class files (Bootstrap → Extension → Application class loaders).
2. Runtime Data Areas: Method Area (class metadata), Heap (objects), Stack (method frames, per-thread), PC Register, Native Method Stack.
3. Execution Engine: Interpreter (slow, line-by-line) + JIT Compiler (compiles hot paths to native code — makes Java fast) + Garbage Collector.
Q52 · Garbage Collection
How does Garbage Collection work in Java? What are GC algorithms?
The GC automatically reclaims memory from objects that are no longer reachable (no references from roots: stack variables, static fields, JNI).

Heap structure: Young Generation (Eden + 2 Survivor spaces) → Old Generation (Tenured).
Minor GC: Cleans Young Gen (fast, frequent). Objects surviving multiple GCs are promoted to Old Gen.
Major/Full GC: Cleans Old Gen (slow, causes pauses). Goal: minimize "stop-the-world" pauses.

Common GC algorithms:
Serial GC: Single-threaded. Good for small apps.
G1 GC (default Java 9+): Region-based, concurrent, predictable pause times. Good for large heaps.
ZGC / Shenandoah: Ultra-low latency (<1ms pauses). For latency-sensitive microservices.

Java 8+ Features (Q61–Q70)

Java 8 features are mandatory knowledge for any Java interview in India today. Lambda, Stream API, and Optional are the most asked.
Q61 · Lambda
What is a lambda expression in Java? What is a functional interface?
A lambda expression is an anonymous function — shorthand for implementing a functional interface inline.
// Before Java 8
Runnable r = new Runnable() { public void run() { System.out.println("hi"); } };

// With lambda
Runnable r = () -> System.out.println("hi");
A functional interface is an interface with exactly one abstract method (annotated with @FunctionalInterface). Examples: Runnable, Callable, Comparator, Predicate<T>, Function<T,R>, Consumer<T>, Supplier<T>.
Q62 · Stream API
What is the Java Stream API? What is the difference between intermediate and terminal operations?
The Stream API allows declarative, functional-style processing of collections. Streams are lazy — nothing executes until a terminal operation is called.

Intermediate operations (return Stream, lazy): filter(), map(), flatMap(), sorted(), distinct(), limit(), peek().
Terminal operations (trigger execution, return result): collect(), forEach(), count(), findFirst(), reduce(), anyMatch(), toList().
List<String> result = list.stream()
  .filter(s -> s.startsWith("A"))    // intermediate
  .map(String::toUpperCase)         // intermediate
  .collect(Collectors.toList());     // terminal
Q63 · Optional
What is Optional in Java 8 and when should you use it?
Optional<T> is a container that may or may not hold a non-null value. It makes nullability explicit in the API, reducing NullPointerException risks.
Optional<String> opt = Optional.ofNullable(getName());
opt.ifPresent(name -> System.out.println(name));
String result = opt.orElse("Unknown");
String result2 = opt.orElseThrow(() -> new NotFoundException());
Use for: Return types of methods that may not find a result (like repository findById()). Don't use Optional as a method parameter, in collections, or in entity fields.
Q64 · Default Methods
What are default methods in Java 8 interfaces? Why were they added?
Default methods allow interfaces to provide a method implementation using the default keyword. Introduced to enable backward-compatible API evolution — adding new methods to existing interfaces without breaking all implementing classes.
interface Vehicle {
  default void start() { System.out.println("Starting..."); }
}
If a class implements two interfaces with the same default method, it must override it (compile error otherwise). If a class inherits a method from a superclass and a default method from an interface with the same signature, the class method wins.

Spring Boot (Q71–Q80)

Spring Boot is used at almost every Indian product company. These questions are asked for backend/fullstack Java roles at Amazon, Flipkart, Paytm, and enterprise companies.
Q71 · Spring Core
What is Dependency Injection and Inversion of Control in Spring?
Inversion of Control (IoC): Instead of your class creating its own dependencies, the Spring container creates and manages them. Control over object creation is "inverted" from the class to the framework.

Dependency Injection (DI): The mechanism Spring uses to provide dependencies to objects — via constructor, setter, or field injection. Constructor injection is preferred (promotes immutability and testability).
@Service
public class OrderService {
  private final PaymentService paymentService;

  // Constructor injection (preferred)
  public OrderService(PaymentService ps) { this.paymentService = ps; }
}
Q72 · Spring Annotations
What is the difference between @Component, @Service, @Repository, and @Controller?
All four are specializations of @Component — they all register a Spring bean. The difference is semantic and enables additional functionality:
@Component: Generic Spring bean — use when no other specialization fits.
@Service: Business logic layer. No extra behavior, but communicates intent.
@Repository: Data access layer. Automatically wraps persistence exceptions into Spring's DataAccessException hierarchy.
@Controller: Web MVC controller. Handles HTTP requests. Use @RestController (= @Controller + @ResponseBody) for REST APIs.
Q73 · Transactions
How does @Transactional work in Spring? What are propagation and isolation?
@Transactional wraps a method in a database transaction. Spring uses AOP to proxy the bean — on method call, a transaction is begun; on normal return, it commits; on RuntimeException, it rolls back.

Propagation: What happens when a transactional method calls another transactional method. Common values: REQUIRED (default — join existing or create new), REQUIRES_NEW (always new transaction), NESTED.

Isolation: Controls what a transaction can see from concurrent transactions. Levels: READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE. Higher isolation = fewer anomalies but lower concurrency.
Q74 · Auto-configuration
What is Spring Boot auto-configuration? How does @SpringBootApplication work?
@SpringBootApplication is a meta-annotation combining:
1. @Configuration — marks it as a config class
2. @EnableAutoConfiguration — tells Spring Boot to guess and configure beans based on classpath dependencies
3. @ComponentScan — scans the package and sub-packages for Spring components

Auto-configuration reads META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Java 2.7+) or spring.factories — lists of config classes. Each config class uses @ConditionalOnClass, @ConditionalOnMissingBean etc. to decide if it should apply.
Q75 · Bean Scopes
What are Spring bean scopes?
singleton (default): One instance per Spring container. The same bean is returned for all requests.
prototype: A new instance created every time the bean is requested.
request: New instance per HTTP request (web context only).
session: New instance per HTTP session (web context only).
application: One instance per ServletContext lifecycle.

Injecting a prototype-scoped bean into a singleton requires special handling (using ApplicationContext.getBean() or @Lookup) — otherwise the prototype bean gets created once (when the singleton is created) and reused, defeating its purpose.
💡
Final tip for Java interviews in India: The most common follow-up after any Java answer is "what happens under the hood?" For HashMap: "how does it rehash?". For synchronized: "how does a monitor lock work?". For Spring: "how does AOP proxy work?". Practice explaining the internals — that's what separates a good answer from a great one.
Pranjal Jain
Pranjal Jain

Ex-Microsoft SDE · IIT Kanpur · Founder of Prepflix. Helps engineers crack product company interviews across India.