https://blog.csdn.net/hpwzjz/article/details/81412988
基础
Python这门语言的看法
python是一门具有解释性、编译性、互动性和面向对象的脚本语言。
python与php相比可以处理多进程多线程任务。
语法没有java那么严格 java的可移植性是需要代价的
什么是闭包
函数中嵌套函数 且外层函数的返回值也是函数 闭包中需要注意的是变量的作用域,内层函数使用外层函数的值需要加nolocal 使用全局变量的值需要加global。
什么是装饰器
装饰器的目的就是对已封装函数进行操作,为其加上新的功能或一系列运算 。 在django中有middleware中间件,它其实就是高级的装饰器用法。
def outside(func):
def inside(str):
func(str)
print('inside')
return inside
@outside
def hello(str):
print('hello',str)
hello('str')
生成式、生成器、迭代器和可迭代对象区别和应用?
生成式:
[expr for iter_var in iterable] 即 [返回值 for 元素 in 可迭代对象]
lst = [x*x for x in range(1,6)]
print(lst)
生成器
拥有yield关键字的Python函数,生成器是一次性取值,且只能取一次。
线程、进程和协成
线程:程序执行的最小单位。
进程:进程是程序的一次执行,进程是可以和别的计算并行执行。
协程:协程是一种用户态的轻量级线程,协程的调度完全由用户控制,协程拥有自己的寄存器和栈。
一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程
序的运行效率
线程不能够独立执行,必须依存在进程中
一个线程可以多个协程,一个进程也可以单独拥有多个协程
线程进程都是同步机制,协程是异步。
互斥锁
某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;
直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。
死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资
源,就会造成死锁。
进程间通讯的方式有哪些,各有什么优缺点:
-
管道:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程之间使用。进程的亲缘关系通常是指父子进程关系。
-
有名管道(FIFO):有名管道也是半双工的通信方式,但是允许在没有亲缘关系的进程之间使用,管道是先进先出的通信方式。
-
信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
-
消息队列:消息队列是有消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
-
信号 ( sinal ) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
-
共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
-
套接字( socket ) :套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
参考链接
Python内存管理
python中万物皆对象,python的存储问题是对象的存储问题,并且对于每个对象,python会分配一块内存空间去存储它。
Python的内存管理机制:引入计数、垃圾回收、内存池机制。
引入计数:在Python中,每个对象都有指向该对象的引用总数—引用计数。
垃圾回收:当Python中的对象越来越多,占据越来越大的内存,启动垃圾回收(garbage collection),将没用的对象清除。
内存池机制:Python中有分为大内存和小内存:(256K为界限分大小内存)
1、大内存使用malloc进行分配
2、小内存使用内存池进行分配
3、Python的内存池(金字塔)
TCP和UDP的区别
- TCP面向连接,UDP无连接。
- TCP提供可靠的服务,UDP不可靠
- TCP面向字节流,把数据堪称一连串无结构的字节流,UDP面向报文。TCP全双工可靠信道,UDP是不可靠信道。
- 稳定的UDP:
Python面向对象继承时要注意什么?
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类。
继承分单继承和多继承 多继承需要注意继承的顺序,而且子类继承父类后如果方法命名与父类相同 则会覆盖。
但在python3中。可以使用super函数来调用父类方法
经典类和新式类,深度优先和广度优先是什么?
在python2中,如果明确写了继承object,那么这个类就是新式类;如果没有写,那么就是旧式类(经典类)。
在python3中,不管写没写object,这个类都是新式类。
python的类可以继承多个类,如果继承多个则寻找方式就有两种深度优先广度优先,经典类按深度优先方式查找,新式类按广度优先方式查找。
单例模式
单例模式是一个对象只能有一个类。一个单例类只能有一个实例。
继承object类,并重写类中的__new__(cls)方法
class Earth(object):
__instance=None #定义一个类属性做判断
def __new__(cls):
if cls.__instance==None:
#如果__instance为空证明是第一次创建实例
#通过父类的__new__(cls)创建实例
cls.__instance==object.__new__(cls)
return cls.__instance
else:
#返回上一个对象的引用
return cls.__instance
new()和__init__()方法有什么却别
1.init 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
2.new 通常用于控制生成一个新实例的过程。它是类级别的方法。
数据库
数据库引擎
innodb引擎 Memory引擎 Merge引擎
innodb引擎一大特点就是支持外键。 内存和空间大 支持事务。
数据库锁
由于数据库是多用户共享资源,所以需要处理并发问题,而数据库锁的机制就是为了处理这一问题,当出现并发的时候,如果不做控制就会出现各种问题 比如脏数据。修改丢失等 所有数据库并发需要事务来控制,事务并发问题需要数据库锁来控制。
事务四个特性。持久型 原子性 一致性 隔离性
数据库锁有 乐观锁 悲观锁 死锁。活锁 行锁 表锁 页级锁
排它锁有称为写锁。共享锁又称为读锁
F和Q函数的理解
F函数主要用于获取字段当前的值。
假如有表,表有字段age,我想把所有age都自增1,该如何做?
SQL语句:update 表名 set age=age+1。
# F()的用法(用于获取字段原来的值)
from django.db.models import F
result = models.UserInfo.objects.update(age=F('age')+1)
print(result)
Q函数
主要用于组合筛选条件
需求:假如有表,取表中id为(1,10)的数据
SQL: select * from 表名 where id>1 and id<10
# Q的用法(用于组合筛选条件)
# 用法一(逻辑非用‘~’代替)
from django.db.models import Q
results = models.UserInfo.objects.filter(Q(id__gt=1) & Q(id__lt=10))
# results = models.UserInfo.objects.filter(Q(id=1) | Q(id=2))
for row in results:
print(row.id,row.username,row.age)
queryset的常用方法
filter:将满足条件的数据提取出来,返回一个新的QuerySet。
exclude:排除满足条件的数据,返回一个新的QuerySet。
annotate:给QuerySet中的每个对象都添加一个使用查询表达式(聚合函数,F表达式,Q表达式,Func表达式等)的新字段。
order_by:指定将查询的结果根据某个字段进行排序,如果要倒叙排序,那么可以在这个字段的前面加一个负号。
values:用来指定提取数据时,提取那些字段。
数据库索引以及注意点?
数据库索引
1、表的主键、外键必须有索引;
2、数据量超过300的表应该有索引;
3、经常与其他表进行连接的表,在连接字段上应该建立索引;
4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
5、频繁进行数据操作的表,不要建立太多的索引;
6、删除无用的索引,避免对执行计划造成负面影响;
注意事项
- 限制表上的索引数目
- 对复合索引,按照字段在查询条件中出现的频度建立索引
- 删除不再使用,或者很少被使用的索引
- 对复合索引,按照字段在查询条件中出现的频度建立索引
drop、delete和truncate区别?
delete删除的时候就是一条一条的删除记录,它可以配合事务,将删除掉的数据找回。
truncate删除,它是将整个表摧毁,然后再创建一张一模一样的表,它删除的数据无法找回。
执行计划和慢日志?
执行计划
1、作用
预估sql语句执行的时间,一般准确
2、格式:
explain sql语句
3、type类型的快慢(all最慢,const最快)
all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
慢日志
1、基于内存
a)、执行时间和log文件
查看:show variables like ‘%query%’;
b)、查看未命中索引
show variables like ‘%queries%’;
c)、修改
set global long_query_time= 2;
set global slow_query_log=ON
set global slow_query_log_file=文件的绝对路径
set global log_queries_not_using_indexes=ON
2、基于配置文件
a)、启用配置文件
mysqld --defaults-file 配置文件(可以自定义,也可用默认),建议备份
b)、配置文件内容
long_query_time= 2;
slow_query_log=ON
slow_query_log_file=文件的绝对路径
log_queries_not_using_indexes=ON
…
c)、重启服务
net stop mysql
net start mysql
数据库负载均衡
为了处理海量数据的存储与访问。
原理
首先要有一个链接数据库的控制端,这个控制端处于程序与数据库的中间。当对数据进行处理的时候,会先经过这个中间层来,有这个中间层来确定访问哪个数据库,根据当前数据库的负载情况采取有效的均衡策略。
多数据库数据同步
读写分离
大多数互联网业务,往往读多写少,这时候,数据库的读会首先称为数据库的瓶颈,这时,如果我们希望能够线性的提升数据库的读性能,消除读写锁冲突从而提升数据库的写性能,那么就可以使用“分组架构”。读写分离是用来解决数据库的读性能瓶颈的。
- 将数据库分为了主从库,一个主库用于写数据,多个从库完成读数据的操作,主从库之间通过某种机制进行数据的同步,是一种常见的数据库架构。
- 一个主从同步集群,通常被称为是一个“分组”。
数据库/数据表拆分
ORM缺点和优点
ORM的技术不用考虑复杂的SQL语句,提高了开发效率,同时ORM会牺牲程序的执行效率和会固定思维模式.
js中this的使用
this只有在执行的时候才能确认,定义时无法被确认。
Web框架
Http协议
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
一次完整的HTTP请求过程
- 对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址
- 根据这个IP,找到对应的服务器,发起TCP的三次握手
- 建立TCP连接后发起HTTP请求
- 服务器响应HTTP请求,浏览器得到html代码
- 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)(先得到html代码,才能去找这些资源)
- 浏览器对页面进行渲染呈现给用户
- 服务器关闭关闭TCP连接
请求头和响应头
请求头
Connection:表示是否需要持久连接
Content-Length:表示请求消息正文的长度。(请求体)
Cookie:这是最重要的请求头信息之一
Cache-Control:表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒。
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
响应头
Connection:表示是否需要持久连接。
Set-Cookie:设置HTTP cookie。
Last-Modified 文档的最后改动时间。
Expires 应该在什么时候认为文档已经过期,从而不再缓存它?
常用的HTTP请求方法
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
- OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性 - HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。 - GET
向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在Web Application中,其中一个原因是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数:web_link和web_url - POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form - PUT
向指定资源位置上传其最新内容 - DELETE
请求服务器删除Request-URL所标识的资源 - TRACE
回显服务器收到的请求,主要用于测试或诊断 - CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
Django请求生命周期
-
当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中. -
url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了. -
视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
-
客户端浏览器接收到返回的数据,经过渲染后显示给用户.
FBV模式和CBV模式
一个url对应一个视图函数,这个模式叫做FBV(Function Base Views),除了FBV之处,Django中还有另外一种模式叫做CBV(Class Base views),即一个url对应一个类。
什么是WSGI
定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器对接起来。
Django高并发负载均衡
什么是负载均衡
当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能。那么,在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台服务器的负载情况将请求分配给某一台后端服务器去处理。
那么在这个过程中,调度者如何合理分配任务,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整体性能最优,这就是负载均衡问题。
链接
cookie和session的区别
cookies
位于用户的计算机上,用来维护用户计算机中的信息,直到用户删除
session
session称为会话信息,位于web服务器上,主要负责访问者与网站之间的交互,当访问浏览器请求http地址时,将传递到web服务器上并与访问信息进行匹配, 当关闭网站时就表示会话已经结束,网站无法访问该信息了,所以它无法保存永久数据,我们无法访问以及禁用网站
-
Cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量。它只允许4kb它没有在cookie中保存多个变量。
-
cookie的存储限制了数据量,只允许4KB,而session是无限量的
-
我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
-
设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
TCP/IP 三次握手,四次挥手
TCP三次握手
所谓三次握手,是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.在socket编程中,客户端执行connect()时。将触发三次握手。
(1) 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)异步序列编码到服务器B,并进入SYN_SEND状态,等待服务器B确认。
(2) 第二次握手:服务器B收到SYN包,必须确认客户A的ACK(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
(3) 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
TCP 四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端。
(4) 客户端发回ACK报文确认,并将确认序号设置为收到序号加1
socket通信
服务器:
-
创建一个socket
-
bind一个句柄(端口和地址)
-
listen设置监听的客户数
-
accept客户端的句柄
-
读写。
客户机:
-
创建一个socket
-
connect到服务器
-
读写操作。