Потокобезопасный вывод уникальных элементов из массива с использованием карты

Инициализируйте 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 будет выведено один раз, порядок не задан. Здесь «неповторяющиеся» означает удаление дублей, а не числа, встречающиеся ровно один раз; для второго смысла нужен подсчёт частот.

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

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

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

Подробнее