Вопросы по Python
Типы и изменяемость, коллекции, функции, генераторы, декораторы, ООП, GIL и asyncio: всё, что гоняют на технической секции Python-бэкенда, QA-автоматизации и ML. После трека вы читаете хитрый код без запуска и объясняете, что происходит под капотом CPython.
Проверьте себя: тест по Python
20 вопросов, 10 минут, уровень junior, middle или senior
Типы, изменяемость и сравнение
Встроенные типы, изменяемые и неизменяемые объекты, is и ==, ссылки, копирование и истинность.
Урок: Типы, изменяемость и сравнение в Python за 7 минут 7 мин- Что возвращают and и or
- bool как подкласс int
- Своя глубокая копия вложенных структур
- Подсчитать значения по типам
- Сумма денег без ошибок float
- Отфильтровать только None
- Какие значения ложны в Python
- Копирование вложенного списка
Ещё 19 вопросов и задач
- copy против deepcopy
- Модель данных Python: всё объект
- Что такое хешируемый объект
- Почему сравнивают через is None
- Сравнение float в Python
- Загадка += над списком в кортеже
- Переполнение int в Python
- Чем is отличается от ==
- Ловушка [[0]*3]*3
- Значение и его истинность
- Какие типы Python неизменяемые
- NaN в списке и проверка in
- Ссылки на список и +=
- Ключи 1, True и 1.0 в dict
- Поверхностная копия списка
- Кеш малых целых в CPython
- is и == в Python: когда что использовать
- Изменяемые и неизменяемые типы Python
- Всегда ли кортеж хешируем
Коллекции
list, tuple, dict, set: устройство, сложность операций, срезы, comprehension и модуль collections.
Урок: list, tuple, dict и set в Python: устройство и сложность 8 мин- Убрать дубли с сохранением порядка
- Сгруппировать анаграммы
- LRU-кеш на OrderedDict
- Топ-k частых слов
- Counter.most_common
- Зачем нужен deque
- Худший случай поиска в dict
- Удаление ключей во время итерации
Ещё 24 вопроса и задачи
- Порядок ключей в dict
- Почему dict иногда тормозит на вставке
- Представления dict.keys()
- Группировка через defaultdict
- defaultdict против dict.get
- Как устроен dict в CPython
- list против tuple
- Ловушка dict.fromkeys со списком
- Проверка x in для list и set
- Группы анаграмм: число и размеры
- Первый неповторяющийся символ строки
- Самая длинная подстрока без повторов
- Пересечение массивов с учётом повторов
- Сколько пар дают сумму k
- Уникальные посетители страниц по логу
- Сложность insert(0) у списка
- Сложность операций с коллекциями
- Порядок ключей после перезаписи и удаления
- Удаление из списка в цикле
- Операции над множествами
- Как создать пустое множество
- Стабильность сортировки и сортировка по двум ключам
- Как выбрать коллекцию в Python
- Как работает словарь в Python
Функции и области видимости
Аргументы, *args и **kwargs, изменяемые значения по умолчанию, LEGB, замыкания, lambda.
Урок: Функции в Python: аргументы, LEGB и замыкания 7 мин- Что такое *args и **kwargs
- Перекрытие встроенных имён
- Как передаются аргументы в функцию Python
- Где хранятся переменные замыкания
- Вызов с *args и **kwargs: разбор сигнатуры
- Композиция функций
- Мемоизация через замыкание
- Повтор вызова с ограничением попыток
Ещё 18 вопросов и задач
- Когда вычисляется значение по умолчанию
- Где хранятся значения по умолчанию
- Сигнатура с / и *
- Функции как объекты первого класса
- Правило LEGB
- functools.partial
- Распаковка ** и повторяющийся аргумент
- Лямбды в цикле и позднее связывание
- Изменяемое значение по умолчанию
- Зачем нужен nonlocal
- Порядок поиска имён LEGB
- Два счётчика на замыканиях
- Значение по умолчанию копит данные
- Лямбды с аргументом по умолчанию
- Только позиционные и только именованные параметры
- Замыкания в Python
- Почему опасны изменяемые значения по умолчанию
- UnboundLocalError при изменении глобальной переменной
Итераторы и генераторы
Протокол итерации, yield, ленивые вычисления, yield from, itertools и одноразовость генераторов.
Урок: Итераторы и генераторы в Python за 7 минут 7 мин- Когда выполняется тело генератора
- Разбить последовательность на пачки
- Рекурсивно развернуть вложенные списки
- Конвейер обработки лога на генераторах
- Свой итерируемый класс, который можно обходить много раз
- Когда выполняется finally в недочитанном генераторе
- Полезные функции itertools
- Ленивые вычисления
Ещё 17 вопросов и задач
- Протокол итерации
- Генераторное выражение против list comprehension
- itertools.groupby на несортированных данных
- Итерируемый объект и итератор: разница
- Повторный обход map
- Функции itertools и их результат
- Что делает цикл for по шагам
- Ленивое условие в генераторном выражении
- Порядок выполнения генератора
- zip съедает элемент итератора
- Является ли range итератором
- return внутри генератора
- send в генератор
- Генераторы в Python: что это и зачем
- Как работает for в Python
- Что делает yield from
- zip списков разной длины
Декораторы
Функции как объекты, декораторы с параметрами, functools.wraps, lru_cache и декораторы классов.
Урок: Декораторы в Python: от простого до параметризованного 7 мин- Класс как декоратор
- Декоратор, считающий вызовы
- Декоратор ограничения частоты вызовов
- Декоратор проверки типов аргументов
- Декоратор с параметром: заполните пропуски
- functools.cache против lru_cache
- Что такое декоратор
- Атрибут __wrapped__
Ещё 16 вопросов и задач
- lru_cache на методе экземпляра
- lru_cache и нехешируемые аргументы
- Декоратор-класс на методе
- Декоратор без return в обёртке
- Порядок применения нескольких декораторов
- Когда что выполняется при @retry(3)
- Когда печатает декоратор
- Статистика lru_cache
- Порядок применения и вызова декораторов
- Декоратор с параметрами: сколько уровней
- Где применяют декораторы в реальном коде
- Напишите и объясните декоратор
- Во что разворачивается @decorator
- functools.total_ordering
- Когда выполняется код декоратора
- Зачем нужен functools.wraps
ООП и dataclasses
Классы, наследование и MRO, super, магические методы, property, дескрипторы, __slots__, dataclasses и метаклассы.
Урок: ООП в Python: классы, MRO, магические методы и dataclasses 8 мин- Изменяемый атрибут класса
- classmethod против staticmethod
- Вычислить MRO алгоритмом C3
- Полиморфизм: площадь фигур
- Дескриптор с проверкой значения
- Класс Vector с магическими методами
- Список по умолчанию в dataclass
- Приоритет дескрипторов и словаря экземпляра
Ещё 20 вопросов и задач
- __eq__ без __hash__
- Неизменяемый dataclass со списком
- Что генерирует @dataclass
- Что такое дескриптор
- __new__ против __init__
- __getattr__ против __getattribute__
- Регистрация подклассов без метакласса
- Магические методы и операции
- Что вызывается при создании экземпляра
- MRO в ромбовидном наследовании
- Двойное подчёркивание в имени атрибута
- Атрибут класса и атрибут экземпляра
- Сравнение и repr у dataclass
- Цепочка super в ромбе
- property с проверкой значения
- __repr__ и __str__
- Что дают __slots__
- dataclass, NamedTuple или Pydantic
- MRO и super при множественном наследовании
- Что на самом деле вызывает super()
Исключения и контекстные менеджеры
try/except/else/finally, иерархия исключений, свои ошибки, ExceptionGroup, with и contextlib.
Урок: Исключения и контекстные менеджеры в Python 7 мин- Метод add_note у исключений
- Чем плох голый except
- Открыть ресурсы и закрыть их при ошибке
- Безопасное преобразование в число
- Свой suppress
- Собрать все ошибки валидации
- try/finally в @contextmanager
- EAFP и LBYL
Ещё 19 вопросов и задач
- Когда выполняется else у try
- ExceptionGroup и except*
- Когда __exit__ подавляет исключение
- return в try и в finally
- contextlib.ExitStack
- Иерархия исключений Python
- Протокол контекстного менеджера
- Встроенные исключения и ситуации
- Порядок веток except
- Порядок блоков при успешном try
- Причина и контекст исключения
- Контекстный менеджер подавляет ошибку
- except* и ExceptionGroup
- Порядок try/except/else/finally
- raise против raise e
- Зачем raise ... from e
- Контекстные менеджеры: как работают и как написать свой
- Как вы обрабатываете ошибки в Python-сервисе
- Исключение в переменной и утечка памяти
Модули, пакеты и окружения
Система импорта, __name__, пакеты, циклические импорты, venv, pip, uv, pyproject.toml.
Урок: Модули, пакеты и виртуальные окружения в Python 6 мин- Циклический импорт и from-импорт
- Порядок установки пакетов по зависимостям
- Разобрать requirements.txt
- Сравнение версий пакетов
- Editable-установка пакета
- Команды создания окружения
- pyproject.toml
- sys.modules
Ещё 13 вопросов и задач
- Что такое uv
- Сколько раз выполняется код модуля
- Нужен ли __init__.py
- Зачем lock-файл зависимостей
- Зачем if __name__ == "__main__"
- Где Python ищет модуль
- Повторный импорт и sys.modules
- Относительный импорт при прямом запуске
- Свой файл перекрыл модуль стандартной библиотеки
- Как вы управляете зависимостями Python-проекта
- Что происходит при import в Python
- Порядок поиска при импорте
- Зачем виртуальное окружение
GIL, потоки и процессы
Что такое GIL, когда помогают потоки, а когда процессы, concurrent.futures, гонки и free-threaded CPython.
Урок: GIL, потоки и процессы в Python 8 мин- Выбор между потоками, процессами и asyncio
- Найти риск взаимной блокировки
- Время работы пула с ограничением параллелизма
- Смоделировать потерю обновления
- Потоки для CPU-bound задачи
- Как избежать взаимной блокировки
- concurrent.futures
- Зачем в CPython GIL
Ещё 16 вопросов и задач
- Lock против RLock
- fork в многопоточной программе
- Free-threaded CPython в 3.13 и 3.14
- Что такое GIL
- Потоки для сетевых запросов
- Пул процессов без if __name__ == "__main__"
- Задача и подходящий инструмент
- Почему numpy может работать параллельно в потоках
- Порядок результатов pool.map
- Счётчик под блокировкой в потоках
- Что нельзя передать в процесс
- Производитель и потребитель
- Гонка данных при наличии GIL
- Как распараллелить обработку в Python-сервисе
- Что такое GIL и как с ним жить
- Когда CPython переключает потоки
asyncio
Корутины, цикл событий, задачи, gather и TaskGroup, отмена, таймауты и блокирующий код.
Урок: asyncio в Python: корутины, задачи и цикл событий 8 мин- time.sleep внутри корутины
- CancelledError и except Exception
- Время скачивания с семафором
- Сколько займёт асинхронная программа
- Порядок вывода задач с sleep(0)
- Вызов корутины без await
- Почему нужна ссылка на задачу из create_task
- Конкурентный запуск корутин
Ещё 18 вопросов и задач
- Синхронный код внутри asyncio
- Корутина, задача, цикл событий
- Таймауты в asyncio
- Отмена gather
- Что делает gather при ошибке задачи
- Функции asyncio и их назначение
- Сколько потоков использует asyncio
- Когда стартует задача из create_task
- Порядок выполнения задач asyncio
- asyncio.timeout и отмена
- Гонка в однопоточном asyncio
- Ограничение числа одновременных запросов
- Последовательные await против gather
- Как устроен цикл событий asyncio
- asyncio против потоков
- asyncio.Lock и потоки
- Чем TaskGroup лучше gather
- Как вызвать синхронную библиотеку из async-кода
Типизация
Аннотации, mypy, Optional и объединения, дженерики нового синтаксиса, Protocol, TypedDict.
Урок: Типизация в Python: аннотации, mypy, дженерики и Protocol 7 мин- Any против object
- Дженерик-стек
- Сужение типа: нормализовать значение
- Проверить словарь по схеме типов
- TypeVar с ограничением
- Ковариантность и инвариантность
- Зачем аннотации типов
- Вариантность в синтаксисе PEP 695
Ещё 19 вопросов и задач
- Инвариантность list
- Literal для набора значений
- Конструкции typing и их смысл
- Что означает Optional
- Аннотации во время выполнения
- match по типам
- Когда нужен @overload
- Типизация декоратора с сохранением сигнатуры
- Синтаксис дженериков Python 3.12
- Protocol и структурная типизация
- Проверяет ли Python аннотации при выполнении
- Аннотация Self
- Protocol или абстрактный класс
- Как вы используете типизацию в Python-проекте
- Аннотация колбэка
- Зачем if TYPE_CHECKING
- Аннотация словаря списков
- Аннотация «число или None»
- Зачем TypedDict
Память и производительность
Подсчёт ссылок, сборщик циклов, размер объектов, профилирование и типичные ускорения.
Урок: Память и производительность Python-кода 7 мин- Встроенные функции против ручного цикла
- Пересечение больших списков id
- Числа Фибоначчи без экспоненты
- Скользящая медиана потока на двух кучах
- Найти пару с суммой быстрее O(n²)
- Циклические ссылки и gc
- Управление памятью в CPython
- Инструменты профилирования Python
Ещё 20 вопросов и задач
- Почему Python медленнее C
- gc.freeze в форкающихся воркерах
- Поколения сборщика мусора
- Что показывает sys.getsizeof
- Количество различных чисел
- Суммы на отрезках: префиксные суммы
- k наибольших чисел
- Почему локальные переменные быстрее глобальных
- Инструмент и что он измеряет
- Почему in по списку медленный
- del и время жизни объекта
- Слабая ссылка после удаления объекта
- С чего начинать оптимизацию
- Как CPython освобождает память
- __slots__ для миллионов объектов
- Утечка памяти в Python-воркере
- Как ускорить медленный Python-сервис
- Склейка строк в цикле
- Как найти утечку памяти
- Зачем WeakValueDictionary
Стандартная библиотека
collections, itertools, functools, heapq, bisect, datetime, pathlib, json, re и logging на практике.
Урок: Стандартная библиотека Python, которую ждут на собесе 8 мин- Что возвращает bisect_left
- Рабочие дни между датами
- Разности соседних значений
- Развернуть вложенный JSON в плоские ключи
- Оценка по баллам через bisect
- Слить k отсортированных списков
- Разбор строк лога регулярным выражением
- Арифметика Counter
Ещё 25 вопросов и задач
- defaultdict и setdefault
- Самые частые слова через Counter
- Модуль collections
- heapq и bisect
- Работа с таймзонами
- groupby требует сортировки
- Макс-куча в heapq
- Кириллица в json.dumps
- Сколько элементов не больше x: бинарный поиск
- Минимальное число переговорок
- Слияние пересекающихся интервалов
- Минимальная грузоподъёмность: бинарный поиск по ответу
- Максимум в скользящем окне
- Самые частые слова с правилом равенства
- Форматирование сообщений logging
- Задача и модуль стандартной библиотеки
- Naive и aware datetime
- Counter и most_common
- Арифметика дат и таймзоны
- Порядок извлечения из кучи
- secrets против random
- Даты и таймзоны в бэкенде
- Модули стандартной библиотеки, которыми вы пользуетесь
- Безопасный вызов внешней команды
- Почему не datetime.utcnow()
Тестирование и pytest
Фикстуры, parametrize, моки и monkeypatch, изоляция тестов и покрытие.
Урок: Тестирование на Python: pytest, фикстуры и моки 7 мин- Тестируемая функция со временем
- Фейковый репозиторий вместо БД
- Мини-раннер параметризованных тестов
- Функция slugify и таблица тестов
- Зачем conftest.py
- Что говорит 100% покрытие
- Параметризованный тест pytest
- Фикстура с yield
Ещё 17 вопросов и задач
- Встроенные фикстуры pytest
- Фикстура pytest
- Mock, stub и fake
- Изоляция тестов с базой данных
- Инструменты тестирования Python
- Что плохого в избыточных моках
- Встроенная фикстура monkeypatch
- Жизненный цикл фикстуры с yield
- Mock записывает вызовы
- Mock без spec и опечатка в методе
- Зачем pytest.mark.parametrize
- Где делать patch
- Проверка исключения в pytest
- scope у фикстуры
- Как протестировать код с внешним API
- Как вы тестируете Python-сервис
- Тестирование кода, зависящего от времени