Home
Series About Subscribe
Вопросы для собеседования на Python для Mid-level разработчиков

Вопросы для собеседования на Python для Mid-level разработчиков

Я собрал серию постов с моей личной базой вопросов для собеседований на Python. Она не идеальна, не полна, и нет, ответов тут нет. Некоторые вопросы могут показаться странноватыми или взятыми из ниоткуда. Но по моему опыту, именно они хорошо показывают, кто на самом деле готов к работе.

Серия разбита на три части по уровню опыта:

Есть вопрос, который, как тебе кажется, должен быть здесь? Или то, что ты сам всегда спрашиваешь на собеседованиях? Дай знать — с удовольствием послушаю!

Что здесь значит «middle»

Для начала определимся с уровнями. Как я это вижу: junior знает синтаксис, middle знает, что ломается в проде, senior знает, что не стоит строить вообще.

У некоторых вопросов ниже есть заметка о том, что я слушаю в ответе. Если ты собеседуешь — вот куда копать. Если готовишься — вот что отличает сильный ответ от заученного, и вот что обычно хочет услышать человек по другую сторону стола.

Вопросы

1. Концепции языка Python

Q: Что выведет -12 % 10?

Q: Что выведет -12 // 10?

Q: Как называется последовательность вычисления операторов в выражении a * b * c?

Q: Почему нельзя использовать изменяемый объект (например, пустой список) в качестве значения по умолчанию для аргумента в Python?

Q: Что делает функция id() в Python?

  • Уточнение: Две равные строки могут иметь одинаковый id(). Почему?

Q: Что такое comprehensions в Python (list, dict, set)? Когда их стоит использовать?

Q: В Python 3.10 добавили structural pattern matching (match/case). Чем это отличается от цепочки if/elif?

  • Уточнение: Что match может деструктурировать такого, что if не сделает чисто?

Q: Для чего используется ключевое слово yield в Python?

Q: Как отличить итераторы от генераторов в Python?

  • Бонус: Напиши пример для каждого.

Q: В чём разница между методами __iter__ и __next__?

Q: Как создать словарь, который сохраняет порядок пар ключ-значение?

Q: Когда стоит использовать dataclass вместо NamedTuple, TypedDict или обычного класса?

Здесь нет неправильного ответа, поэтому его нельзя вызубрить. Я хочу услышать, как изменяемость взвешивается против хешируемости и стоимости в рантайме. И хочу услышать, что TypedDict вообще перестаёт быть классом, как только программа запускается.

  • Уточнение: Что даёт frozen=True, и чего это стоит?

Q: Почему стоит использовать pathlib вместо os.path и конкатенации строк?

Q: Что такое блоки try, except, else и finally? Приведи примеры.

2. Контекстные менеджеры

Q: Что такое контекстный менеджер, и чем он отличается от использования try...finally?

try/finally делает ровно то же самое, поэтому «это более pythonic» — довольно тупой ответ. Я жду __enter__/__exit__ и суть, которая за ними стоит: менеджер можно переиспользовать. С try/finally ты пишешь это заново в каждом месте вызова, пока кто-нибудь однажды не забудет.

Q: Какие методы нужно реализовать, чтобы создать свой класс контекстного менеджера?

Q: Объясни блоки with. Почему они считаются более pythonic, чем try-finally?

Q: Опиши случай, где контекстные менеджеры могут быть полезны.

3. Основы асинхронности

Q: Что такое синхронный код, и чем он отличается от асинхронного кода?

Q: Чем async-функции отличаются от обычных функций Python?

Q: Что такое ключевые слова async и await в Python? Приведи простой пример.

  • Уточнение: Что делает await, и когда его стоит использовать?

Q: Для чего нужен event loop в Python, и как с ним взаимодействует функция asyncio.run()?

Q: Как обрабатывать исключения в асинхронном коде на Python?

Q: Тебе нужно вызвать три независимых async API. Что не так с тем, чтобы ожидать их один за другим, и как бы ты это исправил?

  • Уточнение: Один из трёх падает с ошибкой. Что происходит с двумя другими?

Q: Можешь объяснить назначение конструкций async with и async for? Приведи примеры.

Q: Как выполнить файловый ввод-вывод асинхронно в Python?

Q: Когда стоит выбрать асинхронное программирование вместо многопоточности в Python?

4. Продвинутые концепции

Q: Что такое модуль unittest в Python? Как писать тесты на Python?

