50 ключевых вопросов на собеседовании Python-разработчика: подготовка
Для кого эта статья:
- Python-разработчики, готовящиеся к собеседованиям
- Специалисты, стремящиеся улучшить свои навыки программирования и уверенность при прохождении интервью
Рекрутеры и менеджеры по найму, желающие понять, какие вопросы задавать кандидатам на позицию Python-разработчика
Собеседование на Python-разработчика — игра, где ставки высоки, а правила меняются от компании к компании. Один неверный ответ может стоить вам работы мечты, а правильная подготовка открывает двери в топовые IT-компании с шестизначными зарплатами. Изучив топ-50 вопросов, от базовых понятий до сложных архитектурных решений, вы сформируете арсенал знаний, который впечатлит даже самого придирчивого технического интервьюера. Готовы превратить стрессовое собеседование в демонстрацию вашего мастерства? 🐍
Хотите гарантированно пройти техническое собеседование на Python-разработчика? Курс Python-разработки от Skypro подготовит вас к самым каверзным вопросам от рекрутеров. В отличие от справочников и статей, наши эксперты дают актуальную информацию из реальных интервью 2023 года, а также проводят mock-интервью с детальным разбором ошибок. Выпускники курса успешно проходят собеседования в 87% случаев — впечатляющий результат для рынка с высокой конкуренцией!
Как подготовиться к собеседованию на Python-разработчика
Подготовка к техническому интервью — процесс, требующий системного подхода. Многие разработчики совершают фатальную ошибку, пытаясь за ночь выучить все концепции Python. Результат предсказуем: поверхностные знания, которые рассыпаются при первом же уточняющем вопросе интервьюера.
Эффективная подготовка включает несколько ключевых компонентов:
- Диагностика текущего уровня — определите, к какой категории вы относитесь (junior, middle, senior), и сфокусируйтесь на соответствующих вопросах.
- Регулярная практика кодирования — решайте алгоритмические задачи на платформах вроде LeetCode или HackerRank, фокусируясь на задачах с использованием Python.
- Глубокое понимание основ — изучите детально работу GIL, модель памяти, особенности ООП в Python и другие фундаментальные концепции.
- Знание экосистемы — ознакомьтесь с популярными фреймворками и библиотеками (Django, Flask, Pandas, NumPy), релевантными для вашей специализации.
- Проработка реальных кейсов — подготовьте рассказы о проектах, в которых вы участвовали, с акцентом на технические решения и ваш вклад.
Андрей Петров, Senior Python Developer
Я провалил три собеседования подряд, прежде чем понял свою ошибку. Я готовился хаотично: читал статьи, смотрел видео, но не систематизировал знания. Для четвертого интервью я составил таблицу тем с приоритетами, ежедневно уделял два часа практике и записывал ответы на диктофон, анализируя их качество. Кроме того, я провел пять пробных собеседований с коллегами, что помогло выявить пробелы в знаниях о многопоточности и асинхронном программировании. В результате четвертое собеседование в компании, о которой я мечтал, прошло блестяще — интервьюер даже заметил: "Редко встречаю кандидатов с таким структурированным мышлением".
Важный аспект подготовки — понимание типичной структуры технического собеседования для Python-разработчиков:
| Этап | Длительность | Содержание | Рекомендации |
|---|---|---|---|
| Общие вопросы по программированию | 10-15 минут | Алгоритмы, структуры данных, паттерны проектирования | Повторите базовые алгоритмы сортировки и поиска |
| Специфические вопросы по Python | 20-30 минут | Особенности языка, GIL, метаклассы, декораторы | Практикуйте объяснение сложных концепций простым языком |
| Практическое задание | 30-60 минут | Написание кода, решение алгоритмических задач | Тренируйтесь писать код без IDE, проговаривая процесс мышления |
| Системное проектирование | 15-20 минут | Архитектура приложений, масштабирование | Изучите принципы SOLID и архитектурные паттерны |
| Вопросы кандидата | 5-10 минут | Возможность задать вопросы интервьюеру | Подготовьте вопросы, демонстрирующие ваш интерес к компании |
Помните: интервьюеры ценят не только правильные ответы, но и ход мыслей. Умение структурированно рассуждать, признавать пробелы в знаниях и задавать уточняющие вопросы часто ценится выше идеальных, но заготовленных ответов. 🧠

