Hands-On Pages for This Track — Build Spec
This is the working spec for extending the lego-block hands-on format into the interview program. The machinery is already here and one page (C03 — rate limiting) is built end to end as the reference. Everything below is what a fresh session needs to continue without rediscovering it.
Scope: this track only. Nothing outside swe-interview-prep/ changes.
What the format is
One page per topic. Each page is a sequence of numbered blocks — a block is a self-contained lego piece that builds one mechanism, proves it works in isolation, and hands what it made to the next — followed by an assembly that wires every block into one working thing and measures it.
Each block on the rendered page has five parts:
| Part | Source | Purpose |
|---|---|---|
## Block N — title + Teaches: | the @block(...) decorator | one-line claim |
> The problem | notes/<slug>.md | what breaks without this mechanism |
| the code | sliced from the .py | the real source, never retyped |
| Reading the implementation | notes/<slug>.md | the lines that carry the algorithm |
| the output | captured by running the .py | never transcribed by hand |
| What the numbers say / Beyond the toy | notes/<slug>.md | how to read it; what production does |
Then, after the assembly, an optional page-level deep dive from
deep/<slug>.md: design space, latency/cost model, hardware, alternatives,
connections, failure modes, primary sources.
The rule that makes it worth reading: every number is captured from a real
run. build_pages.py executes the script and splices its stdout. If a result
drifts, regenerating rewrites the page. Nothing is hand-copied.
What is already here
handson/
_harness.py block decorator + run_all; --block N, --quiet
build_pages.py the generator; PAGES registry at the top
c03_rate_limiter.py worked reference, 6 blocks + assembly
c03.md generated (do not hand-edit)
notes/ per-block annotations (empty — see below)
deep/ per-page deep dives (empty — see below)
HANDOFF.md this file
Run it:
cd handson
python3 c03_rate_limiter.py # every block, then the assembly
python3 c03_rate_limiter.py --block 3 # one block and its prerequisites
python3 c03_rate_limiter.py --quiet # assembly only
python3 c03_rate_limiter.py --verify # re-derive and assert every claim
python3 build_pages.py # regenerate every page
python3 build_pages.py c03 # regenerate one
python3 test_handson.py # the suite (also runs under pytest)
Every page must supply verify(). Captured output is reproducible but not
necessarily correct — a wrong measurement reproduces perfectly. verify()
recomputes each headline number from a second implementation, independent of
the blocks, and asserts it with check(label, ok, detail). --verify exits
non-zero on any failure, test_handson.py runs it for every page, and the
generator splices the resulting table into a Verify the claims section. The
rule: a block with a bug must not be able to make its own claim pass, which
is why verify() does not import the block's classes.
Every block needs a runnable inline example. The code on a page shows the
mechanism; it does not show how to trigger it. So each block's annotation
carries a ```python-run fence, which the generator executes at build
time and renders as the snippet plus its real captured output:
**Try it yourself**
```python-run
from c03_rate_limiter import parts
FixedWindow = parts()["FixedWindow"]
fw = FixedWindow(limit=5, window=1.0)
print(sum(fw.allow(t) for t in (0.98, 0.99, 1.001, 1.002)))
```
A snippet that raises fails the build, and one that prints nothing fails the test suite, so a broken example cannot ship. Three of these caught real errors in their own prose while being written --- an example that claimed to straddle a window boundary and did not, a Little's-law cap compared against a p99, and a block-table count off by 10x. That is the point of executing them.
parts() is what makes them possible: it calls collect() from the harness,
which runs every block silently and returns the state dict, so FixedWindow,
FencedLock and friends are importable without copy-pasting. Module-level
classes (Resource, FencedResource in c11) are imported directly instead.
Each PAGES entry also needs a predict field — five or six numbers the reader
should guess before reading. That is what turns the page from a document into an
exercise, and the ones people get wrong are the ones worth writing an annotation
about.
c03 has no notes/c03.md or deep/c03.md yet. That is deliberate: it
shows the bare layout, so the first job is to write those two files and see the
page transform. Use ../../systems-from-scratch/handson/notes/p03.md and
deep/p04.md as the models — they are the closest in subject matter.
What to build, in priority order
The interview program is not fifteen systems builds, so the unit differs per track. Ordered by value per hour:
1. Track C + D designs → miniatures (20 candidates, do 6–8)
The 12 systems designs and 8 ML-infra designs are currently prose. A hands-on page turns "I read a design doc" into "I built the mechanism and measured it", which is exactly the gap an interview exposes. C03 is the template.
Strongest candidates, because each has a mechanism that is small to build and sharp to measure:
| Page | From | The measurable thing |
|---|---|---|
c03 ✅ | d03 rate limiter | boundary burst: fixed window allows 2× |
c11 | d11 lock service | fencing tokens; a lease expiring mid-operation |
c05 | d05 load shedding | queue depth vs latency; the utilisation knee |
c04 | d04 webhook delivery | retry storms, backoff+jitter, dedup keys |
c01 | d01 job scheduler | at-least-once vs exactly-once, lease renewal |
m02 | m02 KV cache tier | paged vs contiguous KV, fragmentation waste |
m03 | m03 GPU scheduler | bin-packing vs gang scheduling, fragmentation |
m05 | m05 eval harness | sample size for a % difference in pass rate |
2. Track B internals → adopt the existing experiments (5 files)
tracks/python-internals/experiments/exp01..exp05.py already exist and already
have a section() / claim() convention. Do not rewrite them. Either:
- port them to
@blockand generate pages (uniform, more work), or - teach
build_pages.pyto read the existingsection()markers (less churn).
Prefer the second. The existing scripts are good; what they lack is the annotation layer and a rendered page.
3. Track A coding → progressive solutions (2 problems exist)
Each harness problem becomes a page whose blocks are successive attempts: naive → correct → optimal, each measured, with the complexity argument in the annotation. This is closer to how the problem is actually solved under time pressure than a finished solution is.
Conventions that are not obvious
Math. This book runs MathJax with \\(...\\) and \\[...\\]. CommonMark eats
a single backslash before ASCII punctuation, so the source needs two:
write \\\\(x\\\\), which renders as \(x\). $$ does not work. Use \\_ for
underscores inside math.
Anchors. mdBook slugs a heading by lowercasing, dropping non-alphanumerics
and turning spaces into hyphens. ## Block 4 — Rate limiting becomes
#block-4--rate-limiting (two hyphens: the em dash vanishes between two spaces).
Cross-page shorthand like #block-4 will not resolve. Write the full slug,
or run the resolver in the verification section below.
Never fuzzy-match anchors. An auto-fixer at cutoff 0.55 once turned
#straggler into #storage. Match by exact prefix or fix by hand.
Generated files are outputs. Never hand-edit handson/*.md — edit the .py,
notes/, or deep/ and regenerate.
PLAN.md is locked pending your diagnostic scores. Hands-on pages are
additive content; they must not touch the allocation in PLAN.md.
The annotation layer
notes/<slug>.md is split on ### B<n> headers, one per block. A note may
contain <<<CODE>>> and <<<OUTPUT>>> placeholders to control where the code
and the captured output land; whatever it omits is appended. So a note can be
pure prose or a full layout.
### B1
> **The problem.** One paragraph: what breaks without this mechanism.
<<<CODE>>>
**Reading the implementation**
- `the_line(...)` — why it is written this way, and what breaks if it is not.
**What the numbers say**
<<<OUTPUT>>>
**Beyond the toy**
What production does instead, with the cost model and the named systems.
The bar: a reader who already knows the mechanism should still learn something. If a paragraph could have been written without running the code, cut it.
Wiring a new page in
- Write
handson/<name>.pywith@block+assembly, run it until the output is correct and interesting. - Add an entry to the
PAGESdict inbuild_pages.py(fields are documented in place).projectmust point at the track page it belongs to, relative to the book root. - Write
notes/<slug>.mdand, if the topic warrants it,deep/<slug>.md. python3 build_pages.py <name-prefix>- Add to
SUMMARY.md, nested under the design it belongs to:- [d03 — Distributed Rate Limiter](tracks/systems-design/designs/d03-rate-limiter.md) - [Hands-On — Rate Limiting, Block by Block](handson/c03.md) - Add a forward link from the design page to the hands-on page.
Verification, before any commit
cd swe-interview-prep && mdbook build # must be clean
cd .. && node tools/build-search-index.mjs # new pages must appear
Then the link and anchor audit — this catches the #block-N shorthand problem:
import os, re, pathlib
root = pathlib.Path("."); dist = pathlib.Path("../dist/book/swe-interview-prep")
strip = lambda t: re.sub(r"`[^`\n]*`", "", re.sub(r"^```.*?^```", "", t, flags=re.S|re.M))
html_for = lambda k: (pathlib.Path(k).parent/"index.html") if pathlib.Path(k).name=="README.md" \
else pathlib.Path(k).with_suffix(".html")
anchors = {h.relative_to(dist).as_posix(): set(re.findall(r'id="([^"]+)"', h.read_text(errors="ignore")))
for h in dist.rglob("*.html")}
for md in root.rglob("*.md"):
if any(x in md.parts for x in ("dist", "notes", "deep", ".pytest_cache")): continue
for m in re.finditer(r'\[[^\]]*\]\(([^)\s]+)\)', strip(md.read_text())):
raw = m.group(1)
if raw.startswith(("http", "mailto:")): continue
tgt, _, frag = raw.partition("#")
key = md.as_posix() if not tgt else os.path.normpath(md.parent/tgt).replace("\\","/")
if not (root/key).exists(): print("MISSING FILE ", md, raw)
elif frag and key.endswith(".md"):
hk = html_for(key).as_posix()
if hk not in anchors or frag not in anchors[hk]: print("MISSING ANCHOR", md, raw)
Note notes/ and deep/ are excluded — they are partials whose relative
links resolve from the page they are spliced into, not from their own location.
Worth adding once there are several pages: a tools/tests/test_handson.py
modelled on the systems track's, asserting every script exits 0, every declared
block reports completion, every block has an annotation, and no <<<CODE>>>
placeholder survives into a page. This track currently has no pytest suite, so
that is a net addition rather than an extension.
The reference implementation
../../systems-from-scratch/handson/ — 15 pages, 109 blocks, and the same
generator. Most useful to copy from:
notes/p03.md,notes/p04.md— annotation depth and tonedeep/p04.md,deep/p14.md— deep-dive structureREADME.md— index page with a self-correction tableconcepts.md— the cross-cutting map, worth an equivalent here once there are 6+ pages (the recurring mechanisms in this track are different: idempotency, fencing, backoff, quorum, the utilisation knee, at-least-once vs exactly-once)
The thing that made those pages good was not the format. It was that seven of them document a prediction the measurement refuted, and the refutation stayed on the page with the experiment that produced it. C03 already has one: the first draft's assembly used a burst wholly inside one window, every algorithm scored identically, and the prose claiming the burst column "discriminates" was contradicted by the table under it. The fix was to straddle the boundary. Keep that habit — it is the whole difference between a tutorial and a reference.