Q: Современный синтаксис type hints: в чём разница между List[int] и list[int], и между Optional[str] и str | None? Что бы ты написал сегодня?

Ничего сложного здесь нет. Вопрос просто датирует их: ответ показывает, на каком Python они писали последние несколько лет, и насколько они следят за best practices.

Q: Объясни проверку типов в Python. Почему Python считается строго типизированным языком?

Q: Как эффективно изолировать код на Python (например, виртуальные окружения)?

  • Уточнение: Что идёт в pyproject.toml, и что заменило для тебя setup.py?
  • Уточнение: В чём разница между lock-файлом и requirements-файлом, и когда эта разница кусается?

Это проверяет разницу между намерением и реализацией. requirements.txt — это то, что выбрал ты сам. Зафиксированные транзитивные зависимости — это то, что выбрал за тебя резолвер. pip freeze > requirements.txt стирает эту границу: он сваливает весь граф в один файл и больше не помнит, какая часть была твоим решением.

Q: Как скопировать объект в Python? В чём разница между поверхностной (shallow) и глубокой (deep) копией?

Перекликается с вопросом про [[]] * 3 чуть ниже. Одно и то же дважды, и мне интересно, свяжут ли они эти два вопроса.

Q: Как в Python управляется память?

  • Уточнение: Зачем в Python сборщик мусора, и как он работает?

Q: Как поделиться глобальными переменными между модулями? Это вообще хорошая идея?

Q: Что такое атрибут __slots__ у класса? Какие у него плюсы и минусы?

К этому моменту плюсы, наверное, знают все. Вопрос больше про минусы: нет __dict__, нет атрибутов, которые ты не объявил, и наследование перестаёт быть бесплатным.

Q: Что такое метаклассы в Python?

  • Бонус: Как создать класс, не используя оператор class?

5. Задачи на кодинг

Q: Как проверить, что один кортеж содержит все элементы другого кортежа?

Q: Что выведет следующий код?

>>> list = ['a', 'b', 'c', 'd', 'e']
>>> print(list[10:])

Q: Как перезагрузить ранее импортированный модуль? (предположим, что модуль — это файл module.py)

Q: Что выведет следующий код?

>>> a = [[]] * 3
>>> a[1].append(1)
>>> print(a)

Q: Что не так со следующим кодом?

def foo():
    from .module import *
    print(f"{bar()}")

Q: Файл находится в /usr/lib/python/person.py. Программа запускается командой python /usr/lib/python/person.py. Что будет на выходе?

class Person:
    def __init__(self, name):
        __name__ = name

    def getAge(self):
        print(__name__)

p = Person("John")
p.getAge()

Q: Напиши декоратор timeit для измерения времени выполнения функции.

Q: Напиши декоратор, который будет ловить ошибки и повторять функцию максимум 3 раза (настраиваемо).

Q: Что выведет следующий код?

class parent:
    def __init__(self, param):
        self.v1 = param

class child:
    def __init__(self, param):
        self.v2 = param

obj = child(11)
print(obj.v1 + " " + obj.v2)

Q: Почини следующий код, чтобы он заработал.

class Repeater:
    ...
class RepeaterIterator:
    ...

repeater = Repeater("Hello")
for i in repeater:
    print(i)  # hello

Q: Напиши код, который получает уникальные значения из списка сложных типов (собственных классов). Пример: [A(1, "ab"), A(2, "ab"), A(2, "aa"), A(1, "ab")] -> [A(1, "ab"), A(2, "ab"), A(2, "aa")].

Q: У нас есть следующий код с неизвестной функцией f(). В f() мы не хотим использовать return, вместо этого мы, возможно, хотим использовать генератор.

for x in f(5):
    print(x,)

Вывод выглядит так:

0 1 8 27 64

Напиши функцию f(), чтобы получить вывод выше.

Q: Что выведет следующий код?

x = [[0], [1]]
print(len(' '.join(list(map(str, x)))))

Q: Напиши функцию для генерации всех перестановок строки.

Q: Реализуй базовый LRU (Least Recently Used) кэш.

Дополнительные материалы

Liked this? I publish one deep-dive every other Tuesday.

Join 4,000+ engineers. No sponsors.

Get the newsletter

Enjoyed what you just read? Others like these as well:

Python Interview Questions for Beginners (Junior)

Optional arguments MUST use keywords (Python3)

Design Patterns Suck