楼层: 首页/ 软件技术/ Python Web 开发/ 常见坑与高频面试题
6

常见坑与高频面试题

Pitfalls & Interview Questions

Web 开发的坑,一半是"安全",一半是"上下文/异步用错"。下面把高频考点一次性过一遍。

坑/考点一句话
SQL 注入永远用 ORM 参数化查询,别拼 SQL 字符串。.filter(name=user_input) 安全,.raw(f"...{x}...") 危险。
XSS模板默认自动转义 {{ x }};要写 HTML 用 {{ x|safe }},但确认 x 可信。
CSRF表单带 {% csrf_token %};API 用 token 认证就不用 cookie,天然免疫。
密码哈希永远别明文存密码。Flask 用 werkzeug.security.generate_password_hash,Django 用 django.contrib.auth.hashers,或 bcrypt。
DEBUG=True 上线会暴露调试器和环境变量,等于开后门。生产必须 DEBUG=False。
Flask 上下文请求外用 db.session 前必须 with app.app_context():。
FastAPI 异步阻塞async def 里别调同步阻塞库,会卡事件循环。
Django N+1循环里访问外键会重复查库,用 select_related/prefetch_related。

Web 安全三剑客:SQL 注入 / XSS / CSRF

论三种攻击怎么防

SQL 注入:用户输入 ' OR 1=1 -- 拼进 SQL 就能拖库。防法:用 ORM 参数化查询,别拼字符串。XSS:用户输入 <script> 在别人浏览器执行。防法:模板自动转义(Jinja2/DTL 默认开),别用 |safe 包不可信数据。CSRF:恶意网站借你已登录的 cookie 发请求。防法:表单带 CSRF token,API 用 Authorization header 不用 cookie。

密码哈希与 JWT 安全

# 密码永远别明文存,用慢哈希 # Flask: from werkzeug.security import generate_password_hash, check_password_hash hashed = generate_password_hash("mypassword") check_password_hash(hashed, "mypassword") # True # JWT 安全要点: # 1. 用强 SECRET,别用 "secret" # 2. 短过期时间(access token 15 分钟,refresh token 7 天) # 3. HTTPS 传输,别放 URL 里 # 4. 登出要靠黑名单(Redis 存已注销的 jti)
高频面试题 20 道(挑重点)

1. WSGI 和 ASGI 区别?

答案

WSGI 同步(Flask/Django),ASGI 异步(FastAPI/Starlette),支持 WebSocket/SSE。Uvicorn 是 ASGI 服务器,Gunicorn 是 WSGI。

2. GET 和 POST 的本质区别?

答案

GET 参数在 URL、幂等、可缓存;POST 参数在 body、非幂等。但安全上两者都不安全(HTTPS 才加密),别用 GET 传密码。

3. 状态码 200/301/302/403/404/500 分别啥意思?

答案

200 成功;301 永久重定向;302 临时重定向;403 没权限;404 找不到;500 服务器内部错误。

4. Cookie、Session、JWT 三兄弟?

答案

Cookie 是浏览器存的小块;Session 服务端存状态、靠 cookie 里 sessionid 关联;JWT 把状态签名塞 token、服务端无状态。API 用 JWT,传统网页用 Session。

5. 为什么生产不用 Flask/Django 自带 runserver?

答案

它是单线程开发服务器,没做性能/安全加固。生产用 Gunicorn/Uvicorn 多 worker,前面套 Nginx 处理静态文件、HTTPS、负载均衡。

6. 什么是中间件?

答案

请求进来/响应出去之间"横切"的逻辑:打日志、CORS、鉴权、压缩。Flask 用 before/after_request,FastAPI 用 add_middleware,Django 在 MIDDLEWARE 列表注册。

7. RESTful API 设计原则?

答案

资源用名词(/users),动作用 HTTP 方法(GET/POST/PUT/DELETE),无状态,用状态码表达结果,版本化(/v1/users)。

8. 为什么 ORM 防 SQL 注入?

答案

ORM 把参数和 SQL 分开传输,数据库驱动自动转义,恶意输入被当成数据而非命令。拼字符串 SQL 就没这层保护。

9. FastAPI 的 response_model 干嘛用?

答案

限定响应字段、过滤掉不该返回的(如密码 hash),同时生成 OpenAPI 文档。比如返回 ORM 对象但 response_model=UserOut,自动只挑白名单字段。

10. Django 的 MT V 各是啥?

答案

Model 数据层(对应表),Template 视图层(HTML),View 控制层(业务逻辑)。URLconf 把 URL 映射到 View。

11. 什么是 RESTful?PUT 和 PATCH 区别?

答案

REST 是一种风格:资源名词化、HTTP 方法表达动作、无状态。PUT 全量替换整个资源,PATCH 局部更新某个字段。

12. 为什么密码不能存明文?哈希和加密的区别?

答案

哈希单向(bcrypt/argon2),加密双向(AES)。密码只能存哈希——验证时算哈希比对。彩虹表/慢哈希(bcrypt 自带 cost factor)防暴力破解。

13. 什么是 CORS?为什么浏览器要搞这一出?

答案

浏览器同源策略:网页 JS 默认不能跨域发请求。服务器返回 Access-Control-Allow-Origin 头才放行。FastAPI 用 CORSMiddleware,Flask 用 flask-cors。

14. 什么是 CSRF?什么是 XSS?两者区别?

答案

CSRF 是"冒充已登录用户发请求"(借 cookie),靠 token 防;XSS 是"往页面注入恶意脚本",靠输出转义防。一个防冒充,一个防注入。

15. 为什么生产要 Nginx 反向代理?不能 Gunicorn 直接对外?

答案

Nginx 擅长:静态文件、HTTPS 终止、负载均衡、防慢连接、压缩。Gunicorn 只管跑 Python worker。两者分工:Nginx 在前挡流量,Gunicorn 在后跑业务。

16. FastAPI 的依赖注入和 Python 装饰器有什么区别?

答案

装饰器包函数,对函数"做手脚";依赖注入是声明"我要什么",框架帮你构造并传进来。DI 可参数化、可覆盖、可在测试时替换(比如测试时换假 DB),装饰器做不到。

17. Django 的 select_related 和 prefetch_related 区别?

答案

select_related 用 SQL JOIN,一次性查外键/一对一;prefetch_related 发第二条 SQL 用 IN 查询多对多/反向外键。选不对就 N+1。

18. 为什么 FastAPI 的性能能接近 Go/Node?

答案

① ASGI 异步,单线程高并发;② Pydantic 2 Rust 内核校验快;③ Starlette 是 asyncio 之上的薄封装,少拷贝。但 CPU 密集仍受 GIL 限制。

19. 什么是幂等性?哪些 HTTP 方法天然幂等?

答案

同一请求发一次和发 N 次效果一样。GET/HEAD/PUT/DELETE 幂等,POST 不幂等(每次创建新资源)。设计 API 时重试要考虑幂等。

20. 怎么防止暴力破解登录?

答案

登录失败限流(IP/账号)、验证码、bcrypt 慢哈希拉长破解成本、账号临时锁定、审计日志。别自己发明,用现成方案(django-axes、slowapi)。