> Какие сигналы существуют в операционной системе (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Avito
Стек: Go
> Пример ответа
Короткий ответ
Сигналы - это асинхронные уведомления, которые ОС отправляет процессу для сообщения о событиях: завершении, ошибках, таймерах или пользовательских действиях. В POSIX-системах стандартный набор включает SIGINT, SIGTERM, SIGKILL, SIGHUP, SIGUSR1/2 и другие. В Go runtime перехватывает сигналы и транслирует их в канал os.Signal, позволяя приложению корректно завершиться или выполнить cleanup. Понимание сигналов критично для graceful shutdown и работы с процессами.
Подробное объяснение
Сигналы делятся на несколько категорий:
- Управляющие терминалом: SIGINT (Ctrl+C), SIGQUIT (Ctrl+), SIGHUP (закрытие терминала)
- Завершение: SIGTERM (стандартный запрос на завершение), SIGKILL (безусловное убийство), SIGSTOP/SIGCONT (пауза/возобновление)
- Ошибки: SIGSEGV (нарушение памяти), SIGFPE (арифметическая ошибка), SIGPIPE (запись в закрытый pipe)
- Пользовательские: SIGUSR1, SIGUSR2 - для межпроцессного взаимодействия
- Таймеры: SIGALRM, SIGVTALRM, SIGPROF
Ключевые свойства:
- Асинхронность: сигнал может прийти в любой момент выполнения
- Обработка: default action, ignore, или пользовательский handler
- Блокировка: сигнал можно временно заблокировать, но не отменить
- Доставка: pending signals доставляются после разблокировки
В Go runtime:
- Сигналы обрабатываются на уровне runtime, а не напрямую через syscall
signal.Notify(ch, sig...)регистрирует канал для получения сигналовsignal.Stop(ch)отменяет регистрациюsignal.Ignore(sig...)игнорирует сигналыsignal.Reset(sig...)возвращает default behavior
Особенности Go:
- SIGKILL и SIGSTOP нельзя перехватить - это ограничение ОС
- Go runtime сам обрабатывает SIGSEGV, SIGBUS и другие для panic
- SIGPIPE по умолчанию вызывает завершение программы, но в Go это поведение изменено для stdout/stderr
На практике
Для backend-приложений на Go наиболее важны:
- Graceful shutdown: перехват SIGTERM и SIGINT для корректного завершения HTTP-сервера, закрытия соединений с БД, завершения in-flight запросов
- Reload конфигурации: SIGHUP часто используется для перезагрузки конфигов без остановки процесса
- Управление воркерами: SIGUSR1/SIGUSR2 для динамического изменения числа горутин или уровня логирования
- Дочерние процессы: необходимо пробрасывать сигналы в дочерние процессы и учитывать их статусы
Типичный паттерн graceful shutdown:
- Создать канал для сигналов
- Запустить HTTP-сервер в горутине
- В main-горутине ждать сигнал
- Вызвать
server.Shutdown(ctx)с таймаутом
Пример кода
GOpackage mainimport ("context""fmt""net/http""os""os/signal""syscall""time")func main() {// Канал для сигналовsigChan := make(chan os.Signal, 1)signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)// HTTP-серверsrv := &http.Server{Addr: ":8080"}go func() {fmt.Println("Server started")if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {fmt.Printf("Server error: %v\n", err)os.Exit(1)}}()// Ожидание сигналаsig := <-sigChanfmt.Printf("Received signal: %v\n", sig)// Graceful shutdown с таймаутомctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()if err := srv.Shutdown(ctx); err != nil {fmt.Printf("Shutdown error: %v\n", err)}fmt.Println("Server stopped gracefully")}
Как отвечать на собеседовании
Начни с определения сигналов как асинхронных уведомлений. Перечисли основные категории и приведи примеры для каждой. Обязательно упомяни разницу между SIGTERM и SIGKILL - это частый вопрос.
Затем переходи к Go-специфике: как runtime обрабатывает сигналы, зачем нужен signal.Notify, какие сигналы нельзя перехватить. Подчеркни практическую важность - graceful shutdown.
Если спросят про низкоуровневые детали, расскажи про блокировку сигналов, pending signals и разницу между обработкой в Go и C. Для senior-позиции важно показать понимание того, как сигналы взаимодействуют с планировщиком Go и горутинами.
Что проверяет интервьюер
- Понимание базовой модели сигналов в POSIX
- Знание конкретных сигналов и их назначения
- Умение применять сигналы на практике (graceful shutdown)
- Понимание особенностей обработки сигналов в Go runtime
- Способность объяснить, почему SIGKILL нельзя перехватить
- Понимание различий между сигналами и другими механизмами IPC
Типичные ошибки
- Путаница между SIGTERM и SIGKILL: SIGTERM можно обработать, SIGKILL - нет
- Забывают, что
signal.Notifyнужно вызывать до запуска сервера - Не используют буферизованный канал для сигналов - можно потерять сигнал
- Пытаются перехватить SIGKILL или SIGSTOP
- Не учитывают, что
signal.Stopне закрывает канал - Путают
signal.Ignoreиsignal.Reset - Не обрабатывают ошибку
srv.Shutdown- игнорируют таймаут - Думают, что сигналы в Go работают так же, как в C - не учитывают особенности runtime
> Похожие задачи по Go
Какую архитектуру и технологии использовать для реализации клиента чата с REST API?
Как описать схему базы данных для модели библиотеки с сущностями автор, книга, читатель и связями между ними
Происходит ли копирование данных при передаче слайса и массива в функцию в Go
Расскажите про опыт оптимизации
> Похожие задачи по backend
Какую архитектуру и технологии использовать для реализации клиента чата с REST API?
Как описать схему базы данных для модели библиотеки с сущностями автор, книга, читатель и связями между ними
Происходит ли копирование данных при передаче слайса и массива в функцию в Go
Какие типы данных относятся к мутабельным, а какие к немутируемым
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью