Table of Contents
Exercises — Month 6 · Week 3 (Performance, profiling & hardening)¶
Standard-library-only Go packages with table-driven tests. Run all:
go test ./exercises/month-06/week-3/...
# allocation-sensitive tests are most reliable with the optimizer on (the default):
go test -race ./exercises/month-06/week-3/...
Prompts¶
1. tokenbucket — deterministic rate limiter¶
Implement a token-bucket Limiter with an injected clock (now func() time.Time)
so refills are exact and testable without time.Sleep. It starts full (burst
tokens), refills lazily at rate tokens/sec capped at burst, and Allow/AllowN
consume tokens. The clock injection is the key idea — it makes time a value you
control in tests.
- Skills: lazy refill math, dependency injection for testability, floating-point bucket accounting.
2. allocfree — kill allocations with the append pattern¶
Implement AppendCSV(dst, fields) and AppendInt(dst, n) that write into a
caller-provided buffer instead of returning a fresh string, so they allocate
zero times when the buffer has capacity. Prove it with testing.AllocsPerRun.
This mirrors the stdlib's own strconv.AppendInt / Time.AppendFormat style.
- Skills: append-into-buffer pattern,
strconv.AppendInt,testing.AllocsPerRun, reasoning about what escapes to the heap.
3. bufpool — sync.Pool used safely¶
Wrap a sync.Pool of *bytes.Buffer. Get must return a Reset buffer (a
pooled object is not zeroed); Greet builds a string and returns it after Put
(the string copies, so it doesn't alias pooled memory). Tests force reuse to
catch a missing Reset and run concurrently for -race.
- Skills:
sync.PoolGet/Put/Reset discipline, whybytes.Buffer.Stringis safe after Put, concurrency hygiene.
Results¶
| Exercise | Focus | go test |
|---|---|---|
tokenbucket |
injected clock, lazy refill, burst cap | ✅ |
allocfree |
append pattern, zero-alloc, AllocsPerRun |
✅ |
bufpool |
sync.Pool Reset discipline, race-safe |
✅ |