Skip to content

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 with errors.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/list for 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