生产级高频面试题
Section 1: FastAPI 入门 — 生产级高频面试题
Q1: FastAPI 和 Flask 的核心区别是什么?为什么选 FastAPI?
答:
| 维度 | Flask | FastAPI |
|---|---|---|
| 协议 | WSGI(同步) | ASGI(异步) |
| 数据校验 | 手动 / 用 marshmallow | 内置 Pydantic,自动校验 |
| 文档 | 需手动写 / flask-restx | 自动生成 Swagger + ReDoc |
| 类型提示 | 仅作装饰 | 运行时校验 + 编辑器补全 |
| 性能 | 一般 | 接近 Node.js/Go |
选 FastAPI 的理由:AI/RAG 项目需要异步高并发(LLM 调用是典型 IO 密集型),FastAPI 原生 async 支持是刚需。
Q2: 什么是 ASGI?和 WSGI 有什么区别?
答:
- WSGI(Web Server Gateway Interface):同步标准,一个请求占用一个线程,处理完才能释放。Flask 用的就是 WSGI。
- ASGI(Asynchronous Server Gateway Interface):异步标准,支持 WebSocket、HTTP/2,一个线程可同时处理多个请求。FastAPI/Starlette 基于 ASGI。
WSGI: 请求1[===] 请求2[===] 请求3[===] (串行)
ASGI: 请求1[==] 请求2[==] 请求3[==] (并发,IO等待时切换)
Q3: Pydantic 在 FastAPI 中的作用是什么?
答: 三重作用:
- 请求校验:自动验证 JSON 请求体,不合法返回 422 + 详细错误
- 自动文档:模型字段自动生成 Swagger 文档的参数说明
- 序列化:response_model 自动过滤返回字段,防止泄露内部数据
# response_model 只返回 ItemResponse 定义的字段
# 即使函数返回了额外字段,也不会暴露给前端
@app.post("/items", response_model=ItemResponse)
def create_item(item: ItemCreate): ...
Q4: async def 和 def 在 FastAPI 中有什么区别?
答:
async def:FastAPI 把它放进事件循环,遇到await时让出 CPU,适合 IO 密集操作def:FastAPI 在线程池中运行它,适合 CPU 密集操作- 错误用法:在
async def里调用time.sleep()(阻塞事件循环,比def还慢) - 正确用法:
async def里用await asyncio.sleep(),def里用time.sleep()
Q5: 路径参数和查询参数如何区分?
答: FastAPI 按函数参数名自动判断:
- 参数名出现在 URL 路径的
{}中 → 路径参数 - 参数名不在路径中 → 查询参数
@app.get("/users/{user_id}") # user_id 是路径参数
def get_user(user_id: int, active: bool = True): # active 是查询参数...
# 访问:/users/42?active=true
URL 里的 {} → 路径参数
URL 里的 ?key=val → 查询参数
JSON 里的数据 → 请求体(必须用模型Pydantic或 Body ())
Path/Query/Body 三个就是分别给这 3 种位置加校验、加说明的元数据。
Q6: 为什么 AI Agent 项目推荐用 FastAPI?
答:
- LLM API 调用是典型 IO 密集型(等待网络响应),async 高并发是刚需
- Pydantic 校验保证 Agent 输入输出数据结构可靠
- 自动生成的 Swagger 文档方便团队调试 Agent 接口
- 与 LangChain、OpenAI SDK 等主流 AI 库无缝集成
- 项目后期部署 Docker + uvicorn 非常成熟
Q7: HTTPException 和普通 Exception 有什么区别?
答:
HTTPException:FastAPI 专门设计,携带status_code和detail,直接转为 HTTP 响应- 普通
Exception:FastAPI 默认返回 500 Internal Server Error,不暴露内部错误信息
# 生产级写法:捕获异常 -> 转为 HTTPException
try:result = some_operation()
except ValueError as e:raise HTTPException(status_code=400, detail=str(e))
except Exception as e:logger.error(f"未知错误: {e}")raise HTTPException(status_code=500, detail="服务器内部错误")
Q8: Field(...) 中的三个点 ... 是什么意思?
答: ... 是 Python 内置的 Ellipsis 对象,在 Pydantic 中表示必填字段(没有默认值)。等价于不给默认值:
name: str = Field(...) # 必填
name: str # 也是必填(简写)
name: str = "默认值" # 可选,有默认值
