Predict the Output of a Go Program That Appends to a Sub-Slice

Read the full interview experience this question came from →

Quick Overview

A Go output-prediction question: a short program takes a sub-slice of a slice, appends to it inside a helper function and prints three slices. It tests how slice headers, length, capacity and shared backing arrays interact with append, and whether a candidate can trace them precisely.

Predict the Output of a Go Program That Appends to a Sub-Slice

Company: Zoox

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Without running it, predict exactly what this Go program prints, and explain why each of the three lines comes out the way it does. ```go package main import "fmt" func foo(a []int) []int { a = append(a, len(a)) return a } func main() { x := []int{1, 2, 3, 0, 0, 0, 0} y := x[:3] z := foo(y) fmt.Println(x) fmt.Println(y) fmt.Println(z) } ``` This was an output-prediction exercise: no conceptual questions up front, just the code and a request for its output. ```hint Track every slice For `x`, `y`, the parameter `a` and `z`, write down the length, the capacity and the backing array each one refers to. ``` ```hint What append does with room to spare Decide whether the `append` inside `foo` has to allocate, and what that means for memory that `x` can also see. ``` ### Clarifying Questions - Do you want only the three printed lines, or also the length and capacity of every slice after each statement? - May I assume the standard formatting of `fmt.Println` for an `[]int`: values separated by spaces inside square brackets? ### What a Strong Answer Covers - The exact three output lines, in order - A slice as a header of pointer, length and capacity that is copied on assignment and on a function call, with each slice's length and capacity traced - The rule for when `append` writes into the existing backing array and when it allocates a new one - Why a write made through one slice is visible through another slice of the same array, while a change of length is not ### Follow-up Questions - What does the program print if `x` is declared as `[]int{1, 2, 3}` instead? - What changes if `main` uses the full slice expression `y := x[:3:3]`? - After `z := foo(y)`, the program also runs `w := append(y, 99)`. What do `z` and `x` print now, and why is this pattern a bug in real code? - How would you change `foo` so that it can never modify a caller's data?

Overview: A Go output-prediction question: a short program takes a sub-slice of a slice, appends to it inside a helper function and prints three slices. It tests how slice headers, length, capacity and shared backing arrays interact with append, and whether a candidate can trace them precisely.

Read the full Zoox Software Engineer interview experience this question came from

Zoox logo
Zoox
Oct 2, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

Without running it, predict exactly what this Go program prints, and explain why each of the three lines comes out the way it does.

package main

import "fmt"

func foo(a []int) []int {
	a = append(a, len(a))
	return a
}

func main() {
	x := []int{1, 2, 3, 0, 0, 0, 0}
	y := x[:3]
	z := foo(y)
	fmt.Println(x)
	fmt.Println(y)
	fmt.Println(z)
}

This was an output-prediction exercise: no conceptual questions up front, just the code and a request for its output.

Clarifying Questions Guidance

  • Do you want only the three printed lines, or also the length and capacity of every slice after each statement?
  • May I assume the standard formatting of fmt.Println for an []int : values separated by spaces inside square brackets?

What a Strong Answer Covers Guidance

  • The exact three output lines, in order
  • A slice as a header of pointer, length and capacity that is copied on assignment and on a function call, with each slice's length and capacity traced
  • The rule for when append writes into the existing backing array and when it allocates a new one
  • Why a write made through one slice is visible through another slice of the same array, while a change of length is not

Follow-up Questions Guidance

  • What does the program print if x is declared as []int{1, 2, 3} instead?
  • What changes if main uses the full slice expression y := x[:3:3] ?
  • After z := foo(y) , the program also runs w := append(y, 99) . What do z and x print now, and why is this pattern a bug in real code?
  • How would you change foo so that it can never modify a caller's data?