Спасательный круг для собеседования на Python-разработчика
Шпаргалка в форме вопрос-ответ с примерами и ссылками на источники в помощь для собеседования на Python. Составлена по реальным интервью.
Всё ли вы знаете для собеседования на Python? Ниже мы собрали популярные вопросы для разработчика Python и ответы на них. Там, где кратким пояснением не обойтись, приведены ссылки на подходящие источники. Естественно, никакой список не обозначит все возможные вопросы собеседования. Зато вы сможете отыскать лакуны в знаниях и вовремя их исправить.
Типы данных и конструкции, которые нужно знать для собеседования на Python
Какие вам знакомы структуры данных Python? Перечислите, какие из них mutable/immutable.
Кроме базовых структур данных (mutable: list, dict, set и immutable – tuple) полезно разбираться в модуле collections с удобными дополнительными структурами, такими как Counter.
Что делает функция id()?
Возвращает идентификатор переданного объекта, уникальный на время его существования.
Как удалить повторяющиеся элементы списка, сохранив порядок следования остальных?
lst = ["a", "b", "a", "c", "c"] lst = list(dict.fromkeys(lst))
Как получить список всех атрибутов объекта?
В простейшем виде с помощью функции dir(). Об особых случаях читайте здесь.
Как получить конкатенацию кортежей, выкинув неуникальные элементы?
Через множества:
tuple(set((1, 2)) ^ set((2, 3)))
Почему при изменении списка в цикле используется конструкция вида for x in x in lst[:]
?
Здесь применяется оператор среза [:], то есть создается копия. Поэтому изменения в цикле не влияют на оригинальный список.
Где будет быстрее поиск и почему: dict, list, set, tuple?
Средняя временная сложность поиска в множествах и словарях соответствует O(1), в случае последовательностей O(n). Кортежи – это неизменяемый тип, поэтому они могут давать выигрыш в скорости перед списками.
Есть два списка одинаковой длины. В одном – ключи, в другом – значения. Как составить словарь?
dict(zip(['key1', 'key2'], ['value1', 'value2']))
Как инвертировать словарь, то есть поменять местами пары ключ-значения?
Базовыми средствами без привлечения библиотеки itertools так:
d = {'a': 1, 'b': 2} dict(zip(d.values(), d.keys()))
Итераторы и анонимные функции
В чем отличие (i for i in arr)
от [i for i in arr]
?
Слева – выражение-генератор, справа – генератор списка (list comprehension). Генератор списка целиком создает список в памяти, а выражение-генератор – по мере необходимости.
В чем отличие итераторов и генераторов?
Итератор является более общей концепцией, чем генератор, и представляет собой любой объект, класс которого имеет методы __next__ и __iter__. Генератор – это итератор, который обычно создается путем вызова функции, содержащей не менее одного оператора yield. Это ключевое слово действует аналогично return, но возвращает объект-генератор.
Что такое анонимные функции? Где они могут быть полезны?
В Python анонимные функции создаются при помощи лямбда-выражений. Такие выражения удобно использовать в местах, где ожидается функция с достаточно ограниченной задачей.
Классы и декораторы
Если для собеседования на Python вам необходимо освежить знания в ООП, загляните в статью ООП на Python.
Что такое магические методы?
Так называют специальные методы, обрамленные двумя подчеркиваниями. Магические методы представляют простой способ заставить объекты вести себя аналогично встроенным типам. Это, в частности, позволяет стандартизировать поведение базовых операторов с экземплярами класса.
Чем new
отличается от init
?
Метод __new__ используется, когда нужно управлять процессом создания нового экземпляра, а __init__ – когда контролируется его инициализация. Поэтому new возвращает новый экземпляр класса, а init – ничего.
Какая разница между одинарным (_) и двойным (__) подчеркиванием перед именем объекта?
Одинарным подчеркиванием задаются частные переменные, функции, методы и классы. Все эти объекты будут проигнорированы при импорте с помощью
from module import *
Двойное подчеркивание применяется для искажения имен атрибутов в классе (вызвать такой метод стандартным образом не получится). О других случаях.
Как в Python воплощены public, private, protected методы?
Этот вопрос напрямую связан с предыдущим. Все компоненты класса Python по умолчанию являются открытыми (public). Для защищенных (protected) методов по соглашению Python добавляется префикс одиночного подчеркивания, для закрытых (private) методов – префикс двойного подчеркивания. Примеры и пояснения.
Что такое MRO?
MRO – сокращение от method resolution order. То есть это способ разрешения проблемы множественного наследования классов. Для конструирования линеаризации класса в версиях Python с новым стилем классов используется алгоритм C3 линеаризации.
Для чего в Python используются слоты?
Магический атрибут __slots__ позволяет задать ограниченный набор атрибутов, которыми будет обладать экземпляр класса. За счет такого ограничения можно повысить скорость работы при доступе к атрибутам и сэкономить место в памяти.
Что такое контекстные менеджеры? Где они применяются? Как создать свой контекстный менеджер?
Контекстные менеджеры – это конструкции, которые упрощают работу с тем или иным интерфейсом. Например, работу с файлами или базами данных. Создаются они с помощью оператора with. Для создания собственного класса контекстного менеджера используется библиотека contextlib.
Декораторы, дескрипторы и метаклассы
Что такое декораторы с параметрами?
В качестве декоратора можно использовать выражение, значение которого – функция, принимающая и возвращающая функцию. А значит, можно создавать декораторы с параметрами (фабрики декораторов). Подробно с примерами.
Чем отличаются и как используются декораторы @classmethod и @staticmethod?
Базовые декораторы classmethod, staticmethod используются для методов, определённых внутри классов. В метод класса первым аргументом передаётся класс. Аналогично метод экземпляра в первом аргументе получает сам экземпляр. Статичный метод используется в том случае, когда метод не имеет доступа к тому, что представляет собой класс или объект класса.
Что такое дескриптор?
Дескриптор – атрибут объекта, чьё поведение при доступе переопределяется методами __get__, __set__ и __delete__. Если определен хотя бы один из этих методов, объект становится дескриптором.
Что такое метаклассы в Python?
В Python классы являются объектами, поэтому они сами должны чем-то генерироваться. Эти конструкции представляют собой своеобразные «классы классов» и называются метаклассами. Примером встроенного метакласса является type. В основном метаклассы используются для создания API. Подробнее читайте в нашей публикации.
Тестирование, отладка и стиль кода
Как вы тестируете код? Что такое mock?
Для модульного тестирования используется unittest. Если вы пока не тестировали код на Python, у нас есть гайд. Mock – это специальный модуль (ставший недавно частью стандартной библиотеки) для тестирования без существенной адаптации кода под тесты.
Как проводится отладка программ на Python?
В Python есть модуль pdb. Он позволяет пошагово провести отладку программы. В версии 3.7 появилась функция breakpoint(), которая также облегчает дебаггинг.
Что такое PEP8?
Cоглашение о том, как писать код на Python. Нередко среда разработки после соответствующей настройки позволяет автоматически поддерживать программный код в соответствии с этими правилами или теми, что приняты в компании.
Какие есть программы для проверки стиля кода? Каковы их преимущества и недостатки?
Скажем, pylint, pyflakes. Наиболее популярные инструменты мы уже описали и сравнили.
Производительность и проектирование
В чём состоит отличие процессов от потоков?
Модули – это subprocess и threading. Использование нескольких процессов аналогично использованию нескольких независимых программ, обмен данными организован через каналы. Если приложение должно выполнять несколько задач в одно и то же время, используются потоки (threads). В этом случае для ограничения доступа потоков к памяти в Python имеется блокировщик GIL.
Что такое AsyncIO? Когда его имеет смысл использовать?
В отличие от потоков, в AsyncIO переключение между сопрограммами происходит лишь тогда, когда сопрограмма ожидает завершения внешней операции. AsyncIO подойдет, если приложение большую часть времени тратит на чтение/запись данных, а не их обработку, то есть, например, для работы с веб-сокетами.
В чем заключается проблема циклических зависимостей? Как ее решить?
Циклические зависимости обычно служат признаком некачественного проектирования системы. Временное решение – перенести импорт во вложенные области видимости. В частности, определения функций.
Как реализовать шаблон Singleton на Python? Какие есть альтернативы?
Стандартный пример описан в примерах PEP-0318. Менее удобна для тестирования реализация через декоратор, элегантнее вариант через метаклассы.
Какие шаблоны проектирования вы еще знаете? Какими пользовались?
Фабричный метод, абстрактная фабрика, прототип, компоновщик, итератор.