Вопросы на собеседовании: Python-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Senior.
Смотреть пример резюме: Python-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
Я бы ограничил каждый колбэк или шаг корутины примерно 2 мс, а разбор на 12 мс вынес из event loop.
- Цикл выполняет готовые колбэки, продвигает задачи до приостановки на await, обрабатывает таймеры и опрашивает селектор, поэтому один шаг на 12 мс уже нарушает лимит лага 10 мс для всех сокетов.
- Я бы разбил парсинг на части с явными точками передачи управления, только если состояние дёшево обрабатывается по частям; иначе CPU-работа на чистом Python идёт в ProcessPoolExecutor или нативный парсер, а блокирующий I/O в asyncio.to_thread.
- Я бы включил loop.set_debug, установил loop.slow_callback_duration в 0,005 и запланировал монотонный heartbeat каждые 10 мс для измерения p95 и p99 лага цикла.
- Вынос должен быть ограниченным: отправка 10 000 задач парсинга лишь переносит очередь, поэтому я ограничу число активных задач и при достижении лимита отклоню сообщения или приостановлю чтение.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат превратить кооперативное планирование в числовой бюджет блокировки и выбрать правильный способ выноса работы.
Я бы использовал asyncio для сетевого этапа, отдельный пул потоков для блокирующего SDK и пул процессов для вычислений на чистом Python.
- При 1 000 элементах в секунду сетевое ожидание 40 мс требует около 40 конкурентных задач asyncio, поэтому я начну примерно с 64, а не создам поток на каждое соединение.
- SDK потребляет около 20 потокосекунд в секунду; ThreadPoolExecutor на 24-32 воркера даёт небольшой запас, если вызов в основном ждёт I/O и освобождает GIL.
- CPU-этап требует 8 ядросекунд в секунду, поэтому я начну с ProcessPoolExecutor примерно на 10 воркеров, оставив шесть ядер для event loop, потоков SDK, сериализации и ОС.
- Ограниченные очереди между тремя этапами показывают насыщение; если pickle данных занимает больше времени, чем вычисление за 8 мс, я объединю элементы в батчи или передам ссылки на общую память.
Зачем это спрашивают: Интервьюер проверяет, сопоставляет ли кандидат измеренное время ожидания и CPU с гибридной моделью конкурентности Python вместо одного подхода для всех этапов.
Пул из 32 потоков останется примерно на уровне одного ядра и 25 преобразований в секунду, поэтому цель в 200 операций он не выполнит.
- GIL позволяет только одному потоку выполнять байткод Python в одном интерпретаторе; дополнительные CPU-потоки добавляют переключения и расходы на блокировки, а не восьмикратный параллелизм.
- Восемь процессов имеют идеальный потолок 200 преобразований в секунду, потому что 8 делённое на 0,040 равно 200, но запаса на сериализацию, ОС и разброс задержек не остаётся.
- Я бы использовал ProcessPoolExecutor для крупных задач и либо выделил около 10 эффективных ядер, либо сократил время преобразования ниже 32 мс, чтобы держать загрузку 8-ядерного хоста около 80 процентов.
- Потоки станут подходящим вариантом, только если горячая работа перейдёт в NumPy или другое C-расширение, освобождающее GIL, что я проверю бенчмарком на 1, 8 и 32 потоках.
Зачем это спрашивают: Интервьюер проверяет количественное понимание GIL, включая разницу между теоретическим потолком процессов и устойчивой пропускной способностью.
Я бы выбрал free-threaded сборку только после подтверждения совместимости C-расширения и масштабирования от 8 до 32 потоков к цели в 1 200 запросов в секунду.
- Я бы импортировал расширение и проверил sys._is_gil_enabled; расширение без объявления Py_MOD_GIL_NOT_USED через слот Py_mod_gil может снова включить GIL в интерпретаторе.
- Матрица бенчмарков сравнит обычный и free-threaded CPython на 1, 8 и 32 потоках по пропускной способности, p99, RSS и цене одного потока, поскольку удаление GIL может обменять параллельное масштабирование на дополнительные расходы каждого потока.
- Я проверю разделяемые Python-кэши и глобальное состояние расширения на гонки, защищу составные изменения через threading.Lock и переведу C-код с надежды на GIL на поддерживаемые API критических секций.
- Если расширение небезопасно или масштабирование остановится раньше 1 200 запросов в секунду, обычный CPython с процессами и общей read-only памятью будет менее рискованным решением.
Зачем это спрашивают: Интервьюер проверяет, рассматривает ли кандидат free threading как измеряемое решение о рантайме и совместимости расширений, а не как автоматическое ускорение на многих ядрах.
Я бы поместил TaskGroup внутрь asyncio.timeout на 300 мс, чтобы ошибка шарда или дедлайн отменяли всю принадлежащую запросу соседнюю работу.
- Обычное исключение одного дочернего задания заставляет TaskGroup отменить остальные 11 задач, дождаться их очистки и затем выбросить ExceptionGroup, не оставляя отсоединённую работу.
- Каждая корутина шарда должна освобождать соединение в finally и повторно выбрасывать asyncio.CancelledError; проглоченная отмена может удерживать одно из четырёх соединений дольше жизни запроса.
- Я сохраню объекты задач из group.create_task и прочитаю результаты только после успешного выхода из контекста, чтобы частичный ответ не ушёл случайно.
- Если один шард явно необязателен, его дочерняя задача сама преобразует ожидаемую ошибку в типизированное запасное значение; перехват снаружи группы отменил бы здоровые задачи до применения этой политики.
Зачем это спрашивают: Интервьюер проверяет точную семантику структурной отмены, очистку ресурсов и границу между обязательной и необязательной дочерней работой.
Консьюмеры обрабатывают 4 000 сообщений в секунду, поэтому я ограничу очередь примерно 8 000 элементов под двухсекундный бюджет ожидания, а не стану поглощать весь всплеск.
- Безграничная очередь растёт на 1 000 сообщений в секунду и достигает 60 000 элементов, то есть минимум 120 МБ данных плюс расходы объектов Python, тогда как maxsize=8000 ограничивает полезные данные примерно 16 МБ.
- Продюсеры должны ожидать queue.put, а внешний источник должен получить быстрый отказ, если asyncio.wait_for не может поставить сообщение за заданный срок, например 100 мс.
- Каждый консьюмер вызывает task_done в finally, а при остановке сервис ожидает queue.join перед отменой 20 консьюмеров, чтобы принятые сообщения имели явную семантику завершения.
- Я опубликую глубину очереди, возраст старейшего элемента, время ожидания put и число отказов, потому что одна глубина не отличает крупный дешёвый всплеск от работы, уже пропустившей дедлайн.
Зачем это спрашивают: Интервьюер проверяет, выводит ли кандидат предел очереди из скорости обслуживания и бюджета ожидания и связывает ли его с явным поведением при перегрузке.
Я бы выбрал spawn ради корректности, а трёхсекундный лимит выдержал бы отдельным отображением кэша вместо fork многопоточного родителя.
- Fork копирует только вызывающий поток, но наследует блокировки, сокеты и файловые дескрипторы остальных 11 потоков, поэтому дочерний процесс может навсегда ждать лок, владелец которого исчез.
- multiprocessing.get_context со spawn запускает чистый интерпретатор; я использую защиту main и initializer для явного создания клиентов, случайного состояния и логирования каждого дочернего процесса.
- Передача 300 МБ аргументом пула сериализовала бы данные восемь раз, поэтому я открою кэш через read-only mmap или сегмент shared_memory, к которому подключится каждый созданный через spawn воркер.
- Fork допустим, только если пул создаётся из намеренно однопоточного загрузчика до запуска фоновых потоков и сетевых клиентов, но это более узкий случай, чем допускает сценарий.
Зачем это спрашивают: Интервьюер проверяет, может ли кандидат отказаться от небезопасного наследования fork и при этом конкретно решить проблемы старта spawn и передачи данных.
Я бы оставил одно неизменяемое хранилище на 12 ГБ и отобразил его во все 16 процессов вместо создания до 192 ГБ частных копий.
- Версионированный файл np.memmap даёт каждому созданному через spawn воркеру представление ndarray поверх страничного кэша ОС; multiprocessing.shared_memory с np.ndarray(buffer=shm.buf) подходит, если таблица не должна храниться в файле.
- В Linux предзагрузка до fork тоже использует copy-on-write, но родитель должен оставаться однопоточным, а даже случайные записи могут загрязнить страницы, пока память не приблизится к 12 ГБ на процесс.
- Для ежечасного обновления я создам новую неизменяемую версию, атомарно опубликую её имя, дам воркерам переключить отображение между запросами и удалю старое только после освобождения всеми пользователями.
- multiprocessing.Manager и Queue не подходят для случайных обращений такого размера, потому что каждый доступ проходит через прокси или сериализацию; изменяемые дельты лучше хранить отдельно в небольшом хранилище.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат сохранить одну физическую копию данных с учётом метода запуска процессов, обновлений и случайных затрат copy-on-write.
Я бы вынес этап в ограниченный пул процессов, но также добавил CPU, поскольку нагрузка уже требует 7,5 из восьми ядер без учёта расходов.
- asyncio.to_thread не подходит для этой работы на чистом Python под GIL; корутина запроса должна ожидать loop.run_in_executor с ProcessPoolExecutor.
- Восемь идеальных воркеров выполнят лишь 320 задач в секунду по 25 мс, поэтому при 300 запросах остаётся около 6 процентов запаса, чего недостаточно для стабильного p99 в 200 мс.
- Я бы целился примерно в 70 процентов CPU, используя 12 ядер и 10 процессов, либо оптимизировал этап примерно до 18 мс, сохраняя мощность для event loop и сериализации.
- Семафор ограничит число отправленных задач примерно размером пула, admission timeout в 50 мс отклонит избыток, а крупные тела запросов будут уменьшены до пересечения границы pickle.
Зачем это спрашивают: Интервьюер проверяет правильную передачу работы из async в процессы и понимание того, что сам вынос не создаёт недостающую CPU-мощность.
Я бы использовал отдельный ThreadPoolExecutor на 50 воркеров с таким же ограничителем конкурентности, признавая, что лимит внешнего сервиса почти не оставляет запаса пропускной способности.
- По закону Литтла нужно 600 умножить на 0,080, то есть 48 одновременных вызовов, а 50 потоков дают теоретический потолок 625 вызовов в секунду, лишь примерно на 4 процента выше нагрузки.
- Корутина должна захватить asyncio.Semaphore до loop.run_in_executor с таймаутом около 100 мс, чтобы время SDK вместе с очередью ещё укладывалось в бюджет эндпоинта 250 мс.
- Отдельный executor не даст 50 блокирующим вызовам SDK вытеснить DNS, файловую работу и другие задачи общего пула, а метрики должны покрывать активные потоки, ожидание семафора, задержку SDK и отказы.
- Решение предполагает, что SDK ждёт I/O и освобождает GIL; если профиль показывает вычисления на Python, потоки не масштабируются, а если 600 вызовов обязательны, лимит внешнего сервиса придётся поднять или часть запросов отклонять.
Зачем это спрашивают: Интервьюер проверяет количественный расчёт пула, изоляцию от общего executor, ограниченный допуск и понимание слишком узкого запаса ёмкости.
Я рассчитываю ASGI-воркеры по нагрузочному тесту одного воркера, а число реплик выбираю так, чтобы потеря одного пода не нарушала целевую задержку.
- Если один Uvicorn-воркер выдерживает 600 RPS при p99 150 мс, я начинаю с 6 воркеров на под и 4 подов: 24 event loop дают номинальные 14 400 RPS, а 3 оставшихся пода всё ещё дают 10 800 RPS.
- Каждый воркер владеет одним event loop и мультиплексирует в нём I/O-запросы; ASGI не распараллеливает валидацию JSON и другую CPU-работу, поэтому 6 воркеров оставляют 2 ядра для ОС, сайдкаров и пиков.
- FastAPI lifespan создаёт по одному пулу asyncpg и одному httpx.AsyncClient на воркер, поэтому каждый лимит пула умножается на 24 и должен укладываться в бюджеты базы и внешних сервисов.
- Я ограничиваю число активных обработчиков 200 на воркер, задаю конечный accept backlog, возвращаю 503 при исчерпании допуска и масштабируюсь по CPU вместе с задержкой event loop, а не накапливаю безграничные задачи до роста p99.
Зачем это спрашивают: Интервьюер оценивает количественный расчёт ASGI-мощности, изоляцию процессов, умножение ресурсов и явный backpressure вместо правила один воркер на ядро без измерений.
Я использую async-view для конкурентных HTTP-вызовов и ровно один раз перехожу в синхронный Django для транзакционного блока ORM.
- Эти 2 HTTP-вызова выполняются вместе через один переиспользуемый httpx.AsyncClient, сокращая общее время примерно с 240 до 120 мс и не занимая Django-потоки во время ожидания сокетов.
- Полную ORM-транзакцию длительностью 20 мс я помещаю за один вызов sync_to_async с thread-sensitive выполнением вместо чередования sync и async для отдельных запросов.
- При 500 RPS на реплику шаг базы требует около 10 конкурентных слотов по закону Литтла, поэтому я начинаю с 16 ограниченных sync-потоков и не более 16 соединений с базой на реплику.
- Два исходящих вызова требуют около 120 конкурентных слотов на реплику, поэтому семафор на 160 слотов и ограниченная очередь с дедлайнами создают backpressure до насыщения HTTP-пула.
Зачем это спрашивают: Сильный ответ сводит дорогие переходы к минимуму, оставляет транзакционный Django-код синхронным и выводит лимиты потоков и соединений из измеренного времени удержания.
Я выделяю приложению 25 секунд на завершение внутри 30-секундного дедлайна пода и даю каждой принятой задаче явного владельца и путь отмены.
- По SIGTERM процесс немедленно проваливает readiness и перестаёт принимать новые HTTP-запросы и upgrade, а Uvicorn получает до 15 секунд на завершение уже принятых запросов.
- Фоновая работа живёт в TaskGroup или реестре отслеживаемых задач; долговечные задачи перестают забираться из очереди, активные получают 8 секунд на checkpoint, а одноразовые отменяются в порядке зависимостей.
- Каждая корутина ловит CancelledError только для освобождения ресурса и затем пробрасывает его дальше, а блоки finally до 25-й секунды закрывают клиенты asyncpg, httpx, Kafka и телеметрии.
- На 25-й секунде я отменяю оставшиеся задачи и выхожу, оставляя Kubernetes 5 секунд запаса; работа, не допускающая отмену, должна находиться в долговечной очереди, а не в неотслеживаемом вызове create_task.
Зачем это спрашивают: Интервьюер проверяет, образуют ли readiness, завершение запросов, владение задачами, отмена и очистка ресурсов единую временную схему внутри дедлайна Kubernetes.
Я делю ёмкость зависимостей между всеми 80 процессами-воркерами до выбора локальных размеров пулов, потому что настройки каждого процесса умножаются на весь парк.
- Я резервирую 100 соединений PostgreSQL для миграций, администрирования и других сервисов, оставляя API 400, поэтому каждый пул asyncpg начинает с min_size 1 и max_size 5.
- В среднем запрос удерживает PostgreSQL 15 мс, что при 2 000 RPS даёт всего 30 одновременных пользователей базы во всём парке, поэтому 400 соединений являются потолком, а не целью пропускной способности.
- HTTP-вызов в среднем длится 80 мс, что даёт 160 одновременных вызовов во всём парке; max_connections 8 на каждый httpx-клиент допускает пик в 640 вызовов и остаётся ниже внешнего лимита 1 000.
- Я задаю короткие дедлайны получения соединения, публикую время ожидания пула и никогда не удерживаю asyncpg-соединение во время HTTP await, потому что так задержка внешнего сервиса напрямую истощает пул базы.
Зачем это спрашивают: Интервьюер ожидает расчёт пулов на весь парк, применение закона Литтла и понимание того, что await в неправильной области удерживает дефицитное соединение.
Я передаю один абсолютный дедлайн 800 мс и заставляю каждую зависимость расходовать документированную долю оставшегося времени вместо запуска собственного независимого таймера.
- Я выделяю 80 мс аутентификации, 180 мс складу, 220 мс ценам, 120 мс приложению и базе, 100 мс сети и сериализации, а ещё 100 мс оставляю резервом для хвостовой задержки.
- Только идемпотентный GET цен получает 1 ретрай внутри своих 220 мс: 90 мс на попытку 1, до 20 мс джиттера и backoff, затем 90 мс на попытку 2.
- Обёртка над httpx читает оставшийся дедлайн из context variable и задаёт connect, pool, read и total timeout как меньшее из этого остатка и лимита зависимости.
- Общий token bucket ограничивает ретраи 5 процентами исходного трафика, а для неидемпотентной записи автоматический ретрай разрешается только после появления ключа идемпотентности.
Зачем это спрашивают: Вопрос проверяет отношение к таймаутам и ретраям как к конечным сквозным бюджетам с конкретным контролем усиления, а не как к несвязанным настройкам клиентов.
Я обеспечиваю общий token bucket на 600 RPS в Redis и выдаю подам небольшие пакеты токенов, чтобы автомасштабирование не умножало лимит.
- Один Lua-скрипт пополняет глобальный bucket по серверному времени Redis, ограничивает его 1 200 токенами и атомарно выдаёт поду не более 10 токенов на 100 мс.
- Интерактивный трафик получает 80 процентов новых токенов, batch получает 20 процентов, а любой класс может занять неиспользованную ёмкость, чтобы резервирование не теряло пропускную способность.
- При p95 внешнего сервиса 200 мс всему парку нужно около 120 одновременных вызовов на 600 RPS, поэтому каждый под начинает с семафора на 5 слотов и очереди, отбрасывающей элемент, который не успеет стартовать до дедлайна 500 мс.
- Ответ 429 с Retry-After замораживает новые выдачи на указанный интервал; при недоступности Redis поды расходуют только неистёкшие токены, а затем закрывают доступ, не нарушая контракт стороннего API.
Зачем это спрашивают: Интервьюер оценивает атомарную координацию парка, ограниченную локальную конкурентность, backpressure по дедлайнам и цену доступности за соблюдение внешней квоты.
Я сохраняю порядок по ключу через ограниченные локальные очереди партиции и коммичу только наибольший непрерывный оффсет, для которого вся работа завершена.
- Я запускаю 24 процесса-консьюмера по 4 партиции; каждая партиция хеширует ключи в 8 последовательных asyncio-очередей, что даёт 32 задачи-обработчика на процесс и около 400 сообщений в секунду мощности на партицию.
- Битовая карта завершений отслеживает результаты не по порядку, но коммиттер каждые 500 мс продвигается только по непрерывному префиксу, поэтому медленный ключ не подтверждает более позднюю незавершённую запись.
- Когда очередь партиции достигает 1 000 записей, я ставлю эту партицию на паузу и возобновляю ниже 500, а poll loop продолжает обслуживать хартбиты, чтобы давление обработки не вызывало ребаланс.
- При отзыве партиции я прекращаю выдачу, даю очередям 10 секунд на завершение, коммичу непрерывный префикс, а незавершённые записи после переназначения возвращаются в идемпотентные upsert-операции базы.
Зачем это спрашивают: Сильный ответ связывает назначение партиций, конкурентность задач, порядок, непрерывные коммиты, polling и backpressure в единую схему доставки как минимум один раз.
Я превращаю 6-часовой запуск в долговечно арендованные идемпотентные части, максимальное время которых остаётся ниже 2-минутного бюджета повтора.
- При требуемых 13 900 строках в секунду я начинаю с диапазонов первичного ключа по 500 000 строк, занимающих около 36 секунд, и получаю примерно 600 независимо перезапускаемых частей.
- Таблица job_chunks хранит диапазон, снимок входа, статус, номер попытки и checksum результата; воркеры забирают строки через SKIP LOCKED с арендой на 5 минут и хартбитом каждые 30 секунд.
- Каждая часть пишет через идемпотентный upsert и отмечает себя завершённой в той же транзакции базы, поэтому перезапуск может повторить вычисление, но не дублирует видимый результат.
- В начале задачи я фиксирую high-water mark и снижаю конкурентность воркеров, когда p95 базы превышает 100 мс, меняя скорость завершения на контролируемую нагрузку production-трафика.
Зачем это спрашивают: Интервьюер проверяет долговечный прогресс, стабильное разделение, идемпотентную публикацию, ограниченный повтор и троттлинг вместо одного длинного курсора и оффсета в памяти.
Я распределяю 50 000 сокетов по 10 подам с лимитом 5 000 соединений на каждом и явно ограничиваю каждый буфер соединения.
- Базовый бюджет 64 КиБ на соединение занимает около 320 МиБ на под; каждый сокет получает очередь отправки на 8 сообщений, добавляющую не более 16 КиБ, после чего сервер закрывает медленного клиента с кодом 1013.
- ASGI connection scope управляет одним reader и одним writer внутри TaskGroup, явно отменяя соседнюю задачу при завершении любой стороны, чтобы освободить подписки, память очереди и presence-состояние.
- Redis Pub/Sub достаточно для эфемерного fan-out, а возобновляемая доставка использует Kafka или Redis Streams с курсором на 60 секунд; локальный реестр пода не является единственным источником маршрутизации.
- Хартбиты идут каждые 30 секунд, а останавливаемый под отклоняет новые upgrade, даёт клиентам 20 секунд на переподключение в другом месте и затем закрывает оставшиеся сокеты с кодом 1012.
Зачем это спрашивают: Интервьюер ищет расчёт памяти на сокет, жизненный цикл ASGI-задач, backpressure для медленных клиентов, межподовый fan-out и переподключение, безопасное для деплоя.
Я помещаю поведение протокола в независимое от транспорта ядро и оставляю 2 тонкие I/O-оболочки вместо запуска event loop за синхронным API.
- Чистые построители запросов, парсеры ответов, состояние пагинации, аутентификация и retry state machine используются совместно; ядро возвращает следующее действие, не вызывая сокет или функцию сна.
- Sync-оболочка владеет httpx.Client и использует time.sleep, а async-оболочка владеет httpx.AsyncClient и использует anyio.sleep с отменой; обе предоставляют явные методы close и context manager.
- Методы 120 эндпоинтов генерируются из одной схемы в отдельные типизированные фасады, что убирает ручное дублирование и сохраняет нативные sync и async сигнатуры.
- Я прогоняю одинаковые 300 контрактных сценариев на обоих фасадах и добавляю отдельные тесты на потокобезопасность и async-отмену, принимая небольшое дублирование транспортного цикла ради отказа от asyncio.run и скрытых рабочих потоков.
Зачем это спрашивают: Интервьюер проверяет практичное sans-I/O ядро, нативную семантику жизненного цикла обоих API и честную границу между общей логикой протокола и неизбежно разной I/O-оркестрацией.
Закрытые вопросы
- 21
Python API обслуживает 2 000 запросов в секунду при загрузке CPU 75 процентов, а p99 составляет 180 мс при целевом значении 120 мс. Как вы профилируете его с помощью py-spy под реальной нагрузкой?
latencyprofilingapi - 22
Детерминированная пакетная задача на Python обрабатывает 10 млн записей за 22 минуты, а должна укладываться в 12 минут. Как вы примените cProfile для поиска и проверки оптимизации?
optimizationprofilingconcurrency - 23
Числовое преобразование 50 млн значений float64 занимает 42 секунды в цикле Python, но контейнер ограничен 3 ГБ памяти. Как векторизовать его, не потеряв выигрыш на временных массивах NumPy?
pandasnumpypython - 24
Парсер на чистом Python обрабатывает 5 млн записей за 70 секунд, 80 процентов сэмплов приходится на один цикл, а целевое время равно 15 секундам. Как вы выберете между Cython, расширением CPython на C и Rust с PyO3?
nativepython - 25
Python API отдаёт 20 000 ответов в секунду с payload размером 4 КБ, а сериализация потребляет 30 процентов CPU. Как вы выберете между stdlib json, orjson, msgspec и pickle?
serializationapipython - 26
Двенадцать подов Gunicorn по восемь воркеров обслуживают 5 000 запросов чтения в секунду для объектов по 20 КБ, вычисляемых за 40 мс и допускающих устаревание не более 5 секунд. Вы выберете кэш процесса или Redis?
rediscachingconcurrency - 27
Эндпоинт ранжирует 100 000 товаров при 300 запросах в секунду, занимает 900 мс и должен достичь 200 мс. В каком порядке вы будете оптимизировать горячий путь?
optimizationendpoints - 28
Python CLI тратит 1,4 секунды на показ справки, а serverless-функция из того же пакета получает холодный старт 1,9 секунды. Как вы сократите время запуска из-за импортов?
python - 29
Python-шлюз разбирает поток 2 ГБ на фреймы по 64 КБ со скоростью 450 МБ/с, а профиль показывает четыре копирования байтов на фрейм. Как применить memoryview и buffer protocol, чтобы достичь 1 ГБ/с?
pythontypinggateway - 30
Эндпоинт SQLAlchemy возвращает 500 заказов в среднем с тремя позициями каждый, выполняет 501 SQL-запрос и занимает 1,6 секунды при цели 200 мс. Как убрать N+1, не создав взрыв числа строк?
sqln+1orm - 31
CSV-файл размером 5 ГБ раздувается до 40 ГБ в Python-задаче с лимитом памяти 8 ГБ. Как вы перепроектируете загрузку?
memorypython - 32
Долгоживущий Python-воркер прибавляет около 300 МБ RSS каждый час при стабильной нагрузке. Как определить, накапливаются ли живые объекты?
concurrencypython - 33
В памяти нужно держать 8 миллионов небольших объектов координат. Когда вы примените __slots__, а когда выберете другое представление?
memoryslots - 34
Задача должна преобразовать 20 миллионов строк базы данных в контейнере с 512 МБ памяти. Как вы организуете генераторы и потоковую обработку порциями?
databasecontainersstreaming - 35
Обработчик графа создаёт 2 миллиона узлов со ссылками на родителей и потомков, а память не освобождается быстро после каждой порции в 6 ГБ. Как вы поступите с циклами, слабыми ссылками и финализацией?
batchmemoryconcurrency - 36
Как перевести 500 000 строк нетипизированного Python-кода с 18 000 начальными ошибками на строгую проверку mypy, не останавливая разработку функций?
pythontyping - 37
Сервис загружает 120 плагинов, включая сторонние реализации, которые нельзя изменить. Вы зададите контракт плагина через Protocol или ABC?
dependenciestyping - 38
У вас 80 эндпоинтов с декораторами и репозитории для 12 типов моделей. Как TypeVar и ParamSpec сохранят точность этих абстракций?
ooptypingendpoints - 39
Python-сервис принимает 20 000 JSON-событий в секунду и имеет независимое от фреймворков доменное ядро. Где вы примените Pydantic, dataclass и TypedDict?
pythondataclassestyping - 40
Нетипизированный платёжный SDK напрямую импортируется в 60 модулях и распространяет Any по коду со строгим mypy. Как вы его изолируете?
spreadtyping - 41
Внутреннему SDK, который используют 18 сервисов, нужен единый API fetch_invoice с 2 режимами: raw возвращает bytes, а parsed возвращает Invoice. Как типизировать такой публичный API, чтобы вызывающему коду не требовались cast?
api - 42
Сервис со strict mypy получает 25 000 партнёрских JSON-сообщений в минуту, читает строки от 3 версий схемы и вызывает полностью типизированные внутренние функции. Где вы всё равно проводите рантайм-валидацию?
schemavalidationtyping - 43
У модели checkout есть 4 строковых статуса и 7 полей Optional, поэтому код позволяет создать захваченный платёж без ссылки провайдера или отправить неоплаченный заказ. Как вы перепроектируете типы?
- 44
У FastAPI-сервиса 9 внешних зависимостей и 120 модульных тестов, которые теперь в основном патчат глобальные объекты модулей. Как вы измените связывание без DI-контейнера?
unitcontainersdependencies - 45
Батч-воркер может открыть от 1 до 24 входных потоков и 8 временных выходных файлов, а отмена должна закрыть каждый полученный ресурс за 2 секунды. Какую идиому жизненного цикла Python вы примените?
batchresiliencepython - 46
Checkout поддерживает Stripe, Adyen и один локальный банк с 3 разными форматами запросов, а домену нужны authorize, capture и refund. Как применить Strategy и Adapter, не строя фреймворк?
- 47
В монорепозитории находятся 12 независимо развёртываемых Python-сервисов и 5 общих пакетов, а разрешение зависимостей сейчас даёт разные окружения на ноутбуках и в CI. Как вы устроите pyproject-файлы и блокировку через uv?
deploymentmonorepodependencies - 48
Внутренняя библиотека версии 1.7 импортируется 15 сервисами, а метод должен начать возвращать Receipt вместо None. Какую последовательность SemVer и депрекации вы примените в следующие 90 дней?
- 49
Python-пакету нужны чистое ядро, 3 опциональные возможности postgres, s3 и fast, а также поддержка CPython 3.11-3.13 на 5 сочетаниях ОС и архитектуры. Как вы его упакуете и протестируете?
postgresarchitecturepython - 50
Восемь разработчиков, 3 задания CI и 6 production-образов сейчас разрешают разные зависимости на Python 3.11 и 3.12. Как сделать виртуальные окружения и ограничения интерпретатора воспроизводимыми?
dependenciesvenvpython - 51
RSS пода FastAPI растет с 420 МБ до 1,50 ГБ за 5 часов при стабильном трафике, tracemalloc показывает рост на 1,03 ГБ, а objgraph находит 180 000 удерживаемых объектов Response. Что вы делаете во время инцидента?
incidentsframeworksmemory - 52
Воркер Pillow обрабатывает 10 000 миниатюр/час, и RSS растет с 380 МБ до 1,82 ГБ за 6 часов, но tracemalloc добавляет лишь 12 МБ, а счетчики objgraph остаются в пределах 1%. Как локализовать и исправить проблему?
memory - 53
Восемь параллельных задач NumPy поднимают RSS воркера с 620 МБ до 3,6 ГБ; после завершения tracemalloc падает с 2,9 ГБ до 410 МБ и objgraph возвращается в пределы 2%, но RSS остается 3,2 ГБ. Это утечка и что нужно изменить?
batchnumpymemory - 54
После добавления JSON-канонизатора на чистом Python сервис с 8 vCPU падает с 1800 до 410 запросов/с, p99 растет с 90 до 760 мс, а процесс с 32 потоками использует лишь 115% CPU. Как вы реагируете?
concurrencypython - 55
Fraud endpoint начинает получать payload по 200 КБ, CPU растет с 35% до 96%, пропускная способность падает с 720 до 190 запросов/с, а py-spy показывает 64% сэмплов в проверке дубликатов по вложенному списку. Каково production-исправление?
throughputprofilingendpoints - 56
Asyncio API при 450 запросах/с внезапно показывает задержку event loop 1,8 с, 620 готовых к выполнению задач, CPU 18% и p99 2,4 с после релиза с проверкой метаданных S3. Как восстановить сервис?
asyncapiaws - 57
Websocket-сервис остается здоровым при CPU 12%, но перестает доставлять сообщения: 214 задач ожидают более 60 секунд, а dumps задач делятся между lock_a.acquire и lock_b.acquire после релиза reconnect. Как решить инцидент?
deploymentwebsockets - 58
У asyncio-воркера уведомлений число незавершенных задач растет на 900/час, а RSS на 95 МБ/час; через 8 часов 7400 задач ждут внутри HTTP-клиента, хотя объем завершенных работ не меняется. Что вы измените?
asynchttp - 59
После изменения response model p99 endpoint FastAPI растет со 170 до 930 мс при 600 запросах/с, CPU повышается с 48% до 84%, а spans базы данных остаются короче 20 мс. Как применить живое профилирование и исправить проблему?
databaseendpointsprofiling - 60
Новый фильтр поиска поднимает p99 endpoint с 240 мс до 4,8 с, медиана остается 85 мс, а средний CPU равен 42%; только 1,3% запросов содержат описания длиннее 30 КБ. Как диагностировать и сдержать проблему в production?
endpoints - 61
В сервисе на Python 3.11 напрямую закреплен starlette==0.36.3, а FastAPI 0.115.0 требует Starlette >=0.37.2,<0.42.0. Резолвер отклоняет сборку, но исправление безопасности нужно выпустить на 18 production-подов за 4 часа. Что делать?
frameworkspython - 62
Релиз 2026.07.12 пересобрал сервис на Python 3.11.9 после обновления lock-файла, которое изменило 47 пакетов, включая Pydantic с 2.8.2 до 2.10.4, и доля ошибок валидации выросла с 0,2% до 6,4% на 30 инстансах. Как реагировать?
pythonvalidation - 63
После обновления HTTPX с 0.27.2 до 0.28.1 задержка p95 в API на Python 3.12 выросла со 180 мс до 510 мс при 900 запросах в секунду, CPU остался на 42%, а число исходящих соединений утроилось со 120 до 365. Как выбрать исправление?
latencyapipython - 64
Версия 3.6.0 проходит 412 тестов из репозитория, но ее wheel на 24 воркерах вызывает ModuleNotFoundError для billing.rules, потому что каталог пакета не попал в артефакт; версия 3.5.9 работает. Что должен изменить ответственный за релиз?
deploymentpackagingmodules - 65
Wheel с C-расширением fastcodec 1.9.0 имеет тег manylinux_2_28_x86_64 и работает с glibc 2.35, но 60 хостов Amazon Linux 2 с glibc 2.26 отклоняют его и переходят к 14-минутной сборке из исходников. Как безопасно исправить ситуацию?
packaging - 66
Разработчики фиксируют зависимости на Python 3.12.4, где async-cache 5.1 выбирает speedups 2.0 с требованием Python >=3.12, но production работает на Python 3.11.9 в 40 контейнерах и установка падает. Как устранить расхождение?
containersdependenciesasync - 67
Свежая сборка 37 сервисов предупреждает, что telemetry-core 4.2.1 отозван из-за ошибки с потерей данных, но точное общее ограничение все равно требует эту версию; доступна 4.2.2, и резолвер работает после снятия ограничения. Что делать?
- 68
Внутренний wheel authcrypto 2.6.0 собрали на glibc 2.39 с OpenSSL 3.2, а затем развернули на 16 хостах Debian 11 с glibc 2.31 и OpenSSL 1.1.1; все воркеры падают из-за неопределенного SSL-символа на Python 3.11.8. Как правильно восстановить работу?
fundamentalspythondeployment - 69
Образ 2026.7.4 обновляет NumPy с 1.26.4 до 2.0.1 и вызывает падение 31% из 80 аналитических воркеров в скомпилированном плагине, а очередь растет с 2 000 до 19 000 за 12 минут. Какой откат и последующие действия нужны?
data-structuresnumpyrollback - 70
Один и тот же коммит резолвится в 126 пакетов на ноутбуке с Python 3.12.3, в 129 пакетов в CI с Python 3.12.5 и в 127 пакетов при развертывании, потому что 2 приватных индекса содержат разные сборки parserkit 7.4.0. Как получить воспроизводимое исправление?
reproducibilityindexesdeployment - 71
У Python API бюджет базы ограничен 40 соединениями, а 12 задач-потребителей обрабатывают до 20 одновременных запросов каждая. Во время всплеска трафика p95 ожидания соединения вырос с 8 мс до 4,5 с, 37 соединений остаются внутри транзакции, а CPU базы держится на 42%. Что произошло, как доказать причину и какие безопасное смягчение, постоянное исправление и критерий проверки вы выберете?
databasetransactionsconcurrency - 72
Внешний сервис начинает отвечать HTTP 503 в течение 30 секунд, но ваш Python-сервис увеличивает исходящий трафик с 800 до 4 800 запросов в секунду, потому что 16 экземпляров делают до 5 повторов с фиксированной задержкой 100 мс. Что произошло и какие доказательства, смягчение, постоянное исправление и числовой критерий проверки нужны?
resiliencehttppython - 73
Очередь Celery обрабатывает 50 000 платежных задач; после сбоя воркера 620 задач выполнились дважды, а 140 принятых задач не дали результата. Используются поздние подтверждения, тайм-аут видимости 60 секунд, а задача может выполняться 180 секунд. Как диагностировать и сдержать инцидент, затем предотвратить повторение и проверить исправление?
resiliencetask-queuesconcurrency - 74
Группа Python-потребителей Kafka из 8 участников выполняет 23 ребалансировки за 10 минут после роста обработки до 70 секунд; max.poll.interval.ms равен 60 000, смещения фиксируются до записи в базу, а аудит находит 310 пропущенных строк и 480 дублей. Что сломалось и как это доказать, смягчить, исправить и проверить?
concurrencypythondatabase - 75
Эндпоинт Django завершается по тайм-ауту через 30 секунд, 65 сессий базы ждут блокировки строк, а блокирующая транзакция длится 95 секунд и выполняет 90-секундный HTTP-вызов внутри transaction.atomic. CPU базы равен 35%. Какой ответ покажет уровень senior?
databasetransactionshttp - 76
Сервис asyncio обрывает по тайм-ауту 2 000 запросов в минуту через 3 секунды; число открытых сокетов растет с 300 до 12 000 за 20 минут, 1 700 задач остаются ожидающими, и процесс достигает лимита 16 384 файловых дескрипторов, потому что блок except BaseException подавляет отмену. Что произошло и что делать?
asyncconcurrencydescriptors - 77
Python-сервис запускает 8 процессов по 32 потока на хосте с 8 ядрами. При 1 600 запросах в секунду очередь на CPU достигает 70, число переключений контекста утраивается, CPU равен 98%, p99 задержки составляет 12 секунд, а пропускная способность падает до 900 запросов в секунду. Как обработать и проверить этот инцидент насыщения?
concurrencydata-structurespython - 78
Кэшированный объект с TTL 10 минут истекает в полдень; 400 Python-воркеров промахиваются по нему за 2 секунды, чтения базы растут с 200 до 18 000 в секунду, а p95 задержки достигает 9 секунд. Что произошло, как это доказать и какие смягчение, исправление и критерий проверки безопасны?
cachinglatencydatabase - 79
После выката версии схемы 4 на 20% продюсеров Python-потребители отклоняют 7 500 из 100 000 сообщений, потому что status изменился со строки на объект, а обязательное поле переименовали. Очередь ошибочных сообщений растет на 250 сообщений в минуту. Каков ваш план инцидента и критерий допуска релиза?
data-structurespythonschema - 80
При развертывании Kubernetes отправляет SIGTERM с периодом завершения 30 секунд 20 Python-воркерам. У каждого воркера по 40 задач в памяти, процесс прекращается через 30 секунд, и 260 из 800 задач исчезают, потому что подтверждение происходит до обработки. Как отреагировать и предотвратить следующую потерю при остановке?
kubernetesdeploymentconcurrency - 81
После обновления 24 воркеров с Python 3.10 до 3.11 0,7% сообщений падают с ValueError, потому что десятичные идентификаторы длиной 12 000 цифр преобразуются в int. Как найти и исправить причину, не ослабляя защиту всего сервиса?
python - 82
Сервис обрабатывает 25 000 платежных callback в минуту; mypy принимает cast из response.json() в PaymentEvent TypedDict, но 1,8% запросов падают с KeyError, когда провайдер присылает другую структуру. Что нужно изменить?
concurrencycallbackstyping - 83
Python-задача биллинга относит 340 из 2 миллионов платежей не к тому рабочему дню и расходится с реестром на одну копейку в 1 120 строках. Временные метки приходят с 4 разными смещениями, а суммы приходят десятичными строками. Как исправить и проверить корректность?
python - 84
Релиз заблокирован: 14 из 600 асинхронных тестов pytest падают только в полном наборе примерно раз в 20 прогонов, обычно с предупреждением о незавершенной задаче или тайм-аутом. Как расследовать это без добавления повторных запусков?
pytestasyncresilience - 85
Во время инцидента безопасности выясняется, что 6 экземпляров Python-сервиса вызывали pickle.loads для 12 400 клиентских файлов за 30 дней. Какие немедленные и постоянные меры вы примете?
incidentspython - 86
При 2 200 запросах в секунду p99 Python API растет со 180 мс до 1,4 с после того, как user_id и исходные пути увеличили метрики с 80 000 до 4,2 миллиона рядов, а очередь синхронных JSON-логов достигла 50 000 записей. Как восстановить наблюдаемость без блокировки запросов?
observabilitymonitoringdata-structures - 87
Канарейка нового Python-образа на 5% трафика поднимает p99 с 220 до 680 мс и задержку цикла событий с 12 до 190 мс при тех же 900 запросах в секунду, но ошибки остаются на уровне 0,1%. Что делать до продолжения развертывания?
deployment-strategiespython - 88
После релиза ошибки оформления заказа растут с 0,2% до 14% на 36 Python-подах в течение 7 минут, и инженер предлагает исправить одну проверку None прямо в работающем контейнере вместо отката. Как выбрать между откатом и хотфиксом?
containersrollbackpython - 89
Миграция делает customer.timezone обязательным в таблице на 80 миллионов строк, пока вместе работают 24 старых и 24 новых Python-воркера, причем старые воркеры не читают и не записывают это поле. Как изменить миграцию и развертывание рантайма?
fundamentalspythonmigrations - 90
CPU в production достигает 100%, а очередь запросов растет с 300 до 18 000 за 10 минут на 40 Python-воркерах, но перезапуск всех процессов уничтожит свидетельства и может усилить сбой. Как безопасно отлаживать живую систему?
data-structurespythonsystem-design - 91
Python-воркер за 6 часов увеличивает RSS на 1,2 ГБ, и middle-разработчик исправляет это вызовом gc.collect() каждые 30 секунд, хотя безлимитный кеш результатов уже хранит около 900 000 записей. Что вы попросите его сделать дальше и как проверите исправление, не забирая у него расследование?
cachingpython - 92
После изменения asyncio-эндпоинта p95 растет с 80 мс до 1900 мс: обработчик вызывает time.sleep(0.2) и делает 3 вызова requests.get примерно по 400 мс каждый. Как вы проведете автора через исправление и проверите, что цикл событий больше не блокируется?
asyncevent-loopendpoints - 93
Middle-разработчик построил слой валидации на 3 метаклассах, генерируемых дескрипторах и динамическом добавлении методов; добавление 1 поля теперь занимает около 40 минут, а типизаторы почти не показывают полезных сигнатур. Как вы оспорите дизайн, сохраните ответственность автора и проверите более простую замену?
injectionvalidationdescriptors - 94
Middle-разработчик открывает PR на 2400 строк и 18 файлов для изменения сверки платежей со сроком через 2 дня и говорит, что тесты не позволят уложиться. Что вы сделаете и как проверите поставку, не забирая PR себе?
estimationreacttesting - 95
Разработчик сообщает об ускорении парсера на 35% по результатам 3 прогонов примерно по 200 мс без прогрева, с включенным CPU turbo и фикстурой 10 КБ, хотя продакшен-входы близки к 10 МБ. Как вы исправите бенчмарк и дадите ему подтвердить вывод?
validationfixtures - 96
При миграции 12 000 строк пакета на строгую типизацию middle-разработчик добавляет 600 аннотаций Any и 45 подавлений type: ignore, а затем создает 2 циклических импорта, импортируя классы только ради аннотаций. Что вы попросите изменить и как проверите прогресс, не забирая миграцию себе?
migrations - 97
Обновление зависимости cryptography с 41 до 44 закрывает уязвимость CVSS 9.1, но ломает внутреннюю обертку и 27 тестов; один разработчик требует немедленного обновления, другой хочет закрепить версию 41 на 6 месяцев. Как вы разрешите технический спор, сохраните ответственность и проверите выбранный путь за 48 часов?
ownershipdependenciestesting - 98
После изменения сериализатора, развернутого middle-разработчиком, доля ошибок API растет с 0,2% до 18% на 11 минут, а разработчик говорит, что reviewer одобрил изменение. Что вы сделаете во время и после инцидента, чтобы он сохранил ответственность, сервис восстановился, а исправление было проверено?
incidentsownershipapi - 99
На ревью PR вы просите middle-разработчика добавить asyncio.Lock вокруг обновления словаря из 2 операций, но он указывает, что код работает в 1 потоке цикла событий и между чтением и записью нет await. Сервис обслуживает 10 000 параллельных корутин. Как вы исправите замечание, сохраните его ответственность и проверите утверждение о конкурентности?
asyncconcurrencyownership - 100
Middle-разработчик оценивает в 8 дней Python-конвейер импорта 1 000 000 строк с безопасными повторами, прогрессом и возобновлением, но бизнес-срок составляет 3 дня. Как вы согласуете объем, сохраните за разработчиком ответственность за оценку и проверите реалистичную поставку?
estimationresiliencepython