Concurrency
Concurrency is not a syntax you learn, it is a set of failures you have personally caused. Rather than ten unrelated toys, this track builds two systems properly. The first three exercises are a bank: money vanishes, then the fix deadlocks, then a rate limiter shows that the clock is harder than the lock. The remaining seven are one load balancer, built up from a registry you can add backends to into something with health checks, a connection pool, a circuit breaker, graceful draining and consistent hashing — each exercise adding a capability and, with it, a new class of bug that the previous design could not have had. Every exercise is solved three times, in Java, Go and Python, because the same bug is silent in one language, loud in another, and disguised by the GIL in the third.
- 01The bank that loses money
Start with a transfer function that works perfectly in tests and destroys money under load. Solved in Go, Java and Python — where the same bug is loud, invisible, and disguised by the GIL respectively.
- 02The bank that freezes itself
Per-account locks are the obvious optimisation and they introduce deadlock. Build it, freeze it on purpose, then fix it in Go, Java and Python — where only one of the three runtimes will tell you what went wrong.
- 03A rate limiter for a payment gateway
A token bucket is ten lines and almost everybody writes it wrong the first time. Built in Go, Java and Python — where every real difference turns out to be about the clock, not the lock.
- 04A load balancer you can register backends with
Registration is the interesting part, not the routing. Crash it with an index out of bounds, then find the boundary that makes the bug unconstructible rather than merely fixed — and the two bugs that survive even after you draw it.
- 05Least-busy routing, and the race in picking the minimum
- 06Health checks, and the threads that outlive what they were checking
- 07A connection pool per backend, and backpressure when it is full
- 08A circuit breaker that lets exactly one request through
- 09Removing a backend without dropping what it is already doing
- 10Routing that barely moves when the ring changes