Course contents

The can't-skip Java interview checklist

The master list of 73 Java interview must-says across 14 areas, each with the exact fact an interviewer is waiting for and links to its revision sheet and full lesson, prioritised by how often it's asked.

FreeMust know for interviewsLesson27 min readCoreReviewed Oct 2026 · Java 21
On this page
  1. Priority at a glance
  2. 1. Core Java and OOP
  3. 2. Strings
  4. 3. equals and hashCode
  5. 4. Exceptions (can't-miss)
  6. 5. Collections and HashMap
  7. 6. Generics
  8. 7. Concurrency basics (can't-miss)
  9. 8. The Java memory model (can't-miss)
  10. 9. Locks, atomics, executors and CompletableFuture
  11. 10. Concurrent collections
  12. 11. JVM memory, class loading and GC
  13. 12. Java 8 to 21 features
  14. 13. Design patterns and SOLID
  15. 14. Production and debugging
  16. How to say it in the interview

✅ What is the can't-skip checklist?

It's the list I'd hand a friend who has a Java interview in two weeks: 73 items, grouped into 14 areas, each with the exact sentence the interviewer is waiting to hear. Every item links to its Last-Mile revision sheet for the why, and to the full lesson for the depth. Think of it as a pilot's pre-flight checklist: experienced pilots still run it, because the cost of missing one line is far higher than the 10 minutes it takes.

For this lesson, we'll go area by area through every item that comes up again and again in Java interviews, ordered roughly by how often it's asked. I've written each must-say as the fact itself, not a topic name, because "know HashMap" is useless as a checklist item and "load factor 0.75, resize doubles, treeify at 8 when the table is 64+" is something you can test. Three areas carry a can't-miss flag: exception handling, the Java memory model and multithreading. Those are where I've seen the most otherwise strong candidates lose an offer.

Below the line (out of scope)

The 30-second answer

If you can say every item on this page out loud in under 60 seconds each, you're covered for the Java part of almost any interview loop. The heaviest areas are concurrency (threads, synchronized, volatile, happens-before, thread pools, ConcurrentHashMap) and collections (HashMap internals, equals/hashCode), followed by exceptions, core OOP, the JVM and GC, Java 8 to 21 features, and design patterns. Tick an item only when you've said it cleanly without notes, re-test it 2 and 6 days later, and spend your last week on whatever is still unticked rather than re-reading what you know.

What you’ll learn

  • See every can't-skip Java interview topic in one place, grouped into 14 areas
  • Know the exact must-say fact for each item, not only its name
  • Prioritise by how often each area is asked, with concurrency, the JMM and exceptions first
  • Spot the two classic bugs on sight: double-checked locking without volatile and the mutable HashMap key
  • Use the list as a last-week self-test that links straight to the right revision sheet and full lesson

Interview radar

Asked very often: HashMap internals, equals and hashCode, checked versus unchecked exceptions, synchronized versus volatile, ThreadPoolExecutor parameters, streams and Optional. Senior rounds probe: happens-before and safe publication, ConcurrentHashMap internals, CompletableFuture composition, virtual threads and pinning, G1 versus ZGC, how you'd find a memory leak. Production angle: swallowed exceptions, unbounded executor queues, mutable map keys, and reading a thread dump during an incident.

01Priority at a glance

Not every area deserves the same time. The table below is the ranking I'd use, with the days each area gets in the 30-day plan and the 15-day sprint. If you're short on time, work top to bottom and stop where the clock stops.

Area How often asked Days (30 / 15) Revision sheet
Multithreading, JMM, locks, executors, concurrent collections Very high, deepest probes 7 / 4 Multithreading and the JMM
Collections, HashMap, generics Very high 5 / 2 Collections and HashMap
Exceptions High, every level 2 / 1 Exceptions
Core Java, OOP, strings, equals/hashCode High, usually the opener 2 / 1 Core Java and OOP
Java 8 to 21 High for streams, medium for 17 to 21 2 / 1 Java 8 to 21
JVM memory, GC, production debugging Medium; very high for senior 3 / 1 JVM memory and GC
Design patterns and SOLID Medium, often inside coding 2 / 1 Design patterns and SOLID
Everything, rapid-fire Your last two days 2 / 2 The final 48 hours

The table hides one thing: how the mix shifts with seniority. The heat map below shows how often each area comes up by round type. Notice how the senior column turns red for concurrency, the JMM, the JVM and debugging, and the production column for the JVM and debugging, while the phone-screen column is dominated by core Java, equals/hashCode, exceptions and collections.

Fig. 1

A heat map with 14 Java areas as rows and four interview types as columns: phone screen, mid-level loop, senior loop and production round; core Java, equals and hashCode, exceptions and collections are almost always asked from the phone screen onward, while the memory model, executors, JVM and production debugging become almost always asked only in senior and production rounds

A heat map with 14 Java areas as rows and four interview types as columns: phone screen, mid-level loop, senior loop and production round; core Java, equals and hashCode, exceptions and collections are almost always asked from the phone screen onward, while the memory model, executors, JVM and production debugging become almost always asked only in senior and production rounds
Tip

Each item below has two links. Revise opens the Last-Mile sheet with the must-say and the why. Full lesson opens the deep lesson where it's published, or the module overview where it's still being written. Open the full lesson only when the sheet isn't enough.

021. Core Java and OOP

Priority: high, and almost always the first 10 minutes. These are quick to fix and expensive to fumble, because a shaky answer here colours how the interviewer hears everything after.

  • Pass-by-value: Java always passes by value; for objects, the value copied is the reference, so a method can mutate the object but reassigning the parameter never changes the caller's variable. Revise · Full lesson
  • Overloading vs overriding: overloading is chosen at compile time from the static argument types; overriding is chosen at runtime from the object's actual class. static, private and final methods are not overridden; a static method with the same signature hides the parent's. Revise · Full lesson
  • Abstract class vs interface: an abstract class can hold instance state and constructors but you extend only one; an interface has no instance state, a class implements many, and since Java 8 and 9 it can have default, static and private methods. Interface for a capability, abstract class for a shared skeleton with state. Revise · Full lesson
  • static and final: static means one copy per class (per class loader), not per object; final on a variable means assigned once (the referenced object can still change), on a method means no override, on a class means no subclass. Revise · Full lesson
  • Immutable class recipe: final class, private final fields, no setters, defensive copies of mutable inputs and outputs, and don't leak this from the constructor. You get thread safety and safe hash keys for free. Revise · Full lesson
  • Composition over inheritance: inheritance couples you to the parent's implementation, so a parent change can break subclasses (the fragile base class problem). Use extends only for a true is-a that respects substitution; otherwise hold the object and delegate. Revise · Full lesson
  • Autoboxing and the Integer cache: Integer.valueOf caches -128 to 127, so == on two boxed 127s is true and on two 128s is false; always compare boxed values with equals. Unboxing a null throws NullPointerException. Revise · Full lesson

032. Strings

Priority: high on phone screens. Interviewers use strings to check whether you understand references, immutability and memory in one small topic.

  • Why String is immutable: so strings can be shared safely in the pool, cache their hashCode, be used as map keys, be shared across threads without locks, and not be changed after a security check (file paths, class names, URLs). Revise · Full lesson
  • String pool and ==: literals are interned in the string pool, which lives on the heap since Java 7; new String("a") always creates a new object, so == compares references and equals compares characters. Revise · Full lesson
  • StringBuilder vs StringBuffer: concatenating in a loop copies the whole string each time (O(n²) characters); use StringBuilder, which is unsynchronized. StringBuffer synchronizes every method and is legacy. Since Java 9, a single a + b + c compiles to invokedynamic, but loops still need a builder. Revise · Full lesson
  • Compact strings: since Java 9, a String is backed by a byte[] plus a coder flag, using 1 byte per character for Latin-1 text and 2 for anything else, which roughly halves string memory in ASCII-heavy heaps. Revise · Full lesson

043. equals and hashCode

Priority: very high. This is the bridge between core Java and collections, and it's the topic I'd bet on appearing in any Java loop.

  • The contract: equals must be reflexive, symmetric, transitive, consistent and return false for null; equal objects must have equal hash codes, while unequal objects may collide. Revise · Full lesson
  • Override both or neither: override equals without hashCode and two equal keys land in different buckets, so HashMap.get misses and a HashSet holds "duplicates". Use the same fields in both. Revise · Full lesson
  • Mutable keys get lost: change a field used by hashCode after inserting the key and the entry stays in the old bucket, so get and remove can't find it (see the snippet below). Revise · Full lesson
  • Records and compareTo consistency: records generate equals, hashCode and toString from their components. Sorted collections use compareTo, not equals: new BigDecimal("1.0") and new BigDecimal("1.00") are two elements in a HashSet but one in a TreeSet. Revise · Full lesson

Here's the mutable-key bug in five lines. Before reading the comment, predict what the last line prints.

List<String> key = new ArrayList<>(List.of("a"));
Map<List<String>, Integer> map = new HashMap<>();
map.put(key, 1);
key.add("b");                       // hashCode of the key changes
System.out.println(map.get(key));   // null: lookup goes to a different bucket

054. Exceptions (can't-miss)

Priority: high at every level, and a favourite for judging production maturity. Exception questions start easy ("checked vs unchecked?") and turn senior fast ("where do you catch, where do you log, what happens to the interrupt flag?").

Can't-miss area

Exception handling is asked in almost every Java loop, from phone screen to senior. Get all 8 items below to green before you move on.

  • The hierarchy: Throwable splits into Error (OutOfMemoryError, StackOverflowError; don't catch these) and Exception; RuntimeException and its subclasses are unchecked, every other Exception is checked and must be caught or declared. Revise · Full lesson
  • Checked vs unchecked, with an opinion: checked for recoverable conditions the caller can act on (IOException), unchecked for programming errors (IllegalArgumentException, NullPointerException). Most modern code and frameworks prefer unchecked, partly because checked exceptions don't fit lambdas. Revise · Full lesson
  • finally semantics: finally runs after try or catch, even after a return; it doesn't run if the JVM exits (System.exit, crash, kill). A return inside finally overrides the earlier result and silently swallows any exception. Revise · Full lesson
  • try-with-resources: works with any AutoCloseable (Java 7+), closes resources in reverse declaration order, and if both the body and close() throw, the body's exception propagates with the close failure attached via getSuppressed(). Revise · Full lesson
  • Custom exceptions and chaining: name exceptions after the failure (PaymentDeclinedException), extend RuntimeException unless callers must recover, and always pass the cause (new X(msg, cause)) so the original stack trace survives. Revise · Full lesson
  • Handling in production: never swallow with an empty catch; log once at the boundary instead of log-and-rethrow at every layer; translate low-level exceptions at layer boundaries; don't catch Throwable broadly. Revise · Full lesson
  • InterruptedException: catching it clears the thread's interrupt flag, so either rethrow it or call Thread.currentThread().interrupt() to restore it; swallowing it makes threads impossible to cancel and pools impossible to shut down. Revise · Full lesson
  • Cost and overriding rules: creating an exception is expensive mainly because fillInStackTrace walks the stack, so never use exceptions for normal control flow. An overriding method may not throw new or broader checked exceptions than the method it overrides. Revise · Full lesson

065. Collections and HashMap

Priority: very high. "How does HashMap work?" is the single most common Java internals question, and the follow-ups go straight into concurrency.

  • ArrayList vs LinkedList: ArrayList gives O(1) random access and amortised O(1) append, growing by 1.5x; LinkedList is O(n) for get(i), costs an extra node object per element and has poor cache locality. LinkedList rarely wins; use ArrayDeque for queues and stacks. Revise · Full lesson
  • HashMap put and get: spread the hash with h ^ (h >>> 16), pick the bucket with (n - 1) & hash, then match by stored hash, ==, then equals. Default capacity 16 and load factor 0.75, so the first resize happens at 13 entries and doubles the table. Revise · Full lesson
  • Treeification: since Java 8, a bucket turns into a red-black tree once it holds 8 nodes and the table has at least 64 buckets (below 64 it resizes instead), and turns back into a list at 6. Worst-case lookup drops from O(n) to O(log n). Revise · Full lesson
  • Ordering: HashMap, LinkedHashMap, TreeMap: HashMap has no order and allows one null key; LinkedHashMap keeps insertion or access order (access order plus removeEldestEntry gives an LRU cache); TreeMap is a sorted red-black tree with O(log n) operations that uses compareTo. Revise · Full lesson
  • Fail-fast iterators: iterators check a modCount and throw ConcurrentModificationException on structural changes during iteration, even in one thread; it's best-effort, not a guarantee. Remove with Iterator.remove() or removeIf. Revise · Full lesson
  • HashMap is not thread-safe: concurrent puts can lose entries or corrupt the table; in Java 7, head insertion during resize could form a cycle and hang get in an infinite loop. Java 8 switched to tail insertion but is still unsafe: use ConcurrentHashMap. Revise · Full lesson
  • Unmodifiable collections: List.of and Map.of (Java 9+) are truly unmodifiable and reject null; Collections.unmodifiableList is a read-only view whose backing list can still change; Arrays.asList is fixed-size but writable through set. Revise · Full lesson

076. Generics

Priority: medium. Usually two or three questions, often as a follow-up to collections, and a good place to show you understand compile time versus runtime.

  • Type erasure: generic types exist only at compile time; at runtime List<String> and List<Integer> are the same List class, so you can't write new T(), instanceof List<String> or new T[10]. Revise · Full lesson
  • Invariance and PECS: List<String> is not a List<Object>. Use ? extends T when you only read from a structure (producer) and ? super T when you only write to it (consumer): Producer Extends, Consumer Super. Revise · Full lesson
  • Arrays vs generics: arrays are covariant and reified, so Object[] a = new String[1]; a[0] = 1; compiles and throws ArrayStoreException at runtime; generics are invariant and catch the same mistake at compile time. Revise · Full lesson

087. Concurrency basics (can't-miss)

Priority: very high. This is where interviewers separate "I've used threads" from "I understand threads", and it's the area with the most follow-up depth.

Can't-miss area

Multithreading is the most heavily weighted area in the whole plan. Sections 7 to 10 together are 20 items; aim to have all of them green by mock interview 2.

  • Creating threads, start vs run: Runnable returns nothing; Callable returns a value and can throw checked exceptions. start() creates a new thread that calls run(); calling run() directly runs on the current thread. In real code, submit tasks to an executor instead of new Thread. Revise · Full lesson
  • Thread states: NEW, RUNNABLE, BLOCKED (waiting to enter a monitor), WAITING, TIMED_WAITING, TERMINATED. A thread blocked on socket I/O shows as RUNNABLE, which surprises people reading thread dumps. Revise · Full lesson
  • synchronized: acquires the monitor of the object (or of the Class for static methods), gives mutual exclusion and visibility (unlock happens-before the next lock of the same monitor), and is reentrant. Revise · Full lesson
  • wait, notify, sleep: wait and notify require holding the monitor (else IllegalMonitorStateException); wait releases the lock, sleep doesn't. Always call wait inside a while loop that rechecks the condition, because of spurious wakeups, and prefer notifyAll. Revise · Full lesson
  • Race conditions: count++ is three steps (read, add, write), and check-then-act (if (!map.containsKey(k)) map.put(k, v)) is two; both lose updates under contention. Fix with a lock, an atomic operation (AtomicInteger, computeIfAbsent) or by not sharing the state. Revise · Full lesson
  • Deadlock: needs all four conditions: mutual exclusion, hold and wait, no preemption, circular wait. Prevent it with a global lock ordering or tryLock with a timeout; find it with jstack, which prints "Found one Java-level deadlock". Revise · Full lesson

098. The Java memory model (can't-miss)

Priority: high for mid-level, very high for senior. Few candidates can explain it cleanly, which is exactly why it's such a strong signal when you can.

Can't-miss area

When I ask "why does this need volatile?", I want happens-before in the first sentence. Practise the five items below until that's automatic.

  • What the JMM is: the rules in JLS chapter 17 for when a write in one thread is guaranteed visible to a read in another. Without a happens-before edge, the compiler and CPU may reorder or cache, and a thread can see a stale value forever. Revise · Full lesson
  • Happens-before rules: program order within a thread; unlock of a monitor before a later lock of the same monitor; a volatile write before a later read of the same variable; Thread.start() before the started thread's actions; a thread's actions before another thread's join() returns. The relation is transitive. Revise · Full lesson
  • volatile: guarantees visibility and ordering, not atomicity. Good for a stop flag or publishing a fully built object; count++ on a volatile field still loses updates. Revise · Full lesson
  • Double-checked locking: the field must be volatile, because instance = new X() is allocate, construct, assign, and without volatile the assignment can become visible before construction finishes, so another thread sees a half-built object. Simpler alternatives: the holder idiom or an enum. Revise · Full lesson
  • final fields and safe publication: final fields are guaranteed visible once the constructor completes, provided this didn't escape during construction. Publish shared objects safely through a static initializer, a volatile or final field, a lock, or a concurrent collection. Revise · Full lesson

This is the version of double-checked locking I'd expect you to write on a whiteboard without hesitation:

public final class Config {
    private static volatile Config instance;   // volatile is the whole point

    public static Config get() {
        Config local = instance;               // one volatile read on the fast path
        if (local == null) {
            synchronized (Config.class) {
                local = instance;
                if (local == null) {
                    instance = local = new Config();
                }
            }
        }
        return local;
    }
}

109. Locks, atomics, executors and CompletableFuture

Priority: very high for mid-level and senior. Executors are where interviewers check whether you've run concurrent code in production, not only read about it.

  • ReentrantLock vs synchronized: ReentrantLock adds tryLock with a timeout, lockInterruptibly, optional fairness and multiple Conditions, but you must unlock() in finally. ReadWriteLock allows many readers or one writer. Default to synchronized unless you need one of those features. Revise · Full lesson
  • Atomics and CAS: AtomicInteger uses a compare-and-set retry loop instead of a lock. Watch for the ABA problem (AtomicStampedReference fixes it), and use LongAdder for hot counters, since it spreads updates across cells and sums on read. Revise · Full lesson
  • ThreadPoolExecutor task flow: below corePoolSize a new thread is created; otherwise the task is queued; if the queue is full, threads are added up to maximumPoolSize; beyond that the RejectedExecutionHandler runs (default AbortPolicy throws, CallerRunsPolicy gives back-pressure). Revise · Full lesson
  • Executors factory traps and sizing: newFixedThreadPool uses an unbounded LinkedBlockingQueue, so a backlog grows until OutOfMemoryError; newCachedThreadPool has no thread limit. Prefer an explicit pool with a bounded queue, sized near the core count for CPU-bound work and cores × (1 + wait/compute) for I/O-bound work. Revise · Full lesson
  • CompletableFuture: supplyAsync without an executor runs on ForkJoinPool.commonPool() (cores minus 1 threads), so pass your own executor for blocking I/O. thenApply maps a value, thenCompose chains a call that returns another future, thenCombine joins two; handle failures with exceptionally or handle. Revise · Full lesson
  • Virtual threads (Java 21): JVM-managed threads mounted on a small pool of carrier threads, so blocking I/O unmounts them instead of holding an OS thread; millions are feasible versus a few thousand platform threads. Don't pool them (limit with a Semaphore), they don't speed up CPU-bound work, and in Java 21 blocking inside synchronized pins the carrier. Revise · Full lesson

1110. Concurrent collections

Priority: high for senior. ConcurrentHashMap in particular is the natural follow-up to every HashMap question.

  • ConcurrentHashMap: since Java 8 there are no segments; an empty bin is filled with a CAS and a non-empty bin is locked with synchronized on its first node, while reads take no lock. It rejects null keys and values (so get returning null always means absent), offers atomic compute, merge and putIfAbsent, and has weakly consistent iterators that never throw ConcurrentModificationException. Revise · Full lesson
  • CopyOnWriteArrayList vs synchronized wrappers: copy-on-write copies the whole array on every write, which suits read-mostly lists such as listeners and is terrible for write-heavy ones. Collections.synchronizedMap uses one lock for everything, and you must synchronize manually while iterating. Revise · Full lesson
  • BlockingQueue: put blocks when full and take blocks when empty, which gives you producer-consumer for free. ArrayBlockingQueue is bounded with one lock; LinkedBlockingQueue is optionally bounded (default capacity Integer.MAX_VALUE) with separate put and take locks. Revise · Full lesson

1211. JVM memory, class loading and GC

Priority: medium for juniors, very high for seniors. Expect "what's on the heap versus the stack?" at any level and "how would you tune or choose a GC?" at senior level.

  • Memory areas: the heap holds objects and is shared and garbage-collected; each thread has its own stack of frames (-Xss, 1 MB by default on 64-bit Linux); class metadata lives in Metaspace in native memory, which replaced PermGen in Java 8; plus the PC register, native stacks and the code cache. Revise · Full lesson
  • Which error means what: Java heap space (too many live objects or a leak), Metaspace (class loader leak), GC overhead limit exceeded (over 98% of time in GC recovering under 2% of heap), unable to create native thread (OS thread limit), and StackOverflowError (deep or infinite recursion). Each points to a different fix. Revise · Full lesson
  • Class loading: bootstrap, then platform (Java 9+, formerly extension), then application loader, with parent-first delegation so nobody can replace java.lang.String. A class is loaded, linked (verify, prepare, resolve) and initialized; static initialization runs once and is thread-safe, which the holder idiom relies on. Revise · Full lesson
  • How GC decides what's garbage: anything not reachable from GC roots (thread stacks, static fields, JNI references) is garbage, which is why cycles are collected and Java doesn't use reference counting. Most objects die young, so the heap is generational: young collections are frequent and cheap, old collections are rarer and costlier. Revise · Full lesson
  • Choosing a collector: G1 is the default since Java 9, region-based with a 200 ms pause target (-XX:MaxGCPauseMillis); ZGC keeps pauses under about 1 ms even on very large heaps (generational with -XX:+ZGenerational in Java 21); Parallel maximises throughput for batch jobs. Start with G1, move to ZGC when tail latency matters. Revise · Full lesson
  • Memory leaks in Java: a leak is an unintended reference: static collections, caches without eviction, listeners never removed, ThreadLocal values in pooled threads, inner classes holding their outer instance. Know the four reference strengths: strong, soft, weak, phantom. Revise · Full lesson
  • Heap sizing in containers: the JVM reads container limits (since Java 10) and by default caps the heap at 25% of available memory, which wastes most of a container. Set -XX:MaxRAMPercentage to around 70 to 75, leaving room for Metaspace, thread stacks and direct buffers. Revise · Full lesson

1312. Java 8 to 21 features

Priority: high for streams and lambdas, which appear in nearly every coding round; medium for 17 to 21 features, which earn you credit for being current.

  • Lambdas and functional interfaces: a lambda implements an interface with exactly one abstract method (Function, Supplier, Consumer, Predicate, BiFunction); captured local variables must be effectively final. Default methods, added in Java 8, let interfaces such as Collection gain stream() without breaking implementors. Revise · Full lesson
  • Streams: lazy, single-use pipelines of intermediate operations (map, filter) that run only when a terminal operation (collect, forEach) is called. map is one-to-one, flatMap flattens; Collectors.toMap throws IllegalStateException on duplicate keys unless you pass a merge function; parallel streams share the common pool, so avoid them for I/O. Revise · Full lesson
  • Optional: a return type for "may be absent", not for fields, parameters or collections. orElse(x) always evaluates x, orElseGet(supplier) evaluates only when empty; prefer orElseThrow to a bare get(). Revise · Full lesson
  • Records, sealed types, pattern matching: records (Java 16) are immutable data carriers with generated constructor, accessors, equals, hashCode and toString; sealed types (Java 17) restrict subclasses via permits; pattern matching for switch and record patterns (Java 21) give exhaustive switches over a sealed hierarchy with no default. Revise · Full lesson
  • Versions and the smaller features: LTS releases are 8, 11, 17, 21 and 25. Know var (Java 10, locals only), switch expressions (14), text blocks (15) and sequenced collections (21, adding getFirst, getLast and reversed). Revise · Full lesson

1413. Design patterns and SOLID

Priority: medium. Usually one or two direct questions, plus credit for applying them naturally while you code.

  • Singleton, three ways: an enum singleton is the safest (serialization and reflection proof); the holder idiom gives lazy, thread-safe creation through class initialization; double-checked locking works only with volatile. Mention that singletons hurt testability. Revise · Full lesson
  • Builder and factories: a builder handles many optional parameters and produces an immutable object; static factory methods (List.of, Integer.valueOf) have names and can cache instances; abstract factory creates families of related objects. Revise · Full lesson
  • Strategy, observer, decorator, proxy: strategy swaps an algorithm (a Comparator lambda is one); observer pushes events to listeners; decorator wraps to add behaviour (BufferedInputStream); proxy stands in front of an object (Spring AOP, java.lang.reflect.Proxy). Revise · Full lesson
  • SOLID with one example each: Single responsibility (one reason to change), Open/closed (extend without editing), Liskov (a subtype must be usable wherever the parent is: the square and rectangle problem), Interface segregation (small interfaces), Dependency inversion (depend on abstractions, inject through constructors). Revise · Full lesson

1514. Production and debugging

Priority: low for juniors, very high for seniors. A senior candidate who can't describe reading a thread dump or a heap dump raises a flag, however good the theory was.

  • Thread dumps: take them with jcmd <pid> Thread.print or jstack, three dumps 5 to 10 seconds apart. Look for many threads BLOCKED on the same lock, the deadlock section, or all pool threads stuck in the same frame. For high CPU, map the hot OS thread id from top -H to the hex nid in the dump. Revise · Full lesson
  • Heap dumps: run with -XX:+HeapDumpOnOutOfMemoryError in production, or take one with jcmd <pid> GC.heap_dump; open it in a heap analyser and follow the biggest retained sizes in the dominator tree to the reference holding them. Revise · Full lesson
  • GC logs, JFR and flame graphs: enable -Xlog:gc* (unified logging since Java 9) to correlate latency spikes with pauses; JDK Flight Recorder records allocation, locks and hot methods at about 1 to 2% overhead; a flame graph shows where CPU time goes. Revise · Full lesson
  • One story of your own: have a 90-second story of a real incident (a leak, contention or deadlock, a swallowed exception) told as signal, diagnosis, fix, and what you changed afterwards. Interviewers weigh this more than any definition. Revise · Full lesson
Where candidates slip

Many candidates tick an item because the name looks familiar ("volatile, yes, I know that one"). This is frequently a mistake because the interviewer isn't asking whether you've heard of it; they're waiting for the specific fact in bold above. If you can't say the must-say sentence nearly word for word, it isn't ticked.

16How to say it in the interview

The checklist is most useful in your last week, when there's no time for new material. Here's how I'd use it. Seven days out, run every unticked item and every item you ticked more than a week ago, out loud, 60 seconds each. Five days out, open the revision sheet only for what failed. Two days out, switch to The final 48 hours and stop opening full lessons altogether.

When I ask any question on this list, I'm listening for the must-say fact first, then the why, then where it breaks. Candidates who lead with the fact sound sure of themselves; candidates who build up to it through background sound like they're searching. The bolded facts above are written to be your first sentence.

In the interview

"A HashMap is an array of buckets. On put, it spreads the key's hashCode with h ^ (h >>> 16), picks a bucket with (n - 1) & hash, and stores the entry there, matching existing keys by hash and then equals. The default capacity is 16 with a 0.75 load factor, so it doubles the table after 12 entries, and since Java 8 a bucket with 8 or more entries becomes a red-black tree once the table has 64 buckets. Two things break it in practice: overriding equals without hashCode, and mutating a key after inserting it. And it isn't thread-safe, so under concurrency I'd use ConcurrentHashMap, which CASes empty bins and locks only the bin it's writing to."

On the whiteboard

  • 73 items, 14 areas; tick only after 60 s out loud
  • Most days: concurrency + JMM (7), collections (5)
  • Can't-miss: exceptions, JMM, multithreading
  • Lead with the must-say, then why, then the trap
  • Last week: re-test unticked → sheet → final 48 h
  • Two snippets to write blind: DCL with volatile, mutable key bug

Interview questions for this topicComing soon

Further reading (8)