Blog

Top 50 Java Interview Questions for Freshers 2026

Prepare with real Java interview questions asked at TCS, Infosys, Wipro, EPAM, Mphasis, startups and service-based companies.

FreshersJavaOOPCollectionsJava 8Interview Prep
50Questions
8Topics Covered
15 MinEstimated Read
BeginnerFriendly
Reading Progress0%

1. OOP Concepts in Java

The most important OOP questions asked in almost every Java interview.

The four pillars of Object-Oriented Programming are:

  • Encapsulation — wrapping data and methods into a class and restricting direct access using access modifiers.
  • Inheritance — a child class acquires properties and methods from a parent class using extends.
  • Polymorphism — the same method name with different behaviour: compile-time (overloading) and runtime (overriding).
  • Abstraction — hiding implementation details and exposing only the interface, via abstract classes and interfaces.

Interview Tip: Always explain each pillar with a real-world example — interviewers want understanding, not definitions.

Q2. What is the difference between == and .equals() in Java?Most AskedCode Example

== compares references (memory addresses) for objects; for primitives it compares values. .equals() compares content. String, Integer and other wrapper classes override it to compare values.

String a = new String("hello");
String b = new String("hello");

System.out.println(a == b);       // false (different objects)
System.out.println(a.equals(b));  // true  (same content)

Interview Tip: Always use .equals() to compare object contents, especially Strings.

FeatureAbstract ClassInterface
MethodsAbstract + concreteDefault + abstract (Java 8+)
VariablesInstance variables allowedOnly public static final
ConstructorYesNo
Multiple inheritanceNo (single only)Yes (implement many)
Use caseIS-A with shared stateContract / capability

Interview Tip: Rule of thumb: use an interface for a capability (HAS-A), an abstract class for shared base state (IS-A).

Overloading — same method name, different parameters, in the same class. Resolved at compile time.

Overriding — a subclass provides a new implementation for a parent method with the same signature. Resolved at runtime.

// Overloading
void print(String s) {}
void print(int n) {}

// Overriding
class Animal { void speak() { System.out.println("..."); } }
class Dog extends Animal {
    @Override
    void speak() { System.out.println("Woof"); }
}
  • final variable — value cannot be changed (a constant).
  • final method — cannot be overridden in a subclass.
  • final class — cannot be subclassed (e.g. String, Integer).
  • this — refers to the current object; used to access current-class fields, methods and constructors.
  • super — refers to the immediate parent class; used to call the parent constructor or access overridden parent members.
class Animal {
    Animal() { System.out.println("Animal created"); }
}
class Dog extends Animal {
    String name;
    Dog(String name) {
        super();          // parent constructor
        this.name = name; // current object's field
    }
}

A constructor is a special method used to initialise an object. It has the same name as the class and no return type. Yes — constructors can be overloaded by varying the parameter list.

class Student {
    String name; int age;
    Student() { this("Unknown", 0); }          // no-arg
    Student(String name) { this(name, 18); }    // one-arg
    Student(String name, int age) {             // two-arg
        this.name = name; this.age = age;
    }
}

Interview Tip: Constructor chaining with this(...) avoids duplicate initialisation code.

static members belong to the class, not to any instance — shared across all objects.

  • static variable — one copy shared by all instances.
  • static method — called without an object; cannot access instance members directly.
  • static block — runs once when the class is loaded.
class Counter {
    static int count = 0;       // shared
    Counter() { count++; }
    static void show() {        // no object needed
        System.out.println(count);
    }
}

2. Collections Framework in Java

Important collection questions every fresher should know before interviews.

FeatureArrayListLinkedList
Backed byDynamic arrayDoubly linked list
Random access (get)O(1)O(n)
Insert/delete (middle)O(n)O(1)
Use caseFrequent readsFrequent insertions

Interview Tip: Never say one is just 'faster' — always qualify it with the operation type.

FeatureHashMapHashTable
Thread safetyNot thread-safeThread-safe (synchronized)
Null keysOne null key allowedNo null keys
PerformanceFasterSlower
Modern usePreferredLegacy — use ConcurrentHashMap
  • HashMap — no ordering, O(1) get/put.
  • LinkedHashMap — maintains insertion order, O(1) get/put.
  • TreeMap — sorted by natural order or a Comparator, O(log n) get/put.

A HashMap stores entries in an array of buckets. The key's hashCode() is hashed to compute a bucket index. Collisions (multiple keys in one bucket) are stored as a linked list, which converts to a balanced tree when a bucket exceeds 8 entries (Java 8+) for O(log n) lookups.

// Simplified flow on put(key, value):
int hash  = hash(key.hashCode());
int index = (n - 1) & hash;   // bucket index
// equals() resolves collisions within the bucket

Interview Tip: Mention the treeify threshold (8) — it impresses interviewers and shows Java 8 awareness.

  • Iterator — forward traversal only, works on all Collection types.
  • ListIterator — bidirectional (forward + backward), works only on List, and can add/set elements during iteration.

You get a ConcurrentModificationException from fail-fast iterators. Use Iterator.remove() instead of collection.remove() during iteration, or use a fail-safe collection like CopyOnWriteArrayList.

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("x")) it.remove(); // safe
}
  • Comparable — natural ordering, single compareTo() method, implemented by the class itself.
  • Comparator — custom/multiple orderings, compare() method, defined externally.
// Comparable
class Student implements Comparable<Student> {
    int marks;
    public int compareTo(Student o) { return this.marks - o.marks; }
}

// Comparator
Comparator<Student> byName = (a, b) -> a.name.compareTo(b.name);
list.sort(byName);
  • List — ordered, allows duplicates, index-based (ArrayList, LinkedList).
  • Set — no duplicates, mostly unordered (HashSet, TreeSet).
  • Map — key-value pairs, unique keys (HashMap, TreeMap).

Want to practise Java interviews with real mentors?

Join CodeBegun Java Full Stack Training and boost your career in top IT companies.

Talk to Counsellor

3. Strings in Java

String immutability, pooling and the StringBuilder family.

Once created, a String's value cannot change — any modification creates a new object. Reasons:

  1. Security — used in network connections, file paths, class loading.
  2. Thread safety — immutable objects need no synchronisation.
  3. String Pool — lets the JVM safely reuse literals.
  4. HashCode caching — constant hash makes it a great HashMap key.

A special region in the JVM heap where string literals are stored. When you write a literal, Java checks the pool first and reuses the existing reference. new String("hello") always creates a new object, bypassing the pool.

String a = "hello";          // pooled
String b = "hello";          // same reference
String c = new String("hello"); // new object

a == b;          // true
a == c;          // false
a == c.intern(); // true
FeatureStringStringBuilderStringBuffer
MutabilityImmutableMutableMutable
Thread safeYesNoYes
PerformanceSlowest concatFastestSlower

Interview Tip: Use StringBuilder for string building inside loops — it's the most common follow-up question.

intern() returns the canonical (pooled) reference of a string. If the pool already contains an equal string, that reference is returned; otherwise the string is added to the pool.

String a = new String("cb");
String b = a.intern();
System.out.println(b == "cb"); // true

Because String is immutable, each += creates a brand new object — O(n²) work and lots of garbage. Use a StringBuilder instead.

// Bad — creates n new String objects
String s = "";
for (int i = 0; i < n; i++) s += i;

// Good — O(n)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) sb.append(i);
String result = sb.toString();

4. Exception Handling in Java

Checked vs unchecked, try-with-resources and the final/finally/finalize trap.

Checked — must be handled with try-catch or declared with throws (e.g. IOException, SQLException). Checked at compile time.

Unchecked — extend RuntimeException, no mandatory handling (e.g. NullPointerException, ArrayIndexOutOfBoundsException).

  • throw — used inside a method to actually throw an exception object.
  • throws — used in the method signature to declare that it might throw an exception.
void readFile(String path) throws IOException {
    if (path == null)
        throw new IllegalArgumentException("Path is null");
}

Interview Tip: Confusing throw and throws is one of the most common fresher mistakes — be crisp here.

The finally block normally always runs after try-catch (used for cleanup). It does not execute when System.exit() is called, or when the JVM crashes (e.g. OutOfMemoryError or the thread is killed).

Yes, since Java 7 with the multi-catch syntax using |.

try {
    // risky code
} catch (IOException | SQLException e) {
    // handle both the same way
    log.error(e.getMessage());
}

A Java 7 feature that automatically closes resources implementing AutoCloseable at the end of the block — no manual finally needed.

try (BufferedReader br = new BufferedReader(new FileReader("f.txt"))) {
    return br.readLine();
} // br.close() called automatically

Extend Exception (checked) or RuntimeException (unchecked) and pass a message to the parent constructor.

class InsufficientBalanceException extends RuntimeException {
    InsufficientBalanceException(String msg) {
        super(msg);
    }
}
throw new InsufficientBalanceException("Balance too low");
  • final — a keyword for constants / non-overridable methods / non-extendable classes.
  • finally — a block that always runs after try-catch for cleanup.
  • finalize() — a method called by the GC before object destruction (deprecated; avoid it).

Interview Tip: This trio is a classic trick question — keep the three meanings completely separate in your head.

5. Java 8+ Features

Lambdas, streams, Optional and functional interfaces.

Anonymous functions that implement a functional interface. Syntax: (parameters) -> expression.

List<String> names = Arrays.asList("Priya", "Ravi", "Sai");
names.forEach(name -> System.out.println(name));
// method reference form:
names.forEach(System.out::println);

A sequence of elements supporting sequential and parallel aggregate operations. Streams do not store data — they pipeline operations on a source (filter, map, reduce, collect).

List<Integer> result = numbers.stream()
    .filter(n -> n > 10)
    .map(n -> n * 2)
    .collect(Collectors.toList());

Interview Tip: Be ready to write a filter→map→collect pipeline on a whiteboard from memory.

A container that may or may not hold a non-null value — it helps avoid NullPointerException.

Optional<String> name = Optional.ofNullable(getName());
name.ifPresent(System.out::println);
String value = name.orElse("Unknown");

Methods with a body inside an interface, added in Java 8 so interfaces can evolve without breaking existing implementations.

interface Greet {
    default void hello() {
        System.out.println("Hello from interface");
    }
}

An interface with exactly one abstract method — the target type for a lambda. Annotated with @FunctionalInterface (optional but recommended). Examples: Predicate<T>, Function<T,R>, Consumer<T>, Supplier<T>.

@FunctionalInterface
interface Calculator {
    int operate(int a, int b);
}
Calculator add = (a, b) -> a + b;

A shorthand for a lambda that just calls an existing method. Four kinds: static, instance of a particular object, instance of an arbitrary object, and constructor.

names.stream().map(String::toUpperCase);   // instance method
list.forEach(System.out::println);          // bound instance
Stream.generate(ArrayList::new);            // constructor
  • map() — transforms each element 1:1, producing a stream of values.
  • flatMap() — transforms each element into a stream and flattens all of them into one stream.
// map -> Stream<List<Integer>>
lists.stream().map(list -> list);

// flatMap -> Stream<Integer> (flattened)
lists.stream().flatMap(List::stream).collect(Collectors.toList());

6. Multithreading in Java

Threads, synchronisation, deadlocks and thread pools.

Implementing Runnable is preferred because:

  • Java has no multiple inheritance — extending Thread blocks you from extending another class.
  • Runnable separates the task from the execution mechanism.
  • It works cleanly with thread pools (ExecutorService accepts Runnable).

It ensures only one thread executes a synchronized method or block at a time, using the object's intrinsic lock (monitor) — preventing race conditions.

class Counter {
    private int count = 0;
    synchronized void increment() { count++; }
}

A deadlock occurs when two or more threads are blocked forever, each waiting for a lock the other holds.

Prevention: always acquire locks in a consistent global order, use timeouts (tryLock), and keep lock scopes small.

  • wait() — releases the lock and pauses the thread until notified.
  • notify() — wakes one waiting thread.
  • notifyAll() — wakes all waiting threads.

