Getting Started
Installing Rust, understanding the toolchain, and why every real project goes through Cargo.
Part of Rust Interview Mastery · Based on The Rust Programming Language
Installation & Toolchain
How do you install Rust, and what does rustup actually manage?
You install Rust through rustup, the official toolchain installer — typically curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh. Rustup manages the whole toolchain: rustc (the compiler), cargo (the build system and package manager), the standard library, and tooling like rustfmt and clippy.
Rustup also handles channels — stable, beta, and nightly — and cross-compilation targets. rustup update upgrades everything; rustup self uninstall removes it.
What is the difference between rustc and cargo?
rustc is the compiler: it takes a .rs file and produces a native binary. cargo is the project manager: it invokes rustc with the right flags, resolves and downloads dependencies, runs tests, builds docs, and standardizes project layout.
You can compile hello.rs with rustc hello.rs, but the moment you have a dependency or more than one file, you want Cargo. Every real Rust project — and every interview codebase — is a Cargo project.
Is Rust interpreted or compiled, and what does that imply?
Rust is a compiled, ahead-of-time language. cargo build produces a native executable — there is no VM, no interpreter, no JIT tier like Java or Python.
The consequence that matters in interviews: a Rust binary can be copied to a machine that has no Rust installed and just run. That's also why Rust fits CLI tools, embedded targets, and WASM.
Why does println! end with an exclamation mark?
The ! marks a macro invocation, not a function call. println! expands into generated code at compile time, which is how it accepts a variable number of arguments — functions in Rust can't be variadic.
You'll see the same pattern with vec![], format!, assert_eq!, panic!. Interview follow-up: macros do compile-time code generation; functions do runtime calls.
Cargo & Project Anatomy
What does cargo new actually create?
my_project/
├── Cargo.toml # manifest: metadata + dependencies
└── src/
└── main.rs # binary crate root
cargo new my_project scaffolds the manifest and a hello-world main.rs, and initializes a git repo (with .gitignore) unless you're inside an existing one. cargo new --lib creates a library crate (src/lib.rs) instead.
Explain cargo check vs build vs run vs --release. When do you use each?
- cargo check — typechecks and borrow-checks without producing a binary. Fastest feedback; run it constantly while editing.
- cargo build — compiles a debug binary into target/debug. Unoptimized but has debug info.
- cargo run — build + execute in one step; standard dev loop.
- cargo build --release — full optimizations into target/release; use for benchmarks and shipping.
Interviewers like the check/build distinction because it shows you understand compile-time cost.
What are Cargo.toml and Cargo.lock, and which do you commit?
Cargo.toml is the manifest you edit: package name, version, edition, and [dependencies] with semver ranges like rand = "0.9". Cargo.lock is generated — it records the exact versions Cargo resolved.
Rule: binaries commit the lockfile (reproducible builds), libraries don't (downstream resolves its own). The manifest says intent; the lockfile says what actually got built.
What does the default main function signature look like and what can it return?
fn main() {
println!("Hello, world!");
}
No arguments, unit return type (). Later you'll learn main can return Result<(), E> or ExitCode so the process exits with a proper status — that's how CLIs signal failure to shells.