Исключения и отладка: вопросы для собеседования (часть 2)
try/except, raise, типы исключений, отладка с pdb — на собеседовании спрашивают, как обрабатывать ошибки и что происходит при необработанном исключении. Просят объяснить разницу между ValueError и TypeError, показать try/except/finally. Грамотная обработка ошибок отличает продакшн-код от скрипта в Jupyter.
Вопросы 6–10 из 20
6В ноутбуке аналитик написал `except Exception: pass`, чтобы код «не падал». Почему это считается плохой практикой, если цель — быстро находить и исправлять проблемы?
AПотому что инструкция `pass` замедляет работу интерпретатора и заметно увеличивает общее время выполнения ноутбука на больших данных.
BПотому что `except Exception:` ловит только `KeyError`, а остальные исключения вроде `ValueError` всё равно прервут выполнение ячейки.
CПотому что такая конструкция запрещена синтаксисом Python: `pass` нельзя использовать в качестве тела блока `except` без других инструкций.
DПотому что ошибки молча скрываются: данные могут стать неверными, а трассировка и первопричина проблемы теряются для последующей отладки.
Ответ: Широкий перехват с молчаливым `pass` скрывает реальные ошибки, ломает отладку и приводит к тихим дефектам в данных.
Задача обработки исключений — не «чтобы не падало», а чтобы поведение оставалось корректным и диагностируемым. `except Exception: pass` превращает реальные ошибки в тихие дефекты: метрики могут считаться неправильно, и вы не узнаете почему. Лучше ловить конкретные исключения и явно решать, что делать: записать в лог, поставить `None`, прекратить выполнение или поднять исключение через `raise`. Это сохраняет трассировку и помогает быстро найти первопричину.
Подробный разбор → 7В начале traceback всегда есть строка `Traceback (most recent call last)`. Как она помогает читать стек вызовов?
ATraceback показывает цепочку вызовов от внешнего к внутреннему, и самый нижний фрейм обычно ближе всего к месту реальной ошибки
BЭто означает, что ошибка уже была обработана интерпретатором и можно игнорировать остаток traceback при отладке кода
CЭто означает, что ошибка произошла в самом первом фрейме списка, а остальные строки нужны только для контекста
DЭто означает, что Python выводит фреймы traceback в случайном порядке и порядок чтения не имеет значения
Ответ: Traceback читают как стек вызовов: он показывает, какие функции привели к месту падения.
Строка `Traceback (most recent call last)` подсказывает: ниже будет список вызовов, а «последний» вызов (внизу) — обычно там, где исключение возникло. Понимание этой структуры помогает быстро найти первопричину, а не лечить симптомы в верхних слоях кода. Порядок фреймов всегда детерминированный, и они никогда не выводятся случайно. Игнорировать остаток traceback тоже не стоит — именно нижняя часть содержит ключевую информацию о месте падения.
Подробный разбор → 8Скрипт упал с `TypeError`, данных много и непонятно, где именно проблема. Какой следующий шаг чаще всего самый эффективный для диагностики?
AСлучайно менять строки кода и перезапускать скрипт целиком, пока ошибка не исчезнет сама на каких-то данных
BСразу обернуть весь код в `try/except Exception` и продолжить расчёты дальше, не разбираясь в причине падения
CОткрыть `traceback`, перейти на указанную строку, проверить значения и типы переменных и свести вход к минимальному примеру
DПерезапустить интерпретатор и повторить запуск без изменений в надежде, что ошибка не воспроизведётся повторно на тех же данных
Ответ: `traceback` плюс проверка типов и значений на конкретной строке — самый быстрый путь к первопричине ошибки.
Отладка — это локализация: где упало, на каких данных, какие типы и значения участвовали. `traceback` сразу указывает место, а проверка `type(...)` и вывод ключевых переменных помогает понять, почему операция недопустима. Минимальный воспроизводимый пример резко ускоряет исправление и снижает риск внести случайные ошибки в рабочий код.
Подробный разбор → 9Вы пишете функцию `parse_age(age_text)`, которая должна принимать только неотрицательный возраст. Как лучше явно сообщить об ошибке входных данных, если пришло `-5`?
AВернуть строку `'error'` и продолжить расчёты с этим значением дальше
BВывести предупреждение через `print` и продолжить работу с отрицательным возрастом
CСделать `raise KeyError('age')`, чтобы пометить проблему отсутствующего ключа
DСделать `raise ValueError('age must be non-negative')` и прервать выполнение
Ответ: Для некорректного значения входных данных уместен `raise ValueError(...)`.
Когда входные данные нарушают ожидания (например, возраст отрицательный), полезно «сломать» выполнение явным исключением. `raise ValueError(...)` делает ошибку понятной, позволяет быстро отладить источник плохих данных и не продолжать расчёты с некорректными значениями. `KeyError` сигнализирует об отсутствующем ключе в словаре — это другая семантика. Возврат строки или вывод через `print` маскирует ошибку и легко проигнорировать.
Подробный разбор → 10Вы получили traceback, в нём несколько строк вида `File '...', line ...`. Какой фрагмент обычно указывает на место, где исключение реально возникло?
AСамая первая строка `Traceback (most recent call last)` в начале вывода ошибки
BСамая верхняя строка `File ... line ...` в списке фреймов сразу под заголовком
CЛюбая строка `File ... line ...` подходит одинаково, кадры стека равнозначны при разборе
DСамая нижняя строка `File ... line ...` непосредственно перед строкой типа исключения
Ответ: В traceback место возникновения исключения чаще всего видно в нижнем фрейме стека вызовов.
Traceback показывает стек вызовов от внешнего к внутреннему, поэтому «внизу» обычно находится строка кода, где ошибка действительно произошла, а выше — цепочка вызовов, которая к ней привела. Это помогает быстро перейти к нужной строке и проверить значения и типы переменных рядом с ошибкой. Верхняя строка «`Traceback (most recent call last)`» — это просто заголовок, а не место сбоя.
Подробный разбор →