AI
prepair.app
Пройти интервью →
EnglishРусскийУкраїнська
🐍

Middle Python Backendвопросы на собеседовании Python разработчика

Middle · 2–4 года опыта

Собеседование Python-разработчика охватывает внутренности языка, асинхронность, Django или FastAPI и работу с базой. Ниже — самые частые вопросы с эталонными ответами. Middle: более глубокое понимание, оптимизацию и реальные рабочие ситуации.

Темы для подготовки

Типы данных и структуры
Декораторы и генераторы
GIL и конкурентность
asyncio и async/await
Django / FastAPI
ORM и оптимизация SQL

10 вопросов уровня Middle с ответами

1

В чём разница между списком и кортежем? Когда выбрать каждый?

Ответ

Списки изменяемы, кортежи неизменяемы, из-за чего кортежи хешируемы и годятся в качестве ключей словаря. Кортежи чуть быстрее и сигнализируют читателю, что это фиксированная запись, а не растущая последовательность. Список берут, когда содержимое меняется, кортеж — для фиксированных разнородных данных вроде координат или возвращаемой пары.

2

Что такое декоратор? Напишите декоратор, измеряющий время выполнения.

Ответ

Декоратор — это вызываемый объект, который принимает функцию и возвращает замену, чтобы добавить поведение, не трогая исходное тело. Декоратор замера времени оборачивает вызов: засечь perf_counter до, вызвать функцию, засечь после, залогировать разницу и вернуть результат. Обязательно применяйте functools.wraps к внутренней функции, чтобы имя, docstring и сигнатура оригинала пережили интроспекцию.

3

Объясните разницу между генератором и обычной функцией. Зачем нужен yield?

Ответ

Обычная функция вычисляет всё и возвращает один раз; генератор приостанавливается на каждом yield и возобновляется с того же места, отдавая значения лениво. Это значит постоянный расход памяти независимо от количества элементов, поэтому можно итерироваться по файлу в гигабайты или по бесконечной последовательности. Именно yield превращает функцию в конечный автомат, который интерпретатор умеет ставить на паузу.

4

Что такое *args и **kwargs? Приведите пример использования.

Ответ

*args собирает лишние позиционные аргументы в кортеж, **kwargs собирает лишние именованные в словарь. Их применяют, когда функция должна принимать произвольную сигнатуру — чаще всего в декораторах и обёртках, пробрасывающих всё дальше. Зеркальное применение — распаковка: вызов f(*items, **options) разворачивает последовательность и словарь в аргументы.

5

В чём разница между multiprocessing, threading и asyncio?

Ответ

Threading даёт конкурентность внутри одного процесса и помогает только на I/O из-за GIL. Multiprocessing поднимает отдельные интерпретаторы с настоящим параллелизмом ценой запуска процессов и межпроцессного обмена — это правильный выбор для CPU-нагрузки. asyncio это однопоточная кооперативная конкурентность: задачи уступают управление в точках await, что масштабируется на десятки тысяч сокетов, но блокирует всё, если внутри корутины вызвать синхронный код.

6

Что такое контекстный менеджер? Как реализовать свой?

Ответ

Контекстный менеджер гарантирует подготовку и завершение вокруг блока — именно это использует with, чтобы закрыть файл или отпустить блокировку даже при исключении. Реализовать можно классом с __enter__ и __exit__ либо генератором под декоратором @contextlib.contextmanager, который делает один yield между кодом подготовки и очистки. Метод __exit__ получает информацию об исключении и может подавить его, вернув True.

7

Объясните MRO и множественное наследование.

Ответ

Method Resolution Order задаёт порядок, в котором Python ищет атрибут по классам, и вычисляется алгоритмом линеаризации C3. Он гарантирует, что класс всегда идёт раньше своих родителей и что порядок базовых классов соблюдается, благодаря чему ромбовидное наследование ведёт себя предсказуемо. super() идёт по MRO, а не прыгает сразу к родителю, поэтому кооперативное множественное наследование требует, чтобы каждый класс в цепочке вызывал super().

8

Что такое N+1 в Django ORM? Как помогают select_related и prefetch_related?

Ответ

N+1 возникает, когда queryset возвращает N объектов, и каждое обращение к связанному полю порождает отдельный запрос. select_related решает это для ForeignKey и OneToOne, делая SQL JOIN и заполняя связанный объект тем же запросом. prefetch_related работает с ManyToMany и обратными связями: выполняет второй запрос и соединяет результаты уже в Python, поэтому запросов получается два, а не один.

9

В чём разница между shallow copy и deep copy?

Ответ

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

10

В чём разница между __str__ и __repr__?

Ответ

__repr__ адресован разработчику и в идеале должен быть однозначным — часто это выражение, которым объект можно было бы воссоздать; именно его показывают REPL и отладчики. __str__ адресован конечному пользователю, его вызывают print() и str(), а при отсутствии он падает обратно на __repr__. Привычка реализовывать __repr__ ценнее, потому что она делает читаемыми логи и трейсбеки.

🦎

Прочитать ответы недостаточно

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

Пройти интервью Middle Python Backend →
Бесплатно · 3 интервью в месяц

Другие уровни — Python Backend

Junior Python BackendSenior Python BackendВсе вопросы Python Backend

Другие специализации

🔍Middle QA Manual🤖Middle QA AutomationMiddle Java Backend🐘Middle PHP Backend🦫Middle Go Backend🟢Middle Node.js Backend⚛️Middle React Frontend💚Middle Vue Frontend🅰️Middle Angular FrontendMiddle Next.js