Skip to content

Monthly Review — Month 3: Concurrency & Parallelism

Journal index · Roadmap › this month · Release notes

🎬 Headline

I can design, build, test (-race), and profile a real concurrent system — proven by a bounded, cancellable, rate-limited crawler — not just launch a goroutine.

🛠️ Skills Acquired

Skill Confidence (1-5) Evidence (link)
Goroutines, channels, select, fan-in/out 4 examples/month-03/goroutines, generator
The sync toolbox (Mutex/RWMutex, WaitGroup, Once, Pool) 4 examples/month-03/mutex, once-pool
sync/atomic & lock-free patterns (CAS retry) 3 examples/month-03/atomic, exercises/.../atomicgate
Concurrency patterns (worker pool, pipeline, semaphore) 4 examples/month-03/workerpool
context cancellation & graceful shutdown 4 examples/month-03/graceful-shutdown
Rate limiting (token bucket, time.Ticker) 3 examples/month-03/rate-ticker, exercises/.../tokenbucket
Race-detector testing & deterministic concurrent tests 4 exercises/month-03/week-4
Profiling concurrent code (runtime/pprof, go tool pprof) 3 examples/month-03/pprof-demo

📦 Projects Completed

  • Concurrent crawler (stdlib, in-memory graph) — examples/month-03/crawler + exercises/month-03/week-4/crawl · key learning: a single-owner dedup map + worker pool + outstanding-work counter gives a correct, mutex-free, terminating crawler; layered with context shutdown and a token-bucket rate limiter.

💡 Lessons Learned

  • Get the algorithm right single-threaded, then add concurrency as a layer.
  • "Share memory by communicating": a single owner over channels often beats a lock.
  • Cancellation is cooperative — context closes Done(); goroutines must opt in and main must wait.
  • Concurrency limits and rate limits are orthogonal dials.
  • A green -race is evidence, not proof; assert invariants and inject time for determinism.
  • Measure before optimising — block/mutex profiles explain why more workers stopped helping.

📉 Areas for Improvement

  • Reading block/mutex/trace profiles fluently and acting on them.
  • Goroutine-leak detection in tests/CI.
  • Production-grade concerns: per-host politeness, distributed rate limiting, real HTML parsing.

🔁 Concepts to Keep Reviewing (carry into spaced repetition)

  • Channel axioms (nil/closed/send-on-closed) and the no-copy rule for sync types.
  • defer cancel() / ticker.Stop() resource hygiene.
  • CAS retry loops and when atomics beat a mutex.
  • Worker-pool/semaphore sizing vs. the bottleneck resource.

🧑‍💼 Interview Readiness

Area Ready? Notes
Language fundamentals Carried from Months 1–2; reinforced by concurrent code.
Concurrency Can whiteboard a worker pool, fan-in/out, pipeline, semaphore, context shutdown, and a token bucket; explain races and -race.
Web/DB Starts Month 4 (HTTP services) and Month 5 (databases).

🎒 Portfolio Updates

  • Updated example/exercise READMEs with the Week 4 crawler index
  • New résumé bullet: "Built a bounded, cancellable, rate-limited concurrent crawler in Go; verified race-free with go test -race and profiled with pprof."
  • Pinned/featured: the month-03 concurrency examples + crawler capstone
  • Tagged release v0.3.0 + wrote release notes

📊 Metrics

Total hours Days completed Exercises Projects Books/articles Avg confidence
38 28/28 11 1 6 3.6/5

⏭️ Next Month Preview

Month 4 — Networked Services: net/http servers and clients, routing and middleware, JSON APIs, and graceful server shutdown, all built on this month's concurrency foundation.

Suggested commit: docs(journal): month 3 review then git tag -a v0.3.0 -m "Month 3 complete"