Java Interview Questions - Expert Level Answers
Strings
1. Why are strings immutable in Java?
a. Strings are immutable to ensure security, thread safety, and
efficiency via the String Constant Pool. Once created, a String
object cannot be changed, making it safe to share across
multiple threads without synchronization.
2. How does intern() work?
a. intern() checks the String Pool for a string with the same value.
If found, it returns the reference from the pool; otherwise, it adds
the string to the pool and returns the new reference.
3. How many objects are created using literals and new operator?
a. String literal: 1 object (if not already in the pool). Using new
String(): always creates a new object in heap and optionally
another in the pool if interned.
4. How does the String Constant Pool work?
a. JVM maintains a pool of strings to optimize memory. Literals are
interned automatically; same content shares the same reference.
5. Difference between equals() and ==?
a. ==: checks reference equality. equals(): checks value/content
equality.
6. String vs StringBuffer vs StringBuilder?
a. String: immutable, thread-safe
b. StringBuffer: mutable, thread-safe
c. StringBuilder: mutable, non-thread-safe
Object
1. Why is wrapper class required?
a. Needed for collections (which work with objects), and to use
utility methods (e.g., [Link]()), and autoboxing.
Wrapper classes in Java provide a way to use primitive data types (like int,
char, boolean) as objects. Each primitive type has a corresponding wrapper
class in the [Link] package:
int → Integer
char → Character
boolean → Boolean
byte → Byte
short → Short
long → Long
float → Float
double → Double
Reasons and Use Cases for Wrapper Classes:
1. Collections Framework Compatibility
a. Java collections (like ArrayList, HashMap) work only with objects,
not primitives.
b. Example:
List<Integer> list = new ArrayList<>(); // can't use List<int>
2. Autoboxing and Unboxing
a. Java automatically converts between primitives and their
wrapper classes:
Integer x = 10; // autoboxing
int y = x; // unboxing
3. Utility Methods
a. Wrapper classes provide useful methods for parsing and
conversion:
int num = [Link]("123");
String s = [Link](456);
4. Null Representation
a. Primitive types cannot be null, but wrapper objects can:
Integer i = null; // useful in frameworks, databases
5. Type Conversion and Comparisons
a. Wrapper classes offer easy ways to convert between data types
and compare values:
Double d = [Link]("23.5");
boolean result = [Link](10).equals(10);
6. Annotations and Generics
a. Annotations and generic-based frameworks (like Hibernate,
Spring) work with objects, not primitives.
Conclusion: Wrapper classes bridge the gap between object-oriented
features of Java and the use of efficient primitive types. They allow primitives
to be used where only objects are accepted while also enriching them with
helpful methods.
2.
3. \]Methods of Object class?
a. equals(), hashCode(), toString(), clone(), finalize(),
wait(), notify(), notifyAll()
4. Does Java give importance to primitive types?
a. Yes, for performance. Primitives are faster and require less
memory.
5. Is Java pass by value or reference?
a. Always pass by value. For objects, the reference is passed by
value.
OOPs
1. Types of OOPs
a. Abstraction, Encapsulation, Inheritance, Polymorphism
2. Composition vs Aggregation vs Association?
a. Association: General relationship
b. Aggregation: Has-a with independent lifecycle
c. Composition: Has-a with dependent lifecycle
Composition vs Aggregation vs Association - Detailed Explanation
These are types of relationships in Object-Oriented Programming, particularly
within class design.
1. Association
a. Definition: A general relationship where one object uses or is
connected to another.
b. Example: A Teacher and a Department can be associated.
c. Type: Bi-directional or uni-directional.
d. Example in Code:
class Teacher {
String name;
}
class Department {
Teacher teacher; // association
}
2. Aggregation (Has-A relationship)
a. Definition: A special form of association where the child (part)
can exist independently of the parent (whole).
b. Use Case: Represents a "whole-part" relationship, but parts are
not tightly bound.
c. Example: A Library has Books. Books can exist without the
library.
d. Code Example:
class Book {
String title;
}
class Library {
List<Book> books; // aggregation
}
3. Composition (Strong Has-A relationship)
a. Definition: A strong form of association where the child cannot
exist independently of the parent. If the parent is destroyed,
the child is also destroyed.
b. Use Case: Ownership relationship.
c. Example: A House has Rooms. Rooms do not exist without the
House.
d. Code Example:
class Room {
String name;
}
class House {
private List<Room> rooms = new ArrayList<>(); // composition
public House() {
[Link](new Room());
}
}
Summary Table:
Lifecycle Real-world
Concept Type
Dependency Example
Associatio General Student and
Independent
n Link Course
Aggregatio Weak Has-
Independent Library and Books
n A
Compositi Strong Has-
Dependent House and Rooms
on A
3. Overloading vs Overriding
a. Overloading: Same method name, different signature
b. Overriding: Subclass redefines superclass method
4. Abstract class vs Interface?
a. Abstract class: Can have constructors, state, and methods (both
abstract and concrete).
b. Interface: All methods are abstract (until Java 8), no constructors.
Multiple inheritance possible.
5. Can private or static methods be overridden?
a. No. Private methods are not inherited. Static methods are
hidden, not overridden.
6. Can main() be overloaded?
a. Yes, but JVM always calls the public static void
main(String[] args) version.
7. Can abstract class have a main method?
a. Yes. It's just a class, so it can have static methods.
Serialization
1. What is Serialization/Deserialization?
a. Serialization: converting object state to byte stream.
b. Deserialization: rebuilding object from byte stream.
2. Use of transient?
a. Prevents fields from being serialized.
Definition: The transient keyword in Java is used to indicate that a
particular field of a class should not be serialized during the object
serialization process.
Why Use transient? When an object is serialized using mechanisms like
ObjectOutputStream, all non-static and non-transient fields are saved.
However, sometimes you may want to exclude certain fields:
Use Cases:
1. Sensitive Information
a. Prevent sensitive data like passwords, security tokens from being
stored.
class User implements Serializable {
String username;
transient String password; // will not be saved in file
}
2. Non-Serializable Objects
a. If an object field is not serializable, marking it transient prevents
NotSerializableException.
class MyClass implements Serializable {
transient Socket socket; // Socket is not serializable
}
3. Derived or Temporary Fields
a. Fields that can be recalculated or are temporary (like loggers,
caches).
class Employee implements Serializable {
int id;
transient int cachedSalary; // not stored, calculated at
runtime
}
Serialization Example:
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("[Link]"));
[Link](new User("admin", "secret"));
On deserialization, the password field will be null.
Important Notes:
transient works only with instance variables.
static fields are implicitly not serialized.
Conclusion: The transient keyword is a powerful tool to control which
parts of an object should be persisted, helping ensure security, avoid
serialization errors, and optimize performance.
3. Serialize subclass if superclass not serializable?
a. Yes, if the superclass has a no-arg constructor.
4. Uninitialized non-serializable fields tolerated?
a. Yes, they'll be null/default after deserialization.
Cloning
1. Marker interface?
a. Interface with no methods (e.g., Serializable, Cloneable) to signal
capability.
A marker interface is an interface that contains no methods or
constants. It is used to mark or tag classes so that they can be given
special behavior by the JVM or libraries during runtime.
Examples in Java:
Serializable – Marks a class as serializable.
Cloneable – Marks a class as eligible for object cloning using
[Link]().
Remote – Indicates that an object can be used in RMI (Remote Method
Invocation).
Why Use Marker Interfaces?
1. JVM Recognition:
a. The JVM or frameworks can check if a class is "marked" by using
instanceof checks.
b. Example:
if (object instanceof Serializable) {
// perform serialization logic
}
2. Behavior Modification Without Code Changes:
a. Marking a class with an interface can change how frameworks
like Java Serialization or Spring handle the class.
3. Type Safety:
a. Marker interfaces allow compile-time checks to ensure only
specific types are passed to a method.
Comparison with Annotations:
Marker interfaces (pre-Java 5) were the only option.
Annotations are now preferred in modern Java (post Java 5+).
However, marker interfaces still serve a role when type identity is
important.
Example Usage:
public class Employee implements Serializable {
private String name;
private int id;
}
Custom Marker Interface:
public interface Trackable {} // no methods
public class AuditLog implements Trackable {
private String action;
}
Runtime Check:
if (object instanceof Trackable) {
[Link]("Auditing enabled for this object.");
}
Conclusion: Marker interfaces act as metadata that provides semantic
meaning to classes. Despite the rise of annotations, they are still relevant in
places where type checking and legacy systems are involved.
2. Shallow vs Deep Copy?
a. Shallow: copies references.
b. Deep: copies objects recursively.
Shallow Copy:
A shallow copy creates a new object, but does not create copies of
the objects that are referenced by the original object.
Instead, it copies the references to those objects.
Changes to the referenced objects in the copied object will reflect in
the original.
Example:
class Address {
String city;
}
class Employee implements Cloneable {
int id;
Address address;
protected Object clone() throws CloneNotSupportedException {
return [Link](); // shallow copy
}
}
In this case, both the original and cloned Employee will point to the
same Address object.
Deep Copy:
A deep copy creates a new object and also recursively copies all
objects referenced by it.
Changes to the referenced objects in the copy do not affect the
original object.
Example:
class Address {
String city;
Address(String city) {
[Link] = city;
}
Address(Address address) {
[Link] = [Link];
}
}
class Employee implements Cloneable {
int id;
Address address;
Employee(Employee emp) {
[Link] = [Link];
[Link] = new Address([Link]); // deep copy
}
}
Key Differences:
Feature Shallow Copy Deep Copy
Object Top-level + all referenced
Only top-level object
Creation objects
Shared
Yes No
References
Memory Usage Less More
Lightweight or
Use Case Complete isolation needed
immutable data
When to Use:
Use shallow copy for lightweight, read-only, or immutable object
structures.
Use deep copy when complete independence from the original object
is required.
Exception Handling
1. Error vs Exception?
a. Error: JVM level issues, not recoverable.
b. Exception: application-level, can be handled.
2. Checked vs Unchecked Exception?
a. Checked: must be declared or caught.
b. Unchecked: runtime, optional handling.
Definition:
Checked Exceptions are checked at compile-time.
Unchecked Exceptions are checked at runtime (i.e., not checked by
the compiler).
Checked Exceptions:
Must be either caught using try-catch block or declared using throws
keyword.
Indicate recoverable conditions.
Subclasses of Exception (excluding RuntimeException).
Examples:
IOException, SQLException, FileNotFoundException,
ParseException
public void readFile() throws IOException {
BufferedReader br = new BufferedReader(new
FileReader("[Link]"));
}
Unchecked Exceptions:
Not required to be caught or declared.
Indicate programming bugs, such as logic errors or improper use of
API.
Subclasses of RuntimeException.
Examples:
NullPointerException, ArrayIndexOutOfBoundsException,
IllegalArgumentException, ArithmeticException
public void divide(int a, int b) {
int result = a / b; // may throw ArithmeticException
}
Comparison Table:
Checked
Feature Unchecked Exception
Exception
Compile-time
Yes No
checking
Inheritance Extends Exception Extends RuntimeException
Mandatory Yes (try-catch or
No
handling throws)
External issues Programming bugs (e.g.,
Use Case
(e.g., IO) null ref)
Best Practices:
Use checked exceptions for recoverable conditions that the caller
should explicitly handle.
Use unchecked exceptions for bugs that should be fixed in code logic.
Conclusion:
Java’s exception model encourages developers to handle error
conditions deliberately using checked exceptions, while allowing
flexibility and cleaner code paths for runtime issues using unchecked
exceptions.
3. Custom Exception?
a. Extend Exception or RuntimeException.
4. Runtime Exception?
a. Unchecked exception like NullPointerException.
5. JVM handling?
a. Uncaught exceptions terminate thread and print stack trace.
6. Final, finalize, finally?
a. Final: constant
b. finalize(): called before GC
c. finally: always executed block
7. Superclass of all exceptions?
a. Throwable
8. Is Throwable an interface?
a. No, it’s a class.
9. When finally doesn’t execute?
a. JVM exits ([Link]()), fatal error occurs.
10. Throwing higher checked exception?
Can a Subclass Method Throw a Higher Checked Exception?
No — in Java, a subclass method cannot declare to throw a broader
(higher) checked exception than the one declared in the parent method it
overrides.
Why?
This is to maintain polymorphism and substitutability.
If a superclass method throws a specific checked exception, the
subclass should not surprise the caller with a more general or new
checked exception.
Example — Not Allowed:
class Parent {
public void readFile() throws IOException {}
}
class Child extends Parent {
// Compile-time error: Exception is broader than IOException
public void readFile() throws Exception {}
}
Example — Allowed:
class Parent {
public void readFile() throws IOException {}
}
class Child extends Parent {
// Allowed: throws narrower exception
public void readFile() throws FileNotFoundException {}
}
Unchecked Exceptions:
You can throw a new or broader unchecked exception from the
subclass method.
class Parent {
public void process() {}
}
class Child extends Parent {
public void process() {
throw new NullPointerException("Unchecked exception
allowed");
}
}
Key Rule Summary:
Parent Method Subclass Method Can
Throws Throw
No Exception No checked exceptions
Same or subclass of that
Checked Exception
exception
Unchecked
Any unchecked exception
Exception
Conclusion:
You cannot throw a broader checked exception than the
overridden method in a subclass.
Doing so would break the Liskov Substitution Principle.
11. Unchecked in child, none in parent?
Allowed.
Can a Subclass Method Throw an Unchecked Exception Even if the
Parent Method Declares None?
Yes — a subclass can throw any unchecked exception (i.e., exceptions
that extend RuntimeException) even if the overridden method in the parent
class does not declare any exceptions.
Why Is This Allowed?
Unchecked exceptions are not enforced by the compiler.
They indicate programming bugs or unexpected states rather than
recoverable conditions.
Example — Allowed:
class Parent {
public void perform() {
// No exception declared
}
}
class Child extends Parent {
@Override
public void perform() {
throw new IllegalArgumentException("Invalid input");
}
}
Behavior:
Compilation succeeds.
The exception is thrown at runtime only if the faulty code is executed.
Important Notes:
This is different from checked exceptions, where method signatures
must conform to the parent.
Overriding methods must not introduce new checked exceptions,
but unchecked exceptions are exempt from this rule.
Use Cases:
Often used for custom runtime validations, like input checks, assertion
violations, or lazy error handling.
Conclusion:
Subclass methods can throw unchecked exceptions regardless of what
their parent class methods declare.
Use this with caution to avoid unexpected runtime failures.
12. throw vs throws?
throw: used to throw an exception
throws: used in method signature
Enum
1. Why use Enum?
a. Represents fixed set of constants, type-safe, supports methods.
Garbage Collection
1. How GC works?
What is Garbage Collection (GC)?
Garbage Collection is a process by which the JVM automatically
frees up memory by destroying objects that are no longer reachable.
Why is it Needed?
To prevent memory leaks and manage heap memory efficiently.
Java developers do not need to explicitly release memory like in C/C++
(no free() needed).
How it Works Internally:
1. Reference Checking
a. JVM identifies objects that are unreachable from any live thread
or static reference chain.
2. Mark and Sweep Algorithm
a. Mark: Traverse object graph and mark all reachable objects.
b. Sweep: Collect unmarked (unreachable) objects and reclaim
memory.
3. Generational Collection (Heap Segmentation)
a. Java heap is divided into:
i. Young Generation: New objects (frequent collection)
ii. Old Generation (Tenured): Long-living objects
(infrequent collection)
iii. Permanent Generation / Metaspace: Metadata about
classes (Java 8+ uses Metaspace)
4. Minor vs Major GC
a. Minor GC: Cleans young generation. Fast and frequent.
b. Major GC (Full GC): Cleans old generation. Takes longer.
5. Garbage Collectors in JVM
a. Serial GC: Single-threaded, for small applications.
b. Parallel GC: Uses multiple threads, good throughput.
c. CMS (Concurrent Mark Sweep): Reduces pause time.
d. G1 (Garbage First): Balances throughput and pause times.
Default from Java 9+.
e. ZGC / Shenandoah (Java 11+): Ultra-low latency collectors.
Explicit GC Triggering (Not Recommended):
[Link](); // Request GC, not guaranteed
Best Practices:
Rely on JVM’s GC; don’t manually manage memory.
Nullify references of large objects when no longer needed.
Avoid memory leaks via static references or unclosed resources.
Tools for Monitoring GC:
jconsole, jvisualvm, GC logs, Java Flight Recorder, GCeasy, Heap
dumps
Conclusion:
Java GC is a powerful automated memory management system.
Understanding GC behavior helps improve application performance,
especially for long-running or large-scale systems.
Collections
1. Array vs ArrayList?
a. Array: fixed size, faster. ArrayList: dynamic size, more flexible.
2. ArrayList vs LinkedList?
a. ArrayList: better for indexing/search. LinkedList: better for
insertion/deletion.
3. Fail Safe vs Fail Fast Iterators?
a. Fail Fast: throws ConcurrentModificationException. Fail Safe:
works on copy.
Collection Iterator Exception on
Type Type Modification
ArrayList, HashSet, HashMap Fail-Fast
Yes
CopyOnWriteArrayList, Fail-
No
ConcurrentHashMap Safe
4. ConcurrentModificationException?
a. Thrown when a collection is modified while iterating (fail-fast
behavior).
5. Internal working of HashMap?
a. HashMap uses an array of buckets; each bucket uses a linked list
or tree (Java 8+) for collisions. Uses hashCode() and equals().
Internal Working of HashMap - Detailed Explanation
1. Data Structure Used:
Internally, a HashMap is implemented using an array of buckets,
where each bucket is a linked list or tree (from Java 8 onwards).
2. Key Methods:
put(K key, V value) — Inserts key-value pair
get(Object key) — Retrieves value by key
3. How put() Works:
[Link]("A", 100);
The hashCode() of the key is computed.
Hash is transformed (bit manipulation) to spread entries uniformly.
An index is computed using: index = (n - 1) & hash, where n is the
array size.
If bucket is empty → entry is stored.
If not → compare keys using equals() → if match, replace; else add to
chain.
If entries in a bucket exceed threshold (8 entries), the linked list is
converted to a balanced tree for faster lookup (Java 8+).
4. How get() Works:
[Link]("A");
Computes the hash and index like put().
Navigates the bucket to find the correct node using equals().
5. Bucket Collision Handling:
A collision occurs when multiple keys hash to the same index
(bucket).
These are handled via:
o Chaining: Entries form a linked list in that bucket.
o Treeification (Java 8+): If linked list exceeds a threshold (≥8
entries), it's converted to a balanced tree (Red-Black Tree).
Collisions do not cause overwriting unless the keys are equal as per
equals().
6. Load Factor and Resize:
Load Factor: Threshold for resizing (default = 0.75).
When size >= capacity * loadFactor, a resize operation occurs.
The underlying array is doubled in size and existing entries are
rehashed.
7. Java 8 Treeification:
If a bucket has more than 8 entries and size > 64, it's converted to a
TreeNode (Red-Black Tree) to optimize performance.
Reduces time complexity from O(n) to O(log n) in worst cases.
8. Null Keys and Values:
Allows one null key and multiple null values.
Hash for null key is always 0 and placed at index 0.
9. Time Complexity:
Operati Best/Average Worst Case (Pre- Worst Case
on Case Java 8) (Java 8+)
get/put O(1) O(n) (chaining) O(log n) (tree)
10. Important Methods Used Internally:
hashCode() — calculates hash
equals() — checks key equality
resize() — expands the map when needed
treeifyBin() — converts linked list to tree
Conclusion: HashMap provides average-case O(1) performance for get
and put operations by using hashing, linked lists, and tree structures
(post Java 8). Understanding its internal mechanics helps optimize memory
and performance in real-world applications.
6. Java 8 changes in HashMap?
a. Buckets switch from linked list to tree when items > 8, and size
> 64 for performance.
7. Null key in HashMap?
a. Allowed; only one null key.
8. Is key immutability mandatory?
a. Yes, mutable keys may cause incorrect bucket location.
9. Override equals() and hashCode()?
a. Required for proper key comparison in hash-based collections.
10. HashSet vs LinkedHashSet vs TreeSet
HashSet: unordered
LinkedHashSet: ordered (insertion)
TreeSet: sorted (uses Comparable/Comparator)
11. Internal structure of TreeMap?
Red-Black Tree; maintains sorted order based on keys.
12. HashMap vs ConcurrentHashMap
ConcurrentHashMap: thread-safe, avoids lock on entire map (bucket-
level locking).
13. Comparable vs Comparator
Comparable: natural order (implements compareTo())
Comparator: custom order (implements compare())
Comparable vs Comparator - Detailed Explanation
1. Purpose: Both are used for sorting objects in Java, but serve slightly
different purposes:
Comparable: Used to define the natural ordering of objects.
Comparator: Used to define custom ordering, especially when the
class doesn’t implement Comparable or multiple sort criteria are
needed.
2. Comparable Interface:
Belongs to [Link] package
Method: int compareTo(T obj)
Must be implemented by the class whose objects are being sorted
Example:
class Employee implements Comparable<Employee> {
int id;
String name;
public int compareTo(Employee other) {
return [Link] - [Link]; // ascending by id
}
}
[Link](employeeList); // uses compareTo()
3. Comparator Interface:
Belongs to [Link] package
Method: int compare(T o1, T o2)
Can be defined outside the class
Useful for multiple sort orders
Example:
class NameComparator implements Comparator<Employee> {
public int compare(Employee e1, Employee e2) {
return [Link]([Link]);
}
}
[Link](employeeList, new NameComparator());
4. Java 8 Comparator with Lambda:
[Link]((e1, e2) -> [Link]([Link]));
5. Key Differences:
Feature Comparable Comparator
Package [Link] [Link]
compare(Object o1, Object
Method compareTo(Object o)
o2)
Sorting Logic
Inside the class Outside the class
Location
Affects Natural
Yes No
Order?
Multiple Sort No (only one Yes (multiple comparators
Logic implementation) possible)
6. When to Use:
Use Comparable when natural order is sufficient (e.g., alphabetical, ID
order).
Use Comparator for more complex or multiple sorting strategies (e.g.,
name, salary, date).
Conclusion: Use Comparable for default class-level sorting and Comparator
when sorting logic is external or dynamic. Java 8’s lambda expressions and
method references make Comparator more concise and powerful.
14. BlockingQueue?
Thread-safe queue; supports operations that wait for the queue to
become non-empty/full.
15. Vector? When to use?
Thread-safe legacy class; generally replaced by newer collections
unless synchronization is required.
Multithreading & Concurrency
1. Multithreading vs Multiprocessing vs Multiprogramming vs
Multitasking?
a. Multithreading: multiple threads in one process.
b. Multiprocessing: multiple processes.
c. Multiprogramming: multiple programs in memory.
d. Multitasking: user-level concurrency.
2. Life cycle of a Thread
a. New → Runnable → Running → Waiting/Blocked → Terminated
3. Extends Thread vs Implements Runnable?
a. Use Runnable to share resource logic and avoid single
inheritance issue.
4. yield() vs sleep() vs join()?
a. yield(): Hints to thread scheduler to switch.
b. sleep(): Pauses current thread.
c. join(): Waits for thread to die.
5. wait() vs sleep()?
a. wait(): Releases lock, used in synchronized block.
b. sleep(): Retains lock, used anywhere.
6. Why join()?
a. To ensure thread finishes execution before moving forward.
7. Override start()?
a. Possible but not recommended. Use run() for custom logic.
8. Override run()?
a. Yes, to define task.
9. Start thread twice?
a. No. Throws IllegalThreadStateException.
10. Calling run() directly?
a. Runs in current thread, not a new one.
11. Why use ThreadPool?
a. Better performance by reusing threads and controlling resource
use.
12. What is Race Condition?
a. When multiple threads access and modify shared data
concurrently.
13. What is Synchronization? Types?
a. Synchronization ensures one thread accesses critical section.
b. Types: Method-level, block-level, static.
14. Object Locking vs Class Locking?
a. Object lock: per object (synchronized instance methods).
b. Class lock: per class (synchronized static methods).
15. 2 threads accessing m1 and m2?
a. No, if both are synchronized on same object.
16. Multiple threads accessing non-synchronized methods?
a. Yes.
17. 2 static synchronized methods called by threads?
a. No. They block each other due to class-level lock.
18. Static sync vs Non-static sync?
a. Different locks (class vs object), so do not block each other.
19. Can constructors be synchronized?
a. No. Object isn’t accessible until constructor finishes.
20. What is Deadlock?
a. Two or more threads waiting on each other’s locks endlessly.
21. Inter-thread communication? wait(), notify(), notifyAll()?
a. Used for communication between threads holding the same lock.
22. IllegalMonitorStateException?
a. Thrown when wait(), notify() called without holding lock.
23. wait()/notify() belong to which class?
a. [Link]
24. Thread class methods? sleep() in Thread or Object?
a. In Thread class.
25. Producer Consumer Problem?
a. Classic example using wait/notify for inter-thread
communication.
26. Volatile vs Synchronized?
a. volatile: ensures visibility.
b. synchronized: ensures visibility + atomicity.
27. Atomic variables?
a. Use [Link] for lock-free thread-safe
ops.
Concurrency Utilities
1. Runnable vs Callable?
a. Runnable: no return. Callable: returns value, can throw
exception.
2. What is Future Object?
a. Represents result of asynchronous computation.
3. CompletableFuture?
a. Enhanced future for non-blocking async workflows.
4. Future: done(), isCancelled(), cancel()?
a. done(): task finished
b. isCancelled(): was it cancelled?
c. cancel(): cancel if not started.
5. ThreadLocal class?
a. Provides thread-confined variables.
6. CountDownLatch?
a. Waits for countdown to reach zero before proceeding.
7. CyclicBarrier?
a. Waits for a group of threads to reach a barrier.
8. ReentrantLock?
a. Allows thread to re-acquire the same lock multiple times.
9. [Link]() vs execute()?
a. submit(): returns Future
b. execute(): void return, Runnable only
10. Types of Executor Services?
a. FixedThreadPool, CachedThreadPool, SingleThreadExecutor,
ScheduledThreadPool
11. FixedThreadPool working?
a. Limits thread count; extra tasks queue up.
Next up: Java 8 Features followed by Design Principles & Java Version
Enhancements.
Java 8 Features
1. Interface 8 changes
a. Java 8 allows default and static methods in interfaces.
b. Default methods can have implementation using default
keyword.
c. Static methods can be accessed via interface name.
2. What is Functional Interface? Why needed?
a. Interface with one abstract method.
b. Enables lambda expressions and method references.
c. Example: Runnable, Callable, Predicate, Function
What is a Functional Interface? A functional interface in Java
is an interface that contains exactly one abstract method. It
may have any number of default or static methods, but only one
abstract method.
Why Is It Needed?
Functional interfaces are the foundation for lambda
expressions and method references, introduced in Java 8.
Enables functional programming constructs, reducing
boilerplate and improving readability.
How to Declare a Functional Interface:
@FunctionalInterface
interface Calculator {
int operate(int a, int b);
}
The @FunctionalInterface annotation is optional, but if used,
the compiler will enforce the rule of having only one abstract
method.
Using with Lambda Expression:
Calculator add = (a, b) -> a + b;
[Link]([Link](5, 3)); // Output: 8
Examples of Built-in Functional Interfaces ([Link]):
Function<T, R> — takes a parameter of type T and returns R
Predicate<T> — returns boolean (e.g., filters)
Consumer<T> — accepts input and returns nothing (e.g.,
printing)
Supplier<T> — returns a result without taking any input
Example with Predicate:
Predicate<String> isShort = s -> [Link]() < 5;
[Link]([Link]("Java")); // true
Difference from Regular Interfaces:
Functional
Feature Regular Interface
Interface
Abstract
Exactly one One or more
Methods
Lambda No (unless single abstract
Yes
Compatible method)
Functional-style Type contracts, multiple
Used For
operations methods
Conclusion: Functional interfaces are key to enabling cleaner,
concise, and functional-style programming in Java 8+. They're
heavily used in Java Streams, Collections API enhancements, and
asynchronous workflows.
3. Difference between Collection and Stream
a. Collection: data in memory, mutable.
b. Stream: compute operations on data, mostly lazy and functional.
4. Terminal vs Intermediate Operators
a. Terminal: produce result (e.g., collect(), forEach())
b. Intermediate: return a stream (e.g., map(), filter())
In Java 8 Streams, operations are divided into two categories:
1. Intermediate Operations:
Return a Stream itself.
Are lazy: they don’t process data until a terminal operation is invoked.
Can be chained together.
Examples:
filter(): filters elements based on predicate.
map(): transforms each element.
distinct(), sorted(), limit()
List<String> names = [Link]("Sam", "Sara", "John");
[Link]()
.filter(name -> [Link]("S")) // intermediate
.map(String::toUpperCase); // still lazy
2. Terminal Operations:
Trigger the execution of the stream pipeline.
Produce a result or a side-effect.
Can only be used once per stream.
Examples:
collect(): gathers elements into a collection.
forEach(): performs action on each element.
count(), reduce(), anyMatch(), findFirst()
[Link]()
.filter(name -> [Link]("S"))
.forEach([Link]::println); // terminal → triggers
execution
Comparison Table:
Feature Intermediate Operator Terminal Operator
Return Non-stream (value, void, or
Stream
Type result)
Lazy (evaluated on Eager (evaluated
Laziness
demand) immediately)
Chainabili
Yes No (terminates the stream)
ty
Conclusion:
Use intermediate operations to build the pipeline.
Use terminal operations to execute the pipeline and produce output.
This separation allows high performance, short-circuiting, and lazy
evaluation in stream processing.
5. What is Optional?
a. A container for optional values. Helps avoid
NullPointerException.
b. Example: [Link](), [Link](),
[Link]()
6. FlatMap vs Map?
a. map(): one-to-one mapping.
b. flatMap(): one-to-many mapping, flattens nested structure.
7. Parallel Sort vs Sort?
a. parallelSort(): divides array and sorts in parallel using
multiple threads.
b. sort(): single-threaded, sequential.
8. Predicate vs BiPredicate?
a. Predicate<T>: one input, boolean result.
b. BiPredicate<T, U>: two inputs, boolean result.
9. Diamond Problem in Java 8?
a. Solved using default methods.
b. Conflict resolved by class overriding the method or specifying via
[Link]().
What is the Diamond Problem? The Diamond Problem occurs when a
class inherits from two interfaces that both provide a default method with
the same signature. Java needs to know which method to use — this
ambiguity is what’s referred to as the Diamond Problem.
Why does it occur? In Java 8, interfaces can now include default methods
(methods with a body), so it's possible for multiple interfaces to define a
method with the same name and parameters.
Example:
interface A {
default void show() {
[Link]("From A");
}
}
interface B {
default void show() {
[Link]("From B");
}
}
class C implements A, B {
// Compilation error unless show() is overridden
public void show() {
[Link](); // Or [Link](); to resolve
explicitly
}
}
How Java Solves It: Java does not allow ambiguity — the implementing
class must explicitly override the method to resolve the conflict.
Resolution Options:
Override the method in the subclass and explicitly call the desired
interface using [Link]()
Conclusion: The Diamond Problem is handled in Java 8 by requiring the
class to resolve the conflict explicitly, ensuring clarity and avoiding
ambiguity.
Next up: Design Patterns, SOLID Principles, and Java Version Enhancements.
Design Patterns, SOLID Principles, and Java Version Enhancements
1. Difference between JDK, JRE, and JVM
a. JVM (Java Virtual Machine): Executes Java bytecode. It's
platform-dependent.
b. JRE (Java Runtime Environment): Provides libraries + JVM.
Needed to run Java applications.
c. JDK (Java Development Kit): Full suite including JRE +
development tools like compiler, debugger.
Compone
Description
nt
It is the engine that actually runs Java applications. JVM loads
JVM (Java
class files, verifies bytecode, executes it, and provides
Virtual
runtime environment. Each OS has its own JVM
Machine)
implementation.
JRE (Java
Contains JVM + set of libraries and other files to run Java
Runtime
applications. It does not include development tools like
Environm
compilers. It is used to run Java code.
ent)
JDK (Java It is a superset of JRE. It includes the JRE plus development
Developm tools like javac, java, javadoc, javap, and debugger. It is
ent Kit) used to develop and run Java applications.
Relationship Diagram:
JDK = JRE + Development Tools
JRE = JVM + Libraries
Key Differences:
Feature JDK JRE JVM
Development + Execution
Role Executes bytecode
Execution only
JRE + compiler + JVM +
Contains Part of JRE
tools libraries
Developers & End-
Used By Developers End-users
users
Executab javac, java, javadoc,
java N/A (runs bytecode)
le etc.
Conclusion:
JVM runs the program
JRE provides runtime environment
JDK provides tools to write, compile, and run Java programs
2. What is Immutable Class?
a. An immutable class is one whose state (fields) cannot be
changed once created.
b. To make a class immutable:
i. Mark it as final
ii. Make all fields private and final
iii. Do not provide setters
iv. Return deep copies for mutable objects in getters
c. Example: String, Integer, LocalDate
3. What are SOLID Principles?
a. S: Single Responsibility Principle — a class should have only one
reason to change.
b. O: Open/Closed Principle — software entities should be open for
extension, closed for modification.
c. L: Liskov Substitution Principle — derived types must be
completely substitutable for their base types.
d. I: Interface Segregation Principle — no client should be forced to
depend on methods it does not use.
e. D: Dependency Inversion Principle — depend on abstractions,
not concrete implementations.
4. ClassNotFoundException vs NoClassDefFoundError
a. ClassNotFoundException: Thrown when class is not found
during runtime using [Link]() or ClassLoader.
b. NoClassDefFoundError: Thrown when JVM tries to load a class
that was present during compilation but missing at runtime.
5. Singleton Design Pattern
a. Ensures only one instance of a class is created.
b. Used in logging, configuration, thread pools.
Singleton Design Pattern in Java - Detailed Explanation
What is Singleton Pattern?
Singleton Pattern ensures that a class has only one instance and
provides a global access point to that instance.
Why Use Singleton?
Controlled access to resources (e.g., loggers, configuration objects,
caches, thread pools).
Improves performance by avoiding unnecessary object creation.
Types of Singleton Implementations:
1. Eager Initialization
class EagerSingleton {
private static final EagerSingleton instance = new
EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2. Lazy Initialization (Not Thread Safe)
class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
3. Thread-Safe Singleton (Synchronized)
class ThreadSafeSingleton {
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton() {}
public static synchronized ThreadSafeSingleton getInstance()
{
if (instance == null) {
instance = new ThreadSafeSingleton();
}
return instance;
}
}
4. Bill Pugh Singleton (Recommended)
class BillPughSingleton {
private BillPughSingleton() {}
private static class Helper {
private static final BillPughSingleton INSTANCE = new
BillPughSingleton();
}
public static BillPughSingleton getInstance() {
return [Link];
}
}
5. Enum Singleton (Thread-safe & Serialization-safe)
enum EnumSingleton {
INSTANCE;
public void service() {
[Link]("Singleton via Enum");
}
}
Comparison Table:
Thre Lazy Serializ Breakable
Implementa
ad Initializ ation via Notes
tion Type
Safe ation Safe Reflection?
Instance
Eager
Yes No Yes Yes created even if
Initialization
unused
Lazy Not suitable for
No Yes No Yes
Initialization multithreading
Thread-Safe
Performance
(Synchronize Yes Yes No Yes
overhead
d)
Best
Bill Pugh
Yes Yes No Yes performance
Singleton
and safety
Enum Simplest and
Yes Yes Yes No
Singleton safest
How to Break Singleton Pattern in Java?
Even though Singleton is meant to be unbreakable, it can be broken using:
1. Using Reflection
Constructor<Singleton> constructor =
[Link]();
[Link](true);
Singleton instance2 = [Link](); // New instance
Fix: Throw exception from constructor if instance already exists.
2. Using Serialization
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("[Link]"));
[Link](singletonInstance);
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("[Link]"));
Singleton instance2 = (Singleton) [Link]();
Fix: Implement readResolve() to return the same instance.
protected Object readResolve() {
return instance;
}
3. Using Cloning
Singleton cloned = (Singleton) [Link]();
Fix: Override clone() method and throw exception or return same instance:
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
Conclusion: While Singleton is a powerful design pattern, it must be
implemented carefully to be thread-safe and resistant to reflection, cloning,
and serialization issues.
c. Uses static inner class for lazy initialization.
6. How to break Singleton?
a. Reflection: Can access private constructor.
b. Deserialization: Creates new instance.
c. Cloning: Can create a new copy.
Solutions:
d. Reflection: Throw exception in constructor if instance already
exists.
e. Deserialization: Implement readResolve().
f. Cloning: Override clone() to return same instance.
7. Java Version Enhancements
a. Java 8:
i. Lambda expressions
ii. Streams API
iii. Functional interfaces
iv. Optional class
v. Default & static methods in interfaces
vi. New Date/Time API
b. Java 9:
i. Module system (Project Jigsaw)
ii. JShell (REPL)
iii. Collection factory methods ([Link]())
c. Java 10:
i. var keyword (local variable type inference)
d. Java 11:
i. New string methods (isBlank(), lines())
ii. Local variable syntax for lambda
e. Java 12-13:
i. Switch expression preview
ii. Text blocks (preview)
f. Java 14-15:
i. Records (preview)
ii. Sealed classes (preview)
g. Java 16-17 (LTS):
i. Records (standard)
ii. Pattern Matching for instanceof
iii. Sealed Classes
iv. Foreign Linker API (incubator)
h. Java 18+:
i. UTF-8 by default
ii. Simple Web Server
iii. Pattern matching enhancements
This concludes the expert-level breakdown for all major Java interview areas.
Comprehensive Java Interview Questions (Beginner to Expert)
Beginner Level
1. What is Java?
a. Java is a high-level, class-based, object-oriented programming
language designed to have as few implementation dependencies
as possible.
2. Features of Java?
a. Platform independent, Object-Oriented, Secure, Robust,
Multithreaded, High Performance (via JIT), Distributed.
3. What is a Class and Object?
a. Class is a blueprint, object is an instance of a class.
4. Main method signature in Java?
public static void main(String[] args)
5. Difference between local, instance, and static variables?
a. Local: inside method
b. Instance: in class, outside method
c. Static: class-level variable
6. What are constructors?
a. Special methods used to initialize objects.
7. Method Overloading?
a. Same method name, different parameters.
8. What is a package?
a. A namespace to group related classes and interfaces.
9. Access Modifiers?
a. public, protected, default, private — control visibility.
10. Difference between break and continue?
break: exits loop
continue: skips to next iteration
Intermediate Level
1. What is inheritance?
a. Mechanism to acquire properties of parent class.
2. Types of inheritance in Java?
a. Single, Multilevel, Hierarchical (Multiple not supported with
classes).
3. What is Polymorphism?
a. Ability to take many forms: compile-time (overloading), runtime
(overriding).
4. Final keyword use cases?
a. Final variable: constant
b. Final method: cannot override
c. Final class: cannot be extended
5. Interfaces vs Abstract classes?
a. Interfaces: full abstraction (Java 8+ supports default/static
methods)
b. Abstract: partial abstraction
6. Garbage Collector in Java?
a. JVM component to automatically reclaim memory.
7. Type Casting?
a. Implicit (widening) and Explicit (narrowing).
8. Exception Propagation?
a. An exception moves up the call stack until caught.
9. Difference between Array and ArrayList?
a. Array: fixed size
b. ArrayList: dynamic size
10. What is a wrapper class?
Object representation of primitive types.
Advanced Level
1. Memory areas in JVM?
a. Heap, Stack, Method Area, Program Counter Register, Native
Method Stack.
2. Java Memory Model (JMM)?
a. Defines interaction between threads and memory.
3. Class loading process?
a. Loading → Linking (Verify, Prepare, Resolve) → Initialization
4. Reflection API?
a. Allows inspection/modification of classes at runtime.
5. Annotations?
a. Provide metadata. Custom annotations can be created using
@interface.
6. Lambda expressions?
a. Anonymous functions for functional programming.
7. Stream API usage examples?
[Link]().filter(x -> x > 5).collect([Link]());
8. Concurrency utilities?
a. ConcurrentHashMap, CountDownLatch, Semaphore,
ExecutorService
9. Immutable vs Mutable Objects?
a. Immutable: state can’t change (e.g., String)
b. Mutable: state can change (e.g., StringBuilder)
10. Best practices in multithreading?
Use ExecutorService, minimize shared mutable state, prefer
immutability.
Collections Deep Dive + Cheat Sheet + Coding Interview Focus
Core Concepts and Usages
1. List vs Set vs Map
a. List: Ordered(maintain Insertion order), duplicates allowed —
ArrayList, LinkedList
b. Set: Unordered, unique elements — HashSet, LinkedHashSet,
TreeSet
c. Map: Key-value pairs — HashMap(Unordered), TreeMap,
LinkedHashMap, ConcurrentHashMap
Linked:- Maintain insertion Order.
2. ArrayList vs LinkedList
a. ArrayList: better for index-based access, resizing costlier
b. LinkedList: better for insert/delete, slower for access
3. HashSet vs TreeSet vs LinkedHashSet
a. HashSet: fast, unordered
b. TreeSet: sorted, slower (uses Red-Black tree)
c. LinkedHashSet: maintains insertion order
4. HashMap vs Hashtable vs ConcurrentHashMap
a. HashMap: not thread-safe, allows null key
b. Hashtable: thread-safe, legacy, no null key/value
c. ConcurrentHashMap: thread-safe, high performance
5. PriorityQueue vs TreeSet
a. PriorityQueue: queue with natural/custom ordering
b. TreeSet: sorted set, no duplicates
6. BlockingQueue (e.g., ArrayBlockingQueue)
a. Supports waiting for space/data
b. Used in Producer-Consumer problems
7. Stack vs Deque
a. Stack: LIFO, legacy class
b. Deque: can be used as both stack and queue (ArrayDeque)
8. Fail-Fast vs Fail-Safe Iterators
a. Fail-Fast: throws ConcurrentModificationException (e.g.,
ArrayList)
b. Fail-Safe: works on clone (e.g., CopyOnWriteArrayList)
9. Comparator vs Comparable
a. Comparable: natural ordering via compareTo()
b. Comparator: custom order via compare()
10. Map Implementations Use-Cases
a. HashMap: fast lookup
b. TreeMap: sorted keys
c. LinkedHashMap: access order
d. ConcurrentHashMap: high concurrency
Coding Interview Focus Areas
1. Frequency Count Using HashMap
a. Count characters or words:
Map<Character, Integer> map = new HashMap<>();
for (char c : [Link]()) {
[Link](c, [Link](c, 0) + 1);
}
2. Remove Duplicates From List
List<Integer> list = [Link](1, 2, 2, 3);
Set<Integer> unique = new HashSet<>(list);
3. Sort Map by Values
[Link]()
.stream()
.sorted([Link]())
.forEach(e -> [Link]([Link]() + ": " +
[Link]()));
4. Top K Frequent Elements (using PriorityQueue + HashMap)
5. Find First Non-Repeating Character
6. Group Anagrams
a. Use Map<String, List<String>>, key is sorted char array of
each word
7. Custom Sorting using Comparator
[Link]((a, b) -> b - a); // descending sort
8. Implement LRU Cache
a. Use LinkedHashMap with accessOrder set to true
9. Detect Cycle in Graph using Map and DFS
10. Thread-safe Collections for Producer-Consumer
a. BlockingQueue, ConcurrentHashMap, CopyOnWriteArrayList