Golang | Вопросы собесов
4.76K subscribers
31 photos
970 links
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2
🤔 Как защититься от ошибки во время конкурентной записи в map?

В Go обычный map не потокобезопасен. Если несколько горутин одновременно записывают в map, возникнет ошибка "fatal error: concurrent map writes".
Решение: использовать синхронизацию через sync.Mutex, sync.RWMutex или sync.Map.

🚩Использование `sync.Mutex` (мьютекс)

Блокируем доступ на запись и чтение через sync.Mutex.
package main

import (
"fmt"
"sync"
)

type SafeMap struct {
mu sync.Mutex
m map[string]int
}

func (s *SafeMap) Set(key string, value int) {
s.mu.Lock() // Блокируем доступ
defer s.mu.Unlock()
s.m[key] = value
}

func (s *SafeMap) Get(key string) int {
s.mu.Lock() // Блокируем на чтение
defer s.mu.Unlock()
return s.m[key]
}

func main() {
safeMap := SafeMap{m: make(map[string]int)}
var wg sync.WaitGroup

for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
safeMap.Set(fmt.Sprintf("key%d", i), i)
}(i)
}

wg.Wait()
fmt.Println("Готово:", safeMap.Get("key5")) // Получаем значение без гонок данных
}


🚩Использование `sync.RWMutex` (оптимизация для чтения)

sync.RWMutex позволяет нескольким горутинам читать одновременно, но блокирует запись.
type SafeMap struct {
mu sync.RWMutex
m map[string]int
}

func (s *SafeMap) Set(key string, value int) {
s.mu.Lock() // Блокируем только на запись
defer s.mu.Unlock()
s.m[key] = value
}

func (s *SafeMap) Get(key string) int {
s.mu.RLock() // Разрешаем множественное чтение
defer s.mu.RUnlock()
return s.m[key]
}


🟠Использование `sync.Map` (встроенный потокобезопасный `map`)
sync.Map из стандартной библиотеки уже потокобезопасен, но работает немного медленнее обычного map из-за внутренних механизмов.
package main

import (
"fmt"
"sync"
)

func main() {
var m sync.Map

var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
m.Store(i, i*10) // Потокобезопасная запись
}(i)
}

wg.Wait()

val, ok := m.Load(5) // Потокобезопасное чтение
if ok {
fmt.Println("Значение:", val)
}
}


Использование канала (`chan`) вместо `map`
Вместо map можно передавать данные через канал (chan), если логика позволяет.
package main

import (
"fmt"
)

func main() {
ch := make(chan map[string]int, 1)
ch <- make(map[string]int)

go func() {
m := <-ch
m["key"] = 42
ch <- m
}()

m := <-ch
fmt.Println(m["key"]) // 42
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Forwarded from Идущий к IT
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рутиной

📺 Видео: https://youtu.be/G_FOwEGPwlw
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Внутреннее устройство интерфейса?

Интерфейс состоит из двух частей: указателя на динамический тип и указателя на данные, связанные с этим типом. Такая структура позволяет интерфейсу хранить и управлять значениями разных типов динамически.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1