Interview replay
Full round replay — the singleton
Timed verbal replay with pass/fail criteria per follow-up.
How to run this
The opener
“How do you implement a thread-safe singleton?”
Budget: 45 seconds. Going long here is itself a fail signal.
Follow-ups
1. “What is wrong with the lazy null check?”
Testing: Naming the pattern, not just the symptom.
Scoring
Pass: Check-then-act — two threads can both see null and both construct. It can only happen once per JVM, at startup, which is why it survives testing and review.
Fail: Says it is fine because assignment is atomic.
2. “Why does double-checked locking need volatile?”
Testing: Ordering versus visibility.
Scoring
Pass: Without it the write publishing the reference can be reordered ahead of the writes initialising the object, so another thread sees a non-null reference to a half-built instance.
Fail: Says volatile is an optimisation, or that the second null check is enough.
3. “How does the holder class avoid synchronization?”
Testing: Do they know where the guarantee comes from?
Scoring
Pass: The nested class is initialised on first reference and the JVM guarantees class initialisation runs once with correct publication. The lock is the JVM's, not yours.
Fail: Thinks it is lazy by luck, or that static means thread-safe generally.
4. “Can reflection break it?”
Testing: The door most candidates have never tried.
Scoring
Pass: Yes — setAccessible(true) on the private constructor gives a second instance, for every class-based form. Constructor.newInstance refuses enums with 'Cannot reflectively create enum objects'.
Fail: Believes a private constructor prevents it.
5. “What happens when a singleton is serialized and read back?”
Testing: Silent duplication.
Scoring
Pass: A new object, every round trip, with no error. Add readResolve returning the instance. Enums are deserialized by name so identity holds with nothing extra.
Fail: Assumes deserialization returns the existing instance.
6. “So why is the enum recommended?”
Testing: Can they summarise the trade?
Scoring
Pass: It is the only form that is thread-safe, reflection-proof and serialization-proof at once, with no code from you. It cannot extend a class, which is the cost.
Fail: Says it is just a shorter syntax.
7. “Is a Spring singleton bean the same thing?”
Testing: The scope distinction and why it matters.
Scoring
Pass: No — one per application context, not per JVM. And it is an ordinary object, so it can be constructed in a test with stubs and replaced by configuration.
Fail: Treats them as equivalent.
8. “How would you test code that calls Config.get()?”
Testing: The real objection to the pattern.
Scoring
Pass: With difficulty — it is global state you cannot substitute, and it carries whatever one test did into the next. The honest answer is that it should be injected instead.
Fail: Suggests reflection or a static setter without acknowledging why that is needed.
9. “Your singleton is constructed perfectly. What have you not established?”
Testing: Construction versus use.
Scoring
Pass: That using it is safe. A public mutable map or a count++ method on a process-wide object is shared mutable state whatever created it. The pattern addresses construction only.
Fail: Considers the job done once one instance is guaranteed.