Interview replay
Full round replay — the memory model
Timed verbal replay with pass/fail criteria per follow-up.
How to run this
The opener
“What is the happens-before relationship?”
Budget: 45 seconds. Going long here is itself a fail signal.
Follow-ups
1. “Does it mean A executes before B in time?”
Testing: The misconception the name creates.
Scoring
Pass: No. It is a visibility guarantee between two actions. Clock order across threads implies nothing, which is why a sleep is never a fix.
Fail: Treats it as an ordering-in-time statement.
2. “What happens when there is no edge between a write and a read?”
Testing: Do they say 'stale briefly' or 'no guarantee'?
Scoring
Pass: There is no guarantee at all — the read may never observe the write. Not late, not eventually. The JIT can hoist the read out of a loop entirely.
Fail: Says the reader sees an old value for a short time.
3. “Name the edges you actually use.”
Testing: Breadth beyond volatile and synchronized.
Scoring
Pass: Program order; releasing and acquiring the same monitor; a volatile write and its later reads; Thread.start() and Thread.join(); final fields at the end of a constructor; and every java.util.concurrent handoff — latches, futures, blocking queues.
Fail: Only names volatile and synchronized.
4. “A field is written before thread.start() and read inside the thread. Does it need volatile?”
Testing: Whether they can say no.
Scoring
Pass: No. start() is an edge, so everything before it is visible in the new thread. Adding volatile changes nothing except suggesting the author was unsure.
Fail: Adds volatile to be safe, with no reason.
5. “A producer writes five plain fields then counts down a latch. Are they visible after await()?”
Testing: Transitivity in their own words.
Scoring
Pass: Yes. The writes happen-before the countDown by program order, that happens-before await returning, and that happens-before the reads. One edge carries all five, and the latch does not know they exist.
Fail: Says only the latch's own state is covered.
6. “What does final guarantee, and when does it not?”
Testing: The freeze action and its one hole.
Scoring
Pass: A final field set in a constructor is visible fully initialised to any thread that sees the reference, with no synchronization. It fails if the constructor leaks `this`, because the object became reachable before the freeze.
Fail: Says final only prevents reassignment.
7. “The field is volatile and the object is immutable, but describe() reads it twice. Safe?”
Testing: The trap that survives both fixes.
Scoring
Pass: No. Two reads can straddle a write and return fields from two different objects. Neither volatile nor immutability makes two reads atomic — read once into a local.
Fail: Says it is safe because the field is volatile.
8. “How do you publish a config object safely with no lock on the read path?”
Testing: The reusable pattern.
Scoring
Pass: Immutable type with final fields, build the replacement completely, assign it to a volatile reference in one write, and read that reference once into a local.
Fail: Synchronizes the readers, or makes the individual fields volatile.
9. “How would you prove the code has no visibility bug?”
Testing: Whether they know testing cannot do it.
Scoring
Pass: By naming the edge between every cross-thread write and read. If you cannot name one, there isn't one. jcstress exists for the empirical direction because ordinary tests cannot reach these interleavings.
Fail: Would write a load test and trust a green result.