2.5Kпросмотров
32.2%от подписчиков
4 февраля 2026 г.
Score: 2.8K
Это один из самых любимых вопросов на Go-собеседованиях. Проверяют, понимаешь ли ты, как устроены slice, len / cap и что реально делает append. Что выведет программа? package main import "fmt" func add(s []int) { s = append(s, 99)
} func main() { a := make([]int, 2, 4) a[0], a[1] = 1, 2 add(a) fmt.Println("a:", a) fmt.Println("a[:3]:", a[:3])
} Разбор go
a := make([]int, 2, 4)
len = 2
cap = 4
underlying array = [1, 2, _, _] Слайс - это структура:
go
pointer -> array
len
cap При передаче в функцию копируется заголовок, но указывает он на тот же массив. Внутри:
go
s = append(s, 99) Так как cap=4, места хватает → новый массив НЕ создаётся.
В память записывается: go
[1, 2, 99, _] Но: s внутри функции: len=3 go
a в main: len=2 Вывод
go
a: [1 2]
a[:3]: [1 2 99] Вопрос 2 (сложнее)
package main import "fmt" func add(s []int) { s = append(s, 99) s[0] = 42
} func main() { a := []int{1, 2} add(a) fmt.Println("a:", a)
} Разбор
go
a := []int{1,2}
len=2
cap=2 Теперь в append места нет → создаётся новый массив. Внутри add:
go
new array = [1 2 99]
s -> указывает на новый массив Но a всё ещё указывает на старый: go
old array = [1 2] Строка: go
s[0] = 42 Меняет новый массив, не старый. Вывод
go
a: [1 2] Главная идея Поведение append зависит от capacity. Условие Что происходит
cap хватает меняется тот же массив
cap не хватает создаётся новый Slice передаётся по значению, но содержит указатель на массив.
append может незаметно "оторвать" его от исходных данных. Как писать безопасно
go
func add(s []int) []int { s = append(s, 99) return s
} a = add(a) Что этим проверяют на собесе • slice ≠ массив
• len vs cap
• устройство slice header
• поведение append
• aliasing памяти Если это не понимать, будут странные баги в продакшене. Запустить код: https://go.dev/play/p/V9KyryLj3TV