关注

1.3 FastAPI → Django → Vue → React 面试题

下面按 FastAPI → Django → Vue → React 四个模块梳理高频面试题,附代码案例。


一、FastAPI 篇

Q1:FastAPI 的核心特点和优势是什么?为什么被称为“高性能”?

核心答题框架

FastAPI 是一个现代、快速(高性能)的 Web 框架,其核心优势:

  • 极致性能:底层基于 Starlette(ASGI 框架),原生支持 async/await,在处理 I/O 密集型任务时高效利用单线程处理成千上万并发连接,性能可与 Node.js 和 Go 媲美
  • 类型安全与自动校验:深度集成 Pydantic,利用 Python 类型提示自动完成请求数据的解析、验证和序列化
  • 自动生成 API 文档:开箱即用提供 Swagger UI (/docs) 和 ReDoc (/redoc)
  • 依赖注入系统:强大且灵活

加分回答:> “FastAPI 的‘高性能’指处理高并发 I/O 的能力;‘快’不仅指性能,也指开发速度——通过类型安全和自动文档,显著提升开发效率。”

代码案例:基础 FastAPI 应用

from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn

app = FastAPI()

# 定义 Pydantic 模型(自动校验)
class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = False

# 路径操作装饰器 + 类型提示
@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.post("/items/")
async def create_item(item: Item):
    # FastAPI 自动校验请求体是否符合 Item 模型
    return {"item_name": item.name, "price": item.price}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Q2:FastAPI 的依赖注入(Dependency Injection)是如何实现的?

核心答题框架

依赖注入是一种解耦组件之间依赖关系的设计模式。FastAPI 中通过 Depends 实现:

  1. 定义依赖项(普通函数或类)
  2. 使用 Depends 标记参数
  3. 请求到达时,FastAPI 自动调用依赖函数并递归解析所有子依赖
  4. 最终将返回值注入路径操作函数

代码案例:数据库会话依赖注入

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session

app = FastAPI()

# 定义依赖项:获取数据库会话
def get_db():
    try:
        db = SessionLocal()
        yield db
    finally:
        db.close()

# 定义依赖项:根据 ID 获取商品
def get_item(item_id: int, db: Session = Depends(get_db)):
    item = db.query(Item).filter(Item.id == item_id).first()
    if not item:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

# 路径操作函数中注入依赖
@app.get("/items/{item_id}")
async def read_item(item: Item = Depends(get_item)):
    return item

加分回答:> “依赖注入让代码更可测、更解耦。常见误区是在视图函数内硬编码依赖,正确做法是统一用 Depends 声明,让框架负责组装。”


Q3:FastAPI 中同步函数和异步函数如何选择?

核心答题框架

场景推荐原因
I/O 密集型(数据库查询、HTTP 请求、文件读写)async def非阻塞,提高并发
CPU 密集型(复杂计算、加密)def(同步)异步对 CPU 任务无帮助,反而增加开销
混合场景async def + run_in_executor将 CPU 任务放到线程池执行

二、Django 篇

Q4:Django 的核心思想是什么?

核心答题框架

Django 的核心思想是 “电池已内置”(Batteries Included) ——框架自带常用功能(ORM、认证、表单、模板、Admin 后台等),无需额外找第三方库。同时 Django 遵循 MTV(Model-Template-View) 架构模式:

组件职责
Model定义数据模型,操作数据库(ORM)
Template负责页面展示(HTML)
View处理业务逻辑,连接 Model 和 Template

加分回答:> “Django 的 MTV 和传统 MVC 本质类似,只是把 Controller 的职责放到了 View 里,而 Template 替代了 View 的展示层。”


Q5:描述 Django 请求的完整生命周期。

核心答题框架

用户请求 → WSGI 服务器 → 中间件(process_request) → URL 路由匹配 → 
中间件(process_view) → 视图处理 → 模板渲染 → 
中间件(process_response) → 响应返回
  1. 请求发起:浏览器生成 HTTP 请求发送给服务器
  2. WSGI 接收:WSGI 服务器将 HTTP 请求转换为 Python 可理解格式
  3. 中间件处理:请求依次经过所有中间件的 process_request 方法(认证、日志、权限等)
  4. URL 路由匹配:URL 调度器根据 urls.py 找到对应视图
  5. 视图处理:视图执行业务逻辑(数据库查询等)
  6. 模板渲染:视图将数据传递给模板,生成 HTML
  7. 响应返回:视图返回响应对象,经过中间件 process_response 返回客户端

代码案例:自定义中间件

# middleware.py
from django.utils.deprecation import MiddlewareMixin

class RequestLogMiddleware(MiddlewareMixin):
    def process_request(self, request):
        # 请求进入时记录日志
        print(f"Request: {request.method} {request.path}")
        return None  # 继续处理

    def process_response(self, request, response):
        # 响应返回时记录
        print(f"Response status: {response.status_code}")
        return response

# settings.py 中注册
MIDDLEWARE = [
    # ...
    'myapp.middleware.RequestLogMiddleware',
]

Q6:Django ORM 的 N+1 查询问题是什么?如何解决?

核心答题框架

N+1 查询指:查询主表 N 条记录后,每条记录又额外查询一次关联表,导致总共 N+1 次 SQL。

代码案例

# ❌ 产生 N+1 查询
books = Book.objects.all()  # 1 次查询
for book in books:
    print(book.author.name)  # 每本书额外 1 次查询,共 N+1 次

# ✅ 使用 select_related(外键、一对一)
books = Book.objects.select_related('author').all()  # 1 次 JOIN 查询

# ✅ 使用 prefetch_related(多对多、反向外键)
books = Book.objects.prefetch_related('tags').all()  # 2 次查询

加分回答:> “select_related 生成 JOIN 查询(适合外键),prefetch_related 分别查询后在 Python 层面关联(适合多对多)。选错反而会拖慢性能。”


三、Vue 篇

Q7:Vue3 相比 Vue2 有哪些主要改进?

核心答题框架

改进点说明
响应式系统使用 Proxy 替代 Object.defineProperty,能监听对象属性的添加/删除及数组索引变化
性能提升重构虚拟 DOM(PatchFlag、静态提升)、事件缓存
Tree-shaking模块化架构,未使用代码不会被打包
Composition API更灵活的逻辑组织和复用方式
TypeScript 支持源码用 TS 重写,类型推断更好
新组件Teleport、Suspense、Fragment

Q8:Composition API 和 Options API 的区别?

核心答题框架

  • Options API(Vue2 方式):按选项(datamethodscomputed)组织代码
  • Composition API(Vue3 方式):按逻辑功能组织代码,在 setup() 中组合

代码案例:自定义组合式函数(逻辑复用)

// useCounter.js - 组合式函数
import { ref } from 'vue';

export function useCounter(initialValue = 0) {
    const count = ref(initialValue);
    const increment = () => { count.value++; };
    const decrement = () => { count.value--; };
    return { count, increment, decrement };
}

// MyComponent.vue - 在组件中使用
import { useCounter } from './useCounter';

export default {
    setup() {
        const { count, increment, decrement } = useCounter(10);
        return { count, increment, decrement };
    }
};

加分回答:> “Composition API 解决了 Vue2 Mixins 的命名冲突和来源不清晰问题。同时更好的 TypeScript 支持让大型项目更可控。”


Q9:Vue3 的生命周期钩子有哪些变化?

核心变化

Vue2Vue3 组合式 API说明
beforeCreatesetup() 替代直接在 setup 中写
createdsetup() 替代直接在 setup 中写
beforeMountonBeforeMount挂载前
mountedonMounted挂载后
beforeUpdateonBeforeUpdate更新前
updatedonUpdated更新后
beforeDestroyonBeforeUnmount名称变更
destroyedonUnmounted名称变更

四、React 篇

Q10:React 18 有哪些核心新特性?

核心答题框架

  • Concurrent Rendering(并发渲染) :渲染可中断
  • Automatic Batching(自动批处理) :多次 setState 自动合并
  • Transitions(startTransition) :标记非紧急更新
  • Suspense 增强
  • 新的 Hydration API

加分回答:> “React 18 的核心不是新功能,而是调度能力的升级,让 UI 更‘可中断’。”


Q11:useState 和 useReducer 的区别?

核心答题框架

场景推荐
单一独立状态useState
复杂状态逻辑(多个子值联动)useReducer

代码案例

// useState - 简单状态
const [count, setCount] = useState(0);

// useReducer - 复杂状态
const initialState = { count: 0 };

function reducer(state, action) {
    switch (action.type) {
        case 'increment': return { count: state.count + 1 };
        case 'decrement': return { count: state.count - 1 };
        default: return state;
    }
}

const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: 'increment' });

加分回答:> “useReducer 更接近 Redux 思想,适合复杂状态流转。组件内状态管理用 useReducer 就够了,不一定非要上 Redux。”


Q12:useEffect 的清理函数什么时候执行?

核心答题框架

  1. 组件卸载时
  2. 依赖项变化,下一次 Effect 执行之前

代码案例

useEffect(() => {
    const timer = setInterval(() => {
        console.log('tick');
    }, 1000);

    // 清理函数:防止内存泄漏 + 重复订阅
    return () => {
        clearInterval(timer);
    };
}, []);  // 空依赖 → 只在挂载和卸载时执行

加分回答:> “清理函数防止内存泄漏重复订阅。如果不清理定时器、事件监听或 WebSocket,组件卸载后它们依然存活,造成严重的内存泄漏。”


Q13:React 和 Vue 的核心区别?

核心答题框架

维度ReactVue
思想UI = f(state)MVVM 响应式
数据更新手动 setState自动依赖追踪
模板JSXTemplate
灵活性极高适中

加分回答:> “React 是 UI 库,Vue 是 框架。React 更偏‘自由’,Vue 更偏‘约束’——这决定了选型时要看团队偏好和项目复杂度。”


五、框架对比总结(面试加分)

维度FastAPIDjangoVueReact
定位高性能 API 框架全栈 Web 框架前端框架前端 UI 库
核心哲学类型安全 + 异步电池已内置渐进式组合式
适用场景微服务、API 服务复杂 Web 应用、CMS中后台、渐进增强大型 SPA、跨平台
性能特点极高(ASGI + async)中等(WSGI,支持异步)虚拟 DOM + 响应式虚拟 DOM + Fiber

选型决策框架

FastAPI for APIs,Django for full-stack,Flask for everything else ——然后只在 benchmark 证明你需要时才做优化。”

FastAPI 高频面试题与代码案例

FastAPI 是目前 Python 生态中最流行的现代 Web 框架,面试中几乎必问。以下整理了一套高频面试题,每个问题都配有可直接运行的代码片段,帮助你从“知道”到“能写”。


1. 基础概念

Q1: FastAPI 相比 Flask/Django 有什么优势?

核心要点:

  • 高性能:基于 Starlette(ASGI)和 Pydantic,性能接近 Node.js 和 Go。
  • 自动生成 API 文档:内置 Swagger UI (/docs) 和 ReDoc (/redoc)。
  • 类型提示与数据验证:利用 Python 类型注解,Pydantic 自动校验请求/响应数据。
  • 异步支持:原生 async/await,适合 I/O 密集型任务。
  • 依赖注入系统:简洁强大,便于复用和测试。
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.post("/items/")
async def create_item(item: Item):
    return {"item_name": item.name, "item_price": item.price}

Q2: 如何定义路径参数、查询参数和请求体?

from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

# 路径参数
@app.get("/users/{user_id}")
async def get_user(user_id: int):
    return {"user_id": user_id}

# 查询参数
@app.get("/items/")
async def list_items(skip: int = 0, limit: int = 10, q: str = Query(None, max_length=50)):
    return {"skip": skip, "limit": limit, "q": q}

# 请求体
class ItemCreate(BaseModel):
    name: str
    price: float

@app.post("/items/")
async def create_item(item: ItemCreate):
    return item

2. 异步与并发

Q3: FastAPI 中的 async def 和普通 def 有什么区别?何时使用?

答案:

  • async def 定义异步函数,适合 I/O 操作(数据库查询、HTTP 请求),可在函数内使用 await
  • 普通 def 是同步函数,FastAPI 会在线程池中执行,适合 CPU 密集型或不需要 await 的任务。
  • 选型原则:如果依赖库支持异步,用 async def;否则用普通 def
import asyncio
from fastapi import FastAPI

app = FastAPI()

# 异步:适合 I/O
@app.get("/async-data")
async def get_async_data():
    await asyncio.sleep(1)  # 模拟 I/O
    return {"data": "async result"}

# 同步:适合 CPU 密集型
@app.get("/sync-data")
def get_sync_data():
    import time
    time.sleep(1)  # 模拟 CPU 计算
    return {"data": "sync result"}

Q4: 如何实现并发请求?FastAPI 如何处理大量并发?

答案:

  • FastAPI 基于 ASGI,使用 uvicorn 服务器,支持高并发。
  • 内部使用 asyncio 事件循环,I/O 操作不阻塞。
  • 对于 CPU 密集型任务,应使用 BackgroundTasks 或 Celery 异步处理,避免阻塞事件循环。
from fastapi import BackgroundTasks

def send_email(email: str, message: str):
    # 模拟发邮件(CPU/IO 密集)
    import time
    time.sleep(2)
    print(f"Email sent to {email}")

@app.post("/send-email/")
async def send_email_endpoint(email: str, bg_tasks: BackgroundTasks):
    bg_tasks.add_task(send_email, email, "Hello")
    return {"message": "Email queued"}

3. 依赖注入

Q5: FastAPI 的依赖注入是如何工作的?写一个自定义依赖。

答案:
依赖注入通过 Depends 实现,将可重复使用的逻辑(如认证、数据库会话)提取为函数,并自动解析依赖链。

from fastapi import Depends, FastAPI

app = FastAPI()

# 定义依赖
def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons

@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons

Q6: 如何用依赖注入实现数据库会话管理?

from fastapi import Depends, FastAPI
from sqlalchemy.orm import Session
from .database import SessionLocal, engine

app = FastAPI()

# 依赖:获取数据库会话
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/")
def read_users(db: Session = Depends(get_db)):
    users = db.query(User).all()
    return users

4. 中间件与 CORS

Q7: 如何添加 CORS 中间件?

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产环境应限定域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Q8: 如何自定义中间件记录请求耗时?

import time
from fastapi import Request

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.perf_counter()
    response = await call_next(request)
    process_time = time.perf_counter() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

5. 认证与授权

Q9: 如何实现 JWT 认证?

关键步骤:

  1. 用户登录验证,返回 JWT token。
  2. 依赖函数解析 token 并验证用户身份。
  3. 受保护路由通过 Depends 依赖认证。
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from pydantic import BaseModel

SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise HTTPException(status_code=401)
    except JWTError:
        raise HTTPException(status_code=401)
    return username

@app.get("/users/me")
async def read_users_me(current_user: str = Depends(get_current_user)):
    return {"username": current_user}

Q10: 如何限制接口调用频率(Rate Limiting)?

可以使用 slowapi 库或自定义中间件。

from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
app.add_exception_handler(429, _rate_limit_exceeded_handler)

@app.get("/heavy")
@limiter.limit("5/minute")
async def heavy_endpoint(request: Request):
    return {"message": "This is a rate-limited endpoint"}

6. 数据库集成

Q11: FastAPI 如何集成 SQLAlchemy(异步)?

使用 asyncpgsqlalchemy.ext.asyncio

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/db"
engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User))
    return result.scalars().all()

7. 测试

Q12: 如何为 FastAPI 编写单元测试?

使用 httpxpytest

from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Hello World"}

def test_create_item():
    response = client.post("/items/", json={"name": "Foo", "price": 50.5})
    assert response.status_code == 200
    assert response.json()["item_name"] == "Foo"

8. 部署与性能

Q13: 生产环境如何部署 FastAPI?

常用方式:

  • Uvicorn + Gunicorn(多进程):gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
  • Docker:使用 uvicorn 并设置 --workers 参数。
  • Kubernetes:使用容器化部署,结合 HPA 弹性伸缩。
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Q14: 如何优化 FastAPI 性能?

  • 使用 async I/O 操作。
  • 使用 Pydantic V2 的更快性能。
  • 启用 GZip 压缩。
  • 使用缓存(aiocache 等)。
  • 使用 nginxtraefik 作为反向代理,终结 SSL。
  • 使用 prometheus 监控。

以上便是 FastAPI 面试的高频核心问题与代码案例。建议你在面试前亲手运行这些代码,并理解每个环节的设计思路,这样在回答时会更自信。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_42655650/article/details/162078065

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--