Logo
Logo
54 results for
  • Recursion trips people up not because the concept is hard, but because they try to trace through it. “If I call f(3), then f(3) calls f(2), which calls f(1)…” and then they lose the thread. I used to do this. My interviewer at a Series B startup once watched me spend three minutes trying to mentally simulate a recursive call stack for a problem that had a two-line solution once I stopped simulating and started trusting.

    fundamentals interviews Created Sat, 07 Sep 2024 00:00:00 +0000
  • The news feed is the product feature that defines social media. Every time you open Instagram or Twitter, you see a personalized, ranked, real-time stream of content from people you follow. Behind that deceptively simple UI is one of the hardest distributed systems problems in consumer tech: how do you compute a personalized feed for hundreds of millions of users, where any piece of content needs to appear in potentially millions of feeds, within seconds of being posted?

    fundamentals system design Created Fri, 06 Sep 2024 00:00:00 +0000
  • I merged a PR last year that passed all tests on my M2 MacBook and broke on the Linux CI runner. The issue? I’d used std::path::PathBuf with hardcoded forward slashes, which worked fine on macOS but blew up on Linux because the test setup expected a specific path format. CI exists to catch exactly this kind of “it works on my machine” problem. Here’s how to set it up properly for Rust.

    Rust tutorial rust testing Created Thu, 05 Sep 2024 16:45:00 +0000
  • I shipped a CLI tool with 23 flags once. Twenty-three. The --help output scrolled past two terminal screens. Users hated it, nobody could remember the flags, and every deployment script was a wall of backslash-continued command lines. That’s when I learned: if your tool has more than about eight flags, you need a configuration file.

    The Configuration Hierarchy

    Every serious CLI tool follows the same precedence order:

    1. Command-line flags (highest priority)
    2. Environment variables
    3. Project-local config file (.myapp.toml in the current directory)
    4. User config file (~/.config/myapp/config.toml)
    5. System config file (/etc/myapp/config.toml)
    6. Compiled-in defaults (lowest priority)

    Each layer overrides the one below it. This lets users set defaults in their home directory, override them per-project, and override those on a per-invocation basis with flags. kubectl, git, docker — they all work this way.

    Rust tutorial rust cli Created Thu, 05 Sep 2024 11:08:00 +0000
  • There was a test suite I worked on where tests passed individually but failed when run together. The failure pattern was non-deterministic — sometimes test A broke test B, sometimes test C broke test A, and it changed with the -count flag. After two hours of bisecting, we found it: a package-level var config Config that every test modified by calling loadConfig("testdata/some-fixture.json"). The tests were sharing state without knowing it, and the one that ran last set the config for all the others.

    Go tutorial golang code quality Created Thu, 05 Sep 2024 00:00:00 +0000
  • When I review Go code, naming problems tell me more about the author’s understanding of the codebase than almost anything else. A function called HandleRequest that parses JSON, queries a database, formats a response, and writes to a log tells me its author didn’t know what it does either. A variable called data in a function that handles three different kinds of data tells me the author stopped thinking halfway through. Names are the first layer of documentation — they’re read far more often than comments, and unlike comments, they can’t drift out of sync with the code.

    Go tutorial golang code quality Created Wed, 04 Sep 2024 00:00:00 +0000
  • A coworker once asked me to review a Rust CLI they’d written. It read a CSV file, transformed some columns, and wrote the result. Worked perfectly — until someone piped in a 2GB file. The tool ate 4GB of RAM, hung for thirty seconds, then crashed. They were reading the entire file into a String before processing a single line. Classic.

    Why I/O Is Harder Than It Looks

    Unix tools work because of a simple contract: read from stdin, write to stdout, errors to stderr. cat file | grep pattern | sort | uniq -c. Each program does one thing. They compose through pipes. It’s beautiful when it works.

    Rust tutorial rust cli Created Tue, 03 Sep 2024 08:45:00 +0000
  • Redis chose skip lists for its sorted set implementation, and that choice is more interesting than it first appears. When you have ZADD, ZRANGE, and ZRANK all needing to run at O(log n), you might reach for a balanced BST. But Redis chose a probabilistic alternative that’s simpler to implement, easier to reason about in concurrent contexts, and performs comparably in practice.

    Understanding skip lists taught me something important about engineering tradeoffs: sometimes “good enough with simpler code” beats “optimal but complex.”

    fundamentals data structures Created Tue, 03 Sep 2024 00:00:00 +0000
  • I once optimized a hot loop by replacing a HashMap lookup with a Vec indexed by a precomputed key. Felt clever. Ran the benchmarks. The “optimized” version was 15% slower because the Vec was huge, cache-cold, and the access pattern was random. Without the benchmark, I would’ve shipped that “improvement” and bragged about it. Performance intuition is unreliable. Measurement isn’t.

    The Problem

    Rust is fast by default, but that doesn’t mean your code is fast. You can still write O(n^2) algorithms, cause cache thrashing, allocate unnecessarily, or clone data you could borrow. Worse, optimizations that seem obvious can backfire in ways you don’t expect.

    Rust tutorial rust testing Created Mon, 02 Sep 2024 13:20:00 +0000
  • Backtracking is the algorithmic equivalent of “try everything, but be smart about giving up early.” It is a systematic way to explore a search space where you build a solution incrementally and abandon partial solutions as soon as you detect they cannot possibly lead to a valid result.

    I first encountered backtracking outside of textbooks when building a scheduling system that needed to assign employees to shifts while respecting availability constraints, skill requirements, and labor regulations. The brute force approach — enumerate all possible assignments — was computationally equivalent to exploring all permutations, which was 20! for 20 employees. Backtracking with constraint pruning reduced the search space by several orders of magnitude.

    fundamentals algorithms Created Mon, 02 Sep 2024 00:00:00 +0000