Prepare for your Java job interview with confidence! Explore a comprehensive collection of Java interview questions and answers covering essential topics such as object-oriented programming, data structures, concurrency, exception handling, and more.
Table of Contents
Detailed Java Interview Questions and Answers
- What are the main features of Java?
- Answer: Java features include simplicity, object-oriented nature, portability, robustness, security, multithreading capability, and high performance through Just-In-Time compilation.
- Explain the concept of OOP and its principles in Java.
- Answer: OOP principles in Java include:
- Encapsulation: Bundling data and methods that operate on the data within a single unit (class).
- Answer: OOP principles in Java include:
public class Person {
private String name; // Encapsulated field
public String getName() { // Public method to access the field
return name;
}
public void setName(String name) {
this.name = name;
}
}
Abstraction: Hiding complex implementation details and showing only necessary features.
abstract class Animal {
abstract void makeSound(); // Abstract method
}
class Dog extends Animal {
void makeSound() {
System.out.println("Bark");
}
}
Inheritance: A new class inherits properties and behavior from an existing class.
class Animal {
void eat() {
System.out.println("This animal eats food");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Bark");
}
}
Polymorphism: Methods do different things based on the object it is acting upon.
Animal myDog = new Dog();
myDog.makeSound(); // Outputs: Bark
3. What is the difference between JDK, JRE, and JVM?
- JDK (Java Development Kit): Contains tools for developing Java applications (JRE, compiler, debugger).
- JRE (Java Runtime Environment): Runs Java applications, includes JVM and standard libraries.
- JVM (Java Virtual Machine): Executes Java bytecode and provides a runtime environment.
4. Describe the memory management in Java.
Java uses automatic memory management with garbage collection. Memory is divided into heap (for objects) and stack (for method calls and local variables).
5. What is the Java Memory Model?
The Java Memory Model defines how threads interact through memory, ensuring visibility, ordering, and atomicity of shared variables.
6. How does garbage collection work in Java?
Garbage collection automatically frees memory by removing objects that are no longer referenced. Algorithms include mark-and-sweep and generational collection.
7. What are the different types of references in Java?
- Strong: Default type, prevents garbage collection.
- Soft: Used for caches, collected before OutOfMemoryError.
- Weak: Used for canonicalizing mappings, collected eagerly.
- Phantom: Used for cleanup actions, collected after finalization.
8. Explain the finalize() method.
The finalize()
method is called by the garbage collector before an object is collected. It’s used to clean up resources but is deprecated due to unpredictability.
9. What is the difference between ==
and equals()
in Java?
==
compares reference identity.equals()
compares object content.
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
10. What is the hashCode()
method? How is it related to equals()
?
The hashCode()
method returns an integer hash code for the object. If two objects are equal (equals()
returns true), they must have the same hash code to ensure correct functioning in hash-based collections.
public class Person {
private String name;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
11. Explain the use of the volatile
keyword.
The volatile
keyword ensures that the value of a variable is always read from main memory, not from a thread’s local cache. It guarantees visibility of changes to variables across threads.
private volatile boolean flag = true;
12. What are the differences between wait()
and sleep()
?
wait()
: Causes the current thread to release the monitor lock and wait until another thread invokesnotify()
ornotifyAll()
on the same object.sleep()
: Causes the current thread to pause execution for a specified time without releasing the monitor lock.
synchronized (obj) {
obj.wait(); // releases the lock on obj
}
Thread.sleep(1000); // pauses the current thread for 1 second
13. What is the difference between notify()
and notifyAll()
?
notify()
: Wakes up a single thread that is waiting on the object’s monitor.notifyAll()
: Wakes up all threads that are waiting on the object’s monitor.
synchronized (obj) {
obj.notify(); // wakes up one waiting thread
}
synchronized (obj) {
obj.notifyAll(); // wakes up all waiting threads
}
14. What is a deadlock? How can it be avoided?
A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a resource. It can be avoided by acquiring locks in a consistent order and using timeout for lock acquisition.
// Avoiding deadlock by acquiring locks in the same order
synchronized (lock1) {
synchronized (lock2) {
// critical section
}
}
15. What are the different types of thread pools in Java?
FixedThreadPool
: A fixed number of threads.CachedThreadPool
: Creates new threads as needed and reuses existing ones.SingleThreadExecutor
: A single worker thread.ScheduledThreadPool
: A pool that can schedule commands to run after a delay or periodically.
ExecutorService fixedPool = Executors.newFixedThreadPool(10);
ExecutorService cachedPool = Executors.newCachedThreadPool();
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(5);
16. Explain the use of the Callable
and Future
interfaces.
Callable
is similar to Runnable
but can return a result and throw a checked exception. Future
represents the result of an asynchronous computation, allowing us to retrieve the result once the computation is complete.
Callable<Integer> task = () -> {
return 123;
};
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // returns 123
Collections Framework
17. What is the Java Collections Framework?
The Java Collections Framework provides a set of interfaces (List, Set, Map) and implementations (ArrayList, HashSet, HashMap) for managing groups of objects.
18. Explain the difference between ArrayList and LinkedList.
ArrayList
: Uses a dynamic array, fast random access, slow insertions/deletions.LinkedList
: Uses a doubly-linked list, slower access, fast insertions/deletions.
List<String> arrayList = new ArrayList<>();
List<String> linkedList = new LinkedList<>();
19. How does HashMap work internally?
HashMap
uses an array of buckets, each bucket containing a linked list or a tree. The key’s hash code determines the bucket index. Collisions are resolved by chaining (linked list) or tree (if many elements).
Map<String, Integer> map = new HashMap<>();
map.put("key", 1);
20. What is the difference between HashSet and TreeSet?
HashSet
: UsesHashMap
, no order, constant-time performance.TreeSet
: UsesTreeMap
, maintains sorted order, log-time performance.
Set<String> hashSet = new HashSet<>();
Set<String> treeSet = new TreeSet<>();
21. What is the difference between Comparable and Comparator?
Comparable
: Defines natural ordering within the class by implementingcompareTo()
.Comparator
: Defines custom ordering outside the class by implementingcompare()
.
class Person implements Comparable<Person> {
private String name;
@Override
public int compareTo(Person other) {
return this.name.compareTo(other.name);
}
}
class PersonNameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
}
22. What is the use of the Collections
utility class?
The Collections
class provides static methods for manipulating collections, such as sorting, searching, and shuffling.
List<String> list = new ArrayList<>(Arrays.asList("b", "c", "a"));
Collections.sort(list); // sorts the list
23. Explain the Iterator
interface.
The Iterator
interface provides methods to iterate over a collection (hasNext()
, next()
, remove()
).
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
24. What is the difference between Iterator
and ListIterator
?
Iterator
allows traversing elements in one direction.ListIterator
extendsIterator
and allows bi-directional traversal and modification of elements.
List<String> list = new ArrayList<>();
ListIterator<String> listIterator = list.listIterator();
25. What is the LinkedHashMap
class?
LinkedHashMap
maintains a doubly-linked list of its entries, preserving insertion order or access order. It extends HashMap
.
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("one", 1);
26. What is the PriorityQueue
class?
PriorityQueue
is a queue that orders its elements according to their natural ordering or by a specified comparator. The head of the queue is the least element.
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.add(3);
priorityQueue.add(1);
priorityQueue.add(2);
System.out.println(priorityQueue.poll()); // Outputs: 1
27. How does the ConcurrentHashMap
class work?
ConcurrentHashMap
allows concurrent read and write operations by dividing the map into segments and locking only the affected segment during updates.
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("key", 1);
28. What is the TreeMap
class?
TreeMap
is a NavigableMap
implementation that uses a Red-Black tree. It orders its elements based on their natural ordering or by a specified comparator.
TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("b", 2);
treeMap.put("a", 1);
29. What is the difference between HashMap
and TreeMap
?
HashMap
provides constant-time performance for basic operations but does not maintain any order. TreeMap
provides log-time performance and maintains its elements in sorted order.
HashMap<String, Integer> hashMap = new HashMap<>();
TreeMap<String, Integer> treeMap = new TreeMap<>();
30. How does the WeakHashMap
class work?
WeakHashMap
uses weak references for its keys, allowing them to be garbage-collected if there are no strong references. It is useful for implementing canonicalizing mappings.
WeakHashMap<String, Integer> weakHashMap = new WeakHashMap<>();
31. Explain the CopyOnWriteArrayList
class.
CopyOnWriteArrayList
is a thread-safe variant of ArrayList
where all mutative operations (add, set, etc.) are implemented by making a fresh copy of the underlying array.
CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>();
32. What is the Deque
interface?
Deque
(Double Ended Queue) is an interface that extends Queue
and allows elements to be added or removed from both ends.
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("first");
deque.addLast("last");
33. Explain the BlockingQueue
interface.
BlockingQueue
is a queue that supports operations that wait for the queue to become non-empty when retrieving and waiting for space to become available when storing. It’s useful in producer-consumer scenarios.
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(10);
34. What is the difference between Iterator
and ListIterator
?
Iterator
allows traversing elements in one direction.ListIterator
extendsIterator
and allows bi-directional traversal and modification of elements.
List<String> list = new ArrayList<>();
ListIterator<String> listIterator = list.listIterator();
Concurrency and Multithreading
35. What is a Thread
in Java?
A Thread
is a lightweight process that can execute code concurrently with other threads within the same application.
Thread thread = new Thread(() -> System.out.println("Hello from a thread"));
thread.start();
36. What is the Runnable
interface?
Runnable
represents a task that can be executed by a thread. It has a single method run()
.
Runnable task = () -> System.out.println("Task is running");
Thread thread = new Thread(task);
thread.start();
37. What is the Callable
interface?
Callable
is similar to Runnable
but can return a result and throw a checked exception.
Callable<Integer> task = () -> 123;
38. Explain synchronized
methods and blocks.
Synchronization ensures that only one thread can execute a block of code at a time, preventing data inconsistency.
public synchronized void synchronizedMethod() {
// synchronized code
}
public void method() {
synchronized(this) {
// synchronized block
}
}
39. What are thread states in Java?
A thread can be in one of several states: NEW
, RUNNABLE
, BLOCKED
, WAITING
, TIMED_WAITING
, and TERMINATED
40. What is the ExecutorService
?
ExecutorService
is a high-level replacement for working with threads directly. It manages a pool of worker threads, allowing you to submit tasks for execution.
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
41. What is the difference between submit()
and execute()
methods in ExecutorService
?
execute()
: Executes aRunnable
task but does not return a result.submit()
: Submits aRunnable
orCallable
task and returns aFuture
representing the task’s result.
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(() -> System.out.println("Runnable executed"));
Future<Integer> future = executor.submit(() -> 123);
42. What is a CountDownLatch
?
CountDownLatch
is a synchronization aid that allows one or more threads to wait until a set of operations in other threads completes.
CountDownLatch latch = new CountDownLatch(3);
Runnable task = () -> {
System.out.println("Task completed");
latch.countDown();
};
new Thread(task).start();
latch.await(); // Main thread waits until the count reaches zero
43. What is a CyclicBarrier
?
CyclicBarrier
is a synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All tasks completed"));
Runnable task = () -> {
System.out.println("Task executed");
barrier.await();
};
new Thread(task).start();
44. Explain ReentrantLock
and its usage.
ReentrantLock
is a mutual exclusion lock with the same basic behavior as the implicit monitors accessed using synchronized
blocks but with extended capabilities. It allows for more flexible locking operations and is useful in advanced concurrency scenarios.
ReentrantLock lock = new ReentrantLock();
lock.lock(); // Acquires the lock
try {
// Critical section
} finally {
lock.unlock(); // Releases the lock
}
45. What is a Semaphore
?
Semaphore
is a synchronization primitive that restricts the number of threads that can access a resource concurrently. It maintains a set of permits to control access.
46. What is a BlockingQueue
?
BlockingQueue
is a queue that supports operations that wait for the queue to become non-empty when retrieving and wait for space to become available when storing. It’s useful in producer-consumer scenario
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(10);
47. Explain the ThreadLocal
class.
ThreadLocal
provides thread-local variables, allowing each thread to have its own independently initialized instance of the variable. It’s typically used to store per-thread context or avoid synchronization.
private static final ThreadLocal<Integer> threadId = ThreadLocal.withInitial(() -> Thread.currentThread().getId());
public static int getThreadId() {
return threadId.get();
}
48. What is the difference between start()
and run()
methods of the Thread
class?
start()
: Creates a new thread and starts its execution. It calls therun()
method internally.run()
: Entry point for the thread’s execution. It should be overridden to define the task to be performed by the thread.
Thread thread = new Thread(() -> System.out.println("Hello from a thread"));
thread.start(); // Calls run() internally
49. What is a Future
in Java concurrency?
Future
represents the result of an asynchronous computation. It provides methods to check if the computation is complete, retrieve the result, or cancel the task.
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(() -> 123);
Integer result = future.get(); // Waits for the computation to complete and retrieves the result
50. What is the CompletableFuture
class?
CompletableFuture
is a Future
that may be explicitly completed (setting its value and status), enabling further control over the asynchronous computation.
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
future.thenApply(s -> s + " World").thenAccept(System.out::println);