0% found this document useful (0 votes)
2 views38 pages

Java BE Master Guide Answers

The document is a comprehensive guide covering various topics related to Java, including JVM, Java 8 features, collections, multithreading, and Spring. It includes a structured breakdown of questions and answers across different levels of difficulty, providing insights into concepts such as JVM architecture, functional interfaces, and memory management. Additionally, it offers practical tips for interview preparation and performance tuning in Java applications.

Uploaded by

sandeep.r
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views38 pages

Java BE Master Guide Answers

The document is a comprehensive guide covering various topics related to Java, including JVM, Java 8 features, collections, multithreading, and Spring. It includes a structured breakdown of questions and answers across different levels of difficulty, providing insights into concepts such as JVM architecture, functional interfaces, and memory management. Additionally, it offers practical tips for interview preparation and performance tuning in Java applications.

Uploaded by

sandeep.r
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

aster Guide – Complete Answers JVM · Java 8 · Collections · Multithreading · Spring B

■ Basic ■ Intermediate ■ Advanced

# Section Coverage

1 JVM / Java / JRE Q1–Q9

2 Java 8 Features Q10–Q21

3 Collections Q22–Q50

4 Exception Handling Q51–Q56

5 String Q57–Q66

6 Multithreading Q67–Q91

7 Spring / Spring Boot Q92–Q101

8 Spring Controller & Web Q102–Q127

9 JPA / JDBC Q128–Q162

10 Database Q163–Q184

11 Microservices Q185–Q209
1. JVM / Java / JRE

1 What is Java Virtual Machine (JVM)? Difference between JVM / JDK Basic
/ JRE?
The JVM (Java Virtual Machine) is an abstract computing machine that enables Java's WORA (Write Once, Run
Anywhere) promise. It loads, verifies, and executes Java bytecode (.class files) on the host OS. The JVM is not a
physical machine—it is a specification, and each vendor ships an implementation (HotSpot, OpenJ9, GraalVM).

Component Contains Purpose

JDK JRE + javac + tools (jar, jdb, jshell, jmap, jstack…)


Develop, compile, run Java apps

JRE JVM + core libraries ([Link] / modules) Run Java apps (no compiler)

JVM Class loader + Runtime data areas + Execution engine


Execute bytecode

Key insight
JDK ⊃ JRE ⊃ JVM. Since Java 11, Oracle merged JDK and JRE; there is no standalone JRE download—you ship a
custom runtime with jlink.

■ Interviewer Tip

Be ready to explain WORA: bytecode is platform-neutral; the JVM implementation is platform-specific. Mention that
GraalVM's native-image compiles ahead-of-time, giving a different tradeoff.

2 Explain the JVM architecture and its main components. What are Intermediate
the different runtime data areas?

JVM Architecture
The JVM has three main subsystems:
• Class Loader Subsystem – Loading, Linking (Verify → Prepare → Resolve), Initialization.
• Runtime Data Areas – Memory regions used during execution.
• Execution Engine – Interpreter, JIT compiler, Garbage Collector.

Runtime Data Areas

Area Shared? Purpose

Method Area / Metaspace Yes (all threads) Class metadata, static variables, constant pool

Heap Yes (all threads) Object instances & arrays; GC operates here

JVM Stacks No (per thread) Frames for each method call; holds local vars, operand stack

PC Register No (per thread) Address of next JVM instruction to execute

Native Method Stack No (per thread) Supports native (C/C++) method calls via JNI
// Each method call pushes a new Stack Frame containing: // 1. Local Variable Array – method params +
local vars // 2. Operand Stack – for arithmetic / method args // 3. Frame Data – return address, ref to
constant pool public int add(int a, int b) { // creates one frame on the JVM stack return a + b; //
uses operand stack internally }

■ Interviewer Tip

StackOverflowError → JVM stack exhausted (deep/infinite recursion). OutOfMemoryError: Java heap space → heap full.
OutOfMemoryError: Metaspace → class metadata area full.

3 What are thread-specific runtime data areas? What is the impact of Intermediate
thread creation on memory?
Each thread gets its own copy of three areas:
• JVM Stack: Each new method call pushes a frame (~KB); uncapped deep recursion causes StackOverflowError.
Default stack size: ~512 KB–1 MB (configurable with -Xss).
• PC (Program Counter) Register: 1 word; tracks next instruction address. Negligible overhead.
• Native Method Stack: Used only when calling JNI methods; same overflow risk.
Impact of creating 1,000 threads: ~1,000 × 1 MB = ~1 GB just for stacks, before any heap usage. This is why thread
pools and virtual threads (Java 21) exist—virtual threads have tiny, heap-allocated stacks that grow on demand.

■ Interviewer Tip

Mention Project Loom (Java 21): virtual threads are mounted on carrier threads; their stack lives on the heap, making
millions of concurrent tasks feasible without OOM.

4 Advanced
Explain the Java Memory Model (JMM) and its guarantees.

The JMM defines how threads interact through memory. Without it, the compiler, CPU, and caches can reorder
instructions freely, leading to visibility bugs.

JMM Guarantees
• Atomicity: reads/writes of int, float, references are atomic; long/double may not be unless volatile.
• Visibility: without synchronisation, a thread may read a stale cached value.
• Ordering: the JMM defines when one action is guaranteed to be seen by another (happens-before).
// Without JMM guarantees – may loop forever boolean ready = false; int value = 0; // Thread 1 value =
42; ready = true; // CPU may reorder these two writes! // Thread 2 while (!ready) {}
[Link](value); // may print 0 without volatile // Fix: declare both volatile or use
synchronized block

■ Interviewer Tip

The JMM was formally revised in Java 5 (JSR-133). Key rules: volatile writes happen-before subsequent volatile reads of
the same variable; monitor unlock happens-before subsequent lock on the same monitor.

5 Advanced
What are happens-before relationships in the JMM?
Happens-before is the JMM's formal ordering guarantee: if action A happens-before action B, then A's effects are visible
to B—no matter what the CPU cache or compiler does.

Built-in Happens-Before Rules


• Program order: each action in a thread happens-before the next action in that thread.
• Monitor lock: unlock(m) happens-before every subsequent lock(m).
• Volatile write: write to volatile field happens-before every subsequent read of that field.
• Thread start: [Link]() happens-before any action in the started thread.
• Thread join: all actions in a thread happen-before [Link]() returns.
• Transitivity: if A hb B and B hb C, then A hb C.
volatile boolean flag = false; int data = 0; // Thread 1 data = 100; // (A) flag = true; // (B)
volatile write – flushes data too // Thread 2 while (!flag) {} // (C) volatile read – happens-before
guarantees A visible [Link](data); // (D) sees 100 because: A hb B hb C hb D

6 How does the JVM implement volatile variables and atomic Advanced
operations?
volatile maps to CPU memory-barrier (fence) instructions:
• A volatile write emits a StoreStore barrier before and a StoreLoad barrier after – flushes processor write buffer.
• A volatile read emits a LoadLoad barrier before and a LoadStore barrier after – invalidates CPU cache line, fetching
fresh value.
Atomic operations ([Link]) use CPU Compare-And-Swap (CAS) instructions (x86: LOCK
CMPXCHG). CAS is a single atomic instruction: if [address] == expected, set [address] = new; return old value.
AtomicInteger counter = new AtomicInteger(0); // Under the hood for incrementAndGet(): // do { old =
[Link](); } while (!CAS(counter, old, old+1)); // No lock needed – CAS retry loop (spin) is fast
for low contention

■ Limitation

volatile guarantees visibility but NOT atomicity of compound actions (e.g., i++ = read-modify-write). Use AtomicInteger or
synchronized for compound updates.

7 Production service shows frequent Full GCs. How would you Advanced
analyse and resolve?

Step 1 – Collect Evidence


• Enable GC logging: -Xlog:gc*:file=[Link]:time,uptime,level,tags:filecount=5,filesize=20m
• Use JFR: jcmd [Link] duration=60s filename=[Link]
• Heap histogram: jmap -histo:live

Step 2 – Diagnose Cause

Symptom Likely Cause Fix

Old Gen fills up fast Memory leak / oversized objects Heap dump + analyzer (MAT/VisualVM)

Many long-lived objects Tuning: survivors too small Increase -XX:SurvivorRatio

Metaspace OOM Class loader leak Check frameworks, dynamic proxies


Symptom Likely Cause Fix

GC pauses >1s Heap too large for STW Switch to G1/ZGC/Shenandoah

Frequent minor GC Eden too small Increase -Xmn or NewRatio

Step 3 – Common JVM Tuning Args


-Xms4g -Xmx4g # Heap size (set equal to avoid resize pauses) -XX:+UseG1GC # G1 – default Java 9+; good
for large heaps -XX:MaxGCPauseMillis=200 # Pause target for G1 -XX:+UseZGC # Sub-millisecond GC (Java
15+ production-ready) -XX:MetaspaceSize=256m # Avoid frequent Metaspace GC
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/[Link]

■ Interviewer Tip

Mention the GC algorithms: Serial (single-thread, small heaps), Parallel GC (throughput), G1 (balanced, default since Java
9), ZGC & Shenandoah (ultra-low pause, concurrent).

8 Intermediate
Various JVM/Java args that can help fine-tune performance?

Flag Purpose

-Xss512k Per-thread stack size (reduce for many threads)

-XX:+TieredCompilation Enable C1+C2 JIT (default)

-XX:CompileThreshold=1000 Methods compiled after 1000 invocations

-XX:+PrintCompilation Log JIT compilation events

-XX:+UseStringDeduplication Reduce duplicate String objects (G1 only)

-XX:+OptimizeStringConcat Optimize String concatenation

-[Link]=8 Control common ForkJoinPool size

-XX:+AlwaysPreTouch Touch heap pages at JVM start (reduces latency spikes)

9 Intermediate
What is MetaSpace? How does it differ from PermGen?

Aspect PermGen (≤ Java 7) Metaspace (Java 8+)

Location JVM heap (contiguous) Native memory (off-heap)

Default size Fixed (default 64–85 MB) Unbounded (limited by OS)

OOM risk Frequent in large apps Less frequent; can set -XX:MaxMetaspaceSize

What's stored Class metadata, interned strings, static vars Class metadata only (statics moved to heap)

GC Part of Full GC GC-triggered when threshold reached


Metaspace uses native memory and resizes dynamically. The main trigger for Metaspace OOM is a class-loader leak
(e.g., redeploy-heavy app servers, reflection-heavy frameworks creating new class loaders).
2. Java 8 Features

10 What are Functional Interfaces? Why added in Java 8? Is Basic


@FunctionalInterface mandatory?
A Functional Interface (FI) is an interface with exactly one abstract method (SAM – Single Abstract Method). Java
8 introduced them to enable lambda expressions—every lambda is an instance of a FI.
Why? To enable functional-style programming: passing behaviour (code) as data without verbose anonymous class
boilerplate. Enables Streams, CompletableFuture, event handlers.
@FunctionalInterface is NOT mandatory, but recommended: it is a compile-time contract—if you accidentally add a
second abstract method, the compiler errors immediately.
@FunctionalInterface interface MathOperation { int operate(int a, int b); // exactly one SAM // can
have default/static methods – still a FI default void printResult(int r) { [Link](r); } }
// Lambda is an instance of MathOperation MathOperation add = (a, b) -> a + b; MathOperation fizzBuzz =
(a, b) -> (a + b) % 3 == 0 ? 0 : a + b; [Link]([Link](3, 4)); // 7

11 Types/Categories of Functional Interfaces? Pre-defined FIs? Basic


Difference between Predicate, Function, and Supplier?

Interface Signature Use case

Predicate<T> boolean test(T t) Filter / boolean condition

Function<T,R> R apply(T t) Transform / map one type to another

BiFunction<T,U,R> R apply(T t, U u) Two-input function

Supplier<T> T get() Lazy value producer (no input)

Consumer<T> void accept(T t) Consume value, produce no result

BiConsumer<T,U> void accept(T t, U u) Consume two values

UnaryOperator<T> T apply(T t) Special Function where T in = T out

BinaryOperator<T> T apply(T t1, T t2) Same type input+output binary op

Runnable void run() Pre-defined, no args no return

Callable<V> V call() throws Exception Pre-defined, returns value, can throw

12 Basic
Write a FI for summing 2 numbers or FizzBuzz and use it.

@FunctionalInterface interface IntBiOp { int apply(int a, int b); } // Sum IntBiOp sum = (a, b) -> a +
b; [Link]([Link](5, 7)); // 12 // FizzBuzz as Function<Integer, String>
Function<Integer, String> fizzBuzz = n -> (n % 15 == 0) ? "FizzBuzz" : (n % 3 == 0) ? "Fizz" : (n % 5
== 0) ? "Buzz" : [Link](n); [Link](1,
20).mapToObj(fizzBuzz::apply).forEach([Link]::println);
13 Basic
What is a default method, and why is it required?

A default method is a method in an interface with a body, marked with the default keyword. Introduced in Java 8.

Why required?
• Backward compatibility: Java needed to add forEach(), stream(), etc. to Collection and List interfaces without
breaking every existing implementation. Default methods allowed adding new behaviour to existing interfaces without
forcing all implementors to update.
• Mixin-style reuse: interfaces can now provide shared utility behaviour.
interface Vehicle { String getBrand(); // abstract – must implement default String getType() { return
"Car"; } // default – may override static Vehicle create(String b) { return () -> b; } } class Bus
implements Vehicle { public String getBrand() { return "Volvo"; } @Override public String getType() {
return "Bus"; } // overriding default }

■ Diamond Problem

If two interfaces provide conflicting default methods, the implementing class MUST override it; otherwise compile error.
Class method always wins over interface default.

14 Intermediate
Can a Functional Interface extend another interface?

Rules:
• A FI can extend an interface that has no abstract methods (e.g., Marker interfaces or interfaces with only
default/static methods). Still has exactly one SAM.
• A FI cannot extend another interface that adds a new abstract method—that would give it 2 SAMs, violating the FI
contract.
• A FI CAN inherit abstract methods that it also overrides from Object (like equals, hashCode, toString)—these don't
count toward the SAM count.
interface Printable { default void print() { [Link]("printing"); } } @FunctionalInterface
interface PrintableSupplier<T> extends Printable { T get(); // still one SAM – valid FI }

15 Method References? Syntax? How to sort ignoring case using Intermediate


method reference?

Type Syntax Example

Static method ClassName::staticMethod Integer::parseInt

Instance method (specific) instance::method [Link]::println

Instance method (arbitrary) ClassName::instanceMethod String::toUpperCase

Constructor ClassName::new ArrayList::new

List<String> names = [Link]("Banana", "apple", "Cherry"); // Lambda version: [Link]((a, b)


-> [Link](b)); // Method reference – String::compareToIgnoreCase // matches
BiFunction<String,String,Integer> = Comparator<String> [Link](String::compareToIgnoreCase); //
clean & readable // Printing [Link]([Link]::println); // instance method of specific object
16 Difference between Lambdas and Anonymous Inner Classes in Intermediate
scope and performance?

Aspect Lambda Anonymous Inner Class (AIC)

'this' reference Refers to enclosing class Refers to the AIC itself

Separate .class file No (no extra .class generated) Yes (OuterClass$[Link])

Variable capture Effectively final only Effectively final only

Implementation invokedynamic (linkage deferred to runtime) new HeapObject each call

Memory Often single instance (stateless lambda) Always a new object

Serialisable Not by default Can implement Serializable

Performance: Lambda uses invokedynamic (LambdaMetafactory at first call, then direct method handle) – avoids
creating a new class file and can be optimised by JIT. Stateless lambdas are cached as a singleton.

17 Intermediate
Asynchronous Programming? CompletableFuture?

CompletableFuture (Java 8) is the go-to for non-blocking async pipelines. It implements both Future and
CompletionStage.
CompletableFuture<String> future = CompletableFuture .supplyAsync(() -> fetchUser(id)) // runs in
ForkJoinPool .thenApply(user -> enrichUser(user)) // transform (sync) .thenCompose(user ->
fetchOrders([Link])) // chain another CF (flatMap) .exceptionally(ex -> defaultUser()) // handle
error .thenAccept([Link]::println); // terminal consumer // Combine two independent futures
CompletableFuture<String> a = [Link](() -> "Hello"); CompletableFuture<String>
b = [Link](() -> "World"); [Link](b, (x, y) -> x + " " +
y).thenAccept([Link]::println); // Wait for all [Link](a, b).join();

■ Interviewer Tip

thenApply = map; thenCompose = flatMap. Use thenApplyAsync/thenComposeAsync to run the callback on a different
thread pool. Always handle exceptionally or handle to prevent silent failures.

18 Difference between terminal and intermediate operations in Java 8 Basic


Streams?

Aspect Intermediate Terminal

Returns Stream<T> Non-stream result or void

Evaluation Lazy (not executed until terminal) Triggers pipeline execution

Examples filter, map, flatMap, sorted, distinct, peek, limit, skip


collect, forEach, count, reduce, findFirst, anyMatch, toList()

Can chain? Yes No

List<String> result = [Link]("a","bb","ccc","dd","e") .filter(s -> [Link]() > 1) // intermediate


– lazy .map(String::toUpperCase) // intermediate – lazy .sorted() // intermediate – lazy
.collect([Link]()); // terminal – triggers ALL above // Nothing runs until collect() is
called!

19 Intermediate
Parallel Streams? When to use? Pitfalls in a web application?

parallelStream() splits the stream into sub-streams processed by the common ForkJoinPool (default: CPU cores – 1
threads). Under the hood: Spliterator divides data; work-stealing balances load.

When to use
• Large data sets (hundreds of thousands of elements).
• CPU-bound, stateless, order-independent operations.

Pitfalls in a Web Application


• Thread starvation: parallel streams share the COMMON ForkJoinPool with other parallel tasks. In a web app,
every request using parallelStream() competes for the same small pool.
• Deadlock risk: if parallel task itself tries to join another parallel task.
• Shared mutable state: counter++ in parallel stream is a race condition.
• Ordering overhead: forEachOrdered() in parallel negates parallelism benefit.
• Small collections: overhead of splitting/merging worse than sequential.
// WRONG: shared mutation int[] count = {0}; [Link]().forEach(e -> count[0]++); // race
condition // RIGHT: use reduction or atomic long count = [Link]().count(); // safe // or
use a custom ForkJoinPool to avoid starving common pool: ForkJoinPool pool = new ForkJoinPool(4);
[Link](() -> [Link]().forEach(this::process)).get();

20 What is a Spliterator in Java 8? Difference between Iterator vs Intermediate


Spliterator?

Aspect Iterator Spliterator

Purpose Sequential traversal Sequential + parallel traversal

Java version Java 1.2 Java 8

Key method hasNext() / next() tryAdvance() / forEachRemaining() / trySplit()

Parallel support No Yes – trySplit() divides for parallel processing

Characteristics None SIZED, ORDERED, SORTED, DISTINCT, etc.

trySplit() is the key method: it returns a new Spliterator covering roughly half the elements, enabling Fork/Join
parallelism. If the collection is small or unsplittable, returns null.

21 Intermediate
Is multiple inheritance possible in Java 8? Diamond problem?

Java does not support multiple inheritance of classes (to avoid ambiguity). A class can implement multiple interfaces.
With default methods in Java 8, the diamond problem can arise if two interfaces define the same default method.
Resolution rules:
• 1. Class wins: if the class (or superclass) overrides the method, it wins.
• 2. Most specific interface wins: if InterfaceB extends InterfaceA and both have the default, InterfaceB's version
wins.
• 3. Must override: if two independent interfaces have the same default method, the implementing class must
override it.
interface A { default void hello() { [Link]("A"); } } interface B extends A { default void
hello() { [Link]("B"); } } interface C { default void hello() { [Link]("C"); }
} class D implements B, A {} // B wins (more specific) – prints "B" class E implements A, C {} //
COMPILE ERROR – must override hello() class F implements A, C { public void hello() { [Link]();
} // explicit resolution }
3. Collections

22 Internal working of ArrayList and HashMap. What happens when Intermediate


you put a duplicate key in HashMap?

ArrayList – Internal Working


ArrayList wraps an Object[] array. Default initial capacity = 10. When capacity is reached, it grows to capacity × 1.5: a
new array is allocated and [Link] copies all elements—O(n) cost but amortised O(1) add.
// ArrayList growth: DEFAULT_CAPACITY = 10, grow factor ~1.5 int newCapacity = oldCapacity +
(oldCapacity >> 1); // e.g., 10 → 15 → 22 Object[] newArray = [Link](elementData,
newCapacity);

HashMap – Internal Working


HashMap stores entries in an array of Node[] table. Steps for put(key, value):
• 1. hashCode(): compute hash of key.
• 2. Spread hash: (h = [Link]()) ^ (h >>> 16) – mixes high/low bits to reduce collisions.
• 3. Index: (capacity – 1) & hash – bitwise AND ensures index stays in array bounds.
• 4. Bucket: if empty, create Node; if occupied (collision), chain as singly linked list.
• 5. Treeify: if a bucket's linked list length ≥ 8 AND [Link] ≥ 64, convert to Red-Black Tree → O(log n) lookup
instead of O(n).
• 6. Resize (rehash): when size > capacity × loadFactor (default 0.75), double capacity and rehash all entries.

Duplicate Key
If the key already exists (same hash + equals() returns true), the old value is replaced with the new value. The key is
NOT duplicated. put() returns the old value.

■ Key Requirements

For HashMap keys: override BOTH hashCode() AND equals(). If two keys are equal() but have different hashCodes,
HashMap treats them as different keys—data corruption. Use immutable objects as keys (String, Integer) for safety.

23 Why ConcurrentHashMap when HashTable already exists? Intermediate


Segmentation, Locking, Concurrent Modification?

Feature HashTable ConcurrentHashMap

Locking Entire table locked (single lock) Bucket-level locking (Java 8: CAS + synchronized on bin)

Null keys/values Not allowed Not allowed

Concurrent reads Blocked while writing Non-blocking reads (volatile fields)

Throughput Low (coarse lock) High (fine-grained locks)

Java version Legacy (Java 1.0) Java 5+, redesigned Java 8

Iterator Fail-fast (throws CME) Weakly consistent (no CME)


Java 8 Implementation: CHM uses an array of Node bins. Reads use volatile reads (no lock). Writes use CAS for
empty bins, or synchronized on the bin head for non-empty. This allows 16–n concurrent writers to different bins
simultaneously.

24 Basic
Differences between Vector and ArrayList?

Feature Vector ArrayList

Thread Safety Synchronized (all methods) Not synchronized

Growth Doubles capacity Grows 50%

Performance Slower (lock overhead) Faster

Fail-fast iterator Yes Yes

Legacy Java 1.0 (legacy) Java 1.2 (preferred)

Prefer ArrayList for single-threaded code. For thread-safe lists, use CopyOnWriteArrayList or
[Link](new ArrayList<>()).

25 Basic
When is LinkedList better than ArrayList?

LinkedList is better when:


• Frequent insertions/deletions at the head or middle: O(1) once you have the node reference (no array shifting).
ArrayList shifts elements O(n).
• Implementing a Queue or Deque: LinkedList implements Deque; addFirst/removeFirst are O(1).
ArrayList is better for random access (get(i) is O(1) vs O(n) for LinkedList) and for most iteration-heavy workloads
(better cache locality).
In practice, ArrayList outperforms LinkedList in almost all real-world scenarios due to CPU cache locality. LinkedList has
higher per-element memory overhead (two pointers + object header).

26 Basic
Differences between HashMap and Hashtable?

Feature HashMap Hashtable

Null 1 null key, multiple null values No null key or value

Thread safety Not thread-safe Thread-safe (synchronized methods)

Performance Faster Slower (coarse-grained locking)

Iterator Fail-fast Enumerator (not fail-fast)

Inheritance AbstractMap Dictionary (legacy)


27 Intermediate
Internal working of TreeMap? Difference from HashMap?

TreeMap is backed by a Red-Black Tree (a self-balancing BST). All operations (get, put, remove) are O(log n).
Maintains keys in natural sorted order (Comparable) or custom Comparator order.

Aspect HashMap TreeMap

Order None (hash-based) Sorted by key (natural/Comparator)

get/put O(1) average O(log n)

Null key 1 allowed Not allowed (NullPointerException)

Extra API None firstKey(), lastKey(), headMap(), tailMap(), floorKey()

28 Immutable class – why needed? How to make it secure from I/O Intermediate
and reflection?
Why? Immutable objects are inherently thread-safe (no state changes), safe as Map keys (hash never changes), and
easier to reason about.

Rules to Create an Immutable Class


• 1. Declare class as final (prevents subclassing).
• 2. All fields private final.
• 3. No setters.
• 4. Return deep copies of mutable fields in getters.
• 5. Make deep copies of mutable constructor args.
public final class ImmutablePerson { private final String name; private final List<String> hobbies; //
mutable field! public ImmutablePerson(String name, List<String> hobbies) { [Link] = name;
[Link] = new ArrayList<>(hobbies); // defensive copy IN } public String getName() { return name;
} public List<String> getHobbies() { return [Link](hobbies); // defensive copy
OUT } }

Security against Reflection


• Reflection can bypass private + final. Mitigation: add a check in the constructor to throw an exception if already
instantiated, or use Java modules ([Link] with opens restrictions).

29 Intermediate
Shallow vs Deep cloning? Which for Immutable class?

Aspect Shallow Clone Deep Clone

Primitive fields Copied Copied

Object references Reference copied (same object) New objects created recursively

Method [Link]() (implements Cloneable) Manual copy / serialization / copy constructors

Risk Shared mutable state Safe

For Immutable? Not needed (immutable has no mutable state) Required if constructor receives mutable objects
// Shallow clone – reference is shared: int[] orig = {1,2,3}; int[] shallow = [Link](); shallow[0]
= 99; // orig[0] is still 1 for primitives in array // But for object arrays, the referenced objects
ARE shared // Deep clone via serialization (all classes must be Serializable): ByteArrayOutputStream
bos = new ByteArrayOutputStream(); new ObjectOutputStream(bos).writeObject(original); MyClass deepCopy
= (MyClass) new ObjectInputStream( new ByteArrayInputStream([Link]())).readObject();

30 Comparator vs Comparable? Implement to sort Employee by Basic


descending salary.

Aspect Comparable Comparator

Package [Link] [Link]

Method compareTo(T o) compare(T o1, T o2)

Modifies class? Yes (must implement in class) No (external class / lambda)

Natural order Yes (single) Multiple orderings possible

Use case Default sort Custom / alternate sort

class Employee implements Comparable<Employee> { int id; String name; double salary; int age; //
Natural order – ascending by id public int compareTo(Employee o) { return [Link]([Link],
[Link]); } } List<Employee> emps = ...; // given list // Sort by descending salary using Comparator:
[Link]([Link](Employee::getSalary).reversed()); // or: [Link]((e1, e2) ->
[Link]([Link], [Link])); // Multi-level sort: descending salary, then ascending name:
[Link]([Link](Employee::getSalary).reversed()
.thenComparing(Employee::getName));

31 Intermediate
What is CopyOnWriteArrayList? How is it different from ArrayList?

CopyOnWriteArrayList (COWAL) creates a fresh copy of the underlying array on every mutating operation (add,
set, remove). Reads see the current snapshot without locking.

Aspect ArrayList CopyOnWriteArrayList

Thread safety Not thread-safe Thread-safe

Write cost O(1) amortised O(n) – full array copy

Read cost O(1) O(1), lock-free

Iterator Fail-fast (throws CME) Fail-safe (snapshot, no CME)

Best for Single-threaded / synchronized externally Read-heavy, rare writes (event listeners)

32 Advanced
WeakHashMap? WeakReference? SoftReference?

Type GC Behaviour Use Case

StrongReference Never GC'd while reachable Normal objects


Type GC Behaviour Use Case

SoftReference GC'd only when JVM needs memory (last resort)Memory-sensitive cache

WeakReference GC'd at the next GC cycle Canonicalized mappings, listeners

PhantomReference GC'd; enqueued for post-mortem cleanup Off-heap resource cleanup

WeakHashMap: keys are stored as WeakReferences. When a key is GC'd (no other strong reference exists), the entry is
automatically removed. Used for metadata maps where entries should live only as long as the key lives.

33 Intermediate
Synchronized Collection vs Concurrent Collection?

Aspect Synchronized Collection Concurrent Collection

How [Link] wrapper – single lock


Fine-grained
on entire collection
locking (CHM) or lock-free (COWAL, Concurren

Iterator Fail-fast (need external sync) Weakly consistent / snapshot

Throughput Low High

Examples synchronizedList, synchronizedMap ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLink

34 Basic
Why do we get ConcurrentModificationException during iteration?

ArrayList (and most non-concurrent collections) maintains a modCount counter that increments on every structural
modification. The iterator captures expectedModCount at creation time. On each next() call, it checks modCount ==
expectedModCount. If another thread (or the same thread using [Link]()) modifies the collection, modCount
changes → ConcurrentModificationException is thrown immediately (fail-fast).
List<String> list = new ArrayList<>([Link]("a","b","c")); for (String s : list) { //
enhanced-for uses Iterator internally if ("b".equals(s)) [Link](s); // modCount++ → next
iteration throws CME! } // Fix: use [Link]() Iterator<String> it = [Link](); while
([Link]()) { if ("b".equals([Link]())) [Link](); } // safe // Or: [Link](s ->
"b".equals(s)); (Java 8)

35 Basic
What is a PriorityQueue in Java?

PriorityQueue is a heap-based (min-heap by default) unbounded queue. The head is always the smallest element
(natural order or Comparator). Operations: offer/add O(log n), poll/peek O(1) for head, O(log n) for poll.
PriorityQueue<Integer> pq = new PriorityQueue<>(); // min-heap [Link](5); [Link](1); [Link](3);
[Link]([Link]()); // 1 – smallest first // Max-heap using reversed Comparator:
PriorityQueue<Integer> maxPQ = new PriorityQueue<>([Link]()); // Top-K largest
elements using a min-heap of size k: int k = 3; int[] nums = {4,1,7,3,9,2}; for (int n : nums) {
[Link](n); if ([Link]() > k) [Link](); // evict smallest } // pq now contains the k largest: {4, 7,
9}
4. Exception Handling

36 Basic
What is the base class for Error and Exception in Java?

Both Error and Exception extend Throwable. Throwable is the root of the entire exception hierarchy.
Throwable ■■■ Error // serious system failures; don't catch ■ ■■■ StackOverflowError ■ ■■■
OutOfMemoryError ■ ■■■ AssertionError ■■■ Exception // application-level; handle these ■■■
RuntimeException (Unchecked) ■ ■■■ NullPointerException ■ ■■■ IllegalArgumentException ■ ■■■
IndexOutOfBoundsException ■■■ Checked Exceptions ■■■ IOException ■■■ SQLException ■■■
ClassNotFoundException

37 Basic
What is a finally block? Output of the given program?

The finally block always executes after try/catch, regardless of whether an exception was thrown or caught. Used for
cleanup (closing resources).
Output of the given program: In try block → In finally block → Result: 30
Why 30? The finally block executes after the try block's return 10. The finally block itself contains return 30, which
overrides the try block's return. This is a classic gotcha—a return in finally overrides any earlier return.

■ Anti-Pattern

Never put a return statement in a finally block. It silently swallows exceptions and overrides return values, making
debugging very difficult.

When does finally NOT execute?


• [Link]() is called.
• JVM crashes (SIGSEGV, OOM in native code).
• The thread executing try/catch is killed.
• An infinite loop in the try block.

38 Differences between Checked and Unchecked Exceptions? How to Basic


handle?

Aspect Checked Unchecked

Compile check Yes (must declare or catch) No

Base class Exception (not RuntimeException) RuntimeException

Examples IOException, SQLException, ClassNotFoundException


NPE, IllegalArgument, ArrayIndexOutOfBounds

When Expected recoverable conditions Programming bugs

Handling try-catch or throws declaration Fix the bug; optionally catch at boundary
// Checked: must handle or declare void readFile(String path) throws IOException { BufferedReader br =
new BufferedReader(new FileReader(path)); // FileNotFoundException is checked – must declare or catch
} // Unchecked: optional handling void divide(int a, int b) { if (b == 0) throw new
IllegalArgumentException("b cannot be zero"); // unchecked return a / b; }

39 Can we create a finally without a catch? Scenarios where finally Basic


won't execute?
Yes! try-finally (without catch) is valid. This is used when you want to guarantee cleanup but not handle the exception at
this level.
Connection conn = null; try { conn = getConnection(); doWork(conn); // exception propagates up }
finally { if (conn != null) [Link](); // always closes } // better: use try-with-resources

40 Basic
What is Exception Propagation? Show with code.

When a method throws an exception without catching it, the exception travels up the call stack until it reaches a handler
or the JVM prints a stack trace.
void methodC() { int x = 1/0; } // throws ArithmeticException void methodB() { methodC(); } //
propagates up void methodA() { try { methodB(); } catch (ArithmeticException e) { // caught here
[Link]("Caught in A: " + [Link]()); } } // For checked exceptions, each method must
declare throws or catch

41 Can we throw additional unchecked exceptions in overridden Intermediate


methods?
Rules for exception in method overriding:
• Can throw fewer or narrower checked exceptions than the parent (or none).
• CANNOT throw new or broader checked exceptions than the parent.
• CAN throw any unchecked (RuntimeException) regardless.
class Parent { void method() throws IOException { } } class Child extends Parent { // OK: narrower
checked exception void method() throws FileNotFoundException { } // OK: no exception // void method()
{ } // OK: unchecked exception (RuntimeException) // void method() throws NullPointerException { } //
COMPILE ERROR: broader checked exception // void method() throws Exception { } }

42 Intermediate
Try-with-resources? Any recent changes?

Introduced in Java 7, try-with-resources automatically closes any resource implementing AutoCloseable. close() is
called in the finally block implicitly, even if an exception occurs.
// Java 7+ try (BufferedReader br = new BufferedReader(new FileReader("[Link]")); Connection conn =
getConnection()) { // both br and conn auto-closed in reverse order of declaration } catch
(IOException e) { handle(e); } // Java 9+: effectively-final variables outside try BufferedReader br =
new BufferedReader(new FileReader("[Link]")); try (br) { /* use br */ } // br declared outside, still
auto-closed
Suppressed exceptions: if both the try block AND close() throw exceptions, the exception from close() is suppressed
(attached to the primary exception via addSuppressed). Retrieve via [Link]().
5. String

43 Why is String immutable in Java? How many objects does 'new Basic
String("Shiv")' create?
Why immutable?
• Thread safety: multiple threads can share the same String without synchronisation.
• String pool: literals are interned (shared). If mutable, changing one would affect all references.
• Security: method parameters (file paths, usernames) can't be changed after validation.
• HashMap keys: hash is cached in String (hashCode field); stable only because immutable.

Object Creation Count


String s = new String("Shiv"); // 1 or 2 objects // If "Shiv" literal not in pool → 2 objects: 1 in
pool + 1 on heap // If "Shiv" already in pool → 1 object: only on heap String s1 = "Shiv"; // 0 or 1:
uses pool (creates only if not exists) String s2 = "Shiv"; // 0: reuses pool entry – same reference as
s1 [Link](s1 == s2); // true (same pool reference) [Link](s == s1); // false
(s is a separate heap object) String s3 = new String("Java"); String s4 = [Link](); // puts in pool
(or returns existing pool ref) // s1=="Java" ? s1==s4 → true (both from pool)

44 Basic
String interning concept. Output of the given program.

String interning: [Link]() returns the canonical (pool) version of the string. If the pool contains an equal string,
returns that reference; otherwise adds to pool.
String s1 = "Java"; // s1 → pool["Java"] String s2 = "Java"; // s2 → same pool ref String s3 = new
String("Java"); // s3 → new heap object String s4 = [Link](); // s4 → pool["Java"] (same as s1) s1
== s2 → true (both pool) s1 == s3 → false (s3 is heap object) s1 == s4 → true (s4 is interned = pool
ref = s1)

45 Basic
Output: String s = 'Hello'; [Link]('World'); println(s)?

Output: Hello. String is immutable. [Link]("World") creates a NEW String "HelloWorld" but discards it immediately
because the return value is not stored. The original reference s still points to "Hello".
String s = "Hello"; [Link]("World"); // creates new String – return value ignored
[Link](s); // Hello // To capture: s = [Link]("World"); // or s += "World";
[Link](s); // HelloWorld

46 Basic
String vs StringBuffer vs StringBuilder – efficiency order?

Class Mutable? Thread-Safe? Performance Use Case

String No Yes (immutable) Slowest for concat in loop Fixed text, map keys

StringBuffer Yes Yes (synchronized) Medium Multi-threaded string building

StringBuilder Yes No Fastest Single-threaded string building (most com


Efficiency order (fast → slow) for string operations: StringBuilder > StringBuffer > String. Note: Java compiler
automatically converts string concatenation in a loop to StringBuilder (but not across loop iterations).

47 How many objects: String s1='abc'; String s2=new String('abc'); Basic


String s3=[Link]()?
Answer: 2 objects (possibly 3 if pool doesn't have 'abc' yet).
String s1 = "abc"; // 1 pool object (if new) String s2 = new String("abc"); // 1 heap object (pool
already has "abc") String s3 = [Link](); // 1 heap object "ABC" (new, different content) //
Total: "abc" in pool + s2 on heap + "ABC" on heap = 2-3 depending on prior state // s1 == s2 → false
(s2 is heap) // [Link](s2) → true (content equal) // s3 is "ABC" – different content from s1,
always a new object
6. Multithreading

48 Thread vs Runnable? Creating threads in different ways. Runnable Basic


as lambda?
// 1. Extend Thread class MyThread extends Thread { public void run() { [Link]("T1"); } }
new MyThread().start(); // 2. Implement Runnable Runnable r = new Runnable() { public void run() {
[Link]("T2"); } }; new Thread(r).start(); // 3. Runnable as Lambda (Java 8) – Runnable is
a @FunctionalInterface new Thread(() -> [Link]("T3")).start(); // 4. Callable with Future
Callable<Integer> c = () -> 42; Future<Integer> f = [Link]().submit(c);
[Link]([Link]()); // 42 // 5. ExecutorService (preferred in production) ExecutorService
pool = [Link](4); [Link](() -> [Link]("T5 in pool"));
[Link]();
Thread vs Runnable: Extending Thread prevents your class from extending another class (Java has single inheritance).
Implementing Runnable is more flexible and separates the task from the thread lifecycle. Prefer Runnable/Callable +
ExecutorService in production.

49 What does the synchronized keyword do? How does it work Intermediate
internally?
synchronized ensures that only one thread at a time executes a critical section by acquiring the object's intrinsic lock
(monitor).

JVM Internal Implementation (Monitor)


• Each object has an associated monitor (mutex + wait set + entry set).
• JVM emits MONITORENTER at block entry and MONITOREXIT at block exit (bytecode instructions).
• Modern JVMs use biased locking (single thread acquires cheaply), thin lock (CAS-based for short contention),
and fat lock (OS mutex for high contention).
public class Counter { private int count = 0; // synchronized method: lock is 'this' public
synchronized void increment() { count++; } // synchronized block: finer-grained, explicit lock object
private final Object lock = new Object(); public void decrement() { synchronized (lock) { count--; } }
// synchronized static: lock is [Link] public static synchronized void staticOp() { } }

Scope Lock Object

Instance method this (the instance)

Static method [Link] (the Class object)

Block Specified object reference (this, lock, [Link]…)

50 Race Condition vs Visibility Problem? How volatile solves Intermediate


visibility?
Race Condition: Two threads read-modify-write shared state concurrently without synchronisation → inconsistent result.
Example: count++ (3 steps: read, increment, write) by two threads simultaneously can result in one increment being lost.
Visibility Problem: A thread caches a variable in CPU register/L1 cache; another thread writes a new value to main
memory but the first thread never sees it (reads stale cached value).
How volatile fixes visibility: A volatile write issues a store barrier (flushes all pending writes to main memory). A
volatile read issues a load barrier (invalidates cache, reads from main memory). This guarantees the latest value is
always visible.

■ volatile is NOT enough for atomicity

volatile fixes visibility but NOT race conditions on compound ops. Use AtomicInteger or synchronized for i++.

51 What is a daemon thread? How to make a user thread into a Basic


daemon thread?
A daemon thread is a background/service thread. The JVM exits when only daemon threads remain (all user threads
have finished). Examples: GC thread, JIT compiler thread.
Thread t = new Thread(() -> { while(true) { doBackgroundWork(); } }); [Link](true); // MUST call
BEFORE start() [Link](); // If setDaemon called after start() → IllegalThreadStateException // Check:
[Link]([Link]()); // true

52 Intermediate
wait(), notify(), notifyAll()? Which class? Why?

These methods are in [Link], not Thread. Why? Because any object can be used as a monitor lock.
Waiting/notifying must be tied to the same lock object.

Method Effect

wait() Releases the monitor lock and waits in the wait set until notified or interrupted

notify() Wakes one arbitrary thread from the wait set; it must re-acquire the lock

notifyAll() Wakes ALL waiting threads; all compete for the lock; safest choice

synchronized (lock) { while (!condition) { [Link](); } // release lock, enter wait set // condition
is true; proceed } // In another thread: synchronized (lock) { condition = true; [Link](); //
wake all waiters } // MUST call wait/notify inside synchronized block on the SAME object

■ Interviewer Tip

Always use while (!condition) { wait(); } not if – because of spurious wakeups (OS can wake threads without notify). Also
notifyAll() is safer than notify() to avoid missed signals.

53 Basic
Runnable vs Callable?

Aspect Runnable Callable<V>

Return type void V (generic)

Throws checked? No (must wrap) Yes (throws Exception)

Java version 1.0 5.0


Aspect Runnable Callable<V>

submit() returns Future<?> (value is null) Future<V>

Use with Thread, ExecutorService ExecutorService

Runnable r = () -> [Link]("no return"); Callable<String> c = () -> { [Link](100); //


can throw checked InterruptedException return "result"; }; Future<String> f = [Link](c);
String result = [Link](2, [Link]); // blocks, can timeout

54 ExecutorService? Types of thread pool? What considerations when Intermediate


creating?

Factory Creates Use case

newFixedThreadPool(n) Fixed n threads CPU-bound tasks; predictable load

newCachedThreadPool() Unbounded; idle threads reused Short-lived async tasks; burst workloads

newSingleThreadExecutor() 1 thread Sequential task queue

newScheduledThreadPool(n) Scheduling pool Cron-like tasks

newVirtualThreadPerTaskExecutor() (Java 21) Virtual thread per task I/O-bound massive concurrency

Design Considerations
• Pool size: CPU-bound → N+1 threads (N = cores). I/O-bound → N × (1 + wait/compute ratio).
• Queue capacity: unbounded (LinkedBlockingQueue default) can OOM under load. Use bounded
ArrayBlockingQueue with a RejectedExecutionHandler.
• Shutdown: always call shutdown() + awaitTermination() to drain the queue.
• Thread factory: name threads for observability (thread-pool-1 is unhelpful in thread dumps).

55 Basic
Difference between wait() and sleep()?

Aspect wait() sleep()

Class Object Thread (static method)

Lock release YES – releases the monitor NO – keeps the lock

Where called Inside synchronized block Anywhere

Woken by notify/notifyAll Timeout or interrupt

Purpose Inter-thread coordination Pause/delay

56 ReentrantLock vs synchronized? Explain fairness, condition Advanced


variables.
Feature synchronized ReentrantLock

Explicit lock/unlock No (automatic) Yes – must unlock in finally

Fairness No (unfair by default) new ReentrantLock(true) = fair

Condition variables wait()/notify() (one condition set) [Link]() – multiple Condition objects

Try to acquire Not possible tryLock() / tryLock(timeout)

Interruptible wait Not easily lockInterruptibly()

Performance Slightly better for simple cases More features, similar perf on modern JVMs

ReentrantLock lock = new ReentrantLock(true); // fair Condition notFull = [Link]();


Condition notEmpty = [Link](); void produce(T item) throws InterruptedException {
[Link](); try { while ([Link]() == MAX) [Link](); [Link](item); [Link]();
} finally { [Link](); } // MUST be in finally }

57 Intermediate
What is ThreadLocal?

ThreadLocal provides thread-scoped variables. Each thread has its own isolated copy. No synchronisation
needed—threads cannot see each other's values.
ThreadLocal<SimpleDateFormat> sdf = [Link](() -> new SimpleDateFormat("yyyy-MM-dd"));
// Each thread gets its own SDF instance – SDF is not thread-safe String formatted =
[Link]().format(new Date()); // CRITICAL: Always remove in finally (especially in thread pools) try {
use([Link]()); } finally { [Link](); } // prevents memory leak in pooled threads

■ Memory Leak Risk

ThreadLocal values are held via a WeakReference key but a strong reference to the value. If a thread pool reuses threads
and you forget remove(), the old value leaks for the lifetime of the thread.

58 Intermediate
CyclicBarrier vs CountDownLatch?

Feature CountDownLatch CyclicBarrier

Reusable No (one-time) Yes (resets after each barrier trip)

Who waits One or more threads wait for latch to reach 0 All participating threads wait at barrier

Count-down by Any thread calling countDown() Each participating thread calling await()

Action on trip Nothing (just releases waiters) Optional Runnable barrierAction runs

Use case Wait for N events; app startup Parallel computation phases; synchronisation points

// CountDownLatch – main waits for 3 workers CountDownLatch latch = new CountDownLatch(3); for (int i
= 0; i < 3; i++) { [Link](() -> { doWork(); [Link](); }); } [Link](); // blocks
main until count = 0 // CyclicBarrier – 3 threads wait for each other at barrier CyclicBarrier barrier
= new CyclicBarrier(3, () -> [Link]("All done!")); for (int i = 0; i < 3; i++) {
[Link](() -> { doPhase1(); [Link](); doPhase2(); }); }
7. Spring / Spring Boot

59 Basic
IoC? Purpose and benefits of IoC container in Spring? DI types?

Inversion of Control (IoC): Instead of objects creating their own dependencies (new keyword), control is handed to an
external container (Spring's ApplicationContext) which creates and wires objects.

Benefits
• Loose coupling: classes depend on interfaces, not implementations.
• Testability: inject mocks via constructor (no Spring needed in unit tests).
• Lifecycle management: container manages singleton scope, lazy init, destroy callbacks.

DI Types

Type How Pros/Cons

Constructor injection @Autowired on constructor (implicit in Spring 4.3+)


BEST: guarantees non-null, supports final fields, testable with

Setter injection @Autowired on setter Optional dependencies; allows reconfiguration

Field injection @Autowired on field Convenient but hides deps, can't use final, requires Spring co

@Service public class OrderService { private final PaymentService payment; // final – immutable
private final InventoryService inventory; // Constructor injection – Spring auto-detects single
constructor public OrderService(PaymentService payment, InventoryService inventory) { [Link] =
payment; [Link] = inventory; } }

60 Singleton in Spring vs Singleton pattern in Java? Is Spring Intermediate


singleton thread-safe?

Aspect Java Singleton Pattern Spring Singleton Bean

Scope JVM-wide: 1 instance per ClassLoader 1 instance per ApplicationContext

Creation Static field + private constructor Managed by IoC container

Multiple contexts 1 instance Each context has its own instance

Is Spring singleton bean thread-safe? NO by default. If the bean has mutable instance fields and multiple threads call
it concurrently, you have a race condition. Spring only guarantees single instantiation—not thread safety of the instance.
Fix: Keep singleton beans stateless (no mutable instance fields). For state, use request/session scope, or use
ThreadLocal.

61 Intermediate
Lifecycle of a Spring Bean?

1. Instantiation : Container creates bean instance via constructor 2. Populate props : Dependency
injection (@Autowired fields/setters) 3. BeanNameAware : setBeanName() called if implemented 4.
BeanFactoryAware : setBeanFactory() called if implemented 5. ApplicationContextAware:
setApplicationContext() if implemented 6. BeanPostProcessor : postProcessBeforeInitialization() (e.g.,
@PostConstruct) 7. @PostConstruct : custom init method 8. InitializingBean : afterPropertiesSet() 9.
@Bean(initMethod) : custom init-method 10. Bean Ready : in use by application 11. @PreDestroy : custom
destroy (before container shuts down) 12. DisposableBean : destroy() 13. @Bean(destroyMethod): custom
destroy-method

62 Autowiring? @Primary, @Qualifier, Convention over Intermediate


configuration?
When two beans implement the same interface, Spring doesn't know which to inject and throws
NoUniqueBeanDefinitionException.

Resolution strategies
• @Primary: marks one bean as default when multiple candidates exist.
• @Qualifier('beanName'): specify exact bean by name at injection point.
• Convention: name the variable to match the bean name – Spring resolves by name as a fallback.
interface NotificationService { void send(String msg); } @Service @Primary class EmailNotification
implements NotificationService { ... } @Service class SmsNotification implements NotificationService {
... } @Service class OrderService { @Autowired @Qualifier("smsNotification") // explicit private
NotificationService sms; @Autowired // gets EmailNotification (Primary) private NotificationService
notification; // Convention: field named 'smsNotification' auto-resolves to SmsNotification @Autowired
private NotificationService smsNotification; }

63 Significance of @SpringBootApplication? What annotations does it Basic


comprise?
@SpringBootApplication is a convenience meta-annotation combining three annotations:

Annotation Purpose

@Configuration Marks class as a source of @Bean definitions for ApplicationContext

@EnableAutoConfiguration Triggers Spring Boot's auto-configuration: reads [Link] / AutoConfiguration.i

@ComponentScan Scans the current package and sub-packages for @Component, @Service, @Repos

Auto-configuration internals: @EnableAutoConfiguration reads


META-INF/spring/[Link]. Each listed class uses
@Conditional annotations (@ConditionalOnClass, @ConditionalOnMissingBean) to configure only when the relevant
library is on the classpath.

64 Basic
How does @ComponentScan work if no package name given?

When no package is specified, @ComponentScan uses the package of the annotated class as the base package. This
is why Spring Boot recommends placing the @SpringBootApplication class in the root package of your application—all
sub-packages are automatically scanned.
[Link] ■■■ [Link] // @SpringBootApplication → scans [Link].* ■■■ service/ ■ ■■■
[Link] // picked up automatically ■■■ controller/ ■■■ [Link] // picked up
automatically
8. Spring Controller & Web Layer

65 @RequestParam, @PathVariable, and @RequestBody? Give Basic


implementation and endpoint generation.
@RestController @RequestMapping("/api/employees") public class EmployeeController { // @PathVariable –
part of the URL path // GET /api/employees/42 @GetMapping("/{id}") public Employee
getById(@PathVariable Long id) { return [Link](id); } // @RequestParam – query string
parameter // GET /api/employees?name=Alice&dept=Engineering @GetMapping public List<Employee>
search(@RequestParam String name, @RequestParam(required=false, defaultValue="ALL") String dept) {
return [Link](name, dept); } // @RequestBody – JSON/XML body deserialized to POJO // POST
/api/employees { "name": "Bob", "salary": 5000 } @PostMapping public ResponseEntity<Employee>
create(@RequestBody @Valid Employee emp) { Employee saved = [Link](emp); return
[Link]([Link]("/api/employees/" + [Link]())).body(saved); } }

66 REST methods (GET, POST, PUT, PATCH, DELETE, OPTIONS). Basic


Which are idempotent?

Method Safe? Idempotent? Use Case

GET Yes Yes Read resource

HEAD Yes Yes Read headers only

OPTIONS Yes Yes Discover allowed methods (CORS preflight)

DELETE No Yes Delete resource (same result if called N times)

PUT No Yes Replace entire resource

PATCH No No (usually) Partial update

POST No No Create resource / trigger action

Safe: does not change server state. Idempotent: calling N times = same result as calling once.

67 Explain the lifecycle of a REST request in Spring Boot Intermediate


(DispatcherServlet flow).
HTTP Request ■ ▼ DispatcherServlet (Front Controller) ■ ■■ HandlerMapping → finds which @Controller
method handles the URL ■ ■■ HandlerAdapter → adapts the handler (invokes the method) ■ ■ ■■
[Link]() ■ ■ ■■ Controller method execution ■ ■ ■ ■■ @RequestBody →
HttpMessageConverter (JSON → POJO) ■ ■ ■ ■■ @ResponseBody → HttpMessageConverter (POJO → JSON) ■ ■
■■ [Link]() ■ ■■ ExceptionResolver (if exception thrown) ■ ■■
[Link]() ■ ▼ HTTP Response
Async handling (DeferredResult/Callable): the DispatcherServlet releases the Servlet thread back to the pool. A
separate thread resolves the DeferredResult. DispatcherServlet then processes the result on another thread.

68 How does @Cacheable work internally? CacheInterceptor, Advanced


CacheManager, Cache Resolver.
@Cacheable is implemented via Spring AOP. When you call a @Cacheable method, a proxy intercepts the call:
• 1. CacheInterceptor (MethodInterceptor) is invoked.
• 2. It calls CacheResolver to determine which cache(s) to use.
• 3. It generates the cache key using KeyGenerator (default: method params, or SpEL expression).
• 4. Cache lookup: if key exists in cache, return cached value immediately (method NOT called).
• 5. On cache miss: invoke the actual method, store result in cache, return result.

Annotation Behaviour

@Cacheable Return cached value or invoke method and cache result

@CachePut Always invoke method AND update cache (used for updates)

@CacheEvict Remove entry from cache (on delete/update)

@Caching Combine multiple cache annotations on one method

@Service public class ProductService { @Cacheable(value="products", key="#id", condition="#id > 0",


unless="#result == null") public Product findById(Long id) { return [Link](id).orElse(null); }
@CachePut(value="products", key="#[Link]") public Product update(Product product) { return
[Link](product); } @CacheEvict(value="products", key="#id") public void delete(Long id) {
[Link](id); } } // [Link]: // [Link]=redis (or caffeine, ehcache,
simple)

69 How to secure REST APIs using Spring Security + JWT? JWT Advanced
structure? Lifecycle?

JWT Structure (3 parts, Base64URL-encoded, dot-separated)


[Link] {alg:"HS256", typ:"JWT"} . {sub:"userId", roles:[], exp:timestamp} .
HMAC_SHA256(header+payload, secret)

JWT Lifecycle
• 1. Client sends credentials to /auth/login.
• 2. Server validates, creates JWT signed with secret/private key.
• 3. Client stores JWT (memory or HttpOnly cookie).
• 4. Client sends JWT in Authorization: Bearer header.
• 5. Server's JwtAuthFilter extracts and validates token on each request.
• 6. Token expires (exp claim); client re-authenticates or uses refresh token.
@Component public class JwtAuthFilter extends OncePerRequestFilter { protected void
doFilterInternal(HttpServletRequest req, ...) { String token = extractToken(req); // "Bearer xxxx" if
(token != null && [Link](token)) { String username = [Link](token);
UserDetails user = [Link](username);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null,
[Link]()); [Link]().setAuthentication(auth); }
[Link](req, res); } }

70 How does @Valid and @Validated work? Difference? Custom Intermediate


validation?
Feature @Valid (javax/jakarta) @Validated (Spring)

Triggers Bean Validation Yes Yes

Groups support No Yes (validation groups)

Method-level validation No Yes (with MethodValidationPostProcessor)

Nested object validation Yes (with @Valid on field) Yes

// Custom Validation Annotation @Target({FIELD, PARAMETER}) @Retention(RUNTIME)


@Constraint(validatedBy = [Link]) public @interface ValidPhone { String message()
default "Invalid phone number"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload()
default {}; } public class PhoneValidator implements ConstraintValidator<ValidPhone, String> { public
boolean isValid(String phone, ConstraintValidatorContext ctx) { return phone != null &&
[Link]("\\+?[0-9]{10,13}"); } } @PostMapping("/users") public ResponseEntity<?>
create(@RequestBody @Valid UserDto dto) { ... } // MethodArgumentNotValidException → handle in
@ControllerAdvice

71 Exception handling in Spring Boot: @ExceptionHandler, Intermediate


@ControllerAdvice, ResponseEntityExceptionHandler?
@RestControllerAdvice // combines @ControllerAdvice + @ResponseBody public class
GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler([Link]) public ResponseEntity<ErrorResponse>
handleNotFound(ResourceNotFoundException ex) { return [Link](404).body(new
ErrorResponse("NOT_FOUND", [Link]())); }
@ExceptionHandler([Link]) public ResponseEntity<ErrorResponse>
handleValidation(MethodArgumentNotValidException ex) { List<String> errors =
[Link]().getFieldErrors()
.stream().map(FieldError::getDefaultMessage).collect([Link]()); return
[Link]().body(new ErrorResponse("VALIDATION_FAILED", [Link]())); }
@ExceptionHandler([Link]) public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
[Link]("Unexpected error", ex); return [Link](500).body(new
ErrorResponse("INTERNAL_ERROR", "Unexpected error")); } }
9. JPA / JDBC / Spring Data JPA

72 Basic
Difference between JPA, Hibernate/MyBatis, Spring Data JPA?

Layer What it is Examples

JDBC Low-level DB API: SQL + ResultSet + [Link].*

JPA Specification (JSR 338): ORM standard interfaces


[Link] / [Link]

Hibernate JPA implementation + extra features (HQL, criteria)


SessionFactory, Session

MyBatis SQL Mapper (XML/annotation SQL, manual mapping)


SqlSession

Spring Data JPA Abstraction over JPA: repositories, query methods


JpaRepository, @Query

Spring Data JPA reduces boilerplate: you define an interface extending JpaRepository and Spring generates the
implementation at runtime using proxy + EntityManager.

73 Create Employee Entity with all annotations. @GeneratedValue Basic


strategies?
@Entity @Table(name = "employees", indexes = { @Index(name = "idx_emp_name", columnList = "name") })
public class Employee { @Id @GeneratedValue(strategy = [Link], generator = "emp_seq")
@SequenceGenerator(name = "emp_seq", sequenceName = "employee_sequence", allocationSize = 10) // batch
10 IDs at once private Long id; @Column(nullable = false, length = 100) private String name;
@Column(nullable = false) private int age; @Column(nullable = false, precision = 10, scale = 2)
private double salary; // getters, setters, constructors }

Strategy How DB Support Performance

AUTO JPA picks based on DB All Varies

IDENTITY DB auto-increment MySQL, PostgreSQL No batch insert possible

SEQUENCE DB sequence object Oracle, PostgreSQL Supports batch (allocationSize)

TABLE ID table in DB All (portable) Slow (lock on ID table)

74 Intermediate
[Link] vs EAGER? N+1 problem? How to fix?

Aspect EAGER LAZY

When loaded Always with parent Only on access (proxy)

Default for @OneToMany No (LAZY) Yes (LAZY)

Default for @ManyToOne Yes (EAGER) No


Aspect EAGER LAZY

Risk Too much data fetched LazyInitializationException outside session

N+1 Problem: Fetching 1 list of orders + 1 query per order to fetch customer = N+1 queries. Caused by LAZY loading
iterated outside transaction.

Fixes
• JOIN FETCH in JPQL: SELECT o FROM Order o JOIN FETCH [Link]
• @EntityGraph: attribute paths to fetch eagerly for a specific query.
• Hibernate @BatchSize: batch load N associations in one IN query.
// Fix using JOIN FETCH @Query("SELECT o FROM Order o JOIN FETCH [Link] WHERE [Link] = :s")
List<Order> findWithCustomer(@Param("s") String status); // Fix using EntityGraph
@EntityGraph(attributePaths = {"customer", "items"}) List<Order> findByStatus(String status);

75 Intermediate
@Transactional? @Modifying? Optimistic vs Pessimistic Locking?

@Transactional
Wraps method in a DB transaction (begin/commit/rollback). [Link] (default): joins existing tx or creates
new. Rollback on RuntimeException by default; add rollbackFor=[Link] for checked exceptions.

@Modifying
Required for @Query methods that execute UPDATE/DELETE. Without it, Spring Data treats the query as a SELECT
and throws exception. Use with @Transactional.
@Modifying @Transactional @Query("UPDATE Employee e SET [Link] = :salary WHERE [Link] = :id") int
updateSalary(@Param("id") Long id, @Param("salary") double salary);

Locking Mechanism Use Case

Optimistic (@Version) @Version field; increment on save; if mismatch →


Low-contention:
OptimisticLockException
read often, write rarely

Pessimistic (@Lock) DB-level row lock (SELECT FOR UPDATE) High contention; financial transactions

@Entity class Product { @Id Long id; @Version int version; // JPA manages this – increments on each
save } // Repository: @Lock(LockModeType.PESSIMISTIC_WRITE) Optional<Product> findById(Long id); //
SELECT ... FOR UPDATE

76 How do you handle bidirectional relationships and avoid infinite Intermediate


recursion in JSON?
@Entity class Department { @Id Long id; String name; @OneToMany(mappedBy = "department", cascade =
[Link]) @JsonManagedReference // serialized List<Employee> employees; } @Entity class
Employee { @Id Long id; String name; @ManyToOne @JoinColumn(name = "dept_id") @JsonBackReference //
NOT serialized (prevents infinite loop) Department department; } // Alternative: use @JsonIgnore on
one side // Or: use DTOs (best practice – no Jackson annotations on entities)

77 Intermediate
How do you implement auditing in Spring Data JPA?

@Configuration @EnableJpaAuditing public class JpaConfig { } @MappedSuperclass


@EntityListeners([Link]) public abstract class Auditable { @CreatedDate
@Column(updatable=false) private LocalDateTime createdAt; @LastModifiedDate private LocalDateTime
updatedAt; @CreatedBy @Column(updatable=false) private String createdBy; @LastModifiedBy private
String modifiedBy; } @Entity class Employee extends Auditable { ... } // Provide current user: @Bean
public AuditorAware<String> auditorProvider() { return () -> [Link](
[Link]().getAuthentication()) .map(Authentication::getName); }
10. Database

78 Basic
DDL vs DML? DELETE vs TRUNCATE? WHERE vs HAVING?

Concept Details

DDL Data Definition Language: CREATE, ALTER, DROP, TRUNCATE – change schema;

DML Data Manipulation Language: INSERT, UPDATE, DELETE, SELECT – change data;

DELETE DML; row-by-row removal; WHERE clause; fires triggers; logged; can rollback

TRUNCATE DDL; removes ALL rows; no WHERE; no triggers; minimal logging; faster; no rollback

WHERE Filters rows BEFORE aggregation (works without GROUP BY)

HAVING Filters groups AFTER GROUP BY aggregation

-- WHERE vs HAVING SELECT dept, AVG(salary) FROM employees WHERE age > 25 -- filter rows first (before
grouping) GROUP BY dept HAVING AVG(salary) > 60000; -- filter groups (after aggregation)

79 Basic
ACID Properties?

Property Meaning Example

Atomicity All or nothing – transaction completes fully or rollsTransfer:


back completely
debit + credit both succeed or both fail

Consistency DB moves from one valid state to another; constraints


Balance
always
never
hold
goes negative (constraint enforced)

Isolation Concurrent transactions don't interfere; each seesDirty


a consistent
read, non-repeatable
snapshot read, phantom read prevention

Durability Committed transactions persist even after crash Write-ahead log (WAL) ensures data survives power failure

80 Intermediate
Indexing? Advantages/Disadvantages? When to use?

Index: auxiliary data structure (B-Tree by default in most RDBMS) that speeds up data retrieval at the cost of storage
and write performance.

Advantage Disadvantage

Faster SELECT, WHERE, JOIN, ORDER BY Slower INSERT, UPDATE, DELETE (index must be updated)

Enforces UNIQUE constraints Disk space overhead

Enables efficient range queries Too many indexes degrade write-heavy workloads

Supports covering indexes Index maintenance during bulk loads (disable, then rebuild)
When to create an index?
• Columns frequently in WHERE, JOIN ON, ORDER BY, GROUP BY.
• High cardinality columns (many distinct values; low cardinality like boolean is not useful).
• Foreign key columns (not auto-created by most DBs, but needed for JOIN performance).
• Don't index small tables (full scan is faster).

81 Basic
SQL query execution order?

-- Logical execution order (not written order): 1. FROM -- identify source tables 2. JOIN -- combine
tables 3. WHERE -- filter rows (before grouping) 4. GROUP BY -- group remaining rows 5. HAVING --
filter groups 6. SELECT -- choose columns / expressions 7. DISTINCT -- remove duplicates 8. ORDER BY --
sort result 9. LIMIT/OFFSET -- pagination

82 Intermediate
Find employee with 2nd or Nth highest salary.

-- 2nd highest salary SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM
employees); -- Nth highest using DENSE_RANK (handles ties): WITH ranked AS ( SELECT name, salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk FROM employees ) SELECT name, salary FROM ranked WHERE
rnk = 2; -- change 2 to N -- Nth highest per department: WITH ranked AS ( SELECT name, salary, dept,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rnk FROM employees ) SELECT * FROM ranked
WHERE rnk = 3;

83 Advanced
Partitioning? Types? Horizontal vs Vertical partitioning?

Type Description Use Case

Range Rows split by value range of a column Date-based: Jan in p1, Feb in p2

List Rows split by explicit list of values Country-based: US, EU, ASIA

Hash Rows distributed by hash of a column Uniform distribution, no natural range

Composite Combination of above Range by year + hash by customer_id

Aspect Horizontal (Sharding) Vertical

What splits Rows across tables/DBs Columns across tables

Example Users 1-1M in shard1, 1M+ in shard2 User table + UserProfile table

Goal Scale out / distribute load Reduce table width; cache hot columns
11. Microservices

84 Basic
Microservices vs Monolith? Benefits and downsides?

Aspect Monolith Microservices

Deployment Single deployable unit Many independent services

Scaling Scale entire app Scale individual services

Technology Uniform tech stack Polyglot (each service can differ)

Development Simpler initially Complex; need DevOps maturity

Failure isolation One bug can crash all Failure isolated to service

Data management Single DB DB per service (distributed data)

Latency In-process calls Network calls (REST/gRPC)

When to use Microservices?


• Teams are large and need independent deployment cycles.
• Different services have different scaling needs.
• High fault-tolerance requirements.
• NOT recommended for small teams / early-stage startups (operational overhead is high).

85 Intermediate
Event-Driven Architecture (EDA)? Event vs Command vs Query?

Message Type Definition Direction Example

Event Something that happened (past tense)


Broadcast (pub/sub) OrderPlaced, PaymentFailed

Command Request to do something Point-to-point ProcessPayment, ShipOrder

Query Request for data Request-Reply GetOrderStatus

Event Bus / Message Broker (Kafka, RabbitMQ): decouples producers from consumers. Producer publishes event
without knowing consumers. Consumers subscribe and react asynchronously. Enables high throughput, replay, and
temporal decoupling.
Event Sourcing: instead of storing current state, store the sequence of events that led to the state. Current state =
replay of events. Benefits: full audit log, time travel, easy projections. Challenges: event schema evolution, eventual
consistency.

86 Saga Pattern? Types? What happens if a step fails? Compensating Advanced


transactions?
Saga: a pattern for distributed transactions. Instead of a 2-phase commit (ACID across services), a Saga is a sequence
of local transactions. Each step publishes an event or command for the next step.

Type Coordination Pros/Cons

Choreography Each service reacts to events; no central coordinator


Decoupled; hard to track flow; debugging complex

Orchestration Central Saga Orchestrator sends commands; waits


Easier
for replies
to track; single point of failure; tight coupling to orches

Failure Handling – Compensating Transactions


If step N fails, execute compensating transactions for steps N-1, N-2,… down to step 1 to undo the partial work. The key
requirement: compensating transactions must be idempotent (safe to retry).
// Orchestration Saga for Order: // Step 1: Create Order → compensate: CancelOrder // Step 2: Reserve
Inventory → compensate: ReleaseInventory // Step 3: Charge Payment → compensate: RefundPayment //
Step 4: Ship Order → (last step, no compensate needed) // If Step 3 fails: execute
RefundPayment(skipped), ReleaseInventory, CancelOrder

87 CQRS? Benefits? How to keep read model in sync with write Advanced
model?
CQRS (Command Query Responsibility Segregation): separate the write model (Commands: change state) from the
read model (Queries: return data). They can use different databases, schemas, and technologies.

Benefits
• Read model optimised for queries (denormalised, cached, search-friendly).
• Write model optimised for business rules and consistency.
• Independent scaling of read and write sides.

Keeping Read Model in Sync


• Event-driven sync: write side publishes domain events (Kafka). Read side consumes and updates its projection
store.
• Eventual consistency: read model may be slightly behind write model. Acceptable for most read workloads.
// Write side @CommandHandler void handle(CreateOrderCommand cmd) { Order order = new Order(cmd);
[Link](order); [Link](new OrderCreatedEvent(order)); // triggers read model
update } // Read side consumer @EventHandler void on(OrderCreatedEvent event) {
[Link](new OrderSummaryView(event)); // denormalised view }

