Golang | Вопросы собесов
4.51K subscribers
34 photos
788 links
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
💊7
🤔 Безопасен ли map?

Нет, карты (maps) в Go не являются потокобезопасными по умолчанию. Использование карты в нескольких горутинах без должной синхронизации может привести к состояниям гонки, некорректным данным и паникам. Давайте рассмотрим более детально, почему это так и как можно обеспечить потокобезопасность при работе с картами в многопоточной среде.

🚩Почему карты в Go не потокобезопасны

Карты в Go разработаны для обеспечения высокой производительности при использовании в однопоточных сценариях. Если несколько горутин одновременно пытаются читать и изменять карту, возникает конкуренция за доступ к данным, что может привести к следующим проблемам:

🟠Состояния гонки
Одновременный доступ к карте из нескольких горутин может привести к состояниям гонки, когда порядок выполнения операций непредсказуем.
🟠Паники
Одновременное изменение структуры карты, например добавление или удаление элементов, может вызвать панику в программе.

🚩Подходы к обеспечению потокобезопасности

🟠Мьютексы (Mutex)
Самый распространенный способ синхронизации доступа к карте — использование sync.Mutex. Мьютексы позволяют заблокировать доступ к карте на время чтения или записи.
package main

import (
"fmt"
"sync"
)

func main() {
var mu sync.Mutex
m := make(map[string]int)
var wg sync.WaitGroup

write := func(key string, value int) {
mu.Lock()
m[key] = value
mu.Unlock()
}

read := func(key string) int {
mu.Lock()
defer mu.Unlock()
return m[key]
}

wg.Add(2)
go func() {
defer wg.Done()
write("key1", 42)
}()
go func() {
defer wg.Done()
fmt.Println(read("key1"))
}()
wg.Wait()
}


🟠RWMutex
Если в вашей программе чаще происходят операции чтения, чем записи, можно использовать sync.RWMutex, который позволяет нескольким горутинам читать данные одновременно, но обеспечивает эксклюзивный доступ для записи.
package main

import (
"fmt"
"sync"
)

func main() {
var mu sync.RWMutex
m := make(map[string]int)
var wg sync.WaitGroup

write := func(key string, value int) {
mu.Lock()
m[key] = value
mu.Unlock()
}

read := func(key string) int {
mu.RLock()
defer mu.RUnlock()
return m[key]
}

wg.Add(2)
go func() {
defer wg.Done()
write("key1", 42)
}()
go func() {
defer wg.Done()
fmt.Println(read("key1"))
}()
wg.Wait()
}


🟠sync.Map
Go предоставляет специальную структуру sync.Map, которая изначально создана для безопасного использования в многопоточной среде. Она автоматически обеспечивает синхронизацию операций.
package main

import (
"fmt"
"sync"
)

func main() {
var m sync.Map
var wg sync.WaitGroup

wg.Add(2)
go func() {
defer wg.Done()
m.Store("key1", 42)
}()
go func() {
defer wg.Done()
value, _ := m.Load("key1")
fmt.Println(value)
}()
wg.Wait()
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3🤔2
🤔 Что можешь сказать о HTTP3?

HTTP/3, работающий на основе QUIC, обеспечивает быструю передачу данных поверх UDP. Для его использования в Go можно применять библиотеки вроде quic-go, позволяющие интегрировать поддержку HTTP/3.


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