Встречается на 25% собеседований по Go
Что такое context в Go
Пакет context в Go предоставляет стандартный механизм для управления временем жизни операций, их отменой и передачи контекстно-зависимых данных. Он является ключевым инструментом для разработки надёжных конкурентных программ, позволяя контролировать выполнение горутин и предотвращать утечки ресурсов.
Как это работает
context позволяет создавать цепочки контекстов, где родительский контекст может отменять дочерние. Основные возможности:
- Управление временем жизни: задание дедлайнов или таймаутов для операций (например, HTTP-запросов, обращения к БД).
- Отмена операций: отмена родительского контекста автоматически отменяет все дочерние, что удобно для распределённых систем.
- Передача данных: через
WithValueможно передавать запрос-специфичные данные (идентификаторы, токены), хотя это не основное назначение.
Основные функции
| Функция | Описание |
|---|---|
context.Background() | Пустой контекст, корень всех контекстов. |
context.WithCancel(parent) | Создаёт дочерний контекст с функцией cancel, которая отменяет его и всех потомков. |
context.WithDeadline(parent, time) | Отменяется автоматически в указанное время. |
context.WithTimeout(parent, duration) | Отменяется через указанный интервал времени. |
context.WithValue(parent, key, val) | Добавляет пару ключ-значение для передачи данных. |
Пример
go
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Создаём контекст с таймаутом 2 секунды
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // вызываем cancel при выходе из main
go func() {
select {
case <-time.After(1 * time.Second):
fmt.Println("operation succeeded")
case <-ctx.Done():
fmt.Println("operation canceled")
}
}()
time.Sleep(3 * time.Second) // ждём дольше таймаута
}В этом примере горутина ждёт 1 секунду, но контекст отменяется через 2 секунды. Так как операция завершается раньше, выводится "operation succeeded". Если бы операция длилась дольше таймаута, контекст бы отменился, и мы увидели бы "operation canceled".
Подводные камни
- Всегда вызывайте
cancel: даже если контекст с таймаутом,defer cancel()предотвращает утечку ресурсов. - Не храните контекст в структурах: передавайте его первым аргументом в функции.
- Не используйте
WithValueдля передачи необязательных параметров: это делает код менее читаемым. - Не игнорируйте
ctx.Done(): если функция блокируется, она должна реагировать на отмену.
Когда использовать
- При работе с HTTP-серверами: каждый запрос получает свой контекст.
- При вызовах к внешним сервисам или БД: ограничение времени ожидания.
- При запуске горутин, которые должны останавливаться по сигналу.
Коротко
contextуправляет отменой, таймаутами и передачей данных.- Основные функции:
WithCancel,WithDeadline,WithTimeout,WithValue. - Всегда вызывайте
cancel, чтобы избежать утечек. - Передавайте контекст первым аргументом в функции.
- Следите за
ctx.Done()в длительных операциях.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы
