# Core Java Interview Questions: Complete Guide with Answers and Examples

Mastering Core Java is essential for cracking technical interviews at top tech companies. Whether you’re preparing for **coding rounds, design discussions, or scenario-based questions**, having a solid grasp of **Java fundamentals, memory management, multithreading, collections, and design patterns** can set you apart.

This **comprehensive guide covers all the essential Core Java interview questions in 2025**, with clear explanations, comparisons, and **code examples**. From **OOP principles to Java 8 features, JVM internals, and practical real-world scenarios**, you’ll get a complete overview of the concepts that interviewers frequently test.

Use this guide to **boost your Java knowledge, strengthen problem-solving skills, and confidently tackle interviews**, making sure you’re well-prepared for both theoretical and hands-on coding rounds.

## Object Oriented Programming Concepts

### **1\. What are the principles of OOP?**

OOP (Object-Oriented Programming) is based on four main principles:

1. **Encapsulation** – Bundling data and methods that operate on that data into a single unit (class).  
    *Example:* Private fields with public getters/setters.
    
2. **Abstraction** – Hiding internal implementation details and exposing only essential features.  
    *Example:* Abstract classes and interfaces.
    
3. **Inheritance** – Reusing properties and methods from an existing class into a new class.  
    *Example:* `class Dog extends Animal`
    
4. **Polymorphism** – The ability of objects to take multiple forms.  
    *Example:* Method overriding where the same method behaves differently in different subclasses.
    

These principles together make code **modular, extensible, and maintainable**.

### **2\. Difference between abstraction and encapsulation**

| **Feature** | **Abstraction** | **Encapsulation** |
| --- | --- | --- |
| **Purpose** | Focuses on hiding implementation details | Focuses on bundling data and behavior |
| **Achieved By** | Abstract classes and interfaces | Access modifiers (private, public, etc.) |
| **Concerned With** | Design level | Implementation level |
| **Example** | Hiding database connection details behind an interface | Making class variables private and exposing getters/setters |

**In short:**  
Abstraction hides *what* is done, Encapsulation hides *how* it’s done.

### **3\. What is inheritance? How is it implemented in Java?**

**Inheritance** allows one class to inherit properties and behaviors from another, promoting code reuse.

In Java:

```java
class Parent {
    void greet() { System.out.println("Hello!"); }
}

class Child extends Parent {
    void greetChild() { System.out.println("Hi from Child!"); }
}
```

Here, `Child` inherits the `greet()` method from `Parent`.

**Types of inheritance in Java:**

* Single
    
* Multilevel
    
* Hierarchical
    

> Note: Java does **not support multiple inheritance with classes** to avoid ambiguity, but supports it with interfaces.

### **4\. What is polymorphism? Types?**

Polymorphism allows an object to behave differently based on context.

**Types:**

1. **Compile-time polymorphism (Method Overloading):**
    
    * Same method name, different parameter lists.
        
    * Resolved at compile-time.
        
    
    ```java
    void show(int a) {}
    void show(String b) {}
    ```
    
2. **Runtime polymorphism (Method Overriding):**
    
    * Subclass provides a new implementation of a parent method.
        
    * Resolved at runtime using **dynamic method dispatch**.
        

Polymorphism improves flexibility and scalability in OOP systems.

### **5\. What is method overloading vs overriding?**

| **Feature** | **Method Overloading** | **Method Overriding** |
| --- | --- | --- |
| **When** | Compile-time | Runtime |
| **Class Relationship** | Same class | Parent-child classes |
| **Parameters** | Must differ in type/number/order | Must be same |
| **Return Type** | Can differ | Must be same or covariant |
| **Static Binding** | Yes | No (uses dynamic binding) |

**Example:**

```java
// Overloading
void add(int a, int b) {}
void add(double a, double b) {}

// Overriding
class A { 
    void show() {} 
}
class B extends A { 
    void show() {} 
}
```

### **6\. Can we override static methods?**

No.  
Static methods are **bound at compile-time** (using class reference), not runtime (using object).

If a subclass defines a static method with the same name as the parent class’s static method, it **hides** the parent method — it’s not overriding.

```java
class Parent { 
    static void greet() {} 
}
class Child extends Parent { 
    static void greet() {} 
} // Method hiding
```

### **7\. Can a constructor be overridden?**

No.  
Constructors are **not inherited**, so overriding doesn’t apply.

However, constructors can be **overloaded** — a class can have multiple constructors with different parameter lists.

```java
class Person {
    Person() {}
    Person(String name) {}
}
```

### **8\. Why use interfaces instead of abstract classes?**

Interfaces are preferred when you want to **define a contract** that multiple unrelated classes can implement.

**Key reasons:**

* Java supports **multiple interface inheritance**, but not multiple class inheritance.
    
* Promotes **loose coupling** — implementation can vary independently.
    
* Ideal for defining **APIs, services, or capabilities** (e.g., `Comparable`, `Runnable`).
    

**Example:**  
A class can `implements Serializable, Comparable` but can only `extends` one abstract class.

### **9\. Interface vs Abstract Class**

| **Feature** | **Interface** | **Abstract Class** |
| --- | --- | --- |
| **Inheritance** | Multiple allowed | Single allowed |
| **Contains** | Abstract methods + constants (Java 8+: default & static methods too) | Can have abstract & concrete methods |
| **Variables** | `public static final` by default | Can be instance variables |
| **Constructor** | Not allowed | Allowed |
| **Use Case** | When defining behavior/contract | When defining base class with partial implementation |

In modern Java, interfaces are often used to define **capabilities**, while abstract classes define **common base logic**.

### **10\. Can we create an object of abstract class or interface?**

No, both **cannot be instantiated** directly.  
They serve as blueprints for subclasses or implementing classes.

However, you can create:

* **Anonymous inner classes** or **lambda expressions** that provide concrete implementations.
    

```java
Runnable r = new Runnable() {
    public void run() { System.out.println("Running..."); }
};
```

Here, an **anonymous implementation** of the interface is created.

## Java Basics

### **1\. What is the Java Virtual Machine (JVM)?**

The **JVM (Java Virtual Machine)** is an abstract machine that executes Java bytecode.  
It provides a **runtime environment** for Java applications and is platform-dependent.

**Key responsibilities:**

* **Loading**: Uses the ClassLoader to load class files.
    
* **Verifying**: Ensures bytecode security.
    
* **Executing**: Uses the Just-In-Time (JIT) compiler to convert bytecode to native code.
    
* **Memory Management**: Allocates and manages heap, stack, and garbage collection.
    

In short:  
👉 **Java code → compiled to bytecode → executed by JVM → runs on any OS (platform independence).**

### **2\. Explain JRE vs JDK vs JVM.**

| **Component** | **Full Form** | **Purpose** |
| --- | --- | --- |
| **JVM** | Java Virtual Machine | Executes Java bytecode |
| **JRE** | Java Runtime Environment | Contains JVM + libraries required to run Java apps |
| **JDK** | Java Development Kit | Contains JRE + development tools (compiler, debugger, etc.) |

