Библиотека Go для собеса | вопросы с собеседований – Telegram
Библиотека Go для собеса | вопросы с собеседований
7.02K subscribers
254 photos
10 videos
1 file
630 links
Вопросы с собеседований по Go и ответы на них.

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

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

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

Наши каналы: https://news.1rj.ru/str/proglibrary/9197
Download Telegram
Как вам вопросы прошедшей недели

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

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍9🔥8😢2
Как отправителю правильно закрыть канал

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

После получения сигнала, отправитель может корректно закрыть основной канал данных:
func main() {
dataCh := make(chan int)
stopCh := make(chan struct{})

go func() {
for {
select {
case data, ok := <-dataCh:
if !ok {
// Канал закрыт, прекращаем обработку
return
}
// Обработка данных
fmt.Println(data)
case <-stopCh:
// Получен сигнал остановки, закрываем канал dataCh
close(dataCh)
return
}
}
}()

// Отправка данных в канал
dataCh <- 1
dataCh <- 2

// Отправка сигнала остановки
stopCh <- struct{}{}
}


🎁 Новогодняя акция: 3 курса по цене 1
🤝
Помощь с выбором курса

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
😁43🤔1
Как писать обёртки для фаззинг-тестов в Go

Фаззинг-тест начинается с func Fuzz и принимает *testing.F:
func FuzzParse(f *testing.F) {
// Seed-корпус
f.Add("valid input")
f.Add("edge case")

// Фаззинг-функция
f.Fuzz(func(t *testing.T, input string) {
result, err := Parse(input)
if err != nil {
return // Ошибка — нормально
}
// Проверки инвариантов
if result == nil {
t.Error("результат не должен быть nil при отсутствии ошибки")
}
})
}


Часто тестируемая функция принимает сложные типы, а фаззер работает только с базовыми: string, []byte, int, bool и несколькими другими. Обёртка конвертирует примитивы в нужные структуры:
func FuzzUserValidation(f *testing.F) {
f.Add("john@example.com", 25, true)

f.Fuzz(func(t *testing.T, email string, age int, active bool) {
// Обёртка: преобразуем примитивы в структуру
user := User{
Email: email,
Age: age,
Active: active,
}

err := ValidateUser(user)
// Проверяем инварианты
if age < 0 && err == nil {
t.Error("отрицательный возраст должен вызывать ошибку")
}
})
}


🎁 Новогодняя акция: 3 курса по цене 1
🤝
Помощь с выбором курса

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Зачем нужен CGO_ENABLED=0 при сборке Go-приложений

Флаг CGO_ENABLED=0 вырубает CGo на этапе компиляции — ваш код собирается полностью на чистом Go, без единой строчки из C-библиотек.

При CGO_ENABLED=1 компилятору нужны C-тулчейн и хедеры для целевой платформы. С CGO_ENABLED=0 просто делаете GOOS=linux GOARCH=arm64 go build — и готово, бинарник для любой архитектуры собран за секунды.

Можно использовать минималистичные образы типа scratch или distroless — приложение запустится даже в контейнере без единой установленной библиотеки.

Убирая C-код, вы автоматически избавляетесь от целого класса уязвимостей: buffer overflow, use-after-free и прочих радостей ручного управления памятью. Плюс код становится действительно платформонезависимым.

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Объясните систему пакетов в Go

Каждый .go файл стартует с декларации package название — это определяет, к какой логической группе относится код.

Пакет с именем main компилируется в исполняемый бинарник. Без main — это библиотеки для переиспользования в других проектах.

Никаких магических автоимпортов — каждую зависимость указываете руками: import "github.com/user/repo/pkg". Go-компилятор сразу видит все связи между модулями.

Простое, но мощное правило:

PublicFunc() — заглавная буква, доступна везде
privateFunc() — строчная буква, видна только внутри пакета

Это работает для всего: функций, типов, структур, переменных. Никаких ключевых слов public/private — компилятор смотрит только на первую букву.

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

Стандартная функция time.Sleep() в Go имеет существенный недостаток — она блокирует выполнение и не реагирует на сигналы завершения работы через context. Горутина замирает на указанное время, игнорируя любые попытки её остановить.

Вместо прямого использования time.Sleep() можно комбинировать select с time.After() и каналом контекста:
select {
case <-time.After(duration):
// Пауза завершилась естественным образом
case <-ctx.Done():
// Контекст отменён — немедленно выходим
return ctx.Err()
}


