Blog
Notes on data structures & algorithms, system design, and things I learn along the way.
Learning DSA? Follow the structured path — ordered articles from recursion to dynamic programming.→How to turn 'a hundred million users' into requests per second, storage, bandwidth and cache size in a few lines of arithmetic. The handful of numbers worth memorising, a worked URL-shortener example, and how each estimate should change the design.
Why inheritance hierarchies explode when behaviours combine, how composing small objects avoids it, and when inheritance is still the right tool. With the arithmetic, the fragile base class problem, and decorators in TypeScript.
Keyword search finds exact terms; vector search finds meaning; each misses what the other catches. How BM25 scores documents, why you can't just add the two scores, how reciprocal rank fusion merges rankings using positions alone, and where a reranker fits.
How a subject notifies a list of observers through a small interface, so new reactions can be added without editing the code that triggers them. Implementing it in TypeScript, its pitfalls — ordering, errors, leaks, re-entrancy — and how it relates to event emitters, pub/sub and the DOM.
When one business operation spans several databases, there's no single transaction to wrap it in. How two-phase commit makes it atomic at the price of blocking, how sagas use compensating actions instead, orchestration vs. choreography, and the isolation problems sagas leave you to solve.
The maximum of every window of size k in an array, in O(n) instead of O(n·k). How a deque of indices with decreasing values throws away elements that can never win, why every element is pushed and popped at most once, and where the same idea shows up.
Five principles for object-oriented design, applied one at a time to a single order service. What each one actually prevents, how to spot a violation in a code review, and when following them blindly makes code worse.
A vending machine, an order, a TCP connection: objects that respond to the same event differently depending on what happened before. How to model them as explicit state machines, implement them with the State pattern or a transition table, and stop invalid states from existing.
When one step of an algorithm varies — pricing, sorting, retry policy, compression — the Strategy pattern puts each variant behind an interface and picks one at runtime. How it works, how it looks in TypeScript with classes or plain functions, and when a switch statement is still better.
Pick items with weights and values to maximise value without going over a capacity, using each at most once. Why greedy fails, how a table of 'best value with these items and this capacity' solves it, how to recover the chosen items, and the one-array version that iterates backwards.
148 posts · page 1 of 15