How to Pass a Java Interview: Top Advanced-Level Questions
An interview for an advanced Java developer position (Middle/Senior) is not just a syntax check. Interviewers want to see a deep understanding of the JVM internals, multithreading, garbage collector algorithms, and the nuances of the standard library. In this article, we will break down the most common and difficult questions that will help you confidently pass a technical interview.
1. Multithreading and Synchronization: From volatile to Lock
An advanced Java interview almost always starts with questions about multithreading. You need not only to know the synchronized keyword but also to understand how volatile, AtomicInteger, ReentrantLock work and what happens-before is.
Question: What is the difference between synchronized and ReentrantLock?
The key difference is flexibility. synchronized is a lock at the object monitor level. ReentrantLock provides advanced capabilities: the ability to interrupt a thread's wait (lockInterruptibly()), a non-blocking lock attempt (tryLock()), and support for multiple conditions (Condition).
// Example of using ReentrantLock with Conditionimport java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.Condition;
public class BlockingQueueExample { private final ReentrantLock lock = new ReentrantLock(); private final Condition notFull = lock.newCondition(); private final Condition notEmpty = lock.newCondition(); private final Object[] items = new Object[10]; private int putIndex, takeIndex, count;
public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) { notFull.await(); // wait until space becomes available } items[putIndex] = x; if (++putIndex == items.length) putIndex = 0; count++; notEmpty.signal(); // signal that an element has been added } finally { lock.unlock(); } }
public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) { notEmpty.await(); // wait until an element appears } Object x = items[takeIndex]; if (++takeIndex == items.length) takeIndex = 0; count--; notFull.signal(); // signal that space has become available return x; } finally { lock.unlock(); } }}Question: How does the volatile keyword work?
volatile guarantees that reading and writing a variable occurs directly from main memory, bypassing the CPU cache. This ensures visibility of changes for all threads but does not guarantee atomicity (for example, the increment count++ still requires synchronization).
You should also remember about happens-before: a write to a volatile variable happens before any subsequent read of the same variable from another thread.
2. Java Memory Model (JMM) and Garbage Collector
Understanding how the JVM manages memory is a mandatory requirement for a Senior developer. Interviewers often ask about different generations (Young/Old Generation), types of garbage collectors, and JVM tuning.
Question: What types of Garbage Collector exist in Java 17?
Modern Java (17+) supports several GCs:
- G1GC (Garbage First) — the default GC. It divides the heap into regions and collects garbage in regions with the largest number of dead objects.
- ZGC (Z Garbage