Такой подход позволяет горутине мгновенно реагировать на отмену контекста.

🎁 Новогодняя акция: 3 курса по цене 1
🤝
Помощь с выбором курса

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
8😁1
«Этот манёвр будет стоить нам 51 год...»

На собеседованиях по Go всё чаще спрашивают не только про горутины и каналы, но и про фундаментальные алгоритмы и архитектуру высоконагруженных систем. Не ждите, пока пробелы в знаниях станут критическими.

В Proglib Academy поднимаются цены. У вас есть шанс зайти на обучение по старой стоимости:

— Разработка ИИ-агентов
— Математика для разработки AI-моделей
— ML для старта в Data Science
— Математика для Data Science
— Специалист по ИИ
— Алгоритмы и структуры данных
— Программирование на Python
— Основы IT для непрограммистов
— Архитектуры и шаблоны проектирования

Забрать базу для собеседований

⚠️ Цены вырастут уже 19 января
Какие основные сущности в планировщике в Go

Планировщик Go реализует модель M:N, где M горутин выполняются на N потоках ОС.

В его основе лежат три ключевые сущности:

G (Goroutines) — это потоки выполнения, основные единицы конкурентности в Go. Они значительно легче потоков ОС и могут создаваться тысячами.

M (Machines) — это потоки операционной системы, которые непосредственно исполняют код на физических ядрах процессора. Они выполняют горутины.

P (Processors) — логические процессоры, которые служат связующим звеном между G и M. Каждый P имеет локальную очередь готовых к выполнению горутин и управляет их распределением. Количество P обычно равно числу доступных ядер CPU.

Горутины хранятся в очередях выполнения— есть локальные очереди у каждого P и одна глобальная.

🎁 Новогодняя акция: 3 курса по цене 1
🤝
Помощь с выбором курса

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

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

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

🐸 Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍5😢3🥱3🔥2
Что происходит при склеивании строк

Строки в Go неизменяемы. При использовании оператора «+» для конкатенации каждый раз создается новая строка в памяти. Это приводит к избыточным аллокациям и падению производительности при частых операциях склеивания.

Для построения строк используйте strings.Builder — он накапливает данные во внутреннем буфере и минимизирует выделение памяти.

Пример с strings.Builder:
var builder strings.Builder
for i := 0; i < 1000; i++ {
builder.WriteString("x")
}
result := builder.String()


🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤‍🔥4
Как можно получить дедлок при работе с горутинами

Deadlock возникает, когда все горутины заблокированы и ждут друг-друга, из-за чего программа не может продолжить выполнение. Рантайм обнаруживает это и завершает программу с ошибкой fatal error: all goroutines are asleep - deadlock!.

Типичные причины дедлоков: отправка в небуферизованный канал без получателя, чтение из канала без отправителя, циклическое ожидание на мьютексах, ожидание на WaitGroup, которая никогда не завершится.

Примеры:
// Пример 1: отправка без получателя
ch := make(chan int)
ch <- 1 // deadlock - никто не читает

// Пример 2: чтение без отправителя
ch := make(chan int)
<-ch // deadlock - никто не пишет

// Пример 3: взаимная блокировка
var mu1, mu2 sync.Mutex
go func() {
mu1.Lock()
mu2.Lock() // ждет mu2
}()
mu2.Lock()
mu1.Lock() // ждет mu1


Используйте select с default или таймауты для предотвращения.

🐸Библиотека Go для собеса
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
ЭТОТ ПОСТ СПАСЕТ ТВОЙ 👩‍💻-СОБЕС

В наше время очень тяжело попасть на собеседование! Поэтому предлагаем вам очень серьезно относиться к ним.
Не упускайте не единое собеседование, готовьтесь к каждому, как к последнему.
Регулярно проверяйте свои hard-skills.
Забирай чек-лист из закрепленного сообщения - 55 вопросов из реальных собесов!

P.S. помимо непосредственно GO, разбираем другие необходимые технологии, про них нельзя забывать!

Помни, что каждое собеседование в 2026 на вес золота!
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1🌚1
Зачем append возвращает слайс

append возвращает слайс, потому что операция добавления элементов может привести к реаллокации базового массива, если текущая capacity недостаточна.

Поэтому если бы append не возвращал слайс, а модифицировал исходный, мы бы потеряли ссылку на новый массив после реаллокации.

Даже если реаллокация не произошла и базовый массив остался тем же, возвращаемый слайс будет иметь обновленную длину.

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