1.NGINX正向代理,反向代理,负载均衡
正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。
反向代理,多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源是明确的,但是请求具体由哪台服务器处理的并不明确了
反向代理主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息!
负载均衡
反向代理中,服务器按照一定的规则分发给后端服务器,将服务器接收到的请求按照规则分发的过程叫做负载均衡
负载均衡的调度算法:权重轮训,ip_hash,url_hash
2.nginx配置
server {
listen 80;
server_name www.111.com;
location / {
include uwsgi_params; # 将uwsgi参数添加进nginx
uwsgi_pass 0.0.0.0:8000; # 反向代理转发请求给uwsgi
}
}
location /static {
alias /opt/crmstatic/;
}
3.django聚合查询,分组,F,Q
聚合查询
aggregate()是QuerySet 的一个终止子句,它返回一个包含一些键值对的字典。
print(models.Book.objects.all().aggregate(Avg('price')))
# {'price__avg': 12.5}
print(models.Book.objects.all().aggregate(a=Avg('price')))
# {'a': 12.5}
分组查询
annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数),annotate前面的values作为分组的依据,不写values默认按照id来分组
models.Book.objects.values('publish__id').annotate(a=Avg('price'))
#
F查询
可以在查询中引用字段,用来比较两个字段,还可以对F()对象加减乘除
也可以通过F函数进行修改字段的操作
Q查询
与或非操作
4.django生命周期
wsgiref(web server)接收用户请求,并进行初次封装
中间件
url路由匹配
视图函数 -- 数据库 -- 模板渲染
中间件
wsgiref返回响应
5.djangoORM中get和filter的区别
相同点,都可以加筛选条件
get 返回model对象,而且只有一个,超过一个或者没有报错
filter 返回queryset类型,取不到返回[]
6.css清除浮动
1. 固定高度:在父标签里面加一个其他的标签
2. 伪元素清除法:在标签后面加一个内容为空的块级标签,加上clear: both;
3. overflow:hidden
7.wsgi和uWSGI的区别
wsgi是一种通信协议,介于Web应用程序(Web框架)与Web服务器之间交互的规范
uwsgi是一种通信协议,是uWSGI独有的协议
uWSGI是一个web服务器,实现了WSGI、uwsgi、http协议等
浏览器 <---> web服务器 <-wsgi-> 框架
8.实例方法,类方法,静态方法
实例方法
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
调用:只能由实例对象调用。
类方法
定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
调用:实例对象和类对象都可以调用。
静态方法
定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
调用:实例对象和类对象都可以调用。
9.MVC架构和MTV架构,区别
MVC 软件系统分为三个基本部分
模型 (Model)、视图 (View) 和控制器 (Controller)
Model: 负责业务对象与数据库的映射 (ORM)
View: 负责与用户的交互
Control: 接受用户的输入调用模型和视图完成用户的请求
Django 框架的 MTV 设计模式借鉴了 MVC 框架的思想, 三部分为
Model、Template 和 View
Model (模型): 负责业务对象与数据库的对象(ORM)
Template (模版): 负责如何把页面展示给用户
View (视图): 负责业务逻辑, 并在适当的时候调用 Model 和 Template
此外, Django 还有一个 urls 分发器,
它将一个个 URL 的页面请求分发给不同的 view 处理, view 再调用相应的 Model 和 Template
10.python如何进行内存管理的,内存泄漏的原因,怎么避免
内存管理:
1.引用计数:赋值计数器+1,删除-1
2.垃圾回收:解决对象的循环引用,引用计数无法解决时
3.内存池机制:将不用的内存放到内存池,不反还给操作系统
内存泄漏:
1.对象一直被全局变量所引用, 全局变量生命周期长.
2.循环引用中的对象定义了__del__方法(Python文档写的)
3.垃圾回收机被禁用或者设置成debug状态, 垃圾回收的内存不会被释放.
解决:
使用gc、objgraph模块定位泄露位置,逐个处理
11.sql将数据库去重
select distinct 字段1 from 表名;
12.斐波那契,99乘法表
斐波那契:输入一个最大值
def fib(max):
x, y = 0, 1
while y < max:
x, y = y, x+y
yield x
for i in fib(1000):
print(i)
99乘法表
print('\n'.join(['\t'.join([f"{j}*{i}={i * j}" for j in range(1, i + 1)]) for i in range(1, 10)]))
13.读大文件
def read_in_chunks(path, chunk_size=1024 * 1024):
with open(path)as f:
while True:
chunk_data = f.read(chunk_size)
if not chunk_data:
break
yield chunk_data
filePath = './path/filename'
for chunk in read_in_chunks(filePath):
print(chunk)
14.列表去重
# 要求保持原有列表中元素的排列顺序
l = []
for i in alist:
if i not in l:
l.append(i)
alist = l
# 无需考虑原有列表中元素的排列顺序
alist = list(set(alist))
15.邮箱正则
^\w+@\w+(\.\w+)+$
16.read,readline,readlines区别
.read() # 读取全部内容
.read(n) # 读取最多n(字符(r模式),字节(rb模式))的内容
.readline() # 读取一行内容
.readlines() # 读取所有数据,根据换行符将值保存为列表
17.re的match,search,findall
match以什么开头,返回结果集
search找第一个,返回结果集
结果集为NONE时用group就报错
findall匹配所有
18.用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别
<.*>这种匹配称作贪心匹配 <.*?>称作惰性匹配
19.常用正则
\d任意数字 \w数字字母下划线 \s任意空白符 .非换行符的任意字符
[^]非字符组的所有 ()分组
{n}出现n次 {n,}至少n次 {n,m}n到m次 ?匹配0或1 +匹配1或多 *匹配0或多
量词后的?表示惰性匹配
a.*?b 从a开始匹配,匹配任意长度,直到b停止
20.*args, **kwargs 的区别是什么?
*args 接收不定数量的位置参数组织成一个元组
**kwargs 接收不定数量的关键字参数组织成一个字典
21.sql优化基本原则
1.减少select *
2.使用like时避免使用%
3.小结果集驱动大结果集
4.null包含的列不作为索引
5.不要使用 count(id) , 而应该是 count(*)
6.使用批量插入语句节省交互
7.LIMIT 的基数比较大时使用 BETWEEN。
22.python和go的区别?以及各自的优势
python是动态类型的解释型语言,代码简洁易懂
go是静态类型的编译型语言,天生支持高并发
23.列表推导式和生成器推导式
列表推导式占用内存,可以重复利用
生成器推导式节省内存,但不可重复利用
24.魔术方法总结
__new__ 创建一个空对象然后返回这个空对象
__init__ 负责将类进行实例化
__call__ 负责将对象转化为可执行对象,实现了该方法,就是可调用对象
__str__ 利用 print 函数打印一个对象时触发
__repr__ 当没有 __str__ 方法时触发 __repr__ 方法, 返回数据本身
__enter__() 和 __exit__() 只有支持上下文管理器的对象才能使用 with, 即在对象内实现了两个方法:
25.队列、栈
两个队列实现一个栈
进栈:元素入队列A
出栈:判断如果队列A只有一个元素,则直接出队。否则,把队A中的元素出队并入队B,直到队A中只有一个元素,再直接出队。为了下一次继续操作,互换队A和队B。
两个栈实现一个队列
入队:元素进栈A
出队:先判断栈B是否为空,为空则将栈A中的元素 pop 出来并 push 进栈B,再栈B出栈,如不为空则栈B直接出栈
26.使用yield实现一个协程
def consumer():
'''任务1:接收数据,处理数据'''
while True:
x=yield
def producer():
'''任务2:生产数据'''
g=consumer()
next(g)
for i in range(10000000):
g.send(i)
producer()
27.mysql相关
1.存储引擎和区别
InnoDB 支持事务、外键、行锁
MyISAM 支持表锁,访问快
Memory 存在内存中
2.触发器、函数、视图、存储过程
触发器
对数据库某个表进行 (增、删、改) 前后, 自动执行的代码
函数
MySQL 提供的内置函数, 还可以自定义函数 (实现程序员需要的SQL逻辑处理)
视图
视图是由查询结果形成的一张虚拟表, 可以简化查询
存储过程
把一段代码封装起来, 当要执行这一段代码的时候, 可以通过调用该存储过程来实现
经过第一次编译后再次调用不需要再次编译, 比一个个执行 SQL 语句效率高
3.索引种类
普通索引: 仅加速查询
唯一索引: 加速查询 + 列值唯一 (可以有 null)
主键索引: 加速查询 + 列值唯一 (不可以有null) + 表中只有一个
组合索引: 多列值组成一个索引, 专门用于组合搜索, 其效率大于索引合并
全文索引: 对文本的内容进行分词, 进行搜索
3.无法命中索引的情况
1.like与%一起使用
2.使用函数、or、!=、>、order by
3.类型不一致
4.组合索引未遵循最左前缀原则
4.组合索引需要注意什么
最左前缀匹配原则
最左的匹配成功才匹配第二个,以此类推
5.执行计划
SQL在数据库中执行时的表现情况,通常用于SQL性能分析、优化等场景。
可以看到是否命中索引,计划能命中哪些,实际命中了哪些,执行的顺序
6.慢日志
用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。
7.分库分表
垂直分库/分表:实现冷热数据分离,不解决数据量大带来的性能损耗
水平分库/分表:数据减少,提高性能,切分的表结构相同,拆分规则难抽象
8.数据库优化
1.更换存储引擎
2.SSD存储
3.分库分表
4.使用redis,memcache做缓存
5.读写分离
9.left 、right和 inner join 的区别
left join 返回包括左表中的所有记录和右表中联结字段相等的记录
right join 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join 只返回两个表中联结字段相等的行
10.char 和 varchar的区别
char 定长,浪费空间,存取快
varchar 变长,节省空间,存取慢
28.only 和 defer 的区别?
defer 除了指定字段之外
only 只查询几个字段
29.select_related 和 prefetch_related 的区别?
有外键存在时, 可以很好的减少数据库请求的次数, 提高性能
select_related 通过多表 join 关联查询, 一次性获得所有数据, 只执行一次SQL查询
prefetch_related 分别查询每个表, 然后根据它们之间的关系进行处理, 执行两次查询
30.缓存穿透、缓存雪崩、缓存击穿
缓存穿透
概念:访问一个不存在的key,缓存不起作用
解决:将查到的空值写进缓存,设置较短过期时间
缓存雪崩
概念:大量的key设置了相同的过期时间,导致缓存在同一时刻全部失效
解决:缓存过期时间加上一个随机值
缓存击穿
概念:一个存在的key,在缓存过期的一刻,有大量请求
解决:SETNX设置一个短期key锁住当前key的访问
31.HTTP/HTTPS/websocket
HTTP:超文本传输协议,由请求和相应构成,信息明文传输,端口是80
HTTPS:超文本传输安全协议,信息加密传输,需要到CA申请证书,端口是443
websocket:建立在tcp协议上的全双工通讯协议,只需要完成一次握手,浏览器与服务器之间就直接可以创建持久性的连接,并进行双向数据传输。