Базовые вопросы по Python для junior-специалистов
Junior-разработчикам необходимо продемонстрировать твердое понимание основ Python. На этом уровне интервьюеры оценивают базовые знания и потенциал роста, а не глубокую экспертизу. Рассмотрим ключевые вопросы, которые регулярно появляются на собеседованиях начального уровня.
1. В чем разница между списками и кортежами в Python? Списки (lists) являются изменяемыми, кортежи (tuples) — неизменяемыми. Кортежи обычно используются для гетерогенных данных, списки — для гомогенных. Кортежи занимают меньше памяти и обеспечивают защиту от непреднамеренных изменений.
2. Что такое PEP 8? PEP 8 — руководство по стилю кодирования на Python, описывающее соглашения о форматировании: отступы (4 пробела), максимальную длину строки (79 символов), соглашения об именовании и другие стилистические рекомендации для повышения читаемости кода.
3. Как работают словари в Python и какова их внутренняя реализация? Словари — это коллекции пар ключ-значение, реализованные через хеш-таблицы. Ключи должны быть неизменяемыми объектами. Доступ к элементам выполняется за постоянное время O(1) в среднем случае.
4. Объясните работу с исключениями в Python. Обработка исключений выполняется через блоки try/except/else/finally. Это позволяет изящно обрабатывать ошибки и обеспечивать корректное выполнение критических операций (например, закрытие файлов) даже при возникновении ошибок.
try:
# Код, который может вызвать исключение
result = x / y
except ZeroDivisionError:
# Обработка конкретного исключения
print("Деление на ноль!")
except Exception as e:
# Обработка других исключений
print(f"Ошибка: {e}")
else:
# Выполняется, если исключений не возникло
print(f"Результат: {result}")
finally:
# Выполняется всегда
print("Операция завершена")
5. Что такое генераторы и генераторные выражения? Генераторы — это функции, возвращающие итерируемый объект с помощью yield вместо return. Они создают значения "на лету" и не хранят весь набор данных в памяти, что делает их эффективными для работы с большими наборами данных.
6. Как работают списковые включения (list comprehensions)? Списковые включения — это синтаксический сахар для создания списков. Они обеспечивают более элегантную и читаемую альтернативу циклам for с условными проверками.
# Традиционный подход
squares = []
for i in range(10):
squares.append(i**2)
# Списковое включение
squares = [i**2 for i in range(10)]
# С условием
even_squares = [i**2 for i in range(10) if i % 2 == 0]
7. Объясните разницу между методами __new__ и __init__.
__new__ — статический метод, отвечающий за создание экземпляра класса. __init__ инициализирует уже созданный экземпляр. __new__ вызывается перед __init__ и может возвращать экземпляр другого класса.
8. Что такое менеджеры контекста и как их использовать?
Менеджеры контекста (context managers) обеспечивают корректное выполнение операций инициализации и очистки ресурсов. Реализуются через протокол __enter__/__exit__ или декоратор @contextmanager.
# Использование менеджера контекста для работы с файлами
with open('file.txt', 'r') as f:
data = f.read()
# Файл автоматически закрывается при выходе из блока with
9. Как работает сборщик мусора в Python? Python использует подсчет ссылок как основной механизм сборки мусора. Когда количество ссылок на объект достигает нуля, объект удаляется. Дополнительно используется циклический сборщик для обнаружения и удаления циклических ссылок.
10. Что такое декораторы и как они работают? Декораторы — это функции высшего порядка, которые принимают функцию и возвращают новую функцию, расширяя поведение оригинальной без изменения ее кода. Часто используются для логирования, кэширования, проверки прав доступа.
def logged(func):
def wrapper(*args, **kwargs):
print(f"Вызов {func.__name__} с аргументами {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"Результат: {result}")
return result
return wrapper
@logged
def add(x, y):
return x + y
# Теперь при вызове add() будет выводиться дополнительная информация
result = add(2, 3) # Вызов add с аргументами (2, 3), {}
# Результат: 5
Помимо теоретических вопросов, junior-разработчикам стоит быть готовыми к вопросам о стандартных библиотеках Python:
- collections — расширенные типы данных (defaultdict, Counter, OrderedDict)
- itertools — функции для эффективной работы с итераторами
- functools — инструменты для функционального программирования
- datetime — работа с датами и временем
- json/pickle — сериализация и десериализация данных
Готовность ответить на эти базовые вопросы формирует необходимый фундамент для успешного прохождения интервью на позицию начинающего Python-разработчика. 🚀
Средний уровень: вопросы по Python для middle-разработчиков
Middle-разработчик должен не просто знать базовые конструкции, но и глубоко понимать принципы работы Python, оптимизации кода и продвинутые концепции языка. На этом уровне интервьюеры ожидают от кандидата самостоятельности, опыта принятия технических решений и способности объяснить нюансы выбранных подходов.
Елена Соколова, Tech Lead Python
Я проводила собеседования на позицию middle Python-разработчика для проекта по обработке больших данных. Один кандидат особенно запомнился: когда я спросила о GIL и многопоточности, вместо заученного определения он рассказал, как столкнулся с проблемой производительности в реальном проекте. Он объяснил, как использовал профилирование для выявления узких мест, сравнил подходы с threading и multiprocessing, показал графики бенчмарков и объяснил, почему в конкретном случае переход на asyncio дал 30% прирост скорости. Такой практический подход к ответу, основанный на реальном опыте, а не на теоретических знаниях, сразу выделил его среди других кандидатов. Мы предложили ему позицию в тот же день.
Рассмотрим ключевые вопросы среднего уровня сложности:
11. Объясните Global Interpreter Lock (GIL) и его влияние на многопоточность в Python. GIL — это механизм, который позволяет только одному потоку выполнять байт-код Python одновременно. Это обеспечивает безопасность памяти, но ограничивает истинный параллелизм CPU-bound задач в многопоточных программах. Для CPU-интенсивных задач обычно используют multiprocessing, а для I/O-bound задач threading или asyncio.
12. Как работают метаклассы в Python и для чего они используются? Метаклассы — это классы, создающие другие классы. Они позволяют изменять процесс создания класса, добавляя атрибуты, методы или изменяя существующие. Используются для реализации ORMs, валидации атрибутов класса, автоматической регистрации классов и создания API.
class MetaValidator(type):
def __new__(mcs, name, bases, attrs):
# Проверяем, что все публичные методы имеют документацию
for attr_name, attr_value in attrs.items():
if not attr_name.startswith('_') and callable(attr_value):
if not attr_value.__doc__:
raise TypeError(f"Метод {name}.{attr_name} должен иметь документацию")
return super().__new__(mcs, name, bases, attrs)
class MyClass(metaclass=MetaValidator):
def method_with_doc(self):
"""Этот метод имеет документацию."""
pass
def method_without_doc(self):
# Вызовет ошибку TypeError при определении класса
pass
13. Объясните принцип работы декораторов с параметрами. Декораторы с параметрами — это функции, возвращающие декоратор. Они позволяют настраивать поведение декоратора через параметры, делая его более гибким.
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
results = []
for _ in range(times):
results.append(func(*args, **kwargs))
return results
return wrapper
return decorator
@repeat(times=3)
def say_hello():
return "Hello"
print(say_hello()) # ['Hello', 'Hello', 'Hello']
14. Как работают дескрипторы и когда их стоит использовать?
Дескрипторы — это объекты, реализующие протокол __get__, __set__ или __delete__. Они позволяют контролировать доступ к атрибутам класса. Применяются для валидации, вычисляемых свойств, ленивой загрузки данных.
15. Объясните различия между __getattr__, __getattribute__ и дескрипторами.
__getattr__ вызывается, когда атрибут не найден. __getattribute__ вызывается при любом доступе к атрибуту и может перехватить все обращения. Дескрипторы определяют поведение конкретных атрибутов. Неправильное использование __getattribute__ может вызвать бесконечную рекурсию.
16. Какие методы оптимизации производительности Python-кода вы знаете? Оптимизация включает профилирование (cProfile, line_profiler), использование оптимизированных структур данных, генераторов вместо списков для больших наборов данных, JIT-компиляторов (PyPy, Numba), перенос критических участков на Cython/C и применение многопроцессорности для CPU-bound задач.
17. Объясните работу с асинхронным программированием в Python (asyncio). asyncio — это библиотека для написания конкурентного кода с использованием синтаксиса async/await. Она позволяет обрабатывать множество I/O-операций без блокировки в рамках одного потока, что повышает эффективность I/O-bound приложений.
import asyncio
async def fetch_data(url):
print(f"Начинаем загрузку {url}")
await asyncio.sleep(2) # Имитация I/O операции
print(f"Данные с {url} получены")
return f"Результат от {url}"
async def main():
# Запускаем задачи конкурентно
results = await asyncio.gather(
fetch_data("example.com/1"),
fetch_data("example.com/2"),
fetch_data("example.com/3")
)
print(results)
# Выполнение займет примерно 2 секунды, а не 6
asyncio.run(main())
18. Как работают генераторы и корутины? В чем разница между ними? Генераторы — это функции с yield, которые возвращают итератор. Корутины (async функции) — это расширение генераторов, позволяющее приостанавливать и возобновлять выполнение функции с сохранением состояния. Основное различие: генераторы производят данные, корутины потребляют данные и позволяют двунаправленную коммуникацию.
19. Объясните процесс импорта модулей в Python и систему поиска модулей. При импорте Python ищет модуль в следующих местах: текущий каталог, PYTHONPATH, стандартные библиотеки, каталоги .pth-файлов. Система импорта включает поиск, компиляцию (при необходимости), выполнение кода модуля и кэширование. Результат кэшируется в sys.modules для избежания повторной загрузки.
20. Какие паттерны проектирования вы использовали в Python-проектах? Среди популярных паттернов: Singleton (для доступа к базе данных), Factory Method (создание объектов без указания конкретного класса), Observer (механизм событий), Strategy (изменение алгоритма во время выполнения), Decorator (расширение функциональности объектов).
| Паттерн | Описание | Применение в Python | Потенциальные проблемы |
|---|---|---|---|
| Singleton | Гарантирует, что класс имеет только один экземпляр | Соединения с БД, логгеры, кэши | Затрудняет тестирование, нарушает SRP |
| Factory | Создает объекты без указания конкретного класса | Конфигурируемые объекты, плагины | Может усложнить код при небольшой иерархии |
| Observer | Определяет зависимость "один ко многим" между объектами | GUI-приложения, обработка событий | Непредсказуемость порядка оповещения наблюдателей |
| Strategy | Определяет семейство алгоритмов и делает их взаимозаменяемыми | Различные алгоритмы сортировки, валидации | Клиент должен знать о различных стратегиях |
| Decorator | Динамически добавляет объекту новые обязанности | Логирование, кэширование, авторизация | Может привести к большому количеству мелких классов |
21. Как работает управление памятью в Python? Python использует автоматическое управление памятью с подсчетом ссылок и циклическим сборщиком мусора. Для оптимизации применяются пулы объектов (для небольших целых чисел), а для минимизации фрагментации — специальные стратегии выделения памяти.
22. Что такое контекстные переменные и как их использовать? Контекстные переменные (contextvars) позволяют хранить значения в контексте выполнения и обеспечивают изоляцию между различными задачами asyncio. Это улучшенная альтернатива threading.local для асинхронного кода.
23. Объясните принцип работы property-декораторов и их преимущества. Property-декораторы позволяют определять методы, которые ведут себя как атрибуты. Они обеспечивают инкапсуляцию, валидацию, вычисляемые свойства без изменения API класса.
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0:
raise ValueError("Возраст не может быть отрицательным")
self._age = value
@property
def is_adult(self):
return self._age >= 18
person = Person("Alice", 25)
print(person.age) # 25
person.age = 30 # Использование setter
print(person.is_adult) # True
24. Какие проблемы могут возникнуть при работе с многопоточностью/многопроцессностью и как их решать? Основные проблемы: состояние гонки (race conditions), взаимная блокировка (deadlocks), проблема производителя-потребителя. Решения: использование блокировок (Lock, RLock), семафоров, очередей, избегание сложных блокировок, применение синхронизации только когда необходимо.
25. Расскажите о модуле collections в стандартной библиотеке Python. collections предоставляет специализированные контейнеры: Counter (подсчет элементов), defaultdict (словарь с дефолтными значениями), deque (эффективная двусторонняя очередь), namedtuple (именованные кортежи), OrderedDict (словарь с сохранением порядка вставки, в новых версиях Python обычные dict также сохраняют порядок).
Для middle-разработчика критично не только знать ответы на эти вопросы, но и уметь демонстрировать понимание практического применения этих концепций в реальных проектах. 🔧
Senior Python: сложные вопросы для опытных разработчиков
Senior-разработчики должны демонстрировать глубокое понимание внутренних механизмов Python, архитектурных решений и оптимизации производительности. На этом уровне ожидается не просто знание синтаксиса и концепций, а понимание всей экосистемы Python, включая CPython, альтернативные реализации и способы взаимодействия с низкоуровневым кодом.
26. Объясните принципы работы интерпретатора Python и этапы выполнения кода. Интерпретатор Python работает в несколько этапов: лексический анализ (токенизация), синтаксический анализ (построение AST), компиляция (преобразование AST в байт-код) и выполнение байт-кода виртуальной машиной. Понимание этих этапов позволяет оптимизировать код и эффективно использовать такие инструменты как ast и dis.
27. Расскажите об устройстве объектной модели Python. Всё в Python является объектами, включая функции, классы и модули. Каждый объект имеет идентификатор, тип и значение. Объектная модель включает MRO (Method Resolution Order) для наследования, дескрипторы для управления доступом к атрибутам, и протоколы для определения поведения объектов (итерации, контекстные менеджеры и т.д.).
28. Как работают slots и когда их следует использовать? slots позволяет явно определить все атрибуты класса, предотвращая создание динамического словаря dict. Это уменьшает расход памяти (до 50%) и слегка ускоряет доступ к атрибутам. Однако slots ограничивает динамическое добавление новых атрибутов и усложняет множественное наследование.
class RegularClass:
pass
class SlottedClass:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
# Демонстрация разницы в потреблении памяти
import sys
regular_objects = [RegularClass() for _ in range(1000000)]
slotted_objects = [SlottedClass(0, 0) for _ in range(1000000)]
print(f"Память regular: {sys.getsizeof(regular_objects[0]) * len(regular_objects)}")
print(f"Память slotted: {sys.getsizeof(slotted_objects[0]) * len(slotted_objects)}")
29. Объясните работу с многопоточностью в Python и ограничения GIL. Как оптимизировать многопоточные программы? GIL (Global Interpreter Lock) позволяет только одному потоку выполнять байт-код Python, что ограничивает истинный параллелизм для CPU-bound задач. Для оптимизации: используйте threading для I/O-bound задач, multiprocessing для CPU-bound задач, минимизируйте обращения к GIL в критических секциях, используйте релизы GIL в C-расширениях и применяйте альтернативные реализации Python (PyPy) или JIT-компиляторы (Numba).
30. Расскажите о современных подходах к конкурентному программированию в Python. Современные подходы включают: asyncio для неблокирующего I/O и корутины, структурированный параллелизм с concurrent.futures, комбинирование асинхронности с многопроцессностью для гибридных нагрузок, применение специализированных фреймворков (Dask для распределенных вычислений) и интеграцию с C++/Rust через pybind11/PyO3 для высокопроизводительных компонентов.
31. Как проводить профилирование Python-кода и оптимизировать узкие места? Профилирование включает использование cProfile/lineprofiler для определения горячих точек, memoryprofiler для анализа памяти, tracemalloc для отслеживания утечек и py-spy для профилирования production-среды. Оптимизация: алгоритмические улучшения, кэширование результатов, использование оптимизированных структур данных, JIT-компиляция критических участков.
32. Расскажите о типизации в Python. Как использовать статическую типизацию и ее преимущества? Python 3.5+ поддерживает аннотации типов через модуль typing. Преимущества: раннее обнаружение ошибок с помощью mypy/pyright, улучшение документации кода, лучший IntelliSense в IDE. Сложности: увеличение объема кода, необходимость поддержки аннотаций в актуальном состоянии, особенности типизации для динамичных аспектов Python (метаклассы, функциональное программирование).
33. Объясните принципы метапрограммирования в Python и когда его следует применять. Метапрограммирование — это код, который манипулирует другим кодом. Включает метаклассы, декораторы, monkey patching, динамическое создание атрибутов/методов. Применяется для создания DSL, ORM, автоматической регистрации компонентов, валидации в момент определения классов. Требует осторожности из-за потенциального усложнения кода и снижения его читаемости.
34. Какие существуют альтернативные реализации Python и их особенности? Основные альтернативы CPython: PyPy (JIT-компиляция, выше скорость, собственный GIL), Jython (интеграция с Java, без GIL), IronPython (интеграция с .NET), MicroPython/CircuitPython (для микроконтроллеров), Stackless Python (микропотоки), Pyston (JIT-оптимизации для веб-серверов).
35. Как работает интеграция Python с C/C++ кодом? Расскажите о различных подходах. Основные подходы: Python C API (прямой доступ к CPython API), Cython (транслирует Python-подобный код в C), ctypes (вызов функций из динамических библиотек), CFFI (интерфейс взаимодействия с C), pybind11 (C++11 интеграция), Boost.Python (С++ обертки для Python). Выбор зависит от требований к производительности, удобства разработки и переносимости.
36. Объясните принципы Clean Architecture в контексте Python-приложений. Clean Architecture предполагает разделение приложения на слои: сущности (бизнес-объекты), use cases (бизнес-логика), интерфейсы (API, контроллеры), инфраструктура (БД, внешние сервисы). Ключевые принципы: зависимости направлены внутрь, внутренние слои не знают о внешних, бизнес-логика изолирована от деталей реализации. Реализуется через инверсию зависимостей, абстракции и тщательное проектирование границ модулей.
37. Какие архитектурные паттерны вы применяли в крупных Python-проектах? В зависимости от типа приложения: Hexagonal Architecture (порты и адаптеры для изоляции ядра), CQRS (разделение команд и запросов), Event Sourcing (хранение состояния как последовательности событий), Microservices (деление системы на независимые сервисы с асинхронной коммуникацией), DDD (моделирование на основе предметной области).
38. Расскажите о принципах эффективного тестирования Python-кода. Эффективное тестирование включает: многоуровневый подход (unit, integration, system, e2e тесты), TDD/BDD методологии, параметризованные тесты для покрытия множества сценариев, использование моков и стабов для изоляции тестов, property-based testing для обнаружения неочевидных ошибок, мутационное тестирование для оценки качества тестов, непрерывное выполнение тестов в CI/CD.
39. Как обеспечить устойчивость и отказоустойчивость в Python-приложениях? Ключевые аспекты: Circuit Breaker для предотвращения каскадных сбоев, Bulkhead для изоляции ресурсов, Timeout для ограничения времени ожидания, Retry с экспоненциальной задержкой, Rate Limiting для защиты от перегрузок, Graceful Degradation при отказе компонентов, распределенное логгирование, мониторинг и трассировка (OpenTelemetry), постоянные стресс-тесты системы.
40. Как реализовать безопасное и эффективное межпроцессное взаимодействие в Python? Для IPC можно использовать: multiprocessing.Queue/Pipe для коммуникации между процессами, shared memory через multiprocessing.Value/Array, использование базы данных или key-value хранилища (Redis), сетевые протоколы (socket, ZeroMQ), системные механизмы IPC (file, pipe, mmap), RPC через gRPC/Apache Thrift для более сложных сценариев.
Кандидаты на позицию Senior Python Developer должны не только знать ответы на эти вопросы, но и демонстрировать способность принимать архитектурные решения, анализировать компромиссы различных подходов и выбирать оптимальные инструменты для конкретных задач. 🏗️
Практические задачи по Python на технических собеседованиях
Помимо теоретических вопросов, технические интервью для Python-разработчиков обычно включают практические задания. Эти задачи позволяют оценить не только знания кандидата, но и его способность применять их на практике, алгоритмическое мышление и навыки написания чистого, эффективного кода.
Рассмотрим типичные практические задачи разного уровня сложности, которые часто встречаются на собеседованиях:
41. Задача на строки и базовые алгоритмы (Junior) Проверить, является ли строка палиндромом (читается одинаково в обоих направлениях, игнорируя пробелы, знаки препинания и регистр).
def is_palindrome(s):
# Приводим к нижнему регистру и удаляем все нецифровые и небуквенные символы
s = ''.join(c for c in s.lower() if c.isalnum())
return s == s[::-1]
# Тесты
assert is_palindrome("A man, a plan, a canal: Panama") == True
assert is_palindrome("race a car") == False
42. Задача на работу с коллекциями (Junior) Найти первый неповторяющийся символ в строке.
def first_non_repeating_char(s):
char_count = {}
# Подсчитываем частоту каждого символа
for char in s:
char_count[char] = char_count.get(char, 0) + 1
# Находим первый символ с частотой 1
for char in s:
if char_count[char] == 1:
return char
return None
# Тесты
assert first_non_repeating_char("leetcode") == "l"
assert first_non_repeating_char("loveleetcode") == "v"
43. Задача на рекурсию (Junior+/Middle) Написать функцию для вычисления n-го числа Фибоначчи с использованием рекурсии и мемоизации.
def fibonacci(n, memo={}):
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)
return memo[n]
# Тесты
assert fibonacci(0) == 0
assert fibonacci(1) == 1
assert fibonacci(10) == 55
44. Задача на ООП (Middle) Реализуйте класс для работы с рациональными числами (дробями) с перегрузкой операторов.
from math import gcd
class Fraction:
def __init__(self, numerator, denominator):
if denominator == 0:
raise ZeroDivisionError("Denominator cannot be zero")
# Нормализация знака
if denominator < 0:
numerator, denominator = -numerator, -denominator
# Сокращение дроби
g = gcd(abs(numerator), denominator)
self.numerator = numerator // g
self.denominator = denominator // g
def __add__(self, other):
if isinstance(other, int):
other = Fraction(other, 1)
return Fraction(
self.numerator * other.denominator + other.numerator * self.denominator,
self.denominator * other.denominator
)
def __sub__(self, other):
if isinstance(other, int):
other = Fraction(other, 1)
return Fraction(
self.numerator * other.denominator – other.numerator * self.denominator,
self.denominator * other.denominator
)
def __mul__(self, other):
if isinstance(other, int):
other = Fraction(other, 1)
return Fraction(
self.numerator * other.numerator,
self.denominator * other.denominator
)
def __truediv__(self, other):
if isinstance(other, int):
other = Fraction(other, 1)
return Fraction(
self.numerator * other.denominator,
self.denominator * other.numerator
)
def __eq__(self, other):
if isinstance(other, int):
other = Fraction(other, 1)
return (self.numerator == other.numerator and
self.denominator == other.denominator)
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
return f"{self.numerator}/{self.denominator}"
# Тесты
f1 = Fraction(1, 2)
f2 = Fraction(1, 3)
assert str(f1 + f2) == "5/6"
assert str(f1 – f2) == "1/6"
assert str(f1 * f2) == "1/6"
assert str(f1 / f2) == "3/2"
45. Задача на алгоритмы и структуры данных (Middle) Реализовать алгоритм обхода бинарного дерева в ширину (BFS) и вернуть значения узлов по уровням.
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def level_order_traversal(root):
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue)
level_values = []
for _ in range(level_size):
node = queue.popleft()
level_values.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(level_values)
return result
# Тесты
tree = TreeNode(3,
TreeNode(9),
TreeNode(20,
TreeNode(15),
TreeNode(7)))
assert level_order_traversal(tree) == [[3], [9, 20], [15, 7]]
46. Задача на обработку исключений и контекстные менеджеры (Middle) Реализуйте контекстный менеджер для измерения времени выполнения кода и логирования исключений.
import time
import logging
import traceback
from contextlib import contextmanager
@contextmanager
def measure_execution_time(task_name):
start_time = time.time()
try:
yield
elapsed_time = time.time() – start_time
logging.info(f"Task '{task_name}' completed in {elapsed_time:.4f} seconds")
except Exception as e:
elapsed_time = time.time() – start_time
logging.error(f"Task '{task_name}' failed after {elapsed_time:.4f} seconds")
logging.error(f"Error: {str(e)}")
logging.debug(f"Traceback: {traceback.format_exc()}")
raise
# Использование
logging.basicConfig(level=logging.INFO)
def complex_calculation():
time.sleep(0.1)
return 42
def failing_calculation():
time.sleep(0.1)
raise ValueError("Something went wrong")
with measure_execution_time("Complex calculation"):
result = complex_calculation()
print(f"Result: {result}")
try:
with measure_execution_time("Failing calculation"):
failing_calculation()
except ValueError:
print("Caught the expected error")
47. Задача на многопоточность/асинхронность (Middle+/Senior) Реализовать асинхронную функцию, которая параллельно загружает данные из нескольких URL и обрабатывает результаты.
import asyncio
import aiohttp
import time
async def fetch_url(session, url, timeout=10):
try:
async with session.get(url, timeout=timeout) as response:
return {
'url': url,
'status': response.status,
'content': await response.text(),
'error': None
}
except asyncio.TimeoutError:
return {'url': url, 'error': 'Timeout error', 'status': None, 'content': None}
except Exception as e:
return {'url': url, 'error': str(e), 'status': None, 'content': None}
async def fetch_multiple_urls(urls, max_concurrency=5):
connector = aiohttp.TCPConnector(limit=max_concurrency)
async with aiohttp.ClientSession(connector=connector) as session:
tasks = [fetch_url(session, url) for url in urls]
return await asyncio.gather(*tasks)
async def process_urls(urls):
start_time = time.time()
results = await fetch_multiple_urls(urls)
# Обработка результатов
successful = [r for r in results if r['error'] is None]
failed = [r for r in
**Читайте также**
- [Кортежи в Python: мощный инструмент для эффективного кода](/python/rabota-s-kortezhami-tuple-v-python/)
- [Асинхронное программирование в Python: повышаем скорость кода](/python/asinhronnoe-programmirovanie-v-python-osnovy/)
- [Словари Python: мощный инструмент для эффективного хранения данных](/python/rabota-so-slovaryami-v-python/)
- [Python: 10 библиотек, которые ускорят вашу разработку в разы](/python/primery-ispolzovaniya-bibliotek-v-python/)
- [Полиморфизм в Python: принципы, типы и практическое применение](/python/polimorfizm-v-python/)
- [Операторы и выражения Python: мастерство программирования – тире, запятая](/python/operatory-i-vyrazheniya-v-python/)
- [Множества в Python: уникальность, эффективность и математика данных](/python/rabota-s-mnozhestvami-v-python/)
- [Циклы в Python: for и while для эффективной автоматизации задач](/python/cikly-v-python-for-i-while/)
- [40 задач для начинающих Python-разработчиков: от основ к практике](/python/python-zadachi-dlya-nachinayushih/)
- [Функции в Python: от основ до продвинутого использования](/python/funkcii-v-python-sozdanie-i-ispolzovanie/)


