Python Web开发题库选择题:别背了,开库选做题才是发题硬道理 Python Web开发面试,最怕的择题不是手写代码,而是开库选那种“看着都眼熟,选起来全错”的发题选择题。别问我怎么知道的择题,上周刚帮朋友模拟面试,开库选三十道题他错了十二道,发题错的择题还全是那种“Django中间件执行顺序”和“Flask请求上下文”的基础题。他一脸委屈:“我项目里都用过啊!开库选”——用过和懂,发题是择题两码事。 不信?开库选先来一道开胃菜: 在Django中,如果视图函数需要同时处理GET和POST请求,发题最直接的择题做法是? A. 写两个视图函数,用URL分发 B. 在同一个视图函数中用request.method判断 C. 使用装饰器@require_http_methods D. 定义一个类视图,分别实现get和post方法 选C的人不少,但正确答案是D。C虽然能限制请求方法,但没法在一个函数里优雅地处理两种逻辑。B太原始,A太蠢。类视图才是Django官方推荐的做法,而且CBV(类视图)还能配合mixin做权限控制、缓存等复用。这题考的不是语法,是设计习惯。 再看一个Flask的经典陷阱: Flask中,全局变量request在非请求上下文中访问会抛出什么异常? A. KeyError B. RuntimeError C. AttributeError D. 不会抛异常,返回None 选D的人往往没踩过坑。实际答案是B,RuntimeError: Working outside of request context。这个错误信息我见过太多次了,尤其是在写定时任务或者后台线程时,有人直接import了request然后调用request.args,瞬间爆炸。Flask的上下文是线程隔离的,不是全局单例,这是它跟Django最大的思维差异。 题库里还爱考ORM查询的懒加载行为。比如: 在Django ORM中,执行`Book.objects.filter(price__gt=50)`后,实际数据库查询发生了吗? A. 立即执行 B. 在第一次迭代结果集时执行 C. 在调用.count()时执行 D. 永不执行,除非显式调用.query 答案是B。但很多人选了A,因为习惯性认为filter就是查询。其实filter只是构造了一个QuerySet对象,它是个懒加载的容器。直到你真正需要数据(比如for循环、list()转换、切片),它才去数据库。这个机制的好处是能链式调用多次filter而不会产生多次查询,坏处是你可能无意中持有一个大QuerySet内存泄漏。我见过有人把整个表filter出来,只为了判断是否存在,应该用.exists()而不是for循环。 别忘了还有WSGI和ASGI的区别,题库里必有一道: 以下哪个不是WSGI协议的特点? A. 同步阻塞模型 B. 每个请求由一个可调用对象处理 C. 支持WebSocket长连接 D. 是Python Web应用与服务器之间的标准接口 选C。WSGI天生是请求-响应模型,一个请求处理完就断开。WebSocket需要长连接,所以后来才有了ASGI(异步服务器网关接口)。Django 3.0之后支持ASGI,但很多人还是默认用WSGI跑生产环境,也没问题,只要你的业务不需要实时推送。 最后一道压轴题,考察的是你对框架底层原理的理解: Flask的`app.route()`装饰器内部主要做了什么? A. 将函数注册到URL规则映射表中 B. 创建新的视图函数 C. 启动开发服务器 D. 自动添加CSRF保护 答案是A。但更深一层,它内部用了`add_url_rule()`方法,把URL和端点(endpoint)绑定到视图函数。如果你自己写装饰器,别忘了用`functools.wraps`保留原函数元信息,否则Flask的端点命名会乱套。这些细节,光看文档记不住,得动手改一改源码才知道。 说白了,选择题不是考背诵,是考你有没有真正写过、调试过、踩过坑。每次报错信息就是最好的题库——RuntimeError、TypeError、AttributeError,它们比任何模拟题都诚实。下次刷题时,别只看选项对错,把每个错误选项想一遍:“如果真这么写,会报什么错?”想通了,那题才算做对了。 |