88 Intermediate
Circuit Breaker? Resilience patterns? States?

// Resilience4j Circuit Breaker states: CLOSED → (failure rate >= threshold) → OPEN → (wait
duration) → HALF_OPEN HALF_OPEN → (success) → CLOSED | (failure) → OPEN // Spring Boot setup:
@CircuitBreaker(name="paymentService", fallbackMethod="paymentFallback") public PaymentResponse
pay(PaymentRequest req) { return [Link](req); // may fail } public PaymentResponse
paymentFallback(PaymentRequest req, Throwable t) { return [Link]("Service temporarily
unavailable"); } // [Link]: [Link]:
failure-rate-threshold: 50 # open if 50% fail wait-duration-in-open-state: 10s # wait before HALF_OPEN
sliding-window-size: 10 # last 10 calls

Resilience Patterns Summary


• Retry with exponential backoff: retry after 1s, 2s, 4s… with jitter to avoid thundering herd.
• Timeout: fail fast if dependent service is slow.
• Bulkhead: limit concurrent calls to a service (thread pool / semaphore isolation).
• Rate Limiting: throttle requests to protect downstream.
• Circuit Breaker: stop calls entirely when failure rate is high; give service time to recover.

89 Intermediate
Service Discovery? Steps to implement in Spring Boot?

Service Discovery: in a dynamic microservices environment, service instances start/stop frequently with changing IPs.
Service discovery allows services to find each other without hardcoded IPs.

Type Description Tool

Server-side API Gateway/Load Balancer queries registry; client


AWScalls
ALB,
gateway
Nginx + Consul

Client-side Client queries registry and load-balances itself Eureka + Spring Cloud LoadBalancer

// Spring Cloud Eureka setup: // 1. Eureka Server (service registry) @SpringBootApplication


@EnableEurekaServer public class EurekaServerApp { } # [Link]: [Link]: 8761 // 2. Eureka
Client (each microservice) @SpringBootApplication @EnableDiscoveryClient public class OrderServiceApp
{ } # [Link]: # [Link]: [Link] #
[Link]: order-service // 3. Feign Client with discovery @FeignClient(name =
"payment-service") // resolves via Eureka public interface PaymentClient { @PostMapping("/payments")
PaymentResponse pay(@RequestBody PaymentRequest req); }

90 Distributed Tracing? TraceId, SpanId? How to implement in Spring Intermediate


Boot?
Distributed Tracing: in microservices, a single user request spans multiple services. Distributed tracing assigns a
unique TraceId to the entire request and a SpanId to each service hop, allowing you to reconstruct the full call tree.

Concept Description

TraceId Unique ID for the entire request chain (same across all services)

SpanId Unique ID for one hop/unit of work within the trace

ParentSpanId Points to the span that initiated this span

// Spring Boot 3.x (Micrometer Tracing + Brave/OpenTelemetry): // [Link]: //


spring-boot-starter-actuator + micrometer-tracing-bridge-brave + zipkin-reporter-brave //
[Link]: [Link]: 1.0 # 100% sampling (reduce in prod)
[Link]-url: [Link] // TraceId/SpanId are automatically injected into logs
(MDC) // and propagated via HTTP headers: X-B3-TraceId, X-B3-SpanId, X-B3-ParentSpanId // Feign and
RestTemplate propagate headers automatically with Sleuth/Micrometer // Log pattern shows traceId:
[Link]: '%5p [${[Link]},%X{traceId},%X{spanId}]'

■ Interviewer Tip

Mention Zipkin, Jaeger as tracing backends. For large scale: use OpenTelemetry (OTEL) as the vendor-neutral standard for
traces, metrics, and logs. Spring Boot 3 has first-class OTEL support via Micrometer.
Developed by dhruvtechbytes | @Instagram: dhruvtechbytes Java · Spring Boot · Microservices · Database

You might also like