**Relationship:**  
👉 **JDK = JRE + development tools**  
👉 **JRE = JVM + libraries**

### **3\. What is the role of main() method in Java?**

`main()` is the **entry point** of any standalone Java application.  
Signature:

```java
public static void main(String[] args)
```

**Breakdown:**

* `public`: Accessible by JVM.
    
* `static`: JVM can call it without creating an object.
    
* `void`: Doesn’t return any value.
    
* `String[] args`: Accepts command-line arguments.
    

Without `main()`, the program doesn’t have a starting point.

### **4\. What happens if the main() method is not static?**

If `main()` is **not static**, the JVM cannot invoke it directly because no object of the class exists yet.  
This leads to a **runtime error** like:

```java
Error: Main method is not static in class MainClass
```

JVM needs `main()` to be static so that it can call it **without object instantiation**.

### **5\. Can Java run without main()?**

In modern Java (Java 7+), **no** — every standalone program needs a `main()` method.

Earlier (in applets or servlet containers), Java classes could be run without `main()` because:

* Applets start with the `init()` method.
    
* Servlets are loaded and managed by a container (`init()`, `service()`, `destroy()`).
    

For normal console applications → **main() is mandatory**.

## Memory Management

### **1\. Explain Java memory model.**

The **Java Memory Model (JMM)** defines how Java threads interact through memory — how variables are read/written, and how visibility is ensured in concurrent execution.

It divides memory into:

* **Heap:** Stores objects and their instance variables (shared across threads).
    
* **Stack:** Each thread has its own stack storing method calls and local variables.
    
* **Method Area (Metaspace in Java 8+):** Stores class-level metadata like method definitions and constant pool.
    
* **PC Register:** Holds address of current executing instruction.
    
* **Native Method Stack:** Used for native (non-Java) code execution.
    

The JMM ensures **visibility**, **ordering**, and **atomicity** across threads using keywords like `volatile`, `synchronized`, and `final`.

### **2\. What is heap vs stack?**

| **Aspect** | **Heap** | **Stack** |
| --- | --- | --- |
| **Stores** | Objects, instance variables | Local variables, method calls |
| **Shared?** | Shared among all threads | Each thread has its own stack |
| **Lifetime** | Exists until object is garbage collected | Exists until method completes |
| **Managed By** | Garbage Collector | JVM automatically manages |
| **Access Speed** | Slower | Faster |

Example:

```java
int x = 10;            // stored in stack
Person p = new Person(); // object p in heap, reference in stack
```

### **3\. What is PermGen and Metaspace?**

* **PermGen (Permanent Generation):**  
    Used before Java 8 to store class metadata, static variables, and interned strings.  
    Had a **fixed size**, which could cause `OutOfMemoryError: PermGen space`.
    
* **Metaspace (Java 8+):**  
    Replaced PermGen. It stores **class metadata** in **native memory** (not heap).  
    Grows dynamically as needed, reducing memory errors.
    

✅ **In short:** Metaspace is a more flexible, dynamic replacement for PermGen.

### **4\. What is garbage collection? How does it work?**

**Garbage Collection (GC)** is an automatic memory management process that reclaims memory from objects no longer reachable by any reference.

**How it works:**

1. JVM identifies **unreachable objects** (not referenced anywhere).
    
2. GC frees that memory space.
    
3. Memory is reused for new objects.
    

**GC Algorithms:**

* **Serial GC** (single-threaded, small apps)
    
* **Parallel GC** (multi-threaded)
    
* **G1 GC (Garbage First)** – default in Java 9+, low pause time collector.
    

**Phases:**

* **Mark:** Identify live objects.
    
* **Sweep/Compact:** Remove dead objects and defragment memory.
    

Developers can trigger GC via `System.gc()`, but JVM decides the actual execution time.

### **5\. Finalize method – how and when is it called?**

`finalize()` is a method defined in the `Object` class:

```java
protected void finalize() throws Throwable
```

It’s called by the **Garbage Collector** before reclaiming an object’s memory — a last chance to release resources.

**However:**

* Execution is **not guaranteed** or **timely**.
    
* It might **never be called** if the program exits before GC runs.
    

✅ Since Java 9, `finalize()` is **deprecated**.  
Modern alternatives:

* Use `try-with-resources` for closing streams.
    
* Implement `AutoCloseable` for cleanup logic.
    

## Access Modifiers

### **1\. Difference between private, protected, public, and default**

Java provides four access levels to control visibility of classes, methods, and variables.

| **Modifier** | **Within Class** | **Within Package** | **Subclass (Other Package)** | **Outside Package** |
| --- | --- | --- | --- | --- |
| **private** | ✅ | ❌ | ❌ | ❌ |
| **default** *(no modifier)* | ✅ | ✅ | ❌ | ❌ |
| **protected** | ✅ | ✅ | ✅ | ❌ |
| **public** | ✅ | ✅ | ✅ | ✅ |

**Summary:**

* **private** → Most restrictive; used for encapsulation.
    
* **default** → Accessible within the same package.
    
* **protected** → Visible to subclasses even if they’re in different packages.
    
* **public** → Accessible from anywhere.
    

**Example:**

```java
public class Person {
    private int age;
    protected String name;
    public void greet() {}
}
```

### **2\. Can a class be private in Java?**

Top-level (outer) classes **cannot be private** — they must be either **public** or **default**.

However, **inner classes** can be private.

**Example:**

```java
class Outer {
    private class Inner {   // ✅ allowed
        void show() { System.out.println("Inner"); }
    }
}
```

If a top-level class were private, **no other class** (even in the same package) could access it — defeating the purpose of reusability.

### **3\. What are static blocks?**

A **static block** in Java is used for **class-level initialization**.  
It runs **once**, when the class is **first loaded** into memory (before any constructor or object creation).

**Example:**

```java
class DatabaseConnection {
    static {
        System.out.println("Initializing DB connection...");
    }
}
```

**Use cases:**

* Initialize static variables.
    
* Load configurations.
    
* Perform one-time setup (e.g., registering JDBC drivers).
    

**Order of execution:**

1. Static variables.
    
2. Static blocks (in order of appearance).
    
3. Constructors (when object is created).
    

## Exception Handling

### **1\. Checked vs Unchecked Exceptions?**

| **Type** | **Checked Exception** | **Unchecked Exception** |
| --- | --- | --- |
| **Inheritance** | Subclass of `Exception` (excluding `RuntimeException`) | Subclass of `RuntimeException` |
| **Checked at** | Compile-time | Runtime |
| **Handling Required?** | Must be handled or declared using `throws` | Optional |
| **Examples** | `IOException`, `SQLException`, `FileNotFoundException` | `NullPointerException`, `ArithmeticException`, `ArrayIndexOutOfBoundsException` |

**Key point:**  
Checked exceptions represent **recoverable errors**, while unchecked ones indicate **programming bugs** (e.g., null access).

### **2\. Difference between throw and throws?**

| **Keyword** | `throw` | `throws` |
| --- | --- | --- |
| **Purpose** | Used to actually throw an exception | Declares that a method may throw exceptions |
| **Usage Place** | Inside method body | In method signature |
| **Follows** | Single exception instance | One or more exception classes |
| **Example** | `throw new IOException("File not found");` | `void readFile() throws IOException {}` |

Example:

```java
void readFile() throws IOException {
    throw new IOException("Error reading file");
}
```

### **3\. Can we have try block without catch/finally?**

No ❌  
A `try` block must be followed by at least **one** of the following:

* A `catch` block
    
* A `finally` block
    

However, `try-finally` without `catch` is valid:

```java
try {
    System.out.println("Try block");
} finally {
    System.out.println("Cleanup code");
}
```

This ensures cleanup executes even if no exception occurs.

### **4\. What is the use of finally block?**

The `finally` block is used for **resource cleanup** — it executes **always**, regardless of whether an exception occurs or not.

**Example:**

```java
try {
    FileInputStream fis = new FileInputStream("data.txt");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    System.out.println("Closing resources...");
}
```

✅ Executed:

* After try or catch block
    
* Even if `return` is used inside try or catch  
    ❌ Not executed if JVM exits via `System.exit(0)` or power failure.
    

**Modern alternative:**  
Use **try-with-resources (Java 7+)** to auto-close resources.

### **5\. Custom exception in Java?**

A **custom exception** allows developers to define domain-specific error types.

**Steps to create:**

1. Extend `Exception` (for checked) or `RuntimeException` (for unchecked).
    
2. Add constructors for custom messages.
    

**Example:**

```java
class InvalidAgeException extends Exception {
    public InvalidAgeException(String msg) {
        super(msg);
    }
}

class Validator {
    void validate(int age) throws InvalidAgeException {
        if (age < 18)
            throw new InvalidAgeException("Age must be >= 18");
    }
}
```

**Use cases:**

* Validation (e.g., invalid user input)
    
* Business logic constraints
    
* Domain-specific error reporting (e.g., `InsufficientBalanceException`)
    

## Collections Framework

### **1\. List vs Set vs Map?**

| **Feature** | **List** | **Set** | **Map** |
| --- | --- | --- | --- |
| **Stores** | Ordered collection of elements | Unique elements (no duplicates) | Key-value pairs |
| **Duplicates** | Allowed | Not allowed | Keys: not allowed, Values: allowed |
| **Order** | Maintains insertion order | Depends on implementation | Depends on implementation |
| **Implementations** | `ArrayList`, `LinkedList`, `Vector` | `HashSet`, `LinkedHashSet`, `TreeSet` | `HashMap`, `TreeMap`, `LinkedHashMap` |

**Example:**

```java
List<String> list = new ArrayList<>();
Set<String> set = new HashSet<>();
Map<Integer, String> map = new HashMap<>();
```

### **2\. ArrayList vs LinkedList?**

| Aspect | ArrayList | LinkedList |
| --- | --- | --- |
| **Data Structure** | Dynamic array | Doubly linked list |
| **Access Time** | O(1) for index-based access | O(n) traversal required |
| **Insertion/Deletion (middle)** | O(n) | O(1) if node reference known |
| **Memory Usage** | Less (compact) | More (extra node references) |
| **Use Case** | Random access | Frequent insertions/deletions |

**Example:**

* Use `ArrayList` when reads are frequent.
    
* Use `LinkedList` when insertions/removals are frequent.
    

### **3\. HashMap vs Hashtable?**

| **Feature** | **HashMap** | **Hashtable** |
| --- | --- | --- |
| **Thread-Safety** | Not synchronized | Synchronized |
| **Null Keys/Values** | Allows one null key, multiple null values | Doesn’t allow nulls |
| **Performance** | Faster (no locking) | Slower (locks entire table) |
| **Introduced In** | Java 1.2 | Java 1.0 |
| **Preferred?** | Yes, in modern Java | Legacy class |

✅ For thread-safe alternatives, use `ConcurrentHashMap` instead of `Hashtable`.

### **4\. How does HashMap work internally?**

HashMap stores data in **buckets** using a **hashing mechanism**.

**Process:**

1. Key’s `hashCode()` is computed.
    
2. The hash is mapped to an index in the bucket array (`(n - 1) & hash`).
    
3. Each bucket holds a linked list or tree (Java 8+).
    
4. On `put()`:
    
    * If key exists → value replaced.
        
    * If not → new node added.
        
5. On `get()`:
    
    * Hash computed → bucket located → key compared using `equals()`.
        

**Optimization (Java 8+):**

* If bucket size &gt; 8, converts linked list → **balanced tree** (Red-Black Tree) for O(log n) lookup.
    

### **5\. What is the load factor and threshold in HashMap?**

* **Load Factor:** Defines how full the HashMap can get before resizing (default = 0.75).
    
* **Threshold:** `capacity × loadFactor`.  
    When the number of entries exceeds this threshold, HashMap **resizes** (doubles its capacity).
    

Example:

```java
HashMap<String, Integer> map = new HashMap<>(16, 0.75f);
```

✅ Resizing improves performance but comes with a cost — it’s best to initialize maps with an estimated size to minimize rehashing.

### **6\. What are fail-fast and fail-safe iterators?**

| **Type** | **Behavior** | **Example Collections** |
| --- | --- | --- |
| **Fail-Fast** | Throws `ConcurrentModificationException` if the collection is modified while iterating | `ArrayList`, `HashMap` |
| **Fail-Safe** | Works on a clone or snapshot of the collection | `ConcurrentHashMap`, `CopyOnWriteArrayList` |

Example:

```java
for (Integer i : list) {
    list.add(10); // ❌ throws ConcurrentModificationException
}
```

✅ Use **fail-safe** collections in concurrent environments.

### **7\. What is ConcurrentHashMap and how is it different?**

`ConcurrentHashMap` is a thread-safe alternative to `HashMap` that provides **high concurrency** with minimal locking.

**How it differs:**

* No full-table lock (uses **segment-level locking** or **CAS** in Java 8+).
    
* Null keys/values are **not allowed**.
    
* Iterators are **fail-safe** (operate on snapshot).
    
* Performs better than `Hashtable` under multithreading.
    

**Example:**

```java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("A", 1);
```

### **8\. TreeMap vs HashMap?**

| Feature | HashMap | TreeMap |
| --- | --- | --- |
| **Order** | No ordering | Sorted (natural/comparator) |
| **Implementation** | Hash table | Red-Black tree |
| **Null Keys** | Allows one | Doesn’t allow null key |
| **Performance** | O(1) average | O(log n) |
| **Use Case** | Fast lookups | Sorted data retrieval |

**Example:**

```java
Map<Integer, String> map = new TreeMap<>();
map.put(2, "B");
map.put(1, "A"); // Automatically sorted by key
```

### **9\. What is LinkedHashMap?**

