Xperi · Day 2 · OOP & Collections
Volume I

Java OOP
&
Collections
Mastery

A deep-dive through twelve chapters of Q&A — every question Glassdoor has whispered of, every pattern Xperi has asked, every nuance the JVM hides beneath the surface.

Begin Reading
Easy
Medium
Hard
Xperi Asked
— Index —

The Table of Contents

Day 2 · 12 Chapters
I Chapter I · 12 Questions

Four Pillars of OOP — A Deep Examination

Encapsulation · Inheritance · Polymorphism · Abstraction. The four cornerstones examined through real-world analogies that interviewers love.

Xperi · Day 2

OOP ke 4 pillars kya hain? Ek-ek ko real-world example ke saath explain karo.

1. Encapsulation — Data (fields) aur behavior (methods) ko ek class mein bundle karna, aur access ko control karna private/public ke zariye.

🏦 Real World: Bank Account — balance field private hai. Sirf deposit() / withdraw() se access hoga. Koi bahar se seedha balance change nahi kar sakta.
Java
public class BankAccount {
    private double balance;   // encapsulated

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
    public double getBalance() { return balance; }
}

2. Inheritance — Ek class doosri class ke properties aur methods inherit karti hai. Code reuse hota hai.

Java
class Animal {
    void breathe() { System.out.println("Breathing"); }
}
class Dog extends Animal {
    void bark() { System.out.println("Woof!"); }
}
// Dog can breathe() AND bark()

3. Polymorphism — Same method, different behavior. Compile-time (overloading) aur Runtime (overriding) dono hote hain.

Java
class Shape {
    void draw() { System.out.println("Drawing Shape"); }
}
class Circle extends Shape {
    @Override
    void draw() { System.out.println("Drawing Circle"); }
}
Shape s = new Circle();  // Runtime polymorphism
s.draw();  // "Drawing Circle" — not "Drawing Shape"

4. Abstraction — Implementation details chhupana, sirf essential features dikhana. abstract class ya interface se achieve hota hai.

Java
abstract class Vehicle {
    abstract void start();   // "kaise start hoga" chhupa hai
    void stop() { System.out.println("Stopping"); }
}
class Car extends Vehicle {
    void start() { System.out.println("Car starts with key"); }
}

Encapsulation aur Abstraction mein kya difference hai? Dono ko confuse kyun karte hain log?

AspectEncapsulationAbstraction
DefinitionData hiding + bundlingImplementation hiding
FocusHow data is stored/protectedWhat an object does
Achieved byprivate fields + getters/settersabstract class / interface
LevelClass levelDesign level
💡 Easy trick: Encapsulation = Data ka locker. Abstraction = Remote control — button press karo, andar ka circuit mat dekho.

Runtime Polymorphism kaise kaam karta hai internally? JVM kya karta hai?

Runtime polymorphism Dynamic Method Dispatch ke through kaam karta hai. JVM compile time pe reference type dekhta hai, but runtime pe actual object type ke basis pe method call karta hai.

Internally, JVM vtable (virtual table) use karta hai — ek table of method pointers. Jab koi method call hoti hai, JVM vtable se actual implementation ka pointer uthata hai.

Java
Animal a = new Dog();  // compile time: type = Animal
a.sound();             // runtime: JVM checks Dog's vtable → Dog.sound()
Static methods dispatch at compile time — no runtime polymorphism for static!

IS-A vs HAS-A relationship kya hai? Code example ke saath.

IS-A = Inheritance. Dog IS-A Animal.

HAS-A = Composition. Car HAS-A Engine.

Java
// IS-A
class Dog extends Animal { }  // Dog IS-A Animal

// HAS-A
class Car {
    private Engine engine;  // Car HAS-A Engine (Composition)
}
✅ Prefer HAS-A over IS-A when possible — "Composition over Inheritance" — reduces tight coupling

Multiple Inheritance Java mein kyun allowed nahi hai? Diamond Problem explain karo.

Java mein class ke through multiple inheritance allowed nahi hai kyunki Diamond Problem aata hai:

Java
// Assume ye allowed hota — INVALID Java code
class A { void greet() { print("A"); } }
class B extends A { void greet() { print("B"); } }
class C extends A { void greet() { print("C"); } }
class D extends B, C { }  // D.greet() → B ka lega ya C ka?
💡 Java solution: Interface ke through multiple inheritance allowed hai. Java 8 ke baad default methods aaye, par conflict hone pe class override karna mandatory hai.
Java
interface B { default void greet() { print("B"); } }
interface C { default void greet() { print("C"); } }
class D implements B, C {
    public void greet() { B.super.greet(); }  // must override
}

Covariant return type kya hota hai?

Java 5 ke baad, overriding method parent ke return type ka subtype return kar sakti hai. This is called covariant return type.

Java
class Animal {
    Animal create() { return new Animal(); }
}
class Dog extends Animal {
    @Override
    Dog create() { return new Dog(); }  // Dog is subtype of Animal ✓
}

Object class ke important methods kaunse hain?

Java mein every class implicitly java.lang.Object extend karti hai. Key methods:

MethodPurposeOverride?
equals(Object o)Logical equality checkYES (always with hashCode)
hashCode()Hash value for collectionsYES (with equals)
toString()String representationYES
clone()Object copyYES (implement Cloneable)
finalize()GC se pehle callDeprecated Java 9+
getClass()Runtime class infoNO (final)
wait()/notify()Thread synchronizationNO
Contract: Agar equals() override karo toh hashCode() bhi zaroor override karo — warna HashMap/HashSet mein bugs aate hain!

Deep copy vs Shallow copy kya hai? Java mein kaise implement karte hain?

