{}const=>[]async()letfn</>var
PythonПрофессия

Вопросы на собеседовании Python junior: 25 тем с разбором кода

Готовимся к Python junior без заучивания: типы, mutability, коллекции, функции, области видимости, исключения, итераторы, генераторы, ООП, тесты и SQL.

К

Кодик

Автор

6 мин чтения

Вопросы на собеседовании Python junior чаще проверяют не определения, а способность предсказать поведение кода, назвать граничный случай и предложить проверку. Подготовьте типы и mutability, списки и словари, функции, области видимости, исключения, итераторы, классы, тесты, HTTP и SQL, а каждую тему объясните на коротком примере. Связывайте ответ с версией языка и контрактом задачи.

Формат зависит от вакансии. Backend-команда добавит HTTP, framework, базу данных и асинхронность, аналитическая роль спросит про файлы, pandas и качество данных, автоматизация тестирования добавит pytest и API. Python tutorial охватывает структуры данных, функции, модули, исключения, классы и итераторы. Используйте его как карту, а требования конкретной вакансии как приоритет.

1Язык

Типы, ссылки, функции, исключения и протоколы объектов.

2Практика

Одна задача с тестами и оценкой сложности.

3Проект

Архитектурное решение, ошибка и личный вклад.

Схема ответа: контракт, пример, крайний случай, проверка
Как разложить ответ на технический вопрос по Python: назовите контракт функции, покажите короткий пример, добавьте крайний случай и предложите проверку тестом.

Вопросы на собеседовании Python junior с примером ловушки

Классическая тема связана с изменяемым аргументом по умолчанию. Значение по умолчанию вычисляется при определении функции, поэтому один список переиспользуется между вызовами. Хороший ответ не заканчивается словом mutable: покажите результат, исправьте код и объясните, когда создаётся новый объект.

def add_tag(tag, tags=None):
    # Создаём новый список для каждого вызова без переданного значения
    if tags is None:
        tags = []
    tags.append(tag)
    return tags

first = add_tag("python")
second = add_tag("junior")

print(first)   # ['python']
print(second)  # ['junior']
Ожидаемый результат
  • Вызовы не разделяют один изменяемый список
  • Кандидат объясняет разницу между None и готовым [] в сигнатуре

Следом интервьюер может спросить, почему проверка написана через is None, а не == None. Оператор is сравнивает идентичность объектов, и None является singleton. Затем добавьте тест, где список передан явно: функция должна изменить именно его или, если контракт требует неизменности, создать копию. Важно сначала назвать контракт, а не угадывать желаемое поведение.

🔥 100 000+ учеников уже с нами

Устал читать теорию?
Пора кодить!

Кодик — приложение, где ты учишься программировать через практику. AI-наставник, интерактивные уроки, реальные проекты.

🤖 AI 24/7
🎓 Сертификаты
💰 Бесплатно
🚀 Начать учиться
Присоединились сегодня

25 тем, собранных в пять блоков

ЭлементЧто означаетЧто делать
База языкаТипы, mutability, is и ==, truthiness, scopeПредсказать вывод
Коллекцииlist, tuple, dict, set, comprehensionВыбрать структуру
Функцииargs, kwargs, closure, decorator, generatorОбъяснить выполнение
Надёжностьexceptions, context manager, tests, loggingОбработать сбой
ПриложениеHTTP, JSON, SQL, Git, проектПроследить данные

Для словаря повторите хешируемость ключей и среднюю стоимость операций, но не обещайте точную сложность без условий. Для генератора объясните ленивое получение значений и однократный проход. Для исключений различайте ожидаемую ошибку пользователя и программный дефект. Для контекстного менеджера покажите обязательное освобождение ресурса. Для SQL повторите JOIN, GROUP BY, NULL и параметры запросов.

Что добавляет сильный ответ junior: вывод print, граница, тест
Чем сильный ответ junior отличается от определения: предсказанный вывод print, названная граница вроде пустого списка или None и способ подтвердить это через pytest.

Практика: разберите ловушку Python с изменяемым default

Соберите файл tags.py и доведите ловушку с изменяемым значением по умолчанию до наблюдаемого вывода. Успех: первая версия функции накапливает теги между вызовами, исправленная через None возвращает новый список каждый раз. Разницу зафиксируйте выводом print и одним тестом pytest, чтобы на собеседовании показывать код, а не пересказ.

  1. Плохая версия add_tag. Напишите def add_tag(tag, tags=[]) с append и return, вызовите её с 'python', потом с 'junior' и напечатайте оба результата. В консоли появятся ['python'] и ['python', 'junior']: список один на все вызовы.
  2. id списка по умолчанию. Напечатайте id возвращённого списка после каждого вызова и заодно add_tag.__defaults__. Идентификаторы совпадут, а в __defaults__ будет виден тот самый растущий список, созданный один раз при определении функции.
  3. Починка через None. Поменяйте сигнатуру на def add_tag(tag, tags=None) и добавьте внутри if tags is None: tags = []. Повторный запуск напечатает ['python'] и ['junior']: каждый вызов получает свой список.
  4. Явно переданный список. Вызовите add_tag('dev', my_tags) с готовым списком и проверьте, что изменился именно my_tags. Если контракт требует не трогать вход, возвращайте tags + [tag] или работайте с копией list(tags).
  5. Тест в pytest. Напишите test_add_tag_isolated с двумя проверками подряд: assert add_tag('a') == ['a'] и assert add_tag('b') == ['b']. На версии с None тест зелёный, на версии со списком в сигнатуре падает второй assert.

Верните в сигнатуру tags=[] и запустите pytest ещё раз. Второй assert упадёт с сообщением вида assert ['a', 'b'] == ['b'], потому что список из сигнатуры создан один раз при определении функции и живёт между вызовами. Тот же эффект повторите на словаре: def add_option(key, options={}) накопит ключи ровно так же, и это удобно показать интервьюеру как обобщение.

Критерий готовности. Вы можете сказать, в какой момент вычисляется значение по умолчанию, и объяснить, почему проверка is None надёжнее, чем if not tags. Подтверждение: два прогона с выводами ['python'] и ['junior'] и упавший тест на версии со списком в сигнатуре. Если пустой список пришёл явно, ваша функция обязана работать именно с ним.

Разберите тем же способом соседние ловушки: замыкание в цикле for с lambda, срез списка против copy и попытка положить список ключом словаря. Затем перенесите приём в задачу с вакансии: опишите контракт функции одной строкой в docstring и закройте его двумя тестами, на обычный вход и на пустой. Такой файл открывают на собеседовании и объясняют решение прямо по коду.

Частые ошибки и почему они появляются

Заученный список вопросов создаёт ложное чувство готовности. Небольшое изменение примера разрушает ответ, если кандидат не запускал код. Вторая ошибка: спорить о стиле до уточнения требований. Третья: описывать командный проект так, будто весь код написан лично. Гораздо сильнее честно назвать собственный модуль, решение и исправленный дефект.

Отвечать одним термином

Добавьте пример, наблюдаемый результат и границу.

Молчать при незнании

Скажите, что известно, сформулируйте гипотезу и способ проверить.

Не задавать вопросы

Уточните версию Python, формат входа и ожидаемое поведение.

Самопроверка

Почему пустой список опасен как значение по умолчанию?

Список в сигнатуре создаётся один раз при определении функции, поэтому все вызовы без явного аргумента работают с одним объектом и накапливают в нём данные. Пишите tags=None и создавайте новый список внутри функции.

Чем is отличается от == в Python?

Оператор is сравнивает идентичность: слева и справа должен быть один и тот же объект в памяти. Оператор == вызывает __eq__ и сравнивает значения, поэтому два одинаковых по содержимому списка дают True для == и False для is.

Почему проверяют is None, а не == None?

None существует в единственном экземпляре, поэтому проверка на идентичность через is None точна и не зависит от чужой реализации __eq__. Класс может переопределить == и вернуть True при сравнении с None, а обмануть is так не получится.

Какие объекты можно использовать ключом словаря?

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

Чем генератор отличается от списка?

Генератор отдаёт значения по одному по мере запроса и не держит всю последовательность в памяти, а список создаётся целиком сразу. Пройти по генератору можно один раз: после исчерпания он не начинается заново, и длину у него не спросить.

Что рассказывать про командный проект на собеседовании?

Про командный проект называйте свой участок: какую задачу вы взяли, какое решение выбрали, как проверили и какой дефект исправили. Присвоение чужого кода вскрывается первым же уточняющим вопросом про детали реализации.

Что делать дальше

Запишите ответы на 25 тем голосом и для пяти из них создайте запускаемые примеры с тестами. Системную практику даёт курс Python-разработчика. Алгоритмы закрепите по статье про задачи на Python, а критерии готовности сравните с планом до junior.

🎯Хватит откладывать

Понравилась статья?
Пора применять на практике!

В Кодик ты не просто читаешь — ты сразу пишешь код. Теория + практика = реальный скилл.

Мгновенная практика
🧠AI объяснит код
🏆Сертификат

Без регистрации • Без карты