Django面试题积累

Posted ghylpb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django面试题积累相关的知识,希望对你有一定的参考价值。

Django中models利用orm对mysql进行查询

https://www.cnblogs.com/xiaoyuanqujing/articles/11728294.html

  1. Django ORM查询中select_related和prefetch_related的区别?

    def select_related(self, *fields)
        性能相关:表之间进行join连表操作,一次性获取关联的数据。
    
        总结:
        1. select_related主要针一对一和多对一关系进行优化。
        2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。
    
    def prefetch_related(self, *lookups)
        性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
    
        总结:
        1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
        2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。
    
  2. 对 MVC,MVT解读的理解?

    M:Model,模型,和数据库进行交互
    V:View,视图,负责产生html页面
    C:Controller,控制器,接收请求,进行处理,与M和V进行交互,返回应答。
    技术图片
    1、 用户点击注按钮,将要注册的信息发送给网站服务器。
    2、 Controller控制器接收到用户的注册信息,Controller会告诉Model层将用户的注册信息保存到数据库
    3、 Model层将用户的注册信息保存到数据库
    4、 数据保存之后将保存的结果返回给Model模型,
    5、 Model层将保存的结果返回给Controller控制器。
    6、 Controller控制器收到保存的结果之后,或告诉View视图,view视图产生一个html页面。
    7、 View将产生的Html页面的内容给了Controller控制器。
    8、 Controller将Html页面的内容返回给浏览器。
    9、 浏览器接受到服务器Controller返回的Html页面进行解析展示。
    M:Model,模型,和MVC中的M功能相同,和数据库进行交互。
    V:view,视图,和MVC中的C功能相同,接收请求,进行处理,与M和T进行交互,返回应答。
    T:Template,模板,和MVC中的V功能相同,产生Html页面
    技术图片
    1、 用户点击注册按钮,将要注册的内容发送给网站的服务器。
    2、 View视图,接收到用户发来的注册数据,View告诉Model将用户的注册信息保存进数据库。
    3、 Model层将用户的注册信息保存到数据库中。
    4、 数据库将保存的结果返回给Model
    5、 Model将保存的结果给View视图。
    6、 View视图告诉Template模板去产生一个Html页面。
    7、 Template生成html内容返回给View视图。
    8、 View将html页面内容返回给浏览器。
    9、 浏览器拿到view返回的html页面内容进行解析,展示。

  3. django中间件的使用?

    面试官问你Django中间件的时候,我们不应该只是局限于面试官的问题,而应做到举一反三。
    面试之前准备一些白纸,在问到一些问题的时候应该用画图的形式展示出来
    比如这里问到Django的中间件,我们应该给面试官画出Django的生命周期整体流程图,把中间件作为一部分的回答内容,
    这样的好处在于,即展示了你对Django从前到后的流程都很熟悉又回答了面试官的问题,还顺带秀了一把其他技能,一举两得。
    中间件介绍:作为Django的门户,一切请求都会先经过中间件才会到达Django后端,所以中间件可以用来做全局方面的一些功能
    详细:给我们定义了五个方法

    1.def process_request(request):
    	pass
    2.def process_view(request):
    	pass
    3.def process_template_response(request):
    	pass
    4.def process_exception(request):
    	pass
    5.def process_response(request):
    	pass
    

    这些内容应该做到快速回答,不要"慢条斯理"的,搞IT的都很忙好吧,知识点一定要掌握牢固,脱口而出
    一定要记住你是需要在有限的时间内将自己的看家本领不遗余力的倾囊而出

  4. django开发中数据库做过什么优化?

    1.设计表时,尽量少使用外键,因为外键约束会影响插入和删除性能;
    2.使用缓存,减少对数据库的访问;
    3.在orm框架下设置表时,能用varchar确定字段长度时,就别用text;
    4.可以给搜索频率高的字段属性,在定义时创建索引;
    5.Django orm框架下的Querysets 本来就有缓存的;
    6.如果一个页面需要多次连接数据库,最好一次性取出所有需要的数据,减少对数据库的查询次数;
    7.若页面只需要数据库里某一个两个字段时,可以用QuerySet.values();
    8.在模板标签里使用with标签可以缓存Qset的查询结果。

  5. 验证码过期时间怎么设置?

    将验证码保存到数据库或session,设置过期时间为1分钟,然后页面设置一个倒计时(一般是前端js实现 这个计时)的展示,一分钟过后再次点击获取新的信息。

  6. Python中三大框架各自的应用场景?

    • django:主要是用来搞快速开发的,他的亮点就是快速开发,节约成本,正常的并发量不过10000,如果要实现高并发的话,就要对django进行二次开发,比如把整个笨重的框架给拆掉,自己写socket实现http的通信,底层用纯c,c++写提升效率,ORM框架给干掉,自己编写封装与数据库交互的框
      架,因为啥呢,ORM虽然面向对象来操作数据库,但是它的效率很低,使用外键来联系表与表之间的查询;
    • flask:轻量级,主要是用来写接口的一个框架,实现前后端分离,提升开发效率,Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验
      证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以NoSQL。
      其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是Flask框架的核心。Python最出名的框架要数Django,此外还有Flask、Tornado等框架。虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。
    • Tornado: Tornado是一种 Web 服务器软件的开源版本。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。 得利于其非阻塞的方式和对epoll的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。
  7. 什么是restful api,谈谈你的理解?

    上来先给面试官扔出一手Django的restgramework源码(这一块知识课下一定要自己看着源码走三遍做到烂熟于心,看着面试官的眼睛快速自信的说出。这一手源码扔出来之后,面试已经成功一半)
    REST:Representational State Transfer的缩写,翻译:“具象状态传输”。一般解释为“表现层状态转换”。
    REST是设计风格而不是标准。是指客户端和服务器的交互形式。我们需要关注的重点是如何设计REST风格的网络接口。
    REST的特点:
    1.具象的。一般指表现层,要表现的对象就是资源。比如,客户端访问服务器,获取的数据就是资源。比如文字、图片、音视频等。
    2.表现:资源的表现形式。txt格式、html格式、json格式、jpg格式等。浏览器通过URL确定资源的位置,但是需要在HTTP请求头中,用AcceptContent-Type字段指定,这两个字段是对资源表现的描述。
    3.状态转换:客户端和服务器交互的过程。在这个过程中,一定会有数据和状态的转化,这种转化叫做状态转换。其中,GET表示获取资源,POST表示新建资源,PUT表示更新资源,DELETE表示删除资源。HTTP协议中最常用的就是这四种操作方式。
    RESTful架构:
    1.每个URL代表一种资源;
    2.客户端和服务器之间,传递这种资源的某种表现层;
    3.客户端通过四个http动词,对服务器资源进行操作,实现表现层状态转换。

  8. 如何设计符合 RESTful 风格的 API

    一、域名:
    将api部署在专用域名下:
    http://api.example.com
    或者将api放在主域名下:
    http://www.example.com/api/
    二、版本:
    将API的版本号放在url中。
    http://www.example.com/app/1.0/info
    http://www.example.com/app/1.2/info
    三、路径:
    路径表示API的具体网址。每个网址代表一种资源。 资源作为网址,网址中不能有动词只能有名词,一般名词要与数据库的表名对应。而且名词要使用复数。
    错误示例:
    http://www.example.com/getGoods
    http://www.example.com/listOrders
    正确示例:
    获取单个商品
    http://www.example.com/app/goods/1
    获取所有商品
    http://www.example.com/app/goods

    四、使用标准的HTTP方法:
    对于资源的具体操作类型,由HTTP动词表示。 常用的HTTP动词有四个。
    GET SELECT :从服务器获取资源。
    POST CREATE :在服务器新建资源。
    PUT UPDATE :在服务器更新资源。
    DELETE DELETE :从服务器删除资源。
    示例:
    获取指定商品的信息
    GET http://www.example.com/goods/ID
    新建商品的信息
    POST http://www.example.com/goods
    更新指定商品的信息
    PUT http://www.example.com/goods/ID
    删除指定商品的信息
    DELETE http://www.example.com/goods/ID
    五、过滤信息:
    如果资源数据较多,服务器不能将所有数据一次全部返回给客户端。API应该提供参数,过滤返回结果。 实例:
    指定返回数据的数量
    http://www.example.com/goods?limit=10
    指定返回数据的开始位置
    http://www.example.com/goods?offset=10
    指定第几页,以及每页数据的数量
    http://www.example.com/goods?page=2&per_page=20
    六、状态码:
    服务器向用户返回的状态码和提示信息,常用的有:
    200 OK :服务器成功返回用户请求的数据
    201 CREATED :用户新建或修改数据成功。
    202 Accepted:表示请求已进入后台排队。
    400 INVALID REQUEST :用户发出的请求有错误。
    401 Unauthorized :用户没有权限。
    403 Forbidden :访问被禁止。
    404 NOT FOUND :请求针对的是不存在的记录。
    406 Not Acceptable :用户请求的的格式不正确。
    500 INTERNAL SERVER ERROR :服务器发生错误。
    七、错误信息:
    一般来说,服务器返回的错误信息,以键值对的形式返回。

    { 
        error: ‘Invalid API KEY‘ 
    } 
    

    八、响应结果:
    针对不同结果,服务器向客户端返回的结果应符合以下规范。
    返回商品列表
    GET http://www.example.com/goods
    返回单个商品
    GET http://www.example.com/goods/cup
    返回新生成的商品
    POST http://www.example.com/goods
    返回一个空文档
    DELETE http://www.example.com/goods
    九、使用链接关联相关的资源:
    在返回响应结果时提供链接其他API的方法,使客户端很方便的获取相关联的信息。
    十、其他:
    服务器返回的数据格式,应该尽量使用JSON,避免使用XML。

  9. Celery分布式任务队列?

    情景:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等。 使用celery后,情况就不一样了。解决:将耗时的程序放到celery中执行。将多个耗时的任务添加到队列queue中,也就是用redis实现broker中间人,然后用多个worker去监听队列 里的任务去执行。
    技术图片

    • 任务task:就是一个Python函数。
    • 队列queue:将需要执行的任务加入到队列中。
    • 工人worker:在一个新进程中,负责执行队列中的任务。
    • 代理人broker:负责调度,在布置环境中使用redis。
      正向代理:请求经过代理服务器从局域网发出,然后到达互联网上的服务器。
      特点:服务端并不知道真正的客户端是谁。
      反向代理:请求从互联网发出,先进入代理服务器,再转发给局域网内的服务器。
      特点:客户端并不知道真正的服务端是谁。
      区别:正向代理的对象是客户端。反向代理的对象是服务端。
  10. 对cookie与session的了解?他们能单独用吗?

    首先需要搞清楚的是session是存储在服务器上的,cookie是存储在客户端浏览器上的两者是相辅相成的用户首次访问服务器,服务器会为每个用户单独创建一个session对象(HttpSession),
    并为每个session分配唯一一个id(sessionId),sessionId通过cookie保存到用户端,当用户再次访问服务器时,需将对应的sessionId携带给服务器,服务器通过这个唯一sessionId就可以找到用户对应的session对象,从而达到管理用户状态

  11. django 中当一个用户登录 A 应用服务器(进入登录状态),然后下次请求被 nginx 代理到 B 应用服务器会出现什么影响?

    如果用户在A应用服务器登陆的session数据没有共享到B应用服务器,那么之前的登录状态就没有了。

    1.安装django-cors-headers,之后在settings.py中配置

    pip install django-cors-headers
    INSTALLED_APPS = [
     ...
     ‘corsheaders‘,
     ...
     ] 
     
    MIDDLEWARE_CLASSES = (
     ...
     ‘corsheaders.middleware.CorsMiddleware‘,
     ‘django.middleware.common.CommonMiddleware‘, # 注意顺序
     ...
    )
    #跨域增加忽略
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = (
     ‘*‘
    )
     
    CORS_ALLOW_METHODS = (
     ‘DELETE‘,
     ‘GET‘,
     ‘OPTIONS‘,
     ‘PATCH‘,
     ‘POST‘,
     ‘PUT‘,
     ‘VIEW‘,
    )
     
    CORS_ALLOW_HEADERS = (
     ‘XMLHttpRequest‘,
     ‘X_FILENAME‘,
     ‘accept-encoding‘,
     ‘authorization‘,
     ‘content-type‘,
     ‘dnt‘,
     ‘origin‘,
     ‘user-agent‘,
     ‘x-csrftoken‘,
     ‘x-requested-with‘,
     ‘Pragma‘,
    )
    

    2.使用JSONP
    使用Ajax获取json数据时,存在跨域的限制。不过,在Web页面上调用js的script脚本文件时却不受跨域的影响,JSONP就是利用这个来实现跨域的传输。因此,我们需要将Ajax调用中的dataType从JSON改为JSONP(相应的API也需要支持JSONP)格式。
    JSONP只能用于GET请求。
    3.直接修改Django中的views.py文件
    修改views.py中对应API的实现函数,允许其他域通过Ajax请求数据:

    def myview(_request):
    	response = HttpResponse(json.dumps({“key”: “value”, “key2”: “value”}))
    	response[“Access-Control-Allow-Origin”] = “*”
    	response[“Access-Control-Allow-Methods”] = “POST, GET, OPTIONS”
    	response[“Access-Control-Max-Age”] = “1000”
    	response[“Access-Control-Allow-Headers”] = “*”
    return response
    
  12. git中 .gitignore文件的作用?

    在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件)。这个文件每一行保存了一个匹配的规则例如:

    # 此为注释 – 将被 Git 忽略
    *.a       # 忽略所有 .a 结尾的文件
    !lib.a    # 但 lib.a 除外
    /TODO     # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
    build/    # 忽略 build/ 目录下的所有文件
    doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
    
  13. 列举常见的状态码。

    状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
    
    1xx:指示信息--表示请求已接收,继续处理
    2xx:成功--表示请求已被成功接收、理解、接受
    3xx:重定向--要完成请求必须进行更进一步的操作
    4xx:客户端错误--请求有语法错误或请求无法实现
    5xx:服务器端错误--服务器未能实现合法的请求
    常见状态码:
    
    200 OK                        //客户端请求成功
    400 Bad Request               //客户端请求有语法错误,不能被服务器所理解
    401 Unauthorized              //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 
    403 Forbidden                 //服务器收到请求,但是拒绝提供服务
    404 Not Found                 //请求资源不存在,eg:输入了错误的URL
    500 Internal Server Error     //服务器发生不可预期的错误
    503 Server Unavailable        //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
    更多状态码http://www.runoob.com/http/http-status-codes.html
    
  14. http 和 https 的区别?

    http的中文叫做超文本传输协议,它负责完成客户端到服务端的一系列操作,是专门用来传输注入HTML的超媒体文档等web内容的协议,它是基于传输层的TCP协议的应用层协议
    
    https:https是基于安全套接字的http协议,也可以理解为是http+ssl/tls(数字证书)的组合
    
    http和https的区别:
    
    HTTP 的 URL 以 http:// 开头,而 HTTPS 的 URL 以 https:// 开头
    HTTP 是不安全的,而 HTTPS 是安全的
    HTTP 标准端口是 80 ,而 HTTPS 的标准端口是 443
    在 OSI 网络模型中,HTTPS的加密是在传输层完成的,因为SSL是位于传输层的,TLS的前身是SSL,所以同理
    HTTP无需认证证书,而https需要认证证书  
    
  15. Python web 开发中, 跨域问题的解决思路是?

    # 方案1.安装django-cors-headers
    pip install django-cors-header
    
    配置settings.py文件
     
    INSTALLED_APPS = [
        ...
        ‘corsheaders‘,
        ...
     ] 
    MIDDLEWARE_CLASSES = (
        ...
        ‘corsheaders.middleware.CorsMiddleware‘,
        ‘django.middleware.common.CommonMiddleware‘, # 注意顺序
        ...
    )
    #跨域增加忽略
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = (
        ‘*‘
    )
    CORS_ALLOW_METHODS = (
        ‘DELETE‘,
        ‘GET‘,
        ‘OPTIONS‘,
        ‘PATCH‘,
        ‘POST‘,
        ‘PUT‘,
        ‘VIEW‘,
    )
    CORS_ALLOW_HEADERS = (
        ‘XMLHttpRequest‘,
        ‘X_FILENAME‘,
        ‘accept-encoding‘,
        ‘authorization‘,
        ‘content-type‘,
        ‘dnt‘,
        ‘origin‘,
        ‘user-agent‘,
        ‘x-csrftoken‘,
        ‘x-requested-with‘,
        ‘Pragma‘,
    )
    
    # 方案2.使用JSONP
    使用Ajax获取json数据时,存在跨域的限制。不过,在Web页面上调用js的script脚本文件时却不受跨域的影响,JSONP就是利用这个来实现跨域的传输。因此,我们需要将Ajax调用中的dataType从JSON改为JSONP(相应的API也需要支持JSONP)格式。
    JSONP只能用于GET请求。
    
    # 方案3.直接修改Django中的views.py文件
    
    修改views.py中对应API的实现函数,允许其他域通过Ajax请求数据:
    def myview(_request):
      response = HttpResponse(json.dumps({“key”: “value”, “key2”: “value”}))
      response[“Access-Control-Allow-Origin”] = “*”
      response[“Access-Control-Allow-Methods”] = “POST, GET, OPTIONS”
      response[“Access-Control-Max-Age”] = “1000”
      response[“Access-Control-Allow-Headers”] = “*”
      return response
    
  16. django 请求的生命周期?

    . 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
    请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
    . url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
    一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
    . 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
    . 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
    
  17. django 中如何在 model 保存前做一定的固定操作,比如写一句日志?

    利用Django的Model的Signal Dispatcher,通过django.db.models.signals.pre_save()方法,在事件发生前,发射触发信号,这一切都被调度中的receiver方法深藏功与名的保存了。
    信号的处理一般都写在Model中,举个例子:

    import logging
    from django.db import models
    from django.db.models.signals import pre_save
    from django.dispatch import receiver
    class Order(models.Model):
    logger = logging.getLogger(__name__)
    @receiver(pre_save, sender=Order)
    def pre_save_handler(sender, **kwargs):
     logger.debug("{},{}".format(sender, **kwargs))
    
  18. django的request对象是在什么时候创建的?

    `class WSGIHandler(base.BaseHandler):`
    `-------request = self.request_class(environ)`
    请求走到WSGIHandler类的时候,执行**cell**方法,将environ封装成了request 
    
  19. 简述django中间件及其应用场景?

    .process_request : 请求进来时,权限认证
    .process_view : 路由匹配之后,能够得到视图函数
    .process_exception : 异常时执行
    .process_template_responseprocess : 模板渲染时执行
    .process_response : 请求有响应时执行
    
  20. 简述 django FBV 和 CBV?

    FBV和CBV本质是一样的,基于函数的视图叫做FBV,基于类的视图叫做CBV
    在python中使用CBV的优点:

    • .提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    • .可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
  21. 列举 django orm 中你了解的所有方法?

    # QuerySet对象的所有方法
     <1> all():                  查询所有结果 
     <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象。获取不到返回None
     <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个。
                                 如果符合筛选条件的对象超过一个或者没有都会抛出错误。
     <4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
     <5> order_by(*field):       对查询结果排序
     <6> reverse():              对查询结果反向排序 
     <8> count():                返回数据库中匹配查询(QuerySet)的对象数量。 
     <9> first():                返回第一条记录 
     <10> last():                返回最后一条记录 
     <11> exists():              如果QuerySet包含数据,就返回True,否则返回False
     <12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的
                                 并不是一系 model的实例化对象,而是一个可迭代的字典序列
     <13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
     <14> distinct():            从返回结果中剔除重复纪录
    
  22. django 中如何执行原生 SQL?

    1.使用execute执行自定义的SQL
         直接执行SQL语句(类似于pymysql的用法)
            # 更高灵活度的方式执行原生SQL语句
            from django.db import connection
            cursor = connection.cursor()
            cursor.execute("SELECT DATE_FORMAT(create_time, ‘%Y-%m‘) FROM blog_article;")
            ret = cursor.fetchall()
            print(ret)
    2.使用extra方法 :queryset.extra(select={"key": "原生的SQL语句"})
    3.使用raw方法
        1.执行原始sql并返回模型
        2.依赖model多用于查询
    

以上是关于Django面试题积累的主要内容,如果未能解决你的问题,请参考以下文章

javaio流面试题,积累总结

前端面试题之手写promise

Elasticsearches 面试题 积累

这些面试题你会怎么答?

面试题积累 ( 持续更新 )

模块设计模型前端面试题积累