Skip to content

Java Technical Round Questions & Answers

40 questions for the technical round stage — 4 easy, 27 medium, 9 hard.

About the technical round round

The technical round is the core of a Java interview: concept questions with follow-ups, a live hands-on task and a deep dive into one of your projects. Interviewers check depth, not just definitions.

Tips for the technical round round

  • Say your approach out loud before you start writing.
  • After a correct answer, expect 'why?' and 'what if?' follow-ups; go one level deeper than the question.
  • Pick one project you can explain end to end, including what you would do differently.
  • If you get stuck, explain what you would try next instead of going silent.
Solved — technical roundStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is the difference between synchronized and ReentrantLock?

Save to ▾
Show answer
synchronized is a built-in keyword that locks a monitor and releases it automatically at block exit. ReentrantLock is an explicit lock that adds tryLock with timeout, interruptible locking, fairness options and multiple Condition objects, but you must unlock in a finally block. Both are reentrant. Prefer synchronized for simple cases and ReentrantLock when you need its extra features.
02

What is the difference between map() and flatMap()?

Save to ▾
Show answer
map() transforms each element into exactly one new element, so a Stream of orders mapped to totals stays one-to-one. flatMap() transforms each element into a stream and flattens all of them into one stream, which is useful for one-to-many cases, such as turning a list of orders into a single stream of all items with orders.stream().flatMap(o -> o.items().stream()).
03

A getter returns an internal List and callers modify it, causing bugs. How do you fix this?

Save to ▾
Show answer
This breaks encapsulation. Return an unmodifiable view with Collections.unmodifiableList(list) or a copy with List.copyOf(list), so callers cannot change internal state. Also copy the list passed into the constructor or setter. If the class should be fully immutable, store List.copyOf in a final field. Expose specific methods like addItem() when controlled changes are needed.
04

What is dependency injection and why is constructor injection preferred?

Save to ▾
Show answer
Dependency injection means the container creates objects and supplies their dependencies, instead of classes creating them, which reduces coupling and helps testing. Constructor injection is preferred because dependencies can be final, objects are never half-built, required dependencies are obvious and unit tests can pass mocks without Spring. Field injection with @Autowired hides dependencies and is harder to test.
05

Flatten a list of lists of integers and compute the sum of squares of the even numbers.

Save to ▾
Show answer
flatMap then use a primitive stream to avoid boxing. int result = lists.stream() .flatMap(List::stream) .filter(n -> n % 2 == 0) .mapToInt(n -> n * n) .sum(); mapToInt returns an IntStream, whose sum() is simpler and faster than reduce on boxed Integers.
06

Compare the G1, ZGC and Parallel garbage collectors.

Save to ▾
Show answer
Parallel GC focuses on throughput and uses multiple threads but stops the application during collection. G1, the default since Java 9, splits the heap into regions and targets a pause time goal, which suits most server apps. ZGC is a low latency collector with pauses typically under a millisecond even on very large heaps, and is generational from Java 21. Choose based on latency versus throughput needs.
07

Write a Spring Data JPA repository method that fetches orders with items to avoid N+1.

Save to ▾
Show answer
Use JOIN FETCH or an entity graph. public interface OrderRepository extends JpaRepository<Order, Long> { @Query("select distinct o from Order o join fetch o.items where o.customerId = :cid") List<Order> findWithItems(@Param("cid") Long customerId); @EntityGraph(attributePaths = "items") List<Order> findByStatus(String status); } Both load orders and items in one query.
08

What is the difference between lazy and eager loading?

Save to ▾
Show answer
Lazy loading fetches an association only when it is first accessed, using a proxy; eager loading fetches it immediately with the parent. In JPA, @ManyToOne and @OneToOne default to EAGER, while @OneToMany and @ManyToMany default to LAZY. Best practice is to make all associations lazy and fetch what each use case needs with JOIN FETCH or entity graphs, which avoids loading huge object graphs.
09

An API listing 100 orders fires 101 SQL queries. How do you fix it?

Save to ▾
Show answer
This is the N+1 problem from a lazy association loaded in a loop or by JSON serialisation. Fetch what the endpoint needs in one query with JOIN FETCH or @EntityGraph(attributePaths = "items"), or use a DTO projection query. For collections with pagination, fetch ids first, then fetch associations in a second query to avoid in-memory paging. Add a test that asserts the query count.
10

What is the contract between equals() and hashCode()?

