Java interview questions test your understanding of object-oriented programming, the JVM, collections, concurrency, and modern Java features. Java is still one of the most common languages in backend and enterprise hiring, and interviewers expect you to explain design trade-offs, not just recall syntax. This page covers 40 real Java interview questions with answers across four formats: multiple choice, written answers, spoken responses, and live coding challenges, the same mix used in modern technical interviews.
Practice each question in your browser with no signup required. Answers stay hidden until you attempt the question: type, speak, or code your response first, then compare it against the model answer. Questions range from fundamentals for your first developer job to scenario-based questions for senior roles, so you can find the gaps in your knowledge before the real interview.
40 questions with answersLast updated: Oct 19, 2026
Choose a question. Pick any of the 40 questions. They mix multiple choice, written, spoken, and coding, the same mix a real interviewer uses.
Attempt your answer. Select a multiple-choice option, type your written response, record a spoken answer, or write code in the editor.
Reveal the model answer. Once you have attempted the question, the model answer unlocks so you can compare it with yours.
Move to the next question. Track how many questions you have attempted with the progress bar at the top of the page.
Take a mock interview. When you are ready, try a full mock technical interview on Plaicer with AI-driven follow-up questions.
Java Interview Questions and Answers
0 of 40 attempted
1Multiple choice
How does Java achieve platform independence across different operating systems?
Attempt the question first to reveal the answer.
Answer
Java source code is compiled into platform-independent bytecode that the JVM interprets, enabling the same program to run on any OS with a JVM installed.
2Written answer
Explain how Java achieves the Write Once, Run Anywhere principle through bytecode and the JVM
Attempt the question first to reveal the answer.
Answer
Java source code is compiled by javac into platform-independent bytecode (.class files). The bytecode is not machine code but an intermediate representation. When the program runs, the JVM interprets this bytecode and translates it to the host operating system's native machine code. Since JVMs exist for Windows, Linux, macOS, and other OSes, the same bytecode can execute on any platform with a compatible JVM. This separation of compilation from execution is what enables WORA.
3Spoken answer
Describe a situation where you had to debug a NullPointerException in production and how you resolved it
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I started by checking the stack trace to identify the exact line. The issue was accessing a method on an object that hadn't been initialized. I added null checks before use and improved validation in the initialization code. I also added logging to help catch similar issues earlier. The fix involved both defensive coding and better error handling to fail fast.
4Coding
Create a BankAccount class that handles deposits and withdrawals with thread-safe operations
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public synchronized void deposit(double amount) {
// Implement deposit logic
}
public synchronized void withdraw(double amount) throws InsufficientFundsException {
// Implement withdrawal logic
}
public synchronized double getBalance() {
return balance;
}
}
Attempt the question first to reveal the answer.
Answer
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
if (initialBalance < 0) throw new IllegalArgumentException();
this.balance = initialBalance;
}
public synchronized void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException();
balance += amount;
}
public synchronized void withdraw(double amount) throws Exception {
if (amount <= 0) throw new IllegalArgumentException();
if (amount > balance) throw new Exception("Insufficient balance");
balance -= amount;
}
public synchronized double getBalance() {
return balance;
}
}
5Multiple choice
Explain the role of the Java Virtual Machine in program execution
Attempt the question first to reveal the answer.
Answer
The JVM executes Java bytecode and acts as a bridge between Java programs and the underlying operating system, managing memory and runtime execution.
6Written answer
Describe how the JVM acts as an intermediary between compiled Java code and the operating system
Attempt the question first to reveal the answer.
Answer
The JVM acts as a translator and executor. It receives bytecode, verifies it for security, and executes it by translating bytecode instructions to native machine code. The JVM manages OS-level resources on behalf of Java programs, including memory allocation, thread creation, and system calls. This abstraction layer shields Java code from OS differences, allowing the same bytecode to run anywhere a JVM is available, while the JVM handles OS-specific details.
7Spoken answer
Explain how you would approach optimizing a Java application that has memory leaks
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I profiled the application using JProfiler to find objects not being garbage collected. I discovered unclosed file handles and database connections holding memory. I wrapped resources in try-with-resources blocks and added proper cleanup in finally blocks. I also analyzed static collections that were growing indefinitely and implemented proper eviction policies.
8Coding
Create an inventory system where products can be added, sold, and restocked
public class InventoryItem {
private String productName;
private int quantity;
private double price;
public InventoryItem(String productName, int quantity, double price) {
this.productName = productName;
this.quantity = quantity;
this.price = price;
}
public void sell(int units) throws OutOfStockException {
// Implement sell logic
}
public void restock(int units) {
// Implement restock logic
}
}
Attempt the question first to reveal the answer.
Answer
public class InventoryItem {
private String productName;
private int quantity;
private double price;
public InventoryItem(String productName, int quantity, double price) {
this.productName = productName;
this.quantity = quantity;
this.price = price;
}
public void sell(int units) throws Exception {
if (units > quantity) throw new Exception("Out of stock");
quantity -= units;
}
public void restock(int units) {
if (units < 0) throw new IllegalArgumentException();
quantity += units;
}
}
9Multiple choice
What is the Just-in-Time compiler and when does it activate during runtime?
Attempt the question first to reveal the answer.
Answer
JIT is part of the JVM that compiles bytecode to native machine code when methods are invoked repeatedly, significantly improving execution speed.
10Written answer
Explain the compilation process from source code through bytecode to native machine code
Attempt the question first to reveal the answer.
Answer
The compilation happens in stages: (1) javac compiler reads .java source files and compiles them to .class bytecode files; (2) The JVM loads bytecode at runtime and verifies it for correctness; (3) The JIT compiler monitors which methods are called frequently; (4) When a method is invoked multiple times, JIT compiles it from bytecode to native machine code; (5) Subsequent calls to that method execute the optimized native code directly, avoiding interpretation and improving performance significantly.
11Spoken answer
Walk through how you would implement a thread-safe singleton pattern and why each design choice matters
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created a private constructor to prevent instantiation, used eager initialization in a static block to ensure thread safety at class loading, and synchronized the getInstance() method as a backup. I explained why double-checked locking is an anti-pattern in Java and why the class loader guarantees thread safety. I showed how to test it under concurrent access.
12Coding
Write a method to process data from a file with proper exception handling and resource cleanup
import java.io.*;
import java.util.*;
public class DataProcessor {
public List<String> processFile(String filePath) {
// Implement file reading with try-with-resources
}
}
Attempt the question first to reveal the answer.
Answer
import java.io.*;
import java.util.*;
public class DataProcessor {
public List<String> processFile(String filePath) {
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
return lines;
}
}
13Multiple choice
Describe the different memory areas that the JVM allocates for a Java application
Attempt the question first to reveal the answer.
Answer
JVM memory consists of heap (objects), stack (method frames), method area (class metadata), PC register, and native method stack.
14Written answer
Describe each memory area in the JVM and what data is stored in each
Attempt the question first to reveal the answer.
Answer
The JVM allocates five memory areas: (1) Heap stores all object instances and class instance variables, shared across threads; (2) Stack stores method frames, local variables, and return values, with each thread having its own stack; (3) Method Area stores class structures, method data, bytecode, and static variables; (4) Program Counter Register tracks the instruction being executed; (5) Native Method Stack contains information about native methods. Garbage collection reclaims heap memory, while stack memory is automatically reclaimed when methods return.
15Spoken answer
Describe the difference between using synchronized blocks versus ReentrantLock for concurrent access
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I explained that synchronized is simpler but blocks all threads trying to acquire the lock. ReentrantLock offers tryLock() for timeout-based attempts, fair scheduling, and the ability to lock in one method and unlock in another. I recommended ReentrantLock for complex scenarios where you need fine-grained control, but synchronized for simple cases where its simpler semantics are sufficient.
16Coding
Create a thread-safe counter that increments when incremented from multiple threads
public class ThreadSafeCounter {
private int count = 0;
public void increment() {
// Implement thread-safe increment
}
public int getCount() {
// Implement thread-safe read
}
}
Attempt the question first to reveal the answer.
Answer
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadSafeCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
17Multiple choice
What responsibility does the ClassLoader component have in the JVM?
Attempt the question first to reveal the answer.
Answer
ClassLoader is responsible for loading .class files into JVM memory dynamically, improving efficiency by loading classes only when required.
18Written answer
Explain how the ClassLoader loads classes dynamically and the types of ClassLoaders
Attempt the question first to reveal the answer.
Answer
ClassLoader is responsible for loading .class files into JVM memory at runtime. There are three types: (1) Bootstrap ClassLoader loads core Java classes from JDK; (2) Extension ClassLoader loads classes from the extension directories; (3) Application ClassLoader loads classes from the application classpath. ClassLoaders follow a delegation model where a child asks its parent before loading a class. This enables dynamic loading, where classes are loaded only when needed, improving memory efficiency and startup time.
19Spoken answer
Explain how you would design a connection pool for managing database connections efficiently
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I designed a pool with a fixed number of connections, a queue for waiting requests, and proper lifecycle management. When a connection is requested, it's either reused from the pool or created if capacity allows. Idle connections are closed after a timeout. I included monitoring to track pool utilization and implemented proper error handling for failed connections.
20Coding
Write a method to parse email addresses and validate their format
import java.util.regex.*;
public class EmailValidator {
private static final String EMAIL_REGEX = "";
public boolean isValidEmail(String email) {
// Implement validation logic
}
}
Attempt the question first to reveal the answer.
Answer
import java.util.regex.*;
public class EmailValidator {
private static final String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@(.+)$";
public boolean isValidEmail(String email) {
if (email == null) return false;
Pattern pattern = Pattern.compile(EMAIL_REGEX);
return pattern.matcher(email).matches();
}
}
21Multiple choice
How does JDBC enable Java applications to interact with relational databases?
Attempt the question first to reveal the answer.
Answer
JDBC (Java Database Connectivity) is an API that allows Java applications to connect to and interact with relational databases using SQL.
22Written answer
Describe the components and steps required to connect a Java application to a database
Attempt the question first to reveal the answer.
Answer
JDBC connection requires these steps: (1) Import java.sql package containing JDBC classes; (2) Load the database driver using Class.forName(); (3) Establish connection using DriverManager.getConnection() with database URL, username, and password; (4) Create Statement or PreparedStatement to execute queries; (5) Execute queries using executeQuery() for SELECT or executeUpdate() for INSERT/UPDATE/DELETE; (6) Process ResultSet if results are returned; (7) Close ResultSet, Statement, and Connection to release resources. JDBC abstracts database-specific details, allowing the same code to work with different databases by changing drivers.
23Spoken answer
Walk through how you would implement custom exception classes for a banking application
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created a base PaymentException and specific subclasses like InsufficientFundsException, InvalidAccountException, and TransactionFailedException. Each carried relevant context like account details or transaction ID. This allowed calling code to catch specific exceptions and handle them appropriately, while generic catch blocks could still catch all payment-related errors.
24Coding
Use Java Streams to filter and transform a collection of user objects
import java.util.*;
import java.util.stream.*;
public class UserProcessor {
public List<String> getActiveUserEmails(List<User> users) {
// Use streams to filter and map users
}
}
Attempt the question first to reveal the answer.
Answer
import java.util.*;
import java.util.stream.*;
public class UserProcessor {
public List<String> getActiveUserEmails(List<User> users) {
return users.stream()
.filter(User::isActive)
.map(User::getEmail)
.collect(Collectors.toList());
}
}
25Multiple choice
Explain the process of creating a copy of an existing object in Java
Attempt the question first to reveal the answer.
Answer
Object cloning is achieved by implementing the Cloneable interface and overriding the clone() method to create independent copies.
26Written answer
Distinguish between shallow copy and deep copy when cloning objects
Attempt the question first to reveal the answer.
Answer
Shallow copy creates a new object but copies only field values. For reference types, the copy and original share references to the same nested objects in memory. Changes to shared objects affect both copies. Deep copy recursively copies all referenced objects, creating completely independent clones where the copy has its own nested objects. Shallow copy is faster but can lead to unexpected shared state changes. Deep copy is slower but provides true independence. The clone() method performs shallow copy by default; achieving deep copy requires custom implementation.
27Spoken answer
Describe how you would migrate legacy code from ArrayList to Stream API while maintaining backward compatibility
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created a wrapper class that converted ArrayList operations to Stream operations internally, maintaining the same public API. I refactored internal methods to return streams, allowing modern code to chain operations. I kept the old ArrayList-based methods deprecated but functional for backward compatibility, allowing gradual migration across the codebase.
28Coding
Sort a list of employee records by salary in descending order using a Comparator
import java.util.*;
public class EmployeeManager {
public List<Employee> sortBySalary(List<Employee> employees) {
// Implement sorting with custom comparator
}
}
Attempt the question first to reveal the answer.
Answer
import java.util.*;
public class EmployeeManager {
public List<Employee> sortBySalary(List<Employee> employees) {
return employees.stream()
.sorted(Comparator.comparingDouble(Employee::getSalary).reversed())
.collect(Collectors.toList());
}
}
29Multiple choice
How does Java handle errors and unexpected events during program execution?
Attempt the question first to reveal the answer.
Answer
Java exception handling uses try-catch-finally blocks to catch exceptions, handle them, and ensure cleanup operations are performed.
30Written answer
Explain the hierarchy of exception classes and how try-catch-finally blocks work
Attempt the question first to reveal the answer.
Answer
Exception hierarchy starts with Throwable, which has two branches: Exception (for recoverable errors) and Error (for serious JVM problems). Exceptions are either Checked (must be caught or declared, like IOException) or Unchecked (RuntimeExceptions like NullPointerException). Try-catch-finally blocks work by: try block executes code that might throw exceptions; catch blocks handle specific exception types; finally block always executes regardless of exceptions, used for cleanup. Multiple catch blocks can handle different exceptions. The first matching catch block executes, then control passes to finally if present.
31Spoken answer
Explain your approach to choosing between inheritance and composition when designing class hierarchies
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I preferred composition: instead of Dog extends Animal, I used Dog has-an Animal. This avoided tight coupling and deep inheritance hierarchies. Inheritance is appropriate for true IS-A relationships with shared behavior; composition is safer for HAS-A relationships where the part can be replaced.
32Coding
Create a generic Pair class that can hold two objects of any type
public class Pair<K, V> {
private K first;
private V second;
public Pair(K first, V second) {
this.first = first;
this.second = second;
}
public K getFirst() {
return first;
}
public V getSecond() {
return second;
}
}
Attempt the question first to reveal the answer.
Answer
public class Pair<K, V> {
private K first;
private V second;
public Pair(K first, V second) {
this.first = first;
this.second = second;
}
public K getFirst() { return first; }
public V getSecond() { return second; }
public void setFirst(K first) { this.first = first; }
public void setSecond(V second) { this.second = second; }
}
33Multiple choice
How do compile-time and runtime exceptions differ in their handling requirements?
Attempt the question first to reveal the answer.
Answer
Checked exceptions (like IOException) are verified by compiler and must be handled; unchecked exceptions (like NullPointerException) occur at runtime without compile-time checks.
34Written answer
Compare how checked and unchecked exceptions are handled differently by the compiler
Attempt the question first to reveal the answer.
Answer
Checked exceptions are verified by the compiler at compile time. If a method throws a checked exception (like IOException or SQLException), either the method must catch it with try-catch or declare it in the method signature using throws. Failure to handle this results in a compile error. Unchecked exceptions (RuntimeExceptions like NullPointerException or ArithmeticException) are not verified by the compiler. No try-catch or throws declaration is required. These exceptions typically indicate programming errors and are usually not caught, allowing the program to terminate with a stack trace. This design forces developers to consciously handle recoverable errors while letting programming mistakes propagate.
35Spoken answer
Describe how you would implement proper garbage collection tuning for a high-throughput application
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I tuned heap sizes appropriately for the application's workload, selected the right garbage collector (G1GC for large heaps), and adjusted the young/old generation ratio. I monitored GC logs to identify long pause times and adjusted accordingly. For a high-throughput system, I prioritized throughput by using parallel GC or minimized pauses using low-latency collectors.
36Coding
Implement a thread-safe singleton for database connection management
public class DatabaseConnection {
// Implement singleton pattern
private DatabaseConnection() {
}
public static DatabaseConnection getInstance() {
// Return singleton instance
}
}
Attempt the question first to reveal the answer.
Answer
public class DatabaseConnection {
private static DatabaseConnection instance;
private DatabaseConnection() {}
public static synchronized DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
}
37Multiple choice
How does multithreading enable concurrent execution within a single Java process?
Attempt the question first to reveal the answer.
Answer
Multithreading enables multiple threads to run concurrently within a single process, each with its own stack but sharing heap memory.
38Written answer
Explain the thread lifecycle and how threads communicate and synchronize with each other
Attempt the question first to reveal the answer.
Answer
Thread lifecycle has five states: (1) New when created but not started; (2) Runnable when start() is called, ready to execute; (3) Blocked when waiting for a lock; (4) Waiting when wait() is called, waiting for notification; (5) Terminated after run() completes. Threads communicate through shared memory or wait/notify mechanisms. Synchronization ensures only one thread accesses critical sections: synchronized methods/blocks use object locks (monitors); volatile keyword ensures variable visibility; wait() pauses a thread until notify() wakes it; join() waits for another thread to complete. Without proper synchronization, race conditions and data corruption can occur in multithreaded applications.
39Spoken answer
Walk through how you would handle concurrent modifications to a shared collection in a multithreaded system
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I used CopyOnWriteArrayList for frequent reads or Collections.synchronizedList() for balanced access. For multiple collections, I implemented proper ordering of lock acquisition to avoid deadlocks. I also considered using concurrent collections like ConcurrentHashMap that allow multiple threads to access different segments simultaneously.
40Coding
Implement a custom Iterator for a collection that filters elements during iteration
import java.util.*;
public class FilteredList<T> implements Iterable<T> {
private List<T> items;
public FilteredList(List<T> items) {
this.items = items;
}
@Override
public Iterator<T> iterator() {
// Return custom iterator that filters
}
}
Attempt the question first to reveal the answer.
Answer
import java.util.*;
public class FilteredList<T> implements Iterable<T> {
private List<T> items;
public FilteredList(List<T> items) {
this.items = items;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int index = 0;
public boolean hasNext() {
return index < items.size();
}
public T next() {
return items.get(index++);
}
};
}
}
Topics covered
JVM fundamentals: platform independence, bytecode, the JIT compiler
JVM memory areas and garbage collection tuning
Class loading: the ClassLoader and dynamic loading
Object-oriented design: inheritance vs composition, custom classes
Exception handling: checked vs unchecked, try-catch-finally, try-with-resources
Streams and Comparators: filtering, mapping, sorting
Generics and custom iterators
Design patterns and databases: Singleton, connection pooling, JDBC
Frequently asked questions
How many Java interview questions are on this page?
40 real Java interview questions across four formats: multiple choice (10), written answer (10), spoken answer (10), and coding (10).
Do I need to sign up to practice?
No. All 40 questions and model answers are free with no signup. You attempt each question first, and the model answer unlocks once you have engaged.
Who are these Java interview questions for?
Developers preparing for Java technical interviews at any level, from first job to senior engineer roles. Questions cover fundamentals through real-world scenarios.
What topics do the Java questions cover?
The questions cover JVM fundamentals, memory and garbage collection, and class loading. They also test object-oriented design, exception handling, and multithreading. Coding tasks include streams, generics, and thread-safe classes.
Can I practice coding questions in the browser?
Yes. Coding questions include starter code in an in-browser editor, so you can write your solution without installing anything.
How often are the questions updated?
The question bank is reviewed regularly and updated to reflect current Java interview patterns.
Can I take a full mock interview?
Yes. Plaicer's mock technical interview walks you through a realistic 30 to 45 minute interview with AI-driven follow-up questions.
Should I prepare for Java 8+ features or older versions?
Focus on modern Java (8 and later). Questions cover streams and Comparators alongside core OOP, the JVM, and multithreading.