web框架知识整理

编程知识 更新时间:2023-04-25 08:02:48

1.Django 创建项目的命令?

django-admin startproject 项目名称
python manage.py startapp 应用 app 名

2.Django 创建项目后,项目文件夹下的组成部分(对 mvt 的理解)?

项目文件夹下的组成部分:

manage.py  #是项目运行的入口,指定配置文件路径。与项目同名的目录,包含项目的配置文件。
___init.py #是一个空文件,作用是这个目录可以被当作包使用。
settings.py #是项目的整体配置文件。
urls.py #是项目的 URL 配置文件。
wsgi.py #是项目与 WSGI 兼容的 Web 服务器。

3.对 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 页面

M:Models:一个抽象层,用来构建和操作你的web应用中的数据,模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。

T:模板(templates):模板层提供了设计友好的语法来展示信息给用户。使用模板方法可以动态地生成HTML。模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。

V:视图(views):用于封装负责处理用户请求及返回响应的逻辑。视图可以看作是前端与数据库的中间人,他会将前端想要的数据从数据库中读出来给前端。他也会将用户要想保存的数据写到数据库。

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 页面内容进行解析,展示。

4.Django 中 models 利用 ORM 对 Mysql 进行查表的语句(多个语句)?

字段查询

all():返回模型类对应表格中的所有数据。
get():返回表格中满足条件的一条数据,如果查到多条数据,则抛异常:MultipleObjectsReturned,查询不到数据,则抛异常:DoesNotExist。
filter():参数写查询条件,返回满足条件 QuerySet 集合数据。
条件格式:
模型类属性名__条件名=值
注意:此处是模型类属性名,不是表中的字段名
关于 filter 具体案例如下:
判等 exact。

BookInfo.object.filter(id=1)
BookInfo.object.filter(id__exact=1)此处的__exact 可以省略

模糊查询 like

例:查询书名包含’传’的图书。contains

contains BookInfo.objects.filter(btitle__contains=’传’)

空查询 where 字段名 isnull

BookInfo.objects.filter(btitle__isnull=False)

范围查询 where id in (1,3,5)

BookInfo.objects.filter(id__in=[1,3,5])

比较查询 gt lt(less than) gte(equal) lte

BookInfo.objects.filter(id__gte=3)

日期查询

BookInfo.objects.filter(bpub_date__year = 1980)
BookInfo.objects.filter(bpub_date__gt = date(1980,1,1))

exclude:返回不满足条件的数据。

BookInfo.objects.exclude(id=3)

F 对象

作用:用于类属性之间的比较条件。

from django.db.models import F
#例:
where bread > bcomment BookInfo.objects.filter(bread__gt =F(‘bcomment’))
#例:
BookInfo.objects.filter(bread__gt=F(‘bcomment’)*2)

Q 对象

作用:用于查询时的逻辑条件。可以对 Q 对象进行&|~操作。

from django.db.models import Q
BookInfo.objects.filter(id__gt=3, bread__gt=30)
BooInfo.objects.filter(Q(id__gt=3) & Q(bread__gt=3))
#例:
BookInfo.objects.filter(Q(id__gt=3) | Q(bread__gt=30))
#例:
BookInfo.objects.filter(~Q(id=3))

order_by 返回 QuerySet

作用:对查询结果进行排序。

BookInfo.objects.all().order_by('id')
BookInfo.objects.all().order_by('-id')
BookInfo.objects.filter(id__gt=3).order_by('-bread')

聚合函数

作用:对查询结果进行聚合操作。

sum count max min avg

aggregate:调用这个函数来使用聚合。

from django.db.models import Sum,Count,Max,Min,Avg
BookInfo.objects.aggregate(Count('id'))

{‘id__count’: 5} 注意返回值类型及键名

BookInfo.objects.aggregate(Sum(‘bread’))

{‘bread__sum’:120} 注意返回值类型及键名

count 函数

作用:统计满足条件数据的数目。
例:统计所有图书的数目。

BookInfo.objects.all().count()

例:统计 id 大于 3 的所有图书的数目。

BookInfo.objects.filter(id__gt = 3).count()

模型类关系

1)一对多关系
例:图书类-英雄类
models.ForeignKey() 定义在多的类中。
2)多对多关系
例:新闻类-新闻类型类
models.ManyToManyField() 定义在哪个类中都可以。
3)一对一关系
例:员工基本信息类-员工详细信息类
models.OneToOneField() 定义在哪个类中都可以。

5.django 中间件的使用?

Django 在中间件中预置了六个方法,这六个方法的区别在于不同的阶段执行,对输入或输出进行干预,方法如下:
1.初始化:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件。

def __init__():
	pass

2.处理请求前:在每个请求上调用,返回 None 或 HttpResponse 对象。

def process_request(request):
	pass

3.处理视图前:在每个请求上调用,返回 None 或 HttpResponse 对象。

def process_view(request, view_func, view_args, view_kwargs):
	pass

4.处理模板响应前:在每个请求上调用,返回实现了 render 方法的响应对象。

def process_template_response(request, response):
	pass

5.处理响应后:所有响应返回浏览器之前被调用,在每个请求上调用,返回 HttpResponse 对象。

def process_response(request, response):
	pass

6.异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个 HttpResponse 对象。

def process_exception(request,exception):
	pass

6.谈一下你对 uWSGI 和 nginx 的理解?

1.uWSGI 是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http 等协议。Nginx 中HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。WSGI 是一种 Web 服务器网关接口。它是一个 Web 服务器(如 nginx,uWSGI 等服务器)与 web 应用(如用 Flask 框架写的程序)通信的一种规范。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
WSGI 是一种通信协议。
uwsgi 是一种线路协议而不是通信协议,在此常用于在 uWSGI 服务器与其他网络服务器的数据通信。
uWSGI 是实现了 uwsgi 和 WSGI 两种协议的 Web 服务器。

uWSGI 具有超快的性能、低内存占用和多 app 管理等优点,并且搭配着Nginx 就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署 。相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。

nginx 具备优秀的静态内容处理能力,然后将动态内容转发给 uWSGI 服务器,这样可以达到很好的客户端响应。

uwsgi 的参数:
-M 开启 Master 进程
-p 4 开启 4 个进程
-s 使用的端口或者 socket 地址
-d 使用 daemon 的方式运行, 注意, 使用-d 后, 需要加上 log 文件地址,比如-d /var/log/uwsgi.log
-R 10000 开启 10000 个进程后, 自动 respawn(复位)下
-t 30 设置 30s 的超时时间, 超时后, 自动放弃该链接
–limit-as 32 将进程的总内存量控制在 32M
-x 使用配置文件模式

2.nginx 是一个开源的高性能的 HTTP 服务器和反向代理:
1).作为 web 服务器,它处理静态文件和索引文件效果非常高;

2).它的设计非常注重效率,最大支持 5 万个并发连接,但只占用很少的内存空间;
3).稳定性高,配置简洁;
4).强大的反向代理和负载均衡功能,平衡集群中各个服务器的负载压力应用。

7.说说 nginx 和 uWISG 服务器之间如何配合工作的?

首先浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型,如果是静态资源,直接读取静态资源返回给浏览器,如果请求的是动态资源就转交给 uwsgi服务器,uwsgi 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 Django 框架,Django 框架下的应用进行逻辑处理后,将返回值发送到 uwsgi 服务器,然后 uwsgi 服务器再返回给 nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户。
如果可以,画图讲解效果更佳,可以 将下面的图画给面试官。

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

1.设计表时,尽量少使用外键,因为外键约束会影响插入和删除性能;

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

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

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

10.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 服务的一个 理想框架。

11.django 如何提升性能(高并发)?

对一个后端开发程序员来说,提升性能指标主要有两个一个是并发数,另一个是响应时间网站性能的优化一般包括 web 前端性能优化,应用服务器性能优化,存储服务器优化。
对前端的优化主要有:
1.减少 http 请求,减少数据库的访问量,比如使用雪碧图。
2.使用浏览器缓存,将一些常用的 css,js,logo 图标,这些静态资源缓存到本地浏览器,通过设置 http 头中的 cache-control 和 expires 的属性,可设定浏览器缓存,缓存时间可以自定义。
3 对 html,css,javascript 文件进行压缩,减少网络的通信量。
对我个人而言,我做的优化主要是以下三个方面:
1.合理的使用缓存技术,对一些常用到的动态数据,比如首页做一个缓存,或者某些常用的数据做个缓存,设置一定得过期时间,这样减少了对数据库的压力,提升网站性能。
2.使用 celery 消息队列,将耗时的操作扔到队列里,让 worker 去监听队列里的任务,实现异步操作,比如发邮件,发短信。

3.就是代码上的一些优化,补充:nginx 部署项目也是项目优化,可以配置合适的配置参数,提升效率,增加并发量。
4.如果太多考虑安全因素,服务器磁盘用固态硬盘读写,远远大于机械硬盘,这个技术现在没有普及,主要是固态硬盘技术上还不是完全成熟, 相信以后会大量普及。
5.另外还可以搭建服务器集群,将并发访问请求,分散到多台服务器上处理。
6.最后就是运维工作人员的一些性能优化技术了。

12.什么是 restful api,谈谈你的理解?

REST:Representational State Transfer 的缩写,翻译:“具象状态传输”。一般解释为“表现层状态转换”。
REST 是设计风格而不是标准。是指客户端和服务器的交互形式。我们需要关注的重点是如何设计
REST 风格的网络接口。
REST 的特点:
1.具象的。一般指表现层,要表现的对象就是资源。比如,客户端访问服务器,获取的数据就是资源。比如文字、图片、音视频等。
2.表现:资源的表现形式。txt 格式、html 格式、json 格式、jpg 格式等。浏览器通过 URL 确定资源的位置,但是需要在 HTTP 请求头中,用 Accept 和 Content-Type 字段指定,这两个字段是对资源表现的描述。
3.状态转换:客户端和服务器交互的过程。在这个过程中,一定会有数据和状态的转化,这种转化叫做状态转换。其中,GET 表示获取资源,POST 表示新建资源,PUT 表示更新资源,DELETE 表示删除资源。HTTP 协议中最常用的就是这四种操作方式。
RESTful 架构:

