Java Interview Question
A Functional Interface
A Functional Interface is an interface with exactly one abstract method (SAM – Single Abstract Method).
Examples: Runnable
, Callable
, Comparator
, Function<T, R>
.
@FunctionalInterface
interface MyFunc {
void sayHello(); // ✅ only 1 abstract method
}
2️⃣ Reason only 1 abstract method
👉 Because Lambda Expressions in Java are designed to provide the implementation of exactly one abstract method.
If there were multiple abstract methods, the compiler would not know which method the lambda is implementing.
difference between StringBuilder
and StringBuffer
in Java
Feature | StringBuffer | StringBuilder | ||
---|---|---|---|---|
Thread Safety | ✅ Thread-safe (methods are synchronized) | ❌ Not thread-safe (no synchronization) | ||
Performance | Slower (due to synchronization overhead) |
Faster (no synchronization) | ||
Use Case | Use when multiple threads might modify the same string | Use when single thread modifies the string | ||
Introduced in | Java 1.0 | Java 1.5 | ||
String :- String - |
|
Slower when doing modifications (creates new object every time).
difference between .equals()
and ==
in Java
public class EqualsVsDoubleEquals {
public static void main(String[] args) {
String s1 = "Java"; // String literal (stored in String pool)
String s2 = "Java"; // Points to same pool object
String s3 = new String("Java");// New object in heap
System.out.println(s1 == s2); // true (same reference in pool)
System.out.println(s1.equals(s2)); // true (same content)
System.out.println(s1 == s3); // false (different objects in memory)
System.out.println(s1.equals(s3)); // true (content matches)
}
}
1. Method Overloading (Compile-Time Polymorphism)
Definition:
When two or more methods in the same class have the same name but different parameter lists (number or type), it’s called overloading.
-
Happens within the same class.
-
Decided at compile time based on method signature.
-
Return type can be different, but it alone cannot differentiate overloaded methods.
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
}
public class TestOverload {
public static void main(String[] args) {
Calculator c = new Calculator();
System.out.println(c.add(2, 3)); // calls int method
System.out.println(c.add(2.5, 3.5)); // calls double method
System.out.println(c.add(1, 2, 3)); // calls 3-param method
}
}
✅ Key Points:
-
Done in the same class.
-
Happens at compile time (compiler decides which method to call).
-
Can overload static, instance, and constructors.
2. Method Overriding (Run-Time Polymorphism)
Definition:
When a subclass provides its own implementation of a method already present in the parent class (with the same method name, parameters, and return type), it’s called overriding.
-
Happens between parent and child classes.
-
Decided at runtime using the actual object type.
A Singleton class in Java is a class that allows only one object (instance) to be created for the entire application.
It’s used when exactly one instance of a class is needed to coordinate actions globally.
Key Features
-
Only one instance of the class exists.
-
Global access point to that instance.
-
Constructor is private so no one can create an object directly.
-
Instance is returned using a static method.
When to Use
✅ Interview Tip:
If they ask about thread safety in Singleton, you should mention:
-
Use
synchronized
ingetInstance()
(but it’s slower). -
Or use Bill Pugh Singleton (static inner class).
-
Or use Enum Singleton (best for serialization + thread safety).
-
what is thread safety how do you ensure thread safe class ?
Thread safety means that a class or piece of code works correctly when accessed by multiple threads at the same time, without causing race conditions, data corruption, or inconsistent results.
Why it’s needed
If two threads modify the same variable/object at the same time without proper control, results can be unpredictable.
Example problem (race condition):
class Counter {
private int count = 0;
public void increment() {
count++; // not thread safe
}
public int getCount() {
return count;
}
}
increment()
at the same time,count
may not increase correctly because count++
is not atomic.How to Ensure a Thread-Safe Class
1️⃣ Use Synchronization
Make critical sections synchronized
so only one thread accesses at a time.
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
2️⃣ Use volatile
for visibility (not atomicity)
Ensures changes to a variable are visible to all threads.
volatile boolean flag = true;
3️⃣ Use Atomic Classes (from java.util.concurrent.atomic
)
Atomic operations are faster than synchronized for simple counters.
5️⃣ Use Thread-safe Collections
Instead of ArrayList
or HashMap
, use:
"How to make Singleton thread safe?" → Mention:
-
synchronized getInstance()
(simple but slow) -
Bill Pugh Singleton (static inner class)
-
Enum Singleton (best and simplest)
1️⃣ How AtomicInteger
Works
AtomicInteger
is part of java.util.concurrent.atomic
and is thread-safe for single variable operations without using locks.
It uses CAS (Compare-And-Set) at the CPU level.
CAS works like this:
-
Read the current value (expected value).
-
Compute the new value.
-
Atomically update the variable only if it’s still the expected value.
-
If another thread has modified it, retry until success.
incrementAndGet()
internally uses compareAndSet()
→ lock-free and fast.Feature | AtomicInteger |
synchronized |
---|---|---|
Mechanism | Lock-free (uses CAS at CPU level) | Uses monitor locks (object-level) |
Performance | Very fast for single variable updates | Slower due to context switching & blocking |
Scope | Works for atomic operations on single variables only | Works for complex code blocks |
Blocking | Non-blocking | Blocking |
When to Use | Counters, flags, sequence numbers | Multi-step logic that must be atomic |
Fairness | No fairness guarantee (fastest wins) | Lock fairness can be ensured (ReentrantLock) |
3️⃣ Example Difference
🔴 Using synchronized
class SyncCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
Locks the entire method → even if 100 threads, only 1 runs count++
at a time.
Thread waits in BLOCKED state.
🟢 Using AtomicInteger
class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // lock-free
}
}
Multiple threads can execute in parallel. CAS ensures correctness without blocking.
1️⃣ What is a HashMap?
-
Key-value pair data structure.
-
Allows null keys (only one) and multiple null values.
-
Not thread-safe (use
ConcurrentHashMap
for thread safety). -
O(1) average time complexity for
put()
andget()
. 2️⃣ Internal Data Structure
Internally, a
HashMap
uses:-
Array of buckets (Node[]) — each bucket holds a linked list or a balanced red-black tree (Java 8+).
-
Node<K,V> structure:
- static class Node<K,V> implements Map.Entry<K,V> {
- final int hash; // hash code of the key
- final K key; // key
- V value; // value
- Node<K,V> next; // pointer to next node in case of collision
- }
The process is:
-
Java computes the key’s
hashCode()
(an integer). -
Applies hash function to spread bits (to reduce collisions):
int hash = (key == null) ? 0 : hash(key.hashCode());
Find the Bucket Index
-
index = (n - 1) & hash
(wheren
= array length). -
This is faster than modulo.
Insert into Bucket
-
If bucket is empty → create new Node.
-
If key already exists → update value.
-
If collision occurs → add new node at the end (linked list).
Convert to Tree (Java 8+)
-
If the linked list size in a bucket exceeds TREEIFY_THRESHOLD (default 8) and capacity ≥ 64 → convert to Red-Black Tree for faster lookup.
-
-
-
5️⃣ Collision Handling
-
Uses Separate Chaining — each bucket stores multiple entries in a linked list/tree.
-
In Java 8+, linked list → tree if too many collisions.
6️⃣ Resizing
-
When size exceeds threshold =
capacity * loadFactor
(default 0.75):-
Double the capacity.
-
Rehash all entries into the new bucket array.
-
-
Resizing is costly — try to set initial capacity if possible.
9️⃣ Common Interview Follow-ups
-
What happens if two keys have same hashCode?
→ Stored in same bucket, collision handled via chaining/tree. -
Why is load factor 0.75?
→ Good balance between time & space; reduces collisions while avoiding too much resizing.
-
How is
null
key stored?
→ Always stored in bucket 0. -
Is
HashMap
thread-safe?
→ No. UseConcurrentHashMap
or synchronize externally. -
Difference between
HashMap
andHashtable
?
→Hashtable
is synchronized, doesn’t allow null keys/values.
7️⃣ Java 7 vs Java 8 Difference
Feature | Java 7 | Java 8 |
---|---|---|
Bucket storage | Linked List | Linked List + Red-Black Tree |
Order of insertion in bucket | Head insertion | Tail insertion |
Hash collision handling | More prone to long chains | Tree structure improves worst case to O(log n) |
difference between HashMap, Hashtable, and ConcurrentHashMap in Java
1. HashMap
-
Thread Safety: ❌ Not thread-safe — multiple threads can cause data inconsistency.
-
Nulls: ✅ Allows one null key and multiple null values.
-
Performance: Fastest (no synchronization overhead).
-
Introduced: Java 1.2
-
Use Case: Single-threaded or read-mostly operations.
2. Hashtable
-
Thread Safety: ✅ Thread-safe — all methods are synchronized.
-
Nulls: ❌ No null key, ❌ no null values.
-
Performance: Slower due to full method synchronization.
-
Introduced: Java 1.0 (Legacy class)
-
Use Case: Rarely used now; replaced by
ConcurrentHashMap
in multi-threaded code.
3. ConcurrentHashMap
-
Thread Safety: ✅ Thread-safe using bucket-level locking (Segmented Locking) instead of locking the entire map.
-
Nulls: ❌ No null key, ❌ no null values.
-
Performance: Faster than Hashtable in multi-threading because it only locks part of the map during updates.
-
Introduced: Java 1.5
-
Use Case: High-performance thread-safe map.
Internal Working
All three use:
-
Array of buckets internally.
-
Hash function to find bucket index.
-
Linked list (and in Java 8+, TreeMap for large buckets) for collision handling.
Difference in locking:
-
Hashtable
: Locks entire map for every operation. -
ConcurrentHashMap
: Locks only the bucket being modified. -
HashMap
: No locking.
If you use an Employee object as a key in a HashMap
, the map works fine — but only if you properly implement hashCode()
and equals()
in the Employee
class.
Otherwise, you’ll run into unexpected behavior like:
-
Duplicate keys being allowed.
-
Failure to retrieve a value even when you used the same data.
Steps:
-
hashCode()
ofemp1
is called → gives a hash value. -
That hash is converted to a bucket index using
(hash & (n - 1))
. -
If the bucket is empty → store
(key=emp1, value="Developer")
there. -
If the bucket already has entries:
-
Compare keys using
equals()
to see if the key already exists. -
If yes → update value.
-
If no → store alongside (collision).
hashCode()
ofemp2
is called → bucket index calculated.-
Finds the bucket.
-
Iterates keys in that bucket → calls
equals()
to match with stored keys. -
If match → returns value, else returns
null
.
Key Rule
For an object to work correctly as a HashMap key:
-
If
emp1.equals(emp2)
→ thenemp1.hashCode()
must be equal toemp2.hashCode()
. -
If you override
equals()
→ you must overridehashCode()
too.
💡 Interview takeaway:
When using a custom object (like Employee
) as a HashMap key:
-
Override equals() and hashCode() based on immutable fields.
-
Avoid mutable fields in keys, otherwise hash codes may change after insertion, making retrieval fail.
new
keyword ✅ (Most common)clone()
methodimplements Cloneable
and overrides clone()
in class.ObjectInputStream
(Deserialization)📌 Interview Tip:
If they ask "How many ways to create an object in Java?" — say:
"There are 5 primary ways:
new
keyword, reflection, cloning, deserialization, and factory methods. Additionally, there are less common ways like usingUnsafe
, class loaders, and builders."
Encapsulation in Java
Encapsulation in Java is about hiding the internal details of a class (its data) and controlling how it’s accessed or modified, typically using private fields with public getter and setter methods.
Think of it like a capsule of medicine: you can take the pill (public method) but you don’t see or directly handle the powder inside (private fields).
Key Points of Encapsulation
-
Data Hiding – Keep class variables private so they cannot be accessed directly from outside.
-
Controlled Access – Use getter and setter methods to read and modify the data.
-
Maintainability – You can change the internal implementation without affecting other classes.
-
Validation – You can put checks in setters to avoid invalid data.
Why This is Encapsulation
-
We hid the fields (
accountHolder
,balance
) from direct access. -
We provided controlled access through getters/setters and specific methods (
deposit
,withdraw
). -
We added validation logic to prevent invalid state.
1. Abstract Questions
Q1: What is an abstract class in Java?
A:
-
A class declared with
abstract
keyword. -
Can have abstract methods (no body) and concrete methods (with body).
-
Cannot be instantiated directly.
-
Used for partial abstraction and code reusability.
Q2: Can we create an object of an abstract class?
A:
No, but we can have references of an abstract class type pointing to subclass objects.
Q3: Can abstract classes have constructors?
A:
Yes. They are used for initializing fields when subclasses are created.
2. Medium Questions
Q4: Difference between abstract class and interface?
A:
Feature | Abstract Class | Interface |
---|---|---|
Methods | Abstract + Concrete | Abstract (Java 7), + default & static (Java 8) |
Fields | Instance & static variables | public static final only |
Inheritance | Single | Multiple |
Constructor | Yes | No |
Q5: Can abstract classes have static methods?
A:
Yes, but static methods cannot be abstract because they belong to the class, not an object.
Q6: Can an abstract class extend another abstract class?
A:
Yes. The subclass can either implement the inherited abstract methods or remain abstract.
3. Tricky Questions
Q7: Can we declare an abstract method as private
?
A:
No. Abstract methods must be visible to subclasses for implementation.
Q8: Can we make an abstract class final
?
A:
No. final
means it cannot be inherited, but an abstract class needs inheritance to implement abstract methods.
Q9: What happens if a subclass does not implement all abstract methods?
A:
The subclass must also be declared abstract.
Q10: Can an abstract class implement an interface?
A:
Yes, but it must either implement all interface methods or remain abstract.
Abstract Class vs Interface (Quick Answer)
-
Abstract Class → Can have both abstract methods and methods with body. Can have variables, constructors, and maintain state. Used when classes are closely related. Supports single inheritance.
-
Interface → Only has abstract methods (before Java 8) and can have default/static methods (Java 8+). All variables are
public static final
. Cannot have constructors or maintain state. Used to define a contract for unrelated classes. Supports multiple inheritance.
Memory Tip:
Abstract Class = Partially built house (some work done).
Interface = Blueprint (only plan given).
Java Exceptions are unexpected events that occur during the execution of a program and disrupt the normal flow of instructions.
They are represented as objects of classes derived from Throwable
.
In Java, exceptions are used to signal errors and handle them gracefully without crashing the program.
Types of Exceptions
-
Checked Exceptions – Checked at compile time (e.g.,
IOException
,SQLException
). -
Unchecked Exceptions – Occur at runtime (e.g.,
NullPointerException
,ArrayIndexOutOfBoundsException
). -
Errors – Serious problems not meant to be handled by applications (e.g.,
OutOfMemoryError
).
Example:
Comments
Post a Comment