Shallow Copy — Reference copy. New object banta hai lekin andar ke references same object point karte hain.

Deep Copy — Complete copy. Andar ke objects bhi naye bante hain.

Java
class Address {
    String city;
    Address(String c) { city = c; }
}

class Person implements Cloneable {
    String name;
    Address address;

    // SHALLOW COPY (default clone)
    protected Object shallowClone() throws CloneNotSupportedException {
        return super.clone();  // address reference copied, not new object
    }

    // DEEP COPY
    protected Object deepClone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = new Address(this.address.city);  // new Address object
        return cloned;
    }
}
Memory Trick: Shallow = Xerox of photo (same image). Deep = Rephotograph everything (new everything).

Marker Interface kya hota hai? Examples do.

Marker Interface = Koi method nahi, sirf "tagging" ke liye use hota hai. JVM ya framework isko check karke behavior decide karta hai.

Java
interface Serializable { }  // No methods — just a tag!
interface Cloneable { }
interface Remote { }       // java.rmi
💡 Java 5 ke baad Annotations ne marker interfaces ko mostly replace kar diya (e.g., @Override, @Deprecated). But Serializable abhi bhi widely used hai.

SOLID Principles kya hain? Ek-ek example ke saath.

LetterPrincipleSimple Meaning
SSingle ResponsibilityClass ka sirf ek kaam — Invoice class sirf invoice handle kare, print mat kare
OOpen/ClosedExtension ke liye open, modification ke liye closed — new shape add karo, existing code mat badlo
LLiskov SubstitutionSubclass parent ki jagah safely use ho sake — Rectangle ko Square se extend mat karo
IInterface SegregationEk bada interface mat banao — Robot ko eat() implement karne pe majboor mat karo
DDependency InversionHigh-level module low-level pe depend na kare — abstractions pe depend karo

Aggregation vs Composition ka difference?

AspectAggregationComposition
RelationshipHAS-A (weak)HAS-A (strong)
LifecycleChild can exist without parentChild dies with parent
ExampleDepartment HAS-A Professor (professor exists after dept closed)House HAS-A Room (room destroyed if house demolished)
In codeReference passed from outsideObject created inside class

Java mein Object Creation ke kitne ways hain?

  1. new keywordDog d = new Dog();
  2. ReflectionClass.forName("Dog").newInstance()
  3. clone()Dog d2 = (Dog) d.clone();
  4. Deserialization — ObjectInputStream se object read karna
  5. Factory methodsInteger.valueOf(5) (reuses cached objects)
II Chapter II · 8 Questions

Abstract Class & Interface

The perennial favourite. We settle, once and for all, which to use when, and what the JVM permits in each case.

Xperi · Day 2

Abstract Class aur Interface mein kya difference hai? Kab kaunsa use karein?

FeatureAbstract ClassInterface
InstantiationNoNo
MethodsAbstract + Concrete bothAbstract + default + static (Java 8+)
VariablesAny typepublic static final only
ConstructorYesNo
InheritanceSingle (extends)Multiple (implements)
Access modifiersAnypublic only (by default)
When to useShared code + template patternContract / capability definition
Rule of Thumb: Abstract class = "is a" relationship + shared state. Interface = "can do" contract. Template Method Pattern → Abstract Class. Strategy Pattern → Interface.

Java 8 mein Interface mein kya changes aaye? default aur static methods kya hote hain?

Java 8 mein Interface ko sirf abstract methods ki jagah default aur static methods bhi allow kiye gaye.

Java
interface Greeter {
    void greet(String name);  // abstract — implement karna mandatory

    default void greetAll(String... names) {  // default — override optional
        for (String n : names) greet(n);
    }

    static Greeter formal() {  // static — interface se call karo
        return name -> System.out.println("Good day, " + name);
    }
}
default method conflict: Agar do interfaces same default method dein, class ko override karna MANDATORY hai — warna compile error.

Java 9 mein private methods bhi interfaces mein aaye — default methods ke liye helper code likhne ke liye.

Functional Interface kya hota hai? Lambda se kya connection hai?

Exactly one abstract method wala interface Functional Interface hota hai. @FunctionalInterface annotation optional lekin recommended hai.

Java
@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);  // only ONE abstract method
}

// Lambda = anonymous implementation of Functional Interface
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;

System.out.println(add.calculate(3, 4));  // 7
Built-in Functional Interfaces: Runnable, Callable, Comparator, Predicate<T>, Function<T,R>, Consumer<T>, Supplier<T>

Kya interface ke andar constructor ho sakta hai? Kya interface mein state maintain ho sakti hai?

No constructor in interface — interfaces instantiate nahi hote, isliye constructor meaningless hai.

No mutable state — Interface ke fields automatically public static final hote hain (constants). Class-level state maintain nahi ho sakti.

Java
interface Config {
    int MAX_SIZE = 100;  // automatically: public static final int MAX_SIZE = 100;
    // int count = 0;  ← This is ALSO final, can't be changed!
}

Template Method Pattern aur Strategy Pattern mein difference — abstract class vs interface ka practical example.

Template Method (Abstract Class) — Algorithm ka skeleton define karo, steps subclass mein customize karo:

Java
abstract class DataMiner {
    final void mine() {   // template method — final so can't be overridden
        String data = extractData();
        String parsed = parseData(data);
        analyzeData(parsed);
    }
    abstract String extractData();   // subclass implements
    abstract String parseData(String d);
    void analyzeData(String d) { System.out.println("Analyzing: " + d); }
}

Strategy (Interface) — Algorithm को runtime pe swap karo:

Java
interface SortStrategy { void sort(int[] arr); }
class Sorter {
    private SortStrategy strategy;
    void setStrategy(SortStrategy s) { strategy = s; }
    void sort(int[] arr) { strategy.sort(arr); }
}
// Runtime mein strategy change kar sakte hain!

Abstract class ka constructor kya purpose serve karta hai jab class instantiate nahi ho sakti?

Abstract class ka constructor subclass object creation ke time call hota hai via super(). Yeh common initialization code share karne ke liye use hota hai.

Java
abstract class Animal {
    protected String name;
    protected int age;

    Animal(String name, int age) {  // constructor in abstract class
        this.name = name;
        this.age = age;
        System.out.println("Animal created: " + name);
    }
}
class Dog extends Animal {
    Dog(String name, int age) {
        super(name, age);  // Abstract class constructor called here
    }
}
// new Dog("Rex", 3) → prints "Animal created: Rex"
III Chapter III · 8 Questions

Static, Instance & Constructor Chaining

Memory, class-loading, the static block, and the precise order in which a Java object is born. The hidden machinery.

Xperi · Day 2

Static aur Instance members mein kya difference hai? Memory mein kahan store hote hain?

FeatureStaticInstance
MemoryMethod Area (Class Area)Heap (per object)
When loadedClass loading timeObject creation time
Per object?No — shared by allYes — each object has own copy
AccessClassName.memberobjectRef.member
Can access instance?No — no 'this'Yes
Java
class Counter {
    static int totalCount = 0;  // shared — Method Area
    int id;                       // per object — Heap

    Counter() {
        totalCount++;
        id = totalCount;
    }
}
Counter c1 = new Counter(); // totalCount=1, c1.id=1
Counter c2 = new Counter(); // totalCount=2, c2.id=2

Static block kab execute hota hai? Agar multiple static blocks hain toh order kya hoga?

Static block class loading ke time execute hota hai — object creation se pehle, top to bottom order mein.

Java
class Demo {
    static int x;

    static {
        x = 10;
        System.out.println("Static Block 1: x = " + x);
    }

    static {
        x = 20;
        System.out.println("Static Block 2: x = " + x);
    }

    Demo() { System.out.println("Constructor"); }
}

/* Output when: new Demo(); new Demo();
   Static Block 1: x = 10   ← only once!
   Static Block 2: x = 20   ← only once!
   Constructor
   Constructor                ← twice
*/
✅ Static blocks are used for: Database connection pool init, loading native libraries (System.loadLibrary), complex static field initialization

Constructor Chaining kya hota hai? this() aur super() ka kya role hai?

Ek constructor se doosra constructor call karna = Constructor Chaining.

  • this() — Same class ke doosre constructor ko call karna
  • super() — Parent class ke constructor ko call karna
Java
class Employee {
    String name;
    String dept;
    double salary;

    Employee(String name) {
        this(name, "General");  // calls 2-arg constructor
    }

    Employee(String name, String dept) {
        this(name, dept, 30000.0);  // calls 3-arg constructor
    }

    Employee(String name, String dept, double salary) {
        this.name = name;          // actual initialization
        this.dept = dept;
        this.salary = salary;
        System.out.println("Employee created: " + name);
    }
}

class Manager extends Employee {
    int teamSize;

    Manager(String name, int teamSize) {
        super(name, "Management", 60000.0);  // parent constructor
        this.teamSize = teamSize;
    }
}
Rules: this() ya super() constructor ka FIRST statement hona chahiye. Dono ek saath nahi ho sakte.

Kya static method ko override kar sakte hain? Kya hota hai agar karo?

Static methods override nahi hoti — woh method hiding (shadowing) karti hain. Dispatch compile-time pe hota hai, runtime pe nahi.

Java
class Parent {
    static void greet() { System.out.println("Parent static"); }
    void hello() { System.out.println("Parent instance"); }
}
class Child extends Parent {
    static void greet() { System.out.println("Child static"); }  // HIDING
    @Override
    void hello() { System.out.println("Child instance"); }  // OVERRIDING
}

Parent p = new Child();
p.greet();   // "Parent static" ← compile-time type = Parent!
p.hello();   // "Child instance" ← runtime type = Child!

Singleton Pattern kya hai? Thread-safe Singleton kaise banate hain?

Singleton = Class ka sirf ek instance ho puri application mein.

Java
// Best approach: Bill Pugh Singleton (Initialization-on-demand holder)
public class Singleton {
    private Singleton() { }  // private constructor

    private static class Holder {
        static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;  // lazy, thread-safe, no sync overhead
    }
}

// Double-Checked Locking (less preferred)
public class Singleton2 {
    private volatile static Singleton2 instance;  // volatile important!
    public static Singleton2 getInstance() {
        if (instance == null) {
            synchronized (Singleton2.class) {
                if (instance == null) instance = new Singleton2();
            }
        }
        return instance;
    }
}
Singleton ko Reflection aur Serialization se tod sakte hain. Safest approach: Enum Singleton
Java
enum EnumSingleton { INSTANCE; }  // Thread-safe, Serialization-safe
IV Chapter IV · 8 Questions

Overloading & Overriding

Compile-time versus runtime polymorphism — the rules, the edge cases, and the traps that catch the unwary.

Xperi · Day 2

Overloading aur Overriding mein exact differences kya hain?

FeatureOverloadingOverriding
TypeCompile-time polymorphismRuntime polymorphism
ClassSame class (or inheritance)Parent-Child only
Method signatureMust differ (params)Must be SAME
Return typeCan be differentSame or covariant
Access modifierNo restrictionCan't reduce visibility
ExceptionAny exceptionOnly same/narrower checked exceptions
static/final?Can overloadCan't override

Kya return type se method overload ho sakta hai?

No! Sirf return type change karne se overloading nahi hoti — compile error aata hai. Compiler method signature (name + parameter types) se methods differentiate karta hai, return type se nahi.

Java
class Test {
    int getValue() { return 1; }
    // double getValue() { return 1.0; } ← COMPILE ERROR — ambiguous

    // Ye overloading hai (parameters different):
    int add(int a, int b) { return a + b; }
    double add(double a, double b) { return a + b; }  // ✓ valid
}

@Override annotation kyun use karein? Yeh optional hai toh kya zarurat?

@Override compiler ko instruction deta hai ki "yeh method parent mein exist karna chahiye". Benefits:

  • Typo protection — agar parent mein method exist nahi karta, compile error milega
  • Code readability — clearly indicates intent
  • Refactoring safety — parent method rename pe alert milega
Java
class Dog extends Animal {
    @Override
    void soound() { ... }  // COMPILE ERROR — typo! Parent has sound() not soound()
    // Without @Override: silently becomes a NEW method, not override!
}

Overriding ke time exception ke rules kya hain?

Exception TypeOverride Rule
Checked ExceptionOverride method same ya narrower checked exception throw kar sakta hai. Broader ya new checked exception nahi.
Unchecked ExceptionKoi restriction nahi — koi bhi RuntimeException throw kar sakte hain
No exception in parentChild checked exception throw nahi kar sakta; unchecked kar sakta hai
Java
class Parent {
    void read() throws IOException { }
}
class Child extends Parent {
    void read() throws FileNotFoundException { }  // ✓ narrower
    // void read() throws Exception { }  ← ✗ broader — COMPILE ERROR
    // void read() throws RuntimeException { }  ← ✓ unchecked OK
}
V Chapter V · 5 Questions

Call by Value & Call by Reference

Java, as it turns out, is always pass-by-value. But with object references, the truth is more subtle than the platitude.

Xperi · Day 2

Java mein Call by Value hai ya Call by Reference? Explain with code.

Java is always Call by Value — always! Lekin object ke case mein, reference की value copy hoti hai.

Java
// Primitives — pure call by value
void change(int x) { x = 100; }
int a = 5;
change(a);
System.out.println(a); // 5 — unchanged! New copy of 5 passed

// Objects — reference value copied (NOT the object)
void modify(StringBuilder sb) {
    sb.append(" World");  // ✓ modifies original — same object
    sb = new StringBuilder("Hello");  // ✗ local reassignment only
}
StringBuilder s = new StringBuilder("Hello");
modify(s);
System.out.println(s); // "Hello World" — append worked, reassign didn't
Key Insight: Java copies the VALUE of the reference (memory address), not the object itself. So object ke andar changes reflect hote hain, but reference reassignment nahi hoti.

String immutable kyun hai? String pool kya hota hai?

String immutable hai kyunki:

  1. Security — Passwords, file paths string mein store hote hain — immutability ensures they can't be tampered
  2. String Pool / Caching — Same string multiple references share kar sakte hain — memory efficient
  3. Thread Safety — Immutable objects inherently thread-safe hain
  4. HashCode caching — HashMap key ke roop mein safe use
Java
String s1 = "Hello";  // String Pool mein jaata hai
String s2 = "Hello";  // Same pool reference
String s3 = new String("Hello");  // Heap mein new object

System.out.println(s1 == s2);      // true (same pool reference)
System.out.println(s1 == s3);      // false (different object)
System.out.println(s1.equals(s3)); // true (same content)

s1 = s1 + " World";  // s1 doesn't change! New String object created

String vs StringBuilder vs StringBuffer — kab kaunsa use karein?

FeatureStringStringBuilderStringBuffer
MutabilityImmutableMutableMutable
Thread SafeYesNoYes (synchronized)
PerformanceSlow (new objects)FastModerate
Use whenFew/no modificationsSingle thread, many changesMulti-thread, many changes
✅ 99% cases mein StringBuilder use karo. StringBuffer use tab karo jab multiple threads same buffer modify karein.
VI Chapter VI · 6 Questions

final, finally & finalize

Three words that share letters and little else. Frequently confused; rarely forgiven.

Xperi · Day 2

final, finally, aur finalize mein kya difference hai?

KeywordUsed forPurpose
finalVariable, Method, ClassPrevent modification/override/inheritance
finallytry-catch blockAlways executes — cleanup code
finalize()Method (deprecated)GC se pehle cleanup — avoid karein
Java
// final
final int MAX = 100;          // constant — can't reassign
final class String { }       // can't extend
final void doSomething() {}  // can't override

// finally
try {
    // risky code
} catch (Exception e) {
    // handle
} finally {
    // ALWAYS runs — even if return/exception in try or catch
    connection.close();  // cleanup here
}

// finalize (DEPRECATED — don't use!)
protected void finalize() throws Throwable {
    // called by GC before collecting — unpredictable, slow
}

Kya finally block kabhi execute nahi hota? Edge cases batao.

Finally almost always executes, lekin in cases mein nahi:

  1. System.exit() call — JVM terminate ho jaata hai
  2. Runtime.halt() — abrupt JVM shutdown
  3. JVM crash / OutOfMemoryError in some cases
  4. Thread ko kill kar diya jaye (abruptly)
  5. Infinite loop in try block
Java
try {
    System.exit(0);  // JVM terminates here
} finally {
    System.out.println("This NEVER prints");  // skipped!
}
Tricky: If both try AND finally return — finally ka return wins!
Java
int test() {
    try { return 1; }
    finally { return 2; }  // returns 2! finally overrides try's return
}

try-with-resources kya hota hai? finally se better kyun hai?

Java 7+ mein try-with-resources AutoCloseable implement karne wali resources ko automatically close karta hai.

