Monthly Review — Month 2: Standard Library, Tooling & Testing¶
🎬 Headline¶
I can read and write real Go programs with the standard library (I/O, encoding, time, HTTP, context, logging), prove them with the testing package (table tests, benchmarks, fuzzing), and ship them behind reproducible tooling and CI — capped by a stdlib-only URL-shortener tagged v0.2.0.
🛠️ Skills Acquired¶
| Skill | Confidence (1-5) | Evidence (link) |
|---|---|---|
io.Reader/Writer, bufio, fmt verbs, strings/strconv |
4 | examples/month-02/io-basics, bufio-scan, fmt-verbs |
encoding/json (tags, custom marshalers, streaming) |
4 | examples/month-02/json-tags |
time, net/http client + context cancellation, log/slog |
4 | time-timers, http-context, slog-structured |
Testing: table-driven t.Run, httptest, coverage, benchmarks, fuzzing |
4 | Week 3 exercises, bench-demo, fuzz-roundtrip |
Tooling: go vet, golangci-lint, Makefile, build tags, pprof, CI |
3 | day 050–054, build-tags, pprof |
| Concurrency-safe stdlib HTTP service | 3 | urlshortener, urlstore |
📦 Projects Completed¶
- URL shortener (stdlib-only) — examples/month-02/urlshortener · base62 codes,
sync.RWMutexstore with de-dup,net/urlvalidation, explicit method checks withAllow, 302 redirects · key learning: maps need a lock under concurrent HTTP, proven withgo test -race.
💡 Lessons Learned¶
- The standard library is a complete toolbox for I/O, encoding, time, HTTP, and logging — most "I need a library" reflexes were premature.
- Tests are documentation that runs: table-driven
t.Runsubtests,httptestfor handlers,testing.Bfor cost, andtesting.Ffor invariants. - Tooling turns "works on my machine" into "works in CI":
go vet(auto-run bygo test), linters as external binaries, aMakefilegate, and GitHub Actions enforcing it. - Build constraints +
GOOS/GOARCHmake cross-platform builds a two-env-var change because the variant is chosen at compile time.
📉 Areas for Improvement¶
- Deeper profiling (
pprofmemory views,runtime/trace) — only scratched the surface. - CI maturity: artifacts, required status checks, reusable workflows.
- Error-handling polish under load (wrapping with
%w, sentinel vs typed errors in a service).
🔁 Concepts to Keep Reviewing (carry into spaced repetition)¶
flatvscuminpprof; when to reach forruntime/trace.- The reference time layout
2006-01-02 15:04:05. - Build-constraint exhaustiveness (OS × arch × custom tags).
- The
gofmt -lCI gate gotcha (test -z "$(gofmt -l .)"). - Loop-var capture in parallel subtests; nil-interface trap.
🧑💼 Interview Readiness¶
| Area | Ready? | Notes |
|---|---|---|
| Language fundamentals | ✅ | slices/append aliasing, value vs pointer receivers, error wrapping, zero values — solid from Month 1, reinforced. |
| Concurrency | 🟨 | sync.RWMutex + race-tested maps done; channels/worker-pools/context propagation is Month 3 focus. |
| Web/DB | 🟨 | stdlib net/http server + httptest strong; no real database/persistence yet. |
🎒 Portfolio Updates¶
- Updated example index (examples/month-02/README.md) and Week 4 exercise README.
- New résumé bullet: "Built a concurrency-safe URL shortener in pure Go (net/http, sync.RWMutex, base62), with table-driven + race-enabled tests and a fmt/vet/lint/test CI gate."
- Pinned/featured: Month 2 examples +
urlshortenercapstone. - Tagged release
v0.2.0+ Month 2 review notes.
📊 Metrics¶
| Total hours | Days completed | Exercises | Projects | Books/articles | Avg confidence |
|---|---|---|---|---|---|
| 42 | 28/28 | 11 | 1 | 8 | 3.7/5 |
⏭️ Next Month Preview¶
Month 3 goes deep on concurrency and real services: goroutines, channels and select axioms, worker pools and pipelines, context propagation, graceful shutdown, and evolving the shortener toward persistence and middleware. Prep: re-skim the channel/context notes and set up the Month 3 journal folder.
Suggested commit: docs(journal): month 2 review then git tag -a v0.2.0 -m "Month 2 complete"