Java Interview
Java Interview
1. How does the Java Memory Model (JMM) handle visibility and ordering?
● Answer: The JMM uses the "happens-before" relationship to guarantee that memory
writes by one specific statement are visible to another specific statement. Keywords like
volatile and synchronized enforce these memory barriers, preventing the CPU
from reordering instructions or caching stale values in local core caches.
● Answer: G1GC divides the heap into regions and prioritizes collecting regions with the
most garbage, aiming for predictable pause times. ZGC is a scalable, low-latency
collector that performs all expensive work (like compaction) concurrently, guaranteeing
pause times under a few milliseconds even on massive heaps (terabytes).
● Answer: Instead of locking the entire map, ConcurrentHashMap locks only a specific
segment or bucket (node) of the map during updates. This allows multiple threads to
read and write to different parts of the map simultaneously without blocking each other.
● Answer: Threads in a pool are reused, not destroyed. If a ThreadLocal variable is not
explicitly removed (using .remove()) after the task completes, the thread retains a
strong reference to the object, preventing the Garbage Collector from cleaning it up.
● Answer: It occurs when independent variables accessed by different threads share the
same CPU cache line. When one thread modifies its variable, the entire cache line is
invalidated across all cores, forcing other threads to unnecessarily reload the cache line
from main memory, killing performance.
● Answer: A deadlock occurs when two or more threads are blocked forever, waiting for
each other to release locks. Prevention involves always acquiring locks in a strict,
globally consistent order across all threads.
● Answer: map() transforms each element into a single new element (1-to-1).
flatMap() transforms each element into a stream of new elements, and then "flattens"
all those distinct streams into a single unified stream (1-to-N).
12. Why should you avoid stateful lambda expressions in Parallel Streams?
● Answer: Parallel streams split the data across multiple threads. If the lambda modifies a
shared external state (like adding to a non-thread-safe ArrayList), it leads to race
conditions, data corruption, and unpredictable results.
15. How do you handle Checked Exceptions inside a Stream map operation?
● Answer: It stands for "Splitable Iterator". It is the engine behind parallel streams,
designed to traverse elements and efficiently partition portions of the underlying data
source to be processed by different threads.
● Answer: IntStream works directly with primitive int values, avoiding the heavy
memory and performance overhead of auto-boxing and unboxing int primitives into
Integer objects.
● Answer: Streams evaluate elements vertically, not horizontally. One element goes
through the entire pipeline of intermediate operations before the next element starts,
which allows short-circuiting to work efficiently.
● Answer: No. Once a terminal operation (like collect, forEach, count) is executed,
the stream is considered consumed and closed. Attempting to reuse it throws an
IllegalStateException.
● Answer: The NameNode is the master server that manages the file system namespace
and metadata (where blocks are located). DataNodes are the worker nodes that actually
store and retrieve the raw data blocks.
22. How does the Shuffle and Sort phase work in MapReduce?
● Answer: After the Map phase, the output data is partitioned by key, sorted, and
transferred across the network to the appropriate Reducer nodes. This guarantees that
all values associated with a single key are processed by the same Reducer.
23. How do Kafka Consumer Groups handle partition assignment and scaling?
● Answer: Each partition in a Kafka topic can be consumed by exactly one consumer
within a specific consumer group. To scale consumption, you add more consumers to the
group, up to the total number of partitions.
● Answer: When a consumer joins, leaves, or crashes, Kafka revokes all partition
assignments and reassigns them among the currently active consumers in the group to
ensure all partitions are being read. Processing pauses during this phase.
25. Explain the Write-Ahead Log (WAL) in distributed systems like HDFS or databases.
● Answer: A WAL is an append-only file where modifications are recorded before they are
applied to the actual data structures. In the event of a crash, the system can replay the
WAL to recover uncommitted or unwritten data.
27. What memory eviction policies does Redis support when it runs out of RAM?
● Answer: Redis supports policies like noeviction (returns errors on writes),
allkeys-lru (evicts least recently used keys), volatile-lru (evicts LRU keys with
an expiration set), and allkeys-lfu (least frequently used).
● Answer: It analyzes text documents, splits them into individual tokens (words), filters out
stop words, applies stemming, and maps each unique token to a list of document IDs
where that token appears, enabling lightning-fast full-text searches.
● Answer: Split-brain occurs when a network partition causes a cluster to divide, and both
sides elect a master node, leading to data inconsistency. It is prevented by requiring a
strict quorum (majority) of master-eligible nodes to elect a leader.
● Answer: A hot partition happens when too many messages are routed to one partition
(e.g., heavily skewed keys). You solve it by modifying the partition key (salting it with a
random number) or using a custom partitioner to distribute the load more evenly.
● Answer: Use a highly available database (like Cassandra) to store the long URL
mapping. Generate unique short IDs using a Base62 encoding algorithm. Put a
distributed cache (Redis) in front of the database to handle heavy read traffic for popular
links.
32. Explain Consistent Hashing and why it is crucial for distributed caches.
● Answer: It maps both data keys and server nodes to a virtual ring. When a server is
added or removed, only a small fraction of keys are remapped (typically to the next node
on the ring), preventing a massive cache miss storm that occurs with standard modulo
hashing.
34. Describe the Token Bucket algorithm for API Rate Limiting.
● Answer: A bucket holds a maximum number of tokens. Tokens are added to the bucket
at a fixed rate. Each API request removes a token. If the bucket is empty, the request is
rejected. It allows for short bursts of traffic while enforcing an overall average rate.
● Answer: Command Query Responsibility Segregation. It splits the application into two
parts: one side handles writes/updates (Commands) optimized for transactional integrity,
and the other side handles reads (Queries) optimized for fast searching (often syncing
data to OpenSearch).
● Answer: Sharding is horizontal scaling at the database level. It partitions a large table
into smaller, faster, more easily managed pieces called shards, distributing the rows
across multiple database servers based on a Shard Key (e.g., user ID).
● Answer: It acts as the single entry point for all clients. It handles cross-cutting concerns
like authentication, SSL termination, rate limiting, request routing, and payload
aggregation, keeping these complexities out of the individual microservices.
● Answer: REST uses HTTP/1.1 and JSON, making it human-readable and widely
supported. gRPC uses HTTP/2 and Protocol Buffers (binary payload), making it
significantly faster, lighter, and strongly typed, ideal for internal service-to-service
communication.
43. What is the N+1 select problem in JPA, and how do you solve it?
● Answer: It occurs when you query a list of entities (1 query) and then access a
lazily-loaded association for each entity, triggering an additional query for every single
row (N queries). Solve it using JPQL JOIN FETCH or JPA @EntityGraph to fetch
everything in one query.
● Answer: REQUIRED (default) joins the existing active transaction; if the inner method
fails, the whole transaction rolls back. REQUIRES_NEW suspends the current transaction
and creates a completely independent transaction; its commit/rollback does not affect
the outer transaction.
● Answer: High-level modules should not depend on low-level modules; both should
depend on abstractions (interfaces). Abstractions should not depend on details; details
should depend on abstractions.
● Answer: An API is idempotent if making multiple identical requests has the same effect
as making a single request. GET, PUT, and DELETE are idempotent by nature, whereas
POST is not. It is critical for safely retrying failed network requests.
● Answer: Technical debt is a tool to ship faster, but it accrues "interest" in the form of
slower future development. I manage it by tracking it visibly in the sprint backlog,
advocating for the Boy Scout Rule (leave code better than you found it), and dedicating
a percentage of team capacity specifically to refactoring.
● Answer: The JMM uses the "happens-before" relationship to guarantee that memory
writes by one specific statement are visible to another specific statement. Keywords like
volatile and synchronized enforce these memory barriers, preventing the CPU
from reordering instructions or caching stale values in local core caches.
● Answer: G1GC divides the heap into regions and prioritizes collecting regions with the
most garbage, aiming for predictable pause times. ZGC is a scalable, low-latency
collector that performs all expensive work (like compaction) concurrently, guaranteeing
pause times under a few milliseconds even on massive heaps (terabytes).
● Answer: Instead of locking the entire map, ConcurrentHashMap locks only a specific
segment or bucket (node) of the map during updates. This allows multiple threads to
read and write to different parts of the map simultaneously without blocking each other.
● Answer: Threads in a pool are reused, not destroyed. If a ThreadLocal variable is not
explicitly removed (using .remove()) after the task completes, the thread retains a
strong reference to the object, preventing the Garbage Collector from cleaning it up.
● Answer: It occurs when independent variables accessed by different threads share the
same CPU cache line. When one thread modifies its variable, the entire cache line is
invalidated across all cores, forcing other threads to unnecessarily reload the cache line
from main memory, killing performance.
● Answer: A deadlock occurs when two or more threads are blocked forever, waiting for
each other to release locks. Prevention involves always acquiring locks in a strict,
globally consistent order across all threads.
● Answer: map() transforms each element into a single new element (1-to-1).
flatMap() transforms each element into a stream of new elements, and then "flattens"
all those distinct streams into a single unified stream (1-to-N).
12. Why should you avoid stateful lambda expressions in Parallel Streams?
● Answer: Parallel streams split the data across multiple threads. If the lambda modifies a
shared external state (like adding to a non-thread-safe ArrayList), it leads to race
conditions, data corruption, and unpredictable results.
15. How do you handle Checked Exceptions inside a Stream map operation?
● Answer: It stands for "Splitable Iterator". It is the engine behind parallel streams,
designed to traverse elements and efficiently partition portions of the underlying data
source to be processed by different threads.
● Answer: IntStream works directly with primitive int values, avoiding the heavy
memory and performance overhead of auto-boxing and unboxing int primitives into
Integer objects.
● Answer: Streams evaluate elements vertically, not horizontally. One element goes
through the entire pipeline of intermediate operations before the next element starts,
which allows short-circuiting to work efficiently.
● Answer: The NameNode is the master server that manages the file system namespace
and metadata (where blocks are located). DataNodes are the worker nodes that actually
store and retrieve the raw data blocks.
22. How does the Shuffle and Sort phase work in MapReduce?
● Answer: After the Map phase, the output data is partitioned by key, sorted, and
transferred across the network to the appropriate Reducer nodes. This guarantees that
all values associated with a single key are processed by the same Reducer.
23. How do Kafka Consumer Groups handle partition assignment and scaling?
● Answer: Each partition in a Kafka topic can be consumed by exactly one consumer
within a specific consumer group. To scale consumption, you add more consumers to the
group, up to the total number of partitions.
● Answer: When a consumer joins, leaves, or crashes, Kafka revokes all partition
assignments and reassigns them among the currently active consumers in the group to
ensure all partitions are being read. Processing pauses during this phase.
25. Explain the Write-Ahead Log (WAL) in distributed systems like HDFS or databases.
● Answer: A WAL is an append-only file where modifications are recorded before they are
applied to the actual data structures. In the event of a crash, the system can replay the
WAL to recover uncommitted or unwritten data.
27. What memory eviction policies does Redis support when it runs out of RAM?
● Answer: It analyzes text documents, splits them into individual tokens (words), filters out
stop words, applies stemming, and maps each unique token to a list of document IDs
where that token appears, enabling lightning-fast full-text searches.
● Answer: Split-brain occurs when a network partition causes a cluster to divide, and both
sides elect a master node, leading to data inconsistency. It is prevented by requiring a
strict quorum (majority) of master-eligible nodes to elect a leader.
● Answer: A hot partition happens when too many messages are routed to one partition
(e.g., heavily skewed keys). You solve it by modifying the partition key (salting it with a
random number) or using a custom partitioner to distribute the load more evenly.
32. Explain Consistent Hashing and why it is crucial for distributed caches.
● Answer: It maps both data keys and server nodes to a virtual ring. When a server is
added or removed, only a small fraction of keys are remapped (typically to the next node
on the ring), preventing a massive cache miss storm that occurs with standard modulo
hashing.
● Answer: Distributed transactions (2PC) are too slow. Instead, use the Saga Pattern
where each service executes a local transaction and emits an event (via Kafka). If a
downstream service fails, compensating events are fired to undo previous actions.
34. Describe the Token Bucket algorithm for API Rate Limiting.
● Answer: A bucket holds a maximum number of tokens. Tokens are added to the bucket
at a fixed rate. Each API request removes a token. If the bucket is empty, the request is
rejected. It allows for short bursts of traffic while enforcing an overall average rate.
● Answer: Command Query Responsibility Segregation. It splits the application into two
parts: one side handles writes/updates (Commands) optimized for transactional integrity,
and the other side handles reads (Queries) optimized for fast searching (often syncing
data to OpenSearch).
● Answer: Sharding is horizontal scaling at the database level. It partitions a large table
into smaller, faster, more easily managed pieces called shards, distributing the rows
across multiple database servers based on a Shard Key (e.g., user ID).
● Answer: It acts as the single entry point for all clients. It handles cross-cutting concerns
like authentication, SSL termination, rate limiting, request routing, and payload
aggregation, keeping these complexities out of the individual microservices.
● Answer: REST uses HTTP/1.1 and JSON, making it human-readable and widely
supported. gRPC uses HTTP/2 and Protocol Buffers (binary payload), making it
significantly faster, lighter, and strongly typed, ideal for internal service-to-service
communication.
43. What is the N+1 select problem in JPA, and how do you solve it?
● Answer: It occurs when you query a list of entities (1 query) and then access a
lazily-loaded association for each entity, triggering an additional query for every single
row (N queries). Solve it using JPQL JOIN FETCH or JPA @EntityGraph to fetch
everything in one query.
● Answer: REQUIRED (default) joins the existing active transaction; if the inner method
fails, the whole transaction rolls back. REQUIRES_NEW suspends the current transaction
and creates a completely independent transaction; its commit/rollback does not affect
the outer transaction.
● Answer: High-level modules should not depend on low-level modules; both should
depend on abstractions (interfaces). Abstractions should not depend on details; details
should depend on abstractions.
● Answer: An API is idempotent if making multiple identical requests has the same effect
as making a single request. GET, PUT, and DELETE are idempotent by nature, whereas
POST is not. It is critical for safely retrying failed network requests.
50. How do you approach Technical Debt?
● Answer: Technical debt is a tool to ship faster, but it accrues "interest" in the form of
slower future development. I manage it by tracking it visibly in the sprint backlog,
advocating for the Boy Scout Rule (leave code better than you found it), and dedicating
a percentage of team capacity specifically to refactoring.
The user is asking to convert the existing interview Q&A document into a more formal, book-like
structure, likely including a Table of Contents and an introduction, while keeping the existing
content.
Table of Contents
● Part 1: JVM Internals & Advanced Concurrency (Q1-Q10)
● Part 2: Java 8 Stream API & Functional Programming (Q11-Q20)
● Part 3: Big Data Ecosystem (Hadoop, Kafka, Redis, OpenSearch) (Q21-Q30)
● Part 4: System Architecture & Design (Q31-Q40)
● Part 5: Spring Ecosystem & Clean Code (Q41-Q50)
● Answer: The JMM uses the "happens-before" relationship to guarantee that memory
writes by one specific statement are visible to another specific statement. Keywords like
volatile and synchronized enforce these memory barriers, preventing the CPU
from reordering instructions or caching stale values in local core caches.
● Answer: G1GC divides the heap into regions and prioritizes collecting regions with the
most garbage, aiming for predictable pause times. ZGC is a scalable, low-latency
collector that performs all expensive work (like compaction) concurrently, guaranteeing
pause times under a few milliseconds even on massive heaps (terabytes).
● Answer: Instead of locking the entire map, ConcurrentHashMap locks only a specific
segment or bucket (node) of the map during updates. This allows multiple threads to
read and write to different parts of the map simultaneously without blocking each other.
● Answer: Threads in a pool are reused, not destroyed. If a ThreadLocal variable is not
explicitly removed (using .remove()) after the task completes, the thread retains a
strong reference to the object, preventing the Garbage Collector from cleaning it up.
● Answer: It occurs when independent variables accessed by different threads share the
same CPU cache line. When one thread modifies its variable, the entire cache line is
invalidated across all cores, forcing other threads to unnecessarily reload the cache line
from main memory, killing performance.
● Answer: A deadlock occurs when two or more threads are blocked forever, waiting for
each other to release locks. Prevention involves always acquiring locks in a strict,
globally consistent order across all threads.
● Answer: map() transforms each element into a single new element (1-to-1).
flatMap() transforms each element into a stream of new elements, and then "flattens"
all those distinct streams into a single unified stream (1-to-N).
12. Why should you avoid stateful lambda expressions in Parallel Streams?
● Answer: Parallel streams split the data across multiple threads. If the lambda modifies a
shared external state (like adding to a non-thread-safe ArrayList), it leads to race
conditions, data corruption, and unpredictable results.
15. How do you handle Checked Exceptions inside a Stream map operation?
● Answer: Lambdas in streams do not allow checked exceptions to be thrown outward.
You must either catch the exception inside the lambda block and wrap it in an unchecked
RuntimeException, or write a custom wrapper functional interface that handles the
exception.
● Answer: It stands for "Splitable Iterator". It is the engine behind parallel streams,
designed to traverse elements and efficiently partition portions of the underlying data
source to be processed by different threads.
● Answer: IntStream works directly with primitive int values, avoiding the heavy
memory and performance overhead of auto-boxing and unboxing int primitives into
Integer objects.
● Answer: Streams evaluate elements vertically, not horizontally. One element goes
through the entire pipeline of intermediate operations before the next element starts,
which allows short-circuiting to work efficiently.
● Answer: No. Once a terminal operation (like collect, forEach, count) is executed,
the stream is considered consumed and closed. Attempting to reuse it throws an
IllegalStateException.
22. How does the Shuffle and Sort phase work in MapReduce?
● Answer: After the Map phase, the output data is partitioned by key, sorted, and
transferred across the network to the appropriate Reducer nodes. This guarantees that
all values associated with a single key are processed by the same Reducer.
23. How do Kafka Consumer Groups handle partition assignment and scaling?
● Answer: Each partition in a Kafka topic can be consumed by exactly one consumer
within a specific consumer group. To scale consumption, you add more consumers to the
group, up to the total number of partitions.
● Answer: When a consumer joins, leaves, or crashes, Kafka revokes all partition
assignments and reassigns them among the currently active consumers in the group to
ensure all partitions are being read. Processing pauses during this phase.
25. Explain the Write-Ahead Log (WAL) in distributed systems like HDFS or databases.
● Answer: A WAL is an append-only file where modifications are recorded before they are
applied to the actual data structures. In the event of a crash, the system can replay the
WAL to recover uncommitted or unwritten data.
27. What memory eviction policies does Redis support when it runs out of RAM?
● Answer: Split-brain occurs when a network partition causes a cluster to divide, and both
sides elect a master node, leading to data inconsistency. It is prevented by requiring a
strict quorum (majority) of master-eligible nodes to elect a leader.
● Answer: A hot partition happens when too many messages are routed to one partition
(e.g., heavily skewed keys). You solve it by modifying the partition key (salting it with a
random number) or using a custom partitioner to distribute the load more evenly.
● Answer: Use a highly available database (like Cassandra) to store the long URL
mapping. Generate unique short IDs using a Base62 encoding algorithm. Put a
distributed cache (Redis) in front of the database to handle heavy read traffic for popular
links.
32. Explain Consistent Hashing and why it is crucial for distributed caches.
● Answer: It maps both data keys and server nodes to a virtual ring. When a server is
added or removed, only a small fraction of keys are remapped (typically to the next node
on the ring), preventing a massive cache miss storm that occurs with standard modulo
hashing.
● Answer: Distributed transactions (2PC) are too slow. Instead, use the Saga Pattern
where each service executes a local transaction and emits an event (via Kafka). If a
downstream service fails, compensating events are fired to undo previous actions.
34. Describe the Token Bucket algorithm for API Rate Limiting.
● Answer: A bucket holds a maximum number of tokens. Tokens are added to the bucket
at a fixed rate. Each API request removes a token. If the bucket is empty, the request is
rejected. It allows for short bursts of traffic while enforcing an overall average rate.
35. What is the CQRS pattern?
● Answer: Command Query Responsibility Segregation. It splits the application into two
parts: one side handles writes/updates (Commands) optimized for transactional integrity,
and the other side handles reads (Queries) optimized for fast searching (often syncing
data to OpenSearch).
● Answer: Sharding is horizontal scaling at the database level. It partitions a large table
into smaller, faster, more easily managed pieces called shards, distributing the rows
across multiple database servers based on a Shard Key (e.g., user ID).
● Answer: It acts as the single entry point for all clients. It handles cross-cutting concerns
like authentication, SSL termination, rate limiting, request routing, and payload
aggregation, keeping these complexities out of the individual microservices.
● Answer: REST uses HTTP/1.1 and JSON, making it human-readable and widely
supported. gRPC uses HTTP/2 and Protocol Buffers (binary payload), making it
significantly faster, lighter, and strongly typed, ideal for internal service-to-service
communication.
43. What is the N+1 select problem in JPA, and how do you solve it?
● Answer: It occurs when you query a list of entities (1 query) and then access a
lazily-loaded association for each entity, triggering an additional query for every single
row (N queries). Solve it using JPQL JOIN FETCH or JPA @EntityGraph to fetch
everything in one query.
● Answer: REQUIRED (default) joins the existing active transaction; if the inner method
fails, the whole transaction rolls back. REQUIRES_NEW suspends the current transaction
and creates a completely independent transaction; its commit/rollback does not affect
the outer transaction.
● Answer: High-level modules should not depend on low-level modules; both should
depend on abstractions (interfaces). Abstractions should not depend on details; details
should depend on abstractions.
47. What is a Circuit Breaker, and why is it necessary?
● Answer: An API is idempotent if making multiple identical requests has the same effect
as making a single request. GET, PUT, and DELETE are idempotent by nature, whereas
POST is not. It is critical for safely retrying failed network requests.
● Answer: Technical debt is a tool to ship faster, but it accrues "interest" in the form of
slower future development. I manage it by tracking it visibly in the sprint backlog,
advocating for the Boy Scout Rule (leave code better than you found it), and dedicating
a percentage of team capacity specifically to refactoring.