Skip to content
tezvyn:

Go & Rust

Go web services, Rust backends, systems programming

38 bites

Test yourself: Top 30 advanced Go & Rust concepts questionsMultiple choice, with the correct answer and why it is correct on every question. Free, no sign-in.

Advanced concepts in Go & Rust

advanced2 min read

Zero-Cost Abstractions: Pay at Compile Time, Not Runtime

Zero-cost abstractions let you write high-level code that compiles to the same machine code as low-level optimizations. This is key in Rust for safe APIs without runtime overhead.

advanced2 min read

Rust's Turbofish (`::<>`): When the Compiler Needs Help

The turbofish (::<>) is your tool to resolve ambiguity when Rust's compiler can't infer a type or trait. Use it when a type implements multiple traits with same-named methods, forcing the compiler to pick the one you specify.

advanced2 min read

Using Box<T> for Heap Allocation in Rust

Rust's Box<T> is a smart pointer that moves data from the stack to the heap. It's essential for creating recursive types, like linked lists, whose size would otherwise be infinite. The main footgun is in FFI: never wrap a C-allocated pointer in a Box.

advanced2 min read

Go's sync.Map: A Specialized Concurrent Map

Go's sync.Map is a concurrent map optimized for keys written once and read many times. It's ideal for long-lived caches, but it's not a generic replacement for a map with a mutex. The footgun is using it for frequent writes, which can be slower.

advanced2 min read

Rust's Rc<T>: Shared Ownership on a Single Thread

Rust's Rc<T> enables shared ownership within a single thread. Think of it as a counter on a heap-allocated resource: cloning an Rc increments the count, and the resource is freed only when the count hits zero. Use it for graph nodes with multiple owners.

advanced2 min read

Rust's Arc<T>: Share Data Ownership Across Threads

Rust's Arc<T> lets multiple threads share ownership of heap data. It's a smart pointer that counts references atomically. Use it for shared caches or config. The footgun: Arc only makes sharing safe, not mutation—you still need a Mutex for that.

advanced2 min read

Go's `internal` Directory: Private by Convention

Go's internal directory creates private packages within your module, making them inaccessible to external projects. Use it for helper logic you don't want to support as a public API.

advanced2 min read

Rust Cargo Workspaces: A Monorepo Control Panel

A Cargo Workspace is a control panel for a multi-crate Rust project, unifying dependencies and build artifacts. Use it for related binaries and libraries to ensure consistent builds.

advanced2 min read

Go's GC: Low-Latency Collection with Tri-color Marking

Go's GC uses a tri-color algorithm to find unused memory concurrently, avoiding long pauses. It's crucial for low-latency services. The main footgun is breaking the invariant: a 'finished' (black) object must never point to a new (white) one without notifying…

advanced2 min read

Rust's Interior Mutability: Mutating 'Immutable' Data

Interior mutability lets you modify data through an immutable reference, moving Rust's borrow checks from compile-time to runtime. It's used in single-threaded code when the compiler can't verify safe access.

advanced2 min read

Rust's NLL: Smarter Borrows Based on Use, Not Scope

Non-Lexical Lifetimes (NLL) make Rust's borrow checker smarter. A borrow's lifetime ends after its last use, not at the end of its code block. This allows modifying data after a borrow is finished, even if the reference variable is still in scope.

advanced2 min read

Go's Panic/Recover: For Exceptional Errors Only

Go's panic/recover is a last-resort error mechanism, not a try/catch replacement. A panic unwinds a goroutine's stack until a recover in a defer'd function catches it. It's used to keep a server alive when one request fails catastrophically.

advanced2 min read

Rust's `panic!`: When to Crash Your Program Intentionally

Rust's panic! is an emergency stop for unrecoverable bugs, intentionally crashing the current thread. It's for impossible states where continuing is dangerous, not for recoverable errors like failed I/O—use Result for that.

advanced2 min read

Composable Error Types with `thiserror` in Rust

thiserror generates boilerplate for custom Rust error types, letting you define specific, matchable errors for a library. Use it when callers need to handle different failure modes. The footgun is using it for simple app errors where anyhow would suffice.

advanced2 min read

Rust Associated Types: One Trait, One Concrete Type

Associated types link a placeholder type to a trait, ensuring any implementation provides one specific type. This cleans up code, like in Rust's Iterator trait. The footgun: a type can only implement a trait with an associated type once.

advanced2 min read

Rust Marker Traits: Properties as Types

Marker traits are empty labels telling the Rust compiler about a type's capabilities, like being copyable or thread-safe. They have no methods; their presence is the signal. They're key for concurrency (Send/Sync) and memory (Copy/Sized) safety checks.

advanced2 min read

Send vs. Sync: Rust's Thread Safety Contracts

Send means a value can move to another thread; Sync means references to it can be shared. They are the compiler's contracts for preventing data races. The compiler checks them when you spawn threads.

advanced2 min read

CSP: Model Concurrency with Message Passing

CSP treats concurrency as isolated processes talking through channels, not threads fighting over shared memory. It shaped Go, Erlang, and occam. Engineers often retrofit shared-state patterns into channel-based code and reintroduce race conditions.

advanced2 min read

Go's Memory Model: Don't Be Clever

Go guarantees your program behaves predictably—as if on one CPU—if you prevent data races. Use channels or sync primitives to serialize access when goroutines share data. The footgun is relying on timing instead of explicit synchronization.

advanced2 min read

Rust's Scoped Threads: Borrowing Across Threads Safely

Scoped threads let you borrow local variables from a parent thread without complex wrappers. The scope guarantees all spawned threads are joined before it exits, satisfying the borrow checker. Use it to parallelize work on stack data.

We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.

See open roles