​ 1.每个 URL 代表一种资源;
​ 2.客户端和服务器之间,传递这种资源的某种表现层;
​ 3.客户端通过四个 http 动词,对服务器资源进行操作,实现表现层状态转换。

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

一、域名:

将 api 部署在专用域名下:
http://api.example
或者将 api 放在主域名下:
http://www.example/api/

二、版本:

将 API 的版本号放在 url 中。
http://www.example/app/1.0/info
http://www.example/app/1.2/info

三、路径:

路径表示 API 的具体网址。每个网址代表一种资源。 资源作为网址,网址中不能有动词只能有
名词,一般名词要与数据库的表名对应。而且名词要使用复数。
错误示例:
http://www.example/getGoods
http://www.example/listOrders
正确示例:
#获取单个商品

http://www.example/app/goods/1
#获取所有商品
http://www.example/app/goods

四、使用标准的 HTTP 方法:

对于资源的具体操作类型,由 HTTP 动词表示。 常用的 HTTP 动词有四个。
GET SELECT :从服务器获取资源。
POST CREATE :在服务器新建资源。
PUT UPDATE :在服务器更新资源。
DELETE DELETE :从服务器删除资源。
示例:
#获取指定商品的信息
GET http://www.example/goods/ID
#新建商品的信息
POST http://www.example/goods
#更新指定商品的信息
PUT http://www.example/goods/ID
#删除指定商品的信息
DELETE http://www.example/goods/ID

五、过滤信息:

如果资源数据较多,服务器不能将所有数据一次全部返回给客户端。API 应该提供参数,过滤返
回结果。 实例:
#指定返回数据的数量

http://www.example/goods?limit=10
#指定返回数据的开始位置
http://www.example/goods?offset=10
#指定第几页,以及每页数据的数量
http://www.example/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/goods
#返回单个商品
GET http://www.example/goods/cup
#返回新生成的商品
POST http://www.example/goods
#返回一个空文档
DELETE http://www.example/goods

九、使用链接关联相关的资源:

在返回响应结果时提供链接其他 API 的方法,使客户端很方便的获取相关联的信息。

十、其他:

服务器返回的数据格式,应该尽量使用 JSON,避免使用 XML。

14.什么 csrf 攻击原理?如何解决?

简单来说就是: 你访问了信任网站 A,然后 A 会用保存你的个人信息并返回给你的浏览器一个cookie,然后呢,在 cookie 的过期时间之内,你去访问了恶意网站 B,它给你返回一些恶意请求代码,要求你去访问网站 A,而你的浏览器在收到这个恶意请求之后,在你不知情的情况下,会带上保存在本地浏览器的 cookie 信息去访问网站 A,然后网站 A 误以为是用户本身的操作,导致来自恶意网站 C 的攻击代码会被执:发邮件,发消息,修改你的密码,购物,转账,偷窥你的个人信息,导致私人信息泄漏和账户财产安全收到威胁

防御 CSRF 的几种策略

目前防御 CSRF 攻击主要有三种策略:

验证 HTTP Referer 字段
在请求地址中添加 token 并验证
在 HTTP 头中自定义属性并验证

验证 HTTP Referer 字段

​ 根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。

​ 比如,访问 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ,用户必须先登陆 bank.example,然后通过点击页面上的按钮来触发转账事件。这时,该转帐请求的 Referer 的值就会是转账按钮所在的页面的 URL,通常是以 bank.example 域名开头的地址。而如果黑客要对银行网站实施 CSRF 攻击,他只能在他自己的网站构造请求,当用户通过黑客的网站发送请求到银行网站时,该请求的 Referer 是指向黑客自己的网站。

​ 因此,要防御 CSRF 攻击,银行网站只需要对转账请求验证其 Referer 值,如果是以 bank.example 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。

​ 这种方法的好处就是简单易行,只需要在最后给所有敏感的请求统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。然而,这种方法并非万无一失。
缺陷

​ 首先,Referer 的值是由浏览器提供的,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。验证 Referer 的值,就是把安全性都依赖于浏览器来保障,这样并不安全。对于某些浏览器,已经有一些方法可以篡改 Referer 的值。黑客完全可以把用户浏览器的 Referer 值设为以 bank.example 域名开头的地址,这样就可以通过验证,从而进行 CSRF 攻击。

​ 其次,即便黑客无法篡改 Referer 值,这种方法仍然有问题。因为 Referer 值会记录下用户的访问来源,有些用户认为这样会侵犯隐私,便会设置浏览器使其在发送请求时不再提供 Referer。那么,服务器端的 Referer 验证也就没有意义了。

在请求地址中添加 token 并验证

​ CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户的 cookie 来通过安全验证。

​ 要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

​ 这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对。

对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue 。

而对于 POST 请求,要在 form 表单加上:

<input type="hidden" name="csrftoken" value="tokenvalue"/>

​ 该方法也有一个缺点是难以保证 token 本身的安全。因为即使是 POST 请求的 token,黑客的网站也同样可以通过 Referer 的值来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。如果想保证 token 本身的安全,可以考虑使用动态 token,也就是每次请求都使用不同的动态 token。

在 HTTP 头中自定义属性并验证

​ 这种方法也是使用 token 进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 对象,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。然而,这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 对页面局部的异步刷新。并非所有的请求都适合用 Ajax 来发起,而且通过该类请求得到的页面不能被浏览器所记录,影响前进、后退、刷新、收藏等操作,给用户带来了不便。

​ 另外,对于没有进行 CSRF 防护的旧系统来说,如果采用这种方法来进行防护,需要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,工作量无疑是巨大的。

原文链接:https://blog.csdn/lamp_yang_3533/article/details/79959071

15.启动 Django 服务的方法?

runserver 方法是调试 Django 时经常用到的运行方式,它使用 Django 自带的 WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。

16.怎样测试 django 框架中的代码?

在单元测试方面,Django 继承 python 的 unittest.TestCase 实现了自己的django.test.TestCase,编写测试用例通常从这里开始。测试代码通常位于 app 的 tests.py 文件中(也可以在 models.py 中编写,一般不建议)。在 Django 生成的 depotapp 中,已经包含了这个文件,并且其中包含了一个测试用例的样例:

python manage.py test   #执行所有的测试用例
python manage.py test app_name, #执行该 app 的所有测试用例
python manage.py test app_name.case_name: #执行指定的测试用例

一些测试工具:unittest 或者 pytest

对Python的Django框架中的项目进行单元测试的方法:https://www.jb51/article/82238.html

17.Django 中哪里用到了线程?哪里用到了协程?哪里用到了进程?

1.Django 中耗时的任务用一个进程或者线程来执行,比如发邮件,使用 celery。
2.部署 django 项目的时候,配置文件中设置了进程和协程的相关配置。

18.django 关闭浏览器,怎样清除 cookies 和 session?

设置 Cookie

def cookie_set(request):
	response = HttpResponse("<h1>设置 Cookie,请查看响应报文头</h1>")
	response.set_cookie('h1', 'hello django')
	return response

读取 Cookie

def cookie_get(request):
	response = HttpResponse("读取 Cookie,数据如下:<br>")
	if request.COOKIES.has_key('h1'):
		response.write('<h1>' + request.COOKIES['h1'] + '</h1>')
	return response

以键值对的格式写会话。

request.session['键']=

根据键读取值。

request.session.get('键',默认值)

清除所有会话,在存储中删除值部分。

request.session.clear()

清除会话数据,在存储中删除会话的整条数据。

request.session.flush()

删除会话中的指定键及值,在存储中只删除某个键及对应的值。

del request.session['键']

设置会话的超时时间,如果没有指定过期时间则两个星期后过期。
如果 value 是一个整数,会话将在 value 秒没有活动后过期。
如果 value 为 0,那么用户会话的 Cookie 将在用户的浏览器关闭时过期。
如果 value 为 None,那么会话永不过期。

request.session.set_expiry(value)

​ Session 依赖于 Cookie,如果浏览器不能保存 cookie 那么 session 就失效了。因为它需要浏览器的 cookie 值去 session 里做对比。session 就是用来在服务器端保存用户的会话状态。
​ cookie 可以有过期时间,这样浏览器就知道什么时候可以删除 cookie 了。 如果 cookie 没有设置过期时间,当用户关闭浏览器的时候,cookie 就自动过期了。你可以改变SESSION_EXPIRE_AT_BROWSER_CLOSE 的设置来控制 session 框架的这一行为。缺省情况下,SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 False ,这样,会话 cookie 可以在用户浏览器中保持有效达 SESSION_COOKIE_AGE 秒(缺省设置是两周,即 1,209,600 秒)如果你不想用户每次打开浏览器都必须重新登陆的话,用这个参数来帮你。如果 SESSION_EXPIRE_AT_BROWSER_CLOSE设置为 True,当浏览器关闭时,Django 会使 cookie 失效。
SESSION_COOKIE_AGE:设置 cookie 在浏览器中存活的时间。

19.代码优化从哪些方面考虑?有什么想法?

1、优化算法时间

算法的时间复杂度对程序的执行效率影响最大,在 Python 中可以通过选择合适的数据结构来优化时间复杂度,如 list 和 set 查找某一个元素的时间复杂度分别是 O(n)和 O(1)。不同的场景有不同的优化方式,总得来说,一般有分治,分支界限,贪心,动态规划等思想。

2、循环优化

每种编程语言都会强调需要优化循环。当使用 Python 的时候,你可以依靠大量的技巧使得循环运行得更快。然而,开发者经常漏掉的一个方法是:避免在一个循环中使用点操作。每一次你调用方法 str.upper,Python 都会求该方法的值。然而,如果你用一个变量代替求得的值,值就变成了已知的,Python 就可以更快地执行任务。优化循环的关键,是要减少 Python 在循环内部执行的工作量,因为 Python 原生的解释器在那种情况下,真的会减缓执行的速度。(注意:优化循环的方法有很多,这只是其中的一个。例如,许多程序员都会说,列表推导是在循环中提高执行速度的最好方式。这里的关键是,优化循环是程序取得更高的执行速度的更好方式之一。)

3、函数选择

在循环的时候使用 xrange 而不是 range;使用 xrange 可以节省大量的系统内存,因为 xrange()在序列中每次调用只产生一个整数元素。而 range()將直接返回完整的元素列表,用于循环时会有不必要的开销。在 python3 中 xrange 不再存在,里面 range 提供一个可以遍历任意长度的范围的iterator。

4、并行编程

因为 GIL 的存在,Python 很难充分利用多核 CPU 的优势。但是,可以通过内置的模块multiprocessing 实现下面几种并行模式:
多进程:对于 CPU 密集型的程序,可以使用 multiprocessing 的 Process,Pool 等封装好的类,通过多进程的方式实现并行计算。但是因为进程中的通信成本比较大,对于进程之间需要大量数据交互的程序效率未必有大的提高。
多线程:对于 IO 密集型的程序,multiprocessing.dummy 模块使用 multiprocessing 的接口封装 threading,使得多线程编程也变得非常轻松(比如可以使用 Pool 的 map 接口,简洁高效)。
分布式:multiprocessing 中的 Managers 类提供了可以在不同进程之共享数据的方式,可以在此基础上开发出分布式的程序。
不同的业务场景可以选择其中的一种或几种的组合实现程序性能的优化。

5、使用性能分析工具

除了上面在 ipython 使用到的 timeit 模块,还有 cProfile。cProfile 的使用方式也非常简单:
python-mcProfilefilename.py,filename.py 是要运行程序的文件名,可以在标准输出中看到每一个函数被调用的次数和运行的时间,从而找到程序的性能瓶颈,然后可以有针对性地优化。

6、set 的用法

set 的 union,intersection,difference 操作要比 list 的迭代要快。因此如果涉及到求 list 交集,并集或者差的问题可以转换为 set 来操作。

7、PyPy

PyPy 是用 RPython(CPython 的子集)实现的 Python,根据官网的基准测试数据,它比 CPython实现的 Python 要快 6 倍以上。快的原因是使用了 Just-in-Time(JIT)编译器,即动态编译器,与静态编译器(如 gcc,javac 等)不同,它是利用程序运行的过程的数据进行优化。由于历史原因,目前 pypy中还保留着 GIL,不过正在进行的 STM 项目试图将 PyPy 变成没有 GIL 的 Python。如果 python程序中含有 C 扩展(非 cffi 的方式),JIT 的优化效果会大打折扣,甚至比 CPython 慢(比 Numpy)。所以在 PyPy 中最好用纯 Python 或使用 cffi 扩展。

20.Django 中间件是如何使用的?

中间件不用继承自任何类(可以继承 object),下面一个中间件大概的样子:

class CommonMiddleware(object):
	def process_request(self, request):
		return None
	def process_response(self, request, response):
		return response

还有 process_view, process_exception 和 process_template_response 函数。
1)初始化:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件。

def __init__(self):
	pass

2)处理请求前:在每个请求上,request 对象产生之后,url 匹配之前调用,返回 None 或HttpResponse 对象。

def process_request(self, request):
	pass

3)处理视图前:在每个请求上,url 匹配之后,视图函数调用之前调用,返回 None 或HttpResponse 对象。

def process_view(self, request, view_func, *view_args,**view_kwargs):
	pass

4)处理响应后:视图函数调用之后,所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse 对象。

def process_response(self, request, response):
	pass

5)异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个 HttpResponse 对象。

def process_exception(self, request,exception):
	pass

21.有用过 Django REST framework 吗?

Django REST framework 是一个强大而灵活的 Web API 工具。使用 RESTframework 的理由有:
Web browsable API 对开发者有极大的好处
包括 OAuth1a 和 OAuth2 的认证策略
支持 ORM 和非 ORM 数据资源的序列化
全程自定义开发——如果不想使用更加强大的功能,可仅仅使用常规的 function-based views
额外的文档和强大的社区支持

22.Celery 分布式任务队列?

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

任务 task:就是一个 Python 函数。
队列 queue:将需要执行的任务加入到队列中。
工人 worker:在一个新进程中,负责执行队列中的任务。
代理人 broker:负责调度,在布置环境中使用 redis。

23…Jieba 分词

Jieba 分词支持三种分词模式:
精确模式:试图将句子最精确地切开,适合文本分析;
全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
功能:
分词,添加自定义词典,关键词提取,词性标注,并行分词,Tokenize:返回词语在原文的起始位置,ChineseAnalyzer for Whoosh 搜索引擎。

24.ngnix 的正向代理与反向代理?

web 开发中,部署方式大致类似。简单来说,使用 Nginx 主要是为了实现分流、转发、负载均衡,以及分担服务器的压力。Nginx 部署简单,内存消耗少,成本低。Nginx 既可以做正向代理,也可以做反向代理。

正向代理:请求经过代理服务器从局域网发出,然后到达互联网上的服务器。
特点:服务端并不知道真正的客户端是谁。
反向代理:请求从互联网发出,先进入代理服务器,再转发给局域网内的服务器。
特点:客户端并不知道真正的服务端是谁。
区别:正向代理的对象是客户端。反向代理的对象是服务端。

25.简述 Django 下的(内建的)缓存机制?

​ 一个动态网站的基本权衡点就是,它是动态的。 每次用户请求页面,服务器会重新计算。从开销处理的角度来看,这比你读取一个现成的标准文件的代价要昂贵的多。
​ 这就是需要缓存的地方。
​ Django 自带了一个健壮的缓存系统来保存动态页面这样避免对于每次请求都重新计算。方便起见,Django 提供了不同级别的缓存粒度:可以缓存特定视图的输出、可以仅仅缓存那些很难生产出来的部分、或者可以缓存整个网站 Django 也能很好的配合那些“下游”缓存, 比如 Squid 和基于浏览器的缓存。这里有一些缓存不必要直接去控制但是可以提供线索, (via HTTPheaders)关于网站哪些部分需要缓存和如何缓存。
设置缓存:
​ 缓存系统需要一些设置才能使用。 也就是说,你必须告诉他你要把数据缓存在哪里- 是数据库中,文件系统或者直接在内存中。 这个决定很重要,因为它会影响你的缓存性能,是的,一些缓存类型要比其他的缓存类型更快速。
​ 你的缓存配置是通过 setting 文件的 CACHES 配置来实现的。 这里有 CACHES 所有可配置的变量值。

django官方文档缓存:https://yiyibooks/xx/django_182/topics/cache.html

26.请简述浏览器是如何获取一枚网页的?

1.在用户输入目的 URL 后,浏览器先向 DNS 服务器发起域名解析请求;
2.在获取了对应的 IP 后向服务器发送请求数据包;
3.服务器接收到请求数据后查询服务器上对应的页面,并将找到的页面代码回复给客户端;
4.客户端接收到页面源代码后,检查页面代码中引用的其他资源,并再次向服务器请求该资源;
5.在资源接收完成后,客户端浏览器按照页面代码将页面渲染输出显示在显示器上;

27.对 cookie 与 session 的了解?他们能单独用吗?

​ Session 采用的是在服务器端保持状态的方案,而 Cookie 采用的是在客户端保持状态的方案。但是禁用 Cookie 就不能得到 Session。因为 Session 是用 Session ID 来确定当前对话所对应的服务器 Session,而 Session ID 是通过 Cookie 来传递的,禁用 Cookie 相当于失去了 SessionID,也就得不到 Session。

28.Django HTTP 请求的处理流程?

Django 和其他 Web 框架的 HTTP 处理的流程大致相同,Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的。我们可以在 Middleware 这个地方把所有Request 拦截住,用我们自己的方式完成处理以后直接返回 Response。

1.加载配置

Django 的配置都在 “Project/settings.py” 中定义,可以是 Django 的配置,也可以是自定义的配置,并且都通过 django.conf.settings 访问,非常方便。

2.启动

最核心动作的是通过 django.core.managementmands.runfcgi 的 Command 来启动,它运行 django.core.servers.fastcgi 中的 runfastcgi,runfastcgi 使用了 flup 的 WSGIServer 来启动 fastcgi 。而 WSGIServer 中携带了 django.core.handlers.wsgi 的 WSGIHandler 类的一个实例,通过 WSGIHandler 来处理由 Web 服务器(比如 Apache,Lighttpd 等)传过来的请求,此时才是真正进入 Django 的世界。

3.处理 Request

当有 HTTP 请求来时,WSGIHandler 就开始工作了,它从 BaseHandler 继承而来。WSGIHandler 为每个请求创建一个 WSGIRequest 实例,而 WSGIRequest 是从http.HttpRequest 继承而来。接下来就开始创建 Response 了。

4.创建 Response

BaseHandler 的 get_response 方法就是根据 request 创建 response,而具体生成response 的动作就是执行 urls.py 中对应的 view 函数了,这也是 Django 可以处理“友好 URL ”的关键步骤,每个这样的函数都要返回一个 Response 实例。此时一般的做法是通过 loader 加载template 并生成页面内容,其中重要的就是通过 ORM 技术从数据库中取出数据,并渲染到Template 中,从而生成具体的页面了。

5.处理 Response

Django 返回 Response 给 flup,flup 就取出 Response 的内容返回给 Web 服务器,由后者返回给浏览器。
总之,Django 在 fastcgi 中主要做了两件事:处理 Request 和创建 Response,而它们对应的核心就是“ urls 分析”、“模板技术”和“ ORM 技术”。

