Defer Ordering Scenario
Fast recall
Quick revision
Core answer
Whether you understand Defer Ordering Scenario beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The scenario, written out:
func f() {
defer fmt.Println("1st registered")
defer fmt.Println("2nd registered")
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered:", r)
}
}()
// Output order:
// 1. "2nd registered" — LIFO
// 2. "1st registered"
// 3. "recovered: <panic>"
// (recovery happens in the LAST defer — the first to run)
panic("boom")
}Wait — the recovery defer is LAST registered, so it runs FIRST. The order: recovery defer (stops the panic), then "2nd", then "1st". The recovery catch happens before the other defers run — the unwind stops at the recovering defer, and the remaining defers in the stack still execute as normal returns.
The precise sequence on panic:
- 1The panic unwinds: deferred calls pop LIFO
- 2The LAST-registered defer (typically the recover wrapper) runs FIRST
- 3recover() returns the panic value — unwinding stops
- 4The deferred function returns — f continues returning normally
- 5Any remaining defers (earlier-registered ones) still run — they're in the normal return path
The interview gotcha: if the recover defer was registered BEFORE the resource defers (reversed order), the resources close BEFORE the recover runs — the ordering is structural, not magical.
Defer Ordering Scenario
Direct Answer
Panic starts unwinding: defers run LIFO (last first). If a defer calls recover, unwinding stops and the function returns normally. The recover must be in a defer, and in the SAME goroutine.
Deep Dive & Architecture
The defer stack and panic's interaction, mechanically: defers are a linked list per goroutine (g._defer). Panic walks this list — calling each deferred function and popping it. A defer that calls recover() sets the panicking flag to recovered — subsequent unwinding stops; the function returns normally. The remaining defers (already-popped-to but not yet run) execute as part of that normal return.
The recover-goroutine constraint: panic and recover are per-goroutine — the defer that recovers must be on the panicking goroutine. A helper goroutine cannot recover the main goroutine's panic; an unrecovered panic in ANY goroutine crashes the program.
The real-world pattern (where this scenario lives): an HTTP handler defer-recovers, converts to a 500, and logs the stack — each goroutine (each request) has its own boundary. The server survives per-request panics because of this exact ordering.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- How would you compare Defer Ordering Scenario with an alternative?
- What is a common mistake when using Defer Ordering Scenario?
- When would you use Defer Ordering Scenario in a real project?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.