Concepts in Go & Rust, page 4
Rust Channels: Thread-Safe Communication
Rust channels are like a thread-safe conveyor belt for sending data between threads. Use them to pass work to workers or aggregate results. The footgun: the receiver blocks forever if any sender isn't dropped, as the channel only closes when all senders are…
Go Channels: Buffered vs. Unbuffered
Unbuffered channels are a synchronous rendezvous, blocking until both sender and receiver are ready. Buffered channels are an async mailbox, letting senders drop messages and go. The footgun is using a buffer to hide a deadlock instead of fixing it.
Rust's async/await: Cooperative Concurrency
Rust's async/await is cooperative concurrency, where tasks explicitly yield control with .await. This is ideal for I/O-bound work like managing thousands of network connections. The biggest footgun: calling an async function without .await does nothing.
Rust Async Runtimes: The Engine for `async/await`
Rust's async/await is just syntax; an async runtime like Tokio is the engine that runs the code. It polls Futures until they complete, managing I/O and scheduling. This is essential for web servers.
Rust's `std::sync::Mutex`: Guarding Shared Data
A Rust Mutex guards shared data, granting access only via a temporary RAII "guard" that auto-releases the lock. It's used inside an Arc for safe multi-threaded mutation.
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.
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.
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.
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.
Go Build: From Source Code to Executable
go build is your factory for turning Go source into a runnable program. It compiles your packages and their dependencies into a single executable. Use it to create a binary for deployment, but don't confuse it with go install which puts the file in your.
cargo build: Compile Your Rust Package and Its Dependencies
Think of cargo build as your project's general contractor. It reads the Cargo.toml blueprint to compile your package and all its dependencies. A common footgun is forgetting it only builds libraries and binaries by default; use --tests for test targets.
cargo test: Rust's All-in-One Test Runner
cargo test is Rust's built-in test runner, automatically discovering and executing unit, integration, and documentation tests. Use it to validate code marked with #[test] and examples in docs.
cargo add: Stop Editing Cargo.toml By Hand
Stop editing Cargo.toml by hand. cargo add lets you add, remove, and modify Rust dependencies from the command line. Use it to pull crates from registries, git repos, or local paths.
go vet: Catch Bugs Compilers Allow
go vet catches suspicious constructs the compiler ignores, like Printf argument mismatches. Run it in CI to spot concurrency and formatting bugs early. It relies on heuristics, so a clean report does not guarantee correctness and false positives can occur.
Cargo Clippy: Your Opinionated Rust Code Reviewer
cargo clippy is an automated code reviewer that goes beyond the compiler, catching subtle bugs, performance issues, and style violations. Run it in CI to enforce idiomatic Rust.
Go Benchmarking: Measure, Don't Guess
Go's benchmark runner finds stable performance numbers by repeatedly calling your code in a loop controlled by b.N. Use it to optimize hot paths or compare algorithm implementations. Forgetting b.ResetTimer() will include setup costs, skewing your results.
Go's Race Detector: Find Concurrency Bugs at Runtime
The Go race detector finds data races by watching memory access at runtime. Use go test -race in CI or on a canary instance, but remember: it only catches races that actually execute. If your tests don't trigger the race, it won't be found.
cargo doc: Turn Code Comments into a Website
cargo doc turns your Rust doc comments into a searchable HTML website for your crate and its dependencies. Use it to generate a local API reference or explore a dependency's API.
Rust Build Scripts: Compiling More Than Just Rust
A build.rs script is a pre-compilation hook for tasks outside Rust's scope, like compiling C code or generating Rust modules. It's essential for FFI or code generation. A key footgun: cfg! checks the host, not the target, breaking cross-compilation.
Rust Cargo Features: Conditional Compilation & Dependencies
Cargo features are compile-time switches for conditional compilation and optional dependencies. They let you build tailored versions of a crate from one source, like an image library that only includes code for the formats you need.
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