Full Stack Java Developer
Interview Guide
Full Stack Java Developer —
Interview Master Guide
Study order: Core Java → OOP → Collections → Multithreading →
Exception Handling → JDBC → Spring Core → Spring Boot →
Spring MVC/REST → Spring Security → Hibernate/JPA →
Microservices → SQL → Frontend (React/Angular) → Git/Tools →
System Design → HR/Behavioral.
1. CORE JAVA
Q1. What are the main features of Java?
Answer: Platform-independent (bytecode runs on JVM), Object-
Oriented, Simple, Secure, Robust (strong memory management,
exception handling), Multithreaded, Architecture-neutral, Portable,
High-performance (JIT compiler), Distributed, Dynamic.
How to explain to interviewer: “Java’s biggest strength is ‘Write
Once, Run Anywhere’ — the compiler converts source code to
bytecode (.class file), and the JVM on any OS interprets/JIT-compiles
that bytecode, so the same .class file runs on Windows, Linux, Mac.”
Q2. JDK vs JRE vs JVM?
JVM (Java Virtual Machine): Abstract machine that executes
bytecode. Platform-dependent implementation, provides runtime
environment.
JRE (Java Runtime Environment): JVM + libraries needed to
run Java apps (no compiler).
JDK (Java Development Kit): JRE + development tools (javac,
javadoc, debugger). Needed to develop Java apps.
JDK = JRE + Development Tools (javac, jdb, javadoc)
JRE = JVM + Library classes ([Link] etc.)
Q3. Explain JVM architecture / memory areas.
Class Loader Subsystem: Loads, links, initializes classes
(Bootstrap → Extension → Application class loaders).
Runtime Data Areas:
Method Area: class-level data (static variables, metadata) —
shared.
Heap: all objects and instance variables — shared, GC happens
here.
Stack: per-thread; stores method calls, local variables, frames.
PC Register: per-thread; address of current instruction.
Native Method Stack: for native (C/C++) method calls.
Execution Engine: Interpreter + JIT Compiler + Garbage
Collector.
Example talking point: “Each thread gets its own stack and PC
register, but heap and method area are shared across threads — that’s
why heap access needs synchronization but stack variables (local
vars) are thread-safe by default.”
Q4. What is the difference between == and .equals()?
== compares reference (memory address) for objects, value for
primitives.
.equals() compares content/value (if overridden, like in String,
Integer).
String a = new String("hello");
String b = new String("hello");
[Link](a == b); // false (different objects)
[Link]([Link](b)); // true (same content)
String c = "hello";
String d = "hello";
[Link](c == d); // true (String pool, same
reference)
Q5. String pool, String immutability — why is String
immutable?
String Pool: Special memory area in heap where literal strings are
stored/reused.
Why immutable: 1. Security — strings used in file paths, network
connections, class loading; mutability could be exploited. 2. String
pool reuse — if mutable, changing one reference would corrupt all
others pointing to same pooled value. 3. Thread-safety — immutable
objects are inherently thread-safe, no synchronization needed. 4.
HashCode caching — since value can’t change, hashcode is
computed once and cached, making String ideal as HashMap keys.
String s = "hello";
[Link](" world"); // creates NEW string, doesn't change s
[Link](s); // still "hello"
Q6. String vs StringBuilder vs StringBuffer
String StringBuilder StringBuffer
Mutability Immutable Mutable Mutable
Yes Yes
Thread-safe No
(immutable) (synchronized)
Slower than
Slow for StringBuilder
Performance Fast
concatenation (sync
overhead)
Single-
Fixed/rarely Multi-threaded
Use case threaded heavy
changed text string ops
string ops
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) [Link](i);
[Link]([Link]()); // 01234
Q7. What are wrapper classes? What is
Autoboxing/Unboxing?
Wrapper classes convert primitives to objects (int→Integer,
double→Double etc.) needed for Collections (which only store objects). -
Autoboxing: primitive → object automatically (Integer i = 5;) -
Unboxing: object → primitive automatically (int j = i;)
Gotcha (common interview trap):
Integer a = 127, b = 127;
[Link](a == b); // true (Integer cache -128 to 127)
Integer c = 128, d = 128;
[Link](c == d); // false (outside cache range, new
objects)
Q8. Pass by value or pass by reference in Java?
Java is always pass by value. For objects, the value of the reference
(the address) is passed, not the object itself — so you can modify the
object’s internal state, but reassigning the reference inside the
method doesn’t affect the caller’s reference.
void modify(StringBuilder sb) {
[Link](" world"); // affects caller's object
sb = new StringBuilder("new"); // does NOT affect caller's
reference
}
2. OOP CONCEPTS
Q9. Four pillars of OOP — explain with examples.
1. Encapsulation — binding data + methods together, hiding internal
state via access modifiers (private fields + public getters/setters).
public class Account {
private double balance; // hidden
public double getBalance() { return balance; }
public void deposit(double amt) { if (amt > 0) balance += amt; }
}
2. Inheritance — child class acquires properties/behavior of parent
(extends).
class Vehicle { void start() { [Link]("starting"); } }
class Car extends Vehicle { void honk() {
[Link]("beep"); } }
3. Polymorphism — one interface, many forms. - Compile-time
(Overloading): same method name, different parameters. - Runtime
(Overriding): subclass redefines parent method, resolved at runtime
via dynamic dispatch.
// Overloading
void area(int side) {}
void area(int l, int b) {}
// Overriding
class Animal { void sound() { [Link]("..."); } }
class Dog extends Animal { @Override void sound() {
[Link]("Bark"); } }
Animal a = new Dog();
[Link](); // "Bark" — runtime polymorphism (dynamic method
dispatch)
4. Abstraction — hiding implementation, exposing only essential
features (via abstract class or interface).
interface Shape { double area(); }
class Circle implements Shape {
double r;
public double area() { return [Link] * r * r; }
}
Q10. Abstract class vs Interface?
Abstract Class Interface
All abstract (until
Can have abstract + Java 8); now allows
Methods
concrete methods default/static
methods
Any type (instance Only public static
Variables
vars) final (constants)
Constructor Yes No
Yes (a class can
No (single
Multiple inheritance implement multiple
inheritance)
interfaces)
Access modifiers Any public by default
Capability/contract
“is-a” relationship
When to use (“can-do”) across
with shared code
unrelated classes
Java 8+: Interfaces can have default and static methods.
interface Vehicle {
default void start() { [Link]("Default start"); }
static void info() { [Link]("Vehicle interface"); }
}
Q11. Why does Java not support multiple inheritance
(with classes)? How is it solved?
To avoid the Diamond Problem (ambiguity when two parent classes
have the same method). Java solves this using interfaces — since Java
8 allows default methods, if a class implements two interfaces with
the same default method, it MUST override it explicitly to resolve
ambiguity.
Q12. Method Overloading vs Overriding
Overloading Overriding
Binding Compile-time (static) Runtime (dynamic)
Parent-child
Class Same class
(inheritance)
Signature Must differ (params) Must be same
Return type Can differ Same or covariant
Private/static/final Cannot be
Can be overloaded
methods overridden
Q13. What is constructor chaining? this() vs super()?
this() calls another constructor in the same class.
super() calls the parent class constructor.
Both must be the first statement in a constructor; you can’t use
both in the same constructor.
class Animal {
Animal() { [Link]("Animal created"); }
}
class Dog extends Animal {
Dog() {
super(); // calls Animal() - optional, compiler adds
automatically if omitted
[Link]("Dog created");
}
}
Q14. What is the final keyword used for?
final variable → constant, can’t be reassigned.
final method → can’t be overridden.
final class → can’t be extended (e.g., String, Integer).
Q15. Static keyword — explain static variables,
methods, blocks.
static means the member belongs to the class, not instances —
shared across all objects.
class Counter {
static int count = 0; // static variable
static { [Link]("Static block runs once on class
load"); }
Counter() { count++; }
static void show() { [Link](count); } // static
method
}
Static methods can’t access non-static (instance) members directly
because they don’t operate on an instance.
Static block runs once when the class is loaded — used for one-
time initialization.
3. COLLECTIONS FRAMEWORK
Q16. Explain the Collections Framework hierarchy.
Iterable
└── Collection
├── List (ordered, duplicates allowed) → ArrayList,
LinkedList, Vector
├── Set (no duplicates) → HashSet, LinkedHashSet, TreeSet
└── Queue → PriorityQueue, ArrayDeque
Map (not a Collection, separate hierarchy) → HashMap, LinkedHashMap,
TreeMap, Hashtable
Q17. ArrayList vs LinkedList
ArrayList LinkedList
Structure Dynamic array Doubly linked list
Access (get) O(1) O(n)
Insert/Delete O(1) once node
O(n) — shifting
(middle) found, O(n) to find it
Memory More (stores
Less overhead next/prev pointers)
Frequent
Use case Frequent reads
insertions/deletions
List<String> list = new ArrayList<>();
[Link]("A"); [Link]("B");
[Link](0); // fast
Q18. HashMap internal working — explain in detail
(very common question).
Answer: HashMap stores key-value pairs in an array of buckets
(Node<K,V>[] table). 1. When you call put(key, value), it computes
hashCode() of the key, then applies a hash spreading function to
reduce collisions, then index = hash & ([Link] - 1) to find the
bucket. 2. If the bucket is empty, a new Node is placed there. 3. If
there’s a collision (same index), it’s added as a linked list in that
bucket (chaining). Since Java 8, if a bucket’s linked list grows beyond
8 nodes (treeify threshold) and table size ≥ 64, it converts to a Red-
Black Tree for O(log n) lookup instead of O(n). 4. get(key)
recomputes the hash, finds the bucket, then iterates/searches that
bucket comparing equals(). 5. Resizing: When size exceeds capacity
* loadFactor (default 0.75), the table doubles and all entries are
rehashed.
Map<String, Integer> map = new HashMap<>();
[Link]("apple", 1);
[Link]("banana", 2);
// Internally: index = hash("apple") & (16-1)
Key Interview Points: - HashMap allows one null key, multiple null
values. - Not thread-safe (use ConcurrentHashMap for multithreading). -
Default capacity = 16, load factor = 0.75. - Why power-of-2 capacity?
So hash & (n-1) works as a fast modulo replacement.
Q19. HashMap vs Hashtable vs ConcurrentHashMap
HashMap Hashtable ConcurrentHashMap
Yes
(synchronized, Yes (segment/bucket-
Thread-safe No
whole map level locking)
locked)
1 null key,
Null No nulls
multiple No nulls allowed
keys/values allowed
null values
Fast in concurrent
Performance Fast Slow (legacy)
environment
Q20. HashSet vs TreeSet vs LinkedHashSet
HashSet: No order guaranteed, O(1) operations, backed by
HashMap internally.
LinkedHashSet: Maintains insertion order, backed by
LinkedHashMap.
TreeSet: Sorted order (natural or via Comparator), backed by
TreeMap (Red-Black tree), O(log n) operations.
Q21. Comparable vs Comparator
Comparable (compareTo): defines the natural/default ordering,
implemented IN the class itself.
Comparator (compare): defines custom/external ordering,
separate class/lambda, can have multiple sort orders.
class Employee implements Comparable<Employee> {
int salary;
public int compareTo(Employee e) { return [Link] -
[Link]; } // natural order
}
// Custom comparator
List<Employee> list = ...;
[Link]([Link](Employee::getName).reversed());
Q22. Fail-fast vs Fail-safe iterators
Fail-fast (ArrayList, HashMap): throws
ConcurrentModificationException if collection is structurally
modified during iteration (uses a modCount check).
Fail-safe (CopyOnWriteArrayList, ConcurrentHashMap): iterates
over a clone/snapshot, doesn’t throw exception, but may not reflect
latest updates.
Q23. How does equals() and hashCode() contract work?
Rule: If two objects are equal via equals(), they must have the same
hashCode(). (Reverse is not required — different objects CAN share
hashcode, called collision.)
class Point {
int x, y;
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point)) return false;
Point p = (Point) o;
return x == p.x && y == p.y;
}
@Override public int hashCode() { return [Link](x, y); }
}
Why it matters: If you override equals() but not hashCode(), the
object will behave incorrectly in HashMap/HashSet (two “equal”
objects might end up in different buckets, both being “found” as
distinct).
Q24. Diamond operator, Generics — why use
Generics?
Generics provide compile-time type safety and eliminate the need
for casting.
List<String> list = new ArrayList<>(); // diamond operator infers
type
[Link]("hello");
// without generics, you'd need: String s = (String) [Link](0);
Generic method example:
public static <T> T getFirst(List<T> list) { return [Link](0); }
4. EXCEPTION HANDLING
Q25. Exception hierarchy
Throwable
├── Error (JVM-level, e.g. OutOfMemoryError, StackOverflowError) —
not meant to be caught
└── Exception
├── Checked (compile-time, must handle/declare) — IOException,
SQLException
└── Unchecked / RuntimeException (NullPointerException,
ArithmeticException)
Q26. Checked vs Unchecked exceptions
Checked: Checked at compile-time; must be handled with try-
catch or declared with throws. E.g. IOException, SQLException. Used
for recoverable conditions.
Unchecked (RuntimeException): Checked at runtime, not
enforced by compiler. E.g. NullPointerException,
ArrayIndexOutOfBoundsException. Usually due to programming bugs.
Q27. try-catch-finally, try-with-resources
try {
int x = 10 / 0;
} catch (ArithmeticException e) {
[Link]("Error: " + [Link]());
} finally {
[Link]("Always executes (cleanup code)");
}
// try-with-resources - auto-closes resources implementing
AutoCloseable
try (BufferedReader br = new BufferedReader(new
FileReader("[Link]"))) {
[Link]([Link]());
} catch (IOException e) {
[Link]();
}
Note: finally always runs except when JVM exits via [Link]() or
the thread is killed.
Q28. Custom exceptions — how and why?
class InsufficientBalanceException extends RuntimeException {
public InsufficientBalanceException(String message) {
super(message); }
}
class Account {
double balance;
void withdraw(double amt) {
if (amt > balance) throw new
InsufficientBalanceException("Not enough balance");
balance -= amt;
}
}
Custom exceptions make error handling domain-specific and
readable, e.g. UserNotFoundException, OrderProcessingException in a
Spring Boot REST API.
Q29. throw vs throws
throw — used to actually throw an exception instance.
throws — used in method signature to declare that a method might
throw a checked exception.
5. MULTITHREADING & CONCURRENCY
Q30. How to create a thread in Java?
// 1. Extending Thread
class MyThread extends Thread {
public void run() { [Link]("Running"); }
}
new MyThread().start();
// 2. Implementing Runnable (preferred — allows extending other
classes too)
class MyTask implements Runnable {
public void run() { [Link]("Running task"); }
}
new Thread(new MyTask()).start();
// 3. Using Lambda (Java 8+)
new Thread(() -> [Link]("Running via lambda")).start();
// 4. ExecutorService (preferred for production)
ExecutorService executor = [Link](4);
[Link](() -> [Link]("Task running"));
[Link]();
Always prefer Runnable/ExecutorService over extending Thread
because Java doesn’t support multiple inheritance — extending
Thread uses up your one inheritance slot.
Q31. start() vs run()
start() creates a new thread and the JVM calls run() on it
asynchronously.
run() called directly just executes like a normal method call on the
current thread — no new thread is created.
Q32. synchronized keyword, locks
synchronized ensures only one thread can execute a block/method at a
time, preventing race conditions.
class Counter {
private int count = 0;
public synchronized void increment() { count++; } // method-
level lock
public void incrementBlock() {
synchronized(this) { count++; } // block-level lock
}
}
Object-level lock vs Class-level lock (synchronized static method
locks the Class object, not instance).
Q33. What is Deadlock? How to avoid it?
Deadlock: Two or more threads waiting forever for each other to
release locks.
// Thread 1 locks A then wants B; Thread 2 locks B then wants A →
deadlock
Avoid by: - Acquiring locks in a consistent global order. - Using
tryLock() with timeout (from [Link]). -
Avoiding nested locks where possible.
Q34. wait() vs sleep() vs notify()/notifyAll()
wait() sleep()
Belongs to Object class Thread class
Releases lock Yes No
Used for Inter-thread communication Pausing execution
Wakes up via notify()/notifyAll() Time elapses
synchronized(obj) {
[Link](); // releases lock, waits till notified
}
synchronized(obj) {
[Link](); // wakes one waiting thread
}
Q35. Executor Framework — why use it over manual
Thread management?
ExecutorService manages a thread pool, reusing threads instead of
creating new ones every time (expensive). Provides submit(), Future
for results, graceful shutdown.
ExecutorService pool = [Link](3);
Future<Integer> future = [Link](() -> 10 + 20);
[Link]([Link]()); // 30
[Link]();
Q36. What is the Java Memory Model (volatile
keyword)?
volatile ensures visibility — a write to a volatile variable by one
thread is immediately visible to other threads (no CPU caching of that
variable). It does NOT guarantee atomicity (use synchronized or
AtomicInteger for that).
private volatile boolean running = true;
Q37. CompletableFuture / parallel streams (modern
Java concurrency)
CompletableFuture<Integer> cf = [Link](() ->
10 * 2)
.thenApply(result -> result + 5);
[Link]([Link]()); // 25
6. JAVA 8+ FEATURES
Q38. Lambda expressions
Concise way to implement functional interfaces (interfaces with a
single abstract method).
Runnable r = () -> [Link]("Running");
Comparator<String> cmp = (a, b) -> [Link]() - [Link]();
Q39. Functional Interfaces
A functional interface has exactly one abstract method (can have
default/static methods too). Annotated with @FunctionalInterface.
Built-in ones: Function<T,R>, Predicate<T>, Consumer<T>, Supplier<T>,
BiFunction<T,U,R>.
Function<Integer, Integer> square = x -> x * x;
Predicate<Integer> isEven = x -> x % 2 == 0;
Consumer<String> print = [Link]::println;
Supplier<String> greet = () -> "Hello";
Q40. Streams API — explain with example
Streams process collections in a functional, declarative style (filter,
map, reduce) without modifying the source.
List<String> names = [Link]("Aman", "Bob", "Charlie",
"Anita");
List<String> result = [Link]()
.filter(n -> [Link]("A"))
.map(String::toUpperCase)
.sorted()
.collect([Link]());
// [AMAN, ANITA]
int sum = [Link](1,2,3,4,5).stream()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.sum(); // 6
// Grouping
Map<Boolean, List<String>> grouped = [Link]()
.collect([Link](n -> [Link]() > 4));
Key points: Streams are lazy (intermediate ops like filter/map don’t
execute until a terminal op like collect/forEach/sum is called). Streams
can be sequential or .parallel().
Q41. Optional class — why use it?
Avoids NullPointerException by representing a value that may or may
not be present.
Optional<String> name = [Link](getName());
[Link]([Link]("Default Name"));
[Link](n -> [Link]("Found: " + n));
Q42. Default and static methods in interfaces (Java 8)
Allows adding new methods to interfaces without breaking existing
implementations.
interface Greeting {
default void hello() { [Link]("Hello!"); }
static void info() { [Link]("Greeting interface"); }
}
Q43. What’s new in Java 9–21 (commonly asked at
senior level)?
Java 9: Module system (JPMS), var in JShell, factory methods
[Link](), [Link]().
Java 10: Local variable type inference (var).
Java 11: New String methods (isBlank, strip), HTTP Client API,
run .java files directly.
Java 14/16: Records (record Point(int x, int y){}) — immutable
data classes.
Java 17 (LTS): Sealed classes, pattern matching for switch
(preview).
Java 21 (LTS): Virtual threads (Project Loom) — lightweight
threads for massive concurrency, pattern matching for switch
finalized.
// Record example
record Point(int x, int y) {}
Point p = new Point(1, 2);
[Link](p.x()); // auto-generated getter, equals,
hashCode, toString
7. JDBC
Q44. Steps to connect Java app to a database using
JDBC
[Link]("[Link]"); // optional in modern
JDBC (auto-loaded via SPI)
Connection con = [Link](
"jdbc:mysql://localhost:3306/mydb", "root", "password");
PreparedStatement ps = [Link]("SELECT * FROM employees
WHERE id = ?");
[Link](1, 101);
ResultSet rs = [Link]();
while ([Link]()) {
[Link]([Link]("name"));
}
[Link]();
Q45. Statement vs PreparedStatement
Statement: Compiled every time, vulnerable to SQL Injection
(string concatenation).
PreparedStatement: Precompiled, parameterized (?
placeholders), prevents SQL injection, better performance for
repeated queries.
// VULNERABLE
Statement st = [Link]();
[Link]("SELECT * FROM users WHERE name = '" + userInput +
"'");
// SAFE
PreparedStatement ps = [Link]("SELECT * FROM users
WHERE name = ?");
[Link](1, userInput);
8. SPRING CORE
Q46. What is Spring Framework? Why use it?
Spring is a lightweight, open-source framework for building Java
enterprise applications. Core benefits: - Dependency Injection (DI) /
Inversion of Control (IoC) — reduces tight coupling. - AOP
(Aspect-Oriented Programming) — for cross-cutting concerns like
logging, transactions. - Modules for data access (JDBC, ORM), web
(MVC), security, testing.
Q47. What is Dependency Injection and Inversion of
Control? (MUST KNOW)
IoC: The control of creating and managing objects is inverted —
instead of your code creating dependencies (new), the Spring
container creates and injects them.
DI: The mechanism by which IoC is achieved — dependencies are
“injected” into a class rather than the class creating them itself.
// Without DI (tight coupling)
class Car {
Engine engine = new Engine(); // Car creates its own dependency
}
// With DI (loose coupling)
@Component
class Engine {}
@Component
class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) { [Link] = engine; } // Spring
injects Engine
}
Types of DI: Constructor Injection (recommended — immutable,
testable), Setter Injection, Field Injection (@Autowired on field —
discouraged, hard to test/make immutable).
Q48. Spring Bean lifecycle
1. Spring container reads configuration (annotations/XML) →
instantiates bean.
2. Dependencies injected.
3. BeanNameAware, BeanFactoryAware callbacks (if implemented).
4. @PostConstruct / afterPropertiesSet() (InitializingBean) called.
5. Bean is ready to use.
6. On shutdown: @PreDestroy / destroy() (DisposableBean) called.
@Component
class MyBean {
@PostConstruct
public void init() { [Link]("Bean initialized"); }
@PreDestroy
public void cleanup() { [Link]("Bean destroyed"); }
}
Q49. Bean Scopes
singleton (default): one instance per Spring container.
prototype: new instance every time it’s requested.
request: one instance per HTTP request (web apps).
session: one instance per HTTP session.
@Component
@Scope("prototype")
class Task {}
Q50. @Component vs @Service vs @Repository vs
@Controller
All are specializations of @Component (so all get auto-detected during
component scanning), but used for semantic clarity and extra
behavior: - @Component: generic Spring-managed bean. - @Service:
business/service layer. - @Repository: DAO/persistence layer —
additionally translates database exceptions into Spring’s
DataAccessException. - @Controller: web layer (returns views);
@RestController = @Controller + @ResponseBody (returns JSON/data
directly).
Q51. @Autowired — how does Spring resolve it? What
if multiple beans of the same type exist?
Spring resolves by type first; if multiple beans match, it tries to
resolve by name (matching variable/field name to bean name), or you
can use @Qualifier to specify explicitly.
@Autowired
@Qualifier("petrolEngine")
private Engine engine;
Use @Primary to mark a default bean among multiple candidates.
Q52. AOP (Aspect-Oriented Programming) — explain
with example
AOP separates cross-cutting concerns (logging, security,
transactions) from business logic. Key terms: Aspect (module of
cross-cutting logic), Advice (action taken — @Before, @After, @Around),
Pointcut (expression matching where to apply), JoinPoint (point of
execution, e.g. method call).
@Aspect
@Component
class LoggingAspect {
@Before("execution(* [Link].*.*(..))")
public void logBefore(JoinPoint jp) {
[Link]("Executing: " +
[Link]().getName());
}
}
Real use case: @Transactional itself is implemented via AOP — Spring
wraps your method call with proxy logic to begin/commit/rollback a
transaction.
9. SPRING BOOT
Q53. What is Spring Boot? How is it different from
Spring?
Spring Boot is built on top of Spring to simplify setup: auto-
configuration, embedded servers (Tomcat/Jetty — no need to
deploy WAR separately), starter dependencies (e.g. spring-boot-
starter-web bundles everything needed for web apps), opinionated
defaults, production-ready features (Actuator).
Spring Spring Boot
Configuration Manual (XML/Java config) Auto-configuration
Server External (deploy WAR) Embedded Tomcat/Jetty
Setup time High (boilerplate) Low (starters)
Q54. Explain @SpringBootApplication
It’s a meta-annotation combining three: - @Configuration — marks
class as a source of bean definitions. - @EnableAutoConfiguration — tells
Spring Boot to auto-configure beans based on classpath dependencies
(e.g. if spring-boot-starter-web is present, auto-configure
DispatcherServlet). - @ComponentScan — scans the package (and sub-
packages) for @Component/@Service/@Repository/@Controller beans.
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
[Link]([Link], args);
}
}
Q55. How does Spring Boot Auto-Configuration work
internally?
Spring Boot scans META-
INF/spring/[Link].
imports (or older [Link]) for auto-configuration classes.
Each is annotated with @Conditional annotations (@ConditionalOnClass,
@ConditionalOnMissingBean, @ConditionalOnProperty) — so a bean is only
auto-configured if certain conditions are met (e.g., a specific class
is on the classpath and the user hasn’t already defined their own bean
of that type).
Q56. [Link] vs [Link] —
example
[Link]=8081
[Link]=jdbc:mysql://localhost:3306/mydb
[Link]-auto=update
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
jpa:
hibernate:
ddl-auto: update
Q57. Spring Boot Profiles
Used to maintain environment-specific configuration (dev, test, prod).
# [Link]
[Link]=8080
# [Link]
[Link]=80
@Profile("dev")
@Configuration
class DevConfig {}
Activate via [Link]=dev in properties or -
[Link]=prod at startup.
Q58. Spring Boot Actuator
Provides production-ready monitoring endpoints: /actuator/health,
/actuator/metrics, /actuator/info, /actuator/env. Used for health
checks in Kubernetes/load balancers and for observability.
Q59. How do you handle exceptions globally in Spring
Boot REST APIs?
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse>
handleNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new
ErrorResponse(HttpStatus.NOT_FOUND.value(), [Link]());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse> handleGeneric(Exception ex)
{
return new ResponseEntity<>(new ErrorResponse(500,
[Link]()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@RestControllerAdvice centralizes exception handling across all
controllers (DRY principle), avoiding repetitive try-catch in every
controller method.
10. SPRING MVC & REST APIs
Q60. Explain Spring MVC architecture / request flow
1. Client sends HTTP request → DispatcherServlet (front controller)
receives it.
2. DispatcherServlet consults HandlerMapping to find which
controller method handles the URL.
3. Controller executes business logic (calls service layer), returns a
ModelAndView or data (for REST, JSON via @ResponseBody).
4. For traditional MVC, ViewResolver maps logical view name to
actual JSP/Thymeleaf template.
5. Response sent back to client.
Client → DispatcherServlet → HandlerMapping → Controller → Service →
Repository → DB
↓
ViewResolver → View →
Response
Q61. Build a REST CRUD API — full example
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
@Autowired
private EmployeeService service;
@GetMapping
public List<Employee> getAll() { return [Link](); }
@GetMapping("/{id}")
public ResponseEntity<Employee> getById(@PathVariable Long id) {
return [Link]([Link](id));
}
@PostMapping
public ResponseEntity<Employee> create(@RequestBody @Valid
Employee emp) {
Employee saved = [Link](emp);
return
[Link]([Link]).body(saved);
}
@PutMapping("/{id}")
public ResponseEntity<Employee> update(@PathVariable Long id,
@RequestBody Employee emp) {
return [Link]([Link](id, emp));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
[Link](id);
return [Link]().build();
}
}
Q62. @RequestParam vs @PathVariable vs
@RequestBody
@PathVariable — extracts value from URI path: /employees/{id} →
/employees/5.
@RequestParam — extracts query parameters: /employees?dept=IT.
@RequestBody — maps the entire JSON request body to a Java
object.
Q63. What are HTTP status codes commonly used in
REST APIs?
200 OK — success (GET/PUT)
201 Created — resource created (POST)
204 No Content — success, no body (DELETE)
400 Bad Request — invalid input
401 Unauthorized — not authenticated
403 Forbidden — authenticated but no permission
404 Not Found
409 Conflict — e.g. duplicate resource
500 Internal Server Error
Q64. What is idempotency in REST? Which HTTP
methods are idempotent?
An idempotent operation produces the same result no matter how
many times it’s repeated. - Idempotent: GET, PUT, DELETE
(calling delete twice still results in resource being gone). - Not
idempotent: POST (calling twice creates two resources).
Q65. RESTful API design best practices
Use nouns, not verbs, in URLs: /orders not /getOrders.
Use proper HTTP methods and status codes.
Version your API: /api/v1/orders.
Use plural resource names, nested resources: /users/5/orders.
Support pagination/filtering: /orders?page=2&size=20&sort=date.
Return meaningful error bodies (not just status codes).
Q66. Validation in Spring Boot
public class Employee {
@NotBlank(message = "Name is required")
private String name;
@Email
private String email;
@Min(18)
private int age;
}
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody Employee emp,
BindingResult result) {
if ([Link]()) return
[Link]().body([Link]());
...
}
11. SPRING SECURITY
Q67. How does Spring Security work (filter chain)?
Spring Security uses a chain of Servlet Filters that intercept every
request before it reaches the controller. Key filters:
UsernamePasswordAuthenticationFilter, BasicAuthenticationFilter,
JwtAuthenticationFilter (custom), ExceptionTranslationFilter,
FilterSecurityInterceptor (authorization check).
Q68. How do you implement JWT-based
authentication in Spring Boot?
1. User sends username/password to /login.
2. Server validates credentials (via AuthenticationManager +
UserDetailsService), generates a JWT signed with a secret key,
containing claims (username, roles, expiry).
3. Server returns JWT to client.
4. Client sends JWT in Authorization: Bearer <token> header on every
subsequent request.
5. A custom OncePerRequestFilter intercepts requests, validates the
JWT signature/expiry, extracts user details, and sets the
SecurityContext so Spring knows the user is authenticated — no
session/state stored on server (stateless).
public class JwtAuthFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res, FilterChain chain) {
String token = extractToken(req);
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);
}
}
Q69. Authentication vs Authorization
Authentication: verifying who you are (login, credentials check).
Authorization: verifying what you’re allowed to do
(roles/permissions — e.g. @PreAuthorize("hasRole('ADMIN')")).
Q70. CSRF, CORS — what are they and how to handle
in Spring Boot?
CSRF (Cross-Site Request Forgery): attacker tricks a logged-in
user’s browser into making unwanted requests. Spring Security
enables CSRF protection by default for stateful (session) apps;
usually disabled for stateless REST APIs using JWT (since there’s
no session cookie to exploit).
CORS (Cross-Origin Resource Sharing): browser security
feature blocking requests from a different origin (domain/port)
unless server explicitly allows it.
@CrossOrigin(origins = "[Link]
@RestController
class MyController {}
12. HIBERNATE / JPA
Q71. What is ORM? What is Hibernate?
ORM (Object-Relational Mapping) maps Java objects to database
tables, eliminating most manual SQL/JDBC boilerplate. Hibernate is
the most popular ORM implementation of the JPA (Java Persistence
API) specification.
Q72. JPA vs Hibernate
JPA is a specification (set of interfaces: EntityManager, @Entity,
etc.) — just rules.
Hibernate is an implementation of JPA (along with EclipseLink,
OpenJPA). You code against JPA interfaces, Hibernate does the
actual work, making your code portable to other JPA providers.
Q73. Basic Entity mapping example
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
@Column(name = "emp_name", nullable = false)
private String name;
@ManyToOne
@JoinColumn(name = "dept_id")
private Department department;
}
Q74. Entity relationships — @OneToMany,
@ManyToOne, @ManyToMany, @OneToOne
// One Department has Many Employees
@Entity
class Department {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "department", cascade = [Link])
private List<Employee> employees;
}
@Entity
class Employee {
@ManyToOne
@JoinColumn(name = "dept_id")
private Department department;
}
// Many-to-Many
@Entity
class Student {
@ManyToMany
@JoinTable(name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private List<Course> courses;
}
mappedBy indicates the inverse (non-owning) side of the relationship —
the owning side has the foreign key.
Q75. Hibernate Caching — First Level vs Second
Level
First-level cache: Enabled by default, scoped to a
Session/EntityManager — within one transaction, repeated lookups
of the same entity by ID hit the cache, not the DB.
Second-level cache: Optional, scoped to the SessionFactory
(shared across sessions) — needs explicit config (e.g. Ehcache,
Redis) and @Cacheable annotation. Useful for read-heavy, rarely-
changing data (e.g. lookup tables).
Q76. Lazy vs Eager loading
Lazy (default for collections): Related entity is fetched only
when accessed — saves performance but can cause
LazyInitializationException if accessed outside an active session.
Eager (default for @ManyToOne/@OneToOne): Related entity fetched
immediately with the parent — can cause performance issues
(N+1 problem) if overused.
@OneToMany(fetch = [Link])
private List<Employee> employees;
Q77. What is the N+1 select problem? How to solve
it?
Problem: Fetching a list of N parent entities triggers 1 query for
parents + N additional queries (one per parent) to fetch their lazy-
loaded children — total N+1 queries instead of 1-2.
Solutions: 1. Use JOIN FETCH in JPQL: SELECT d FROM Department d
JOIN FETCH [Link]. 2. Use @EntityGraph to specify which
associations to fetch eagerly per query. 3. Batch fetching:
@BatchSize(size = 10).
Q78. Entity states / lifecycle in Hibernate
Transient: new object, not associated with any session, no DB
row.
Persistent: associated with an active session, changes are auto-
tracked and synced to DB (dirty checking).
Detached: was persistent, but session closed — changes no longer
tracked automatically.
Removed: marked for deletion.
Employee emp = new Employee(); // transient
[Link](emp); // persistent
[Link](); // detached
[Link](emp); // removed
Q79. @Transactional — how does it work?
Spring wraps the annotated method in a proxy that begins a
transaction before the method executes and commits (or rolls back on
exception) after. By default, rolls back only on unchecked
exceptions (RuntimeException); use rollbackFor = [Link] to
also rollback on checked exceptions.
@Transactional
public void transferMoney(Long fromId, Long toId, double amt) {
[Link](fromId, amt);
[Link](toId, amt); // if this fails, withdraw is
rolled back too
}
Important gotcha: @Transactional doesn’t work for self-invocation
(calling an annotated method from within the same class) because
Spring AOP proxies only intercept external calls.
Q80. Spring Data JPA Repository — explain
public interface EmployeeRepository extends JpaRepository<Employee,
Long> {
List<Employee> findByDepartmentName(String deptName); //
derived query
@Query("SELECT e FROM Employee e WHERE [Link] > :sal")
List<Employee> findHighEarners(@Param("sal") double sal);
}
Spring Data JPA generates the implementation at runtime based on
method naming conventions (findBy..., countBy..., deleteBy...) — no
need to write implementation classes.
13. MICROSERVICES
Q81. What are microservices? Monolith vs
Microservices
Monolith: Single deployable unit, all modules tightly coupled, one
codebase/database. Microservices: Application split into small,
independently deployable services, each owning its own database,
communicating via APIs (REST/gRPC) or messaging
(Kafka/RabbitMQ).
Monolith Microservices
Independent per
Deployment Single unit
service
Scale individual
Scaling Scale entire app
services
Tech stack One stack Polyglot possible
Complex
Complexity Simple to start (networking, data
consistency)
One bug can crash
Fault isolation Isolated failures
whole app
Q82. How do microservices communicate?
Synchronous: REST (HTTP/JSON), gRPC.
Asynchronous: Message brokers — Kafka, RabbitMQ (event-
driven, decoupled, better resilience).
Q83. What is Service Discovery? (Eureka)
In a dynamic environment (containers, auto-scaling), service
instances’ IPs change constantly. Service Discovery (e.g. Netflix
Eureka, Consul) lets services register themselves on startup and
look up other services by name instead of hardcoded IPs.
@EnableEurekaServer // on the discovery server
@EnableEurekaClient // on each microservice
Q84. What is an API Gateway? Why use it?
A single entry point for all client requests, routing them to the
appropriate microservice. Handles cross-cutting concerns:
authentication, rate limiting, load balancing, logging,
request/response transformation. (e.g. Spring Cloud Gateway, Netflix
Zuul, Kong).
Q85. What is Circuit Breaker pattern?
(Resilience4j/Hystrix)
Prevents a failing service from cascading failures across the system. If
a downstream service fails repeatedly, the circuit “opens” and
subsequent calls fail fast (return fallback) instead of waiting/retrying,
giving the failing service time to recover.
@CircuitBreaker(name = "inventoryService", fallbackMethod =
"fallback")
public String getInventory() {
return [Link]("[Link]
service/items", [Link]);
}
public String fallback(Exception e) { return "Inventory service
unavailable"; }
States: Closed (normal) → Open (failing, blocks calls) → Half-Open
(tests if service recovered).
Q86. How do you handle distributed transactions /
data consistency across microservices?
Since each service owns its DB, traditional 2PC doesn’t scale well.
Use the Saga pattern: - Choreography: Each service publishes
events; others react (via Kafka). - Orchestration: A central
orchestrator coordinates the sequence of steps and triggers
compensating transactions on failure (e.g. if payment fails, cancel
the order).
Q87. Config Server (Spring Cloud Config)
Centralizes configuration for all microservices in one place (often
backed by a Git repo), so config can be updated without redeploying
services.
Q88. What is load balancing? Client-side vs Server-
side.
Server-side: A dedicated load balancer (Nginx, AWS ELB)
distributes traffic.
Client-side: The client (or a library like Spring Cloud
LoadBalancer/Ribbon) queries the service registry and picks an
instance itself.
14. SQL / DATABASES
Q89. SQL Joins — explain with example
-- INNER JOIN: only matching rows
SELECT [Link], d.dept_name FROM employees e
INNER JOIN departments d ON e.dept_id = [Link];
-- LEFT JOIN: all from left + matched from right (nulls if no match)
SELECT [Link], d.dept_name FROM employees e
LEFT JOIN departments d ON e.dept_id = [Link];
-- RIGHT JOIN: all from right + matched from left
-- FULL OUTER JOIN: all rows from both (not supported directly in
MySQL, use UNION)
Q90. Difference between WHERE and HAVING
WHERE filters rows before grouping (can’t use aggregate functions).
HAVING filters groups after GROUP BY (can use aggregate functions
like COUNT, SUM).
SELECT dept_id, COUNT(*) AS cnt FROM employees
WHERE salary > 30000
GROUP BY dept_id
HAVING COUNT(*) > 5;
Q91. Primary Key vs Foreign Key vs Unique Key
Primary Key: Uniquely identifies a row, can’t be NULL, only one
per table.
Foreign Key: References primary key in another table, enforces
referential integrity.
Unique Key: Ensures column values are unique, but allows one
NULL (in most DBs).
Q92. Normalization — explain 1NF, 2NF, 3NF
1NF: Atomic values, no repeating groups (each cell holds a single
value).
2NF: 1NF + no partial dependency (non-key columns depend on
the whole composite primary key, not part of it).
3NF: 2NF + no transitive dependency (non-key columns don’t
depend on other non-key columns).
Example: Splitting a single “Orders” table with customer
name/address repeated for every order into separate Customers and
Orders tables (linked by customer_id) removes redundancy — that’s
normalization in action.
Q93. Indexes — what are they, when to use?
An index is a data structure (usually B-Tree) that speeds up row
lookups, at the cost of slower writes (insert/update/delete) and extra
storage. Use indexes on columns frequently used in WHERE, JOIN, ORDER
BY. Avoid over-indexing on tables with heavy writes.
CREATE INDEX idx_emp_dept ON employees(dept_id);
Q94. ACID properties
Atomicity: transaction is all-or-nothing.
Consistency: DB moves from one valid state to another.
Isolation: concurrent transactions don’t interfere with each other.
Durability: once committed, changes persist even after a crash.
Q95. Transaction Isolation Levels
1. Read Uncommitted — dirty reads possible.
2. Read Committed — no dirty reads, but non-repeatable reads
possible.
3. Repeatable Read — no dirty/non-repeatable reads, but phantom
reads possible (MySQL default).
4. Serializable — strictest, fully isolated, slowest.
Q96. Write a query: Find the 2nd highest salary.
SELECT MAX(salary) FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);
-- Or using LIMIT/OFFSET
SELECT DISTINCT salary FROM employees
ORDER BY salary DESC LIMIT 1 OFFSET 1;
-- Or window function (modern, handles ties well)
SELECT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
) t WHERE rnk = 2;
15. FRONTEND (React / Angular basics
for Full Stack roles)
Q97. What is the Virtual DOM in React? Why is it
fast?
React keeps a lightweight in-memory copy of the real DOM (Virtual
DOM). When state changes, React builds a new Virtual DOM tree,
diffs it against the previous one (reconciliation algorithm), and
updates only the changed parts of the real DOM — avoiding expensive
full re-renders.
Q98. useState and useEffect — example
import { useState, useEffect } from 'react';
function EmployeeList() {
const [employees, setEmployees] = useState([]);
useEffect(() => {
fetch('/api/employees')
.then(res => [Link]())
.then(data => setEmployees(data));
}, []); // empty dependency array = runs once on mount
return (
<ul>
{[Link](emp => <li key={[Link]}>{[Link]}</li>)}
</ul>
);
}
useState manages component-local state and triggers re-render on
change. useEffect handles side effects (API calls, subscriptions) —
runs after render, and the dependency array controls when it re-runs.
Q99. Props vs State
Props: Read-only data passed from parent to child component.
State: Mutable, managed within a component, triggers re-render
when updated via setState/useState.
Q100. Angular: what is two-way data binding?
Angular’s [(ngModel)] syncs data between the component (TypeScript)
and the view (HTML) automatically — changes in the input field
update the model, and model changes update the view.
<input [(ngModel)]="[Link]">
Q101. How does a React app talk to a Spring Boot
backend?
fetch('[Link] {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization':
`Bearer ${token}` },
body: [Link]({ name: 'John', dept: 'IT' })
})
.then(res => [Link]())
.then(data => [Link](data));
Backend needs @CrossOrigin (or global CORS config) to allow requests
from the frontend’s origin (e.g. [Link]
16. GIT & TOOLS
Q102. Common Git commands and workflow
git clone <repo-url>
git checkout -b feature/login-page # create+switch branch
git add .
git commit -m "Add login page"
git push origin feature/login-page
git pull origin main
git merge feature/login-page # merge into current branch
git rebase main # reapply commits on top of
main (cleaner history)
Q103. Git merge vs rebase
Merge: Combines histories, creates a merge commit, preserves
full history (non-linear).
Rebase: Replays your commits on top of the target branch,
creates a linear history but rewrites commit hashes (avoid
rebasing shared/public branches).
Q104. What is a Git conflict and how do you resolve
it?
Happens when two branches modify the same line(s) of a file
differently. Git marks the conflicting section with <<<<<<<, =======,
>>>>>>> — you manually edit to keep the correct content, then git add
the file and continue the merge/rebase.
Q105. Maven vs Gradle
Both are build automation tools managing dependencies, compiling,
testing, packaging. - Maven: XML-based ([Link]), convention over
configuration, mature ecosystem. - Gradle: Groovy/Kotlin DSL
([Link]), more flexible, generally faster (incremental builds,
caching).
Q106. Common Maven lifecycle phases
validate → compile → test → package → verify → install → deploy
mvn clean install # cleans target dir, compiles, tests, packages,
installs to local repo
17. SYSTEM DESIGN BASICS (often asked
for 2+ yrs experience)
Q107. How would you design a URL shortener?
(sample framework to answer ANY system design
question)
1. Clarify requirements: scale (reads/writes per day), custom
aliases?, analytics needed?
2. Core API: POST /shorten {longUrl} → returns short code; GET
/{code} → redirects.
3. Encoding: Base62 encode an auto-incrementing ID, or hash +
collision check.
4. Database: Key-value store (short code → long URL) — Redis for
caching hot URLs, plus a persistent DB
(e.g. PostgreSQL/Cassandra) for durability.
5. Scaling: Read-heavy → cache layer + read replicas; Load balancer
in front of stateless app servers.
6. Reliability: Replication, rate limiting to prevent abuse.
General approach to explain to interviewer: “I’d start by clarifying
functional/non-functional requirements and scale, then sketch the
high-level architecture (client → load balancer → app servers → cache
→ DB), then drill into the data model, API contracts, and how I’d
handle scaling bottlenecks like hot keys or high write throughput.”
Q108. How do you ensure a Spring Boot REST API is
scalable and performant?
Use connection pooling (HikariCP, default in Spring Boot).
Add caching (@Cacheable, Redis) for frequently read, rarely
changed data.
Use pagination for large datasets.
Use async processing (@Async, message queues) for long-running
tasks.
Horizontal scaling behind a load balancer; keep services stateless
(session data in Redis, not in-memory).
Use indexes on DB, avoid N+1 queries.
Monitor with Actuator + Prometheus/Grafana.
18. BEHAVIORAL / HR QUESTIONS
Q109. “Tell me about yourself” — structure
1. Current role + years of experience + core tech stack.
2. 1-2 key projects/achievements with measurable impact.
3. Why you’re interested in this role/company. (Keep it to ~90
seconds, don’t repeat your resume verbatim.)
Q110. “Describe a challenging bug you fixed.”
Use STAR method: Situation, Task, Action, Result. Example answer:
“In production, our order service was intermittently timing out.
(Situation) I needed to find the root cause without downtime. (Task) I
added structured logging and traced it to an N+1 query issue in
Hibernate when fetching order line items. (Action) I fixed it with a
JOIN FETCH query and added a DB index, which reduced average
response time from 2.3s to 180ms. (Result)”
Q111. “Why do you want to leave your current
company?”
Keep positive, forward-looking — talk about growth, learning new
tech, bigger scale, not complaints about past employer/colleagues.
Q112. “How do you handle disagreements with team
members?”
Talk about listening to understand their reasoning, presenting
data/trade-offs objectively, and being willing to compromise or defer
to team consensus/tech lead when it’s not a critical issue.
QUICK REVISION CHECKLIST (last 30
min before interview)
OOP 4 pillars with one-line examples
HashMap internal working (hash, bucket, treeify, resize)
Checked vs unchecked exceptions
Thread creation methods + synchronized/deadlock
Streams API (filter/map/collect) one example
Spring DI + Bean lifecycle
@SpringBootApplication breakdown
REST CRUD controller skeleton from memory
JWT auth flow steps
Hibernate lazy/eager + N+1 problem + fix
Microservices: service discovery, API gateway, circuit breaker,
saga
SQL joins + 2nd highest salary query
One STAR-format project story ready to tell
Good luck — speak slowly, give the one-line definition first, then the
example, then why/when to use it. That structure alone makes
answers sound senior-level.