---
name: python
description: Python 后端怎么面：GIL 与 asyncio、Web 框架、ORM、Celery。JD 点名 Python 读。
keywords: [python, django, fastapi, flask, asyncio, celery, gunicorn, uvicorn, sqlalchemy, pydantic, gil, python后端, python开发, 服务端开发, backend]
layer: detail
domains: [backend, ai-agent, ai-algorithm, ai-infra, algorithm]
---

## 面试官在意什么

Python 后端集中在 AI 应用与算法服务、数据平台、SaaS、内容与工具类产品，以及大量创业公司与外企。日常是用 Django/FastAPI/Flask 写 API、用 SQLAlchemy 或 Django ORM 访问数据库、用 Celery 或 asyncio 处理异步任务、跑在 Gunicorn/Uvicorn 后面、部署到容器。Python 面试有一个显著特点：语言太好上手，所以"会写 Python"不值钱，面试官真正在意三件事：一是并发模型是否理解透——GIL 到底限制了什么、asyncio 与线程与进程各解决什么问题、同步代码混进异步框架会怎样；二是对框架"魔法"的理解——Django ORM 的惰性求值与 N+1、FastAPI 的依赖注入与 Pydantic 校验、中间件与生命周期；三是有没有把 Python 服务真正跑稳过——worker 数怎么定、内存为什么涨、Celery 任务丢了怎么办、慢在哪里怎么测。

校招侧重语言与基础：装饰器、生成器、上下文管理器、GIL 与多线程、可变默认参数这类语言陷阱、能否用框架写一个带鉴权与分页的 CRUD 并解释每一步。社招侧重生产问题与设计：异步服务里的阻塞调用排查、Celery 的可靠性与幂等、ORM 性能优化、Python 服务的内存与部署模型、什么时候该把热点换成 Rust/Go 扩展或独立服务。AI 公司会额外关注模型推理服务的封装（批处理、流式响应、GPU 资源隔离）与 Python 类型系统的工程化使用。

怎么问才像这个方向的面试官：
- 架构与方法论（缓存一致性、消息队列语义、限流降级）交给 backend 包，本包专注 Python 运行时、框架机制与生产运维。
- 并发模型是必考：任何 Python 后端候选人都要被问到 GIL、线程/进程/协程的选择依据，并给一个具体场景验证是否真懂。
- 框架题必须落到"魔法失效"场景：ORM 的 N+1、依赖注入的资源泄漏、Celery 的 ack 语义，而不是"介绍一下框架特点"。
- 结合项目规模与公司类型：小团队项目追工程化（类型、测试、依赖管理）；AI 公司追模型服务封装；高流量项目追部署模型与内存治理。
- 2026 年 Python 后端面试的新变化：自由线程（无 GIL 构建）从实验走向可用后，"GIL 怎么绕"要能说清多进程、asyncio、子解释器与自由线程各适合什么；Python 是 Agent 与模型服务的默认语言，面试官会追异步框架里调模型的超时、并发限制与流式响应怎么写。

## 项目 / 实习怎么深挖

简历上出现下面这类经历时从哪里切、追什么。追到候选人能说出机制、数字的来源与一次真实的故障或取舍才算实；只有框架名与结论、说不出自己那一段的，记为危险信号。通用的追问方法见 project-deep-dive。

- 简历出现 FastAPI → 追 def 与 async def 怎么选、依赖注入里管了什么资源、Pydantic 版本与校验性能、部署用几个 worker
- 简历出现 Django → 追 N+1 怎么发现与解决、迁移在线上怎么跑、用了哪些 Django 自带能力而不是自己造、异步视图有没有用
- 简历出现 Celery / 任务队列 → 追 acks 策略、幂等怎么做、堆积过没有、队列怎么拆、beat 怎么防重复
- 简历出现 asyncio / aiohttp / httpx → 追阻塞调用怎么排查、并发上限怎么控、异常怎么收集、有没有 Task 丢失的坑
- 简历出现 SQLAlchemy → 追 Session 作用域、连接池与 worker 数的账、1.x 还是 2.0 风格、异步引擎的懒加载问题
- 简历出现"性能优化" → 追用 py-spy 还是 cProfile、热点是什么、换库还是改算法、前后数字
- 简历出现模型服务 / LLM API 封装 → 追流式与取消、批处理、显存与 worker 模型、超时怎么传递
- 简历出现 Gunicorn / Uvicorn / Docker 部署 → 追 worker 类型与数量依据、内存增长怎么处理、优雅重启怎么做

## 常见失守与危险信号

- GIL 与并发模型选择：认为 GIL 让 Python 完全不能并行；不知道 numpy/IO 调用会释放 GIL；把 asyncio 当成能加速 CPU 计算
- asyncio 原理与阻塞排查：async def 里直接调 requests；不知道 asyncio.create_task 需要持有引用；认为异步一定比同步快
- FastAPI 与 Pydantic：不知道 def handler 跑在线程池里；Pydantic v1 与 v2 的差别说不出；依赖注入只当参数传递用
- Django 生态与 ORM 深度：不知道 QuerySet 什么时候真正执行；for 循环里访问外键属性；迁移直接在线上跑大表加索引不看锁
- SQLAlchemy 与数据库访问：全局一个 Session 到处用；不知道 pool_pre_ping；异步 session 里访问关系属性报错不知道为什么
- Celery 与任务队列可靠性：不知道默认是 acks_early；任务参数传大对象；所有任务共用一个队列一个 worker 池
- 部署模型：Gunicorn / Uvicorn 与 worker：不知道 sync worker 一次只处理一个请求；fork 前打开了数据库连接；容器里不知道内存限制怎么和 worker 数匹配
- 性能定位与优化：只会加 print 计时；没用过 py-spy；优化不做 benchmark
- 内存管理与泄漏：认为有 GC 就不会泄漏；不知道 lru_cache 无界；不知道 C 扩展的内存不在 tracemalloc 里
- 语言特性与常见陷阱：只会背"装饰器是语法糖"；不知道 functools.wraps；类型标注写了但从不跑检查器
- 测试与项目工程化：没有锁文件；测试直接连生产数据库；不知道 fixture 的作用域
- AI / 模型服务封装（可选，AI 公司常问）：每个 worker 各加载一份模型；流式用轮询；不知道客户端断开怎么感知

## 常考主题清单

只列名字、阶梯与答实的标志，作"问到哪一层算实"的参考；问哪些、问几道由这份 JD 与这份简历定，不是配额。

### GIL 与并发模型选择
- 阶梯：GIL 是什么、限制了什么 → IO 密集与 CPU 密集下多线程、多进程、asyncio 各自的表现，GIL 切换与 C 扩展释放 GIL → 服务加了线程池吞吐反而不涨、多进程共享状态与内存拷贝问题的排查 → 什么任务该外包给进程池、C 扩展、独立服务，Python 3.13 的自由线程（free-threaded）与子解释器意味着什么
- 答实的标志：区分 IO 密集用线程/协程、CPU 密集用进程或 C 扩展；知道 fork 后共享只读内存的写时复制；提到 ProcessPoolExecutor 的序列化开销；对 3.12+ 的 per-interpreter GIL 与 3.13 实验性 no-GIL 有基本认识但不迷信

### asyncio 原理与阻塞排查
- 阶梯：协程与事件循环怎么工作 → await 的让出点、Task 与 Future、gather 与 TaskGroup、异步 IO 库（aiohttp、asyncpg、httpx）→ 异步服务里混入同步数据库驱动或 time.sleep 导致整个 loop 卡住、Task 被垃圾回收静默消失、异常没被 await 到的排查 → 什么时候该 run_in_executor、异步的收益边界与调试代价
- 答实的标志：用 loop.slow_callback_duration 或 PYTHONASYNCIODEBUG 抓阻塞；同步调用放 run_in_executor 或 anyio.to_thread；用 TaskGroup（3.11）或 gather 的 return_exceptions 管理异常；知道 uvloop 的收益与限制

### FastAPI 与 Pydantic
- 阶梯：FastAPI 与 Flask/Django 的定位差别 → 依赖注入的作用域与缓存、Pydantic v2 的校验与序列化、def 与 async def handler 的线程池行为 → 请求量上来后 Pydantic 校验成为瓶颈、依赖里打开数据库会话没关、后台任务丢失的排查 → FastAPI 适合什么规模的项目，缺少"电池"（ORM、admin、迁移）怎么补
- 答实的标志：解释 anyio 线程池的默认容量（40）；Pydantic v2 的 Rust 核心与 model_validate 性能；依赖 yield 做资源清理；BackgroundTasks 与 Celery 的适用边界；OpenAPI 自动生成与契约测试

### Django 生态与 ORM 深度
- 阶梯：Django 的请求生命周期与中间件 → QuerySet 的惰性求值、select_related/prefetch_related、事务与 atomic、信号的代价 → N+1、大表分页慢、迁移锁表、ORM 生成的 SQL 与预期不符的排查 → Django 的"全家桶"什么时候是资产什么时候是负担，DRF 与 Django Ninja 的选择，异步视图的现状
- 答实的标志：select_related 走 JOIN、prefetch_related 走 IN 查询各自的内存与 SQL 代价；only/defer 与 values 减少字段；iterator 处理大结果集；知道 Django 4.2+ 的异步 ORM 边界；迁移分离 schema 与数据、用 RunSQL 并发建索引

