Top 20 Java Scenario-Based Interview Questions for Experienced Developers
Practice production-style Java interview scenarios: collections, concurrency, JVM, immutability, caching, retries, and design—problem, approach, tradeoff.
Scenario-based Java interviews test one thing: can you apply Java to real production problems? Not recite definitions.
For experienced roles, expect depth in:
- Concurrency and multithreading
- JVM and memory
- Collections and performance tradeoffs
- Java 8+ APIs
- Design patterns and edge cases
Practice as problem → approach → tradeoff.
1. Large list of objects—remove duplicates efficiently?
Use a Set.
HashSet— fastestLinkedHashSet— preserves insertion order
For custom types, implement correct equals() / hashCode().
List<Employee> list = ...;
Set<Employee> unique = new LinkedHashSet<>(list);
List<Employee> result = new ArrayList<>(unique);
2. Handle NullPointerException in production?
Don’t “catch and pray.” Prevent:
- Validate at boundaries (API inputs)
- Prefer empty collections over null
- Use
Optionalonly when it clarifies APIs
List<Order> orders = Optional.ofNullable(service.getOrders())
.orElse(Collections.emptyList());
3. Thread-safe Singleton?
Practical options:
- Enum singleton — strong against serialization/reflection quirks
- Bill Pugh holder — lazy + thread-safe
class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton I = new Singleton();
}
public static Singleton getInstance() {
return Holder.I;
}
}
4. Checked exception without try-catch in the caller?
Propagate with throws:
void readFile() throws IOException {
// ...
}
5. Design a cache in Java?
Depends on needs:
- Simple in-memory:
ConcurrentHashMap - Production local: Caffeine / Ehcache
- Distributed: Redis
- Always discuss eviction (LRU/TTL) and invalidation (the hard part)
6. Concurrent modification while iterating?
Iterator.remove()when mutating during iterationCopyOnWriteArrayListfor read-heavy listsConcurrentHashMapfor concurrent maps
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("X")) {
it.remove();
}
}
7. Find a memory leak?
Tools: VisualVM, JProfiler, YourKit, Eclipse MAT. Take a heap dump; focus on retained size. Common causes: static references, caches without eviction, unclosed resources.
8. Create an immutable class?
finalclassprivate finalfields- No setters
- Defensive copies for mutable inputs
public final class Person {
private final String name;
private final List<String> tags;
public Person(String name, List<String> tags) {
this.name = name;
this.tags = List.copyOf(tags);
}
public String name() { return name; }
public List<String> tags() { return tags; }
}
9. Sort employees by salary, then name?
employees.stream()
.sorted(
Comparator.comparing(Employee::getSalary)
.thenComparing(Employee::getName)
)
.toList();
10. Safely stop a thread?
Use interruption or a volatile flag. Avoid deprecated Thread.stop().
class Worker implements Runnable {
private volatile boolean running = true;
public void stop() { running = false; }
public void run() {
while (running) {
// work
}
}
}
11. Exceptions in multi-threaded apps?
Thread.setUncaughtExceptionHandlerfor raw threads- For
ExecutorService, inspectFuture.get()(ExecutionException)
12. Detect deadlock?
jstack,jconsole, VisualVM- Programmatically:
ThreadMXBean.findDeadlockedThreads()
13. Ensure resource cleanup (file/DB)?
try-with-resources (preferred):
try (BufferedReader br = Files.newBufferedReader(path)) {
return br.readLine();
}
14. Prevent method overriding?
Mark the method final. Prevent inheritance with a final class.
15. Compare two JSON strings logically?
Parse to structured trees/maps; don’t compare raw string equality.
ObjectMapper om = new ObjectMapper();
JsonNode a = om.readTree(json1);
JsonNode b = om.readTree(json2);
boolean same = a.equals(b);
16. Process large files without OOM?
Stream line-by-line: BufferedReader or Files.lines() (close the stream).
17. Implement retry logic?
Exponential backoff + max attempts. Production: Resilience4j / Spring Retry.
int attempts = 0;
while (attempts < 3) {
try {
callApi();
break;
} catch (Exception e) {
attempts++;
Thread.sleep(200L * attempts);
}
}
18. Immutability in multi-threaded code?
Immutability is the simplest thread-safety: final fields, no setters, no shared mutable state, immutable collections.
19. Schedule a task every 10 seconds?
Prefer ScheduledExecutorService over Timer:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(task, 0, 10, TimeUnit.SECONDS);
20. Producer–consumer design?
BlockingQueue is the cleanest building block:
BlockingQueue<String> q = new ArrayBlockingQueue<>(100);
// producer
q.put("msg");
// consumer
String msg = q.take();
How to practice
For each item, rehearse:
- Clarifying questions (scale, latency, consistency)
- Default approach with API choices
- Tradeoffs and failure modes
Interviewers care less about trivia and more about whether you’ve felt these problems in production.