Java
// Old way — verbose and error-prone
BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("file.txt"));
} finally {
    if (br != null) br.close();  // Can itself throw exception!
}

// New way — clean, automatic
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
}  // br.close() called automatically — even if exception thrown

final variable ka blank initialization kya hota hai?

Blank final variable = Declare karo lekin turant initialize mat karo. Constructor mein initialize karna mandatory hai.

Java
class Circle {
    final double radius;  // blank final — no value yet

    Circle(double r) {
        radius = r;  // must initialize in constructor
    }
    // Cannot have: Circle() { } ← compiler error — radius not initialized
}
VII Chapter VII · 8 Questions

ArrayList & LinkedList — The Internals

When to choose which, and why. With the Big-O comparison that should be tattooed upon the mind of every Java engineer.

Xperi · Day 2

ArrayList internally kaise kaam karta hai? Dynamic resizing kaise hoti hai?

ArrayList internally ek Object array maintain karta hai.

  • Default initial capacity: 10
  • Jab array full hota hai, new array 1.5× size ka create hota hai
  • Old array ke elements copy hote hain — Arrays.copyOf() internally called
Java
// ArrayList internal structure (simplified)
class ArrayList<E> {
    private Object[] elementData;  // internal array
    private int size;

    void add(E e) {
        if (size == elementData.length) {
            // grow by 1.5x: newCapacity = oldCapacity + (oldCapacity >> 1)
            elementData = Arrays.copyOf(elementData, (size * 3) / 2 + 1);
        }
        elementData[size++] = e;
    }

    E get(int index) {
        return (E) elementData[index];  // O(1) — direct array access
    }
}
✅ Performance tip: Agar size pata hai, ArrayList initial capacity specify karo: new ArrayList<>(1000) — resizing avoid hogi

LinkedList internally kaise kaam karta hai? Doubly vs Singly?

Java's LinkedList is a Doubly Linked List. Har node mein:

  • item — actual data
  • prev — previous node reference
  • next — next node reference
Java
// LinkedList Node (internal)
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

// LinkedList maintains head and tail pointers
Node<E> first;  // head
Node<E> last;   // tail
💡 LinkedList implements both List AND Deque interfaces. So it can be used as Queue, Stack, or Deque efficiently!

ArrayList vs LinkedList Time Complexity full comparison?

OperationArrayListLinkedListWhy?
get(index)O(1)O(n)Array direct access vs traverse
add(end)O(1) amortizedO(1)Both fast at end
add(beginning)O(n)O(1)ArrayList shifts all elements
add(middle)O(n)O(n)ArrayList shifts; LL traverses
remove(end)O(1)O(1)Both fast
remove(middle)O(n)O(n)Both need traversal
search (contains)O(n)O(n)Both linear scan
MemoryLess (no pointers)More (prev+next pointers)Each LL node = 3 objects
Cache performanceBetterWorseArray is contiguous in memory
In practice, ArrayList is usually faster even for insertions due to CPU cache locality. LinkedList is only better for frequent add/remove at head/tail.

ArrayList mein Iterator vs for-each vs get(i) loop — kaunsa use karein? ConcurrentModificationException kab aata hai?

Java
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

// 1. Index-based — OK for ArrayList, BAD for LinkedList
for (int i = 0; i < list.size(); i++) { ... }

// 2. for-each — uses Iterator internally, safe for reading
for (String s : list) { ... }

// 3. Iterator — only safe way to remove during iteration
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("b")) it.remove();  // ✓ SAFE
}

// ConcurrentModificationException — structural mod during for-each
for (String s : list) {
    if (s.equals("b")) list.remove(s);  // ✗ THROWS CME!
}

// Java 8 solution
list.removeIf(s -> s.equals("b"));  // ✓ Safe and clean
VIII Chapter VIII · 10 Questions

HashMap & HashSet — The Internals

Buckets, hashing, collisions, treeification, the sacred contract between equals and hashCode. The chapter that separates senior engineers from the rest.

Xperi · Day 2

HashMap internally kaise kaam karta hai? put() operation step by step explain karo.

HashMap internally Array of LinkedList (Buckets) use karta hai. Java 8+ mein jab collision zyada hoti hai toh LinkedList Red-Black Tree mein convert ho jaati hai.

put(key, value) steps:

  1. key ki hashCode() compute karo
  2. Hash ko spread karo: hash = hash ^ (hash >>> 16)
  3. Bucket index calculate karo: index = hash & (capacity - 1)
  4. Us bucket mein Entry store karo
  5. Collision hone pe: same bucket mein chain (LinkedList/Tree)
Java
// Simplified HashMap internals
class HashMap<K, V> {
    Node<K, V>[] table;  // Array of buckets
    int size;
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    static final int DEFAULT_INITIAL_CAPACITY = 16;

    static class Node<K, V> {
        final int hash;
        final K key;
        V value;
        Node<K, V> next;  // linked list for collision
    }

    void put(K key, V value) {
        int hash = key.hashCode() ^ (key.hashCode() >>> 16);
        int index = hash & (table.length - 1);  // bucket index

        // Check for existing key
        for (Node<K,V> n = table[index]; n != null; n = n.next) {
            if (n.hash == hash && n.key.equals(key)) {
                n.value = value;  // update existing
                return;
            }
        }
        // Add new node to bucket
        table[index] = new Node(hash, key, value, table[index]);
        size++;
        // Check if resize needed
        if (size > table.length * DEFAULT_LOAD_FACTOR) resize();
    }
}

Load Factor kya hota hai? Resizing kaise hoti hai?

Load Factor = threshold ratio. Default: 0.75.

Formula: resize when: size > capacity × loadFactor

