Перейти к содержимому
На этой странице

Context в Go

Все темы Go Developer

Как правильно ждать отмены через Context.Done?

Долгая операция включает ctx.Done() в select рядом с работой или ожиданием. При закрытии канала она прекращает запуск новых действий, освобождает свои ресурсы и возвращает ctx.Err() либо ошибку с сохранённой причиной. Проверку выполняют в местах, где функция способна остановиться; один тест перед началом не отменит уже блокирующий вызов. Downstream API получает тот же context, чтобы отмена дошла до сети и БД. Done может быть nil для context без отмены, и select корректно игнорирует такой case. Функция не должна сама ждать, пока caller прочитает канал.


Как распространять context через цепочку вызовов?

context.Context передают первым параметром, обычно с именем ctx, через всю цепочку request-scoped вызовов. Функция создаёт дочерний context только для более узкого deadline, отмены или значения и обязательно вызывает полученный CancelFunc. HTTP, SQL и RPC операции получают этот context своими context-aware методами. Его не хранят в struct и не заменяют nil; если контекст пока не нужен, передают context.Background() на верхней границе. Отмена родителя распространяется детям, но ребёнок не отменяет родителя. Контекст живёт не дольше запроса и не используется как контейнер всех параметров.


Что допустимо хранить в context.WithValue?

В context.WithValue хранят небольшие неизменяемые request-scoped данные, которые передаются по цепочке вызовов: trace ID, аутентифицированного субъекта или метаданные запроса. Ключ задают собственным неэкспортируемым типом, чтобы пакеты не сталкивались по строке. Значение должно быть дополнительным, а не обязательной зависимостью функции. Конфигурацию, logger, БД, feature options и параметры бизнес-метода передают явно. Нельзя складывать изменяемый объект и ожидать потокобезопасности: context безопасен для конкурентного чтения, но не меняет гарантии самого значения.


Почему нужно вызывать CancelFunc после context.WithTimeout?

WithTimeout создаёт таймер и дочерний context. Вызов cancel раньше дедлайна освобождает связанные ресурсы и сразу сообщает дочерним операциям, что результат больше не нужен. Обычный шаблон: сразу после успешного создания написать defer cancel(). Даже если функция завершилась быстро или вернула ошибку, cleanup выполнится. Автоматическое наступление deadline не заменяет явный вызов в нормальном раннем пути. CancelFunc можно вызывать повторно, но он не ждёт завершения goroutines: они должны слушать Done и самостоятельно закончить работу.


Безопасно ли вызывать cancel несколько раз?

Да. CancelFunc можно вызывать несколько раз, в том числе конкурентно; последующие вызовы не меняют состояние. Канал Done закрывается один раз, а Err после отмены стабильно сообщает причину верхнего уровня. Это позволяет нескольким путям завершения использовать один cancel без отдельной защиты sync.Once. Но cancel не закрывает произвольные пользовательские каналы и не ждёт завершения goroutines. Если нужен join, его делают через errgroup, WaitGroup или другой протокол, а workers обязаны реагировать на Done.


Как передать причину отмены контекста?

context.WithCancelCause возвращает CancelCauseFunc, которому передают содержательную ошибку. context.Cause(ctx) возвращает её для отменённого context и потомков, тогда как ctx.Err() остаётся одной из общих ошибок context.Canceled или context.DeadlineExceeded. Это позволяет отличить «клиент ушёл» от «остановились после ошибки worker», не меняя стандартную проверку отмены. Первая установленная причина сохраняется по правилам распространения родителя и ребёнка; последующий cancel её не перезаписывает. Причина не должна содержать секреты и не заменяет wrapping ошибки на границе операции.

Собеседования: Go

Смотри записи интервью, узнай, какие вопросы задают и как отвечают кандидаты.

Вопросы и ответы

Не нашли ответ? Напишите мне в чат. Я делаю Шпаргалку и сам отвечаю на сообщения. Расскажите, что не работает или чего вам не хватает. Может, смогу сразу взять это в работу.

Откуда взяты вопросы?

Из реальных собеседований. Основой подборки стал опыт Вадима Новосёлова: он проходил интервью и записывал вопросы. Подробнее о материалах.

Насколько эти вопросы актуальны?

Эти вопросы встречались нам на реальных собеседованиях в 2025 году. Мы регулярно проходим собеседования и пополняем подборку новыми вопросами. Основы профессии и ключевые технологии остаются востребованными годами, а детали конкретных инструментов и версий стоит сверять с текущей документацией.

На какой уровень рассчитана подборка?

Мы проходили собеседования на вакансии уровня Middle+, а иногда и на Senior-позиции. Вопросы из этих интервью вошли в подборку. Направления работы: Go-разработчик, Backend-разработчик на Go. Глубина обсуждения зависит от вакансии: будь готов объяснить основную идею, привести практический пример и разобрать ограничения и альтернативы решения.

Этот вопрос точно будет на моём собеседовании?

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