Append с новым массивом и небезопасное чтение через unsafe

Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.

Короткий ответ

Что ответить на собеседовании

Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.

Подробный разбор

Ответ с пояснениями

Условие

func TestSlice(t *testing.T) { s := make([]any, 0, 2) s = append(s, 1, 2) // 1 2 len(2) cap(2)

modifySlice(s, 3)
log.Printf("1: %+v", s)

sPtr := unsafe.Pointer(unsafe.SliceData(s))
a := (*[10]any)(sPtr)
log.Printf("2: %+v", *a) // 0 0 3 <nil>....

s = append(s, 4)
log.Printf("3: %+v", s) // 0 0 4

}

func modifySlice(s []any, v any) { s = append(s, v) s[0] = 0 s[1] = 0 }

Ответ

Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.

После такого unsafe-чтения корректный дальнейший вывод гарантировать нельзя: возможны авария и произвольные данные. Если удалить unsafe-блок, последний append даст [1 2 4]. Изменения нулевых элементов происходили в новом локальном массиве modifySlice, поэтому комментарии [0 0 ...] неверны. Читать десять элементов из массива на два элемента нельзя.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее