Table of Contents
Exercises — Month 6 · Week 4 (Capstone: the link-shortener core)¶
Standard-library-only Go packages with table-driven tests. These three packages
are the testable heart of the capstone service — the bits that have no third-party
dependency and so can be proven correct with go test alone. Run all:
go test ./exercises/month-06/week-4/...
# add -race to prove the concurrency-safe stores have no data races:
go test -race ./exercises/month-06/week-4/...
Prompts¶
1. shortcode — base62 id ↔ short code¶
Implement Encode(id int64) (string, error) and Decode(code string) (int64, error)
over the base62 alphabet (0-9a-zA-Z). Encode(0) == "0", negative ids return
ErrNegative, and any non-base62 rune (or empty string) returns ErrInvalidChar.
The invariant that matters: Decode(Encode(id)) == id for all non-negative ids.
- Skills: positional number systems, byte-slice reverse,
strings.IndexRune, sentinel errors witherrors.Is, property-style round-trip testing.
2. linkstore — concurrency-safe in-memory repository¶
Implement a Store satisfying the capstone's repository contract: Create
(rejecting duplicate codes with ErrExists), Get (wrapped ErrNotFound on a
miss, returning a copy), and IncHits. Every method takes ctx context.Context
first and short-circuits a cancelled context. Guard state with sync.RWMutex.
- Skills: context-first APIs,
sync.RWMutex, sentinel wrapping with%w, value-copy returns, race-tested counter mutation.
3. lrucache — cache-aside with LRU + TTL¶
Implement a bounded Cache (capacity-limited LRU via container/list) with a
per-entry TTL and a GetOrLoad(key, loader) cache-aside method that loads on a
miss and never caches loader errors. A SetClock hook makes TTL expiry
deterministically testable.
- Skills:
container/listfor O(1) LRU,sync.Mutex, injectable clocks for time-dependent tests, cache-aside semantics, hit/miss accounting.
Results¶
| Exercise | Focus | go test |
|---|---|---|
shortcode |
base62 round-trip, sentinel errors | ✅ |
linkstore |
context-first repo, RWMutex, errors.Is |
✅ |
lrucache |
LRU + TTL cache-aside, injectable clock | ✅ |