Является ли новый слайс после добавления элементов копией или ссылкой в Go
Что проверяют
Понимаете ли вы, что слайс это заголовок из указателя, длины и ёмкости, и что append иногда переиспользует старый массив, а иногда выделяет новый. Вопрос про алиасинг: от ответа зависит, появится ли в коде тихая порча данных.
Как отвечать
Правильный ответ: как получится, и решает это ёмкость.
Слайс передаётся по значению: копируется заголовок, а не данные. append возвращает новый заголовок. Если длина меньше ёмкости, элемент дописывается в тот же массив, и новый слайс делит память со старым. Если места нет, рантайм выделяет массив побольше, копирует туда элементы и возвращает слайс на новый массив, а старый остаётся сам по себе.
a := make([]int, 2, 4)
b := append(a, 3) // места хватило: общий массив
b[0] = 99 // a[0] тоже стало 99
c := []int{1, 2} // len 2, cap 2
d := append(c, 3) // места нет: новый массив
d[0] = 99 // c[0] не изменилосьОтсюда два вывода. Результат append всегда нужно присваивать, иначе дописанный элемент потеряется. И если нужна независимая копия, её делают явно: slices.Clone, copy в заранее выделенный слайс или срез с тремя индексами вида a[0:2:2], который обрезает ёмкость и заставляет следующий append выделить новый массив.
Коэффициент роста ёмкости в спецификации не зафиксирован и от версии к версии менялся, поэтому в ответе достаточно сказать «растёт кратно», а не называть множитель.
Где спотыкаются
Говорят «слайс это ссылочный тип» и на этом останавливаются. Ссылочных типов в этом смысле в Go нет, есть копируемый по значению заголовок, и именно поэтому функция с append внутри не меняет слайс вызывающего, а функция, пишущая по индексу, меняет.
Режут слайс и дописывают в обрезок: b := a[:2] с последующим append затирает a[2], потому что ёмкость у b осталась от a. Классический источник багов в парсерах и буферах.
Считают, что после append слайсы всегда независимы, и проверяют это на литерале. У литерала ёмкость равна длине, первый же append выделяет новый массив, и пример показывает независимость, которой в общем случае нет.