Prices shown are a USD base. Your local-market price is calculated at checkout in your own currency, plus any local sales tax.
What is inside
20 chapters, in the order the interviews tend to ask them:
Ownership, borrowing and moves
Lifetimes and how to read them
Traits, generics and associated types
Trait objects, dynamic dispatch and the trade off
Error handling with Result and error types
Panics, unwinding and process boundaries
Box, Rc, Arc and reference counting
Interior mutability with Cell and RefCell
Threads, scoped threads and joining
Channels and message passing
Send, Sync and the concurrency contracts
Atomics, ordering and lock free patterns
Async, await and the Future trait
Tokio, tasks and the multi threaded runtime
Unsafe Rust and justifying it
Zero cost abstractions and iterators
Macros, derive and code generation
Building HTTP services with axum and hyper
Database access, pooling and transactions
Testing, fuzzing and structured observability
How the answers are built
Each chapter opens with the checklist the question is really testing. A few from this pack:
Assigning a non Copy value to a new binding moves it, copying the bytes and invalidating the old binding, so every use of the value stays statically findable.
A lifetime annotation names a region of code that a borrow must outlive; it emits no code and changes nothing about how long a value lives at run time.
A trait describes behaviour a type can provide, and implementing one for your own type is how you extend a generic function or a library without editing it.
A trait object such as `Box<dyn Error>` erases the concrete type and pairs the value with a vtable pointer, so a call becomes a pointer load followed by an indirect call.
Result is an enum with Ok and Err variants, so a failure is a value you can match on, return, store, or inspect, and the compiler will not let you ignore it.
Panicking unwinds the stack by default, running every destructor on the way, so a partially built object and the values it owns are still cleaned up.
Questions this pack covers
What does it actually mean to say that a value has one owner?
Why does assigning a String to a new binding move it instead of copying the bytes?
What does a lifetime annotation actually tell the compiler?
Why do most functions need no lifetime annotations at all?
What is actually different between a Rust trait and a Java interface?
Why are generic functions monomorphised rather than erased the way Java generics are?
What is the real difference between a generic type and a dyn type?
How is a trait object actually laid out in memory?
Each one is answered in full in the pack, with the reasoning written out rather than a bullet list.