Вопросы на собеседовании Python middle
Как устроены event loop и GIL, когда брать потоки, процессы или asyncio, что такое дескрипторы и метаклассы, как работают импорт, фикстуры pytest и внедрение зависимостей в FastAPI — то, что спрашивают у разработчика с опытом.
- 01Чем абстрактный базовый класс (ABC) отличается от Protocol?
ABC — номинальная типизация: класс должен явно наследовать абстрактный класс, а нереализованные @abstractmethod не дадут создать экземпляр. Protocol (3.8) — структурная: подходит…
Middle - 02Что будет, если внутри async-функции вызвать блокирующий код?
Встанет весь event loop: блокирующий вызов (time.sleep, requests.get, синхронный драйвер БД, тяжёлое вычисление) не отдаёт управление, и все остальные задачи ждут. Решение …
Middle - 03Как в asyncio работают отмена задач и таймауты?
task.cancel() бросает CancelledError внутрь корутины в точке ближайшего await. Таймаут — asyncio.timeout() (3.11) или wait_for: по истечении задача отменяется, наружу …
Middle - 04Как устроен event loop в asyncio?
Event loop — цикл в одном потоке: берёт готовые к выполнению задачи, выполняет каждую до ближайшего await, а ожидающие ввода-вывода передаёт ОС (epoll, kqueue) и возвращается к…
Middle - 05Чем asyncio.gather отличается от TaskGroup и как в них обрабатываются ошибки?
Оба запускают корутины конкурентно. gather при первой ошибке пробрасывает её, но остальные задачи продолжают работать брошенными (если не return_exceptions=True). TaskGroup (3.11)…
Middle - 06Когда использовать defaultdict, Counter, deque и OrderedDict?
defaultdict(list) — значение по умолчанию для нового ключа (группировка без проверок). Counter — подсчёт: most_common, сложение и вычитание счётчиков. deque — двусторонняя очередь…
Middle - 07Как пользоваться concurrent.futures и чем ThreadPoolExecutor отличается от ProcessPoolExecutor?
Единый интерфейс пулов: submit возвращает Future, map применяет функцию к итерируемому, as_completed отдаёт результаты по готовности. ThreadPoolExecutor — для ввода-вывода (GIL…
Middle - 08Чем dataclass отличается от namedtuple и Pydantic-модели?
@dataclass генерирует __init__, __repr__, __eq__ (опционально порядок, хеш, слоты) по аннотированным полям — обычный изменяемый класс без проверки типов. namedtuple — неизменяемый…
Middle - 09Как написать декоратор с параметрами и зачем нужен functools.wraps?
Декоратор с параметрами — фабрика декораторов: функция принимает параметры и возвращает обычный декоратор, т. е. три уровня вложенности. functools.wraps копирует в обёртку…
Middle - 10Что такое дескриптор и как на нём построены property и методы?
Дескриптор — объект в атрибуте класса, у которого есть __get__ (и, возможно, __set__, __delete__). При обращении obj.attr Python вызывает эти методы вместо простого чтения. На…
Middle - 11Как найти и исправить проблему N+1 запросов в Django ORM?
N+1 — один запрос за списком и по запросу на каждый элемент при обращении к связанному объекту в цикле. select_related — JOIN в одном запросе для ForeignKey и OneToOne…
Middle - 12Как связаны __eq__ и __hash__ и что значит «хешируемый объект»?
Хешируемый объект имеет хеш, неизменный за всё время жизни, и сравнивается через __eq__. Правило: равные объекты обязаны иметь равные хеши. Если класс переопределяет __eq__ без…
Middle - 13Что такое цепочки исключений (raise from) и как правильно создавать свои исключения?
raise NewError(...) from err сохраняет исходную ошибку в __cause__ — в трассировке «The above exception was the direct cause». Простой raise внутри except ставит __context__…
Middle - 14Как устроено внедрение зависимостей в FastAPI?
Depends(func) — FastAPI вызывает func перед обработчиком и передаёт результат в параметр. Зависимости образуют граф, результат кэшируется в пределах запроса, зависимость с yield…
Middle - 15Что меняет сборка Python без GIL (free-threaded)?
Отдельная сборка CPython (python3.13t) без GIL: потоки выполняют Python-код по-настоящему параллельно на разных ядрах. В 3.13 — экспериментальная, в 3.14 — официально…
Senior - 16Что полезного есть в functools — lru_cache, cache, partial, singledispatch?
lru_cache(maxsize) — мемоизация с вытеснением давно неиспользуемых; cache (3.9) — без ограничения. Аргументы должны быть хешируемыми. partial — зафиксировать часть аргументов…
Middle - 17Что делают send, throw и yield from у генераторов?
Генератор — не только источник значений: send(x) передаёт значение внутрь (оно становится результатом выражения yield), throw(exc) бросает исключение в точке yield, close()…
Middle - 18Чем __getattr__ отличается от __getattribute__?
__getattribute__ вызывается при каждом обращении к атрибуту — это сам механизм поиска. __getattr__ вызывается только если атрибут не найден обычным путём. Для прокси, ленивых…
Middle - 19Как работает импорт модулей и что делать с циклическими импортами?
При первом import модуль ищется по sys.path, выполняется сверху вниз один раз и кладётся в sys.modules; повторные импорты берут его оттуда. Циклический импорт ломается, когда…
Middle - 20Какие инструменты itertools стоит знать?
Ленивые строительные блоки: chain (склеить), islice (срез итератора), groupby (группы подряд идущих — нужна предварительная сортировка), product/permutations/combinations…
Middle - 21Почему лямбды, созданные в цикле, возвращают одно и то же значение?
Замыкание захватывает переменную, а не её значение: значение читается в момент вызова. К моменту вызова цикл закончился, и все лямбды видят последнее значение i. Исправление …
Middle - 22Что такое метакласс и когда он действительно нужен?
Класс — тоже объект, а метакласс — класс класса: он управляет созданием классов. По умолчанию это type. Метакласс нужен редко: регистрация подклассов и проверка их структуры…
Senior - 23Как работает unittest.mock.patch и почему патчить нужно там, где объект используется?
patch временно заменяет атрибут по имени на Mock. Подменять нужно в модуле, где имя ищется, а не там, где оно определено: если orders.py сделал from payments import charge…
Middle - 24Какие ограничения есть у multiprocessing и чем fork отличается от spawn?
Процессы не делят память: аргументы и результаты сериализуются pickle и копируются. Лямбды, локальные функции, открытые файлы и соединения не сериализуются. fork копирует процесс…
Middle - 25Чем __new__ отличается от __init__?
__new__ — статический метод, создаёт и возвращает экземпляр (вызывается первым). __init__ — инициализирует уже созданный объект и ничего не возвращает. __new__ переопределяют…
Middle - 26Как найти, что тормозит в Python-программе?
Сначала измерить, потом оптимизировать. cProfile (+ snakeviz) — время по функциям локально. py-spy — сэмплирующий профилировщик, подключается к работающему процессу без…
Middle - 27Как работают фикстуры pytest и что такое их scope?
Фикстура — функция с @pytest.fixture, результат которой pytest передаёт в тест по имени параметра. Код после yield — очистка. scope (function, class, module, package, session)…
Middle - 28Почему Python медленный и как ускорить вычисления?
CPython — интерпретатор байткода с динамической типизацией: каждая операция проверяет типы, числа — объекты в куче. Ускорение: векторизация (NumPy, pandas — циклы на C)…
Middle - 29Как Python управляет памятью — подсчёт ссылок и сборщик мусора?
В CPython основной механизм — подсчёт ссылок: у каждого объекта счётчик, и когда он падает до нуля, объект освобождается сразу. Циклические ссылки (a ссылается на b, b на a)…
Middle - 30Что такое __slots__ и когда его использовать?
__slots__ = ("x", "y") заменяет у экземпляров словарь __dict__ на фиксированные ячейки: объект занимает в несколько раз меньше памяти, доступ к атрибутам чуть быстрее, а добавить…
Middle - 31Почему a is b для чисел и строк иногда True, а иногда False?
CPython заранее создаёт целые от −5 до 256 и переиспользует их — is для них True. Строки, похожие на идентификаторы, и константы в одном блоке кода интернируются компилятором. Всё…
Middle - 32Нужны ли блокировки в многопоточном Python-коде, если есть GIL?
Нужны: GIL защищает внутренние структуры интерпретатора, а не ваши инварианты. x += 1 — несколько инструкций байткода (прочитать, сложить, записать), и поток может быть прерван…
Middle - 33Как в аннотациях Python описать обобщённые типы — TypeVar, Generic, Protocol?
TypeVar — параметр типа: функция first(xs: list[T]) -> T сохраняет связь «что пришло, то и вернулось». Generic — обобщённый класс. С Python 3.12 — новый синтаксис: def…
Middle - 34Что такое слабые ссылки (weakref) и где они нужны?
Слабая ссылка не увеличивает счётчик ссылок: объект удаляется, когда исчезнут обычные ссылки, а слабая начинает возвращать None. Применение: кэши и реестры, которые не продлевают…
Middle - 35Чем WSGI отличается от ASGI?
WSGI — синхронный интерфейс между веб-сервером и приложением: один запрос занимает один поток или процесс до ответа (Flask, Django). ASGI — асинхронный: приложение — корутина…
Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.