`LinkedHashMap` maintains **insertion order** or **access order** of entries.

**Internally:**  
It extends `HashMap` and adds a **doubly-linked list** to preserve order.

**Example:**

```java
Map<Integer, String> map = new LinkedHashMap<>();
map.put(1, "A");
map.put(2, "B");
```

✅ Useful when you need predictable iteration order or LRU caching (using `removeEldestEntry`).

### **10\. When to use ArrayList vs Vector?**

| **Feature** | **ArrayList** | **Vector** |
| --- | --- | --- |
| **Synchronization** | Not synchronized | Synchronized |
| **Performance** | Faster | Slower (locks every method) |
| **Introduced In** | Java 1.2 | Java 1.0 (legacy) |
| **Growth** | Grows by 50% | Grows by 100% (doubles) |

✅ Modern Java avoids `Vector`.  
Use `ArrayList` for single-threaded cases, or `Collections.synchronizedList()` if synchronization is needed.

## Multithreading and Concurrency

### **1\. Difference between process and thread?**

| **Feature** | **Process** | **Thread** |
| --- | --- | --- |
| **Definition** | Independent program in execution | Smallest unit of a process |
| **Memory** | Has its own memory space | Shares memory with other threads of same process |
| **Communication** | Inter-process communication is complex | Easier via shared objects |
| **Failure Impact** | One process crash doesn’t affect others | Thread crash may affect whole process |
| **Example** | Running two Java programs | Two threads in same Java program |

**In short:** Threads share the same heap, enabling lightweight multitasking within a single process.

### **2\. Ways to create a thread in Java?**

There are **three main ways**:

1. **Extend** `Thread` class
    
    ```java
    class MyThread extends Thread {
        public void run() {
            System.out.println("Thread running...");
        }
    }
    new MyThread().start();
    ```
    
2. **Implement** `Runnable` interface
    
    ```java
    class MyTask implements Runnable {
        public void run() {
            System.out.println("Running via Runnable");
        }
    }
    new Thread(new MyTask()).start();
    ```
    
3. **Use** `ExecutorService` or `Callable` (preferred in modern Java)
    
    ```java
    ExecutorService service = Executors.newFixedThreadPool(2);
    service.submit(() -> System.out.println("Running in pool"));
    ```
    

✅ Best practice: Use `ExecutorService` to manage threads efficiently.

### **3\. Thread vs Runnable?**

| **Feature** | **Thread** | **Runnable** |
| --- | --- | --- |
| **Inheritance** | Requires extending Thread | Can be implemented along with other interfaces |
| **Code Reuse** | Less flexible | More flexible (no multiple inheritance issue) |
| **Preferred** | For small/simple use | Runnable preferred for real-world apps |

**Example:**  
If your class already extends another class, use `Runnable` since Java doesn’t support multiple inheritance.

### **4\. What is thread lifecycle?**

A thread in Java passes through these **five states**:

1. **New** – Created but not started (`new Thread()`).
    
2. **Runnable** – Ready to run, waiting for CPU (`start()` called).
    
3. **Running** – Currently executing.
    
4. **Blocked/Waiting** – Waiting for a resource or another thread.
    
5. **Terminated** – Execution completed or stopped.
    

**Example:**

```java
Thread t = new Thread(() -> {});
t.start();  // Runnable
```

### **5\. Difference between wait, sleep, join?**

| **Method** | **Defined In** | **Releases Lock?** | **Purpose** |
| --- | --- | --- | --- |
| **wait()** | Object class | ✅ Yes | Waits until notified (`notify()` / `notifyAll()`) |
| **sleep()** | Thread class | ❌ No | Pauses execution for given time |
| **join()** | Thread class | ❌ No | Waits for another thread to finish |

Example:

```java
Thread t = new Thread(() -> System.out.println("Task"));
t.start();
t.join(); // waits for t to finish
```

### **6\. What is synchronized block/method?**

The `synchronized` keyword ensures **mutual exclusion** — only one thread can access a block/method at a time for a given object.

**Types:**

* **Synchronized method**
    
    ```java
    synchronized void increment() { 
        count++; 
    }
    ```
    
* **Synchronized block**
    
    ```java
    void increment() {
        synchronized(this) {
            count++;
        }
    }
    ```
    

**Benefits:** Prevents race conditions.  
**Downside:** Can reduce performance due to locking.

### **7\. What is a deadlock? How to prevent it?**

A **deadlock** occurs when two or more threads are waiting for each other’s locks indefinitely.

**Example:**

```java
synchronized (obj1) {
    synchronized (obj2) { ... }
}
```

Another thread might lock `obj2` first, then wait for `obj1`.

**Prevention:**

* Acquire locks in a consistent order.
    
* Use `tryLock()` with timeout (`ReentrantLock`).
    
* Avoid nested locks where possible.
    

### **8\. What is volatile keyword?**

The `volatile` keyword ensures that a variable’s value is **always read from main memory**, not from a thread’s local cache.

**Example:**

```java
volatile boolean flag = true;
```

If one thread changes `flag`, other threads immediately see the updated value.

**Important:**

* Ensures **visibility**, not **atomicity**.
    
* For compound operations (e.g., `count++`), use synchronization or `AtomicInteger`.
    

### **9\. Difference between ExecutorService and Thread?**

| **Aspect** | **Thread** | **ExecutorService** |
| --- | --- | --- |
| **Creation** | Manually create and start threads | Manages thread pool automatically |
| **Reusability** | One-time use | Threads are reused |
| **Performance** | Higher overhead | More efficient for multiple tasks |
| **Introduced** | Java 1.0 | Java 5 (`java.util.concurrent`) |

Example:

```java
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
```

✅ **Best practice:** Always use `ExecutorService` for managing multiple threads efficiently.

### **10\. What is thread safety?**

**Thread safety** means an object or code segment behaves correctly when accessed by multiple threads simultaneously.

**Ways to achieve:**

* Use **immutable objects**
    
* Use **synchronized blocks**
    
* Use **atomic classes** (`AtomicInteger`, `AtomicReference`)
    
* Use **concurrent collections** (`ConcurrentHashMap`, `CopyOnWriteArrayList`)
    

**Example:**

```java
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
```

✅ Thread-safe code avoids **race conditions** and **data inconsistency**.

## Java 8 Features

### **1\. What are the major features introduced in Java 8?**

Java 8 introduced **functional programming** concepts and several performance improvements.

**Key Features:**

* Lambda Expressions
    
* Functional Interfaces
    
* Stream API
    
* Optional class
    
* Method References
    
* Default and Static methods in Interfaces
    
* Date and Time API (`java.time`)
    
* Parallel Streams
    

### **2\. What are lambda expressions?**

A **lambda expression** provides a concise way to represent anonymous functions.

**Syntax:**

```java
(parameter) -> expression
```

**Example:**

```java
List<String> names = Arrays.asList("John", "Jane", "Max");
names.forEach(name -> System.out.println(name));
```

**Before Java 8:**

