Skip to content

Software Engineer (Java) Interview Questions & Answers

40 questions for Software Engineer (Java) interviews — 7 easy, 28 medium, 5 hard.

About the Software Engineer (Java) role

A software engineer in a Java team writes production code, participates in design discussions and owns modules of a larger system. Interviews test data structures, core Java, collections, SQL and Spring fundamentals, along with problem solving. Product companies and global capability centres in Bengaluru, Hyderabad, Pune and Gurugram hire for this title at fresher and mid levels. Over time engineers take ownership of services, join on-call rotations and contribute to design reviews and documentation.

Data structures Java concurrency Clean code SQL tuning Unit testing
Solved for this roleStart 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

You need a thread-safe singleton for a configuration loader. How do you implement it?

Core JavaMedium
Save to ▾
Show answer
The simplest safe options are an enum singleton or the holder idiom. With the holder idiom, a private static nested class holds the instance, and the JVM's class loading guarantees lazy, thread-safe initialisation without synchronization. Double-checked locking also works but needs a volatile field. In a Spring application you usually do not write singletons at all, because beans are singleton-scoped by default and the container manages them.
02

Write a record and use pattern matching in a switch expression.

Core JavaMedium
Save to ▾
Show answer
sealed interface Payment permits Card, Upi {} record Card(String number, double amount) implements Payment {} record Upi(String vpa, double amount) implements Payment {} static String describe(Payment p) { return switch (p) { case Card c when c.amount() > 50000 -> "High value card"; case Card c -> "Card ending " + c.number().substring(12); case Upi u -> "UPI to " + u.vpa(); }; } // Sealed types make the switch exhaustive without a default branch (Java 21).
03

What are fail-fast and fail-safe iterators?

Save to ▾
Show answer
Fail-fast iterators, used by ArrayList and HashMap, track a modification count and throw ConcurrentModificationException if the collection is structurally changed during iteration, except through the iterator's own remove. Fail-safe or weakly consistent iterators, used by CopyOnWriteArrayList and ConcurrentHashMap, work on a snapshot or tolerate concurrent changes and never throw that exception, but they may not show the latest updates.
04

You are loading about five lakh records into an ArrayList and a HashMap and memory spikes during loading. What can you do?

Save to ▾
Show answer
Both collections resize by copying when they grow, which causes temporary memory spikes. Pre-size them, for example new ArrayList<>(500000) and HashMap with capacity of expected size divided by 0.75. Better still, avoid holding everything at once: process the data in batches or stream it from the database with pagination. Use primitive-friendly structures or IntStream where possible to avoid boxing overhead.
05

How does HashMap work internally?

Save to ▾
Show answer
HashMap stores entries in an array of buckets. The key's hashCode is spread and masked to find a bucket index. Collisions are kept in a linked list, and since Java 8 a bucket converts to a red-black tree after 8 entries when capacity is at least 64, giving O(log n) worst case. When size exceeds capacity times load factor 0.75, the table doubles and entries are redistributed. get uses hashCode to find the bucket and equals to find the key.
06

Write code that runs tasks in parallel using ExecutorService and collects results.

Core JavaMedium
Save to ▾
Show answer
ExecutorService pool = Executors.newFixedThreadPool(4); try { List<Callable<Integer>> tasks = List.of( () -> fetchCount("orders"), () -> fetchCount("users")); List<Future<Integer>> results = pool.invokeAll(tasks); for (Future<Integer> f : results) { System.out.println(f.get()); } } finally { pool.shutdown(); } // On Java 21 you can use Executors.newVirtualThreadPerTaskExecutor() // for I/O-bound tasks.
07

You are designing a new feature. When would you choose a relational database and when a NoSQL database?

Save to ▾
Show answer
Choose a relational database like PostgreSQL or MySQL when data is structured, relationships matter and you need transactions and joins, such as orders, payments and inventory. Choose NoSQL when you need a flexible schema or huge horizontal scale for simple access patterns: MongoDB for documents, Redis for caching and sessions, Cassandra for high-write time series and Elasticsearch for search. Many systems use both, with SQL as the source of truth.
08

