Skip to content

Instantly share code, notes, and snippets.

@decagondev
Created July 7, 2026 15:46
Show Gist options
  • Select an option

  • Save decagondev/218f558fef6fc3a8021a45b88c70f74c to your computer and use it in GitHub Desktop.

Select an option

Save decagondev/218f558fef6fc3a8021a45b88c70f74c to your computer and use it in GitHub Desktop.

Module 2 Challenger — Take-Home

Representation & the Data/Code Seam: Choosing What Must Be Cheap · the first spectrum

Last time you named a binding constraint. The first thing that derivation hits is this: which operations have to be cheap? Answer that and you've chosen a representation — and a data structure is a bet. This take-home asks you to make that bet on a system you own, and then do the part everyone skips: name what you made expensive. The grade is in reading the whole ledger, not in picking a clever structure.

Time: ~45–60 min · Due: before Module 3 · Submit: post your write-up in the cohort channel.


The assignment

Part A — Choose the representation, name the cost (core)

Pick one system that stores or serves structured data — a level/asset pipeline, a search index, a document store, a cache, a feed.

⚠️ The game leaderboard worked below is off-limits as your submission — it's the worked demo. Pick something else.

In a ~300–400 word write-up, make the four moves:

  1. Name the hot operations. The ones your workload runs most. Start here — not from a structure you like. If you named a structure before you named the workload, start over.
  2. Choose the core representation that makes them cheap — and say plainly what becomes expensive. Read the whole ledger, both columns.
  3. Decide what you precompute — and name what that assumes about how often the data changes. Precompute only what's truly static.
  4. Draw the mechanism/content seam. Where's the line between engine and data? Say what the seam permits (tooling, reuse, ecosystem) and what it forbids.

Part B — Three reflections (a paragraph each)

  1. A time you picked a structure first and asked what it was good at second — what did that cost?
  2. Something you precomputed that turned out not to be static — what did you pay for the wrong assumption?
  3. A seam (or a missing one) that helped or hurt — what did the gap enable or forfeit?

Optional — Peer response (this is our discussion, async)

Reply to one classmate's audit. Find a representation chosen by familiarity rather than the hot operations, or a precomputation over data that isn't actually static — and propose the bet that fits their workload.


Before you start: the four moves you're applying

Everything below is just these, applied to one system. Keep them in front of you:

  1. Start from the hot operations. The bet begins with what your workload runs most — never with a favourite structure. Get the bet wrong and no optimisation saves you; you'll be fast at the wrong thing.
  2. Read the whole ledger. Every representation makes some things cheap and others expensive. Name the expensive column — that's where systems die.
  3. Precompute only what's truly static. Precomputation buys runtime speed by assuming the data won't change. Precompute changing data and you pay the cost without the speed.
  4. Draw the seam where change-rate changes. A clean mechanism/content line buys tooling, reuse, and ecosystems for free. Fuse them and you forfeit all of it.

A worked starter — choosing a representation for a different system

Let's run the bet on something that is not your assignment: a real-time game leaderboard — millions of players, and the screen shows the top 100 plus "your rank." Watch the moves, then make them on your own system.

1 · Name the hot operations. What does this workload actually run? Top-N by score and rank-of-one-player, constantly, on every screen refresh. Score writes happen too, but far less often than the millions of people reading the board. The hot path is ranked read, not write. That's the bet.

2 · Choose the representation — and name the cost. A plain table forces a full sort on every read — wrong bet. The representation that makes the hot path cheap is a score-ordered structure (a sorted set / skip list keyed by score): top-N is a slice off one end, and a player's rank is a position lookup — both cheap. The expensive column: querying by anything other than score — "all players in France," "everyone who joined Tuesday" — is now slow or impossible. I made ranked-by-score cheap and every other query expensive. That's the honest ledger.

3 · Decide what to precompute. The sorted order is the precomputation: I keep the board ordered as scores arrive rather than sorting at read time. What does that assume? That scores change far less often than the board is read — true here. If scores churned every millisecond I'd be paying to re-sort constantly with no read benefit — the precompute-over-changing-data trap.

