Java - Interview preparation guide
- Keywords
- Data types and Operators
- Strings
- Threads
- OOP in Java
- Exceptions
Java Keywords
What is the use of final keyword?
The final keyword in Java is used to indicate that a variable, method, or class cannot be modified in a certain way:
- Final Variable Once assigned, the value of a final variable cannot be changed. It acts like a constant.
For objects, it means the reference cannot be changed, but the object’s internal state can still be modified.
final int x = 10;
x = 20; // Compilation error
final List<String> list = new ArrayList<>();
list.add(\"hello\"); // Allowed
list = new ArrayList<>(); // Not allowed
- Final Method A method marked as final cannot be overridden by subclasses.
Used to prevent altering critical behavior in subclass.
class A {
final void show() {
System.out.println(\"A's show\");
}
}
class B extends A {
void show() { } // Compilation error
}
- Final Class A final class cannot be subclassed.
Often used for security or design reasons (e.g., Java’s String class is final).
final class A {
}
class B extends A { } // Compilation error
What is transient keyword in Java?
The transient keyword is used with variables when serializing an object.
When an object is serialized, all non-transient variables are saved.
Transient variables are ignored during serialization.
Commonly used for sensitive data like passwords or non-serializable fields.
class User implements Serializable {
String username;
transient String password; // won't be saved during serialization
}
When this object is deserialized, the password field will be null.
- It is used to exclude a variable from serialization.
- Useful when sensitive or temporary data should not be stored.
What is volatile keyword?
The volatile keyword is used in multithreaded programming.
It ensures that the value of the variable is always read from main memory, not from a thread-local cache.
Guarantees visibility: When one thread updates a volatile variable, the new value is visible to all other threads immediately.
class SharedResource {
volatile boolean flag = false;
void writer() {
flag = true;
}
void reader() {
if (flag) {
// do something
}
}
}
Without volatile, changes made by one thread might not be visible to another due to CPU caching or compiler optimization.
- Ensures visibility of changes to variables across threads.
- Prevents the JVM from caching the variable locally.
Java Data types
What are the main data types in Java?
Java has two types of data types:
- Primitive types: byte, short, int, long, float, double, char, boolean
- Reference types: Objects, Arrays, Interfaces, Enums
What is the difference between int and Integer?
- int is a primitive data type.
- Integer is a wrapper class that allows int to be used as an object and provides utility methods.
What are the types of operators in Java?
- Arithmetic (+, -, *, /, %)
- Relational (==, !=, <, >, <=, >=)
-
Logical (&&, , !) -
Bitwise (&, , ^, ~, «, ») - Assignment (=, +=, -=, etc.)
- Unary (+, -, ++, –)
- Ternary (condition ? true : false)
Difference between == and .equals() in Java?
- == checks for reference equality (whether they point to the same object).
- .equals() checks for content equality, if overridden (e.g., in String).
Java Strings
What is the difference between String, StringBuilder, and StringBuffer?
| Feature | Mutability | Performance | Use case |
|---|---|---|---|
| String | No | Slow (for changes) | Constant strings |
| StringBuilder | No | Fast | Single-threaded string manipulation |
| StringBuffer | Yes | Slower than StringBuilder | Multi-threaded environments |
String str = \"Hello\";
str.concat(\" World\");
System.out.println(str); // Output: Hello
StringBuilder sb = new StringBuilder(\"Hello\");
sb.append(\" World\");
System.out.println(sb); // Output: Hello World
StringBuffer sb2 = new StringBuffer(\"Hello\");
sb2.append(\" World\");
System.out.println(sb2); // Output: Hello World
concat(" World") returns a new string, but it’s not stored, so str remains "Hello". To get "Hello World", you’d need: str = str.concat(" World");
StringBuilder modifies the original object — much more memory-efficient and faster for repeated modifications (like in loops).
Why is String immutable in Java?
- For security (used in class loading, file paths, network connections)
- For performance (string literals are interned)
- For thread safety (shared across threads safely)
- Because hashCode is cached, it improves the performance of HashMap
What Happens When You Modify a String?
In Java, String is immutable, meaning once a String object is created, its value cannot be changed.
String s = \"hello\";
s = s + \" world\";
Here’s what happens step-by-step:
"hello" is stored in the string pool, and s refers to it.
" world" is also stored in the string pool.
The + operator creates a new String object with the value "hello world".
The variable s now points to this new object.
The original "hello" string remains in memory and unchanged.
Why is this important?
This behavior ensures thread safety and consistency.
It avoids accidental changes to shared strings.
How Does Immutability Help with String Pooling?
The string pool is a special area in the Java heap where interned strings are stored. When you create a string like:
String a = \"test\";
String b = \"test\";
Both a and b point to the same object in the pool because:
Strings are immutable.
There is no risk that a or b will modify the shared string.
If strings were mutable:
Changing the content via one reference would affect all other references.
String pooling would be unsafe and unreliable.
Immutability ensures:
Memory efficiency: fewer duplicate strings.
Faster comparison: reference equality (==) works for interned strings.
Thread safety: multiple threads can safely share strings without synchronization.
What are some commonly used String methods?
- length()
- charAt(index)
- substring(start, end)
- indexOf(), lastIndexOf()
- equals(), equalsIgnoreCase()
- contains(), startsWith(), endsWith()
- replace(), replaceAll()
- split(delimiter)
- toLowerCase(), toUpperCase()
- trim()
What is the difference between == and .equals() with strings?
- == checks reference equality (memory address)
- .equals() checks actual content of the string
String a = \"hello\";
String b = \"hello\";
String c = new String(\"hello\");
System.out.println(a == b); // true (both point to the same object in string pool)
System.out.println(a == c); // false (c is a new object in heap memory)
System.out.println(a.equals(b)); // true (same content)
System.out.println(a.equals(c)); // true (same content)
What is string interning?
Interning is a method of storing only one copy of each distinct string literal in a pool. When a string is interned using intern(), it is added to the string pool.
What is the use of intern() method?
It returns a canonical representation of the string from the string pool. Useful in memory optimization.
String a = new String(\"hello\");
String b = a.intern();
String c = \"hello\";
System.out.println(b == c); // true
How are regular expressions used in Java?
Using the Pattern and Matcher classes from java.util.regex.
Pattern pattern = Pattern.compile(\"\\d+\");
Matcher matcher = pattern.matcher(\"123abc\");
System.out.println(matcher.find()); // true
What are some common regex patterns?
- . – any character
- \d – digit
- \D – non-digit
- \w – word character
- \s – whitespace
- * – zero or more
-
- – one or more
- ? – zero or one
- [abc] – a, b, or c
- ^, $ – beginning or end of line
Difference between replace() and replaceAll() in String?
- replace() works with characters or strings (literal values)
- replaceAll() works with regular expressions
\"abc123\".replace(\"123\", \"\"); // \"abc\"
\"abc123\".replaceAll(\"\\d+\", \"\"); // \"abc\"
Java OOP Concepts
What is the difference between a class and an object?
- A class is a blueprint or template.
- An object is an instance of a class.
class Car {
String color;
void drive() {
System.out.println(\"Driving...\");
}
}
Car myCar = new Car(); // Object of class Car
Can we have a class without any object in Java?
Yes. A class can have only static methods/fields and still be used.
class MathUtils {
public static int square(int x) {
return x * x;
}
}
int result = MathUtils.square(5); // No object needed
What is Encapsulation in Java?
Encapsulation is the process of wrapping data (variables) and methods together into a single unit (class) and restricting direct access.
class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
What is Inheritance?
Inheritance allows a class to acquire properties and behavior of another class.
class Animal {
void sound() {
System.out.println(\"Animal sound\");
}
}
class Dog extends Animal {
void bark() {
System.out.println(\"Woof\");
}
}
Explain Polymorphism
Polymorphism allows one interface to be used for multiple forms.
- Compile-time Polymorphism (Method Overloading)
class Math {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
- Run-time Polymorphism (Method Overriding)
class Animal {
void sound() {
System.out.println(\"Generic sound\");
}
}
class Cat extends Animal {
void sound() {
System.out.println(\"Meow\");
}
}
What is Abstraction?
Abstraction hides internal implementation and shows only functionality.
Using abstract class
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
void draw() {
System.out.println(\"Drawing circle\");
}
}
Using interface
interface Drawable {
void draw();
}
class Rectangle implements Drawable {
public void draw() {
System.out.println(\"Drawing rectangle\");
}
}
What is a constructor?
A constructor is a special method called when an object is created.
It has the same name as the class and no return type.
class Car {
Car() {
System.out.println(\"Car created\");
}
}
What are the types of constructors?
- Default constructor: No arguments
Car() { } - Parameterized constructor: With arguments
Car(String model) { this.model = model; } - Copy constructor: Manually created
Car(Car c) { this.model = c.model; }
What is this keyword used for?
- Refers to the current instance of the class
- Differentiates between local and instance variables
class Student {
String name;
Student(String name) {
this.name = name; // 'this' refers to instance variable
}
}
What is super keyword used for?
- Refers to parent class instance
- Used to call parent class methods/constructors
class Animal {
void sound() {
System.out.println(\"Generic sound\");
}
}
class Dog extends Animal {
void sound() {
super.sound(); // Calls Animal's sound()
System.out.println(\"Bark\");
}
}
What is the difference between static and non-static members?
- Static: Belongs to the class; shared by all instances
- Non-static: Belongs to the object; each object has its own copy
class Example {
static int count = 0;
int id;
Example(int id) {
this.id = id;
count++;
}
}
Can a static method access non-static data?
No. Static methods cannot access non-static members directly.
class Test {
int x = 10;
static void printX() {
// System.out.println(x); // Error: non-static variable x cannot be referenced from a static context
}
}
Java threading
What are the different ways to create a thread in Java?
Extending Thread class
class MyThread extends Thread {
public void run() {
System.out.println(\"Thread running\");
}
}
new MyThread().start();
Implementing Runnable interface
class MyRunnable implements Runnable {
public void run() {
System.out.println(\"Runnable running\");
}
}
new Thread(new MyRunnable()).start();
Using ExecutorService (preferred)
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(() -> System.out.println(\"Thread pool task\"));
executor.shutdown();
What are the states in the thread lifecycle?
New
Runnable
Running
Blocked / Waiting / Timed Waiting
Terminated (Dead)
Use Thread.State enum to query a thread’s current state.
What does the synchronized keyword do?
Ensures mutual exclusion—only one thread can access a critical section at a time.
synchronized (object) {
// critical section
}
Difference between wait(), notify(), and notifyAll()?
wait() → causes the current thread to wait until another thread calls notify() or notifyAll()
notify() → wakes up one waiting thread
notifyAll() → wakes up all waiting threads
Must be called from within a synchronized block.
What is a deadlock? How to prevent it?
Deadlock occurs when two or more threads wait on each other’s resources, creating a cycle.
Prevention:
Lock ordering
Try-lock pattern
Avoid nested locks when possible
What is a race condition?
A race condition happens when two or more threads access shared data and try to change it at the same time, leading to unexpected results.
Fix: Use synchronization or atomic classes.
What is starvation?
A thread is starved when it waits indefinitely for CPU or resource access, usually due to high-priority threads monopolizing access.
What are thread-safe collection classes in Java?
Vector, Hashtable (legacy)
Collections.synchronizedList()
Concurrent Collections (preferred):
ConcurrentHashMap
CopyOnWriteArrayList
BlockingQueue
What is volatile keyword?
volatile ensures changes to a variable are visible to all threads immediately. It prevents caching of the variable’s value by any thread.
volatile boolean running = true;
What is AtomicInteger and when to use it?
It allows lock-free thread-safe operations on integers. Commonly used for counters.
AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet();
What is ReentrantLock? How is it different from synchronized?
Explicit lock from java.util.concurrent.locks
More control than synchronized (e.g., tryLock, fairness policy)
Must be manually released
ReentrantLock lock = new ReentrantLock(); lock.lock(); try { // critical section } finally { lock.unlock(); }
What is the Java Memory Model?
Defines how threads interact with memory. It specifies:
Visibility rules
Happens-before relationships
Instruction reordering
volatile, synchronized, and final interact with the JMM to ensure consistency.
What is the difference between Runnable and Callable?
Feature Runnable Callable Returns? No return value Returns a value (via Future) Throws? Cannot throw checked excep. Can throw checked exceptions
How do you use Callable with ExecutorService?
Callable
What is CompletableFuture?
It’s an enhancement over Future that supports asynchronous, non-blocking programming.
CompletableFuture.supplyAsync(() -> { return "Hello"; }).thenApply(str -> str + " World").thenAccept(System.out::println);
Java Exceptions
What is the difference between checked and unchecked exceptions?
Feature Checked Exception Unchecked Exception Inheritance Extends Exception Extends RuntimeException Compile-time check Required Not required Must handle? Yes (try-catch or throws) No, optional Examples IOException, SQLException NullPointerException, ArithmeticException
Why are some exceptions checked and others unchecked?
Checked exceptions are meant to force the programmer to handle recoverable errors, like file not found. Unchecked exceptions indicate programming bugs, like null pointer access, that should be fixed rather than caught.
What is the purpose of finally block in Java?
The finally block always executes, whether an exception occurs or not. It is used to release resources, like closing files, database connections, etc.
try {
// risky code
} catch (Exception e) {
// handle exception
} finally {
// cleanup code
}
Can a finally block override a return value?
Yes. If both the try and finally blocks have return statements, the return from finally overrides the one from try. But this is discouraged.
Difference between throw and throws?
| Feature | Purpose | Location |
|---|---|---|
| throw | Purpose To actually throw an exception | Inside a method |
| throws | To declare an exception | In method signature |
throw new IOException();
public void read() throws IOException
Can you throw multiple exceptions using throw?
No. throw is used to throw only one exception at a time.
How do you create a custom exception in Java?
public class MyCustomException extends Exception {
public MyCustomException(String message) {
super(message);
}
}
if (age < 18) {
throw new MyCustomException(\"Age must be 18+\");
}
Should custom exceptions extend Exception or RuntimeException?
Depends on the use case:
-
Extend Exception for checked custom exceptions (require handling).
-
Extend RuntimeException for unchecked ones (optional handling).
What are some best practices in exception handling?
- Catch only those exceptions you can handle meaningfully.
- Avoid catching Exception or Throwable unless absolutely necessary.
- Always clean up resources in finally or use try-with-resources.
- Use custom exceptions for business logic clarity.
- Log exceptions properly — don’t silently ignore them.
- Don’t use exceptions for flow control.
What is try-with-resources?
Introduced in Java 7, it automatically closes resources (e.g. InputStream, BufferedReader).
try (BufferedReader br = new BufferedReader(new FileReader(\"file.txt\"))) {
String line = br.readLine();
}
Java Collections
What are the main interfaces in the Java Collections Framework?
List – Ordered collection, allows duplicates. (ArrayList, LinkedList)
Set – Unordered, no duplicates. (HashSet, LinkedHashSet, TreeSet)
Map – Key-value pairs, keys are unique. (HashMap, TreeMap, LinkedHashMap)
Queue – FIFO structure. (PriorityQueue, LinkedList)
Difference between Collection and Collections?
Collection is the root interface for lists, sets, and queues.
Collections is a utility class with static methods like sort(), reverse(), synchronizedList().
Difference between ArrayList and LinkedList?
Feature ArrayList LinkedList Data structure Dynamic array Doubly linked list Access time Fast (O(1) for index) Slow (O(n)) Insert/delete Slow (shifting needed) Fast at head/tail Memory usage Less More (due to node links)
Difference between HashSet and TreeSet?
Feature HashSet TreeSet Order No order Sorted (natural or custom) Performance Faster (O(1)) Slower (O(log n)) Nulls Allows one null Allows one null if comparator supports it
Difference between HashMap, TreeMap, and LinkedHashMap?
Feature HashMap TreeMap LinkedHashMap Order No order Sorted by keys Insertion order Null keys One null key No null keys One null key Performance Fast (O(1)) Slower (O(log n)) Slower than HashMap
What’s the difference between Comparable and Comparator?
Feature Comparable Comparator Interface method compareTo(Object o) compare(Object o1, o2) Location Implemented in the class itself Implemented in separate class Used for Natural ordering Custom ordering
class Student implements Comparable
How do you sort a list using Comparator?
Collections.sort(list, (a, b) -> a.name.compareTo(b.name));
Ways to iterate over a collection?
- For-each loop
- Iterator
- ListIterator (supports reverse)
- Streams (forEach)
- Traditional for-loop (index-based)
What’s the benefit of streams?
They allow functional-style operations like filtering, mapping, and collecting, often making code shorter and more readable.
list.stream().filter(s -> s.startsWith("A")).forEach(System.out::println);