Go slices versus Rust Vec growth and reallocation
understanding of dynamic-array internals.
both are a (pointer, length, capacity) triple over a heap buffer that reallocates and copies on growth, roughly doubling; key difference is Go slices share backing arrays and have no ownership…
What's really being asked
It verifies you understand the pointer/length/capacity model of dynamic arrays, the amortized reallocation behavior on growth, and the ownership and aliasing differences between the two languages.
The full answer
Both types are a three-word header: a pointer to a contiguous heap-allocated buffer, a length (number of initialized elements), and a capacity (allocated slots). Reading and indexing are O(1). When you append beyond capacity, neither can grow in place reliably, so each allocates a new, larger buffer, copies the existing elements over, updates the pointer and capacity, and (in Rust) frees the old buffer. Growth is amortized O(1): the capacity grows by a multiplicative factor, commonly close to doubling for small sizes and a smaller factor as the slice gets large, so the total copying cost across many appends stays linear.
Key difference
A Go slice is a lightweight view into a backing array; multiple slices can share and alias the same array, and slicing does not copy. The slice does not own the array, and the garbage collector reclaims it. A Rust Vec<T> uniquely owns its buffer; ownership and borrowing rules prevent aliasing mutation, and the buffer is freed deterministically when the Vec is dropped. To get a non-owning view in Rust you use a slice type &[T].
The mistakes people make
Saying capacity equals length. Claiming the buffer grows in place without copying. Saying Go slices own their backing array, or forgetting that appending to a Go slice can leave other slices pointing at the old array.
What usually comes next
Why can appending to one Go slice silently stop reflecting in another that shared the array? What is the difference between Vec<T> and &[T]? How do you preallocate to avoid reallocations (make with capacity, Vec::with_capacity)?
A concrete example
In Go, b := append(a, x) may, if a is at capacity, allocate a new array and copy, so b and a then point at different arrays; if there was spare capacity, they share, and mutating b can affect a. In Rust, v.push(x) on a full Vec allocates a larger buffer, copies, frees the old one, and because the Vec owns the buffer exclusively, no other reference could have been aliasing it.
Interview question
What is a key difference between a Go slice and a Rust Vec<T> beyond their shared pointer/length/capacity layout?
- a.A Go slice is a non-owning view that can alias a shared backing array; a Vec uniquely owns its bufferCorrect
- b.Go slices store elements non-contiguously
- c.Rust Vec never reallocates while Go slices always do
- d.Vec has no capacity field
Why? this is the answer
Both reallocate and copy on growth, but a Go slice is a view that can share/alias a backing array it does not own, whereas Vec exclusively owns and frees its contiguous buffer. Both store elements contiguously with a capacity.
Just read this? Test yourself on what you have been reading.
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
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.
We are hiring for this. Open roles that interview on go — each one lists the topics its interview covers.
See open roles