Find employees who earn more than their managers.

Save to ▾
Show answer
SELECT e.name AS employee, e.salary, m.name AS manager, m.salary AS manager_salary FROM employees e JOIN employees m ON e.manager_id = m.id WHERE e.salary > m.salary; -- A self join treats the same table as two roles.
09

Explain final, finally and finalize.

Save to ▾
Show answer
final is a keyword: a final variable cannot be reassigned, a final method cannot be overridden and a final class cannot be extended. finally is a block after try or catch that always runs, used for cleanup, although try-with-resources is now preferred. finalize() was an Object method called before garbage collection; it is deprecated for removal because its timing is unpredictable. Use Cleaner or try-with-resources instead.
10

Which features from Java 17 and Java 21 are useful for a full stack developer?

Core JavaMedium
Save to ▾
Show answer
Java 17 brought records for immutable data carriers, sealed classes to restrict inheritance, text blocks for multi-line JSON or SQL, and pattern matching for instanceof. Java 21, the current widely used LTS alongside 17, added virtual threads for cheap blocking concurrency, pattern matching for switch, record patterns and sequenced collections. Spring Boot 3 needs Java 17 or later, and from Boot 3.2 virtual threads can be enabled with one property.
11

Explain the difference between map and flatMap in streams.

Save to ▾
Show answer
map transforms each element into exactly one new element, so a Stream of orders mapped to customer names gives a Stream of String. flatMap transforms each element into a stream and flattens all of them into one stream. For example, orders.stream().flatMap(o -> o.getItems().stream()) gives every item from every order. Optional also has map and flatMap with the same idea.
12

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

Save to ▾
Show answer
If two objects are equal according to equals(), they must return the same hashCode. Unequal objects may share a hash code, but fewer collisions give better performance. If you override equals without hashCode, HashMap and HashSet will fail to find objects that are logically equal. Base both methods on the same immutable fields; records and IDE or Lombok generation create them correctly.
13

You need to store unique usernames and always display them in alphabetical order. Which collection do you pick?

Save to ▾
Show answer
A TreeSet fits because it rejects duplicates and keeps elements sorted using natural order or a Comparator, with O(log n) add and lookup. Use String.CASE_INSENSITIVE_ORDER as the comparator if Rahul and rahul should be treated as the same. If you only need sorting once at display time, a HashSet followed by sorting may be faster. For concurrent access, ConcurrentSkipListSet is the thread-safe sorted alternative.
14

Describe the main JVM memory areas.

Core JavaMedium
Save to ▾
Show answer
The heap stores objects and is shared by all threads; it is managed by the garbage collector and split into young and old generations. Each thread has its own stack holding method frames, local variables and references. Metaspace, in native memory since Java 8, stores class metadata. There is also the program counter per thread and the code cache for JIT-compiled code. Stack overflow comes from deep recursion, while OutOfMemoryError usually means heap or metaspace is full.
15

Users in different countries see wrong order times. How do you handle dates and time zones in Java?

Core JavaMedium
Save to ▾
Show answer
Store timestamps in UTC using Instant or OffsetDateTime, and map them to TIMESTAMP WITH TIME ZONE or a UTC timestamp column. Convert to the user's zone only when displaying, using ZonedDateTime with ZoneId such as Asia/Kolkata. Avoid java.util.Date and SimpleDateFormat, which are mutable and not thread-safe. Use DateTimeFormatter, send ISO-8601 strings in JSON and set hibernate.jdbc.time_zone to UTC.
16

How does garbage collection work in modern Java?

Core JavaMedium
Save to ▾
Show answer
The GC frees objects that are no longer reachable from GC roots such as thread stacks and static fields. Most objects die young, so the heap is generational: minor collections clean the young generation often and survivors are promoted. G1 is the default collector since Java 9 and targets predictable pause times by collecting regions. ZGC and Shenandoah offer sub-millisecond pauses for large heaps. Tuning usually starts with -Xmx and choosing the collector, not dozens of flags.
17

A report job builds a large string with + inside a loop and is very slow. What do you change?

Save to ▾
Show answer
Each + inside a loop creates a new String and copies the old content, giving roughly O(n squared) work. Replace it with one StringBuilder created before the loop, optionally with an initial capacity, and call append inside the loop. For joining collections, use String.join or Collectors.joining. For very large output, write directly to a BufferedWriter or stream instead of holding everything in memory.
18

How do you use EXPLAIN to analyse a slow query?

Save to ▾
Show answer
EXPLAIN ANALYZE SELECT o.id, o.total FROM orders o WHERE o.customer_id = 42 AND o.status = 'PAID' ORDER BY o.created_at DESC LIMIT 20; -- Look for: Seq Scan / type=ALL (full scan), large 'rows' estimates, -- 'Using filesort' or a Sort node, and actual time per step. -- Fix with: CREATE INDEX ix_orders_cust_status_date -- ON orders (customer_id, status, created_at DESC);
19

What is a functional interface and how do lambdas relate to it?

Save to ▾
Show answer
A functional interface has exactly one abstract method, such as Runnable, Comparator, Function, Predicate, Supplier or Consumer, and can be marked with @FunctionalInterface. A lambda expression is a short implementation of that single method, for example Predicate<String> empty = s -> s.isBlank(). Method references like String::toUpperCase are an even shorter form. Lambdas power the Streams API and callback-style code.
20

Under load, requests fail with a connection timeout from HikariCP. What do you check?

Save to ▾
Show answer
This means all pool connections are busy. Check for long-running queries, transactions held open during remote calls, and connection leaks from code that never closes resources; set leakDetectionThreshold to find them. Compare maximumPoolSize with the database's max connections across all instances, since a bigger pool is not always better. Monitor Hikari metrics through Actuator, fix slow queries and keep @Transactional boundaries short.
21

Tell me about a difficult bug you fixed in a Java project.

Core JavaMedium
Save to ▾
Show answer
Situation: our order API sometimes returned another user's cart. Task: I had to find the root cause quickly. Action: I reproduced it with a load test, found a Spring singleton service storing the current user in an instance field, and moved that state into a method parameter. I added a concurrent test to prevent regressions. Result: the issue disappeared and I shared the learning about stateless beans with the team.
22

What is the difference between a clustered and a non-clustered index?

Save to ▾
Show answer
A clustered index defines the physical order of rows, so the table data itself is stored in the index and there can be only one. In MySQL InnoDB the primary key is the clustered index. A non-clustered or secondary index is a separate structure holding the indexed columns and a pointer, or the primary key in InnoDB, to the row. That is why a short primary key keeps every secondary index smaller.
23

Write a Java method to check whether a string is a palindrome, ignoring case and spaces.

Save to ▾
Show answer
static boolean isPalindrome(String s) { String clean = s.replaceAll("\\s+", "").toLowerCase(); int i = 0, j = clean.length() - 1; while (i < j) { if (clean.charAt(i++) != clean.charAt(j--)) { return false; } } return true; } // Two pointers give O(n) time and O(n) space for the cleaned copy. // isPalindrome("Nurses Run") returns true.
24

How do you keep yourself updated with new Java versions and features?

Save to ▾
Show answer
I follow the six-monthly Java release notes and JEP summaries, and I try new features in small jshell experiments or side projects. For example, when Java 21 became LTS I rewrote a small file-processing tool using virtual threads and pattern matching to understand the benefits. I also read Spring release blogs and watch conference talks, and I share short notes with my team so we upgrade with confidence.
25

Tell me about a mistake you made with production data and how you handled it.

Save to ▾
Show answer
Situation: I ran an update script on production that missed a condition and changed status for more orders than intended. Task: correct it quickly and honestly. Action: I informed my lead immediately, stopped further jobs, used the audit table and a backup to restore the correct values and verified with the business team. Result: data was fixed within an hour. Since then, I always run scripts in a transaction with a row-count check first.
26

Your Spring Boot service crashes with OutOfMemoryError: Java heap space in production. How do you investigate?

Save to ▾
Show answer
First capture evidence: enable -XX:+HeapDumpOnOutOfMemoryError and check GC logs and container memory limits. Open the heap dump in Eclipse MAT or VisualVM and look at the dominator tree for the largest retained objects. Common causes are unbounded caches, loading full tables into lists, static collections that keep growing and large file reads. Fix the leak, add pagination or streaming, set a sensible -Xmx below the container limit and add memory alerts.
27

How do indexes improve performance, and when can they hurt?

Save to ▾
Show answer
An index, usually a B-tree, lets the database find rows without scanning the whole table, which speeds up WHERE, JOIN and ORDER BY on indexed columns. Indexes cost disk space and slow down INSERT, UPDATE and DELETE because each index must also be updated. They help little on low-selectivity columns like a boolean flag. Functions on the column, such as WHERE LOWER(email) = ?, or a leading wildcard in LIKE also prevent normal index use.
28

You get ConcurrentModificationException while removing items from a list inside a for-each loop. How do you fix it?

Save to ▾
Show answer
The for-each loop uses a fail-fast iterator, and calling list.remove changes the modification count. Use list.removeIf(item -> item.isExpired()), which is clean and efficient, or use an explicit Iterator and call iterator.remove(). Another option is to collect the items to keep into a new list with a stream filter. If several threads modify the list, use a concurrent collection instead.
29

Your code has frequent NullPointerExceptions from repository lookups. How would you redesign it?

Core JavaMedium
Save to ▾
Show answer
Return Optional from lookup methods so callers must handle the missing case, for example findById(id).orElseThrow(). Validate inputs at the API boundary with Bean Validation, initialise collections to empty lists instead of null and use Objects.requireNonNull in constructors. Java 17 helpful NPE messages show which variable was null, which speeds debugging. Do not use Optional for fields or method parameters; it is meant for return values.
30

What is the difference between lazy and eager fetching?

Save to ▾
Show answer
Lazy fetching loads an association only when it is first accessed, using a proxy. Eager fetching loads it immediately with the parent. By default, @OneToMany and @ManyToMany are lazy, while @ManyToOne and @OneToOne are eager. Best practice is to make all associations lazy and fetch what each use case needs with JOIN FETCH or entity graphs, because eager loading often pulls large object graphs and causes extra queries.
31

An object put into a HashMap cannot be found later even though it looks equal. What could be wrong?

Save to ▾
Show answer
Most likely a field used in hashCode was changed after insertion, so the object now hashes to a different bucket and get looks in the wrong place. It can also happen when equals is overridden without hashCode. Fix it by using immutable keys, such as records, Strings or IDs, and by basing equals and hashCode on fields that never change. Never mutate an object while it is a key in a hash-based collection.
32

Compare HashMap, Hashtable and ConcurrentHashMap.

Save to ▾
Show answer
HashMap is not synchronized and allows one null key and null values. Hashtable is a legacy class where every method is synchronized, so it is slow and allows no nulls. ConcurrentHashMap is the modern thread-safe choice: reads are mostly lock-free, writes lock only a single bucket using CAS and synchronized blocks, and it offers atomic methods such as computeIfAbsent and merge. It also does not allow null keys or values.
33

Explain transaction isolation levels and the problems each one prevents.

Save to ▾
Show answer
Read Uncommitted allows dirty reads. Read Committed, the default in PostgreSQL, Oracle and SQL Server, prevents dirty reads but allows non-repeatable reads. Repeatable Read, the default in MySQL InnoDB, keeps rows read stable within a transaction, and InnoDB also blocks most phantoms with gap locks. Serializable prevents all anomalies but reduces concurrency. Higher isolation means more locking or retries, so choose per use case and set it with @Transactional(isolation = ...).
34

Explain the architecture of your last full stack project end to end.

Save to ▾
Show answer
In my last project, a React single-page app called a Spring Boot REST API secured with JWT. The API followed controller, service and repository layers, used Spring Data JPA with MySQL and Flyway for migrations, and exposed Swagger documentation. I deployed it with Docker on a cloud VM behind Nginx. My contribution was the order module and payment status flow, and I also wrote the unit tests and CI pipeline.
35

