Java BE Master Guide Answers
Java BE Master Guide Answers
# Section Coverage
3 Collections Q22–Q50
5 String Q57–Q66
6 Multithreading Q67–Q91
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).
JRE JVM + core libraries ([Link] / modules) Run Java apps (no compiler)
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.
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
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.
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?
Old Gen fills up fast Memory leak / oversized objects Heap dump + analyzer (MAT/VisualVM)
■ 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
9 Intermediate
What is MetaSpace? How does it differ from PermGen?
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)
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 }
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.
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.
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
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.
Locking Entire table locked (single lock) Bucket-level locking (Java 8: CAS + synchronized on bin)
24 Basic
Differences between Vector and ArrayList?
Prefer ArrayList for single-threaded code. For thread-safe lists, use CopyOnWriteArrayList or
[Link](new ArrayList<>()).
25 Basic
When is LinkedList better than ArrayList?
26 Basic
Differences between HashMap and Hashtable?
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.
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.
29 Intermediate
Shallow vs Deep cloning? Which for Immutable class?
Object references Reference copied (same object) New objects created recursively
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();
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.
Best for Single-threaded / synchronized externally Read-heavy, rare writes (event listeners)
32 Advanced
WeakHashMap? WeakReference? SoftReference?
SoftReference GC'd only when JVM needs memory (last resort)Memory-sensitive cache
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?
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.
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; }
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
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.
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?
String No Yes (immutable) Slowest for concat in loop Fixed text, map keys
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).
volatile fixes visibility but NOT race conditions on compound ops. Use AtomicInteger or synchronized for i++.
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?
newCachedThreadPool() Unbounded; idle threads reused Short-lived async tasks; burst workloads
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()?
Condition variables wait()/notify() (one condition set) [Link]() – multiple Condition objects
Performance Slightly better for simple cases More features, similar perf on modern JVMs
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
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?
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
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; } }
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
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; }
Annotation Purpose
@ComponentScan Scans the current package and sub-packages for @Component, @Service, @Repos
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
Safe: does not change server state. Idempotent: calling N times = same result as calling once.
Annotation Behaviour
@CachePut Always invoke method AND update cache (used for updates)
69 How to secure REST APIs using Spring Security + JWT? JWT Advanced
structure? Lifecycle?
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); } }
72 Basic
Difference between JPA, Hibernate/MyBatis, Spring Data JPA?
Spring Data JPA reduces boilerplate: you define an interface extending JpaRepository and Spring generates the
implementation at runtime using proxy + EntityManager.
74 Intermediate
[Link] vs EAGER? N+1 problem? How to fix?
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);
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
77 Intermediate
How do you implement auditing in Spring Data JPA?
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 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?
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)
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?
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
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?
Failure isolation One bug can crash all Failure isolated to service
85 Intermediate
Event-Driven Architecture (EDA)? Event vs Command vs Query?
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.
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.
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
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.
Client-side Client queries registry and load-balances itself Eureka + Spring Cloud LoadBalancer
Concept Description
TraceId Unique ID for the entire request chain (same across all services)
■ 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