Skip to content

Expert · Rust careers and interviews · topic 48 of 50 · 35 min

Interview questions: ownership, borrowing and lifetimes

Explanation

Almost every Rust interview starts with ownership. Be ready to explain the three ownership rules, move versus copy versus clone, the borrowing rules and why they prevent data races, String versus &str, what lifetimes mean and when you must write them, and why a function cannot return a reference to a local variable. Answer in short sentences with a tiny example.

How to answer

Interviewers want to see that you understand why, not just that you memorised rules. A good structure: one-sentence definition, the reason it exists, a two-line example, and a common mistake. Practise saying answers out loud; explaining clearly is a skill.

Q1. What is ownership?

Model answer: "Ownership is how Rust manages memory without a garbage collector. Each value has one owner; there is one owner at a time; when the owner goes out of scope the value is dropped. The compiler checks this, so double frees and leaks from forgotten frees are prevented at compile time."

Q2. Move, Copy and Clone: what is the difference?

Model answer: "Assigning a heap-owning value like String moves it: only the pointer, length and capacity are copied and the old variable becomes invalid, to avoid a double free. Small stack-only types that implement Copy, such as integers and bool, are copied and both stay valid. clone() is an explicit deep copy that duplicates the heap data and costs time and memory."

Q3. What are the borrowing rules, and why?

Model answer: "At any time you can have either any number of shared references or exactly one mutable reference, and references must always be valid. This prevents data races and bugs like modifying a collection while iterating it. The checks happen at compile time, so there is no run-time cost."

Q4. String versus &str?

Model answer: "String owns growable UTF-8 text on the heap. &str is a borrowed view of some UTF-8 text: it can point into a String, a literal or another slice. I take &str as a function parameter because it accepts both, and return String when the function creates new text."

Q5. What is a lifetime? When do you write one?

Model answer: "A lifetime is the region of code where a reference is valid. The compiler infers most of them through elision rules. I write them when the compiler cannot tell how an output reference relates to the inputs, for example a function taking two &str and returning one of them, or a struct that holds a reference. Annotations describe relationships; they never extend how long anything lives."

rust
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str {
    if a.len() >= b.len() { a } else { b }
}
The classic example to write on the whiteboard.

Q6. Why can a function not return a reference to a local variable?

Model answer: "The local is dropped when the function returns, so the reference would dangle. The compiler rejects it (E0106 or E0515). The fix is to return an owned value, like String, so ownership moves to the caller."

Q7. What are non-lexical lifetimes?

Model answer: "Since Rust 2018, a borrow lasts until its last use, not until the end of its block. So you can take a shared reference, use it, and then take a mutable one in the same block."

Q8. What does 'static mean?

Model answer: "As a lifetime on a reference, &'static T means the data lives for the entire program, like string literals. As a bound, T: 'static means the type holds no non-static references, which is why thread::spawn requires it: the thread might outlive any borrowed data."

Common interview mistakes

  • Saying "Rust has no memory management". It has automatic, deterministic memory management through ownership.
  • Saying a lifetime annotation "makes a value live longer". It does not.
  • Saying clone is always bad. It is fine when data is small or a copy is truly needed; just know its cost.
  • Long, rambling answers. Define, explain why, show a tiny example, stop.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Interview questions: ownership, borrowing and lifetimes · 1/7

Define → Why → Example → Mistake

Almost every Rust interview starts with ownership. Answer with a definition, the reason, a tiny example, and a common mistake.

Prefer a video by a teacher? Find free videos on “rust interview questions ownership borrowing lifetimes” on YouTube ↗

In real life: A typical live-coding question

An interviewer at a fintech company shares this snippet and asks: "Why does this fail, and how would you fix it?" A strong candidate explains that the shared borrow first is still used after push needs a mutable borrow (E0502), that push may reallocate and leave first dangling, and offers two fixes: copy the value out, or use it before the push.

rust
fn main() {
    let mut balances = vec![500, 1200];
    let first = &balances[0];
    balances.push(300);          // error[E0502]
    println!("{first}");
}
// Fix 1: let first = balances[0];   (copy the i32)
// Fix 2: print first before calling push
Explaining why it is dangerous is what earns the marks.

Practice (0/3 done)

Task 1 · Question

An interviewer asks: "Does a lifetime annotation make a value live longer?" Which answer is correct?

Task 2 · Question

Which is the best one-line explanation of why Rust moves a String on assignment?

Task 3 · Practice

Record yourself (phone voice memo) answering Q1 to Q8 from this topic, each in under 60 seconds. Listen back and mark where you hesitated. Then rewrite your weakest two answers and record them again.

Quick quiz

Question 1

1.Which statement about non-lexical lifetimes is correct?

Question 2

2.Why does thread::spawn require 'static data?

Question 3

3.What is the best fix for "returns a reference to data owned by the current function"?

Question 4

4.Which parameter type is most flexible for read-only text?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which statement about non-lexical lifetimes is correct?

Answer: Borrows last until their last use

NLL ends borrows at their last use.

Why does thread::spawn require 'static data?

Answer: The thread may outlive any borrowed local data

Spawned threads can run after the caller returns.

What is the best fix for "returns a reference to data owned by the current function"?

Answer: Return an owned value

Move ownership out instead of borrowing a local.

Which parameter type is most flexible for read-only text?

Answer: &str

&str accepts literals, Strings and slices.

The compiler suggests adding 'static to a returned reference to a local String. What is usually the right fix?Related

Answer: Return the owned String instead

A local String is dropped at the end of the function; returning ownership is the clean fix.

From Lifetimes

What happens if you call a blocking function inside a tokio task?Related

Answer: It can stall other tasks on that worker thread

Blocking work belongs in spawn_blocking.

From Interview questions: traits, errors, pointers and concurrency

Which type should a ViewModel expose for screen state?Related

Answer: StateFlow

Read-only, always has a value.

From Interview questions: Kotlin

Which constructor type can return a cached instance?Related

Answer: factory

Factories decide what to return.

From Interview questions: Dart

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Rust careers and interviews” before its exam: Interview questions: traits, errors, pointers and concurrency, Portfolio, open source and a learning plan.
  2. Module 12 exam: Rust careers and interviews · 10 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. 50 topics left in the course before the final exam.

← Previous: Where Rust is used and the job market