Interview Question Java 2 yr

๐Ÿ”น Core Java & Multithreading



 Explain the difference between synchronized and ReentrantLock.?


๐Ÿง  synchronized vs ReentrantLock — Quick Cheat Sheet:

synchronized is simple and automatic — just add the keyword, and Java handles locking for you.

Timeout Support ❌ No


Automatic Lock Management: Acquires and releases the lock automatically.


ReentrantLock gives more control — you manually lock/unlock and get extra features.


Timeout Support ✅ Yes (tryLock)

Timeouts: Can attempt to acquire a lock with a timeout (tryLock()).

Manual Lock Management: You must explicitly acquire and release the lock.


✅ Advantages of ReentrantLock over synchronized:


Interruptible Lock Acquisition You can interrupt a thread waiting for a lock (lock.lockInterruptibly()), which is impossible with synchronized.


Timeouts You can try to acquire a lock with a timeout (lock.tryLock(timeout)), giving more control in deadlock-prone scenarios.


๐Ÿ”น Imagine a Bank Queue

  • You go to a bank counter → the counter is the lock.

  • If someone is already at the counter, you wait in line until they leave.

  • This is what happens with synchronized or lock(). You keep waiting no matter what.


๐Ÿ”น Now Imagine You Get an Urgent Call ๐Ÿšจ

While waiting in the queue:

  • Normally, you cannot leave the line. You must wait (this is like synchronized → no way out).

  • But with lockInterruptibly(), you can say:
    ๐Ÿ‘‰ "If my phone rings (interruption), I will leave the line immediately."

This is exactly what lock interrupt means → you are allowed to stop waiting for the lock if something urgent happens (like an interrupt signal).



:


๐Ÿ”น Normal Lock (synchronized / lock())

  • If a thread is waiting for a lock, it must keep waiting until it gets it.

  • Even if something urgent comes up, the thread cannot leave the waiting line.

๐Ÿ‘‰ Example:
Thread-2 is waiting for a lock. Suddenly, it is asked to process a high-priority task (like shutting down the system).
But since it’s stuck waiting, it can’t do that urgent task.



๐Ÿ” What volatile Does in Java

  1. Visibility Guarantee When a variable is declared volatile, any write to it by one thread is immediately visible to other threads. ๐Ÿ‘‰ Without volatile, threads may cache variables locally and not see updates from others.

๐Ÿง  How It Works in the Java Memory Model

  • Reads/Writes Go Directly to Main Memory Threads don’t cache volatile variables—they always read from and write to main memory.


๐Ÿš€ What Is CompletableFuture?

A CompletableFuture<T> represents a future result of an asynchronous computation. You can:

Start tasks asynchronously

Chain actions to run after completion

Combine multiple futures



✅ How It Improves Async Programming

  1. Non-blocking Execution You can launch tasks without waiting for them to finish, freeing up threads and improving scalability.

  2. Chaining with .thenApply(), .thenAccept(), .thenCompose() You can build pipelines of actions that trigger when the result is ready—like promises in JavaScript.

  3. Combining Multiple Futures Use .thenCombine(), .allOf(), or .anyOf() to coordinate multiple async tasks.



๐Ÿงต What Is a Thread Pool?

A thread pool is a group of pre-instantiated reusable threads. Instead of creating a new thread for every task (which is expensive), you submit tasks to the pool and it assigns them to available threads.

⚙️ What Is ExecutorService?

ExecutorService is a high-level API in Java that manages thread pools. It abstracts away the complexity of thread creation, scheduling, and lifecycle management.


✅ Why Use a Thread Pool?

  1. Performance Boost Reuses threads instead of creating new ones—saves memory and CPU.

  2. Better Resource Management Limits the number of concurrent threads, avoiding system overload.

  3. Simplified Concurrency You focus on tasks, not thread mechanics.

  4. Scalability Easily handles large numbers of short-lived tasks.

  5. Graceful Shutdown You can shut down the pool cleanly using shutdown() or shutdownNow().



What is the difference between HashMap, ConcurrentHashMap, and Hashtable?



1. HashMap

  • Thread-safety:Not synchronized → Not safe for multi-threaded environments.

  • Performance: ✅ Very fast in single-threaded use cases (no locking overhead).

  • Nulls: ✅ Allows one null key and multiple null values.

  • Iteration: Fail-fast (throws ConcurrentModificationException if modified while iterating).

  • Use case: Best when single-threaded or when you manage synchronization yourself.

๐Ÿ”น 2. Hashtable (Legacy)

  • Thread-safety:Synchronized on every method → Thread-safe but slow because the whole table is locked for every operation.

  • Performance: ❌ Slower than HashMap and ConcurrentHashMap (coarse-grained lock).

  • Nulls: ❌ Does NOT allow null key or value.

  • Iteration: Fail-fast (but not guaranteed).

  • Use case: Very old (introduced in Java 1.0). Rarely used today → replaced by ConcurrentHashMap.


๐Ÿ”น 3. ConcurrentHashMap

  • Thread-safety: ✅ Yes, but uses fine-grained locking (segments/buckets) instead of locking the entire map.

  • Performance: ✅ Much better than Hashtable in multi-threaded environment (concurrent reads, limited locking for writes).

  • Nulls: ❌ Does NOT allow null keys or values (to avoid ambiguity during concurrent operations).

  • Iteration: Weakly consistent → does not throw ConcurrentModificationException. It reflects updates partially while iterating.

  • Use case: Best choice for multi-threaded applications.



๐Ÿ”น Spring Boot & Microservices


⚙️ What Is Auto-Configuration?

Auto-configuration is Spring Boot’s way of automatically configuring beans based on:

  • The libraries on your classpath

  • The properties you’ve defined

  • The default settings provided by Spring Boot

It uses sensible defaults and conditional logic to wire up components so you don’t have to.

๐Ÿง  How It Works Behind the Scenes

  1. @EnableAutoConfiguration Annotation This is usually included via @SpringBootApplication, which itself is a combo of:

    • @Configuration

    • @EnableAutoConfiguration

    • @ComponentScan


๐ŸŽฏ Interview One-Liner:

"Spring Boot auto-configuration uses classpath detection and conditional logic to automatically wire beans, reducing setup and letting developers focus on business logic."

 


Absolutely! These annotations@Component, @Service, @Repository, and @Controller—are all part of Spring Framework’s stereotype annotations. They mark classes as Spring-managed beans, but each has a specific semantic role in the application architecture.


๐Ÿงฉ @Component

  • Generic stereotype for any Spring-managed bean.

  • Used when the class doesn’t fit into a specific layer (like service, repository, or controller).

  • All other annotations (@Service, @Repository, @Controller) are specializations of @Component.



How do you implement Exception Handling in Spring Boot REST APIs?

try catch'
in a single class ExceptionHandlera

In Spring Boot REST APIs, I use @ControllerAdvice with @ExceptionHandler to handle exceptions globally.



How does Spring Cloud Config work for microservices?

"Spring Cloud Config provides a centralized configuration server for managing external properties across microservices. It allows services to fetch their configuration from a remote Git repository or other sources at startup or runtime. This promotes consistency, version control, and dynamic updates without redeploying services."

You can add a bonus line if time allows:

"Each microservice uses the Spring Cloud Config Client to connect to the Config Server, which serves environment-specific properties like application-dev.yml or application-prod.yml."


How do you implement service-to-service communication? 


Service-to-service communication in microservices is typically implemented using REST APIs or messaging queues. For synchronous calls, I use REST with tools like Feign Client or WebClient in Spring Boot. For asynchronous communication, I use message brokers like RabbitMQ or Kafka to decouple services and improve scalability.

RabbitMQ and Kafka


RabbitMQ

Message Broker (Queue-based)

RabbitMQ queues delete messages once they're acknowledged, so replay isn't supported by default. But since RabbitMQ 3.9, there's a feature called Streams that does support replay.



Kafka

Event Streaming Platform (Log-based).

Kafka is fast, scalable, and stores messages for a long time, which makes it great for analytics and event-driven systems.

๐Ÿ”„ Synchronous Call

  • The caller waits for the response.

  • Like making a phone call—you talk, wait for a reply, then continue.

  • Example: A REST API call where Service A calls Service B and waits for the result.

  • String result = serviceB.getData(); // waits until response is received


๐Ÿ” Asynchronous Call

  • The caller does not wait for the response.

  • Like sending a message—you continue doing other work while the reply comes later.

  • Example: Sending a message to a queue (RabbitMQ/Kafka) and processing it later.

messageQueue.send(data); // returns immediately, response handled later



  1. How do you handle distributed transactions in microservices?


The Saga pattern is a way to manage distributed transactions in a microservices architecture without using traditional two-phase commits.

๐Ÿ”„ Simple Explanation:

"Saga breaks a big transaction into smaller steps, each handled by a different microservice. If one step fails, it triggers compensating actions to undo the previous steps—ensuring eventual consistency across services."

๐Ÿงฉ Two Saga Types:

  • Choreography: Each service listens for events and reacts. No central coordinator.

  • Orchestration: A central Saga orchestrator controls the flow and calls each service step-by-step.


How do you ensure idempotency in payment APIs?

Here’s a crisp, interview-ready answer:

"To ensure idempotency in payment APIs, I use a unique idempotency key—usually passed in the request header. The server stores this key and the result of the first request. If the same request is repeated with the same key, the server returns the original response without reprocessing the payment. This prevents duplicate charges due to retries or network failures."



 


Comments

Popular posts from this blog

Two Sum II - Input Array Is Sorted

Comparable Vs. Comparator in Java

Increasing Triplet Subsequence