Golang | Вопросы собесов
4.45K subscribers
28 photos
1 video
762 links
Download Telegram
🤔 Что будет, если подставить переменную в массив?

Массивы и слайсы могут использоваться для хранения последовательности элементов одного типа. Когда вы "подставляете" переменную в массив или слайс, вы просто присваиваете значение этой переменной одному из элементов массива или слайса.

Пример с массивом
package main

import "fmt"

func main() {
// Создаем массив из 5 целых чисел
var arr [5]int

// Создаем переменную и присваиваем ей значение
x := 10

// Подставляем переменную в массив
arr[0] = x

// Выводим массив
fmt.Println(arr) // Выводит: [10 0 0 0 0]
}


🚩Объяснение

1⃣Создание массива
Это создает массив arr из 5 целых чисел, все элементы которого инициализируются значением 0.
var arr [5]int   


2⃣Создание переменной
Создаем переменную x и присваиваем ей значение 10.
x := 10   


3⃣Присваивание значения элементу массива
Присваиваем значение переменной x первому элементу массива arr.
arr[0] = x   


4⃣Вывод массива
Выводит содержимое массива, показывая, что первый элемент массива теперь равен 10, а остальные элементы остаются нулями.
fmt.Println(arr)   


Пример со слайсом
package main

import "fmt"

func main() {
// Создаем слайс из 3 целых чисел
slice := make([]int, 3)

// Создаем переменную и присваиваем ей значение
x := 20

// Подставляем переменную в слайс
slice[1] = x

// Выводим слайс
fmt.Println(slice) // Выводит: [0 20 0]
}


🚩Объяснение

1⃣Создание слайса
Это создает слайс slice из 3 целых чисел, все элементы которого инициализируются значением 0.
slice := make([]int, 3)   


2⃣Создание переменной
Создаем переменную x и присваиваем ей значение 20.
x := 20   


3⃣Присваивание значения элементу слайса
Присваиваем значение переменной x второму элементу слайса slice.
slice[1] = x   


4⃣Вывод слайса
Выводит содержимое слайса, показывая, что второй элемент слайса теперь равен 20, а остальные элементы остаются нулями.
fmt.Println(slice)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2👍1
🤔Что такое SOLID:

SOLID — это акроним, описывающий пять основных принципов объектно-ориентированного программирования и дизайна: Single responsibility, Open/closed, Liskov substitution, Interface segregation и Dependency inversion. Эти принципы направлены на создание более понятного, гибкого и поддерживаемого кода.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как защититься от ошибки во время конкурентной записи в 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
👍3
🤔 Какие есть средства обобщённого программирования?

Обобщённое (generics) программирование включает:
- Параметрические типы — функции и структуры с типами-плейсхолдерами.
- Ограничения (where, extends, : T) — накладывают требования на типы.
- Обобщённые интерфейсы и классы.
- Type erasure — скрытие конкретного типа при сохранении поведения. Generics позволяют писать универсальный, повторно используемый код с типовой безопасностью.


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