Logo
Logo
249 results for
  • The moment someone says “shortest path” in an interview, I mentally split the problem into two cases: weighted or unweighted? If unweighted — every edge costs the same, every step is distance 1 — BFS gives the shortest path guarantee for free. No Dijkstra needed. BFS explores nodes in order of increasing distance from the source, so the first time you reach a destination, that is definitionally the shortest path.

    fundamentals interviews Created Fri, 07 Mar 2025 00:00:00 +0000
  • When I first started writing Rust, I used Box everywhere. Came from a Java background where everything lives on the heap, and wrapping things in Box felt natural. Took me a while to realize I was fighting the language — most of the time, you don’t need it. But when you do need Box, nothing else will do.

    What Box Actually Is

    Box<T> is the simplest smart pointer in Rust. It allocates a value of type T on the heap and gives you ownership of that allocation through a pointer on the stack. When the Box goes out of scope, it frees the heap memory. That’s it. No reference counting, no garbage collection, no magic.

    Rust tutorial rust internals Created Wed, 05 Mar 2025 08:30:00 +0000
  • We have covered each signal in isolation — structured logs, Prometheus metrics, OpenTelemetry traces, correlation IDs, pprof profiles, and latency distributions. The preceding six lessons described the individual instruments. This one is about wiring them together into a system that actually works during an incident, not just in a demo.

    The goal is this: when something breaks in production, you should be able to answer four questions within five minutes: Is it broken? Who is affected? Where in the system did it break? What is the root cause? Logs, metrics, traces, and profiles each answer one of those questions. The wiring between them — shared trace IDs, consistent service names, deployment markers on dashboards — is what lets you move between signals without losing context.

    Go tutorial golang observability Created Wed, 05 Mar 2025 00:00:00 +0000
  • I once worked on a codebase where someone had written a macro for everything. Creating structs? Macro. Implementing a two-line function? Macro. Logging? Custom logging macro that wrapped println! and added a timestamp. The macro definitions file was 800 lines long. The macros had macros inside them. Nobody on the team could modify them without breaking something, and the original author had left six months earlier. That project taught me more about when not to use macros than any tutorial ever could.

    Rust tutorial rust macros metaprogramming Created Tue, 04 Mar 2025 12:50:00 +0000
  • A colleague once asked me why their Rust program was ten times slower than expected. They were allocating a Vec<u8> inside a tight loop — millions of heap allocations per second. Moved the vec outside the loop, pre-allocated with with_capacity, and the function went from 2 seconds to 80 milliseconds. Stack vs heap isn’t an academic distinction. It’s the difference between fast code and slow code.

    Two Memory Regions, Two Personalities

    Your program has (at minimum) two regions of memory to work with: the stack and the heap. They behave differently, perform differently, and serve different purposes. Rust makes the choice between them more explicit than most languages, which is one of the reasons it’s fast by default.

    Rust tutorial rust internals Created Mon, 03 Mar 2025 14:45:00 +0000
  • Every major Go release follows a rhythm: one or two headline language features, a handful of standard library additions, and a runtime improvement you probably do not notice directly but that makes your services run better in aggregate. Go 1.23 and 1.24 brought the iterator protocol, go tool improvements, and the unique package. Go 1.25 and 1.26 continued this pattern with Swiss table map internals, a production-ready weak pointer API, and improvements to the toolchain that affect how you build, ship, and profile Go binaries.

    Go tutorial golang modern Go Created Sun, 02 Mar 2025 00:00:00 +0000
  • I used #[derive(Serialize)] for two years before I actually looked at what it generates. When I finally ran cargo expand on a struct with five fields, I got 150 lines of serialization code — visitor patterns, generic bounds, field-by-field traversal, error handling. All generated from a single line. Understanding how production crates use macros changed how I think about API design. These aren’t academic exercises — they’re the patterns behind the most downloaded crates in the ecosystem.

    Rust tutorial rust macros metaprogramming Created Sat, 01 Mar 2025 15:40:00 +0000
  • I spent an embarrassing amount of time debugging a networking project where my hand-crafted packet structs were mysteriously three bytes too large. Turns out the compiler was inserting padding I didn’t know about. That’s when I realized most Rust developers — myself included — treat memory layout as a black box. Let’s crack it open.

    Why Layout Matters

    Every type in Rust has two fundamental properties: size and alignment. The size is how many bytes the value occupies. The alignment is which memory addresses the value is allowed to start at. These two numbers determine everything about how your data sits in memory, how much RAM your program uses, and whether your structs can talk to C code or hardware registers.

    Rust tutorial rust internals Created Sat, 01 Mar 2025 10:22:00 +0000
  • Early in my Go career I had a bug where I modified a slice inside a function expecting the caller’s slice to remain unchanged — and it did. Then I had a different bug where I expected the opposite and the caller’s slice was modified. I had no mental model for predicting which would happen. Building that model is what this lesson is about.

    The Problem

    Go passes everything by value. That’s the official line, and it’s true. But “by value” means different things for different types:

    Go tutorial golang internals Created Sat, 01 Mar 2025 00:00:00 +0000
  • One of the more expensive lessons I learned was treating all errors the same. When a database connection drops, you retry. When a user sends an invalid email address, you return a 400 and explain what’s wrong. When someone tries to access a resource that doesn’t belong to them, you return a 403. These are completely different situations — different causes, different remedies, different communication needs — and collapsing them into a single err != nil branch produces services that retry permanent failures, expose internal details to users, and log noise that drowns out real alerts.

    Go tutorial golang Created Fri, 28 Feb 2025 00:00:00 +0000