如图所示,一个 HTTP 请求,首先被转化成一个 HttpRequest 对象,然后该对象被传递给Request 中间件处理,如果该中间件返回了 Response,则直接传递给 Response 中间件做收尾处理。否则的话 Request 中间件将访问 URL 配置,确定哪个 view 来处理,在确定了哪个 view 要执行,但是还没有执行该 view 的时候,系统会把 request 传递给view 中间件处理器进行处理,如果该中间件返回了 Response,那么该 Response 直接被传递给 Response 中间件进行后续处理,否则将执行确定的 view 函数处理并返回 Response,在这个过程中如果引发了异常并抛出,会被 Exception
中间件处理器进行处理。

29.Django 里 QuerySet 的 get 和 filter 方法的区别?

  1. 输入参数
    get 的参数只能是 model 中定义的那些字段,只支持严格匹配。
    filter 的参数可以是字段,也可以是扩展的 where 查询关键字,如 in,like 等。
  2. 返回值
    get 返回值是一个定义的 model 对象。
    filter 返回值是一个新的 QuerySet 对象,然后可以对 QuerySet 在进行查询返回新的 QuerySet对象,支持链式操作,QuerySet 一个集合对象,可使用迭代或者遍历,切片等,但是不等于 list 类型(使用一定要注意)。
  3. 异常
    get 只有一条记录返回的时候才正常,也就说明 get 的查询字段必须是主键或者唯一约束的字段。当返回多条记录或者是没有找到记录的时候都会抛出异常filter 有没有匹配的记录都可以

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

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

31.跨域请求问题 django 怎么解决的(原理)

启用中间件
post 请求
验证码
表单中添加 csrf_token 标签

32.Django 对数据查询结果排序怎么做,降序怎么做,查询大于某个字段怎么做?

排序使用 order_by()
降序需要在排序字段名前加-
查询字段大于某个值:使用 filter(字段名_gt=值)

33.Django 重定向你是如何实现的?用的什么状态码?

使用 HttpResponseRedirect
redirect 和 reverse
状态码:302,301

34.生成迁移文件和执行迁移文件的命令是什么?

python manage.py makemigrations
python manage.py migrate

35.关系型数据库的关系包括哪些类型?

ForeignKey:一对多,将字段定义在多的一端中。
ManyToManyField:多对对:将字段定义在两端中。
OneToOneField:一对一,将字段定义在任意一端中。

36.查询集返回列表的过滤器有哪些?

all() :返回所有的数据
filter():返回满足条件的数据
exclude():返回满足条件之外的数据,相当于 sql 语句中 where 部分的 not 关键字
order_by():排序

37.判断查询集正是否有数据?

exists():判断查询集中否有数据,如果有则返回 True,没有则返回 False。

38.Django 本身提供了 runserver,为什么不能用来部署?

runserver 方法是调试 Django 时经常用到的运行方式,它使用 Django 自带的 WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。

uWSGI 是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http 等协议。注意 uwsgi 是一种通信协议,而 uWSGI 是实现 uwsgi 协议和 WSGI 协议的 Web 服务器。uWSGI 具有超快的性能、低内存占用和多 app 管理等优点,并且搭配着 Nginx 就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署。相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。

39.apache 和 nginx 的区别?

Nginx 相对 Apache 的优点:
轻量级,同样起 web 服务,比 apache 占用更少的内存及资源;
抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而 apache 则是阻塞型的,在高并发下 nginx 能保持低资源低消耗高性能;
配置简洁;
高度模块化的设计,编写模块相对简单;
社区活跃。
Apache 相对 Nginx 的优点:
rewrite ,比 nginx 的 rewrite 强大;
模块超多,基本想到的都可以找到;
少 bug ,nginx 的 bug 相对较多;
超稳定。

40.varchar 与 char 的区别?

har 长度是固定的,不管你存储的数据是多少他都会都固定的长度。而 varchar 则处可变长度但他要在总长度上加 1 字符,这个用来存储位置。所以在处理速度上 char 要比 varchar 快速很多,但是对费存储空间,所以对存储不大,但在速度上有要求的可以使用 char 类型,反之可以用 varchar 类型。

41.查询集两大特性?惰性执行?

惰性执行、缓存 。
创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、
与 if 合用

42.git 常用命令?

git clone 克隆指定仓库
git status 查看当前仓库状态
git diff 比较版本的区别
git log 查看 git 操作日志
git reset 回溯历史版本
git add 将文件添加到暂存区
git commit 将文件提交到服务器
git checkout 切换到指定分支
git rm 删除指定文件

43.电商网站库存问题

一般团购,秒杀,特价之类的活动,这样会使访问量激增,很多人抢购一个商品,作为活动商品,库存肯定是很有限的。控制库存问题,数据库的事务功能是控制库存超卖的有效方式。
1.在秒杀的情况下,肯定不能如此频率的去读写数据库,严重影响性能问题,必须使用缓存,将需要秒杀的商品放入缓存中,并使用锁来处理并发情况,先将商品数量增减(加锁、解析)后在进行其他方面的处理,处理失败再将数据递增(加锁、解析),否则表示交易成功。
2.这个肯定不能直接操作数据库的,会挂的。直接读库写库对数据库压力太大了,要用到缓存。
3.首先,多用户并发修改同一条记录时,肯定是后提交的用户将覆盖掉前者提交的结果了。这个直接可以使用加乐观锁的机制去解决高并发的问题。

44…HttpRequest 和 HttpResponse 是什么?干嘛用的?

HttpRequest 是 django 接受用户发送多来的请求报文后,将报文封装到 HttpRequest 对象中去。
HttpResponse 返回的是一个应答的数据报文。render 内部已经封装好了 HttpResponse 类。
视图的第一个参数必须是 HttpRequest 对象,两点原因:表面上说,他是处理 web 请求的,所以
必须是请求对象,根本上说,他是基于请求的一种 web 框架,所以,必须是请求对象。
因为 view 处理的是一个 request 对象,请求的所有属性我们都可以根据对象属性的查看方法来获

取具体的信息:格式:request.属性

request.path #请求页面的路径,不包含域名
request.get_full_path  #获取带参数的路径
request.method  #页面的请求方式
request.GET GET  #get请求方式的数据
request.POST POST  #post请求方式的数据
request.COOKIES #获取 cookie
request.session #获取 session
request.FILES #上传图片(请求页面有 enctype="multipart/form-data"属性时 FILES 才有数据。

403 错误:表示资源不可用,服务器理解客户的请求,但是拒绝处理它,通常由于服务器上文件和目录的权限设置导致的 web 访问错误。

如何解决:1、把中间件注释。2、在表单内部添加{% scrf_token %}
request.GET.get() 取值时如果一键多值情况,get 是覆盖的方式获取的。getlist()可以获取多个值。
在一个有键无值的情况下,该键名 c 的值返回空。有键无值:c:
在无键无值也没有默认值的情况下,返回的是 None
getlist 返回的是列表,空列表
无键无值:e:None

HttpResponse 常见属性:

content: 表示返回的内容
charset:表示 response 采用的编码字符集,默认是 utf-8
status_code:返回的 HTTP 响应状态码 3XX 是对请求继续进一步处理,常见的是重定向。

常见方法:

init:创建 httpResponse 对象完成返回内容的初始化
set_cookie:设置 Cookie 信息:格式:set_cookies(‘key’,‘value’,max_age=None,expires=None)
max_age 是一个整数,表示指定秒数后过期,expires 指定过期时间,默认两个星期后过期。
write 向响应体中写数据

应答对象:

方式一:render(request,“index.html”) 返回一个模板
render(request,“index.html”, context) 返回一个携带动态数据的页面

方式二:render_to_response(“index.html”) 返回一个模板页面
方式三:redirect(“/”) 重定向
方式四:HttpResponseRdeirect(“/”) 实现页面跳转功能
方式五:HttpResponse(“itcast1.0”)在返回到额页面中添加字符串内容
方式六:HttpResponseJson() 返回的页面中添加字符串内容。
JsonResponse 创建对象时候接收字典作为参数,返回的对象是一个 json 对象。
能接收 Json 格式数据的场景,都需要使用 view 的 JsonResponse 对象返回一个 json 格式数据
ajax 的使用场景,页面局部刷新功能。ajax 接收 Json 格式的数据。
在返回的应答报文中,可以看到 JsonResponse 应答的 content-Type 内容是 application/json
ajax 实现网页局部刷新功能:ajax 的 get()方法获取请求数据
ajax 的 each()方法遍历输出这些数据

45.什么是反向解析

使用场景:模板中的超链接,视图中的重定向
使用:在定义 url 时为 include 定义 namespace 属性,为 url 定义 name 属性
在模板中使用 url 标签:{% url ‘namespace_value:name_value’%}
在视图中使用 reverse 函数:redirect(reverse('namespce_value:name_value’))
根据正则表达式动态生成地址,减轻后期维护成本。
注意反向解析传参数,主要是在我们的反向解析的规则后面天界了两个参数,两个参数之间使用空格隔开:位置参数

反向解析的使用:

1)在项目urls中包含具体应用的urls文件时指定namespace

urlpatterns = [

url(r’^admin/', admin.site.urls),

url(r’^',include(‘booktest.urls’,namespace=‘booktest’)),

]

2)在应用的urls中配置指定的name

urlpatterns = [

​ url(r’^index/$',views.index,name=‘index’),

url(r’^index2/$',views.index2),

]

3)在模板文件中使用时,格式如下:

{% url ‘namespace 名字:name’ %} 例如:

{% url ‘booktest:fan2’ %}

带位置参数:

{% url ‘namespace 名字:name’ 参数 %} 例如:

{% url ‘booktest:fan2’ 1 %}

带关键字参数:

{% url ‘namespace 名字:name’ 关键字参数 %} 例如:

{% url ‘booktest:fan2’ id=1 %}

4)在视图中重定向的时候使用反向解析:

from django.core.urlresolvers import reverse

无参数:

reverse(‘namespace 名字:name名字’)

有位置参数:

reverse(‘namespace 名字:name名字’,args = 位置参数元组)

有关键字参数:

reverse(‘namespace 名字:name名字’,kwargs = 字典)

46.Django 日志管理

配置好之后:

import logging
logger=logging.getLogger(__name__) # 为 loggers 中定义的名称
logger.info("some info ...)

可用函数有:logger.debug()

logger.info()
logger.warning() logger.error()
	Django 文件管理:对于 jdango 老说,项目中的 css,js,图片都属于静态文件,我们一般会将静态文件放到一个单独的目录中,以方便管理,在 html 页面调用时,也需要指定静态文件的路径。静态文件可以放在项目根目录下,也可以放在应用的目录下,由于这些静态文件在项目中是通用的,所以推荐放在项目的根目录下。
	在生产中,只要和静态文件相关的,所有访问,基本上没有 django 什么事,一般都是由 nignx 软件代劳了,为什么?因为 nginx 就是干这个的。

47.Tornado 的核是什么?

Tornado 的核心是 ioloop 和 iostream 这两个模块,前者提供了一个高效的 I/O 事件循环,后者则封装了 一个无阻塞的 socket 。通过向 ioloop 中添加网络 I/O 事件,利用无阻塞的 socket ,再搭配相应的回调函数,便可达到梦寐以求的高效异步执行。

48.Flask 中正则 URL 的实现?

@app.route(‘’)中 URL 显式支持 string、int、float、path 4 种类型,隐式支持正则。
第一步:写正则类,继承 BaseConverter,将匹配到的值设置为 regex 的值。

第一步:写正则类,继承 BaseConverter,将匹配到的值设置为 regex 的值。

class RegexUrl(BaseConverter):
	def __init__(self, url_map, *args):
		super(RegexUrl, self).__init__(url_map)
		self.regex = args[0]

第二步:把正则类赋值给我们定义的正则规则。

app.url_map.converters['re'] = RegexUrl

第三步:在 URL 中使用正则。

@app.route('/regex/<re("[a-z]{3}"):id>')
def regex111(id):
	return 'id:%s'%id

49.Flask 中请求上下文和应用上下文的区别和作用?

current_app、g 是应用上下文。
request、session 是请求上下文。

手动创建上下文的两种方法:

with app.app_context()
app = current_app._get_current_object()

两者区别:
请求上下文:保存了客户端和服务器交互的数据。
应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等。
两者作用:
请求上下文(request context):
Flask 从客户端收到请求时,要让视图函数能访问一些对象,这样才能处理请求。请求对象是一个很好的例子,它封装了客户端发送的 HTTP 请求。
要想让视图函数能够访问请求对象,一个显而易见的方式是将其作为参数传入视图函数,不过这会导致程序中的每个视图函数都增加一个参数,除了访问请求对象,如果视图函数在处理请求时还要访问其他对象,情况会变得更糟。为了避免大量可有可无的参数把视图函数弄得一团糟,Flask使用上下文临时把某些对象变为全局可访问。
应用上下文(application context):
它的字面意思是 应用上下文,但它不是一直存在的,它只是 request context 中的一个对 app的代理(人),所谓 local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。

50.Flask 中数据库设置?

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'

#动态追踪修改设置,如未设置只会提示警告

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

#查询时会显示原始 SQL 语句

app.config['SQLALCHEMY_ECHO'] = True

补充:
app.config[‘SQLALCHEMY_COMMIT_ON_TEARDOWN’]:可以配置请求执行完逻辑之后自动提交,而不用我们每次都手动调用 sessionmit();
监听数据库中的数据,当发生改变,就会显示一些内容:

app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True

显示打印的数据以及 sql 语句,建议不设置,默认为 False:

app.config['SQLALCHEMY_ECHO'] = True

51.常用的 SQLAlchemy 查询过滤器?

52.对 Flask 蓝图(Blueprint)的理解?

1) 蓝图的定义

蓝图 /Blueprint 是 Flask 应用程序组件化的方法,可以在一个应用内或跨越多个项目共用蓝图。使用蓝图可以极大地简化大型应用的开发难度,也为 Flask 扩展 提供了一种在应用中注册服务的集中式机制。

2) 蓝图的应用场景

1.把一个应用分解为一个蓝图的集合。这对大型应用是理想的。一个项目可以实例化一个应用对象,初始化几个扩展,并注册一集合的蓝图。

2.以 URL 前缀和/或子域名,在应用上注册一个蓝图。 URL 前缀/子域名中的参数即成为这个蓝图下的所有视图函数的共同的视图参数(默认情况下)。

3.在一个应用中用不同的 URL 规则多次注册一个蓝图。

4.通过蓝图提供模板过滤器、静态文件、模板和其它功能。一个蓝图不一定要实现应用或者视图函数。

5.初始化一个 Flask 扩展时,在这些情况中注册一个蓝图。

3) 蓝图的缺点

不能在应用创建后撤销注册一个蓝图而不销毁整个应用对象。

4) 使用蓝图的三个步骤

1.创建 一个蓝图对象

blue = Blueprint("blue",__name__)

2.在这个蓝图对象上进行操作 ,例如注册路由、指定静态文件夹、注册模板过滤器…

@blue.route('/')
def blue_index():
	return 'Welcome to my blueprint'

3.在应用对象上注册这个蓝图对象

app.register_blueprint(blue,url_prefix='/blue')

53.Flask 中 WTF 表单数据验证?

在 Flask 中,为了处理 web 表单,我们一般使用 Flask-WTF 扩展,它封装了 WTForms,并且它有
验证表单数据的功能。
WTForms 支持的 HTML 标准字段:

字段对象说明
StringField文本字段
TextAreaField多行文本字段
PasswordField密码文本字段
HiddenField隐藏文件字段
DateField文本字段,值为 datetime.date 文本格式
DateTimeField文本字段,值为 datetime.datetime 文本格式
IntegerField文本字段,值为整数
DecimalField文本字段,值为 decimal.Decimal
FloatFiel文本字段,值为浮点数
BooleanField复选框,值为 True 和 False
RadioField一组单选框
SelectField下拉列表
SelectMutipleField下拉列表,可选择多个值
FileField文件上传字段
SubmitField表单提交按钮
FormField把表单作为字段嵌入另一个表单
FieldList一组指定类型的字段

WTForms 常用验证函数

验证函数说明
InputRequired确保字段中有数据
DataRequired确保字段中有数据并且数据为真
EqualTo比较两个字段的值,常用于比较两次密码输入
Length验证输入的字符串长度
NumberRange验证输入的值在数字范围内
URL验证 URL
AnyOf验证输入值在可选列表中
NoneOf验证输入值不在可选列表中

使用 Flask-WTF 需要配置参数 SECRET_KEY。
CSRF_ENABLED 是为了 CSRF(跨站请求伪造)保护。 SECRET_KEY 用来生成加密令牌,当 CSRF 激活的时候,该设置会根据设置的密匙生成加密令牌。

54.Flask 项目中如何实现 session 信息的写入?

Flask 中有三个 session:
第一个:数据库中的 session,例如:db.session.add()
第二个:在 flask_session 扩展中的 session,使用:from flask_session importSession,使用第三方扩展的 session 可以把信息存储在服务器中,客户端浏览器中只存储 sessionid。
第三个:flask 自带的 session,是一个请求上下文, 使用:from flask import session。自带的session 把信息加密后都存储在客户端的浏览器 cookie 中。

55.项目接口实现后路由访问不到怎么办?

可以通过 postman 测试工具测试,或者看 log 日志信息找到错误信息的大概位置。

56.Flask 中 url_for 函数?

1.URL 反转:根据视图函数名称得到当前所指向的 url。
2.url_for() 函数最简单的用法是以视图函数名作为参数,返回对应的 url,还可以用作加载静态文件。

<link rel="stylesheet" href="{{url_for('static',filename='css/index.css')}}">

该条语句就是在模版中加载 css 静态文件。
3.url_for 和 redirect 区别
url_for 是用来拼接 URL 的,可以使用程序 URL 映射中保存的信息生成 URL。url_for() 函数最简单的用法是以视图函数名作为参数, 返回对应的 URL。例如,在示例程序中 hello.py 中调用url_for(‘index’) 得到的结果是 /。
redirect 是重定向函数,输入一个 URL 后,自动跳转到另一个 URL 所在的地址,例如,你在函数中写 return redirect(‘https://www.baidu’) 页面就会跳转向百度页面。

from flask import Flask,redirect,url_for
app = Flask(__name__)
@app.route('/')
def index():
    login_url = url_for('login')
    return redirect(login_url)
    return u'这是首页'

@app.route('/login/')
def login():
    return u'这是登陆页面'

@app.route('/question/<is_login>/')
def question(is_login):
    if is_login == '1':
        return u'这是发布问答的页面'
    else:
        return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)

57.Flask 中请求钩子的理解和应用?

请求钩子是通过装饰器的形式实现的,支持以下四种:
1,before_first_request 在处理第一个请求前运行
2,before_request:在每次请求前运行
3,after_request:如果没有未处理的异常抛出,在每次请求后运行
4,teardown_request:即使有未处理的异常抛出,在每次请求后运行
应用:

请求钩子

@api.after_request
def after_request(response):
    """设置默认的响应报文格式为 application/json"""
    # 如果响应报文 response 的 Content-Type 是以 text 开头,则将其改为
    # 默认的 json 类型
    if response.headers.get("Content-Type").startswith("text"):
        response.headers["Content-Type"] = "application/json"
    return response

58.一个变量后写多个过滤器是如何执行的?

{{ expression | filter1 | filter2 | … }} 即表达式(expression)使用 filter1 过滤后再使用 filter2 过滤。

59.如何把整个数据库导出来,再导入指定数据库中?

导出:

mysqldump [-h 主机] -u 用户名 -p 数据库名 > 导出的数据库名.sql

导入指定的数据库中:
第一种方法:

mysqldump [-h 主机] -u 用户名 -p 数据库名 < 导出的数据库名.sql

第二种方法:

#先创建好数据库,因为导出的文件里没有创建数据库的语句,如果数据库已经建好,则不用再创建。
create database example charset=utf8;(数据库名可以不一样)
#切换数据库:
use example;
#导入指定 sql 文件:
mysql>source /path/example.sql;

60.Flask 和 Django 路由映射的区别?

在 django 中,路由是浏览器访问服务器时,先访问的项目中的 url,再由项目中的 url 找到应用中url,这些 url 是放在一个列表里,遵从从前往后匹配的规则。在 flask 中,路由是通过装饰器给每个视图函数提供的,而且根据请求方式的不同可以一个 url 用于不同的作用。

61.跨站请求伪造和跨站请求保护的实现

图中 Browse 是浏览器,WebServerA 是受信任网站/被攻击网站 A,WebServerB 是恶意网站/点击网站 B。
(1)一开始用户打开浏览器,访问受信任网站 A,输入用户名和密码登陆请求登陆网站 A。
(2)网站 A 验证用户信息,用户信息通过验证后,网站 A 产生 Cookie 信息并返回给浏览器。
(3)用户登陆网站 A 成功后,可以正常请求网站 A。
(4)用户未退出网站 A 之前,在同一浏览器中,打开一个 TAB 访问网站 B。
(5)网站 B 看到有人方式后,他会返回一些攻击性代码。
(6)浏览器在接受到这些攻击性代码后,促使用户不知情的情况下浏览器携带 Cookie(包括sessionId)信息,请求网站 A。这种请求有可能更新密码,添加用户什么的操作。

从上面 CSRF 攻击原理可以看出,要完成一次 CSRF 攻击,需要被攻击者完成两个步骤:
1.登陆受信任网站 A,并在本地生成 COOKIE。
2.在不登出 A 的情况下,访问危险网站 B。
如果不满足以上两个条件中的一个,就不会受到 CSRF 的攻击,以下情况可能会导致 CSRF:
1).登录了一个网站后,打开一个 tab 页面并访问另外的网站。
2).关闭浏览器了后,本地的 Cookie 尚未过期,你上次的会话还没有已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了…)
解决办法:就是在表单中添加 from.csrf_token。

62.Flask(name)中的__name__可以传入哪些值?

可以传入的参数:
1,字符串:‘hello’,
但是‘abc’,不行,因为 abc 是 python 内置的模块
2,name,约定俗成
不可以插入的参数
1,python 内置的模块,re,urllib,abc 等
2,数字

63.简单说一下,用户访问一个 url 的过程(从浏览器输入 URL到显示界面,中间发生了什么?)

第一步,解析域名,找到 IP

​ (1)浏览器会缓存 DNS 一段时间,一般 2-30 分钟不等。如果有缓存,直接返回 IP,否则下一步。
​ (2)缓存中无法找到 IP,浏览器会进行一个系统调用,查询 hosts 文件。如果找到,直接返回 IP,否则下一步。(在计算机本地目录 etc 下有一个 hosts文件,hosts 文件中保存有域名与 IP 的对应解析,通常也可以修改 hosts 科学上网或破解软件。)
​ (3)进行了(1)(2)本地查询无果,只能借助于网络。路由器一般都会有自己的 DNS 缓存,ISP 服务商 DNS 缓存,这时一般都能够得到相应的 IP。如果还是无果,只能借助于 DNS 递归解析了。
​ (4)这时,ISP 的 DNS 服务器就会开始从根域名服务器开始递归搜索,从顶级域名服务器,到 baidu 的域名服务器。

​ 到这里,浏览器就获得了 IP。在 DNS 解析过程中,常常会解析出不同的 IP。比如,电信的是一个 IP,网通的是另一个 IP。这是采取了智能 DNS 的结果, 降低运营商间访问延时,在多个运营商设置主机房,就近访问主机。电信用户返回电信主机 IP,网通用户返回网通主机 IP。当然,劫持 DNS,也可以屏蔽掉一 部分网点的访问,某防火长城也加入了这一特性。

第二步,浏览器与网站建立 TCP 连接

​ 浏览器利用 IP 直接与网站主机通信。浏览器发出 TCP(SYN 标志位为 1)连接请求,主机返回 TCP(SYN,ACK 标志位均为 1)应答报文,浏览器收到 应答报文发现 ACK 标志位为 1,表示连接请求确认。浏览器返回 TCP()确认报文,主机收到确认报文,三次握手,TCP 链接建立完成。

第三步,浏览器发起默认的 GET 请求

​ 浏览器向主机发起一个 HTTP-GET 方法报文请求。请求中包含访问的 URL,也就是 http://www.baidu/ ,还有 User-Agent 用户浏览器操作系统信息,编码等。值得一提的是 Accep-Encoding 和 Cookies 项。Accept- Encoding 一般采用 gzip,压缩之后传输 html 文件。Cookies 如果是首次访问,会提示服务器建立用户缓存信息,如果不是,可以利用 Cookies 对应键值,找到相应缓存,缓存里面存放着用户名,密码和一些用户设置项。

第四步,显示页面或返回其他

​ 返回状态码 200 OK,表示服务器可以相应请求,返回报文,由于在报头中Content-type 为“text/html”,浏览器以 HTML 形式呈现,而不是下载文件。
​ 但是,对于大型网站存在多个主机站点,往往不会直接返回请求页面,而是重定向。返回的状态码就不是 200 OK,而是 301,302 以 3 开头的重定向码,浏览器在获取了重定向响应后,在响应报文中 Location 项找到重定向地址,浏览器重新第一步访问即可。
​ 补充一点的就是,重定向是为了负载均衡或者导入流量,提高 SEO 排名。利用一个前端服务器接受请求,然后负载到不同的主机上,可以大大提高站点的业务并发 处理能力;重定向也可将多个域名的访问,集中到一个站点;由于baidu,www.baidu 会被搜索引擎认为是两个网站,照成每个的链 接数都会减少从而降低排名,永久重定向会将两个地址关联起来,搜索引擎会认为是同一个网站,从而提高排名。

64.项目中使用了什么调试?

一般用 IDE 进行调试:例如:Pycharm 做断点调试
or
1.在对应位置使用 print 和 logging

2.sentry 第三方调试库,主要应用在 django 项目

3.ipdb(pdb)可以设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等
4.直接让你想要调试的位置让它先跑个异常

65.第三方支付是如何实现的?

聚合支付:ping++,付钱拉,Paymax…
直接对接:支付宝,微信,qq 钱包,银联,百度钱包…
建议:去该类官网了解接口相关知识

1、简单加密

目的是为了保证上传的参数信息没有被篡改,主要分成三部分
接口参数 : 需要和第三方对接的参数
加密类型 : 使用什么类型加密,一般为 MD5
加密密文 : 使用接口参数和第三方生成的 Code 值(固定 salt),进行 MD5 加密成密文
Md5 作为数字签名 H(A)=P 已知 A P,在特殊情况下可以伪造 A1 满足H(A1)=p

2、生成加密的密钥 Key

随机生成 16 位的加密密钥 Key,用于对上一步的内容进行对称加密

3、使用证书加密密钥 Key

对随机生成的密钥 key 进行加密。防止在传输过程中被截获破解。
使用了三种加密算法:
摘要算法:验证原文是否被篡改
对称加密算法:使用密钥对原文进行加密(AES)
非对称加密算法:对密钥进行分发

发送方:

入参 + H(入参+分配的 code)= P 得到键值对 ParamMap
AES ( ParamMap + 随机生成的 Key ) 进行对称加密得到 DecodeString
随机生成的 Key + 私钥证书加密, 得到 EnCodeKey
Http 发送请求, 将 DecodeString 和 EnCodeKey 发送给第三方支付公司

接收方:

证书加密的随机数,使用私钥解密得到 Akey
AES(AKey) = sourceCode(“入参”,“P”)
验证:H(sourceCode + code) = P

66.有用过 docker 吗?docker 的机制、原理(外壳和镜像的区别),说说 docker 与 VMware 虚拟化实现的不同??

1.docker 概念

Docker 是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括 VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。

2.Docker 通常用于如下场景:

web 应用的自动化打包和发布;
自动化测试和持续集成、发布;
在服务型环境中部署和调整数据库或其他的后台应用;
从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的PaaS 环境。

3.docker 的机制和原理

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建Docker 容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。

4.docker 和 VMware 的区别?

​ 各种虚拟机技术开启了云计算时代;而 Docker,作为下一代虚拟化技术,正在改变我们开发、测试、部署应用的方式
​ Docker 守护进程可以直接与主操作系统进行通信,为各个 Docker 容器分配资源;它还可以将容器与主操作系统隔离,并将各个容器互相隔离。
​ 虚拟机启动需要数分钟,而 Docker 容器可以在数毫秒内启动。由于没有臃肿的从操作系统,Docker 可以节省大量的磁盘空间以及其他系统资源。
​ 说了这么多 Docker 的优势,大家也没有必要完全否定虚拟机技术,因为两者有不同的使用场景。虚拟机更擅长于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而 Docker 通常用于隔离不同的应用,例如前端,后端以及数据库。

67.api 和 sdk 的区别?

API: Application Programming Interface编写应用程序的接口,抽象概念。
SDK: Software Development Kit:使用某种语言来暴露 API,提供头文件、库文件、工具(通常不是 IDE)和范例。
API 是接口,SDK 是开发包。就是钢笔和书包的差别,SDK 里面可以有很多
API,也可以说是一系列 API 的幸福全家桶:68.

68.什么是 QPS?

每秒查询率
QPS(TPS):每秒钟 request/事务数量

69.简述 Django 对 HTTP 请求的执行流程。

Django 接收到用户请求的 URL 后,去所有 URL 集合的 urls.py 文件中按照正则匹配目的 url,若匹配到就调用该 URL 的视图函数,执行代码完成相应的功能(对数据库增删改查),返回处理结果的数据,调用相应的模板或构建新页面,
在前端页面通过模板语言接收该结果,并将数据展现填充到相应位置,并将构建好的页面直接返回给浏览器,客户端浏览器将页面代码渲染输出为一个完整页面显示给用户

70.Django 中 Model 的 SlugField 类型字段有什么用途?

SlugField 字段用于生成一个有意义的 URL,一般是将标题转换成 URL,在后台添加时直接使用

71.通过 http 服务器日志如何干掉恶意爬虫;

cat uwsgi.log | grep spider -c #查看有爬虫标志的访问次数
cat uwsgi.log | wc #查看总页面访问次数
cat uwsgi |grep spider|awk '{print $1}'|sort -n|uniq -c|sort -nr #查看爬虫来源 IP
cat uwsgi.log |awk '{print $1 " " substr($4,14,5)}'|sort -n|uniq-c|sort -nr|head -20 #列出在一分钟内访问网站次数最多的前 20 位 ip 地址
/etc/hosts.deny 中列出的都是要禁止的 IP 地址

72.Flask 中数据库app.config[‘SQLALCHEMY_COMMIT_ON_TEARDOWN’]设置的作用?

作用:可以配置请求执行完逻辑之后自动提交,而不用我们每次都手动调用sessionmit()
补充:
监听数据库中的数据,当发生改变,就会显示一些内容
app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’]=True
显示打印的数据以及 sql 语句,建议不设置,默认为 False
app.config[‘SQLALCHEMY_ECHO’] = True

73.模糊查询和精确查询的区别?

filter()模糊查询:把过滤器添加到原查询上,返回一个新查询

filter_by()精确查询:把等值过滤器添加到原查询上,返回一个新查询

74.在虚拟机中部署项目,在 windows 下如何访问?

以 Django 项目为例,启动测试服务器时输入 python manage.py runserver0.0.0.0:8000 或者 python manage.py runserver ip:port (ip 为虚拟机的 ip 地址,端口号自己定义),然后在主机浏览器地址栏中输入 ip:port(ip 为虚拟机的 ip 地址,端口号为前文定义的端口号),此时就能看到 Django 的 Demo 程序"It 's works!"了

75.自定义过滤器的步骤?

#第一步:先定义自定义过滤器函数
def count_substring(string, substring):
return string.count(substring)
#第二步:注册自己定义的过滤器
app.jinja_env.filters['count_substring'] = count_substring
#第三步:最后在模板文件 html 中直接使用注册时的键名
{#前面的作为原字符串 string,传入的作为子字符串 substring#}
{{ 'A long long long long long
long longabc string
count_substring('long') }}<br/>

76.你正在开发注册页面,用户会输入一个邮箱,请写出校验邮箱合法性的正则表达式

^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$

77.在Django项目中,要实现打印一部分view方法的运行时间(精确到毫秒),请写一个名叫log_timeuse的装饰器完成此功能,以便通过如下方式就能使用。

import time
def log_timeuse(fun):
	def fx(request):
		s = time.time()
		fun(request)
		y = time.time()
		print(int((y-s)*1000))
	return fun(request)
return fx

78.简述COOKIE和SESSION的区别与联系

cookie是由服务器生成,存储在浏览器端的一小段信息。

cookie特点:

  1. 以键值对方式进行存储,键和值都是以 ASCII 字符串的形存储(不能是中文字符串)。

  2. 通过浏览器访问一个网站时,会将浏览器存储的跟网站相关的所有cookie信息发送给该网站的服务器。request.COOKIES

  3. cookie是基于域名安全的

  4. cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。

session存储在服务器端,session 是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据。每个客户端都可以在服务器端有一个独立的 Session。

session的特点:

  1. session的特点以键值对进行存储的。

  2. session依赖于cookie

session有过期时间,如果不指定,默认两周会过期

cookie 和session 的区别:
1)cookie数据存放在客户的浏览器上,session数据放在服务器上。
2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4)单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
cookie 和session 的联系:
session是通过cookie来工作的
session和cookie之间是通过 C O O K I E [ ′ P H P S E S S I D ′ ] 来联系的,通过 _COOKIE['PHPSESSID']来联系的,通过 COOKIE[PHPSESSID]来联系的,通过_COOKIE[‘PHPSESSID’]可以知道session的id,从而获取到其他的信息.

79.请简述对REST API设计规范的理解

REST API是使用统一资源标识符(url)来搜寻资源 有七大设计原则:

1).url结尾不应包含(/)

2).正斜杠分隔符(/)必须用来指示层级关系

3).应使用连字符(-)来提高url的可读性

4).不得在url中使用下划线(_)

5).url路径中首选小写字母

6).文件扩展名中不应包含在url中

7).端点名称是单数(但是实际上为了保持url格式的一致性建议使用复数形式)

正在构建的服务中的每个资源将至少有一个url标识它,这个url最好是有意义的,且能充分藐视资源。url应遵循可预测的层次结构,用来提高其可理解性,可用性:可预测的意义在于他们是一致的,他的层次结构在数据关系上时有意义的。

REST API是使用者编写的,url的名称和结构应该能够向使用者传达更清晰的含义。通过遵循上述规则,您将创建一个更清晰的REST API与更友好的客户端。

80.用户注册用户名时,如何做一些控制(如何防止注入攻击)

程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。产生Sql注入。下面是防止办法:

a. 过滤掉一些常见的数据库操作关键字,或者通过系统函数来进行过滤。

b. 在PHP配置文件中将Register_globals=off;设置为关闭状态

c. SQL语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号

d. 提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的

e. 对于常用的方法加以封装,避免直接暴漏SQL语句

f. 开启PHP安全模式:Safe_mode=on;

g. 打开magic_quotes_gpc来防止SQL注入

h. 控制错误信息:关闭错误提示信息,将错误信息写到系统日志。

i. 使用mysqli或pdo预处理。

81.nginx部署具体操作

Nginx的特点:静态资源的高并发,反向代理加速,支持FastCGI,运行SSL、TSL

环境部署:

1)安装编译环境

yum install -y gcc gcc-c++ openssl openssl-devle pcre pcre-devel make get curl

pcre-devel 兼容正则表达式

2)创建安装目录,下载资源

mkdir -p /Application/tools

wget http://nginx/download/nginx-****.tar.gz

3)解压文件,并进入安装文件目录

tar zxf nginx-.tar.gz && cd nginx-

4)创建用户

创建一个没有家目录的且不能登录的用户nginx

sudo useradd nginx -s /sbin/nologin -M

sudo id nginx

uid=501(nginx) gid=501(nginx) groups=501(nginx)

5)配置

./configure --user=nginx --group=nginx --prefix=/Application/nginx-** --with-http_sub_module

指定运行软件的用户名 运行软件的组 指定安装路径 启用Nginx运行状态模块

6)编译并安装

make && make install

7)测试安装结果

7).1:查看进程

ps -ef |grep nginx |grep -v grep

root 2232 1 0 11:14 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx

nginx 9451 2232 0 13:58 ? 00:00:00 nginx: worker process

7).2:查看端口

netstat -antulp |grep nginx

tcp 0 0 0.0.0.0:80 0.0.0.0: LISTEN 2232/nginx

7).3:文本工具测试

7).3.1:curl 127.0.0.1

Welcome access www.52linux.club

7).3.2:www.52linux.club

8)创建软链接

8).1.用于版本升级中,代码的固定安装位置或参数的引用

8).2.ln -s /Application/nginx-1.12.1 /usr/loacl/nginx

lrwxrwxrwx 1 root root 25 Mar 16 15:49 nginx -> /Application/nginx-1.12.1

82.MVC和MVT的异同及其各自的功能

MVT:MVT是一种软件架构设计思想,它的核心思想是解耦合,解的是数据操作、数据展示、业务逻辑处理之间的耦合,M是model,负责对数据的处理;T是Template,负责显示数据;V是Views,负责处理用户的请求,根据需求处理数据,处理完数据处理逻辑,处理完逻辑渲染页面。调用M和T请求响应

MVC:MVC是一种软件架构设计思想,它的核心思想是解耦合,解的是数据操作、数据展示、业务逻辑处理之间的耦合,M是model模型,主要用于封装和数据相关的操作,V是Views视图,负责展示数据,C是Controller控制器,用来接收输入,协调model和Views的关系,处理业务逻辑

83.ORM的概念及其优缺点

ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

总结:简单来说ORM就是封装数据库的操作。

优点:

1.简单:ORM以最基本的形式建模数据。表的字段就是这个类的成员变量

2.可读性:ORM使数据库结构文档化。比如MySQL数据库就被ORM转换为了class类,PHP程序员可以只把注意力放在他擅长的PHP层面(当然能够熟练掌握MySQL更好)

3.可用性:ORM的避免了不规范、冗余、风格不统一的SQL语句,可以避免很多人为Bug,方便编码风格的统一和后期维护

4.可维护性:在数据表结构甚至数据库发生改变时,减少了相应的代码修改;可以很方便地引入数据缓存之类的附加功能

缺点:

1.自动化进行关系数据库的映射需要消耗系统性能。一般来说都可以忽略之,特别是有cache存在的时候

2.在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂且猥琐

3.越是功能强大的ORM越是消耗内存,因为一个ORM Object会带有很多成员变量和成员函数。

适用于敏捷开发和团队合作开发,不适用于有大数据量、大运算量、复杂查询的系统。

84.django字段类型和选项

使用时需引入django.db.models包,字段类型如下:

