Data Race Definition
Fast recall
Quick revision
Core answer
Whether you understand Data Race Definition 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 definition's conditions (all must hold): concurrent access, shared memory, at least one write, no happens-before ordering.
The demonstration — verified:
var buggy int
for i := 0; i < 100; i++ {
go func() { buggy++ }() // no lock
}
// result: 90, not 100 (verified — 10 updates lost)Each counter++ is three operations (read, add, write); goroutines interleaved and overwrote results.
Why Go's data races are scary: the Go memory model doesn't leave the value unspecified — a data race is formally UNDEFINED BEHAVIOR. Torn reads, memory corruption, sporadic crashes. 'It usually works' is not a defense.
The fixes:
- 1Mutex — one at a time
- 2Channel — share memory by communicating
- 3Atomic — lock-free for simple operations
- 4Don't share — goroutine-local, communicate copies
The detection: go -race. The discipline: -race in every test run.
Data Race Definition
Direct Answer
Two goroutines, same memory, at least one WRITE, no synchronization between them. Result: undefined behavior — lost updates, torn reads, crashes. Detect with -race; fix with mutex, channels, or atomics.
Deep Dive & Architecture
The Go memory model's frame: the spec defines happens-before edges (synchronization creates them); an access pair with no edge is a race, and the behavior is undefined. The compiler optimizes assuming race-free — a race violates those assumptions beyond 'lost update.'
The lost-update arithmetic: buggy++ is load, add, store. A and B both load 5, both compute 6, both store 6 — two increments, one result. Over 100 attempts with ~10 overlaps: 90 (scheduler-dependent — different results across runs).
The three fix families by their ordering mechanism:
- Mutex: locks create happens-before edges — everything inside the section is ordered.
- Channel: send happens-before receive — the data is visible after receive. Ownership transfer is total.
- Atomic: every atomic op is an happens-before edge with every other atomic on the same variable.
The pairing: the model defines what counts as a race (the edges), the detector finds pairs without edges, the fixes create the missing edges. One framework, three tools.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Data Race Definition in a real project?
- How would you compare Data Race Definition with an alternative?
- What is a common mistake when using Data Race Definition?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.