Most Commonly Asked Java Interview Questions
Java interview questions freshers face most: OOP, collections, exception handling, JVM memory, and threading, with verified code examples and concise answers.
Six topic areas account for most Java interview questions freshers encounter: OOP design, wrapper classes, collections, exception handling, JVM memory, and threading.
This article covers each with enough depth to answer the questions interviewers actually ask, plus code examples verified from first principles.
OOP in Java: The Concepts Interviewers Test
Java’s four OOP pillars come up in every technical round, typically as definitional questions followed by a code or design problem.
Encapsulation means binding data and methods in one unit and restricting direct field access with private fields and getter/setter methods. Interviewers ask why you’d make a field private rather than public. The answer is controlled mutation and testability.
Inheritance lets a subclass extend a superclass using extends, reusing and specialising behaviour. Key terms: super keyword (access superclass constructor or method), method overriding.
Polymorphism takes two forms. Method overloading (compile-time polymorphism) means multiple methods with the same name but different parameter lists in the same class. Method overriding (runtime polymorphism) means a subclass redefines a superclass method with the same signature. Interviewers ask candidates to distinguish the two explicitly:
class Calculator {
// Overloading — compile-time polymorphism
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
class Animal {
void speak() { System.out.println("..."); }
}
class Dog extends Animal {
@Override
void speak() { System.out.println("Woof"); } // Overriding — runtime polymorphism
}
Abstraction separates what a class does from how. An abstract class can hold method implementations and state but cannot be instantiated directly. An interface defines a contract: before Java 8, all methods were implicitly abstract; Java 8 added default and static methods. A class can implement multiple interfaces but extend only one abstract class. That last constraint is the most tested distinction.
The Singleton design pattern comes up as a practical OOP question. The canonical lazy-initialization form:
class Singleton {
private static Singleton instance;
private Singleton() {} // Private constructor prevents external instantiation
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Note: this pattern is not thread-safe. For concurrent access, use double-checked locking with volatile or the static-holder idiom.
Strings, Wrapper Classes, and the == vs .equals() Trap
Java maintains a string pool inside the heap. String literals go into the pool; two literals with the same content share the same reference. new String("Java") always creates a new heap object, bypassing the pool entirely.
String a = "Java";
String b = "Java";
String c = new String("Java");
System.out.println(a == b); // true — same pool reference
System.out.println(a == c); // false — c is a separate heap object
System.out.println(a.equals(c)); // true — same content
Use .equals() for value comparison in interview code. Using == on String objects is among the top-five Java pitfalls interviewers test.
Java provides a wrapper class for each of its eight primitives:
| Primitive | Wrapper Class |
|---|---|
| boolean | Boolean |
| byte | Byte |
| char | Character |
| int | Integer |
| float | Float |
| double | Double |
| long | Long |
| short | Short |
Autoboxing is the automatic conversion of a primitive to its wrapper class (for example, int to Integer). Unboxing is the reverse. Collections like ArrayList<Integer> hold objects, not primitives, so autoboxing happens transparently when you call list.add(5).
Java Collections: What Interviewers Really Ask
The Oracle Java Tutorial covers the Collections API in full; placement rounds focus on practical tradeoffs.
ArrayList vs LinkedList is the standard opening question:
| Feature | ArrayList | LinkedList |
|---|---|---|
| Internal structure | Dynamic array | Doubly-linked list |
get(index) | O(1) | O(n) |
| Add/remove at middle | O(n), shifts elements | O(1) at node, O(n) to traverse to node |
| Memory overhead | Low | Higher (each node stores two pointers) |
| Best for | Frequent random access | Frequent head/tail insert or delete |
Use ArrayList<E> for most cases. Use LinkedList<E> specifically when insertions and deletions at the front of the list dominate.
HashMap is the standard follow-up. HashMap<K,V> stores key-value pairs in an array of buckets. When you call put(key, value), Java calls hashCode() on the key to determine the bucket. If two keys hash to the same bucket (collision), Java chains them as a linked list (or a red-black tree in Java 8+ when the chain reaches 8 entries). get(key) repeats the hash computation, then calls equals() to find the right entry.
Interviewers consistently ask: if you override equals() in a key class, you must also override hashCode(). Breaking this contract breaks HashMap lookup.
For practice with Java data-structure implementations, FACE Prep’s data structures guide covers Java, C, and Python versions side by side.
Exception Handling
Java’s exception hierarchy starts at Throwable:
Throwable
├── Error (OutOfMemoryError, StackOverflowError) — do not catch; JVM-level failure
└── Exception
├── RuntimeException (unchecked) — NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException
└── Checked exceptions — IOException, SQLException, ClassNotFoundException
Checked exceptions are verified at compile time. A method that may throw one must catch it or declare it with throws. Unchecked exceptions (subclasses of RuntimeException) are not enforced at compile time.
Key try-catch-finally behaviour:
try {
int[] arr = new int[3];
arr[5] = 10; // throws ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Caught: " + e.getMessage());
} finally {
System.out.println("finally runs regardless");
}
// Output:
// Caught: Index 5 out of bounds for length 3
// finally runs regardless
The finally block executes whether or not an exception is thrown, unless System.exit() is called or the JVM terminates abnormally. Interviewers probe this to test understanding of resource cleanup.
throw (verb) is used inside a method body to throw an exception. throws (noun) is used in a method signature to declare the method may propagate a checked exception.
JVM Memory: Heap, Stack, and String Pool
| Memory Area | Stores | Access | Managed by |
|---|---|---|---|
| Heap | Objects, instance variables | All threads (shared) | Garbage Collector |
| Stack | Method frames, local variables, operand stack | Per-thread (private) | JVM (LIFO, auto-freed) |
| String Pool | Interned string literals | All threads (shared) | Part of the heap |
Every new keyword creates a heap object. Method calls push a frame onto the calling thread’s stack; the frame pops when the method returns. Stack overflow (StackOverflowError) occurs when recursive calls exceed the stack depth.
Garbage collection reclaims heap objects that are no longer reachable. Java uses generational GC: new objects enter the Young Generation (Eden space); survivors are promoted to the Old Generation. Placement interviews typically test only conceptual knowledge: which generation, why promotion happens, not GC tuning flags.
Threading Basics
Java threads follow a six-state lifecycle defined in the Thread.State enum:
- NEW — thread created,
start()not yet called - RUNNABLE — executing or ready to execute on the CPU
- BLOCKED — waiting to acquire a monitor lock held by another thread
- WAITING — waiting indefinitely (e.g.,
Object.wait(),Thread.join()with no timeout) - TIMED_WAITING — waiting with a timeout (
Thread.sleep(n),Object.wait(n)) - TERMINATED — execution complete
The synchronized keyword ensures only one thread runs a block at a time by acquiring the object’s intrinsic lock. Synchronized methods lock on this; synchronized blocks take an explicit lock object:
synchronized (lockObject) {
// only one thread at a time reaches here
}
volatile ensures a field is always read from and written to main memory, bypassing CPU cache. It guarantees visibility across threads but not atomicity. For atomic compound operations, use java.util.concurrent.atomic classes or synchronized.
Deadlock occurs when two threads each hold a lock the other needs, creating a circular wait. Interviewers ask for a minimal deadlock example and how to prevent it (consistent lock ordering, tryLock with timeout).
Java’s OOP design, exception handling, and threading concepts are also the building blocks for back-end services that integrate AI APIs, an increasingly common pattern at product companies. The interface-based design and exception-handling patterns from the sections above are the same ones used to write clean Java clients for LLM endpoints.
If you want to test that connection in practice, TinkerLLM runs at ₹299 and walks through building an API-integrated project from scratch, a concrete next step after placement-round prep.
For rounds that go deeper on design and algorithms, FACE Prep’s Directi interview guide covers one of the more technically demanding placement processes freshers encounter.
Primary sources
Frequently asked questions
What is the difference between == and .equals() in Java?
== compares object references (memory addresses). .equals() compares object content (value). For String comparisons in interview code, always use .equals() unless you specifically need reference equality.
What is autoboxing in Java?
Autoboxing is the automatic conversion of a primitive type to its corresponding wrapper class — for example, int to Integer. Unboxing is the reverse. Java performs this transparently when a primitive is added to a collection like ArrayList.
When should I use ArrayList over LinkedList?
Use ArrayList when you need fast random access — get by index runs in O(1). Use LinkedList when you frequently insert or delete at the head or tail, where its O(1) pointer update matters more than ArrayList's O(n) shift cost.
What is the difference between checked and unchecked exceptions?
Checked exceptions (IOException, SQLException) are verified at compile time — your code must catch or declare them with throws. Unchecked exceptions (NullPointerException, ArrayIndexOutOfBoundsException) extend RuntimeException and are not enforced at compile time.
What does the synchronized keyword do in Java?
synchronized restricts access to a method or code block to one thread at a time using the object's intrinsic lock. Synchronized methods lock on 'this'; synchronized blocks let you specify the lock object explicitly for finer control.
What is the difference between abstract class and interface in Java?
An abstract class can have method implementations, instance variables, and constructors. An interface (before Java 8) could only have abstract methods; from Java 8 it supports default and static methods. A class can implement multiple interfaces but extend only one abstract class.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)