Default HashMap: 16 capacity × 0.75 = 12 entries ke baad resize

Resize kaise hota hai:

  1. New array double size (16 → 32 → 64...)
  2. Sab entries rehash hoti hain — new bucket position calculate hoti hai
  3. Old array garbage collected
Load FactorEffectTradeoff
Low (e.g., 0.5)Fewer collisions, more memorySpeed ↑, Memory ↑
High (e.g., 0.9)More collisions, less memorySpeed ↓, Memory ↓
0.75 (default)Good balanceRecommended

Java 8 mein HashMap ka kya change hua? Treeify Threshold kya hai?

Java 8 se pehle: Collision = LinkedList (worst case O(n))

Java 8 ke baad: Jab ek bucket mein 8 se zyada entries aati hain, LinkedList Red-Black Tree mein convert ho jaati hai → O(log n)

Java
static final int TREEIFY_THRESHOLD = 8;   // 8+ entries → convert to tree
static final int UNTREEIFY_THRESHOLD = 6;  // resize ho toh tree → list back
static final int MIN_TREEIFY_CAPACITY = 64; // total capacity ≥ 64 needed
✅ Agar same hashCode wali keys bahut saari hain (hash collision attack), Java 8 ka Tree node unhe efficiently handle karta hai — O(n) to O(log n)

HashMap mutable key use karo toh kya hoga? Kyon keys immutable honi chahiye?

Mutable key ka hashCode change ho sakta hai modification ke baad — toh HashMap key ko dhundh nahi payega!

Java
class MutableKey {
    String data;
    int hashCode() { return data.hashCode(); }
}

Map<MutableKey, String> map = new HashMap<>();
MutableKey key = new MutableKey();
key.data = "hello";
map.put(key, "World");  // stored at bucket for "hello".hashCode()

key.data = "bye";       // key MUTATED! hashCode now different!
map.get(key);           // looks in WRONG bucket → null!
Why String is perfect HashMap key: Immutable + hashCode cached + equals() well-defined

HashSet internally kaise kaam karta hai? HashMap se kya relation hai?

HashSet internally HashMap ka wrapper hai! Har element HashMap key ki tarah store hota hai, value ek dummy constant object hota hai.

Java
class HashSet<E> {
    private final HashMap<E, Object> map = new HashMap<>();
    private static final Object PRESENT = new Object();  // dummy value

    boolean add(E e) {
        return map.put(e, PRESENT) == null;  // key = element, value = dummy
    }

    boolean contains(Object o) {
        return map.containsKey(o);
    }
}
✅ HashSet = HashMap with dummy values. Isliye: No duplicates (HashMap keys unique hote hain), O(1) add/contains/remove, No ordering guarantee

HashMap null keys aur null values handle karta hai? ConcurrentHashMap mein difference?

FeatureHashMapConcurrentHashMapHashtable
Null keys1 allowedNOT allowedNOT allowed
Null valuesMultiple allowedNOT allowedNOT allowed
Thread safeNoYes (segment locks)Yes (full lock)
PerformanceFast (single thread)Good (concurrent)Slow (full sync)
Java
// HashMap null handling
Map<String, Integer> map = new HashMap<>();
map.put(null, 1);      // ✓ null key goes to bucket 0
map.put("a", null);   // ✓ null value allowed

equals() aur hashCode() contract kya hai? Violate karne se kya hoga?

Contract:

  1. If a.equals(b)a.hashCode() == b.hashCode() MUST be true
  2. If a.hashCode() == b.hashCode()a.equals(b) may or may not be true (collision OK)
Java
// VIOLATION: equals without hashCode override
class BadKey {
    int id;
    public boolean equals(Object o) {
        return ((BadKey) o).id == this.id;
    }
    // hashCode NOT overridden → inherits Object.hashCode (memory address)
}

BadKey k1 = new BadKey(); k1.id = 1;
BadKey k2 = new BadKey(); k2.id = 1;
k1.equals(k2);  // true (same id)

Set<BadKey> set = new HashSet<>();
set.add(k1);
set.contains(k2);  // FALSE!! Different hashCode → different bucket!

HashMap ka worst case O(n) kab hota hai? Kaise prevent karein?

Agar sabhi keys ka same hashCode ho (hash collision attack), sab ek hi bucket mein chain banti hain → O(n).

Java
// All go to same bucket — worst case O(n)
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 1000; i++) {
    map.put(i * 16, "val");  // all map to bucket 0 with capacity 16!
}

Java 8 solution: Treeify at 8 — O(n) → O(log n) per bucket. Full O(n) still possible if all buckets have trees.

✅ Better solution: ConcurrentHashMap (thread-safe) or ensure good hashCode() distribution. Objects.hash() use karo for multi-field hashCode.

HashMap mein koi custom object ko key banana ho toh kya implement karna padega?

Custom object as HashMap key banane ke liye:

  1. equals() override karo
  2. hashCode() override karo (consistent with equals)
  3. Object immutable hona chahiye
Java
class Point {
    private final int x, y;  // final = immutable

    Point(int x, int y) { this.x = x; this.y = y; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Point)) return false;
        Point p = (Point) o;
        return x == p.x && y == p.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);  // good hash combining both fields
    }
}

Map<Point, String> map = new HashMap<>();
map.put(new Point(1, 2), "origin");
map.get(new Point(1, 2));  // "origin" ✓ — equals+hashCode both correct

HashMap get() aur getOrDefault() aur computeIfAbsent() — differences?

Java
Map<String, List<Integer>> map = new HashMap<>();

// get — null return karta hai if key missing
map.get("a");  // null

// getOrDefault — default value deta hai
map.getOrDefault("a", new ArrayList<>());  // empty list (not stored)

// computeIfAbsent — stores AND returns default
map.computeIfAbsent("a", k -> new ArrayList<>()).add(1);
// map now has "a" → [1]

// merge — common pattern: word frequency count
Map<String, Integer> freq = new HashMap<>();
freq.merge("apple", 1, Integer::sum);  // increment by 1, or put 1 if absent
IX Chapter IX · 4 Questions

LinkedHashSet & LinkedHashMap

Insertion-order iteration — a doubly-linked list and a HashMap, dancing in perfect harmony.

Xperi · Day 2

LinkedHashMap HashMap se kaise alag hai? Internally kaise kaam karta hai?

LinkedHashMap = HashMap + Doubly Linked List to maintain insertion order.

Har Entry mein HashMap ke buckets ke saath, ek before/after pointer bhi hota hai — doubly linked list maintain karta hai insertion order ke liye.

Java
// LinkedHashMap — insertion order preserved
Map<String, Integer> linked = new LinkedHashMap<>();
linked.put("banana", 2);
linked.put("apple", 1);
linked.put("cherry", 3);
System.out.println(linked);  // {banana=2, apple=1, cherry=3} — insertion order!

// LRU Cache — access order mode
Map<String, Integer> lru = new LinkedHashMap<>(16, 0.75f, true) {
    protected boolean removeEldestEntry(Map.Entry<String,Integer> eldest) {
        return size() > 3;  // keep max 3 entries
    }
};
✅ LRU Cache = LinkedHashMap with accessOrder=true + removeEldestEntry override. This is a classic interview question!

LinkedHashSet kaise kaam karta hai? Kab use karein?

LinkedHashSet = HashSet + insertion order. Internally LinkedHashMap backed hai.

Java
Set<String> set = new LinkedHashSet<>();
set.add("c"); set.add("a"); set.add("b");
System.out.println(set);  // [c, a, b] — insertion order maintained

// Use case: Deduplicate while preserving order
List<String> withDupes = Arrays.asList("x", "y", "x", "z", "y");
Set<String> unique = new LinkedHashSet<>(withDupes);
System.out.println(unique);  // [x, y, z] — unique, insertion order
X Chapter X · 6 Questions

TreeSet & TreeMap — The Red-Black Tree

Self-balancing binary search trees, O(log n) operations, and the eternal debate: Comparable, or Comparator?

Xperi · Day 2

TreeSet internally kaise kaam karta hai? Red-Black Tree kya hota hai?

TreeSet internally TreeMap use karta hai jo Red-Black Tree par based hai.

Red-Black Tree properties:

  • Self-balancing BST (Binary Search Tree)
  • Har node Red ya Black hota hai
  • Root always Black
  • No two consecutive Red nodes
  • Every path from root to null has same Black nodes
  • Guarantees: O(log n) insert, delete, search — always
Java
TreeSet<Integer> ts = new TreeSet<>();
ts.add(5); ts.add(3); ts.add(8); ts.add(1); ts.add(7);
System.out.println(ts);  // [1, 3, 5, 7, 8] — always sorted!

// TreeSet navigation methods
ts.first();         // 1 — smallest
ts.last();          // 8 — largest
ts.floor(6);        // 5 — largest ≤ 6
ts.ceiling(6);      // 7 — smallest ≥ 6
ts.headSet(5);      // [1, 3] — elements < 5
ts.tailSet(5);      // [5, 7, 8] — elements ≥ 5
ts.subSet(3, 8);    // [3, 5, 7] — range [3, 8)

Comparable vs Comparator kya hai? Kab kaunsa use karein?

FeatureComparableComparator
Packagejava.langjava.util
MethodcompareTo(T o)compare(T o1, T o2)
Class modified?Yes (intrusive)No (external)
Sorting typeNatural ordering (1 only)Multiple custom orderings
Use whenYou own the class3rd party class or multiple sorts
Java
// Comparable — natural order
class Student implements Comparable<Student> {
    String name; int age;
    public int compareTo(Student other) {
        return Integer.compare(this.age, other.age);  // sort by age
    }
}

// Comparator — custom, multiple orderings
Comparator<Student> byName = Comparator.comparing(s -> s.name);
Comparator<Student> byAgeDesc = Comparator.comparingInt(Student::getAge).reversed();
Comparator<Student> byNameThenAge = Comparator.comparing(Student::getName)
    .thenComparingInt(Student::getAge);

list.sort(byName);
TreeSet<Student> ts = new TreeSet<>(byName);  // custom order

TreeSet mein null insert karo toh kya hoga?

TreeSet null insert karne pe NullPointerException throw karta hai (Java 7+). Kyunki compareTo() null pe call hota hai jo NPE deta hai.

Java
TreeSet<String> ts = new TreeSet<>();
ts.add(null);  // NullPointerException!

// Workaround: Custom Comparator that handles null
TreeSet<String> ts2 = new TreeSet<>(
    Comparator.nullsFirst(Comparator.naturalOrder())
);
ts2.add(null); ts2.add("b"); ts2.add("a");
System.out.println(ts2);  // [null, a, b]

PriorityQueue kaise kaam karta hai? Min-heap ya Max-heap?

Java's PriorityQueue by default Min-Heap hai (smallest element at top). Internally array-based binary heap hai.

Java
// Min-Heap (default)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(5); minHeap.offer(1); minHeap.offer(3);
minHeap.poll();  // 1 (minimum)

// Max-Heap
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.offer(5); maxHeap.offer(1); maxHeap.offer(3);
maxHeap.poll();  // 5 (maximum)

// Custom object priority
PriorityQueue<Task> pq = new PriorityQueue<>(
    Comparator.comparingInt(Task::getPriority)
);
PriorityQueue Iterator does NOT guarantee order! Use poll() for ordered retrieval.
XI Chapter XI · Reference

The Big-O Cheat Sheet

A reference for the hurried — and for those who, having memorised, wish to confirm what they already know.

Xperi · Day 2

ArrayList

get(i)O(1)
add(e)O(1) amortized
add(i, e)O(n)
remove(i)O(n)
contains()O(n)

LinkedList

get(i)O(n)
addFirst / addLastO(1)
removeFirst / removeLastO(1)
remove(i)O(n)
contains()O(n)

HashMap & HashSet

get / put / removeO(1) avg
Worst caseO(n)
IterationO(n)
ResizeO(n)

LinkedHashMap

get / put / removeO(1)
Insertion-order iter.O(n)
Access-order (LRU)O(1)

TreeMap & TreeSet

get / put / removeO(log n)
IterationO(n)
firstKey / lastKeyO(log n)

PriorityQueue (Heap)

offer / addO(log n)
poll / removeO(log n)
peekO(1)
remove(i)O(n)
Array for O(1) random access. Tree for O(log n) sorted order. Hash for O(1) average. List for O(n) search. Queue or Stack for O(1) end-operations. The five rules, in five phrases.
XII Chapter XII · 6 Questions

Xperi-Specific — Coding Round Patterns

The patterns that recur in Xperi interviews, distilled from Glassdoor, from quora, from the whisperings of those who have faced the panel.

Xperi · Day 2

LRU Cache implement karo Java mein.

Java
class LRUCache {
    private final int capacity;
    private final LinkedHashMap<Integer, Integer> cache;

    LRUCache(int capacity) {
        this.capacity = capacity;
        // accessOrder=true: moves accessed entry to end
        this.cache = new LinkedHashMap<>(capacity, 0.75f, true) {
            protected boolean removeEldestEntry(Map.Entry<Integer,Integer> eldest) {
                return size() > capacity;  // remove LRU when full
            }
        };
    }

    public int get(int key) {
        return cache.getOrDefault(key, -1);  // moves to end (most recent)
    }

    public void put(int key, int value) {
        cache.put(key, value);  // auto removes eldest if over capacity
    }
}

// Test
LRUCache lru = new LRUCache(2);
lru.put(1, 10);
lru.put(2, 20);
lru.get(1);      // 10 — key 1 is now most recent
lru.put(3, 30); // evicts key 2 (least recently used)
lru.get(2);      // -1 — evicted!

Find first non-repeating character in a String.

Java
public char firstNonRepeating(String s) {
    // LinkedHashMap preserves insertion order
    Map<Character, Integer> freq = new LinkedHashMap<>();

    for (char c : s.toCharArray()) {
        freq.merge(c, 1, Integer::sum);
    }

    for (Map.Entry<Character, Integer> e : freq.entrySet()) {
        if (e.getValue() == 1) return e.getKey();
    }
    return '\0';
}
// "aabbcde" → 'c'; Time: O(n), Space: O(1) — max 26 chars

Group anagrams together from a list of strings.

Java
public List<List<String>> groupAnagrams(String[] words) {
    Map<String, List<String>> map = new HashMap<>();

    for (String word : words) {
        char[] chars = word.toCharArray();
        Arrays.sort(chars);
        String key = new String(chars);  // "eat","tea","ate" → "aet"

        map.computeIfAbsent(key, k -> new ArrayList<>()).add(word);
    }

    return new ArrayList<>(map.values());
}
// Input: ["eat","tea","tan","ate","nat","bat"]
// Output: [["eat","tea","ate"],["tan","nat"],["bat"]]
// Time: O(n·k·log k) where k = max word length

Top K frequent elements find karo.

Java
public int[] topKFrequent(int[] nums, int k) {
    // Step 1: Count frequencies
    Map<Integer, Integer> freq = new HashMap<>();
    for (int n : nums) freq.merge(n, 1, Integer::sum);

    // Step 2: Min-heap of size k
    PriorityQueue<Integer> pq = new PriorityQueue<>(
        Comparator.comparingInt(freq::get)
    );

    for (int key : freq.keySet()) {
        pq.offer(key);
        if (pq.size() > k) pq.poll();  // remove least frequent
    }

    int[] result = new int[k];
    for (int i = k - 1; i >= 0; i--) result[i] = pq.poll();
    return result;
}
// Time: O(n log k), Space: O(n+k)

Two Sum problem — HashMap approach.

Java
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> seen = new HashMap<>();

    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (seen.containsKey(complement)) {
            return new int[] { seen.get(complement), i };
        }
        seen.put(nums[i], i);  // store: value → index
    }
    throw new IllegalArgumentException("No solution");
}
// Time: O(n), Space: O(n) — one pass HashMap

Rapid Fire — Xperi ke common short answers.

QuestionAnswer
Stack implementation prefer?ArrayDeque (not Stack class — synchronized)
Queue implementation prefer?ArrayDeque or LinkedList
Collections.sort() algorithm?TimSort — O(n log n) — stable sort
Arrays.sort() for primitives?Dual-Pivot QuickSort — O(n log n) avg
fail-fast vs fail-safe iterator?ArrayList = fail-fast (throws CME); CopyOnWriteArrayList = fail-safe
Unmodifiable collection?Collections.unmodifiableList() or List.of() (Java 9+)
Synchronized list?Collections.synchronizedList(new ArrayList<>())
HashMap initial capacity formula?(expectedSize / loadFactor) + 1
TreeMap vs HashMap?TreeMap: sorted O(log n). HashMap: unsorted O(1)
EnumSet internal?BitVector — fastest Set for enums