Проверяет понимание конкурентного доступа к памяти, data race и внутреннего устройства slice.
Slice в Go не потокобезопасен. Если одна goroutine читает, а другая изменяет slice одновременно, возникает data race. Это может привести к повреждению данных или panic.
Slice в Go - это структура, состоящая из трёх частей:
pointer на массив
length
capacity
Если одна goroutine изменяет slice, например через append, возможны два сценария:
данные записываются в существующий массив
runtime выделяет новый массив и копирует данные
Если другая goroutine в это время читает slice, она может:
читать старый массив
читать частично обновлённые данные
читать уже освобождённую память
Это приводит к data race и неопределённому поведению.
Пример проблемы:
var s []int
go func() {
s = append(s, 1)
}()
go func() {
fmt.Println(len(s))
}()Чтобы избежать проблемы используют:
sync.Mutex
sync.RWMutex
каналы
копирование slice
Пример безопасного варианта:
var mu sync.Mutex
mu.Lock()
s = append(s, 1)
mu.Unlock()