Инициализируйте map и защищайте проверку с добавлением одной критической секцией. Передавайте число аргументом горутины и ждите все горутины через WaitGroup.
Потокобезопасный вывод уникальных элементов из массива с использованием карты
Инициализируйте map и защищайте проверку с добавлением одной критической секцией. Передавайте число аргументом горутины и ждите все горутины через WaitGroup.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо изменить программу так, чтобы:
- из среза
numsвыводились только неповторяющиеся числа; - для контроля уникальности использовалась карта;
- решение корректно работало в многопоточной среде с горутинами.
package main
import (
"log"
)
func main() {
nums := []int{3, 3, 2, 1, 2, 1, 1, 2, 4}
var uniqMap map[int]struct{}
for _, num := range nums {
go func() {
if _, ok := uniqMap[num]; ok {
return
}
uniqMap[num] = struct{}{}
log.Println(num)
}()
}
}
Ответ
Инициализируйте map и защищайте проверку с добавлением одной критической секцией. Передавайте число аргументом горутины и ждите все горутины через WaitGroup.
Основная часть с импортами log и sync:
nums := []int{3, 3, 2, 1, 2, 1, 1, 2, 4}
seen := make(map[int]struct{})
var mu sync.Mutex
var wg sync.WaitGroup
for _, num := range nums {
wg.Add(1)
go func(n int) {
defer wg.Done()
mu.Lock()
_, exists := seen[n]
if !exists { seen[n] = struct{}{} }
mu.Unlock()
if !exists { log.Println(n) }
}(num)
}
wg.Wait()
Каждое из 1,2,3,4 будет выведено один раз, порядок не задан. Здесь «неповторяющиеся» означает удаление дублей, а не числа, встречающиеся ровно один раз; для второго смысла нужен подсчёт частот.