类型描述
AutoField自动增长的IntegerField,通常不用指定,不指定时django会自动创建属性名为id的自动增长属性
BooleanField布尔类型,值为True或False
NullBooleanField支持Null,True、False三种值
CharField(max_length=最大长度)字符串。参数max_length表示最大字符串长度
TextField大文本字段,一般超过4000个字符时使用
IntegerField整数
DecimalField(max_digits=None,decimal_places=None)十进制浮点数。参数max_digits表示总位数。参数decimal_places表示小数位数,与FloatField相比精度高
FloatField浮点数,参数同上
DateField([auto_now=False,auto_now_add=False])日期。1) 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是使用当前日期,默认为False2) 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False3) 参数auto_now和auto_now_add是相互排斥的,组合将会发生错误
TimeField时间,参数同DateField
DateTimeField日期时间,参数同DateField
FileField上传文件字段
ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片

选项

通过选项实现对字段的约束,选项如下:

选项名描述
default默认值。设置默认值
primary_key若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unipure若为True,这个字段在表中必须有唯一值,默认值是False
db_index若为True,则在表中会为此字段创建索引,默认值是False
db_column字段的名称,如果未指定,则使用属性的名称
null若为True,表示允许为空,默认值是False
blank若为True,则该字段允许为空白,默认值是False

85.Django查询函数(查询集返回列表的过滤器有哪些?)

函数名功能返回值说明
get返回表中满足条件的一条且只能有一条数据返回值是一个模型类对象参数中写查询条件。1)若查到多条数据,则抛异常:MultipleObjectsReturned.2)查询不到数据,则抛异常:DoseNotExist.
all返回模型类对应表格中的所有数据返回值是QuerySet类型查询集
filter返回满足条件的数据返回值是QuerySet类型参数写查询条件
exclude返回不满足条件的数据返回值是QuerySet类型参数写查询条件
order by对查询结果进行排序返回值是QuerySet类型参数中写根据哪些字段进行排序

86.Django中F对象和Q对象的作用

F对象:

作用:用于属性之间的比较

使用之前导入:from django.db.models import F

F()表达式表示数据库表的某一列值

F()表达式可以在不实际把数据存入python内存的前提下,引用值和操作数据库

直接产生数据库级别的SQL语句

F表达式的优点:

​ 直接在数据库层面操作

​ 减少了操作

F表达式的应用场景:

​ 1.避免竞争条件

​ 当两个线程同时进行操作,在第一个线程正在操作还未保存的时候,第二个进程进行取值,修改,保存。则第一个操作的值被覆盖丢失。但是由数据库操作的时候则不会出现此种情况。

​ 2.用于Queryset中的过滤

​ F()的实例作为查询中的模型字段的引用。可以用于两个不同字段比较

​ 3.支持加减乘除模幂操作,支持位操作

Q对象:

作用:用于查询时条件之间的逻辑关系。not and or .可以对Q对象进行& | ~

使用之前导入:from django.db.models import Q

87.django查询集

查询集特性:

  1. 惰性查询:只有在实际使用查询集中的数据的时候才会发生对数据库的真查询

  2. 缓存:当使用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果。

限制查询集:

可以对一个查询集进行取下标或者切片操作来限制查询集的结果

对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数。

取出查询集第一个数据的两种方式:

方式说明
b[0]若b[0]不存在,会抛出IndexError异常
b[0:1].get()若b[0:1].get()不存在,会抛出DoseNotExist异常

exists:判断一个查询集中是否有数据。True False

88.Django捕获url参数

进行url匹配时,把所需要的捕获部分设置成一个正则表达式组,这样django框架就会自动把匹配成功后相应组的内容作为参数传递给视图函数。

  1. 位置参数

位置参数,参数名可以随意指定

  1. 关键字参数:在位置参数的基础上给正则表达式组命名即可

?P<组名>

关键字参数,视图中参数名必须和正则表达式组名一致

89.Django中request的属性

(下面除非特别说明,属性都是只读的)

request.POST:保存的是post提交的参数

request.GET:保存的是get提交的参数

path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分

method:一个字符串,表示请求的方法,常用值包括:“POST”,“GET”。

​ 在浏览器中给出地址请求采用get方式,如超链接

​ 在浏览器中点击表的提交按钮发起请求,如果表单的method设置为post则为post请求。

encoding:一个字符串,表示提交的数据的编码方式。

​ 若为None则表示使用浏览器的默认设置,一般为utf-8.

​ 这个属性是可写的,可以通过修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。

GET:QueryDict类型对象,类似于字典,包含get请求方式的所有参数。

POST:QueryDict类型对象,类似于字典,包含post请求方式的所有参数。

FILES:一个类似于字典的对象,包含所有的上传文件。

COOKIES:一个标准的python字典,包含所有的上传文件。

session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django启用会话的支持时才可用。

90.简述 Django 下的(内建的)缓存机制?

一个动态网站的基本权衡点就是,它是动态的。 每次用户请求页面,服务器会重新计算。从开销处理的角度来看,这比你读取一个现成的标准文件的代价要昂贵的多。

这就是需要缓存的地方。

Django 自带了一个健壮的缓存系统来保存动态页面这样避免对于每次请求都重新计算。方便起见,Django 提供了不同级别的缓存粒度:可以缓存特定视图的输出、可以仅仅缓存那些很难生产出来的部分、或者可以缓存整个网站 Django 也能很好的配合那些“下游”缓存, 比如 Squid 和基于浏览器的缓存。这里有一些缓存不必要直接去控制但是可以提供线索, (via HTTPheaders)关于网站哪些部分需要缓存和如何缓存。

设置缓存:

缓存系统需要一些设置才能使用。 也就是说,你必须告诉他你要把数据缓存在哪里- 是数据库中,

文件系统或者直接在内存中。 这个决定很重要,因为它会影响你的缓存性能,是的,一些缓存类型要比其他的缓存类型更快速。

你的缓存配置是通过 setting 文件的 CACHES 配置来实现的。 这里有 CACHES 所有可配置的变量值。

91.ajax请求流程

92.ajax同步异步的区别

​ Ajax是(Asynchronous JavaScript And XML)是异步的JavaScript和xml。也就是异步请求更新技术。Ajax是一种对现有技术的一种新的应用,不是一门新语言。它是用 JavaScript编写。与xml的关系就是可以读取和返回xml文件。

​ ajax通过xmlhttpRequest对象执行操作,其中xmlhttpRequest对象是在浏览器中内置的一个对象,,其运行原理就相当于创建了一个请求代理,通过代理去完成与服务器的交互,交互的过程中客户不需要等待,还可以进行其它的工作,交互完成以后,代理再将交互的结果返回给客户页面。

 其中async是一个布尔值。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的 request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式:Flase。

​ 同步:提交请求->等待服务器处理->处理完毕返回这个期间客户端浏览器不能干任何事。

​ 一心一意:当前只能做一件事,其他事情必须等当前的事情完成,才能继续后面的事情。

​ 例如:你在烤面包,当你把面包放进烤面包机里边,然后你就一直在哪儿傻等着,一直等到面包烤好了你取出面包再开始做下面的事情这个就是同步

​ 异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

​ 三心二意:同时可以做多件事情:左手按着空格键,右手可以不断的击打鼠标,眼睛还要同时看着屏幕,很辛苦。

例如:你不等面包烤好,把面包放进烤面包机之后你就去做其他事情去了,当烤面包机一声铃响提示你烤好了,你取出面包再开始做下面的事情这个就是异步。

ajax局部刷新页面,不会将整个页面刷新

ajax请求在后台,不要返回页面或者重定向,

93.django模板文件的加载顺序

1)首先去配置的模板目录下去找模板文件

2)然后去INSTALLED_APPS 下面的每个应用中去找模板文件,前提是应用中必须有 templates 文件夹。(其中系统默认应用中django.contrib.admin’,‘django.contrib.auth’,含有templates)

94.django模板变量的解析顺序

例如:{{ book.btitle }}

  1. 首先把book 当成一个字典,把btitle当成键名,进行取值book[‘btitle’]

  2. 把book当成一个对象,把btitle当成属性,进行取值book.btitle

  3. 把book当成一个对象,把btitle当成对象的方法,进行取值book.btitle

例如:{{ book.0 }}

  1. 首先把book当成一个字典,把0当成键名,进行取值book[‘0’]

  2. 把book当成一个列表,把0当成下标,进行取值book[0]

如果解析失败,则产生内容时用空字符串填充模板变量

使用模板变量时,点前面可能是字典、对象或者列表

95.django防止csrf的防御原理

1)渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域。

2)服务器交给浏览器保存一个名字为csrftoken的cookie信息。

3)提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败。

96.django中间件类定义中间件预留函数

1)init:服务器响应第一个请求时候用

2)process_request:是产生request对象,进行url匹配之前调用。

3)process_view:是url匹配之后,调用视图函数之前。

4)process_response:视图函数调用之后,内容返回给浏览器之前。

5)process_exception:视图函数出现异常,会调用这个函数。

如果注册的多个中间件类中包含process_exception函数的时候,调用的顺序跟注册的顺序是相反的。

97.浏览器访问django框架流程(浏览器访问中间件原理)

98.django后台管理页面分页

from django.core.paginator import Paginator
paginator = Paginator(areas,10)#按每页10条数据进行分页

Paginator类对象的属性:

属性名说明
num_pages返回分页之后的总页数
page_range返回分页后页码的列表

paginator类对象的方法:

方法名说明
page(self,number)返回第number页的Page类实例对象

Page类对象的属性:

属性名说明
number返回当前页的页码
object_list返回包含当前页的数据的查询集
paginator返回对应的Paginator类对象

Page类对象的方法:

属性名说明
has_previous判断当前页是够有前一页
has_nect判断当前页是否有下一页
previous_page_number返回前一页的页码
next_page_number返回下一页的页码

更多推荐

web框架知识整理

本文发布于:2023-04-19 03:44:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/80d0925e315ff015b0f43f85af3dd592.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:框架   知识   web

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 87138文章数
  • 19110阅读数
  • 0评论数