What is a slice in Go and how does it differ from an array?
Learn what a slice is in Go, how it differs from a fixed-size array, and how pointer, length, capacity, and append work with shared backing arrays.
Expected Interview Answer
A slice is a flexible, dynamically sized view into an underlying array, described by a pointer, a length, and a capacity. An array in Go has a fixed size that is part of its type, so [3]int and [4]int are different types and arrays are copied by value.
Because a slice holds a pointer to a backing array, passing it around shares the same data rather than copying it, and append can grow it by allocating a larger backing array when capacity runs out. Arrays are rarely used directly; slices are the idiomatic Go collection because they resize with append, share efficiently, and support three-index slicing. Understanding that a slice is a small header referencing shared memory explains subtle bugs where two slices mutate the same backing array.
- Dynamic sizing via append
- Cheap to pass since only a small header is copied
- Shares backing storage instead of copying data
- Supports slicing to create sub-views
- Length and capacity are tracked separately
AI Mentor Explanation
An array is like a fixed 11-player team sheet — the number of slots is locked before the match and cannot grow mid-game. A slice is like the wider squad view: it points into a larger pool of registered players, shows the currently selected window, and can expand up to the squad limit by drawing in reserves without reprinting the whole roster.
Step-by-Step Explanation
Step 1
Declare an array
Use [n]T, e.g. var a [3]int — the size n is fixed and part of the type.
Step 2
Create a slice
Use []T with a literal or make([]T, len, cap), or slice an existing array/slice with a[low:high].
Step 3
Understand the header
A slice is a struct of pointer, length, and capacity referencing a backing array.
Step 4
Grow with append
append adds elements; when capacity is exceeded Go allocates a larger backing array and copies over.
Step 5
Watch shared backing
Slices from the same array share memory, so mutating one can affect another until a reallocation occurs.
What Interviewer Expects
- Knows array size is fixed and part of its type
- Describes a slice as pointer, length, and capacity
- Explains arrays copy by value while slices share backing storage
- Understands append and capacity growth
- Aware of shared-backing-array pitfalls
Common Mistakes
- Saying arrays and slices are the same thing
- Forgetting that arrays are passed by value (copied)
- Confusing length with capacity
- Not realizing two slices can share the same backing array
- Assuming append never allocates a new array
Best Answer (HR Friendly)
“An array in Go has a fixed size decided up front, while a slice is a flexible, resizable view into data that can grow as you add items. Slices are what Go programmers use almost all the time because they are convenient and efficient to pass around.”
Code Example
// Array: fixed size, copied by value
var arr [3]int = [3]int{1, 2, 3}
dup := arr // full copy
dup[0] = 99 // arr[0] still 1
// Slice: dynamic, shares backing array
s := []int{1, 2, 3}
fmt.Println(len(s), cap(s)) // 3 3
s = append(s, 4) // may allocate a bigger backing array
sub := s[0:2] // shares backing with s
sub[0] = 100 // also changes s[0]Follow-up Questions
- What is the difference between length and capacity of a slice?
- What happens to the backing array when append exceeds capacity?
- How does copy() differ from assignment for slices?
- Why can two slices unexpectedly affect each other?
- How does three-index slicing a[low:high:max] work?
MCQ Practice
1. Which statement about Go arrays is true?
An array's length is fixed and encoded in its type, so [3]int and [4]int are distinct types.
2. A slice header consists of:
A slice is a small struct holding a pointer to the backing array, a length, and a capacity.
3. What can happen when append exceeds a slice's capacity?
When capacity is exceeded, Go allocates a larger backing array, copies the elements, and returns the new slice.
Flash Cards
What is a Go slice? — A dynamically sized view into a backing array, described by a pointer, length, and capacity.
How is an array different from a slice? — An array has a fixed size that is part of its type and is copied by value; a slice is resizable and shares backing storage.
What is slice capacity? — The number of elements the backing array can hold from the slice's start before it must grow.
What does append do at full capacity? — It allocates a larger backing array, copies the elements, and returns the new slice.
Why can two slices affect each other? — Slices from the same array share the backing memory, so mutating one changes the other until a reallocation.
Continue Learning
Related Interview Questions
How does the underlying array, length, and capacity of a Go slice work?
medium
How does slice aliasing with append cause surprising bugs in Go, and how do you avoid them?
hard
What is a nil pointer, nil slice, and nil map in Go and how do they behave?
medium
What is the difference between make and new in Go?
easy