Библиотека Go для собеса | вопросы с собеседований
6.83K subscribers
218 photos
5 videos
1 file
387 links
Вопросы с собеседований по Go и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/0b524a15

Для обратной связи: @proglibrary_feeedback_bot

Наши каналы: https://t.iss.one/proglibrary/9197
Download Telegram
Какие основные типы context в Go вы знаете

Go предоставляет функции, которые позволяют создавать производные контексты на основе базового
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()


WithCancel — вручную отменяет контекст
WithTimeout — отменяет через заданный интервал времени
WithDeadline — отменяет к заданному моменту времени
WithValue — добавляет пару ключ/значение в контекст (использовать осторожно)

Каждая из этих функций создаёт дочерний контекст, и если родитель будет отменён — отменятся и все дочерние.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🥱1
Зачем в реализации Singleton использовать sync.Once, если уже есть мьютексы

Если вы хотите простую, лаконичную и безопасную реализацию — используйте sync.Once
package main

import (
"fmt"
"sync"
)

type singleton struct {
config string
}

var (
once sync.Once
instance *singleton
)

func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{config: "default"}
})
return instance
}

func main() {
s := GetInstance()
fmt.Println("Singleton config:", s.config)
}

sync.Once гарантирует, что переданная функция будет выполнена строго один раз, даже если GetInstance вызывается из множества горутин.

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

Не подходит, если вам нужно сбрасывать или пересоздавать Singleton (например, в тестах)
Once работает только один раз за весь жизненный цикл приложения

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2
Как правильно использовать ctx.Done() внутри горутин и что произойдёт, если этого не делать

Контекст используется как сигнальный канал. Правильно обрабатывать ctx.Done() нужно всегда, особенно в горутинах
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("goroutine stopped:", ctx.Err())
return
case <-time.After(1 * time.Second):
fmt.Println("working...")
}
}
}(ctx)


Если не слушать ctx.Done(), вы получите:
• Утечки горутин
• Зависание приложения
• Недетерминированное поведение при отмене


🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
Как вам вопросы прошедшей недели

Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.

Также приветствуется фидбек в комментариях.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥137🥱1
Почему инициализация через init() не считается ленивой

Иногда экземпляр Singleton можно создавать заранее, при старте пакета. В Go для этого существует функция init().

Singleton с init() в действии
package main

import (
"fmt"
)

type singleton struct {
config string
}

var instance *singleton

func init() {
instance = &singleton{config: "preloaded"}
}

func GetInstance() *singleton {
return instance
}

func main() {
s := GetInstance()
fmt.Println("Singleton config:", s.config)
}


➡️ Особенности подхода:
• Инициализация происходит один раз, до выполнения main() — автоматически
• Синхронизация не требуется init() вызывается в однопоточном контексте
• Порядок инициализации между пакетами гарантирован Go-рантаймом

➡️ Подходит для простых случаев:
Объект всегда нужен в программе
Конфигурация не зависит от внешнего ввода
Важна простота, а не гибкость

➡️ Недостатки
Нарушает ленивую загрузку — объект создаётся даже если не используется
Затрудняет подмену или настройку из внешнего источника (например, через флаги, файлы, ENV)
Может ограничить тестируемость и повторную инициализацию

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁42👍1
Как правильно использовать context в юнит-тестах

context — мощный инструмент, но в тестах он может мешать, особенно если используется без ограничений по времени или отмене.

Чтобы избежать зависаний и утечек в юнит-тестах, всегда создавайте context с таймаутом:
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()


Это гарантирует:
Тест не будет висеть бесконечно
Ресурсы будут высвобождены
Горутины получат сигнал на завершение


Если ваш тест зависает — это может говорить о том, что где-то в коде игнорируется ctx.Done()

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Какой способ инициализации Singleton в Go выбрать: sync.Mutex, sync.Once или init()

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3
Зачем использовать select, если можно просто читать из канала

