一单例模式
类:具体相同特征的一类事物,类似于模板
单例:常用的软件设计模式,用于设计一个类中只有一个实例且易于外界访问,可以对实例的个数控制并节约系统资源
运用场景:比如某个服务器程序的配置信息,它放在一个文件中,客户端通过一个类来读取配置文件的信息,在程序运行期间,很多地方
需要创建实例,使用单例模式可以很多的节省内存资源,尤其是配置文件内容很多的情况下
class Singleton(object): __instance=None def__init__(self): pass def__new__(cls,*args,**kwd): if Singleton.__instance is None: Singleton.__instance=object.__new__(cls,*args,**kwd) return Singleton.__instance
二打印前一天的本地时间
import datetime now=datetime.datetime.now() print(now) #2018-08-13 09:58:00.700589 print(datetime.timedelta(seconds=1)) #0:00:01 timedelta表示的是时分秒 yes=now-datetime.timedelta(days=1) print(yes.strftime('%Y-%m-%d')) #2018-08-12
三同步,异步,阻塞,非阻塞,并发,并行
同步:当一个进程发起一个函数(任务)调用的时候,一直等到函数(任务)完成,而进程继续处于激活状态
异步:当一个进程发起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行,函数返回的时候
通过状态,通知,事件等方式通知进程任务完成
阻塞和非阻塞针对的是进程和线程:阻塞是当请求不能满足的时候就将进程挂起,而非阻塞不会,
阻塞情况:例如 recv sleep accept input recvfrom等
并行:是指两者同时执行,利用了cpu的多核,从微观考虑,在一个精确的时间片刻,有不同的程序在执行
并发:指两者交替使用资源执行,从宏观考虑,在一个时间段上看出是同时执行的
异步非阻塞: 进程调用函数执行,不等待结果返回就执行其他的命令或函数
四 黏包
黏包现象出现在tcp协议中,而不出现在udp协议中,
tcp协议是面向连接的流式协议,发送端需要等缓冲区满才发送出去,这样数据小的话就会合到一块产生黏包
还有一种情况是:接收方不能及时收取缓冲区的包,造成多个包同时接收,产生黏包
udp协议是数据报协议,面向消息的,采用链式结构记录每一个到达的udp包,每个udp包的消息头中都有消息来源地址和端口信息
易于区分处理
总之:黏包现象的原因是接收方不知道消息之间的界限,不知道一次性提取多少字节的数据,
解决方法:提前告知要接收的数据信息,比如名称,大小等等
五管道和队列
管道:支持双向通信,用于进程之间的通信
队列:在管道的基础上加了锁,保证数据不会被进程重复取出
六打印九九乘法表
利用字符串的判断,拼接打印处理
print(''.join([str(a) +"*"+ str(b) +"="+ str(a * b) + str('\n' if a==b else '\t') for a in range(1, 10) for b in range(1, a+1)]))
七 select poll epoll模型
io多路复用:通过一种机制,可以监视多个文件描述符,一旦描述符就绪(读就绪和写就绪),能通知程序进行相应的读写操作。
I/O多路复用避免阻塞在io上,原本为多进程或多线程来接收多个连接的消息变为单进程或单线程保存多个socket的状态后轮询处理.
select:通过select函数发出io请求后,线程阻塞,一直到数据准备完毕,然后才能把数据从核心空间拷贝到用户空间,同步阻塞方式
poll:通过poll函数发出IO请求后,线程阻塞,直到数据准备完毕,poll函数在pollfd中通过revents字段返回事件,然后线程把数据从核心空间拷贝到用户空间,
所以poll同样是同步阻塞方式,性能同select相比没有改进
epll:由专门的内核线程来不停地扫描fd列表,有结果后,把结果放到fd相关的链表中,用户线程只需要定期从该fd对应的链表中读取事件就可以了
属于异步非阻塞,例如nginx
八生成器表达式和列表推导式内含函数的区别
z = [lambda x:x*i for i in range(3)] x = [o(2) for o in z] print(x) #[4,4,4] for k in range(3): i=k print(i) ----> 2
z = (lambda x:x*i for i in range(3)) x = [o(2) for o in z] print(x) #[0,2,4]
生产器表达式:一次读取一个值用来计算
列表推导式:全部读取完成在接着处理其他的函数
九 关于线程gevent的补丁---顶格写问题
在使用线程的时候往往要加入补丁:from
gevent
import
monkey;monkey.patch_all()
它会把下面导入的所有的模块中的IO操作都打成一个包,gevent就能够认识这些IO了
这行必须顶格写,要不然下面出现i/o阻塞时,会夯住
其他 十 six模块
由一次查找到性能调优看到了six模块:
网址:http://tech.glowing.com/cn/python-web-performance-optimization/
众所周知 Python 2 和 Python 3 版本的分裂给 Python 开发者们带来了很大的烦恼,为了使代码同时兼容两个版本,往往要增加大量的代码。 于是 Six 出现了。正如它的介绍所说,它是一个专门用来兼容 Python 2 和 Python 3 的库。它解决了诸如 urllib 的部分方法不兼容, str 和 bytes 类型不兼容等“知名”问题。
import six,sys print(six.PY2) #python2结果为True print(six.PY3) #python3结果为True sys.version_info[0] #PY2 = 2 sys.version_info[0] #PY3 = 3 sys.version_info[0:2] #PY34>= (3, 4)
body=b'hehe' body1='hehe' s=isinstance(body,six.binary_type) s1=isinstance(body1,six.binary_type) print(s) #True print(s1) #False