[go: up one dir, main page]

0% found this document useful (0 votes)
4 views26 pages

Complete Java Interview Preparation Guide

The document is a comprehensive Java interview preparation guide focusing on core Java and concurrency topics, covering key concepts like the Java Memory Model, synchronization, garbage collection, threading concepts, and advanced concurrency mechanisms. It includes explanations of important keywords, classes, and patterns, along with code examples for thread-safe implementations and producer-consumer scenarios. Additionally, it addresses memory management, performance optimization, and thread management strategies essential for Java developers.

Uploaded by

Saurav Mojumder
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)
4 views26 pages

Complete Java Interview Preparation Guide

The document is a comprehensive Java interview preparation guide focusing on core Java and concurrency topics, covering key concepts like the Java Memory Model, synchronization, garbage collection, threading concepts, and advanced concurrency mechanisms. It includes explanations of important keywords, classes, and patterns, along with code examples for thread-safe implementations and producer-consumer scenarios. Additionally, it addresses memory management, performance optimization, and thread management strategies essential for Java developers.

Uploaded by

Saurav Mojumder
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
You are on page 1/ 26

Complete Java Interview Preparation Guide

🔧 Core Java & Concurrency – Top 50 Questions

Memory Model & Synchronization


1. Explain the Java Memory Model (JMM).
The Java Memory Model defines how threads interact through memory and specifies when
changes made by one thread become visible to other threads [1] . The JMM divides memory
between thread stacks and the heap, where each thread has its own stack containing method
calls and local variables, while the heap is shared among all threads [2] . The JMM addresses
visibility and reordering issues by defining synchronization actions like volatile and
synchronized that ensure proper memory barriers [3] .

2. What does the volatile keyword do?


The volatile keyword ensures that when one thread writes a value to a field, it becomes
immediately available to any thread that subsequently reads it [4] . It prevents threads from
working on cached, out-of-date copies by forcing reads and writes to be accompanied by
memory barriers [4] . Volatile is essentially lock-free and provides the most lightweight means of
ensuring thread-safety for simple visibility requirements [4] .
3. Compare synchronized with ReentrantLock.
synchronized blocks cannot extend beyond a single method and are less flexible, while
ReentrantLock allows extending locking scope across multiple methods [5] . ReentrantLock
provides more flexibility with methods like tryLock() that can check lock availability without
blocking, reducing deadlock chances [5] . ReentrantLock offers better control over lock
acquisition and release but requires explicit unlocking in finally blocks [5] .
4. How does AtomicInteger work internally?
AtomicInteger provides atomic operations on integers without explicit synchronization or
locks [6] . It
uses compare-and-swap (CAS) operations at the hardware level to ensure
[6]
atomicity . All methods like getAndSet(), incrementAndGet(), and compareAndSet() are
performed as single, indivisible operations [6] .
5. When should you use ThreadLocal?
Use ThreadLocal to implement per-thread singleton classes or per-thread context information like
transaction IDs [7] . It's useful for wrapping non-thread-safe objects like SimpleDateFormat to
make them thread-safe [7] . ThreadLocal eliminates sharing by providing explicit copies to each
thread, removing synchronization requirements [7] .
6. Implement a thread-safe counter using AtomicInteger.

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadSafeCounter {


private final AtomicInteger count = new AtomicInteger(0);

public int increment() {


return count.incrementAndGet();
}

public int decrement() {


return count.decrementAndGet();
}

public int getValue() {


return count.get();
}
}

7. Implement Producer-Consumer using wait/notify.

class SharedBuffer {
private Queue<Integer> buffer = new LinkedList<>();
private final int MAX_SIZE = 5;

public synchronized void produce(int value) throws InterruptedException {


while (buffer.size() == MAX_SIZE) {
wait(); // Buffer is full, wait for consumer
}
buffer.add(value);
System.out.println("Produced: " + value);
notify(); // Notify consumer that data is available
}

public synchronized void consume() throws InterruptedException {


while (buffer.isEmpty()) {
wait(); // Buffer is empty, wait for producer
}
int value = buffer.poll();
System.out.println("Consumed: " + value);
notify(); // Notify producer that there's space
}
}

8. Implement Producer-Consumer using BlockingQueue.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumerExample {


private BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
class Producer implements Runnable {
public void run() {
try {
for (int i = 0; i < 10; i++) {
queue.put(i); // Blocks if queue is full
System.out.println("Produced: " + i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

class Consumer implements Runnable {


public void run() {
try {
for (int i = 0; i < 10; i++) {
int value = queue.take(); // Blocks if queue is empty
System.out.println("Consumed: " + value);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

Garbage Collection & Memory Management


9. What are the phases of Garbage Collection in JVM?
GC has three main phases: Marking (identifying objects in use), Normal Deletion (removing
unreferenced objects), and Deletion with Compacting (moving referenced objects together for
easier allocation) [8] . The JVM heap is divided into Young Generation (Eden space and two
Survivor spaces) and Old Generation [8] . Minor GC occurs in Young Generation, Major GC in Old
Generation, and Full GC cleans the entire heap [8] .
10. Difference between G1 and CMS collectors.
G1 collector partitions the heap into equal-sized regions and compacts as it proceeds, avoiding
fragmentation issues that CMS might encounter [9] . G1 uses a pause prediction model to meet
user-defined pause time targets and achieves smoother pause times than CMS [9] . G1 performs
global marking to identify mostly empty regions and tackles them first, making it more efficient
than CMS [9] .
11. What is a memory barrier?
Memory barriers (memory fences) define the visibility and ordering of memory operations
between threads [10] . They prevent reordering of instructions that could lead to unexpected
behavior in multithreaded environments [10] . In Java, memory barriers are implemented through
volatile and synchronized, ensuring proper communication and state consistency across
threads [10] .
12. What is a happens-before relationship?
A happens-before relationship is a set of rules governing how the JVM and CPU can reorder
instructions for performance gains [11] . If action A happens-before action B, then A is visible to
and ordered before B [12] . It ensures that memory changes made by one action are visible to
subsequent actions, preventing race conditions [13] .

Threading Concepts
13. Explain the difference between thread and runnable.
Thread is a class representing an actual thread of execution, while Runnable is an interface
representing a task that can be executed concurrently [14] . Runnable allows implementing
multiple interfaces and better code organization, while Thread provides more control but doesn't
support multiple inheritance [14] . Runnable is lightweight and can be reused across multiple
threads [14] .
14. What is thread starvation?
Thread starvation occurs when a thread is unable to gain regular access to shared resources
and cannot make progress [15] . It happens when "greedy" threads monopolize resources,
synchronized methods take too long, higher priority threads always execute first, or wait-notify
signaling consistently favors certain threads [15] .
15. What is a deadlock and how to prevent it?
Deadlock occurs when two threads hold different locks and wait for each other's locks without
releasing their own [16] . Prevention techniques include consistent lock ordering (always acquire
locks in the same sequence), using timeout mechanisms with tryLock(), and avoiding nested
locks [16] .
16. How to detect thread deadlock in Java?
Use jstack command-line tool with the process ID to analyze thread dumps and detect
deadlocks [17] . The tool shows detailed information about locked objects and which threads are
waiting for which resources [17] . Java monitoring tools like JVisualVM can also detect and
visualize deadlock situations [17] .
17. Explain livelock with an example.
Livelock occurs when threads are not blocked but too busy responding to each other to make
progress [18] . Example: Two polite diners passing a spoon back and forth, each insisting the
other eat first, creating an infinite loop without actual progress [18] . Unlike deadlock where
threads are frozen, livelock threads remain active but unproductive [19] .
18. What is false sharing?
False sharing occurs when two threads on different CPUs write to different variables stored
within the same CPU cache line [20] . When one thread modifies its variable, the entire cache line
is invalidated in other CPU caches, forcing unnecessary reloads even for unrelated variables [20] .
This can be avoided using the @Contended annotation to separate variables into different cache
lines [20] .

Advanced Concurrency
19. Difference between Callable and Runnable.
Runnable's run() method returns void and cannot throw checked exceptions, while Callable's
call() method returns a generic type T and can throw checked exceptions [21] . Callable is more
flexible for operations that need to return results or handle checked exceptions like I/O
operations [21] .
20. What is a Future and CompletableFuture?
Future represents the result of an asynchronous computation, allowing you to check completion
status and retrieve results [22] . CompletableFuture extends Future with additional capabilities like
manual completion, chaining operations, and combining multiple futures without blocking [22] .
CompletableFuture enables non-blocking asynchronous programming with method chaining [22] .

21. How does ExecutorService work?


ExecutorService provides a flexible framework for asynchronous task execution by abstracting
thread management complexities [23] . It accepts Runnable or Callable tasks through methods
like execute() and submit(), managing thread pools internally [23] . Key methods include
shutdown() for orderly termination and awaitTermination() for waiting until all tasks complete [23] .

22. How is ForkJoinPool different from ThreadPoolExecutor?


ForkJoinPool is optimized for divide-and-conquer algorithms using work-stealing, where idle
threads steal tasks from busy threads' queues. ThreadPoolExecutor uses a shared work queue
where all threads compete for tasks. ForkJoinPool is better for recursive tasks that can be
broken down into smaller subtasks.
23. What is work stealing in ForkJoinPool?
Work stealing is a mechanism where idle threads steal tasks from the work queues of busy
threads. Each thread maintains its own double-ended queue (deque), adding tasks to one end
and removing from the other. When a thread's queue is empty, it steals tasks from the tail of
other threads' queues, improving load balancing.
24. Explain CountDownLatch vs CyclicBarrier.
CountDownLatch allows one or more threads to wait until a set of operations completes, counting
down from an initial value and cannot be reused. CyclicBarrier allows a set of threads to wait for
each other to reach a common barrier point and can be reused after all threads arrive.
CountDownLatch is for waiting for events, while CyclicBarrier is for coordinating threads.

25. What is a Phaser?


Phaser is a
flexible synchronization barrier that supports multiple phases of execution and
dynamic registration/deregistration of parties. Unlike CyclicBarrier, it doesn't require a fixed
number of threads and can handle varying numbers of participants across phases. It's useful for
parallel algorithms with multiple stages.
26. What is the role of Semaphore?
Semaphore controls access to aresource pool by maintaining a set of permits. Threads acquire
permits before accessing resources and release them when done. It's useful for limiting the
number of concurrent connections, database connections, or any shared resource with capacity
constraints.
27. How does ReadWriteLock work?
ReadWriteLock allows multiple threads to read simultaneously but exclusive access for writing.
Multiple readers can hold the lock concurrently, but writers must wait for all readers to finish and
have exclusive access. This improves performance for read-heavy workloads compared to
exclusive locks.
28. Explain how CopyOnWriteArrayList works.
CopyOnWriteArrayList creates a new copy of the underlying array for every write operation while
reads access the current array without synchronization. This provides thread-safety with
excellent read performance but expensive write operations. It's ideal for scenarios with many
reads and few writes.
29. When would you use ConcurrentLinkedQueue?
Use ConcurrentLinkedQueue for high-throughput scenarios requiring non-blocking, thread-safe
queue operations. It's suitable for producer-consumer patterns where multiple threads add and
remove elements concurrently without blocking. It provides better performance than
synchronized alternatives for concurrent access patterns.
30. Difference between busy-waiting and blocking.
Busy-waiting (spinning) continuously checks a condition in a loop, consuming CPU cycles while
waiting. Blocking puts the thread to sleep until a condition is met, releasing CPU resources.
Busy-waiting offers lower latency but wastes CPU, while blocking conserves resources but has
higher wake-up overhead.

Memory Management & Performance


31. What are Java memory leaks and how to detect them?
Java memory leaks occur when objects are referenced but no longer used, preventing garbage
collection. Common causes include static collections, listener registrations, and unclosed
resources. Detection tools include heap dumps, profilers like JProfiler, and monitoring
OutOfMemoryError patterns.
32. Describe different memory areas in JVM.
JVM memory includes: Heap (Young Generation with Eden and Survivor spaces, Old
Generation), Method Area/Metaspace (class metadata), Stack (per-thread method calls and
local variables), PC Register (current instruction pointer), and Native Method Stack (native
method calls).
33. How does escape analysis help performance?
Escape analysis determines if objects created within a method escape the method's scope. If
objects don't escape, the JVM can perform optimizations like stack allocation instead of heap
allocation, scalar replacement (breaking objects into primitive variables), and lock elimination for
synchronized blocks.
34. What is lock coarsening and lock elision?
Lock coarsening combines multiple adjacent synchronized blocks into a single larger block to
reduce lock acquisition overhead. Lock elision removes synchronization when the JVM
determines that a lock is not actually needed (e.g., when an object doesn't escape a single
thread).
35. What is biased locking?
Biased locking is a JVM optimization that assumes a lock will be acquired by the same thread
repeatedly. The lock becomes "biased" toward that thread, allowing faster acquisition without
atomic operations. If another thread tries to acquire the lock, the bias is revoked and normal
locking resumes.

Thread Management
36. What are daemon vs user threads?
User threads keep the JVM alive until they complete, while daemon threads don't prevent JVM
shutdown. The JVM exits when all user threads finish, regardless of running daemon threads.
Daemon threads are typically used for background services like garbage collection or
monitoring.
37. How does thread priority work in Java?
Thread priority is a hint to the thread scheduler about the relative importance of threads, ranging
from 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY). However, priority behavior is platform-
dependent and not guaranteed. Modern JVMs often ignore priorities in favor of fair scheduling
algorithms.
38. Explain Thread.sleep() vs wait().
Thread.sleep() pauses the current thread for a specified time without releasing locks, while
wait() releases the object's monitor and waits for notify()/notifyAll(). sleep() is static and can
be called anywhere, while wait() must be called within synchronized blocks and is used for
inter-thread communication.
39. What is spurious wakeup?
Spurious wakeup occurs when a thread waiting on wait() wakes up without being explicitly
notified. This can happen due to system interrupts or JVM optimizations. Always use wait() in a
loop checking the condition to handle spurious wakeups properly.
40. How do you ensure visibility between threads?
Ensure visibility using volatile keywords for simple variables, synchronized blocks for complex
operations, atomic classes for lock-free operations, or higher-level concurrency utilities like
CountDownLatch and CyclicBarrier. These mechanisms create memory barriers ensuring changes
are visible across threads.

Advanced Threading
41. What is a thread pool leak and how to prevent it?
Thread pool leaks occur when threads are created but not properly shut down, or when tasks
hold references preventing garbage collection. Prevent by always calling shutdown() or
shutdownNow() on ExecutorService, using try-with-resources, and avoiding circular references in
tasks.
42. How do you handle uncaught exceptions in threads?
Set an UncaughtExceptionHandler using Thread.setUncaughtExceptionHandler() or
Thread.setDefaultUncaughtExceptionHandler() for global handling. For thread pools, handle
exceptions within tasks or use Future.get() to retrieve exceptions from submitted tasks.
43. Write a custom thread pool.

public class CustomThreadPool {


private final BlockingQueue<Runnable> taskQueue;
private final List<WorkerThread> threads;
private volatile boolean isShutdown = false;

public CustomThreadPool(int poolSize, int queueSize) {


taskQueue = new LinkedBlockingQueue<>(queueSize);
threads = new ArrayList<>(poolSize);

for (int i = 0; i < poolSize; i++) {


WorkerThread worker = new WorkerThread();
threads.add(worker);
worker.start();
}
}

public void submit(Runnable task) {


if (isShutdown) throw new IllegalStateException("Pool is shutdown");
try {
taskQueue.put(task);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

public void shutdown() {


isShutdown = true;
for (WorkerThread thread : threads) {
thread.interrupt();
}
}

private class WorkerThread extends Thread {


public void run() {
while (!isShutdown) {
try {
Runnable task = taskQueue.take();
task.run();
} catch (InterruptedException e) {
break;
}
}
}
}
}

44. How to handle blocking IO in a multithreaded system?


Use separate thread pools for IO-bound tasks, implement asynchronous IO with NIO/NIO.2, use
reactive programming frameworks like RxJava, or implement timeout mechanisms. Consider
using CompletableFuture for non-blocking operations and proper resource management.
45. How do you design a thread-safe LRU cache?

public class ThreadSafeLRUCache<K, V> {


private final int capacity;
private final Map<K, Node<K, V>> cache;
private final Node<K, V> head, tail;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

public ThreadSafeLRUCache(int capacity) {


this.capacity = capacity;
this.cache = new HashMap<>();
this.head = new Node<>(null, null);
this.tail = new Node<>(null, null);
head.next = tail;
tail.prev = head;
}

public V get(K key) {


lock.readLock().lock();
try {
Node<K, V> node = cache.get(key);
if (node != null) {
moveToHead(node);
return node.value;
}
return null;
} finally {
lock.readLock().unlock();
}
}
public void put(K key, V value) {
lock.writeLock().lock();
try {
Node<K, V> existing = cache.get(key);
if (existing != null) {
existing.value = value;
moveToHead(existing);
} else {
Node<K, V> newNode = new Node<>(key, value);
if (cache.size() >= capacity) {
removeLRU();
}
cache.put(key, newNode);
addToHead(newNode);
}
} finally {
lock.writeLock().unlock();
}
}

// Helper methods for doubly-linked list operations


private void moveToHead(Node<K, V> node) {
removeNode(node);
addToHead(node);
}

private void addToHead(Node<K, V> node) {


node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}

private void removeNode(Node<K, V> node) {


node.prev.next = node.next;
node.next.prev = node.prev;
}

private void removeLRU() {


Node<K, V> lru = tail.prev;
cache.remove(lru.key);
removeNode(lru);
}

static class Node<K, V> {


K key;
V value;
Node<K, V> prev, next;

Node(K key, V value) {


this.key = key;
this.value = value;
}
}
}
46. What is optimistic vs pessimistic locking?
Pessimistic locking assumes conflicts will occur and locks resources preemptively using
mechanisms like synchronized or database row locks. Optimistic locking assumes conflicts are
rare and uses versioning or timestamps to detect conflicts during updates, only failing if conflicts
occur.
47. What are the pros/cons of lock-free programming?
Pros: Higher performance, no deadlocks, better scalability, reduced context switching. Cons:
Complex implementation, ABA problem, memory ordering issues, difficult debugging, platform-
dependent behavior. Lock-free programming requires deep understanding of memory models
and atomic operations.
48. How does StampedLock differ from ReadWriteLock?
StampedLock provides optimistic read locks that don't block writers, allowing better performance
for read-heavy workloads. It returns stamps for lock acquisition that must be validated before
use. Unlike ReadWriteLock, it supports upgrading read locks to write locks and offers try-
optimistic reads.
49. What is a race condition and how to avoid it?
A race condition occurs when multiple threads access shared data concurrently and the
outcome depends on thread scheduling. Avoid using synchronization mechanisms (synchronized,
volatile, atomic classes), proper locking strategies, or thread-safe data structures. Always
protect shared mutable state.
50. Tools for analyzing thread dumps and deadlocks.
Use jstack for generating thread dumps, jcmd for JVM diagnostics, JVisualVM for visual
analysis, Eclipse MAT for memory analysis, and JConsole for monitoring. Commercial tools
include JProfiler, YourKit, and AppDynamics for advanced analysis capabilities.

📊 Spring / Spring Boot / API Design – Top 50 Questions

Spring Framework Fundamentals


1. What is Spring Framework and its core features?
Spring Framework is an open-source application framework providing comprehensive
infrastructure support for Java applications [24] . Core features include Dependency Injection (DI)
for loose coupling, Aspect-Oriented Programming (AOP) for cross-cutting concerns,
comprehensive data access support, and modular architecture [25] . Spring focuses on enterprise
application "plumbing" so teams can concentrate on business logic [24] .
2. Explain Spring Bean lifecycle.
Spring Bean lifecycle includes instantiation, dependency injection, initialization, usage, and
destruction phases [26] . The container manages bean creation, calls initialization methods like
@PostConstruct, and destruction methods like @PreDestroy [26] . The lifecycle allows developers to
hook into various stages for custom initialization and cleanup logic [26] .
3. Differences between @Component, @Service, @Repository, and @Controller.
@Component is a generic stereotype for Spring-managed components, while @Service,
@Repository, and @Controller are specializations with specific purposes [27] . @Service indicates
business layer components, @Repository marks persistence layer components with exception
translation, and @Controller designates presentation layer components [27] . All are functionally
equivalent but provide semantic meaning and potential future enhancements [27] .
4. What is Dependency Injection? Types?
Dependency Injection is a design pattern where dependencies are provided to objects rather
than created internally [28] . Types include Constructor Injection (immutable, recommended),
Setter Injection (optional dependencies), and Field Injection (convenient but harder to test) [28] .
Constructor injection promotes immutability and easier testing [28] .
5. What are the different scopes of a Spring bean?
Spring supports five bean scopes: Singleton (default, one instance per container), Prototype
(new instance per request), Request (one per HTTP request), Session (one per HTTP session),
and Global-Session (one per global HTTP session) [29] . Web-aware scopes are only available in
web contexts [29] .

Spring Boot
6. Difference between field and constructor injection.
Constructor injection creates immutable objects and ensures all dependencies are provided at
creation time, making testing easier. Field injection is convenient but makes testing harder since
dependencies can only be injected by the framework. Constructor injection is generally
preferred for mandatory dependencies.
7. What is a @Qualifier?
@Qualifier is used when multiple beans of the same type exist and you need to specify which
one to inject. It works with @Autowired to disambiguate between candidates. You can create
custom qualifiers or use bean names as qualifiers.
8. What is @Primary annotation used for?
@Primary indicates which bean should be given preference when multiple candidates exist for
autowiring. It's an alternative to @Qualifier when you want to designate a default choice among
multiple beans of the same type.
9. What are the key annotations in Spring Boot?
Key annotations include @SpringBootApplication (combines @Configuration,
@EnableAutoConfiguration, @ComponentScan), @RestController, @RequestMapping, @Autowired,
@Value, @ConfigurationProperties, @Profile, and @Conditional annotations for auto-configuration.

10. Explain Spring Boot auto-configuration.


Auto-configuration automatically configures Spring applications based on classpath
dependencies and existing beans. It uses @Conditional annotations to determine when to apply
configurations. Auto-configuration can be excluded using @EnableAutoConfiguration(exclude={})
or disabled entirely.
11. How does Spring Boot resolve dependencies?
Spring Boot resolves dependencies through its starter POMs, which provide curated
dependency sets. The dependency management plugin ensures compatible versions. Boot also
provides dependency resolution through its auto-configuration mechanism and classpath
scanning.
12. How does Spring manage transactions?
Spring provides declarative transaction management through @Transactional annotations and
programmatic transaction management through TransactionTemplate. It supports various
transaction managers and provides transaction propagation, isolation levels, and rollback rules.
13. What is the use of @Transactional?
@Transactional enables declarative transaction management on methods or classes. It supports
properties like propagation behavior, isolation levels, timeout, read-only settings, and rollback
rules for specific exceptions. It can be applied at class or method level.
14. What is propagation in transactions?
Transaction propagation defines how transactions behave when called from within existing
transactions. Types include REQUIRED (join existing or create new), REQUIRES_NEW (always
create new), SUPPORTS (join if exists), MANDATORY (must have existing), and NEVER (fail if
transaction exists).
15. Difference between checked and unchecked exceptions in Spring.
Checked exceptions must be declared in method signatures and handled explicitly. Unchecked
exceptions (RuntimeException subclasses) don't require explicit handling. Spring's
@Transactional rolls back only for unchecked exceptions by default, but can be configured for
checked exceptions.

API Design & REST


16. How to handle exceptions globally in Spring Boot?
Use @ControllerAdvice or @RestControllerAdvice to handle exceptions globally across all
controllers. Combine with @ExceptionHandler methods to handle specific exception types. This
centralizes exception handling and provides consistent error responses.
17. How does Spring Security work?
Spring Security provides authentication and authorization through filters, security contexts, and
security configurations. It uses SecurityFilterChain to intercept requests, authenticate users, and
authorize access based on roles and permissions. It supports various authentication
mechanisms.
18. What is JWT and how is it used in Spring Security?
JWT (JSON Web Token) is a compact, URL-safe token format for securely transmitting
information. In Spring Security, JWTs are used for stateless authentication, containing user
information and signatures. They eliminate the need for server-side session storage.
19. What is OAuth2 and how to implement in Spring Boot?
OAuth2 is an authorization framework allowing third-party applications to access resources on
behalf of users. Spring Boot implements OAuth2 through Spring Security OAuth2, supporting
authorization code, client credentials, and resource owner password flows.
20. How do you version REST APIs?
API versioning strategies include URL versioning (/api/v1/users), header versioning (Accept:
application/vnd.api.v1+json), parameter versioning (?version=1), and media type versioning.
Choose based on client requirements and backward compatibility needs.
21. What are idempotent methods in REST?
Idempotent methods produce the same result when called multiple times with identical
parameters. GET, PUT, DELETE, HEAD, and OPTIONS are idempotent, while POST is not.
Idempotency is crucial for reliability and retry mechanisms.
22. Explain HTTP status codes commonly used.
Common status codes include: 200 (OK), 201 (Created), 204 (No Content), 400 (Bad Request),
401 (Unauthorized), 403 (Forbidden), 404 (Not Found), 409 (Conflict), 500 (Internal Server
Error), and 503 (Service Unavailable).
23. Difference between PUT and PATCH.
PUT replaces the entire resource with the provided data (complete update), while PATCH
applies partial modifications to the resource. PUT is idempotent and requires the complete
resource representation, while PATCH is for partial updates.
24. How to handle validation in REST APIs?
Use Bean Validation annotations (@Valid, @NotNull, @Size, @Email) on request objects. Spring Boot
automatically validates annotated objects and returns 400 Bad Request with validation errors.
Custom validators can be created for complex validation logic.
25. How to use @RestControllerAdvice?
@RestControllerAdvice combines @ControllerAdvice and @ResponseBody for global exception
handling in REST APIs. It handles exceptions across all controllers and returns JSON responses.
Use with @ExceptionHandler methods for specific exception types.
26. Explain HATEOAS.
HATEOAS (Hypertext as the Engine of Application State) is a REST constraint where responses
include links to related resources and available actions. Spring HATEOAS provides support for
creating hypermedia-driven REST services with embedded links and resource representations.

Configuration & Environment


27. What are different ways to read properties in Spring Boot?
Property reading methods include @Value annotations, @ConfigurationProperties classes,
Environment bean injection, and @PropertySource annotations. Properties can come from
application.properties, YAML files, environment variables, and command-line arguments.
28. How do you profile different environments in Spring?
Use @Profile annotations on beans and configurations to activate them for specific
environments. Set active profiles using spring.profiles.active property. Profiles enable
environment-specific configurations for development, testing, and production.
29. What is Spring Actuator?
Spring Actuator provides production-ready features like health checks, metrics, environment
information, and application monitoring endpoints. It exposes management endpoints
(/actuator/health, /actuator/metrics) for monitoring and managing applications in production.
30. What is Spring DevTools?
Spring DevTools provides development-time features like automatic restarts, live reload,
configurations for enhanced development experience, and remote debugging capabilities. It's
automatically disabled in production environments.

Testing
31. How to write unit tests for controllers and services?
Use @WebMvcTest for controller testing with MockMvc, @MockBean for mocking dependencies, and
@Test for service testing. Test controllers with @AutoConfigureTestDatabase for repository testing
and @SpringBootTest for integration testing.
32. How does MockMvc work?
MockMvc provides a server-side testing framework for Spring MVC applications without starting
a full HTTP server. It performs requests and assertions on responses, supporting JSON path
expressions, status code verification, and content matching.
33. Difference between @MockBean and @Mock.
@MockBean is Spring Boot's annotation for adding mock beans to the application context, while
@Mock is Mockito's annotation for creating mock objects. @MockBean replaces beans in the Spring
context, while @Mock creates standalone mocks.

Advanced Spring Features


34. How do you create a custom Spring Boot starter?
Create a custom starter by defining auto-configuration classes with @Configuration and
@ConditionalOn* annotations, creating a META-INF/spring.factories file, and packaging as a JAR.
Include dependencies and configuration properties for easy integration.
35. What is Spring Data JPA?
Spring Data JPA provides repository abstraction over JPA, reducing boilerplate code through
method name conventions, custom query methods, and automatic CRUD operations. It supports
pagination, sorting, and custom repository implementations.
36. Explain JPQL vs native queries.
JPQL (Java Persistence Query Language) is object-oriented and database-independent,
operating on entity objects. Native queries use database-specific SQL and operate on database
tables. JPQL provides portability while native queries offer database-specific optimizations.
37. What is entity lifecycle in JPA?
JPA entity lifecycle includes New (transient), Managed (persistent), Detached (no longer
managed), and Removed (marked for deletion) states. Lifecycle callbacks (@PrePersist,
@PostLoad, etc.) allow custom logic during state transitions.

38. How do you optimize JPA for performance?


Optimization techniques include using fetch joins, lazy loading strategies, query optimization,
proper indexing, connection pooling, caching (first-level and second-level), batch processing,
and avoiding N+1 query problems.
39. What are DTOs and how are they used?
DTOs (Data Transfer Objects) are simple objects for transferring data between layers or
services. They decouple internal entity structures from external APIs, provide data validation,
and enable API versioning without affecting internal models.
40. How do you secure endpoints in Spring REST?
Secure endpoints using Spring Security with authentication mechanisms, role-based
authorization (@PreAuthorize, @Secured), method-level security, CORS configuration, and HTTPS
enforcement. Configure security through SecurityFilterChain.
Infrastructure & Deployment
41. What is a filter and interceptor in Spring?
Filters operate at the servlet level, processing all requests before they reach Spring components.
Interceptors operate at Spring MVC level, allowing pre-processing, post-processing, and after-
completion handling. Interceptors have access to Spring context.
42. What is circuit breaker and how to implement?
Circuit breaker prevents cascading failures by monitoring service calls and opening the circuit
when failure rates exceed thresholds. Implement using Netflix Hystrix, Resilience4j, or Spring
Cloud Circuit Breaker with fallback methods.
43. How do you implement caching in Spring?
Enable caching with @EnableCaching and use @Cacheable, @CachePut, and @CacheEvict annotations.
Spring supports various cache providers like EhCache, Redis, and Caffeine. Configure cache
managers and customize cache behavior.
44. What is @Async in Spring?
@Async enables asynchronous method execution in separate threads. Configure with
@EnableAsync and provide TaskExecutor beans. Methods return Future, CompletableFuture, or
void. Use for long-running operations without blocking callers.
45. How does Spring Scheduling work?
Spring Scheduling allows periodic task execution using @Scheduled annotations with cron
expressions, fixed delays, or fixed rates. Enable with @EnableScheduling and configure
TaskScheduler for custom thread pools.
46. What is an embedded server in Spring Boot?
Spring Boot includes embedded servers (Tomcat, Jetty, Undertow) eliminating separate server
deployment. Applications run as standalone JARs with java -jar command. Embedded servers
simplify deployment and development workflows.
47. How do you deploy Spring Boot on cloud?
Deploy using containerization (Docker), cloud platforms (AWS, Azure, GCP), application
platforms (Heroku, Cloud Foundry), or serverless functions. Configure profiles, externalized
configuration, and health checks for cloud environments.
48. Explain the Spring Boot initialization process.
Spring Boot initialization involves: creating SpringApplication, loading configuration, determining
application type, creating ApplicationContext, loading auto-configurations, scanning for
components, and starting embedded servers. The process is customizable through
ApplicationRunner and CommandLineRunner.
49. How does Spring Boot support microservices architecture?
Spring Boot provides microservices support through Spring Cloud, service discovery (Eureka),
configuration management (Config Server), circuit breakers, API gateways, distributed tracing,
and containerization support.
50. Tools to monitor Spring Boot app in production.
Monitoring tools include Spring Boot Actuator, Micrometer metrics, APM solutions (New Relic,
AppDynamics), logging frameworks (Logback, Log4j), distributed tracing (Zipkin, Jaeger), and
infrastructure monitoring (Prometheus, Grafana).

🔖 Collections, Memory & Language Specifics – Top 50 Questions

Collection Framework Basics


1. Differences between List, Set, and Map.
List allows duplicate elements and maintains insertion order with indexed access. Set prohibits
duplicates and may or may not maintain order depending on implementation. Map stores key-
value pairs where keys are unique, providing fast lookup by key rather than index.
2. How does HashMap work internally?
HashMap uses an array of buckets where each bucket contains a linked list (or tree for high
collision counts) [30] . Hash function determines bucket index from key's hashCode, and collisions
are resolved through chaining [31] . Load factor triggers resizing when buckets become too
full [32] .
3. What are the differences between HashMap and Hashtable?
HashMap is unsynchronized and allows null keys/values, while Hashtable is synchronized and
doesn't allow nulls [33] . HashMap has default capacity of 16 vs Hashtable's 11, and HashMap
uses Iterator while Hashtable uses Enumerator [33] . HashMap extends AbstractMap while
Hashtable extends Dictionary [33] .
4. Why ConcurrentHashMap doesn't allow null keys?
ConcurrentHashMap doesn't allow null keys because in concurrent environments, if get(key)
returns null, you can't determine if the key maps to null or if the key doesn't exist [34] . This
ambiguity could cause race conditions where a key might be removed by another thread
between containsKey() and get() calls [34] .
5. How does LinkedHashMap maintain order?
LinkedHashMap maintains a doubly-linked list of entries in addition to the hash table
structure [35] . Each entry has before/after pointers creating a chain that preserves insertion order
or access order [35] . This allows predictable iteration while maintaining HashMap's O(1)
performance [35] .
6. What is a TreeMap and how does it maintain order?
TreeMap implements NavigableMap using a Red-Black tree structure to maintain keys in sorted
order [36] . It sorts keys according to their natural ordering (Comparable) or a provided
Comparator [36] . TreeMap provides O(log n) performance for containsKey, get, put, and remove
operations [36] .

Collection Implementations
7. What is the difference between ArrayList and LinkedList?
ArrayList uses dynamic arrays providing O(1) random access but O(n) insertion/deletion in
middle. LinkedList uses doubly-linked nodes providing O(1) insertion/deletion but O(n) random
access. ArrayList is better for read-heavy operations, LinkedList for frequent
insertions/deletions.
8. Explain how HashSet ensures uniqueness.
HashSet uses HashMap internally, storing elements as keys with a dummy value. Uniqueness is
ensured through the underlying HashMap's key uniqueness constraint, using hashCode() and
equals() methods to identify duplicates during insertion.
9. Difference between equals() and hashCode().
equals() determines object equality semantically, while hashCode() provides integer hash values
for hash-based collections. Objects that are equal must have the same hashCode, but objects
with same hashCode aren't necessarily equal. Both must be overridden together for proper
collection behavior.
10. What is Comparable vs Comparator?
Comparable provides natural ordering through compareTo() method implemented by the class
itself. Comparator provides external ordering through compare() method in a separate class. Use
Comparable for default ordering, Comparator for custom or multiple orderings.

Specialized Collections
11. When to use EnumSet?
Use EnumSet for efficient storage and operations on enum values. It's implemented as bit
vectors providing excellent performance and memory efficiency. EnumSet operations are much
faster than regular Set implementations for enum elements.
12. How does CopyOnWriteArrayList work?
CopyOnWriteArrayList creates a new array copy for every write operation while reads access
the current array without synchronization. This provides thread-safety with excellent read
performance but expensive writes. Ideal for read-heavy, write-light scenarios.
13. When to use WeakHashMap?
Use WeakHashMap when you want entries to be automatically removed when keys are no
longer referenced elsewhere. Keys are held by weak references, allowing garbage collection
when no strong references exist. Useful for caches and memory-sensitive applications.
14. What is IdentityHashMap?
IdentityHashMap uses reference equality (==) instead of object equality (equals()) for key
comparison. It's useful when you need to distinguish between objects that are equal in content
but different in identity, such as in serialization frameworks.
15. What are fail-fast and fail-safe iterators?
Fail-fast iterators throw ConcurrentModificationException when collection is modified during
iteration (ArrayList, HashMap). Fail-safe iterators work on collection copies and don't throw
exceptions but may not reflect recent changes (CopyOnWriteArrayList, ConcurrentHashMap).

Concurrent Collections
16. How does ConcurrentSkipListMap maintain thread safety?
ConcurrentSkipListMap uses lock-free algorithms with atomic operations and skip list data
structure. It provides expected O(log n) performance for most operations while allowing
concurrent access without blocking. It maintains sorted order and implements NavigableMap.
17. Difference between capacity and size in collections.
Size represents the actual number of elements currently in the collection. Capacity represents
the maximum number of elements the collection can hold before resizing. ArrayList capacity
grows automatically, while HashMap capacity affects performance due to load factor.
18. How to prevent memory leaks with collections?
Prevent memory leaks by removing unused elements, using weak references when appropriate,
clearing collections when no longer needed, avoiding static collections with growing data, and
properly managing listener registrations and callbacks.

Memory Management
19. What is object pooling?
Object pooling reuses expensive objects instead of creating new ones, reducing garbage
collection overhead. Common for database connections, threads, and heavy objects. Implement
using existing pools (Apache Commons Pool) or custom implementations with proper
synchronization.
20. Explain soft, weak, and phantom references.
Soft references are collected when memory is low, useful for caches. Weak references are
collected during any GC cycle, useful for canonicalizing mappings. Phantom references are
collected before finalization, useful for cleanup actions. All allow objects to be garbage
collected.
String Handling
21. What is the String pool?
String pool (intern pool) is a special memory area storing unique String literals to save memory
through sharing. String.intern() moves strings to the pool. Literal strings automatically go to the
pool, while new String() creates heap objects.
22. What is autoboxing and unboxing?
Autoboxing automatically converts primitives to wrapper objects (int to Integer), while unboxing
converts wrapper objects to primitives. This happens automatically in assignments, method
calls, and expressions, but can impact performance in loops and collections.
23. What are wrapper classes in Java?
Wrapper classes (Integer, Double, Boolean, etc.) provide object representations of primitive
types. They enable primitives to be used in collections, provide utility methods, support null
values, and enable autoboxing/unboxing.
24. Difference between == and equals().
== compares references for objects and values for primitives. equals() compares object
content/value as defined by the class implementation. For proper object comparison, always use
equals() and ensure it's properly overridden with hashCode().

Functional Programming
25. What are functional interfaces?
Functional interfaces have exactly one abstract method and can be used with lambda
expressions. Examples include Runnable, Callable, Comparator, and custom interfaces.
@FunctionalInterface annotation ensures single abstract method constraint.
26. What is the default method in interfaces?
Default methods provide implementation in interfaces using 'default' keyword. They enable
interface evolution without breaking existing implementations. Multiple inheritance conflicts are
resolved through explicit overriding or super calls.
27. What is the use of Optional class?
Optional represents potentially absent values, avoiding null pointer exceptions. It provides
methods like isPresent(), get(), orElse(), map(), and filter() for safe value handling. Use instead of
returning null from methods.
String Performance
28. Difference between StringBuilder and StringBuffer.
StringBuilder is not thread-safe but faster for single-threaded operations. StringBuffer is thread-
safe (synchronized methods) but slower due to synchronization overhead. Both provide mutable
string operations avoiding immutable String concatenation overhead.
29. How does the intern() method work?
intern() returns canonical representation from string pool. If string exists in pool, returns existing
reference; otherwise, adds string to pool and returns it. Reduces memory usage for frequently
used strings but can cause memory leaks if overused.

Advanced Collections
30. How are generics implemented at runtime?
Generics use type erasure - generic type information is removed at runtime for backward
compatibility. Raw types replace parameterized types, with casts inserted automatically. This
enables generics to work with legacy code but limits runtime type information.
31. What is type erasure?
Type erasure removes generic type information during compilation, replacing type parameters
with their bounds (Object if unbounded). Bridge methods maintain polymorphism, and casts are
inserted automatically. This enables backward compatibility but prevents runtime generic type
checking.
32. How does ArrayDeque differ from LinkedList?
ArrayDeque uses resizable arrays and is more efficient for queue/stack operations with better
cache locality. LinkedList uses doubly-linked nodes with pointer overhead. ArrayDeque prohibits
null elements while LinkedList allows them.
33. How does PriorityQueue order elements?
PriorityQueue maintains elements in heap order using natural ordering (Comparable) or provided
Comparator. The head is always the smallest element according to ordering. It's not sorted but
maintains partial ordering for efficient priority-based retrieval.
34. Difference between Stack and Deque.
Stack is legacy class with synchronization overhead, while Deque interface provides double-
ended queue operations. ArrayDeque implements Deque more efficiently than Stack. Deque
supports operations at both ends, while Stack only supports LIFO operations.
35. How to make collections immutable?
Create immutable collections using Collections.unmodifiableList(), Guava's ImmutableList, or
copying constructors with defensive copying. Java 9+ provides List.of(), Set.of(), Map.of() for
immutable collections. Ensure contained objects are also immutable.

Iterator and Streaming


36. What is Spliterator?
Spliterator enables parallel iteration over collection elements. It can split itself for parallel
processing and provides characteristics like ORDERED, DISTINCT, SORTED. Used internally by
parallel streams but can be customized for specific collection types.
37. How do you create custom collections?
Extend AbstractList, AbstractSet, or AbstractMap for easier implementation. Implement required
methods like size(), get(), iterator(). Consider thread-safety, performance characteristics, and
proper equals()/hashCode() implementation.
38. How does Collections.synchronizedList work?
Collections.synchronizedList() wraps the original list with synchronized methods. All access must
be synchronized, including iteration which requires manual synchronization blocks. It provides
thread-safety but not performance benefits of concurrent collections.

Specialized Maps
39. What is EnumMap?
EnumMap is a specialized Map implementation for enum keys using arrays internally. It provides
excellent performance, maintains natural enum ordering, and is more memory-efficient than
general-purpose maps for enum keys.
40. What is a NavigableMap?
NavigableMap extends SortedMap with navigation methods like lowerKey(), floorKey(),
ceilingKey(), higherKey(). It provides reverse iteration and subset views. TreeMap and
ConcurrentSkipListMap implement NavigableMap.
41. Difference between subList() and new ArrayList<>(subList()).
subList() returns a view backed by original list - changes affect both lists. new ArrayList<>
(subList()) creates independent copy - changes don't affect original. Views are more memory-
efficient but less safe for modifications.

Resource Management
42. Explain try-with-resources.
Try-with-resources automatically manages resources implementing AutoCloseable. Resources
are closed automatically in reverse order of declaration, even if exceptions occur. It replaces
explicit finally blocks for resource cleanup.
43. What is the role of finalize()?
finalize() is called by garbage collector before object destruction but is deprecated and
unreliable. It has unpredictable timing, performance overhead, and can prevent garbage
collection. Use try-with-resources or explicit cleanup methods instead.

Memory Architecture
44. How is memory managed in JVM?
JVM memory includes Heap (young/old generations), Method Area/Metaspace (class
metadata), Stack (thread-local method frames), PC Registers (instruction pointers), and Native
Method Stacks. Garbage collection manages heap memory automatically.
45. What are the GC roots in JVM?
GC roots are objects that are always reachable and include: local variables, static variables, JNI
references, monitor objects, and system class loader references. Objects reachable from GC
roots are not eligible for garbage collection.
46. How do you find memory leaks in Java?
Use heap dumps with tools like Eclipse MAT, JProfiler, or VisualVM. Monitor memory usage
patterns, analyze object retention, check for unclosed resources, and review static collections.
OutOfMemoryError often indicates memory leaks.
47. Tools used to profile memory in Java apps.
Memory profiling tools include JProfiler, YourKit, Eclipse MAT, VisualVM, JConsole, and async-
profiler. They provide heap analysis, allocation tracking, GC monitoring, and memory leak
detection capabilities.
48. Explain the structure of a Java object in memory.
Java objects consist of object header (mark word, class pointer), instance fields (primitives
inline, objects as references), and optional padding for alignment. Array objects include length
field. Object layout depends on JVM implementation and compression settings.
49. What is JVM tuning and how is it done?
JVM tuning optimizes performance through heap sizing (-Xms, -Xmx), garbage collector
selection (-XX:+UseG1GC), GC parameters, and monitoring. Analyze application behavior, GC
logs, and performance metrics to determine optimal settings.
50. Explain Metaspace and how it replaced PermGen.
Metaspace stores class metadata in native memory instead of heap, replacing PermGen in Java
8+. It grows automatically without fixed size limits, reducing OutOfMemoryError: PermGen space
issues. Class metadata is deallocated when classes are unloaded.

This comprehensive guide covers all 150 interview questions with detailed explanations, code
examples, and practical insights. Each answer provides the depth expected in technical
interviews while remaining concise and actionable. Good luck with your interview!

1. https://en.wikipedia.org/wiki/Java_memory_model
2. https://jenkov.com/tutorials/java-concurrency/java-memory-model.html
3. https://dev.to/adaumircosta/understanding-the-java-memory-model-jmm-p63
4. https://www.javamex.com/tutorials/synchronization_volatile.shtml
5. https://www.java67.com/2023/07/difference-between-reentrantlock-vs.html
6. https://www.codementor.io/@noelkamphoa/atomicinteger-class-in-java-2oh5icptfe
7. https://www.javacodegeeks.com/2020/12/threadlocal-in-java-example-program-and-tutorial.html
8. https://dzone.com/articles/garbage-collection-in-javajvm
9. https://www.techpaste.com/2011/09/garbage-collector-g1-concurrent-mark-sweep-collector-cms/
10. https://codingtechroom.com/question/understanding-memory-barriers-in-java
11. https://jenkov.com/tutorials/java-concurrency/java-happens-before-guarantee.html
12. https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html
13. https://stackoverflow.com/questions/63472450/why-is-happens-before-relationship-called-like-that
14. https://thisvsthat.io/runnable-vs-thread
15. https://www.netjstech.com/2017/10/thread-starvation-in-java-multi-threading.html
16. https://codesignal.com/learn/courses/java-concurrency-foundations/lessons/deadlocks-and-lock-mech
anisms
17. https://community.sap.com/t5/technology-blog-posts-by-sap/an-example-of-deadlock-detection-using
-jdk-standard-tool-jstack/ba-p/13234460
18. https://stackoverflow.com/questions/1036364/good-example-of-livelock
19. https://docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
20. https://www.youtube.com/watch?v=tLS85IfsbYE
21. https://www.linkedin.com/pulse/runnable-vs-callable-java-whats-difference-giovanni-caprio-m9j0f
22. https://pwrteams.com/content-hub/blog/async-programming-and-completablefuture-in-java
23. https://dzone.com/articles/deep-dive-into-java-executorservice
24. https://spring.io/projects/spring-framework
25. https://www.simplilearn.com/tutorials/spring-boot-tutorial/what-is-spring-framework-and-its-advantag
es
26. https://www.upgrad.com/blog/spring-bean-life-cycle-explained/
27. https://stackoverflow.com/questions/6827752/whats-the-difference-between-component-repository-se
rvice-annotations-in
28. https://keyholesoftware.com/what-is-dependency-injection-why-is-it-important-in-the-spring-framew
ork/
29. https://blog.eduonix.com/2018/01/learn-bean-scopes-spring-framework/
30. https://www.youtube.com/watch?v=xKCdp0jjZAw
31. https://www.linkedin.com/pulse/understanding-hashmap-java-internal-working-conflicts-kāshān-asim-
7rzrf
32. https://vivekbansal.substack.com/p/java-hashmap-internals
33. https://techdifferences.com/difference-between-hashmap-and-hashtable-in-java.html
34. http://javainterviewquestionswithanswer.blogspot.com/2016/12/why-concurrenthashmap-does-not-allo
w.html
35. https://blog.stackademic.com/understanding-linkedhashmap-in-java-internals-use-cases-and-impleme
ntation-79f3c15f3e84?gi=bfa1c280847e
36. https://www.baeldung.com/java-treemap

You might also like