Java Advanced Interview Questions
In this page:
Checked vs Unchecked Exceptions
Checked exceptions are enforced by the compiler: a method that can throw one must declare it or catch it, forcing callers to handle the failure explicitly. Unchecked exceptions (RuntimeException and its subclasses) skip that compile-time enforcement entirely, which is why they're typically reserved for programming errors rather than expected failure conditions.
Example: Checked vs Unchecked Exceptions
public class Main {
static void readFile() throws java.io.IOException { // checked -- must be declared or caught
throw new java.io.IOException("file missing");
}
static void process() { // no throws clause needed for unchecked
throw new RuntimeException("unchecked -- skips compile-time enforcement");
}
public static void main(String[] args) {
try { readFile(); } catch (java.io.IOException e) { System.out.println("Checked: " + e.getMessage()); }
try { process(); } catch (RuntimeException e) { System.out.println("Unchecked: " + e.getMessage()); }
}
}
Login to try C/C++/Java/PHP code in the editor
HashMap Collisions and Re-indexing
HashMap collisions happen when two different keys hash to the same bucket; Java handles this by chaining colliding entries into a linked list within that bucket, and in Java 8+ will convert a sufficiently dense bucket's list into a small red-black tree to keep worst-case lookup time from degrading to O(n).
Example: HashMap Collisions and Re-indexing
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "a"); map.put(17, "b"); // both may land in the same bucket depending on capacity
System.out.println(map.get(1) + " " + map.get(17)); // chained within the bucket, still found correctly
}
}
Login to try C/C++/Java/PHP code in the editor
Synchronized Methods vs Blocks
Synchronizing an entire method locks on the whole object (or class, if static), which is simple but can create unnecessary contention. Synchronized blocks let you lock only the specific lines that actually touch shared state, reducing how long other threads have to wait for unrelated work in the same method.
Example: Synchronized Methods vs Blocks
public class Main {
static int counter = 0;
static final Object lock = new Object();
static synchronized void incrementWholeMethod() { counter++; } // locks the whole object
static void incrementBlockOnly() {
synchronized (lock) { counter++; } // locks only these lines
}
public static void main(String[] args) {
incrementWholeMethod();
incrementBlockOnly();
System.out.println(counter);
}
}
Login to try C/C++/Java/PHP code in the editor
Comparable vs Comparator
Comparable defines a class's single, natural sort order via compareTo(), baked directly into the class itself. Comparator lives outside the class and lets you define one or more alternative, situational orderings without modifying the original class at all.
Example: Comparable vs Comparator
import java.util.*;
public class Main {
static class Person implements Comparable<Person> {
String name; int age;
Person(String name, int age) { this.name = name; this.age = age; }
public int compareTo(Person o) { return Integer.compare(age, o.age); } // natural order, baked in
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>(List.of(new Person("Bo", 30), new Person("Al", 20)));
Collections.sort(people); // uses Comparable
people.sort(Comparator.comparing(p -> p.name)); // Comparator, external alternative order
System.out.println(people.get(0).name);
}
}
Login to try C/C++/Java/PHP code in the editor
Shallow Copy vs Deep Copy
A shallow copy duplicates only the top-level object and its direct field references, so nested objects are still shared between the original and the copy. A deep copy recursively constructs entirely new nested objects too, so changes to one copy's inner state never leak into the other.
Example: Shallow Copy vs Deep Copy
public class Main {
static class Address { String city; Address(String city) { this.city = city; } }
static class Person {
Address address;
Person(Address address) { this.address = address; }
Person shallowCopy() { return new Person(this.address); } // shares the same Address
Person deepCopy() { return new Person(new Address(this.address.city)); } // new nested object
}
public static void main(String[] args) {
Person original = new Person(new Address("Delhi"));
Person shallow = original.shallowCopy();
Person deep = original.deepCopy();
System.out.println(original.address == shallow.address);
System.out.println(original.address == deep.address);
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 19 topics to unlock
0/19 topics done
Complete these topics first:
- Java Reflection API
- Java Annotations Advanced
- Java Garbage Collection
- Java Memory Management
- Java Performance Optimization
- Java Advanced Interview Questions
- Java CompletableFuture
- Java Atomic Classes
- Java Locks & Semaphores
- Java Concurrent Collections
- Java Cryptography Basics
- Java Hashing (MD5, SHA)
- Java SSL & HTTPS
- Java Logging (Log4j/SLF4J)
- Java Serialization Advanced
- Java Interview Questions Advanced
- Java Connection Pooling
- Java Test Driven Development
- Java Integration Testing