Save to ▾
Show answer
If two objects are equal by equals(), they must return the same hashCode(). Unequal objects may share a hash code, but fewer collisions give better performance. If you override equals() but not hashCode(), HashMap and HashSet break: an equal key lands in a different bucket and cannot be found. Use the same fields in both methods, or use records, which generate both.
11

Run two tasks in parallel with CompletableFuture and combine their results.

Save to ▾
Show answer
Use a dedicated executor for I/O work. ExecutorService pool = Executors.newFixedThreadPool(4); CompletableFuture<User> user = CompletableFuture.supplyAsync(() -> userApi.get(id), pool); CompletableFuture<List<Order>> orders = CompletableFuture.supplyAsync(() -> orderApi.list(id), pool); Profile p = user.thenCombine(orders, Profile::new) .orTimeout(2, TimeUnit.SECONDS) .join();
12

Write a minimal Dockerfile for a Spring Boot application.

Save to ▾
Show answer
A multi-stage build keeps the image small. FROM eclipse-temurin:21-jdk AS build WORKDIR /app COPY . . RUN ./mvnw -q package -DskipTests FROM eclipse-temurin:21-jre WORKDIR /app COPY --from=build /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "app.jar"] Spring Boot can also build images without a Dockerfile using mvn spring-boot:build-image.
13

What is the difference between Collectors.toMap() and groupingBy()?

Save to ▾
Show answer
toMap() creates one entry per element using key and value functions and throws IllegalStateException on duplicate keys unless you give a merge function. groupingBy() collects all elements with the same key into a List by default, or applies a downstream collector like counting or summingInt. Use toMap for unique keys like id and groupingBy for categories like city.
14

What is CompletableFuture and how is it better than Future?

Save to ▾
Show answer
Future only lets you block with get() to obtain a result. CompletableFuture supports non-blocking composition: thenApply to transform, thenCompose to chain async calls, thenCombine or allOf to join several, and exceptionally or handle for errors. It runs on the common ForkJoinPool by default, but pass your own executor for blocking I/O to avoid starving the pool.
15

Explain bean scopes in Spring.

Save to ▾
Show answer
singleton is the default: one instance per application context. prototype creates a new instance each time it is requested. Web scopes include request, session and application. Singletons must be stateless or thread safe because all requests share them. Injecting a prototype into a singleton gives only one instance, so use ObjectProvider or a scoped proxy to get fresh ones.
16

You need to add a new payment method to a system that has a big if-else on payment type. How would you redesign it?

Save to ▾
Show answer
This breaks the Open/Closed principle. I would create a PaymentProcessor interface with a pay() method and one implementation per type, such as UpiProcessor and CardProcessor. A factory or a Spring map of beans keyed by type picks the right one. Adding a new method then means adding one new class without touching existing tested code, and each processor can be unit tested alone.
17

Write a unit test for a service class using JUnit 5 and Mockito.

Save to ▾
Show answer
Mock the repository and verify behaviour. @ExtendWith(MockitoExtension.class) class ProductServiceTest { @Mock ProductRepository repo; @InjectMocks ProductService service; @Test void throwsWhenMissing() { when(repo.findById(1L)).thenReturn(Optional.empty()); assertThrows(NotFoundException.class, () -> service.get(1L)); verify(repo).findById(1L); } } No Spring context starts, so the test runs in milliseconds.
18

Implement an LRU cache using LinkedHashMap.

Save to ▾
Show answer
Access order plus removeEldestEntry gives LRU in a few lines. class LruCache<K, V> extends LinkedHashMap<K, V> { private final int capacity; LruCache(int capacity) { super(16, 0.75f, true); this.capacity = capacity; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> e) { return size() > capacity; } } get and put are O(1).
19

How do you take a thread dump and a heap dump of a running Java process?

Save to ▾
Show answer
Find the process id with jps or ps, then use jcmd, which is the recommended tool. jps -l jcmd <pid> Thread.print > threads.txt jcmd <pid> GC.heap_dump /tmp/heap.hprof Older tools jstack and jmap do the same. Take three thread dumps a few seconds apart to spot stuck threads, and analyse heap dumps in Eclipse MAT.
20

What is the difference between reduce() and collect()?

Save to ▾
Show answer
reduce() combines elements into a single immutable value using an identity and an associative function, such as summing numbers. collect() is a mutable reduction that accumulates into a container like a List, Map or StringBuilder, which is far more efficient for building collections. Using reduce to build a list creates many intermediate copies, so use collect for containers.
21

You need a cache that evicts the least recently used item when full. How would you build it in Java?

Save to ▾
Show answer
Extend LinkedHashMap with accessOrder set to true and override removeEldestEntry to return true when size exceeds capacity. Each get moves the entry to the end, so the eldest is the least recently used. It is not thread safe, so wrap it with synchronization for shared use. In production prefer Caffeine, which offers size and time based eviction with high concurrency.
22

Map a one-to-many relation between Order and OrderItem in JPA.

Save to ▾
Show answer
Make the child own the foreign key and keep both sides in sync. @Entity class Order { @Id @GeneratedValue Long id; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) List<OrderItem> items = new ArrayList<>(); void addItem(OrderItem i) { items.add(i); i.setOrder(this); } } @Entity class OrderItem { @Id @GeneratedValue Long id; @ManyToOne(fetch = FetchType.LAZY) Order order; }
23

Group a list of orders by city and sum the amount per city.

Save to ▾
Show answer
Use groupingBy with a summing collector. Map<String, Double> totals = orders.stream() .collect(Collectors.groupingBy( Order::city, TreeMap::new, Collectors.summingDouble(Order::amount))); TreeMap keeps cities sorted. For money, store amounts as long paise or BigDecimal and use Collectors.reducing with BigDecimal::add.
24

Explain the happens-before relationship in the Java Memory Model.

Save to ▾
Show answer
Happens-before is the rule that guarantees one action's effects are visible to another. Examples: unlocking a monitor happens-before a later lock of the same monitor, a volatile write happens-before later reads of it, Thread.start() happens-before actions in the started thread, and actions in a thread happen-before another thread's successful join() on it. Without such an edge, threads may see stale or reordered values.
25

Clients report duplicate orders when they retry after a timeout. How do you prevent it?

Save to ▾
Show answer
Make the create order API idempotent. The client sends an Idempotency-Key header; the server stores the key with the result in a table with a unique constraint or in Redis. A retry with the same key returns the saved response instead of creating a new order. Database unique constraints on business keys add another safety net.
26

Production shows Connection is not available, request timed out after 30000ms from HikariCP. What do you check?

Save to ▾
Show answer
The pool is exhausted. Check for connection leaks, where code holds connections without closing, by setting leakDetectionThreshold. Look for long transactions doing remote calls inside @Transactional, slow queries holding connections and a pool size too small for the thread count. Fix leaks, move external calls outside transactions, optimise slow queries and then size the pool from load tests.
27

Two scheduled jobs on different servers process the same records twice. How do you prevent this?

Save to ▾
Show answer
In-JVM locks do not work across servers. Use a distributed lock such as ShedLock with a database table or Redis, so only one instance runs the job at a time. Make the processing idempotent too, for example by marking records with a status and updating with WHERE status = 'NEW' so only one worker claims each row. Database SELECT FOR UPDATE SKIP LOCKED also works well.
28

Explain the entity lifecycle states in JPA.

Save to ▾
Show answer
Transient: a new object not yet linked to a persistence context. Managed (persistent): attached to the context, so changes are tracked and flushed automatically through dirty checking. Detached: was managed but the context closed or it was evicted; changes are not tracked until merge(). Removed: scheduled for deletion on flush. persist, merge, detach and remove move entities between these states.
29

What does the volatile keyword guarantee?

Save to ▾
Show answer
volatile guarantees visibility and ordering: a write to a volatile field is immediately visible to other threads, and it prevents reordering around that access under the Java Memory Model. It does not make compound operations like count++ atomic, because that is a read, modify and write. Use it for flags such as a stop signal, and use AtomicInteger or locks for counters.
30

Write a custom unchecked exception and a Spring handler that returns HTTP 404.

Save to ▾
Show answer
Define the exception, then map it centrally. public class NotFoundException extends RuntimeException { public NotFoundException(String msg) { super(msg); } } @RestControllerAdvice public class ApiErrors { @ExceptionHandler(NotFoundException.class) public ProblemDetail notFound(NotFoundException e) { return ProblemDetail.forStatusAndDetail( HttpStatus.NOT_FOUND, e.getMessage()); } }
31

What are sealed classes and how do they help?

