Weekly Review — Month 3 · Week 1 (Days 057–063)¶
📅 The Week in One Line¶
The foundations of Go concurrency: goroutines, channels, select, and the leak-free pipeline patterns that hold them together.
✅ What I Completed¶
- Day 057 — Goroutines & the
gostatement;sync.WaitGroup; concurrency vs parallelism - Day 058 — Channels: unbuffered (rendezvous) vs buffered (decoupled),
close+range - Day 059 — Channel axioms: the four
closepanics,nil-channel blocking, directional types - Day 060 —
select,default,time.After/Timer/Ticker, labelled break - Day 061 — Deadlocks vs goroutine leaks;
-race,go vet, stack dumps - Day 062 — Generators, pipelines, fan-in
merge,done-channel cancellation - Day 063 — Review + closed-book recall
- Mini-project: pipeline + worker pool + fan-in exercises, all
-race-clean - Exercises solved: 3 (pipeline, fanin, workerpool)
💡 Lessons Learned¶
- A goroutine is cheap (~2 KB growable stack), but coordination is the real cost — always have an explicit join (
WaitGroupor channel). - Unbuffered channels are a synchronisation tool, not just transport: the send/receive rendezvous is the point.
- The sender owns
close, exactly once; with multiple senders, hand close to a single closer goroutine afterwg.Wait(). - A
nilchannel blocking forever is a feature: set aselectcase's channel tonilto switch it off. - Deadlocks announce themselves (runtime panic when all goroutines sleep); leaks are silent and need a
done/contextcancel signal.
💪 Strengths (what clicked)¶
WaitGroupAdd-before-go / deferred-Done / Wait rhythm.- Order-preserving linear pipelines (single FIFO channel).
- Bounding a blocking op with
select+time.After.
🧩 Weaknesses (what's still fuzzy)¶
- Reading goroutine stack dumps to pinpoint a hang's culprit frame.
- Multi-sender close coordination beyond the simple closer-goroutine case.
- Knowing when buffered sizing actually helps under bursty load (needs benchmarks).
🔁 Spaced-Repetition Re-quiz (topics from earlier weeks)¶
- Q: (M1) What does
string(65)produce and why?A
"A"— it's an int→rune conversion to code point U+0041, not"65". Usestrconv.Itoa. - Q: (M1) Why can
appendmutate a slice the caller still holds?A
Slices share a backing array; ifappenddoesn't grow capacity it writes in place, aliasing the original. - Q: (M2) What does
%wdo infmt.Errorf?A
Wraps an error soerrors.Is/errors.Ascan unwrap and match it. - Q: (M2) Why must
context.Contextbe the first parameter?A
Convention for cancellation/deadline propagation; tooling and readers expectctx context.Contextfirst. - Q: (M3) Send on a closed channel vs a nil channel?
A
Closed → panic; nil → blocks forever.
🎯 Action Items¶
- Practise reading
GOTRACEBACK=allstack dumps on a deliberately hung program. - Rewrite the generator example using
context.Contextonce Week 2 covers it. - Benchmark a buffered vs unbuffered producer/consumer to see when buffering pays off.
🚀 Next Week Goals¶
syncprimitives:Mutex,RWMutex,Once,sync.WaitGroupdeeper,sync.Map.sync/atomicand the memory model basics.context.Context: cancellation, deadlines,WithTimeout/WithCancel, the value anti-pattern.
📊 Metrics¶
| Hours | Days hit | Exercises | Commits | Avg confidence |
|---|---|---|---|---|
| 9 | 7/7 | 3 | 7 | 3.⅗ |
Suggested commit: docs(journal): month 3 week 1 review