Explain the different types of SQL joins.

Save to ▾
Show answer
INNER JOIN returns only rows that match in both tables. LEFT JOIN returns all rows from the left table plus matches from the right, with nulls where there is no match. RIGHT JOIN is the reverse. FULL OUTER JOIN returns all rows from both sides, which MySQL does not support directly. CROSS JOIN returns every combination. A self join joins a table to itself, such as employees and their managers.
36

Build a login form with basic validation in React.

Save to ▾
Show answer
function LoginForm({ onLogin }) { const [form, setForm] = useState({ email: '', password: '' }); const [errors, setErrors] = useState({}); const handleChange = e => setForm({ ...form, [e.target.name]: e.target.value }); const handleSubmit = e => { e.preventDefault(); const errs = {}; if (!/^\S+@\S+\.\S+$/.test(form.email)) errs.email = 'Enter a valid email'; if (form.password.length < 8) errs.password = 'Minimum 8 characters'; setErrors(errs); if (Object.keys(errs).length === 0) onLogin(form); }; return ( <form onSubmit={handleSubmit}> <input name="email" value={form.email} onChange={handleChange} /> {errors.email && <span>{errors.email}</span>} <input name="password" type="password" value={form.password} onChange={handleChange} /> {errors.password && <span>{errors.password}</span>} <button type="submit">Login</button> </form> ); }
37

When would you use the Context API and when a state library like Redux Toolkit or Zustand?

Save to ▾
Show answer
Context is good for passing low-frequency global values such as theme, language or the logged-in user without prop drilling. Every consumer re-renders when the context value changes, so it is not ideal for fast-changing data. Redux Toolkit or Zustand suit larger shared client state with many updates, selectors and dev tools. Server data like API responses is often best handled by TanStack Query, which adds caching and refetching.
38

What are the correct and incorrect ways to use Optional?

Save to ▾
Show answer
Use Optional as a return type when a value may be absent, and consume it with map, filter, orElse, orElseGet or orElseThrow. Avoid calling get() without checking, avoid Optional fields in entities or DTOs, avoid Optional parameters and never return null from a method that returns Optional. Prefer orElseGet over orElse when the default is expensive, because orElse always evaluates its argument.
39

Count the frequency of each word in a sentence.

Save to ▾
Show answer
String text = "java is fun and java is fast"; Map<String, Long> freq = Arrays.stream(text.toLowerCase().split("\\s+")) .collect(Collectors.groupingBy( Function.identity(), LinkedHashMap::new, Collectors.counting())); System.out.println(freq); // {java=2, is=2, fun=1, and=1, fast=1}
40

A search query that used to take milliseconds now takes 10 seconds as data grew. How do you troubleshoot?

Save to ▾
Show answer
Get the exact SQL from logs or the slow query log and run EXPLAIN ANALYZE to see whether it does a full scan, a bad join order or a big sort. Check for missing or unused indexes, functions on indexed columns, implicit type conversions and outdated statistics. Add the right composite index, rewrite the query, select fewer columns and paginate. For text search, use a full-text index or a search engine instead of LIKE '%term%'.

Frequently asked questions

What does a Software Engineer (Java) do?

A software engineer in a Java team writes production code, participates in design discussions and owns modules of a larger system. Interviews test data structures, core Java, collections, SQL and Spring fundamentals, along with problem solving. Product companies and global capability centres in Bengaluru, Hyderabad, Pune and Gurugram hire for this title at fresher and mid levels. Over time engineers take ownership of services, join on-call rotations and contribute to design reviews and documentation.

Which skills are tested in a Software Engineer (Java) interview?

Expect questions on Data structures, Java concurrency, Clean code, SQL tuning, Unit testing. Most rounds also ask you to explain a project and solve one practical problem live.

How do I prepare for a Software Engineer (Java) interview?

Revise Core Java, Collections and Streams, SQL and Databases first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.