Save to ▾
Show answer
Sealed classes and interfaces, final in Java 17, restrict which classes can extend them using the permits clause, for example sealed interface Shape permits Circle, Square. Each subclass must be final, sealed or non-sealed. This models a closed set of types, and with pattern matching for switch in Java 21 the compiler can check that every case is handled without a default branch.
32

Write a thread safe singleton class in Java.

Save to ▾
Show answer
The simplest safe options are an enum or the holder idiom. public class Config { private Config() {} private static class Holder { static final Config INSTANCE = new Config(); } public static Config getInstance() { return Holder.INSTANCE; } } The JVM loads Holder lazily and class initialisation is thread safe. An enum singleton also resists reflection and serialization attacks.
33

What does effectively final mean for lambdas?

Save to ▾
Show answer
A lambda can use a local variable from the enclosing method only if that variable is final or effectively final, meaning it is never reassigned after initialisation. Lambdas capture the value, not the variable, so this avoids confusing behaviour and races. To accumulate results, use a stream collector or an AtomicInteger instead of changing a captured local.
34

Implement the Builder pattern for a User class with many optional fields.

Save to ▾
Show answer
A builder avoids long constructors. public class User { private final String name; private final int age; private User(Builder b) { name = b.name; age = b.age; } public static class Builder { private String name; private int age; public Builder name(String n) { name = n; return this; } public Builder age(int a) { age = a; return this; } public User build() { return new User(this); } } } Usage: new User.Builder().name("Asha").age(25).build(). Lombok @Builder generates this.
35

What are transaction isolation levels and which problems do they prevent?

Save to ▾
Show answer
Read Uncommitted allows dirty reads. Read Committed prevents dirty reads and is the default in PostgreSQL and SQL Server. Repeatable Read also prevents non-repeatable reads and is the MySQL InnoDB default. Serializable prevents phantom reads too but reduces concurrency. Choose the lowest level that keeps data correct, and use explicit locking for specific hot rows.
36

Write a Java program to check whether a number is prime.

Save to ▾
Show answer
Check divisibility only up to the square root, which makes it O(sqrt n). public static boolean isPrime(int n) { if (n < 2) return false; if (n % 2 == 0) return n == 2; for (int i = 3; (long) i * i <= n; i += 2) { if (n % i == 0) return false; } return true; } The long cast avoids overflow for large n.
37

What is a ClassLoader and what is the delegation model?

Save to ▾
Show answer
A ClassLoader loads .class files into the JVM. The main loaders are Bootstrap (core classes), Platform (formerly Extension) and Application (classpath). In the parent delegation model a loader first asks its parent to load a class and only loads it itself if the parent cannot. This prevents user code from replacing core classes like java.lang.String.
38

What is the difference between an abstract class and an interface in modern Java?

Save to ▾
Show answer
An abstract class can have state (instance fields), constructors and any access modifier, and a class can extend only one. An interface has no instance state but, since Java 8, can have default and static methods, and since Java 9 private methods; a class can implement many. Use an interface for a capability contract and an abstract class to share code and state among closely related classes.
39

What is the difference between JPA, Hibernate and Spring Data JPA?

Save to ▾
Show answer
JPA, now Jakarta Persistence, is a specification of interfaces and annotations for object relational mapping. Hibernate is the most popular implementation of that specification and adds its own features. Spring Data JPA sits on top and generates repository implementations from interfaces and method names like findByEmail, reducing boilerplate. Your code uses JPA annotations, Hibernate does the work and Spring Data simplifies access.
40

When should you avoid parallel streams?

Save to ▾
Show answer
Parallel streams use the common ForkJoinPool and help only for large, CPU-bound, stateless work on sources that split well, like arrays and ArrayList. Avoid them for small data, I/O or blocking calls, LinkedList or iterate() sources, ordered operations like limit and findFirst, and shared mutable state. In a web server they compete for the same common pool, so measure before using them.

Frequently asked questions

What happens in the Java technical round round?

The technical round is the core of a Java interview: concept questions with follow-ups, a live hands-on task and a deep dive into one of your projects. Interviewers check depth, not just definitions.

How do I clear the technical round round?

Say your approach out loud before you start writing. After a correct answer, expect 'why?' and 'what if?' follow-ups; go one level deeper than the question. Pick one project you can explain end to end, including what you would do differently.

Which round comes next?

A typical order is online assessment, telephonic screening, one or two technical rounds, a managerial round and HR. Use the other round pages to practise each stage.