Каналы

15 вопросов

Каналы - основной механизм коммуникации между горутинами в Go. Буферизованные и небуферизованные, однонаправленные, select, закрытие каналов и типичные паттерны использования.

1 Какой тип возвращает make(chan int, 5)? 🟢 Лёгкий
Ответ: B) chan int

make(chan int, 5) создаёт буферизованный канал с ёмкостью 5. Тип - chan int (двунаправленный). Каналы - ссылочные типы, make возвращает сам канал, не указатель на него.

Подробнее →
2 Что делает блок default в конструкции select? 🟢 Лёгкий
Ответ: B) Выполняется, если ни один канал не готов (неблокирующий select)

select без default блокируется, пока один из каналов не будет готов. С default выполняет default немедленно, если ни один канал не готов. Используется для неблокирующего чтения/записи и try-send паттерна.

Подробнее →
3 Как реализовать таймаут для операции с каналом через select? 🟢 Лёгкий
Ответ: A) Использовать select с case для канала и case <-time.After(d) для таймаута; при истечении d сработает ветка таймаута

Паттерн select + time.After: если данные из канала не приходят за время d, срабатывает ветка таймаута. Для длительных циклов лучше использовать context.WithTimeout.

Подробнее →
4 Что произойдёт при чтении из закрытого канала? 🟡 Средний
Ответ: B) Вернётся zero value

Чтение из закрытого канала не блокирует - возвращается zero value типа элемента. Для проверки: v, ok := <-ch, где ok = false означает "канал закрыт". Цикл for v := range ch автоматически завершается при закрытии.

Подробнее →
5 Что произойдёт при отправке в небуферизованный канал без получателя? 🟡 Средний
Ответ: C) Горутина заблокируется

Небуферизованный канал (make(chan int)) синхронный: отправитель блокируется, пока получатель не прочитает. Если получателя нет - горутина навсегда заблокирована. Если это единственная горутина - deadlock.

Подробнее →
6 Что делает select в Go? 🟡 Средний
Ответ: B) Ожидает операции на каналах

select позволяет ждать на нескольких каналах одновременно. Выполняет первый готовый case. Если несколько готовы - выбирает случайно. С default - не блокирует.

Подробнее →
7 Что произойдёт при отправке в закрытый канал? 🟡 Средний
Ответ: C) panic

Отправка в закрытый канал вызывает panic: send on closed channel. Закрывать канал должен только отправитель, и только когда больше данных не будет. Получатели не должны закрывать каналы.

Подробнее →
8 Что такое однонаправленный канал chan<- int? 🟡 Средний
Ответ: B) Канал только для записи

chan<- int - канал, в который можно только отправлять. <-chan int - только получать. Используются в сигнатурах функций для ограничения доступа. Двунаправленный канал автоматически приводится к однонаправленному.

Подробнее →
9 Как дождаться закрытия канала через range? 🟡 Средний
Ответ: B) for v := range ch {}

for v := range ch читает из канала, пока он не закрыт. При закрытии цикл завершается. Самый чистый способ итерации по каналу. Не забудьте закрыть канал, иначе цикл заблокируется навсегда.

Подробнее →
10 Что произойдёт при повторном закрытии канала? 🟡 Средний
Ответ: C) panic

close(ch) при повторном вызове вызывает panic: close of closed channel. Канал можно закрыть только один раз. Проверки "закрыт ли канал" без чтения из него нет.

Подробнее →
11 Что возвращает len(ch) для буферизованного канала? 🟡 Средний
Ответ: B) Количество элементов в буфере

len(ch) возвращает число элементов, находящихся в буфере канала в данный момент. cap(ch) возвращает ёмкость буфера. Для небуферизованного канала len всегда 0. Важно: к моменту использования результата другая горутина может изменить содержимое буфера.

Подробнее →
12 Что делает select {} (пустой select без case)? 🟡 Средний
Ответ: B) Блокирует горутину навсегда

Пустой select без case блокирует горутину навсегда - нет ни одного case, который мог бы сработать. Используется в main, когда вся работа идёт в других горутинах и нужно предотвратить завершение программы. Аналог бесконечного цикла, но без потребления CPU.

Подробнее →
13 Можно ли привести <-chan int обратно к chan int? 🟡 Средний
Ответ: B) Нет, сужение направления необратимо

chan int можно привести к <-chan int (только чтение) или chan<- int (только запись), но обратное невозможно. Это обеспечивает безопасность: получатель не сможет случайно закрыть или записать в канал. Используйте в сигнатурах функций для ограничения доступа.

Подробнее →
14 Когда лучше использовать мьютекс вместо каналов? 🟡 Средний
Ответ: B) Для защиты shared state (кеш, счётчик)

Мьютекс: защита разделяемого состояния (map, counter) - проще и производительнее. Каналы: координация и передача данных между горутинами (pipeline, fan-out). Мьютекс для простого shared state вполне идиоматичен в Go, несмотря на девиз 'share by communicating'.

Подробнее →
15 Что произойдёт: var ch chan int; <-ch? 🔴 Сложный
Ответ: C) Блокировка навсегда (deadlock)

Чтение из nil-канала блокирует горутину навсегда. Если это единственная горутина - runtime обнаружит deadlock. Отправка в nil-канал тоже блокирует навсегда. Это поведение используется в select для динамического отключения кейсов.

Подробнее →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.