### SQLAlchemy 与数据库访问
- 阶梯：Core 与 ORM 的区别 → Session 的生命周期与 identity map、2.0 风格的 select、autoflush 与 expire_on_commit → 连接池耗尽、Session 跨线程共享、DetachedInstanceError、异步引擎下的懒加载报错的排查 → ORM 与原生 SQL 的边界，连接池大小怎么与 worker 数匹配
- 答实的标志：请求作用域的 Session；连接总数 = worker × (pool_size + max_overflow) 的账；异步下用 selectinload 显式加载；Alembic 迁移与版本管理；慢查询用 echo 或数据库侧日志定位

### Celery 与任务队列可靠性
- 阶梯：为什么用 Celery、Broker 与 Backend 各是什么 → acks_late、prefetch、visibility timeout、任务重试与幂等 → 任务丢失、重复执行、worker 内存持续增长、队列堆积、定时任务重复触发的排查 → Celery 与 RQ/Dramatiq/arq 或直接用 Kafka 的取舍，长任务与短任务是否该分队列
- 答实的标志：acks_late + 幂等键；Redis broker 的 visibility_timeout 与长任务的关系；按优先级与时长拆队列；worker 用 max_tasks_per_child 防内存泄漏；beat 单实例或加锁；任务结果不用 backend 存大数据

### 部署模型：Gunicorn / Uvicorn 与 worker
- 阶梯：WSGI 与 ASGI 的区别 → Gunicorn 的 pre-fork 模型、worker 类型（sync/gthread/uvicorn worker）、worker 数与超时 → 请求被 worker timeout 杀掉、内存随时间增长、fork 后数据库连接共享导致的诡异错误的排查 → 单进程多 worker 还是多容器单进程，与 Kubernetes 的资源配合
- 答实的标志：按 IO/CPU 特征选 worker 类型；preload_app 与 post_fork 钩子处理连接；max_requests 与 jitter 轮换 worker；容器里一个进程 + 水平扩容的简单模型；优雅重启与 graceful_timeout

### 性能定位与优化
- 阶梯：Python 慢在哪里 → cProfile、py-spy、Scalene、memray 各看什么，采样与插桩的区别 → 线上 CPU 高、内存缓慢增长、接口 P99 高的定位步骤，常见热点（JSON 序列化、ORM 对象构造、正则、日志）→ 什么时候优化 Python 代码、什么时候换库（orjson、pydantic v2）、什么时候上 Cython/Rust 扩展或拆服务
- 答实的标志：py-spy dump/record 直接附加到线上进程；memray 或 tracemalloc 定位内存；减少对象构造、流式响应、缓存序列化结果；用 timeit/pytest-benchmark 验证

### 内存管理与泄漏
- 阶梯：引用计数与分代 GC 的关系 → 循环引用、__del__ 的坑、内存碎片与 arena 不归还操作系统 → worker 内存持续增长但 GC 统计正常、大对象释放后 RSS 不降、缓存无上限的排查 → 是否关掉分代 GC、用 max_requests 轮换 worker 还是修根因
- 答实的标志：区分 Python 堆与 C 层内存（numpy、driver）；memray 的 native 追踪；gc.freeze 与 fork 场景；缓存加上限与 TTL；用 objgraph 或 gc.get_referrers 找循环引用

### 语言特性与常见陷阱
- 阶梯：装饰器、生成器、上下文管理器的用途 → 描述符、元类、__slots__、dataclass 与 attrs 的底层 → 可变默认参数、闭包晚绑定、浅拷贝、is 与 == 的线上 bug 排查 → 类型标注（typing、mypy/pyright）在大项目里的收益与推进成本
- 答实的标志：能写出带参数的装饰器并保留元信息；生成器做流式处理省内存；用 Protocol 做结构化类型；mypy strict 分阶段推进；提到 3.10+ 的模式匹配与 3.12 的类型参数语法

### 测试与项目工程化
- 阶梯：pytest 的 fixture 与参数化 → mock 与依赖注入、数据库测试的事务回滚、异步测试 → 测试慢、flaky、与外部服务耦合的治理 → 依赖管理（poetry/uv/pip-tools）、锁文件、镜像构建与可重复环境
- 答实的标志：单元与集成分层；testcontainers 或 factory_boy；pytest-xdist 并行；ruff + mypy + pre-commit；多阶段 Docker 构建与非 root 运行

### AI / 模型服务封装（可选，AI 公司常问）
- 阶梯：把模型封装成 API 要注意什么 → 请求批处理、流式响应（SSE）、GPU 内存与进程模型 → 单个大请求阻塞全部请求、模型加载在每个 worker 重复占显存、超时与取消不传递到推理的排查 → 自己封装还是用推理框架（vLLM、Triton、Ray Serve）
- 答实的标志：StreamingResponse 与 request.is_disconnected；单进程加载 + 队列批处理；异步推理与线程池隔离；对成熟推理框架有认识并知道自建的边界