4 · Draw the seam. Separate the score store (content — just player→score) from the ranking engine (mechanism — top-N, rank, pagination). The seam permits: I can swap the store, point analytics tools straight at the raw scores, or add a second ranking view without touching the store. It forbids nothing I need. One clean line, drawn up front.

Notice what just happened: I named the hot operations first, chose a structure that makes them cheap, named exactly what I made expensive, precomputed only the genuinely-static-enough ordering, and drew a mechanism/content seam. That's the whole of Part A — and it's DOOM's bet: precompute for a fast read, accept a less flexible world. A write-heavy, query-every-attribute workload would've chosen Build's. Your job is to make those moves on your system.


The shape you're auditing

Two columns of one ledger: what the representation makes cheap, and what it makes expensive. And one clean seam between the engine and the data it reads. Your audit names both columns and locates the seam.

flowchart TD
    HOT["Hot operations<br/>top-N · rank-of-player"]
    REP{{"Representation<br/>score-ordered set"}}
    CHEAP["CHEAP<br/>ranked reads"]
    EXP["EXPENSIVE<br/>query by other attributes"]
    STORE([Score store<br/>content])
    ENGINE([Ranking engine<br/>mechanism])

    HOT --> REP
    REP --> CHEAP
    REP --> EXP
    STORE -. clean seam .- ENGINE
    ENGINE --> REP

    style REP stroke:#F5A623,stroke-width:2px
    style EXP stroke:#C97E12,stroke-width:1.5px
    style CHEAP stroke:#6FCF97,stroke-width:1.5px
Loading

Your turn — a template to fill in

Copy this into your doc and replace each blank. Keep it tight — most of the marks are in the expensive column (point 2) and the seam (point 4).

SYSTEM (one line): _______________________________________

1. HOT OPERATIONS (what the workload runs most)
   _____________________________________________________
   The hot path is: ____________________________________

2. REPRESENTATION + THE LEDGER
   Core representation: ________________________________
   What it makes CHEAP: ________________________________
   What it makes EXPENSIVE: ____________________________

3. PRECOMPUTATION
   What I precompute: __________________________________
   What that assumes is static: ________________________

4. THE SEAM
   Mechanism (engine) | Content (data): _________________
   What the seam permits: ______________________________
   What it forbids: ____________________________________

If you want a diagram, copy the Mermaid block above and relabel it for your system — it renders as a flowchart in your Gist.

Part B — starter prompts (answer in your own words; don't just restate these):

  1. Recall a time the structure came first — "let's use a graph DB / a queue / a document store" — and the workload got reverse-engineered to fit it. What did being fast at the wrong thing cost?
  2. Find a cache, an index, or a materialised view you built over data that moved more than you assumed. What did the stale precompute cost?
  3. Point at a seam that paid off (a file format, a plugin API, a clean data/engine split) — or a fusion that hurt. What did the presence or absence of that line enable or forfeit?

Common traps (self-check before you submit)

  • Naming the structure before the workload. "I used a B-tree" is not an analysis. Which operations are hot? comes first; the structure is the answer to that, not the starting point.
  • Listing only the cheap column. Anyone can say what a structure accelerates. The discipline — and most of the marks — is naming what it makes expensive.
  • Precomputing changing data. If the thing you precomputed actually moves, you pay the precompute cost and get no speed. Name what your precompute assumes is static, and check that it is.
  • No seam — or the seam in the wrong place. Fusing engine and content forfeits all tooling and reuse. Draw the line where the rate of change changes.
  • "Best" structure. There isn't one. There's only fit to this workload. If your answer would be identical for a different workload, you haven't chosen — you've defaulted.

What a strong submission shows

  • Starts from the hot operations — the workload drives the structure, not the reverse.
  • Names what the representation makes cheap and what it makes expensive — reads the whole ledger.
  • Precomputes only what's genuinely static, and names the assumption.
  • Draws a clean mechanism/content seam and says what it permits and forbids.

That's the first spectrum. Same problem, opposite bets can both be right — the workload decides. Next module, the data leaves one machine, and you lose the luxury of having the truth and the speed at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment