Intermediate interview questions in Go & Rust, page 3
Why must FFI-bound structs use #[repr(C)] and what breaks without it?
Repr(C) fixes field order, size, alignment to C rules for extern calls; omitting it lets Rust reorder or pad fields, causing UB.

Explain the performance overhead of a cgo call
Tests cgo transition penalties and scheduler semantics. A strong answer cites the ~100x overhead (~171ns vs ~1.8ns), notes C blocks an OS thread and starves the scheduler, and warns about memory copy taxes. Red flag: claiming cgo is free or ignoring blocking.
Passing Go/Rust callbacks to a C library
C needs a plain function pointer; in Go use //export with cgo, in Rust an extern "C" fn; carry state via a void* user-data param.
Logging middleware wrapping an http.Handler in Go
Middleware has signature func(http.Handler) http.Handler, records start time, calls next.ServeHTTP, then logs method, URL, and elapsed duration; chaining works because the wrapper is itself a…
Static dispatch over Write with generics in Rust
Write generically over the std::io::Write trait with a type parameter W: Write, letting the compiler monomorphize and inline per concrete type, avoiding the vtable indirection of Box<dyn Write>.
Using context.Context across microservice calls in Go
Context carries cancellation, deadlines, and values; pass ctx as first arg, set one WithTimeout at the edge, attach a request ID via WithValue, thread it through downstream calls so all cancel…
Rust Send and Sync marker traits explained
Send means a value can move across threads, Sync means a reference can be shared; Rc uses non-atomic refcounts, Arc uses atomic ones.
Fearless concurrency: Rust compile-time vs Go runtime
Rust uses ownership plus Send/Sync to reject data races at compile time; Go encourages channels but still allows races, with the runtime race detector catching them at test…
Rust lifetimes versus Go garbage-collected lifetimes
A lifetime is a compile-time region a reference is valid for; annotations like 'a relate input and output reference durations; Go instead uses garbage collection and escape analysis.
Criterion: the standard Rust benchmarking library
Criterion runs on stable Rust, collects many samples, applies statistical analysis with confidence intervals, and compares against saved baselines to detect regressions.
Structural Go interfaces versus nominal Rust traits
Go interfaces are satisfied implicitly by method shape (structural); Rust traits must be explicitly implemented (nominal).
Goroutines and channels versus ownership-based concurrency
Go uses cheap goroutines and CSP-style channels to coordinate by communication; Rust uses ownership plus Send/Sync to make data races a compile error.
Go (T, error) versus Rust Result for error handling
Go returns a separate error value you may ignore; Rust wraps success or error in one Result enum the compiler forces you to handle. Go favors simplicity, Rust favors compile-enforced safety.
Go interface-constraint generics versus Rust trait bounds
Go constrains type parameters with interfaces and may use dictionaries/shape stenciling; Rust uses trait bounds with full monomorphization for zero-cost specialization.
Go's mandatory runtime versus Rust's minimal runtime
Go ships a GC and goroutine scheduler in every binary, ideal for services; Rust has only a tiny runtime and no GC, enabling embedded, kernels, and WASM.
Go interfaces versus Rust traits and macros at scale
Go uses reflection over interface{} (e.g. encoding/json) for runtime flexibility; Rust uses traits plus derive/proc macros (e.g. serde) for compile-time, zero-cost code generation.
Go slices versus Rust Vec growth and reallocation
Both are a (pointer, length, capacity) triple over a heap buffer that reallocates and copies on growth, roughly doubling; key difference is Go slices share backing arrays and have no ownership…
Designing a logging abstraction: Go interfaces vs Rust traits
Define a Logger interface/trait with a write method; Go interfaces are always dynamically dispatched; Rust lets you choose static dispatch (impl Trait/generics) or…
Go if err != nil versus Rust's ? operator
Go's explicit checks are verbose but make every error site visible; Rust's ? propagates concisely while still forcing the error into the type, reducing boilerplate.
anyhow versus thiserror in Rust error handling
Anyhow gives one opaque dynamic error type for applications where you mostly propagate and report; thiserror derives concrete typed enums for libraries so callers can match on variants.
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