```java
for (String name : names)
    System.out.println(name);
```

✅ **Advantages:**

* Reduces boilerplate code
    
* Enables functional programming
    
* Works well with Streams and Collections
    

### **3\. What is a functional interface?**

A **functional interface** is an interface that contains exactly **one abstract method**.  
It can have **default or static methods** as well.

**Example:**

```java
@FunctionalInterface
interface Calculator {
    int add(int a, int b);
}
```

**Built-in Functional Interfaces (in** `java.util.function`):

* `Predicate<T>` → returns boolean
    
* `Function<T, R>` → transforms T to R
    
* `Consumer<T>` → accepts and performs action
    
* `Supplier<T>` → returns value without input
    

**Example:**

```java
Predicate<Integer> isEven = x -> x % 2 == 0;
System.out.println(isEven.test(4)); // true
```

### **4\. What is the Stream API?**

The **Stream API** is used to process collections of data in a **declarative and functional style**.

**Example:**

```java
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = nums.stream()
                            .map(n -> n * n)
                            .collect(Collectors.toList());
System.out.println(squares);
```

**Key Operations:**

* Intermediate → `filter()`, `map()`, `sorted()`
    
* Terminal → `collect()`, `forEach()`, `count()`, `reduce()`
    

✅ **Streams don’t modify the original collection.**

### **5\. What is the difference between map() and flatMap()?**

| **Method** | **Purpose** | **Example** |
| --- | --- | --- |
| **map()** | Transforms each element | `[1,2,3] → [1,4,9]` |
| **flatMap()** | Flattens nested streams | `[[1,2],[3,4]] → [1,2,3,4]` |

**Example:**

```java
List<List<Integer>> list = Arrays.asList(Arrays.asList(1,2), Arrays.asList(3,4));
list.stream().flatMap(Collection::stream).forEach(System.out::println);
```

### **6\. What is the Optional class?**

`Optional<T>` is a container that may or may not hold a non-null value.  
It helps **avoid NullPointerException**.

**Example:**

```java
Optional<String> name = Optional.ofNullable(getName());
System.out.println(name.orElse("Unknown"));
```

**Common methods:**

* `isPresent()`
    
* `orElse()`
    
* `orElseGet()`
    
* `orElseThrow()`
    
* `map()` and `flatMap()`
    

✅ Always use `Optional` for return types, not fields.

### **7\. What are method references?**

Method references provide a shorthand for calling existing methods using `::`.

**Example:**

```java
list.forEach(System.out::println);
```

**Types:**

* Static method → `ClassName::staticMethod`
    
* Instance method → `object::instanceMethod`
    
* Constructor → `ClassName::new`
    

**Example:**

```java
Supplier<List<String>> supplier = ArrayList::new;
```

### **8\. What are default and static methods in interfaces?**

**Default methods**: Provide a method body inside an interface.

**Example:**

```java
interface Vehicle {
    default void start() {
        System.out.println("Vehicle started");
    }
}
```

**Static methods** in interfaces belong to the interface itself:

```java
interface Utils {
    static void show() {
        System.out.println("Static method in interface");
    }
}
```

✅ These features were introduced to maintain backward compatibility when new methods were added to interfaces like `List` and `Map`.

### **9\. What is the new Date and Time API (java.time)?**

Java 8 introduced a **modern, immutable, thread-safe** Date-Time API.

**Key Classes:**

* `LocalDate`, `LocalTime`, `LocalDateTime`
    
* `ZonedDateTime`
    
* `Period`, `Duration`
    
* `DateTimeFormatter`
    

**Example:**

```java
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
System.out.println(tomorrow);
```

✅ No more `java.util.Date` and `SimpleDateFormat` pain!

### **10\. What are parallel streams?**

Parallel streams allow data to be processed **in multiple threads automatically**.

**Example:**

```java
list.parallelStream()
    .filter(x -> x > 10)
    .forEach(System.out::println);
```

**Note:**

* Use parallel streams **for CPU-intensive** operations.
    
* Avoid for **IO-bound** or small datasets (due to overhead).
    

## Strings

### **1\. String vs StringBuilder vs StringBuffer?**

| **Feature** | `String` | `StringBuilder` | `StringBuffer` |
| --- | --- | --- | --- |
| **Mutability** | Immutable | Mutable | Mutable |
| **Thread-safety** | Not thread-safe | Not thread-safe | Thread-safe (synchronized) |
| **Performance** | Slower (creates new objects) | Faster (no synchronization) | Slightly slower (synchronization overhead) |
| **Use Case** | When data doesn’t change | Single-threaded string manipulations | Multi-threaded string manipulations |

**Example:**

```java
String s = "Hello";
s.concat(" World"); // New object created

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Modified in place
```

✅ For most use cases → prefer **StringBuilder** (fast, flexible).

### **2\. How are strings stored in memory?**

* Strings are stored in a special area of heap memory called the **String Constant Pool (SCP)**.
    
* When you create a string literal, e.g., `"Java"`, it’s **interned** — meaning:
    
    * If `"Java"` already exists in the pool, the same reference is reused.
        
    * If not, it’s added to the pool.
        

**Example:**

```java
String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // true (same reference)
```

✅ **String literals** are interned;  
`new String("Java")` creates a **new object** on the heap (not in SCP).

### **3\. What is the String Constant Pool?**

The **String Constant Pool** (SCP) is part of the **heap memory** (since Java 7+).  
It’s a cache that stores **unique string literals** to improve performance and save memory.

**Example:**

```java
String a = "Test";
String b = "Test";
System.out.println(a == b); // true (both refer to same object)
```

If created using `new`:

```java
String c = new String("Test");
System.out.println(a == c); // false (different objects)
```

✅ You can manually add strings to the pool using `intern()`:

```java
String d = c.intern();
System.out.println(a == d); // true
```

### **4\. Why are Strings immutable in Java?**

**Reasons:**

1. **Security:** Used in sensitive contexts (ClassLoader, File paths, URLs).
    
2. **Thread-safety:** Immutable objects can be shared safely between threads.
    
3. **Caching:** Hash code of a string is cached; immutability ensures it’s consistent.
    
4. **String Pool Optimization:** Same string literals can be reused safely.
    

**Example:**

```java
String s = "Java";
s.concat(" Rocks"); // creates a new string
```

✅ Once created, the value of a String object **cannot be changed**.

### **5\. How does equals() work in String?**

The `equals()` method compares **the contents (values)** of two strings,  
while the `==` operator compares **references**.

**Example:**

```java
String s1 = new String("Hello");
String s2 = new String("Hello");

System.out.println(s1 == s2);       // false (different objects)
System.out.println(s1.equals(s2));  // true (same content)
```

✅ `String` overrides `equals()` and `hashCode()` from `Object` class to compare actual text.

### **6\. How does** `hashCode()` work in Strings?

* The hash code for a string is computed based on its characters:
    
    ```java
    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    ```
    
* Because strings are immutable, their hash code is **cached** for performance.
    

✅ Used extensively in collections like `HashMap` and `HashSet`.

### **7\. How do** `substring()`, `split()`, and `join()` work?

`substring(begin, end)`

* Returns part of the string.
    
* Creates a new String (does not modify original).
    

**Example:**

```java
String s = "developer";
System.out.println(s.substring(0, 3)); // "dev"
```

`split(regex)`

* Splits a string into an array based on a delimiter.
    

```java
String s = "a,b,c";
String[] arr = s.split(",");
```

`String.join(delimiter, elements...)`

```java
String result = String.join("-", "Java", "Python", "C++");
System.out.println(result); // "Java-Python-C++"
```

### **8\. What is String interning?**

Interning ensures that identical strings share the same reference in the **String Pool**.

**Example:**

```java
String s1 = new String("Java");
String s2 = s1.intern();
String s3 = "Java";

System.out.println(s2 == s3); // true
```

✅ Improves memory efficiency, especially when there are many repeated strings.

### **9\. What are common StringBuilder methods?**

* `append()` – concatenates data
    
* `insert()` – inserts at position
    
* `delete()` – removes substring
    
* `reverse()` – reverses content
    
* `capacity()` – returns current buffer capacity
    

**Example:**

```java
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World").reverse();
System.out.println(sb); // "dlroW olleH"
```

### **10\. Can we make String mutable in Java?**

Not directly.  
However, you can **simulate mutability** using:

* `StringBuilder` or `StringBuffer`
    
* Reflection (not recommended)
    
* Creating a wrapper class with a mutable reference internally
    

## Java Keywords and Modifiers

### **1\. Difference between final, finally, and finalize?**

| **Keyword** | **Purpose** | **Example** |
| --- | --- | --- |
| **final** | Restricts modification | `final int x = 10;` or `final class MyClass` |
| **finally** | Block to execute after try/catch | `try {…} finally {…}` |
| **finalize()** | Called by GC before object is destroyed | `protected void finalize() {…}` |

**Summary:**

* `final` → compile-time constant, prevents inheritance/overriding
    
* `finally` → runtime block for cleanup
    
* `finalize()` → deprecated method, used for cleanup before garbage collection
    

### **2\. What does static mean?**

* **Static** members belong to the **class**, not instances.
    
* **Static variable:** Shared across all objects
    
* **Static method:** Can be called without an object
    
* **Static block:** Executes once at class loading
    

**Example:**

```java
class Demo {
    static int count;
    static { System.out.println("Class loaded"); }
    static void show() { System.out.println("Static method"); }
}
Demo.show();
System.out.println(Demo.count);
```

✅ Use static for memory efficiency and shared state.

### **3\. What is transient?**

* **Transient** is a keyword used in **serialization**.
    
* Fields marked as transient are **not serialized**.
    

**Example:**

```java
class User implements Serializable {
    private String name;
    private transient String password; // won’t be saved
}
```

✅ Useful for sensitive data like passwords or temporary fields.

### **4\. What is volatile?**

* Ensures **visibility** of changes across threads.
    
* Guarantees that **reads/writes go directly to main memory**.
    
* Does **not** guarantee atomicity.
    

**Example:**

```java
volatile boolean running = true;

while (running) { 
    /* do work */ 
}
```

Without `volatile`, one thread may never see the updated value.

### **5\. Difference between this and super?**

| **Keyword** | **Purpose** | **Example** |
| --- | --- | --- |
| **this** | Refers to current object | `this.name = name;` |
| **super** | Refers to parent class | `super.toString();` |

* `this()` → calls current class constructor
    
* `super()` → calls parent class constructor
    
* Both must be the **first statement** in constructor when used
    

### **6\. Additional Notes on Keywords/Modifiers**

* **abstract:** Cannot instantiate class, may contain abstract methods
    
* **synchronized:** Ensures mutual exclusion for threads
    
* **native:** Method implemented in platform-specific code (C/C++)
    
* **strictfp:** Ensures floating-point calculations are platform-independent
    
* **default (in interfaces):** Provides default method implementation
    
* **var (Java 10+):** Type inference for local variables
    

## Java Inner Classes

### **1\. What are inner classes?**

An **inner class** is a class defined **within another class**.  
They allow logical grouping of classes and access to **private members** of the outer class.

**Types of inner classes:**

1. **Member (non-static) inner class**
    
2. **Static nested class**
    
3. **Local inner class**
    
4. **Anonymous inner class**
    

### **2\. What are static nested classes?**

* A **static nested class** is declared with the `static` keyword.
    
* Unlike member inner classes, it **does not have access to instance variables** of the outer class.
    
* Can be instantiated without an object of the outer class.
    

**Example:**

```java
class Outer {
    static class Nested {
        void show() { System.out.println("Static nested class"); }
    }
}
Outer.Nested nested = new Outer.Nested();
nested.show();
```

✅ Useful for **grouping classes** logically and reducing namespace pollution.

### **3\. Difference between local, anonymous, and member classes**

| **Type** | **Definition** | **Scope** | **Example** |
| --- | --- | --- | --- |
| **Member inner class** | Defined at class level (non-static) | Can access outer class members | `class Outer { class Inner {} }` |
| **Static nested class** | Defined with `static` keyword | Only static members of outer class | `Outer.Nested nested = new Outer.Nested();` |
| **Local inner class** | Defined inside a method | Only visible within method | `void method() { class Local {} }` |
| **Anonymous inner class** | No class name, used for instant implementation | Usually for implementing interfaces or extending classes | `Runnable r = new Runnable() { public void run() {} };` |

**Key points:**

* Member inner classes hold a **reference to outer class**.
    
* Static nested classes **don’t hold outer class reference**, so memory footprint is smaller.
    
* Anonymous classes are great for **event handlers and callbacks**.
    

**Example of anonymous inner class:**

```java
Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Anonymous Runnable");
    }
};
new Thread(r).start();
```

### **4\. When to use inner classes?**

* When a class is **only relevant to its outer class**.
    
* For **callbacks, listeners, or adapters**.
    
* To **encapsulate helper classes** without exposing them publicly.
    
* To **access outer class private members** without getters/setters.
    

✅ Correct use of inner classes improves **code readability, encapsulation, and design**.

## Design Principles / Patterns

### **1\. What is SOLID?**

[**SOLID**](https://blog.ashutoshkrris.in/solid-principles-for-better-software-design) is an acronym for five design principles that make code **more maintainable, scalable, and testable**:

| **Principle** | **Description** |
| --- | --- |
| **S – Single Responsibility Principle (SRP)** | A class should have **only one reason to change**. Each class should focus on a single functionality. |
| **O – Open/Closed Principle (OCP)** | Classes should be **open for extension, closed for modification**. |
| **L – Liskov Substitution Principle (LSP)** | Subclasses should be **substitutable** for their parent classes without affecting program correctness. |
| **I – Interface Segregation Principle (ISP)** | Clients should **not be forced to depend on methods they don’t use**. Prefer multiple small interfaces over one large interface. |
| **D – Dependency Inversion Principle (DIP)** | High-level modules should **not depend on low-level modules**. Both should depend on **abstractions**. |

✅ These principles are key to **writing clean and scalable Java applications**.

### **2\. What is the Singleton pattern?**

The **Singleton pattern** ensures a class has **only one instance** and provides a global access point.

**Implementation (Thread-safe, lazy initialization):**

```java
class Singleton {
    private static volatile Singleton instance;

    private Singleton() {} // private constructor

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
```

✅ Use cases:

* Logger
    
* Configuration manager
    
* Thread pool manager
    

### **3\. How to implement an immutable class?**

**Steps to make a class immutable:**

1. Declare class as `final`.
    
2. Make all fields `private` and `final`.
    
3. No setters.
    
4. Return **deep copies** of mutable objects.
    

**Example:**

```java
final class Employee {
    private final String name;
    private final int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
}
```

✅ Immutable objects are **thread-safe** and prevent unintended state changes.

### **4\. What is the Factory pattern?**

The **Factory pattern** provides a **way to create objects without exposing instantiation logic**.

**Example:**

```java
interface Shape { void draw(); }

class Circle implements Shape {
    public void draw() { System.out.println("Circle"); }
}

class Square implements Shape {
    public void draw() { System.out.println("Square"); }
}

class ShapeFactory {
    public static Shape getShape(String type) {
        if (type.equalsIgnoreCase("circle")) return new Circle();
        if (type.equalsIgnoreCase("square")) return new Square();
        throw new IllegalArgumentException("Unknown shape");
    }
}

// Usage
Shape s = ShapeFactory.getShape("circle");
s.draw();
```

✅ Use when object creation **logic is complex** or depends on conditions.

### **5\. What is Dependency Injection (DI)?**

**Dependency Injection** is a **design pattern** where an object receives its dependencies from **external sources** rather than creating them internally.

**Types of DI:**

* **Constructor injection** – dependencies passed via constructor
    
* **Setter injection** – dependencies set via setters
    
* **Interface injection** – using an interface to inject dependencies (less common)
    

**Example (Constructor DI):**

```java
class Service {
    private final Repository repo;
    public Service(Repository repo) { this.repo = repo; }
}
Repository repo = new Repository();
Service service = new Service(repo);
```

✅ Benefits:

* Promotes **loose coupling**
    
* Easier **unit testing**
    
* Improves **maintainability**
    

## JVM Internals and Performance

### **1\. What happens when you run a Java program?**

**Steps in Java program execution:**

1. **Compilation:** `.java` source code is compiled into `.class` bytecode using `javac`.
    
2. **Class loading:** JVM loads the `.class` files into memory using ClassLoaders.
    
3. **Bytecode verification:** Ensures code is valid and doesn’t violate JVM constraints.
    
4. **Execution:** Just-In-Time (JIT) compiler converts bytecode into native machine code for performance.
    
5. **Memory allocation:** Objects are created in the heap; references stored in stack.
    
6. **Garbage Collection:** Unreferenced objects are cleaned automatically.
    

✅ Key point: JVM allows **platform independence** by abstracting underlying OS and hardware.

### **2\. Explain class loading process**

Class loading is handled by the JVM in **three phases**:

1. **Loading:** Loads `.class` file into memory using ClassLoader.
    
2. **Linking:**
    
    * **Verification:** Ensures bytecode integrity
        
    * **Preparation:** Allocates memory for static variables
        
    * **Resolution:** Resolves symbolic references
        
3. **Initialization:** Executes static blocks and initializes static fields.
    

### **3\. What is the role of ClassLoader?**

**ClassLoader** loads Java classes into JVM **at runtime**.

**Types of ClassLoaders:**

1. **Bootstrap ClassLoader:** Loads core Java classes (rt.jar)
    
2. **Extension ClassLoader:** Loads JDK extension libraries (`lib/ext`)
    
3. **Application ClassLoader:** Loads classes from classpath (your code)
    
4. **Custom ClassLoader:** Can be created for dynamic class loading
    

✅ ClassLoader ensures **lazy loading** — classes are loaded only when needed.

### **4\. How does Java achieve platform independence?**

* Java code is compiled into **bytecode** (`.class` file), not native machine code.
    
* JVM **interprets bytecode** or uses JIT to convert to **native code**.
    
* Same bytecode can run on any platform with a compatible JVM.
    

**Key principle:** Write Once, Run Anywhere (WORA).

### **5\. How to improve Java performance?**

* **Memory management:**
    
    * Use proper **data structures** (ArrayList vs LinkedList)
        
    * Minimize object creation, reuse objects
        
* **Multithreading:** Use **ExecutorService**, parallel streams wisely
    
* **Collections:** Use **Concurrent collections** for thread safety
    
* **Garbage Collection tuning:** Adjust **heap size** and **GC algorithm**
    
* **String handling:** Use **StringBuilder** instead of String concatenation in loops
    
* **Profiling:** Use tools like **VisualVM, JConsole** to detect bottlenecks
    

### **6\. Garbage Collection overview**

* **Automatic memory management** by JVM
    
* Removes **unreachable objects** from heap
    
* Common collectors: Serial, Parallel, CMS, G1
    
* GC events: Minor GC (young generation), Major GC (old generation)
    
* **Finalize()** is called before GC (deprecated in Java 9+)
    

✅ Modern JVM uses **generational GC** for efficiency.

### **7\. Heap vs Stack**

| **Memory Area** | **Purpose** | **Example** |
| --- | --- | --- |
| **Heap** | Stores objects and arrays | `new Employee()` |
| **Stack** | Stores method call frames, local variables | `int x = 10;` |

* Stack memory is **LIFO**, automatically cleaned.
    
* Heap memory is **shared**, cleaned by GC.
    

### **8\. PermGen vs Metaspace**

* **PermGen (Java 7 and below):** Stores class metadata; fixed size → risk of `OutOfMemoryError`.
    
* **Metaspace (Java 8+):** Dynamically resizable; stored in native memory → reduces class loading errors.
    

## Miscellaneous Java Concepts

### **1\. Serialization vs Deserialization**

* **Serialization:** Converts a Java object into a byte stream to save to disk or send over a network.
    
* **Deserialization:** Converts the byte stream back into a Java object.
    

**Example:**

```java
// Serialization
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.obj"));
oos.writeObject(employee);

// Deserialization
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.obj"));
Employee e = (Employee) ois.readObject();
```

**Notes:**

* Use `transient` keyword for fields that shouldn’t be serialized.
    
* Serializable classes must implement `Serializable`.
    

### **2\. What is a marker interface?**

* An interface **without methods** used to mark a class with special behavior.
    
* Examples: `Serializable`, `Cloneable`, `Remote`.
    

**Purpose:** Provides **metadata** to JVM or frameworks.

### **3\. What is instanceof keyword?**

* Checks if an object is an instance of a specific class or implements an interface.
    

**Example:**

```java
String s = "Java";
if (s instanceof String) {
    System.out.println("s is a String");
}
```

✅ Always returns `true` for null checks: `null instanceof String` → `false`.

### **4\. What is reflection API?**

* **Reflection** allows inspecting and manipulating classes, methods, and fields **at runtime**.
    
* Can be used to:
    
    * Get class info (`Class<?> clazz = obj.getClass();`)
        
    * Access private fields/methods
        
    * Dynamically create instances
        

**Example:**

```java
Class<?> clazz = Class.forName("java.util.ArrayList");
Object obj = clazz.getDeclaredConstructor().newInstance();
```

✅ Useful for frameworks like Spring, Hibernate, and testing tools.

### **5\. What is autoboxing and unboxing?**

* **Autoboxing:** Automatic conversion from primitive to wrapper class
    
    ```java
    int x = 10;
    Integer y = x; // autoboxing
    ```
    
* **Unboxing:** Wrapper class → primitive
    
    ```java
    Integer a = 20;
    int b = a; // unboxing
    ```
    

### **6\. What is enum in Java?**

* `enum` is a **special class representing a fixed set of constants**.
    
* Can have **fields, methods, and constructors**.
    

**Example:**

```java
enum Day { MONDAY, TUESDAY, WEDNESDAY }
Day today = Day.MONDAY;
```

✅ Useful for **type safety** instead of string constants.

### **7\. Can we override private methods?**

* **No**, private methods are not visible to subclasses.
    
* They are **class-specific** and **cannot be overridden**, but they can be **redeclared** in a subclass.
    

### **8\. Can we overload main method?**

* **Yes**, you can overload `main`:
    

```java
public static void main(String[] args) { }
public static void main(int[] args) { }
```

* JVM always calls the **String\[\] main method**.
    

### **9\. Can constructor be private?**

* **Yes**, used in **Singleton pattern** or factory methods.
    
* Prevents direct instantiation from outside the class.
    

### **10\. What are annotations in Java?**

* Metadata for **classes, methods, fields**.
    
* Examples: `@Override`, `@Deprecated`, `@FunctionalInterface`
    
* Custom annotation example:
    

```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Test { 
}
```

### **11\. What is JavaBeans?**

* **JavaBean:** A reusable class following:
    
    * Private fields
        
    * Public getters and setters
        
    * No-arg constructor
        
    * Serializable
        

✅ Used for **encapsulation** and frameworks like JSP, JSF, and Spring.

### **12\. What is var keyword in Java?**

* Introduced in **Java 10** for **local variable type inference**.
    

```java
var name = "Ashutosh"; // inferred as String
```

* Cannot be used for method parameters, fields, or return type.
    

### **13\. What are records in Java?**

* Introduced in **Java 14** as **immutable data carriers**.
    
* Automatically generate **constructor, getters, equals, hashCode, toString**.
    

```java
record Employee(String name, int age) { }
Employee e = new Employee("John", 25);
```

✅ Great for **DTOs and value objects**.

> Learn more about records [here](https://blog.ashutoshkrris.in/dto-vs-record-in-java-which-should-you-use).

### **14\. Difference between compile-time and runtime errors**

| Type | When occurs | Example |
| --- | --- | --- |
| **Compile-time error** | During compilation | Syntax error, missing semicolon |
| **Runtime error** | During program execution | NullPointerException, ArrayIndexOutOfBounds |

## Real-World Scenario-Based Questions

### **1\. How would you optimize a large collection for search?**

**Scenario:** You have a large dataset and need frequent lookups.

**Approach:**

1. **Choose the right data structure:**
    
    * `HashMap` for O(1) key-value lookup.
        
    * `TreeMap` if sorted order is required (O(log n) lookup).
        
    * `HashSet` for unique element search.
        
2. **Indexing:** Precompute indices for frequent queries.
    
3. **Use streams with parallel processing** if data is very large.
    
4. **Avoid unnecessary object creation:** Use primitives or immutable objects.
    
5. **Memory considerations:** If memory is tight, consider using compressed data structures or disk-based solutions.
    

**Example:**

```java
Map<String, Employee> employeeMap = new HashMap<>();
for(Employee e: employees) {
    employeeMap.put(e.getId(), e);
}
// Lookup by ID is now O(1)
```

### **2\. How to handle concurrency in a shared resource?**

**Scenario:** Multiple threads need to access/update shared data.

**Approach:**

1. **Synchronized blocks/methods:**
    
    ```java
    synchronized(this) {
        // critical section
    }
    ```
    
2. **Concurrent Collections:** Use `ConcurrentHashMap`, `CopyOnWriteArrayList`.
    
3. **Locks:** Use `ReentrantLock` for fine-grained control.
    
4. **Atomic Variables:** Use `AtomicInteger`, `AtomicReference` for atomic operations.
    
5. **Avoid deadlocks:** Always acquire locks in consistent order.
    

✅ Modern Java encourages **lock-free structures** and **immutability** where possible.

### **3\. What’s your approach for debugging memory leaks?**

**Steps:**

1. **Identify symptoms:** High heap usage, `OutOfMemoryError`, slow performance.
    
2. **Analyze heap dumps:** Use tools like **VisualVM, Eclipse MAT, JProfiler**.
    
3. **Check references:** Look for **unreleased objects**, static collections, caches.
    
4. **Fix common causes:**
    
    * Remove unused listeners or callbacks
        
    * Use `WeakReference` where needed
        
    * Clear collections properly
        
5. **Test thoroughly:** Run under load to confirm memory usage stabilizes.
    

### **4\. How to ensure thread safety without performance issues?**

**Scenario:** High-concurrency application.

**Approach:**

1. Prefer **immutable objects** to avoid synchronization overhead.
    
2. Use **concurrent collections** (`ConcurrentHashMap`, `ConcurrentLinkedQueue`) instead of synchronized versions.
    
3. Minimize **synchronized blocks** to only critical sections.
    
4. Use **atomic variables** for counters or flags.
    
5. Consider **ReadWriteLock** if reads dominate writes.
    

✅ Key: Balance **thread safety vs performance**.

### **5\. Explain a situation where you used Java 8 features to simplify code**

**Example Answer:**

> “In a recent project, we had a list of employees and needed to filter those in a specific department, sort by salary, and collect names. Using Java 8 Streams and lambdas, I could do it in one readable statement instead of nested loops:
> 
> ```java
> List<String> names = employees.stream()
>     .filter(e -> e.getDepartment().equals("Engineering"))
>     .sorted(Comparator.comparing(Employee::getSalary).reversed())
>     .map(Employee::getName)
>     .collect(Collectors.toList());
> ```
> 
> This approach reduced boilerplate code, improved readability, and was easy to maintain.”

## Wrapping Up

This guide covers **all essential Core Java concepts, coding patterns, and real-world scenarios** needed to excel in Java interviews in 2025. Use it to **strengthen fundamentals, improve problem-solving, and confidently tackle interviews**.
