常见坑与高频面试题
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 安全
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)。