Appendix
Keywords, operators, derivable traits, dev tools, and editions — the reference material interviews pull from.
Part of Rust Interview Mastery · Based on The Rust Programming Language
Keywords & Language Surface
How does Rust categorize keywords, and what are the edge cases?
Three buckets: active keywords (fn, let, match, unsafe, impl...), reserved for future use (abstract, become, do, final, try, yield — can't be used as identifiers today, may gain meaning later), and weak/contextual (union, 'static, raw) that are keywords only in specific contexts.
You can still use reserved names via raw identifiers: r#match, r#try — needed when calling libraries written in an older edition where the word wasn't a keyword yet.
Which operators are overloadable in Rust, and through what?
Arithmetic + - / % → std::ops::{Add, Sub, Mul, Div, Rem}; comparison == != < > <= >= → PartialEq/PartialOrd; bitwise & | ^ << >> ! → BitAnd/BitOr/BitXor/Shl/Shr/Not; compound += -= etc → AddAssign family; deref → Deref; [] index → Index/IndexMut; ? → the Try/FromResidual machinery (internal). Function-call () → Fn/FnMut/FnOnce (unstable to impl directly).
Not overloadable: &&/|| (short-circuit semantics), =/== distinction, .. ranges (a syntax construct that produces Range types). The rule: everything overloadable is a trait — that's the whole design.
Derivable Traits
Which standard traits can be derived, and which do you derive by default on a domain type?
Derive-able: Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default.
Sensible defaults for a plain data struct: #[derive(Debug, Clone, PartialEq)] — Debug for logging/tests, Clone for flexibility, PartialEq for assertions. Add Eq/Hash when it's a HashMap key; PartialOrd/Ord when it sorts; Copy only for small stack-types (breaking-change: fields must all be Copy); Default when a zero-state is meaningful.
Don't derive reflexively: Clone on a Connection type is a design decision, not boilerplate.
What's the semantic difference between PartialEq/Eq and PartialOrd/Ord?
PartialEq = equality where some values may not compare (float NaN != NaN); Eq = total equality — every value equals itself (no NaN equivalent). Eq is a marker on top of PartialEq: implementing Eq asserts reflexivity.
Same shape for ordering: PartialOrd allows unordered pairs (NaN again), Ord is total. Consequence: HashMap keys need Eq+Hash; BTreeMap keys and sort() need Ord; sort_by accepting partial_cmp exists for floats (with the classic f64::total_cmp workaround for float sorting).
Tooling & Editions
What ships in the Rust toolchain beyond the compiler?
- rustfmt / cargo fmt — official formatter; rustfmt.toml for config
- clippy / cargo clippy — 700+ lints on style/perf/correctness; the community's accumulated wisdom as a linter
- rust-analyzer — the IDE brain (LSP): completion, go-to-def, inline hints; powers VS Code / Zed / etc
- rustdoc — docs generator; powers docs.rs
- miri — undefined-behavior interpreter for unsafe code (finds UB the compiler can't)
- cargo-{fix,expand,audit,...} — the extension ecosystem
The point to hit in interviews: the tooling is uniform — rustup component add clippy and it's the same version across teams/CI; format wars are settled upstream.
What are Rust editions and what changed between 2015, 2018, and 2021?
Editions are opt-in dialects per crate (edition = "2021" in Cargo.toml) — they let Rust make breaking syntax changes without breaking the ecosystem; crates in different editions interoperate.
- 2015: the original — required extern crate.
- 2018: extern crate mostly unnecessary, async/await keywords (sync fns on older code couldn't use them), dyn Trait mandatory in trait objects, path clarity (crate::).
- 2021: disjoint closure captures, IntoIterator for [T;N], panic macro consistency, TryFrom/Or_patterns in prelude, reserved gen.
(Beyond book scope: 2024 adds gen blocks prep, lifetime-capture rules, unsafe in extern blocks. New crates default to 2024.)
What's the difference between compile-time and runtime guarantees — summarize the book's worldview in one answer.
The book's thesis in one line: Rust pushes correctness left — into types, ownership, and the borrow checker — so runtime failures become compile errors.
Compile-time: ownership/drop, borrow rules, lifetimes, exhaustive match, Send/Sync, macro expansion, monomorphization, Result forcing acknowledgment of errors. Runtime: bounds checks (panic not UB), RefCell borrow rules (panic not UB), Arc refcounting, Mutex locking, allocator behavior. Even the runtime parts stay defined — a bug panics loudly rather than corrupting memory silently. That worldview is what "fearless" means across the whole book.