interview question of Java Backend
Interview Questions
Core Java (OOPs, Collections, Concurrency Basics)
Explain difference between HashMap, HashTable, and ConcurrentHashMap.
| Feature | HashMap | Hashtable | ConcurrentHashMap |
|---|---|---|---|
| Thread Safety | Not thread-safe | Thread-safe (synchronized methods) | Thread-safe (lock segmentation / fine-grained locking) |
| Null Keys/Values | Allows one null key and multiple null values | Does not allow any null keys/values | Does not allow null keys/values |
| Performance | Faster (no synchronization overhead) | Slower (entire table is locked) | Better concurrency — multiple threads can read/write different segments simultaneously |
| Use Case | Single-threaded apps | Legacy thread-safe code | High-performance concurrent apps |
Example:
If multiple threads are accessing and modifying a map, prefer ConcurrentHashMap. For non-concurrent cases, use HashMap. Avoid Hashtable in modern code.
How does equals() and hashCode() work together in collections?
- hashCode(): Returns an integer hash value used to place objects in hash-based collections (like HashMap, HashSet).
- equals(): Compares two objects for logical equality.
Contract:
- If two objects are equal according to equals(), they must have the same hashCode().
- If two objects have the same hashCode(), they may or may not be equal.
Why it matters:
Collections like HashMap use hashCode() to find a bucket, and then equals() to check if the key already exists.
Example:1
2
3
4
5
6
7
8
9
10
11
12
13
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person p = (Person) o;
return id == p.id;
}
public int hashCode() {
return Objects.hash(id);
}
Difference between shallow copy vs deep copy in Java.
| Type | Description | Example |
|---|---|---|
| Shallow Copy | Copies only object references (not the objects they refer to). Both objects share the same nested objects. | clone() without custom implementation |
| Deep Copy | Copies everything — including new instances of nested objects. Changes in one object don’t affect the other. | Implemented manually or via serialization |
Example:1
2
3
4
5
6// Shallow copy
Employee e2 = e1.clone(); // e1.address and e2.address point to same object
// Deep copy
Employee e2 = new Employee(e1);
e2.address = new Address(e1.address);
How do you prevent deadlock in multithreaded applications?
Deadlock occurs when two or more threads are waiting on each other’s locks.
Ways to prevent it:
- Lock ordering – Always acquire locks in a consistent order.
- Try-lock with timeout – Use tryLock() from ReentrantLock to avoid waiting forever.
- Avoid nested locks – Reduce code sections that acquire multiple locks.
- Use concurrent utilities – Prefer ConcurrentHashMap, BlockingQueue, etc., which manage synchronization internally.
- Minimize synchronized blocks – Keep critical sections small.
Example:1
2
3
4
5if (lock1.tryLock(50, TimeUnit.MILLISECONDS)) {
if (lock2.tryLock(50, TimeUnit.MILLISECONDS)) {
// work
}
}
Explain volatile vs synchronized — when to use each.
| Feature | volatile |
synchronized |
|---|---|---|
| Purpose | Guarantees visibility of changes across threads | Guarantees atomicity and visibility |
| Use Case | When multiple threads read/write a variable, and writes are independent | When operations on shared data must be atomic |
| Locking | No locking (lighter, faster) | Uses intrinsic lock (can block threads) |
| Scope | Variable-level only | Code block or method |
| Example Use | Status flags, configuration values | Counters, complex state updates |
Example:1
2
3
4
5volatile boolean running = true; // visibility only
synchronized void increment() { // atomic operation
count++;
}
Rule of thumb:
- Use volatile for simple flags or status updates.
- Use synchronized (or locks) for compound operations that must be atomic.
Spring & Spring Boot
Difference between @Component, @Service, @Repository, and @Controller.
Spring provides several stereotype annotations to define beans, which also give semantic meaning for better readability:
| Annotation | Purpose | Special Behavior |
|---|---|---|
@Component |
Generic stereotype for any Spring-managed component | Base annotation for all other stereotypes |
@Service |
Indicates a service layer component (business logic) | Mainly semantic, no extra behavior, improves readability |
@Repository |
Indicates a DAO (Data Access Object) component | Converts database exceptions into Spring’s DataAccessException |
@Controller |
Indicates a web controller handling HTTP requests | Typically used with @RequestMapping to handle endpoints; works with Spring MVC |
Summary:
All are detected via component scanning and registered as Spring beans, but @Repository and @Controller have additional framework-specific roles.
What is Spring Boot auto-configuration? How does it work internally?
Auto-configuration is a key feature of Spring Boot that automatically configures your application based on the dependencies on the classpath and properties defined in application.properties or application.yml.
How it works internally:
- Spring Boot uses the
@SpringBootApplicationannotation, which includes@EnableAutoConfiguration. @EnableAutoConfigurationimportsspring.factorieswhich lists all auto-configuration classes.- During startup, Spring Boot evaluates each auto-configuration class using
@Conditionalannotations (e.g.,@ConditionalOnClass,@ConditionalOnMissingBean) to decide which beans to create. - Beans are registered automatically based on what classes and libraries are available on the classpath.
Example:
If spring-boot-starter-data-jpa is on the classpath, Spring Boot auto-configures EntityManagerFactory and DataSource beans automatically.
How do you implement exception handling globally in Spring Boot REST APIs?
Spring Boot provides @ControllerAdvice for global exception handling.
Steps:
- Create a class annotated with
@ControllerAdvice. - Define methods annotated with
@ExceptionHandlerto handle specific exceptions. - Optionally, use
@ResponseStatusor return a custom response body.
Example:
1 |
|
Explain difference between @RequestParam, @PathVariable, and @RequestBody.
| Annotation | Usage | Example |
|---|---|---|
@RequestParam |
Binds query parameters or form data | GET /users?id=123 → @RequestParam("id") Long id |
@PathVariable |
Binds URI template variables | GET /users/123 → @PathVariable("id") Long id |
@RequestBody |
Binds HTTP request body (JSON/XML) to Java object | POST /users with JSON { "name": "John" } → @RequestBody User user |
Summary:
- @RequestParam → query/form parameters
- @PathVariable → path segments
- @RequestBody → request body content
How do you implement profiles in Spring Boot for multiple environments?
Spring Boot supports profiles to separate environment-specific configurations (dev, test, prod).
Steps:
- Create profile-specific properties files:
- application-dev.properties
- application-prod.properties
- Activate a profile:
- In application.properties:
1
spring.profiles.active=dev
- Or via command line:
1
java -jar app.jar --spring.profiles.active=prod
- In application.properties:
- Use @Profile annotation to conditionally load beans:Summary:
1
2
3
4
5
6
7
8@Configuration
@Profile("dev")
public class DevConfig {
@Bean
public DataSource devDataSource() {
return new HikariDataSource();
}
}
Profiles allow you to maintain different configurations for different environments while keeping a single codebase.
JPA / Hibernate
What are entity states (Transient, Persistent, Detached, Removed) in Hibernate?
In Hibernate, an entity can exist in one of four states:
| State | Description | Example |
|---|---|---|
| Transient | The entity is not associated with a Hibernate Session and not persisted in the database. |
User user = new User(); (new object, no save() called) |
| Persistent | The entity is associated with a Hibernate Session and changes will be automatically synchronized with the database. |
session.save(user); |
| Detached | The entity was persistent, but the session is closed or entity is evicted. Changes are not automatically persisted. | session.close(); user.setName("John"); |
| Removed | The entity is scheduled for deletion. It will be deleted when the transaction commits. | session.delete(user); |
Explain lazy loading and how to avoid LazyInitializationException.
Lazy loading is when Hibernate delays loading of associated entities until they are actually accessed.
- Example: employees are loaded from the database only when getEmployees() is called.
1
2
3
4
5
class Department {
private List<Employee> employees;
}
LazyInitializationException occurs if you try to access a lazily loaded collection outside an active session.
Ways to avoid it:
- Open Session in View (not recommended for all cases): Keep session open during view rendering.
- Fetch join in JPQL:
1
SELECT d FROM Department d JOIN FETCH d.employees WHERE d.id = :id
- Eager fetching (careful with performance):
1
@OneToMany(fetch = FetchType.EAGER)
- Initialize collection manually before session closes:
1
Hibernate.initialize(department.getEmployees());
Difference between Criteria API and JPQL.
| Feature | JPQL | Criteria API |
|---|---|---|
| Query Type | String-based queries | Object-oriented, type-safe queries |
| Compile-time safety | No | Yes |
| Readability | Simple for static queries | Better for dynamic queries |
Example1
2
3
4
5// SELECT u FROM User u WHERE u.age > 25
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
cq.select(user).where(cb.gt(user.get("age"), 25));
What is the difference between CascadeType.ALL and orphanRemoval?
| Feature | CascadeType.ALL |
orphanRemoval = true |
|---|---|---|
| Purpose | Applies all operations (persist, merge, remove, refresh) from parent to child | Deletes child entities when they are removed from parent collection |
| Example | Saving parent automatically saves child | Removing a child from parent’s collection deletes it from DB |
| Key Difference | Cascade propagates operations, not necessarily removal | Orphan removal only deletes orphans but doesn’t cascade persist |
Example:1
2
private List<Employee> employees;
- cascade = ALL → persisting parent also persists employees
- orphanRemoval = true → removing employee from list deletes it from DB
How do you implement pagination and sorting in Spring Data JPA?
Spring Data JPA provides Pageable and Sort interfaces for pagination and sorting.
Example:1
2
3
4
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findByAgeGreaterThan(int age, Pageable pageable);
}
Usage in service:1
2
3
4
5Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
Page<User> users = userRepository.findByAgeGreaterThan(25, pageable);
users.getContent().forEach(System.out::println);
System.out.println("Total pages: " + users.getTotalPages());
- PageRequest.of(page, size, sort) specifies page number, page size, and sorting.
- Returns a Page
which contains content, total pages, total elements, and more.
Microservices & Architecture
Explain difference between monolithic and microservices architectures.
| Aspect | Monolithic Architecture | Microservices Architecture |
|---|---|---|
| Structure | Single unified codebase | Collection of small, independent services |
| Deployment | One deployable unit | Each service deployed independently |
| Scaling | Scale entire application | Scale individual services as needed |
| Technology Stack | Usually uniform | Can use different stacks per service |
| Fault Isolation | Failure in one module may affect entire app | Failures isolated to the specific service |
| Development Speed | Slower for large teams | Faster with independent teams |
Summary:
Monolith = single large app; Microservices = many small, loosely coupled apps that communicate over APIs.
How do you implement inter-service communication? (REST, Kafka, gRPC)
Microservices need to communicate with each other. Common methods:
- REST (HTTP/JSON)
- Simple, widely used, synchronous request-response.
- Example:
1
2
public User getUser( Long id) { ... }
- Kafka (Event-driven messaging)
- Asynchronous, decoupled communication using topics.
- Example: Service A produces events → Service B consumes events.
- gRPC (Remote Procedure Calls)
- High-performance, strongly typed, binary protocol using Protocol Buffers.
- Example:Summary:
1
2
3service UserService {
rpc GetUser(UserRequest) returns (UserResponse);
}
- REST → synchronous, simple
- Kafka → asynchronous, decoupled
- gRPC → synchronous or streaming, high performance
What is API Gateway and why do we need it?
An API Gateway is a single entry point for clients to interact with multiple microservices.
Responsibilities:
- Routing requests to appropriate microservices
- Request aggregation (combine multiple service responses)
- Authentication & authorization
- Rate limiting, caching, logging
Example:
- Netflix Zuul, Spring Cloud Gateway, Kong, NGINX
Summary:
API Gateway simplifies client interaction, hides service complexity, and provides cross-cutting features in one place.
How do you manage configuration in multiple microservices?
For multiple services, externalized and centralized configuration is recommended.
Approaches:
- Spring Cloud Config
- Central config server serving properties via Git/Filesystem.
- Services fetch config dynamically.
- Environment variables / Kubernetes ConfigMaps & Secrets
- Store environment-specific configuration outside code.
- Consul / etcd
- Distributed configuration with service discovery integration.
Example with Spring Cloud Config:1
2
3
4
5
6spring:
application:
name: user-service
cloud:
config:
uri: http://config-server:8888
Explain circuit breaker pattern (Hystrix/Resilience4j) with example.
The circuit breaker pattern prevents cascading failures in microservices when one service is down or slow.
How it works:
- Circuit is closed → calls pass normally.
- If failures exceed threshold → circuit opens → further calls fail fast.
- After a timeout → circuit half-open → test a few requests before closing.
Example with Resilience4j (Spring Boot):1
2
3
4
5
6
7
8
9
10
11
12
public class UserService {
public User getUser(Long id) {
// Call external service
}
public User fallbackGetUser(Long id, Throwable t) {
return new User(id, "Default User");
}
}
Summary:
Circuit breakers improve system resilience by preventing cascading failures and allowing graceful degradation.
Cloud & DevOps Basics
What is the difference between Docker image and Docker container?
| Aspect | Docker Image | Docker Container |
|---|---|---|
| Definition | Read-only template with application and dependencies | Running instance of an image |
| Lifecycle | Immutable, stored in registry | Created, started, stopped, or destroyed |
| Purpose | Used to build containers | Executes the application |
| Example | myapp:1.0 image |
docker run myapp:1.0 creates a container |
Summary:
Image = blueprint; Container = running instance of that blueprint.
How does Kubernetes handle scaling and service discovery?
Scaling:
- Kubernetes can automatically scale pods using:
- Manual scaling:
kubectl scale deployment myapp --replicas=5 - Horizontal Pod Autoscaler (HPA): Automatically adjusts replicas based on CPU/memory metrics.
- Manual scaling:
Service Discovery:
- Pods are ephemeral; services use DNS names for discovery.
- Kubernetes Service creates a stable IP and DNS name for a set of pods.
- Example:
http://user-service.default.svc.cluster.local
Explain difference between Blue-Green and Rolling deployments.
| Aspect | Blue-Green Deployment | Rolling Deployment |
|---|---|---|
| Approach | Two identical environments: Blue (current) & Green (new) | Update pods gradually with new version |
| Downtime | Near-zero downtime | Minimal downtime during updates |
| Rollback | Simple: switch traffic back to old environment | Rollback requires reverting pods |
| Complexity | Requires double resources | Resource-efficient |
How do you monitor Spring Boot microservices in production (Actuator, ELK, Prometheus)?
1. Spring Boot Actuator:
- Exposes metrics, health checks, and info endpoints.
- Example:
/actuator/health,/actuator/metrics
2. ELK Stack (Elasticsearch, Logstash, Kibana):
- Centralized logging for multiple microservices.
- Collect logs with Logstash → store in Elasticsearch → visualize in Kibana.
3. Prometheus & Grafana:
- Prometheus scrapes metrics from Actuator endpoints.
- Grafana visualizes metrics in dashboards.
- Example:
1
2
3
4
5management:
endpoints:
web:
exposure:
include: health, metrics, prometheus
What is CI/CD? How have you implemented it in your projects?
CI/CD stands for Continuous Integration / Continuous Deployment.
- Continuous Integration (CI): Automatically build and test code whenever changes are pushed.
- Continuous Deployment (CD): Automatically deploy code to staging/production after passing tests.
Typical Implementation:
- Use GitHub Actions / Jenkins / GitLab CI to build, test, and package Spring Boot services into Docker images.
- Push Docker images to Docker Registry (Docker Hub, ECR, GCR).
- Deploy images to Kubernetes or cloud environment.
- Automated tests and monitoring ensure quality and quick rollback if needed.
Example GitHub Actions snippet:1
2
3
4
5
6
7
8
9
10
11name: CI/CD Pipeline
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to registry
run: docker push myapp:${{ github.sha }}
SQL / Database Knowledge
Write a SQL query to get department-wise average salary.
1 | SELECT |
Explanation:
- GROUP BY groups rows by department.
- AVG() calculates the average salary per department.
- ORDER BY sorts the results (optional).
Difference between INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN.
| Type | Description | Example Result |
|---|---|---|
| INNER JOIN | Returns only rows with matching values in both tables. | Employees that belong to a department. |
| LEFT JOIN | Returns all rows from the left table, even if no match exists in the right table. | All employees, with department info if available. |
| RIGHT JOIN | Returns all rows from the right table, even if no match exists in the left table. | All departments, even those with no employees. |
| FULL JOIN | Returns all rows from both tables, with NULL for missing matches. |
All employees and departments, matched where possible. |
Example:1
2
3SELECT e.name, d.name AS department
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;
How do you optimize slow-running SQL queries?
- Analyze the query plan
- Use EXPLAIN (MySQL, PostgreSQL) to view execution details.
- Identify full table scans, missing indexes, or inefficient joins.
- Create appropriate indexes
- Add indexes on columns used in WHERE, JOIN, and ORDER BY clauses.
- Reduce data retrieval
- Use SELECT specific_columns instead of SELECT *.
- Apply filters and limits.
- Optimize joins and subqueries
- Prefer joins over nested subqueries when possible.
- Use caching
- Cache frequent queries (e.g., Redis, Memcached).
- Partition large tables
- Improves performance on very large datasets.
Explain ACID properties and isolation levels in databases.
ACID Properties
| Property | Description |
|---|---|
| Atomicity | All operations in a transaction succeed or none do. |
| Consistency | Database remains valid before and after the transaction. |
| Isolation | Transactions do not interfere with each other. |
| Durability | Once committed, data changes persist even after failures. |
Isolation Levels
| Level | Description | Common Problems Prevented |
|---|---|---|
| READ UNCOMMITTED | Transactions can read uncommitted data (dirty reads). | None |
| READ COMMITTED | Prevents dirty reads, allows non-repeatable reads. | Dirty reads |
| REPEATABLE READ | Prevents dirty and non-repeatable reads, but phantom reads may occur. | Dirty, non-repeatable reads |
| SERIALIZABLE | Highest level, ensures full isolation (transactions run sequentially). | All |
How do you use indexes, and what are clustered vs non-clustered indexes?
What is an index?
An index improves data retrieval speed by allowing the database to find rows quickly, similar to a book index.
Syntax Example:1
CREATE INDEX idx_employee_name ON employees(name);
Types of Indexes
| Type | Description | Example |
|---|---|---|
| Clustered Index | Physically sorts and stores table data based on the index key. One per table. | PRIMARY KEY automatically creates a clustered index. |
| Non-Clustered Index | Stores index separately from table data, containing pointers to the actual rows. | Used for frequently queried columns not part of the primary key. |
Summary:
- Clustered = data sorted by index
- Non-clustered = separate lookup structure
Best Practices:
- Use indexes on columns often used in filters and joins.
- Avoid over-indexing (it slows down inserts/updates).
- Regularly monitor and rebuild fragmented indexes.
DSA & Coding (GlobalLogic Special Focus)
Write a program to reverse a linked list in Java (iterative + recursive).
Iterative Approach:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Node {
int data;
Node next;
Node(int data) { this.data = data; }
}
public class ReverseLinkedList {
public static Node reverseIterative(Node head) {
Node prev = null, curr = head;
while (curr != null) {
Node next = curr.next; // store next
curr.next = prev; // reverse link
prev = curr; // move prev forward
curr = next; // move curr forward
}
return prev; // new head
}
}
Recursive Approach:1
2
3
4
5
6
7
8public static Node reverseRecursive(Node head) {
if (head == null || head.next == null)
return head;
Node newHead = reverseRecursive(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
Implement a program to find the first non-repeating character in a string.
Logic: Use a frequency map to track occurrences, then find the first char with count = 1.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import java.util.*;
public class FirstNonRepeatingChar {
public static char firstNonRepeating(String s) {
Map<Character, Integer> map = new LinkedHashMap<>();
for (char c : s.toCharArray())
map.put(c, map.getOrDefault(c, 0) + 1);
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
if (entry.getValue() == 1)
return entry.getKey();
}
return '_'; // if no non-repeating char
}
public static void main(String[] args) {
System.out.println(firstNonRepeating("swiss")); // Output: w
}
}
Write a Java program to find the longest common prefix among a set of strings.
Approach: Compare characters of all strings until mismatch occurs.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class LongestCommonPrefix {
public static String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
while (!strs[i].startsWith(prefix)) {
prefix = prefix.substring(0, prefix.length() - 1);
if (prefix.isEmpty()) return "";
}
}
return prefix;
}
public static void main(String[] args) {
String[] input = {"flower", "flow", "flight"};
System.out.println(longestCommonPrefix(input)); // Output: "fl"
}
}
Implement LRU Cache in Java.
Approach: Use LinkedHashMap with access order.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import java.util.*;
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true); // accessOrder = true
this.capacity = capacity;
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
public static void main(String[] args) {
LRUCache<Integer, String> cache = new LRUCache<>(3);
cache.put(1, "A");
cache.put(2, "B");
cache.put(3, "C");
cache.get(1); // access 1
cache.put(4, "D"); // removes 2 (least recently used)
System.out.println(cache.keySet()); // Output: [3, 1, 4]
}
}
Write a REST API to fetch last N orders of a customer (Spring Boot + JPA).
1 |
|
1 |
|
1 |
|
1 |
|
Example Request:1
2GET /api/orders/101/last?n=3
# Response: Returns the last 3 orders for customer 101 sorted by date (descending).

