Что такое capacity слайса в Go и для чего используется
Что проверяют
Понимаете ли вы, что слайс это структура из трёх полей: указатель на массив, длина и ёмкость. За вопросом стоят две практические темы: лишние аллокации и неожиданное разделение памяти между слайсами.
Как отвечать
Ёмкость это число элементов, которое помещается в подлежащем массиве, считая от первого элемента слайса до конца массива. Длина это сколько элементов сейчас доступно. Пока длина меньше ёмкости, append пишет в тот же массив и возвращает слайс с тем же указателем. Когда места нет, выделяется новый массив, данные копируются, а старые слайсы продолжают смотреть на прежнюю память.
Отсюда главный практический приём: если размер известен заранее, создавайте make([]T, 0, n) и снимайте серию перевыделений с копированием. Точный закон роста спецификацией не задан: маленькие слайсы примерно удваиваются, после нескольких сотен элементов прирост становится заметно скромнее, и полагаться на конкретное число нельзя.
Второй важный момент: при взятии подслайса ёмкость наследуется до конца массива, поэтому запись через подслайс видна исходному. Трёхиндексная форма ограничивает ёмкость и делает такую запись невозможной.
Где спотыкаются
Считают ёмкость «уже готовыми элементами» и пытаются читать за длиной. Элементы между длиной и ёмкостью существуют в памяти, но недоступны без переслайсинга, и лежит там не обязательно ноль: после урезания слайса это старые значения.
Забывают, что append может и не выделить новую память. Передали слайс в функцию, та дописала элемент, и вызывающий внезапно видит изменённый хвост своих данных. Работает это через раз, в зависимости от запаса ёмкости, поэтому баг ловится не сразу.
Пишут make([]T, n) вместо make([]T, 0, n) и получают n нулей, к которым потом дописывают настоящие значения. Соседняя ошибка: игнорируют возвращаемое значение append, считая, что слайс меняется на месте.