Logo
Logo
16 results for
  • The hardest part of learning Go generics isn’t the concept — it’s the syntax. The first time I read a function signature like func Keys[K comparable, V any](m map[K]V) []K, I did a double-take. It looks like someone snuck type annotations from another language into Go. But once it clicks, it’s actually pretty elegant — every piece is there for a reason.

    This lesson is about understanding type parameters and constraints deeply enough that you can write them yourself without copying from examples. That’s the threshold that separates “I’ve used generics” from “I understand generics.”

    Go tutorial golang generics Created Mon, 01 Jul 2024 00:00:00 +0000
  • When I first built a real-time notification system, I reached for WebSockets because that’s what everyone said to use for “real-time.” Three months later I was debugging connection drops under load, wrestling with proxy timeouts, and fighting with nginx configuration. When I stepped back and actually thought about the access pattern — server pushing notifications to the browser, never the browser sending data to the server — I replaced WebSockets with Server-Sent Events in a weekend. The code got simpler, the proxies stopped complaining, and we had less to maintain. Picking the right tool requires understanding what each one actually does.

    fundamentals networking Created Mon, 01 Jul 2024 00:00:00 +0000
  • Picture this: you’re using two crates — serde and some db_client crate. You want to implement serde::Serialize for db_client::Row. Sounds reasonable. You write the impl, and the compiler slaps you: “only traits defined in the current crate can be implemented for types defined outside of the current crate.” Welcome to the orphan rules.

    My first reaction was frustration. My second reaction, after dealing with diamond dependency problems in C++ for years, was “oh, this is actually protecting me.”

    Rust tutorial rust traits generics Created Sun, 30 Jun 2024 17:55:00 +0000
  • The first time I deployed a Go binary to a production server, I was braced for the usual ceremony: SSH in, install the right runtime version, copy over config files, fiddle with symlinks. Instead, I ran scp and then the binary, and it just worked. No installation. No dependency hell. No “but it works on my machine.” The binary contained everything it needed.

    This is Go’s single greatest operational advantage: the compiler produces a self-contained executable. Understanding exactly how this works — and how it can break — makes the difference between a deploy that takes five minutes and one that takes an afternoon.

    Go tutorial golang deployment devops Created Sun, 30 Jun 2024 00:00:00 +0000
  • My first encounter with event sourcing was a financial system that needed a complete audit trail. The business requirement was clear: every change to an account balance had to be traceable — who changed it, when, why. The first approach was an audit log table alongside the main accounts table. We’d write to both in a transaction. Within six months, the audit table was out of sync with the accounts table. Bugs in the dual-write logic, a migration that updated account records without touching the audit log, a direct database fix that bypassed the application layer. The audit log was nearly useless. The core insight I eventually arrived at: the audit log shouldn’t be a secondary record — it should be the primary record. That’s event sourcing.

    fundamentals architecture event sourcing Created Sat, 29 Jun 2024 00:00:00 +0000
  • The moment blanket implementations clicked for me, I felt like I’d been handed a cheat code. You write impl<T: Display> ToString for T and suddenly every single type that implements Display automatically gets ToString. One line of implementation logic, infinite types covered. This is how the standard library builds massive capability trees from small pieces.

    What’s a Blanket Implementation?

    A blanket implementation implements a trait for all types matching a bound, rather than for a specific type:

    Rust tutorial rust traits generics Created Fri, 28 Jun 2024 10:20:00 +0000
  • Go’s reflect package carries a reputation: “don’t use it unless you have to.” That advice is correct but incomplete. Understanding when you actually have to use it — and when you are just reaching for it out of habit from dynamic languages — is the difference between reflection that pulls its weight and reflection that creates unmaintainable, slow, panic-prone code that confuses every future reader of the codebase.

    Reflection lets Go inspect and manipulate values, types, and struct fields at runtime without static type information. It is the mechanism behind encoding/json, database/sql’s row scanning, struct validators, ORM frameworks, and dependency injection containers. It is also the mechanism behind a lot of code that should have just used a map or an interface.

    Go tutorial golang reflection Created Fri, 28 Jun 2024 00:00:00 +0000
  • I used to wonder how a Go HTTP server could handle 100,000 concurrent connections with only 8 OS threads. If each connection required a dedicated thread, you would need 100,000 threads — which would require roughly 800 GB of stack space and would spend all their time in the kernel scheduler. The answer is epoll: a Linux kernel interface that lets a single thread wait on thousands of file descriptors simultaneously and be notified only when one is ready for I/O. Go’s runtime uses epoll internally as the foundation of its network I/O model. This lesson explains how.

    fundamentals linux operating systems Created Thu, 27 Jun 2024 00:00:00 +0000
  • Every time PostgreSQL, MySQL, SQLite, or MongoDB uses an index, it’s almost certainly a B-tree or B+ tree underneath. Not a binary search tree — a B-tree. The difference matters more than most engineers realize, and it comes down to one thing: disk read costs.

    I’ve seen engineers add indexes blindly to fix slow queries without understanding what an index actually is. When you understand B-trees, you understand why some indexes help more than others, why certain query patterns can’t use indexes, and why index-heavy tables slow down on writes.

    fundamentals data structures Created Wed, 26 Jun 2024 00:00:00 +0000
  • The first time I got the error “the trait Clone cannot be made into an object,” I stared at it for a solid minute. Clone is one of the most fundamental traits in Rust. How can it not work with dyn? The answer is object safety — a set of rules that determine which traits can be used as trait objects. It’s one of those things that seems arbitrary until you understand why the rules exist.

    Rust tutorial rust traits generics Created Tue, 25 Jun 2024 13:40:00 +0000