Day 070 — Week 2 Review Day¶
Month 3 · Week 2 · ⬅ Day 069 · Day 071 ➡ · Journal index
📋 Full structured review:
week-2-review.md
🎯 Learning Objective¶
Consolidate Week 2 of concurrency (the sync toolbox + the memory model) via closed-book recall and re-run every example and exercise under the race detector.
📚 Topics¶
- Recap:
sync.Mutex/RWMutex,WaitGroupin depth,sync.Once&sync.Pool,sync/atomic+ CAS, the-racedetector, the Go memory model & happens-before.
📝 Notes¶
- Re-ran each example (
go run ./examples/month-03/{mutex,waitgroup,once-pool,atomic}) andgo test -race ./exercises/month-03/week-2/...— safecounter, oncecache, atomicgate all green, no races. - Ran
gofmt -l .andgo vet ./...— no copied locks/atomics, noPrintfissues. - Reimplemented the CAS
storeMaxloop and the once-per-key cache from memory (active recall); got theLoadOrStore+ per-keyOncepairing right on the second try.
🧠 Closed-Book Recall (Week 2)¶
- Q: When
RWMutexoverMutex?A
When reads vastly outnumber writes — many RLock holders run concurrently; otherwise the bookkeeping can make it slower than a plain Mutex.
2. Q: Why Add before go? A
Add inside the goroutine races with Wait, which may see a zero counter and return early.
3. Q: Does once.Do(f) retry if f panics? A
No — the call is consumed; f never runs again. Once is wrong for retry-on-failure init.
4. Q: Why copy data out of a pooled buffer before Put? A
After Put, another goroutine can Get+Reset it and overwrite the backing array, corrupting any view you still hold.
5. Q: What does CompareAndSwap(old,new) return and how is it used? A
true if it set new (current still equalled old), else false; loop and retry on false for lock-free updates.
6. Q: Is a clean go test -race a proof of race-freedom? A
No — it's a dynamic detector; it only flags races that actually occurred this run.
7. Q: A data race is "a stale read" — true? A
False — it's undefined behaviour; the program has no guaranteed semantics. Add a happens-before edge.
🐛 Mistakes / Themes This Week¶
- Copied a struct holding a
Mutex/atomic →go vet"copies lock value" (Days 064, 067). - Returned a pooled buffer's
Bytes()afterPut(Day 066). - Used a plain
boolflag to publish data across goroutines — no happens-before edge (Day 069).
🪶 Feynman Reflection¶
I now have the second half of the concurrency toolbox: when sharing memory in place beats passing it over a channel, guard it — a Mutex/RWMutex for multi-field state, an atomic for a single counter/flag, Once for run-once init, Pool for recycling, all underwritten by the memory model's happens-before edges and verified with -race.
🕳️ Knowledge Gaps Carried Forward¶
context.Contextfor cancellation/deadlines (next week).- Mutex/CAS contention profiling and the crossover where each wins (optimisation month).
✅ Summary¶
Week 2 sync primitives + memory model consolidated; all examples and exercises formatted, vetted, and -race-clean. Confidence on mutex/atomic/once now 3–⅘.
⏭️ Next Steps¶
- Week 3:
context.Context— cancellation, deadlines,WithTimeout/WithCancel, and propagation through call chains.
| Time spent | Difficulty | Confidence |
|---|---|---|
| 75 min | 🟦⬜⬜⬜⬜ | 🟦🟦🟦🟦⬜ |
Suggested commit: docs(journal): month 3 week 2 review (day 070)