Python: задачи лайвкодинг¶
~3 минуты чтения
Предварительно: Подготовка к Python-интервью | Gotchas и трики
Лайвкодинг -- самый стрессовый этап Python-интервью: 45-60 минут, shared editor (CoderPad, HackerRank), интервьюер смотрит в реальном времени. По данным Glassdoor, декораторы спрашивают в 35% Python-собеседований (Squarespace, Яндекс, Minted), генераторы -- в 25% (Morgan Stanley, Airbnb, Hudson River Trading), async -- в 15% (Riot Games, FAANG). Ниже -- реальные задачи от 20+ компаний с шаблонами решений.
DECORATORS¶
Squarespace¶
# Напишите декоратор мемоизации для функции сложения
def memoize(func):
# TODO: реализовать кеширование результатов
pass
@memoize
def add(a: int, b: int) -> int:
return a + b
add(2, 3) # вычисляет
add(2, 3) # должен вернуть из кеша
Minted¶
# Throttle декоратор — функция выполняется только если прошло >100ms
def throttle(min_interval_ms: int = 100):
# TODO: реализовать ограничение частоты вызовов
pass
@throttle(min_interval_ms=100)
def print_message():
print("Hello!")
print_message() # выполнится
print_message() # пропустит (слишком быстро)
time.sleep(0.2)
print_message() # выполнится
Squarepoint Capital¶
# Декоратор с полной типизацией (CoderPad live coding)
from typing import Callable, TypeVar, ParamSpec
P = ParamSpec('P')
R = TypeVar('R')
def logged(func: Callable[P, R]) -> Callable[P, R]:
# TODO: реализовать логирование вызовов с сохранением типов
pass
Яндекс¶
# Параметризированный декоратор замера времени
def timing(unit: str = "seconds"):
# TODO: реализовать замер времени
# unit может быть "seconds" или "milliseconds"
pass
@timing(unit="milliseconds")
def slow_function():
time.sleep(1)
# Ожидаемый вывод: slow_function took 1000.50ms
Habr (Русские IT-компании)¶
# 1. Retry с exponential backoff
def retry(max_tries: int = 3, delay: float = 1, backoff: int = 2):
# TODO: повторять вызов при ошибке с увеличивающейся задержкой
pass
@retry(max_tries=3, delay=1, backoff=2)
def unstable_api():
if random.random() < 0.7:
raise ConnectionError()
return "OK"
# 2. Rate limiter
def rate_limit(calls: int, period: int):
# TODO: ограничить количество вызовов за период
pass
@rate_limit(calls=10, period=60) # макс 10 вызовов в минуту
def api_call():
pass
GENERATORS¶
Hudson River Trading¶
# "Build a Python generator" — CoderPad, 3 часа
# Конкретная задача не раскрыта, формат: online live coding
Morgan Stanley¶
# Fibonacci через generator
def fibonacci(n: int):
# TODO: yield первые n чисел Фибоначчи
pass
list(fibonacci(10)) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Airbnb¶
# Flatten вложенного списка любой глубины
def flatten(lst):
# TODO: рекурсивно yield все элементы
pass
list(flatten([1, [2, [3, 4]], 5])) # [1, 2, 3, 4, 5]
Stripe / Google / Amazon¶
# Обработка большого файла батчами (без загрузки в память)
def read_batches(filename: str, batch_size: int = 1000):
# TODO: yield батчи по batch_size строк
pass
for batch in read_batches("huge.txt", 1000):
process(batch)
COMPREHENSIONS¶
J.P. Morgan¶
# Генерация степеней: num^1, num^2, num^3 для чисел 1-4
powers = ... # TODO: list comprehension
# Ожидаемый результат: [1, 1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64]
Jump Trading¶
# Транспонирование матрицы через comprehension
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = ... # TODO: nested list comprehension
# Ожидаемый результат: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Goldman Sachs¶
# Flatten вложенного списка
nested = [[1, 2], [3, 4], [5]]
flat = ... # TODO: list comprehension
# Ожидаемый результат: [1, 2, 3, 4, 5]
# Dict из двух списков
keys, values = ['a', 'b', 'c'], [1, 2, 3]
d = ... # TODO: dict comprehension
# Ожидаемый результат: {'a': 1, 'b': 2, 'c': 3}
Bloomberg¶
# Группировка по ключу
data = [
{'name': 'Alice', 'dept': 'IT'},
{'name': 'Bob', 'dept': 'IT'},
{'name': 'Charlie', 'dept': 'HR'}
]
by_dept = ... # TODO: dict comprehension с группировкой
# Ожидаемый результат: {'IT': ['Alice', 'Bob'], 'HR': ['Charlie']}
Tinkoff¶
# Трансформация вложенных словарей (lowercase ключи)
params = {
'device1': {'Name': 'Sensor', 'Value': '123'},
'device2': {'Name': 'Motor', 'Value': '456'}
}
result = ... # TODO: nested dict comprehension
# Ожидаемый результат:
# {'device1': {'name': 'Sensor', 'value': '123'},
# 'device2': {'name': 'Motor', 'value': '456'}}
Яндекс¶
# Таблица умножения 10x10
table = ... # TODO: nested list comprehension
# Ожидаемый результат: [[1,2,3...10], [2,4,6...20], ...]
ASYNC¶
Riot Games¶
# Параллельные HTTP запросы без блокировки
async def fetch_all(urls: list[str]) -> list[str]:
# TODO: загрузить все URL параллельно через aiohttp
pass
async def fetch_one(session, url):
# TODO: загрузить один URL
pass
Типичная задача (FAANG)¶
# Producer-Consumer с asyncio.Queue
async def producer(queue: asyncio.Queue):
# TODO: генерировать элементы и класть в очередь
pass
async def consumer(queue: asyncio.Queue):
# TODO: читать из очереди и обрабатывать
pass
Типичная задача (FAANG)¶
# Retry с exponential backoff (async версия)
async def fetch_with_retry(url: str, max_retries: int = 5):
# TODO: повторять запрос с задержкой 1, 2, 4, 8, 16 сек
pass
Типичная задача (FAANG)¶
# Rate limiting через Semaphore
async def fetch_with_limit(urls: list[str], max_concurrent: int = 10):
# TODO: загрузить все URL, но не более max_concurrent одновременно
pass
BACKEND¶
Revolut¶
# Money Transfer API — атомарные транзакции
# POST /transfer
# Критично: race conditions, rollback при ошибке
class TransferService:
async def transfer(self, from_id: int, to_id: int, amount: Decimal):
# TODO: реализовать атомарный перевод
# - проверить баланс отправителя
# - заблокировать обе записи (SELECT FOR UPDATE)
# - выполнить дебет и кредит
# - откатить при ошибке
pass
VK¶
# Каталог товаров с пагинацией и кешированием
# GET /api/goods/byprice?count=20&offset=0
@app.get("/api/goods/byprice")
async def get_goods(count: int = 20, offset: int = 0):
# TODO: реализовать с Redis кешем
# - проверить кеш
# - если нет — запросить из БД
# - сохранить в кеш с TTL
pass
Яндекс¶
# Написать тесты к существующему коду (дают готовый код, 1 час)
@pytest.fixture
async def client():
# TODO: создать тестовый клиент
pass
async def test_create_user(client):
# TODO: тест создания пользователя
pass
async def test_create_user_duplicate(client):
# TODO: тест на дубликат (ожидаем 409)
pass
LRU Cache (Microsoft, Google, Amazon)¶
# O(1) get и put
class LRUCache:
def __init__(self, capacity: int):
# TODO: инициализация
pass
def get(self, key: int) -> int:
# TODO: вернуть значение, обновить "недавность"
pass
def put(self, key: int, value: int) -> None:
# TODO: добавить/обновить, удалить старейший если переполнение
pass
cache = LRUCache(2)
cache.put(1, 'a')
cache.put(2, 'b')
cache.get(1) # 'a' — теперь 1 most recently used
cache.put(3, 'c') # удаляет 2
cache.get(2) # -1 (не найден)
URL Shortener (System Design + Code)¶
# POST /shorten → короткая ссылка
# GET /{code} → редирект
class URLShortener:
def __init__(self):
# TODO: инициализация хранилища
pass
def shorten(self, url: str) -> str:
# TODO: сгенерировать короткий код (Base62)
pass
def resolve(self, code: str) -> str | None:
# TODO: вернуть оригинальный URL
pass
Pagination API (Junior/Middle)¶
# GET /tasks?limit=10&offset=0&sort=created_at&order=desc&status=active
@app.get("/tasks")
async def get_tasks(
limit: int = Query(10, le=100),
offset: int = Query(0, ge=0),
sort: str = Query("created_at"),
order: str = Query("desc"),
status: str | None = Query(None)
):
# TODO: реализовать фильтрацию, сортировку, пагинацию
# Вернуть: {"items": [...], "total": N, "limit": L, "offset": O}
pass
Компании¶
| Компания | Категория | Задача |
|---|---|---|
| Squarespace | Decorators | Memoize |
| Minted | Decorators | Throttle |
| Squarepoint Capital | Decorators | Typed decorator |
| Яндекс | Decorators | Timing с параметром |
| Morgan Stanley | Generators | Fibonacci |
| Airbnb | Generators | Flatten nested list |
| Stripe/Google/Amazon | Generators | Batch file processing |
| J.P. Morgan | Comprehensions | Powers generation |
| Jump Trading | Comprehensions | Matrix transpose |
| Goldman Sachs | Comprehensions | Flatten + dict |
| Bloomberg | Comprehensions | Group by key |
| Tinkoff | Comprehensions | Nested dict transform |
| Riot Games | Async | Parallel HTTP |
| Revolut | Backend | Money transfer |
| VK | Backend | Catalog + cache |
| Hudson River Trading | Generators | Build a generator |
| Microsoft/Google | Backend | LRU Cache |
| Revolut | Backend | Money Transfer API |
| VK | Backend | Catalog + cache |
| Яндекс | Backend | Pytest тесты |
| System Design | Backend | URL Shortener |
| Junior/Middle | Backend | Pagination API |
Типичные ошибки на лайвкодинге¶
Заблуждение: декоратор -- это просто обёртка print-ами
На интервью ожидают @functools.wraps(func) для сохранения __name__, __doc__. Без него debugger, help(), pickle -- все ломаются. Забыть wraps -- моментальный красный флаг для Senior-позиций.
Заблуждение: генератор и список -- одно и то же, только лениво
Генератор нельзя перебрать дважды, у него нет len(), [] и reversed(). Если интервьюер просит "обработать файл в 10GB батчами" и вы возвращаете list -- это провал. Генератор для 1M элементов -- O(1) по памяти вместо O(n).
Заблуждение: asyncio ускоряет любой код
async/await ускоряет только I/O-bound задачи (сеть, диск). Для CPU-bound (вычисления, ML inference) asyncio бесполезен -- нужен multiprocessing. На интервью часто спрашивают: "Когда async НЕ поможет?"
Вопросы на собеседовании¶
"Напишите декоратор мемоизации"
Слабый ответ: обёртка без
@wraps, без обработки unhashable аргументов, без ограничения размера кэша
Сильный ответ:
@wraps(func), dict как кэш с ключом (args, tuple(sorted(kwargs.items()))), упоминание @functools.lru_cache как стандартного решения
"Реализуйте LRU Cache с O(1) get/put"
Слабый ответ: dict + list (O(n) удаление из середины)
Сильный ответ:
OrderedDict с move_to_end() или dict + doubly-linked list. Упоминание что в Python 3.7+ dict сохраняет порядок, но не имеет move_to_end()
"Flatten вложенного списка произвольной глубины"
Слабый ответ: рекурсия без проверки типа, падает на строках (
"abc" -- iterable!)
Сильный ответ:
isinstance(item, Iterable) and not isinstance(item, (str, bytes)), или yield from для рекурсивного генератора
Related: - Python Language Features Interview (deep dives on decorators, generators, async) - Python Gotchas & Tricky Questions (edge cases to know) - Python Interview Sources (URL collection)
2025-12-23