Rust: Ownership, Borrowing & Memory Safety
Rust: Ownership, Borrowing & Memory Safety
Up to 20 questions, shuffled on every run
This quiz tests your grip on the parts of Rust that trip up newcomers and pay off later: ownership and moves, borrowing and lifetimes, traits and generics, pattern matching, error handling with Result, smart pointers, fearless concurrency, and the cargo workflow. Take your time, read each option carefully, and use the hint if you get stuck.
Answer key and explanations20 questions
The quiz above draws 20 questions at random from these 28, so a second attempt will not be the same run. Everything in the pool is listed here.
What happens when you assign one String to another variable in Rust, like `let b = a;`?
AnswerOwnership moves to the new variable and the original becomes invalid.
Non-Copy types like String are moved on assignment, so `a` is no longer usable after `let b = a;`.
Which of these types implements `Copy`, so assignment duplicates the value instead of moving it?
Answeri32
Copy is reserved for types that are trivially duplicable bit-for-bit, mostly stack-only primitives.
What does the `Drop` trait do?
AnswerRuns custom cleanup code automatically when a value goes out of scope.
Drop is Rust's RAII hook. It runs deterministically when the value leaves scope.
How many mutable references to the same value can exist at the same time?
AnswerOnly one.
Rust enforces exclusive mutable access, which is the foundation of compile-time data-race prevention.
Can a mutable reference exist at the same time as immutable references to the same value?
AnswerNo, mutable and immutable references are mutually exclusive in the same scope.
At any point, a value has either one mutable reference or any number of immutable ones.
What is the borrow checker?
AnswerA compile-time analysis that enforces ownership and borrowing rules.
The borrow checker runs at compile time. By the time your code runs, the rules are already proven.
What does `&mut T` mean?
AnswerA mutable, exclusive reference to a value of type T.
The `&mut` is the only way to borrow mutably, and it is always exclusive.
What is the purpose of a lifetime annotation like `'a`?
AnswerIt tells the borrow checker how long a reference must remain valid.
Lifetimes are descriptive contracts the compiler checks; they do not influence runtime behavior.
What does the `'static` lifetime mean?
AnswerThe reference is valid for the entire program.
`'static` simply means "lives as long as the program does".
When can you omit lifetime annotations on function references?
AnswerWhenever the compiler can infer them from the standard elision rules.
Lifetime elision is a small set of deterministic rules; if they apply, you can omit the annotations.
What is a trait in Rust?
AnswerA shared interface that types can implement, similar to an interface or type class in other languages.
Traits are how Rust models polymorphism and abstract behavior.
What does `impl Trait` mean when used as a return type?
AnswerThe function returns some concrete type that implements the trait, without naming it.
`impl Trait` lets you hide the concrete type while guaranteeing it implements the trait.
What is the key difference between `dyn Trait` and `impl Trait`?
Answer`dyn Trait` is dynamic dispatch through a vtable; `impl Trait` is static dispatch resolved at compile time.
Choose `impl Trait` for monomorphized, zero-overhead generics; choose `dyn Trait` when you need runtime polymorphism.
What does `#[derive(Debug)]` do?
AnswerAuto-generates an implementation of the `Debug` trait so you can format with `{:?}`.
`derive` is a procedural macro that writes a trait impl for you when the type's fields support it.
What does "exhaustiveness" mean in a `match` expression?
AnswerThe match must cover every possible value of the scrutinee, often by using `_` for the rest.
The compiler enforces exhaustiveness so adding a new enum variant flags every match that needs updating.
When would you reach for `if let` instead of `match`?
AnswerWhen you need to handle only one specific pattern and ignore everything else.
`if let` is sugar for a `match` that only cares about one arm and ignores the rest.
What does the `_` pattern do inside `match`?
AnswerIt matches any value without binding it, acting as a catch-all.
`_` is the wildcard pattern; it matches and discards, with no binding.
What is the `Result<T, E>` type?
AnswerAn enum with `Ok(T)` for success and `Err(E)` for failure.
Returning `Result` makes the possibility of failure visible in the function's type signature.
What does the `?` operator do?
AnswerIt returns early from the function on an `Err` (or `None`), propagating the value to the caller.
`?` is the ergonomic way to chain fallible calls without nested `match`.
When should you `panic!` instead of returning a `Result`?
AnswerFor programmer bugs and unrecoverable states. `Result` is preferred for expected failures.
Use `Result` for fallible operations and `panic!` for genuine bugs the program cannot reasonably recover from.
What does `Box<T>` do?
AnswerAllocates a value on the heap with a single owner.
Use Box when you need heap allocation, recursive types, or trait objects (`Box<dyn Trait>`).
What is the difference between `Rc<T>` and `Arc<T>`?
Answer`Rc` is single-threaded reference counting; `Arc` uses atomic counters and is safe across threads.
Use Rc inside a single thread; reach for Arc only when you actually share across threads.
What does `RefCell<T>` enable?
AnswerInterior mutability with runtime borrow checking that can panic on violation.
RefCell is for the rare cases where you need mutation behind a shared reference in single-threaded code.
What do the `Send` and `Sync` marker traits mean?
Answer`Send` types can be transferred across thread boundaries; `Sync` types can be safely shared between threads via references.
Send and Sync are auto-traits the compiler uses to prove your program is free of data races.
What's the recommended primitive in `std` for passing messages between threads?
AnswerA channel from `std::sync::mpsc`.
Channels follow the "do not communicate by sharing memory; share memory by communicating" pattern.
Why is Rust's concurrency model called "fearless concurrency"?
AnswerThe ownership system and `Send`/`Sync` traits catch data races and many concurrency bugs at compile time.
The phrase captures Rust's promise: you can refactor concurrent code without fearing data races sneaking in.
What is `cargo`?
AnswerRust's package manager and build tool. It also runs tests, builds docs, and publishes crates.
Cargo is the central entry point for working with Rust projects.
What is `Cargo.toml`?
AnswerA configuration file declaring a package's metadata, dependencies, and build settings.
`Cargo.toml` is the manifest; `Cargo.lock` is the lockfile.








