сеньорчикОткрыть в Telegram
← все вопросывопросы для собеседований · Ошибки и рантайм Go

Вопросы по обработке ошибок и рантайму Go на собеседовании

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

63 вопросов в банке·10 подтем·ниже разбор 9

Из чего состоит тема

Так тема разложена в тренажёре: движок ведёт прогресс по каждой подтеме отдельно и возвращает те, где вы ошибаетесь.

Разборы подтем

Конспект по каждой: что это, как отвечать вслух, на чём валятся, плюс вопросы для самопроверки.

Примеры вопросов с разбором

  1. #go_defer1 / 9
    В каком порядке выполнятся три defer в одной функции?
    A)Строго в порядке объявления: первый отложенный выполнится первым
    B)В случайном порядке, определяемом планировщиком
    C)В обратном порядке (LIFO): последний отложенный — первым
    D)Все одновременно и параллельно при выходе из функции
    показать ответ и разбор
    +C)В обратном порядке (LIFO): последний отложенный — первым

    // разбор: defer'ы кладутся в стек и выполняются в порядке LIFO — последний отложенный первым — при выходе из функции (нормальном или из-за паники). Это удобно для симметричного освобождения ресурсов: открыл A, потом B — закроются B, потом A. Спот-чек: цикл с defer напечатал 2 1 0.

  2. #go_err_idiom2 / 9
    Как Go по соглашению сообщает об ошибке из функции?
    A)Бросает исключение, которое ловят try/catch выше по стеку
    B)Возвращает error последним значением, а вызывающий проверяет его
    C)Пишет в глобальную errno, как в C, и возвращает −1
    D)Логирует ошибку сам и возвращает нулевое значение без сигнала наружу
    показать ответ и разбор
    +B)Возвращает error последним значением, а вызывающий проверяет его

    // разбор: В Go ошибки — обычные значения: функция возвращает error последним результатом (nil, если всё хорошо), а вызывающий обязан его проверить: if err != nil. Исключений с раскруткой стека для штатных ошибок нет (panic — для по-настоящему исключительного). Отсюда явный, пусть и многословный, поток обработки: ошибку видно прямо в сигнатуре.

  3. #go_err_wrap3 / 9
    Чем fmt.Errorf("...: %w", err) отличается от того же с %v?
    A)%w оборачивает (errors.Is/As видят исходную), %v — только текст
    B)Разницы нет, оба форматируют ошибку в строку одинаково
    C)%w печатает полный стек вызовов, а %v — только текст сообщения
    D)%w требует, чтобы ошибка была строкой, иначе паникует
    показать ответ и разбор
    +A)%w оборачивает (errors.Is/As видят исходную), %v — только текст

    // разбор: Глагол %w в fmt.Errorf оборачивает ошибку, сохраняя ссылку на неё в цепочке: errors.Is найдёт по ней sentinel, errors.As извлечёт нужный тип. %v (или %s) лишь вставляет ТЕКСТ ошибки в строку — связь теряется, исходную из обёртки уже не достать. Спот-чек: Is с %w → true, с %v → false. Обычно оборачивают %w, добавляя контекст.

  4. #go_panic_recover4 / 9
    Что происходит при panic, если его никто не перехватил?
    A)Текущая горутина просто продолжает со следующей строки после паники
    B)Стек разворачивается с выполнением defer'ов, затем вся программа падает
    C)Паникует только текущая функция, а вызывающая получает error
    D)Рантайм ставит горутину на паузу до ручного возобновления
    показать ответ и разбор
    +B)Стек разворачивается с выполнением defer'ов, затем вся программа падает

    // разбор: panic прекращает нормальный ход: начинается разворачивание стека, по пути выполняются отложенные defer'ы (в них и живёт шанс на recover). Если ни один defer не сделал recover, разворачивание доходит до верха горутины и роняет ВСЮ программу с трейсом и ненулевым кодом выхода. panic — не «исключение для потока управления», а сигнал катастрофы.

  5. #go_sentinel_custom5 / 9
    Что такое sentinel-ошибка в Go?
    A)Объявленная заранее переменная-ошибка для сравнения через errors.Is
    B)Ошибка, которая завершает программу через os.Exit сразу при возникновении
    C)Временная ошибка-заглушка, удаляемая перед релизом кода
    D)Ошибка, автоматически логируемая рантаймом на стандартный вывод
    показать ответ и разбор
    +A)Объявленная заранее переменная-ошибка для сравнения через errors.Is

    // разбор: sentinel — экспортированная переменная-ошибка пакета, объявленная заранее (var ErrNotFound = errors.New("not found")), чтобы вызывающий сверялся с ней через errors.Is. Классика: io.EOF, sql.ErrNoRows. Плюс — стабильный маркер конкретного случая; минус — жёсткая связь пакетов по значению (для богатых данных лучше свой тип и errors.As).

  6. #go_escape6 / 9
    Что определяет escape analysis компилятора Go?
    A)Какие переменные в функции нигде не используются и потому удаляемы компилятором
    B)Разместить значение на стеке или в куче — по «побегу» ссылки за функцию
    C)Порядок вычисления аргументов в выражении
    D)Какие горутины могут выполняться параллельно без гонок
    показать ответ и разбор
    +B)Разместить значение на стеке или в куче — по «побегу» ссылки за функцию

    // разбор: escape analysis — анализ компилятора: если на значение НЕ остаётся ссылок после возврата функции, оно кладётся на стек (дёшево, освобождается само). Если ссылка «убегает» наружу (возвращается указатель, кладётся в интерфейс/замыкание/канал), значение переносится в кучу — под управление GC. Решения смотрят через go build -gcflags=-m. Спот-чек: &local → moved to heap.

  7. #go_gc7 / 9
    Как в Go управляют памятью под кучей?
    A)Вручную через malloc и free, как в C
    B)Подсчётом ссылок, который программист инкрементит сам
    C)Память вообще не освобождается до конца программы
    D)Автоматически: сборщик мусора чистит недостижимые объекты
    показать ответ и разбор
    +D)Автоматически: сборщик мусора чистит недостижимые объекты

    // разбор: Go — язык со сборкой мусора: рантайм сам находит объекты, до которых больше нет достижимых ссылок, и освобождает их память. Ручных free нет; escape analysis решает, что вообще попадёт в кучу. Это снимает целый класс багов (use-after-free, двойное освобождение) ценой работы GC, которую в Go старались сделать с очень короткими паузами.

  8. #go_mem_stack_heap8 / 9
    Что верно про стек горутины в Go?
    A)Стартует с ~2 КБ и растёт при нужде — горутины поэтому дёшевы
    B)Фиксирован в несколько мегабайт заранее, ровно как стек потока ОС
    C)Горутины стека не имеют — всё живёт в куче
    D)Размер стека задаётся при go и дальше неизменен
    показать ответ и разбор
    +A)Стартует с ~2 КБ и растёт при нужде — горутины поэтому дёшевы

    // разбор: Стек горутины начинается крошечным (около 2 КБ) и растёт по мере необходимости (рантайм копирует его в больший сегмент), а при спаде — сжимается. Поэтому можно держать сотни тысяч горутин: память под стек выделяется по факту, а не мегабайтами заранее, как у потока ОС. Это ключевая причина дешевизны горутин.

  9. #go_pprof9 / 9
    Что позволяет собрать пакет net/http/pprof (или runtime/pprof)?
    A)Статически проверить код на утечки ещё перед сборкой
    B)Профили рантайма: CPU, куча, число горутин, блокировки
    C)Полный дамп исходного кода приложения вместе с покрытием его тестами
    D)Логи всех сетевых запросов приложения
    показать ответ и разбор
    +B)Профили рантайма: CPU, куча, число горутин, блокировки

    // разбор: pprof собирает профили работающей программы: CPU (где горит время), heap (кто и сколько аллоцирует), goroutine (сколько горутин и где стоят — ловит утечки), block/mutex (на чём ждут). Подключил net/http/pprof — снимаешь через go tool pprof по HTTP. Это рантайм-профилирование, а не статический анализ и не логи.

это 9 из 63

Ещё 54 вопросов по теме — в тренажёре, с движком повторения

Прочитать разбор и ответить самому — разные навыки. В Сеньорчике вопросы идут сессиями, а движок возвращает подтемы, где вы ошибаетесь, пока они не начнут отскакивать. Бесплатно, лимит по энергии.

Частые вопросы