All three must be called inside a synchronized block and are used for inter-thread communication (e.g. producer-consumer).

volatile guarantees that reads and writes of a variable go directly to main memory, so all threads see the latest value (visibility). It does not provide atomicity for compound operations like count++.

Interview Tip: Clarify: volatile solves visibility, not atomicity — use AtomicInteger or synchronized for count++.

  • Runnablerun() returns nothing and cannot throw checked exceptions.
  • Callablecall() returns a result (via Future) and can throw checked exceptions.
Callable<Integer> task = () -> 2 + 2;
Future<Integer> f = executor.submit(task);
Integer result = f.get(); // 4

A managed pool of reusable threads that runs submitted tasks — avoiding the cost of creating a new thread per task.

ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> doWork());
pool.shutdown();

7. Object Class Methods

equals, hashCode, toString and clone.

  • If a.equals(b) is true, then a.hashCode() == b.hashCode() must be true.
  • If a.equals(b) is false, the hash codes may or may not differ.
  • Hash code must stay consistent across calls (unless fields used in equals change).

Because hash-based collections (HashMap, HashSet) use both. If you override only equals(), two "equal" objects may land in different buckets and break lookups.

@Override public boolean equals(Object o) { /* compare fields */ }
@Override public int hashCode() { return Objects.hash(id, name); }

Interview Tip: Mention that IDEs and Lombok (@EqualsAndHashCode) can generate both consistently.

Without an override, toString() returns ClassName@hashHex — useless for debugging. Overriding it gives a human-readable representation, which is standard practice for entity and DTO classes.

clone() creates a copy of an object. The class must implement the Cloneable marker interface, otherwise CloneNotSupportedException is thrown. In modern Java, prefer copy constructors or copy factory methods over clone().

  • instanceof — true for the type and its subclasses.
  • getClass() — checks the exact runtime class only.
Object o = new Dog();
o instanceof Animal;            // true (subclass)
o.getClass() == Animal.class;  // false (exact type is Dog)

8. Advanced & Common Topics

Autoboxing, JVM internals and memory.

Java caches Integer objects in the range -128 to 127 (autoboxing cache). Inside that range, == can be true; outside it, each boxed value is a new object.

Integer a = 127, b = 127;
System.out.println(a == b); // true  (cached)

Integer x = 200, y = 200;
System.out.println(x == y); // false (new objects)

Interview Tip: Always use .equals() for wrapper types — this caching quirk is a favourite gotcha.

  • JVM — Java Virtual Machine; runs bytecode, platform-specific.
  • JRE — Java Runtime Environment; JVM + core libraries to run apps.
  • JDK — Java Development Kit; JRE + compiler and dev tools to build apps.

Relationship: JDK ⊃ JRE ⊃ JVM.

Garbage collection automatically reclaims memory from objects that are no longer reachable. System.gc() is only a suggestion. G1 is the default collector since Java 9.

  • Stack — stores primitives, references and method call frames; thread-local; LIFO.
  • Heap — stores all objects; shared across threads; garbage collected.

9. Common Mistakes in Java Interviews

Avoid these and you are already ahead of most freshers.

  1. Saying == compares value for Strings — it compares references.
  2. Confusing throw and throws.
  3. Not knowing when to use StringBuilder vs String.
  4. Saying ArrayList is "faster" without naming the operation type.
  5. Being unable to write a lambda or stream on a whiteboard.
  6. Forgetting HashMap allows one null key.
  7. Overriding equals() without overriding hashCode().

10. How to Prepare for a Java Interview

A simple plan our placed students actually follow.

  1. Understand concepts, not just definitions — draw diagrams if it helps.
  2. Write a code example for each concept instead of reciting it.
  3. Practise on a whiteboard or plain editor — no IDE autocomplete.
  4. Do 5–10 mock interviews before the real one.
  5. Revise your own projects — interviewers ask "how did you build X?"

Want to practise Java interviews with real mentors?

CodeBegun's Java Full Stack program includes 10 mock interviews before placement.

Talk to Counsellor
Chat with us