В Go оператор select — это конкурентный аналог switch, предназначенный исключительно для работы с каналами.

С его помощью можно:
• Ждать сразу несколько операций с каналами (чтение/запись)
• Управлять конкурентными потоками без блокировок
• Не блокироваться, если добавить
default ветку

select {
case msg := <-ch1:
fmt.Println("Received from ch1:", msg)
case ch2 <- 42:
fmt.Println("Sent 42 to ch2")
default:
fmt.Println("Nothing ready")
}


Если ch1 или ch2 готовы — будет выполнен соответствующий case.
Если ни один канал не активен — выполняется default, и select не блокирует выполнение.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🤔1
Можно ли сделать Singleton тестируемым без нарушения его природы

Singleton может мешать тестированию, так как его состояние живёт весь runtime. Но есть обходные пути:

1️⃣ Вынос в интерфейс
type Storage interface {
Get(key string) string
}


2️⃣ Инъекция зависимости через параметр
func ProcessData(s Storage) { ... }


3️⃣ Сброс состояния Singleton (в тестах)
// В тестовых сборках
func resetSingleton() {
instance = nil
once = sync.Once{}
}


Warning: сброс Singleton — антипаттерн, но допустим в юнит-тестах

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤔1
Как реализовать приоритет между каналами, если select выбирает случайно

Одно из важных свойств select в Go — рандомность выбора, если сразу несколько каналов готовы к операции.
select {
case msg := <-ch1:
fmt.Println("ch1:", msg)
case msg := <-ch2:
fmt.Println("ch2:", msg)
}


Если и ch1, и ch2 доступны — Go случайным образом выберет один case.
Это исключает жёсткий приоритет каналов и распределяет нагрузку справедливо (не детерминированно).

Это нужно для предотвращения "голодания" менее приоритетных каналов, также это позволяет реализовать честные очереди и worker pool без ручного балансировщика

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁9👍3🌚2
Что такое отношение happens-before в модели памяти Go

Отношение happens-before гарантирует упорядоченность и видимость операций между разными горутинами. Если операция A happens-before операции B, то все записанные до A значения памяти гарантированно будут видны при выполнении B.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁2🎉1
Как вам вопросы прошедшей недели

Оцените их по шкале 🔥,❤️,👍,😢, 🥱,
где 🔥 — это супер, а 🥱 — это скучно.

Также приветствуется фидбек в комментариях.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥10😢74👾1
Как Redis реализует сохранение данных на диск

Redis поддерживает два механизма сохранения данных: Redis Database Dump, который сохраняет данные в момент времени, и Append-Only File, который записывает каждую операцию записи.

Эти два метода могут использоваться вместе для достижения компромисса между производительностью и надежностью.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3
Go-сервис генерирует логи, но вы теряетесь в поиске и анализе?
Хотите научиться строить быстрый и надёжный поиск по данным микросервисов?

📅 17 июля в 20:00 (МСК) — открытый урок «Взаимодействие микросервиса на Go и Elasticsearch»

Разберём:
▪️ Архитектуру микросервисов на Go и ключевые нюансы
▪️ Базовые принципы работы с Elasticsearch
▪️ Интеграцию Go-сервиса с Elasticsearch для логирования и поиска
▪️ Настройку индексов, фильтрацию и агрегации

Представьте, что вы разворачиваете микросервис, подключаете его к Elasticsearch, логируете события и выдаёте мгновенный полнотекстовый поиск по данным. Ваш сервис становится прозрачным и управляемым.

🚀 Регистрируйтесь на урок «Взаимодействие микросервиса на Go и Elasticsearch»: https://clc.to/sTcjRQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Какие правила happens-before действуют для атомарных операций из пакета sync/atomic

Атомарная операция Store happens-before последующей атомарной операции Load той же переменной (при отсутствии иных атомарных модификаций между ними).

Инициализация всех глобальных переменных happens-before старту функции main(), что гарантирует корректные первоначальные значения при запуске программы.

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM