Skip to content
tezvyn:

Top 30 Rust Interview Questions and Answers

30 multiple-choice questions on Rust, drawn from 30 bites out of the 190 tagged Rust on Tezvyn. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.

30 questions. Pick an answer, or open “Show the answer” to read it.

Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.

  1. Question 1 of 30

    When evaluating a new cloud infrastructure project, which statement accurately reflects the trade-off between using Rust versus Go?

    Show the answer

    Answer: a · Rust provides deterministic latency and compile-time data-race safety at the cost of a steeper learning curve, whereas Go trades runtime GC overhead for simplicity and faster onboarding.

    B is correct because it accurately pairs Rust's deterministic, zero-cost memory safety and compile-time data-race prevention with its steeper learning curve, while recognizing Go's GC introduces runtime overhead in exchange for simplicity and faster onboarding. C is a tempting distractor because Go does automate memory reclamation, but its GC does not prevent data races—memory safety and concurrency safety are distinct, and Go leaves more thread-safety responsibility to the developer.

    Read the full bite: Compare Go's GC and Rust's ownership across performance, productivity, and safety

  2. Question 2 of 30

    What is a key advantage of Rust's philosophy of bundling its official documentation with the language installation?

    Show the answer

    Answer: c · It guarantees developers have immediate, offline access to comprehensive learning materials.

    The card states that bundling the documentation ensures every user has immediate, offline access to a high-quality learning resource. Option D is incorrect because documentation adds to the download size, it doesn't reduce it.

    Read the full bite: Rust's Philosophy: Documentation and Community First

  3. Question 3 of 30

    You add a new variant to an error type during a large refactor. Why does Rust typically surface every place needing an update more reliably than Go?

    Show the answer

    Answer: d · Rust's exhaustive match makes non-updated handling sites fail to compile

    Adding an enum variant makes existing exhaustive matches incomplete, so Rust's compiler flags each site. Go's error values do not force callers to branch, so it does not flag missed sites; Rust does not auto-rewrite code.

    Read the full bite: Refactoring under Go simplicity versus Rust correctness

  4. Question 4 of 30

    When a developer wants to abstract over a third-party type, which difference between Go interfaces and Rust traits is most significant?

    Show the answer

    Answer: d · Go lets a consumer define an interface that the third-party type implicitly satisfies, while Rust requires an explicit impl block to bind the trait to the type.

    Go uses structural typing, so a consumer can define an interface that an existing third-party type automatically satisfies without any declaration; Rust uses nominal typing, requiring an explicit impl block. Distractor A reverses these exact mechanics, reflecting the common misconceptions that Go needs explicit declarations and that Rust traits are implicit.

    Read the full bite: Compare Go interfaces with Rust traits

  5. Question 5 of 30

    Which statement accurately contrasts the safety responsibilities you assume when using unsafe in Rust versus Go?

    Show the answer

    Answer: b · Rust's borrow checker still enforces rules on safe code and only five superpowers bypass checks, while Go requires guaranteeing GC reachability and valid memory

    Rust's borrow checker continues enforcing rules on safe code inside unsafe blocks; only the five superpowers bypass checks, while Go unsafe requires manual cooperation with the GC to ensure reachability and valid memory. Distractor A is wrong because the borrow checker is not fully disabled, and D is wrong because Rust still requires upholding aliasing invariants and Go unsafe enables pointer arithmetic.

    Read the full bite: Contrast unsafe in Go versus Rust and the invariants you assume

  6. Question 6 of 30

    If you write let x = 5 in Rust and x := 5 in Go, which statement about mutability is correct?

    Show the answer

    Answer: c · The Rust declaration is immutable, while the Go declaration allows reassignment without extra keywords

    Rust makes bindings immutable by default, so let x = 5 cannot be reassigned without let mut, while Go variables declared with := or var are mutable by default. Option D is a common misconception because both var and := create mutable bindings in Go, and true immutability requires const.

    Read the full bite: How does Go's variable declaration and mutability differ from Rust?

  7. Question 7 of 30

    What is the main mechanical difference between Go's for i := 1; i <= 5; i++ and Rust's for i in 1..=5?

    Show the answer

    Answer: a · Go uses a C-style control statement that manually manages the index, while Rust consumes an iterator hiding index management.

    Go's for is a control statement with explicit initialization, condition, and increment, whereas Rust's for consumes an iterator produced by the inclusive range. Option D is a tempting distractor because both loops look similar, but claiming they are semantically identical misses the statement-driven versus iterator-based gap.

    Read the full bite: Write a 1-to-5 loop in Go and Rust

  8. Question 8 of 30

    Which accurately describes a key difference between Go's switch and Rust's match?

    Show the answer

    Answer: d · Rust match is an expression that yields a value and requires exhaustive patterns, while Go switch is a statement with implicit breaks and no exhaustiveness check.

    Rust match evaluates to a uniform value and the compiler rejects non-exhaustive patterns, whereas Go switch is statement-oriented, auto-breaks, and never checks exhaustiveness. Option B is tempting but wrong because Go implicitly breaks unless fallthrough is explicit, and Rust match arms never fall through.

    Read the full bite: Compare Go's switch with Rust's match on exhaustiveness, fallthrough, and expressions.

  9. Question 9 of 30

    What is the immediate consequence when ownership of a variable is moved to a function in Rust?

    Show the answer

    Answer: a · The original variable becomes invalid and cannot be accessed further.

    When ownership is moved, the original variable is invalidated, as the card states 'Once you've given it away, it's no longer yours to use' and the example demonstrates a compile error for subsequent use. Option D is incorrect because for complex types like String, ownership is moved, not copied, unless explicitly cloned. Option B is incorrect because the memory is freed when the new owner (the function's parameter) goes out of scope, not immediately upon the move.

    Read the full bite: Rust Ownership: Memory Safety Without a Garbage Collector

  10. Question 10 of 30

    When passing a string to a function by value, why is Go's operation cheap while Rust's String may require explicit cloning?

    Show the answer

    Answer: c · Go strings are small two-word headers copied by value with immutable backing data, whereas Rust String moves ownership and must be cloned to duplicate its heap buffer.

    Go strings are small two-word headers (pointer and length) that are cheaply copied by value while remaining immutable, whereas a Rust String owns its heap buffer and moves ownership by default, so duplicating it requires an explicit clone. Option D is tempting because copy-on-write is common in other languages, but Rust String is uniquely owned and Go strings do not use reference counting.

    Read the full bite: Compare Go string and Rust &str/String types, mutability, UTF-8, ownership

  11. Question 11 of 30

    Which scenario correctly describes a fundamental rule enforced by Rust's borrow checker for memory safety?

    Show the answer

    Answer: a · You can have either one mutable reference or any number of immutable references to data, but not both simultaneously.

    The borrow checker enforces that you can have either one mutable reference OR multiple immutable references to a piece of data at any given time, but never both, preventing data races. Option D is incorrect because the borrow checker strictly disallows multiple mutable references to the same data concurrently, regardless of the function scope.

    Read the full bite: Rust's Borrow Checker: Memory Safety at Compile Time

  12. Question 12 of 30

    What happens if a caller ignores the error when parsing a string to an integer in Go versus Rust?

    Show the answer

    Answer: d · Go compiles silently because error checking is purely conventional, while Rust emits a must-use warning since Result is enforced by the type system

    Go relies on programmer discipline to check the second error return value, so ignored errors compile silently. Rust's Result is must-use, so the compiler warns if it is not handled via match or ?; distractor A reverses these roles.

    Read the full bite: Parse a string to integer in Go and Rust with errors

  13. Question 13 of 30

    What is the primary benefit of defining a Rust trait, such as Summary with a summarize method, and implementing it for multiple distinct types?

    Show the answer

    Answer: b · It allows writing generic functions that can operate on any type that fulfills the Summary contract, promoting code reuse.

    The card states traits enable "writing generic functions that can accept any type that fulfills a certain contract," which directly leads to code reuse and abstraction. Option D is a tempting distractor because traits can have default implementations, but the primary benefit isn't the automatic provision of a default, but rather the ability to treat different types uniformly based on their shared behavior.

    Read the full bite: Rust Traits: Defining Shared Behavior

  14. Question 14 of 30

    When you create b[1:4] from a Go slice b, how does the resulting value compare to borrowing &v[1..4] from a Rust Vec?

    Show the answer

    Answer: d · The Go result is a new three-word header sharing the original array, while the Rust result is a two-word borrowed slice with no capacity field.

    Go slicing creates a new header (pointer, length, capacity) that points into the same underlying array, whereas Rust's &[T] is a two-word fat pointer without capacity because it is only a borrowed view. Distractor B is tempting because one might assume slicing copies data, but Go only copies the descriptor and shares the backing array.

    Read the full bite: Describe Go slice internals and compare to Rust slice and Vec

  15. Question 15 of 30

    When auditing a request-rate counter that may overflow, which statement accurately distinguishes how Rust and Go handle fixed-width integer overflow by default in production release builds?

    Show the answer

    Answer: d · Rust panics on overflow only in debug builds and wraps in release like Go; Rust offers wrapping_ methods for explicit modular arithmetic

    Rust panics on integer overflow in debug builds but wraps silently in release builds, mirroring Go's default behavior, and the wrapping_ methods explicitly opt into modular arithmetic in any mode. Option B is tempting because many candidates mistakenly believe Rust always panics, but it actually wraps in release, and saturating_ clamps to bounds rather than preventing debug panics.

    Read the full bite: Default integer overflow behavior in Go versus Rust

  16. Question 16 of 30

    When a Rust function attempts to parse user input that might be malformed, which error handling approach is most appropriate?

    Show the answer

    Answer: b · Returning a Result<T, E> enum, allowing the caller to handle the potential parsing failure gracefully.

    The card specifies that Result<T, E> should be used for expected failures like parsing user input, which are conditions outside the program's direct control. panic! is reserved for unrecoverable programmer bugs, not anticipated external data issues.

    Read the full bite: Rust's Two Error Types: Recoverable vs. Unrecoverable

  17. Question 17 of 30

    When designing a lookup function that may not find a value, what distinguishes Rust's Option<&T> from Go's *T at the type-system level?

    Show the answer

    Answer: c · Option<&T> explicitly encodes absence while &T remains non-null, costing no extra space via the null pointer optimization.

    Option C is correct because Rust references are non-null by construction, and Option<&T> uses the null pointer optimization to represent None without extra memory, forcing compile-time handling of absence. Option A is a common misconception because Option is an algebraic data type with semantic guarantees that Go's implicit nullability lacks, not merely syntactic sugar.

    Read the full bite: Go nil pointers vs Rust Option: impact on signatures and safety

  18. Question 18 of 30

    What characteristic most directly prevents an abstraction from being considered 'zero-cost'?

    Show the answer

    Answer: b · It necessitates runtime data or dynamic dispatch.

    An abstraction is not zero-cost if it requires runtime information, such as dynamic dispatch or allocations, because the compiler cannot prove it away entirely. While many function calls (option C) might seem costly, they can often be inlined and optimized away at compile time, which is a hallmark of zero-cost abstractions.

    Read the full bite: Zero-Cost Abstractions: Pay at Compile Time, Not Runtime

  19. Question 19 of 30

    Regarding variable mutability, what is the fundamental difference between Rust and Go?

    Show the answer

    Answer: d · Rust variables are immutable by default and need an explicit keyword for mutability, whereas Go variables are mutable by default.

    The card explicitly states that Rust variables are immutable by default and require the 'mut' keyword to become mutable, while Go variables are mutable by default. Option A incorrectly swaps the default behaviors of the two languages.

    Read the full bite: Go vs. Rust: Variable Mutability by Default

  20. Question 20 of 30

    Which statement correctly contrasts the scope of a Go if initializer's := binding with a Rust let binding inside a block?

    Show the answer

    Answer: b · In Go, a variable declared with := in an if initializer is visible in both the if and else branches but not outside, while in Rust, a let binding inside a block is strictly confined to that block.

    The card states that Go's if initializer creates bindings visible in every branch of that if but not outside, whereas Rust's let inside a block is confined to that block. Option C reverses these scope rules, and option D repeats the common misconception that := always mutates rather than potentially shadowing.

    Read the full bite: Shadowing in Go and Rust: idioms, bugs, and if-block scoping

  21. Question 21 of 30

    Given enum WebEvent { PageLoad, PageUnload, KeyPress(char) }, which line correctly instantiates the KeyPress variant with 'q'?

    Show the answer

    Answer: d · let press = WebEvent::KeyPress('q');

    Rust namespaces enum variants under the type with double colons, so WebEvent::KeyPress('q') is correct. WebEvent.KeyPress('q') is invalid because Rust does not use dot notation for enum variants, unlike some other languages.

    Read the full bite: Define a WebEvent enum with PageLoad, PageUnload, and KeyPress

  22. Question 22 of 30

    What is the fundamental difference between variable shadowing and variable mutation in Rust?

    Show the answer

    Answer: d · Shadowing declares a new variable that makes the previous one inaccessible, while mutation modifies the value of an existing variable in place.

    Shadowing creates a completely new variable, potentially allocating new memory, making the original inaccessible. Mutation, however, changes the value of an existing variable in its current memory location. Option B describes when to use each, not the fundamental difference in their operation.

    Read the full bite: Rust's Variable Shadowing: Re-binding, Not Mutating

  23. Question 23 of 30

    You want a Rust function to read a string without taking ownership and accept both a String variable and a literal. Which parameter type achieves this?

    Show the answer

    Answer: b · &str

    &str is a borrowed slice that coerces from &String and accepts literals directly, avoiding clones. &String is wrong because it rejects string literals, forcing callers to allocate a String they do not need.

    Read the full bite: What type replaces String for read-only function parameters in Rust?

  24. Question 24 of 30

    What happens when you call .sum() directly on an iterator of Option<i32> that includes a None?

    Show the answer

    Answer: c · It returns None, short-circuiting the summation

    The Sum<Option<U>> implementation returns None if any element is None, short-circuiting the entire operation. The other choices confuse this behavior with unwrap panics or assume automatic coercion of missing values.

    Read the full bite: Sum Some values in Vec<Option<i32>>, ignoring None

  25. Question 25 of 30

    What is the primary purpose of using Rust's turbofish (`::<>`) or fully qualified syntax?

    Show the answer

    Answer: c · To specify which trait's method to use when multiple traits define methods with the same name for a given type, or to provide type hints for generic functions.

    The card states the turbofish is used to resolve ambiguity when a type implements multiple traits with same-named methods, or to provide type hints for generic functions like `collect()`. Option C accurately describes these scenarios. Option A describes defining generics, not resolving ambiguity during their use.

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

  26. Question 26 of 30

    On a 64-bit architecture, why can reordering struct fields from largest to smallest reduce memory usage in Go and Rust?

    Show the answer

    Answer: b · Compilers preserve source order and insert padding to satisfy alignment, which manual reordering minimizes.

    The correct answer is C because Go and Rust maintain declared field order and insert padding bytes to meet alignment requirements; manually ordering fields by size reduces this internal padding. The most tempting distractor is A because candidates often incorrectly assume compilers automatically optimize struct layout, but the card explicitly states this is a red flag.

    Read the full bite: How does struct field ordering affect memory layout in Go and Rust?

  27. Question 27 of 30

    What is the primary reason Box<T> is essential for defining recursive data structures in Rust?

    Show the answer

    Answer: d · It ensures that the overall size of the recursive type can be determined at compile time.

    The core problem Box<T> solves for recursive types is making their size known at compile time by storing the actual data on the heap and only keeping a fixed-size pointer on the stack. While Box<T> can help prevent stack overflows by moving data off the stack, this is a secondary effect; the primary issue for recursive types is their indeterminate size at compile time.

    Read the full bite: Using Box<T> for Heap Allocation in Rust

  28. Question 28 of 30

    When choosing between an enum and boxed trait objects for a heterogeneous shape collection in Rust, which statement best captures a fundamental architectural difference?

    Show the answer

    Answer: a · Vec<Box<dyn Draw>> stores fat pointers and scatters shape data across heap allocations, while Vec<Shape> keeps all data contiguous with static dispatch.

    Vec<Shape> stores variants contiguously with static dispatch, while Vec<Box<dyn Draw>> uses fat pointers that scatter heap allocations and incur vtable indirection. The distractor claiming dyn Trait inherently requires Box is incorrect because trait objects only require indirection, which can also be provided by references.

    Read the full bite: Compare enum vs trait objects for heterogeneous shapes in Rust

  29. Question 29 of 30

    How do Go and Rust respectively determine whether a function or type is accessible outside its immediate scope?

    Show the answer

    Answer: c · Go exports identifiers that start with an uppercase letter across packages, while Rust uses the pub keyword to make items visible outside their module.

    Go exports uppercase identifiers across packages, while Rust requires explicit pub for module-level visibility. Distractor B is tempting because it correctly names capitalization and pub but wrongly limits Go to file-level scope and Rust to unrestricted crate-wide visibility.

    Read the full bite: How do Go and Rust control visibility of functions and types?

  30. Question 30 of 30

    What happens when a Rust Vec<T> is full and a new item is pushed into it?

    Show the answer

    Answer: a · It allocates a larger memory block, copies all existing items, then adds the new item.

    When a Vec<T> is full, it reallocates by finding a new, larger contiguous memory block, copying all existing elements to it, and then adding the new element. This ensures the vector remains growable. Option D is incorrect because Vec<T> is designed to grow automatically, not to error out when capacity is reached.

    Read the full bite: Rust Vectors: Your Go-To Growable List

Could you explain these out loud?

That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon