python高级3
1. 单例模式的应用场景?
单例模式应用的场景一般发现在以下条件下
①. 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件,应用配置。
②. 控制资源的情况下,方便资源之间的互相通信。如线程池等。
网站的计数器
应用配置
多线程池
数据库配置,数据库连接池
应用程序的日志应用
2. 什么是闭包?
在函数内部嵌套了一个函数,内函数使用了外函数的局部变量,并且外函数返回了内函数的引用,这样就构成了一个闭包。
def outfunc(a,b):
def innerfunc(x):
return x*a+b
return innerfunc
3. 装饰器的本质-闭包
装饰器的作用:在不违反开放封闭的原则下对现有的函数进行功能扩充,比如插入日志、性能测试、事务处理、缓存、 权限的校验等场景,有了装饰器就可以抽离出大量的与函数功能本身无关的雷同代码。函数计时的装饰器:
import time
def timeit(func):
def wrapper():
start = time.time()
func()
end =time.time()
print('used:', end - start)
return wrapper
@timeit
def foo():
for i in range(10000):
pass
foo()
# foo = timeit(foo)
程序运行到装饰器的时候,会立即对下面的函数进行装饰 带参数的装饰器:
4.多线程,多进程
多线程的使用:
def func(x):
print(x)
t= threading.Thread(target=func,args=(12,))
# 线程启动
t.start()
# 主进程阻塞,等待子进程的退出
多进程的使用
from multiprocessing import Process
def func(x):
print(x)
p = Process(target=func,args=(12,))
p.start()# 启动子进程实例(创建子进程)
p.is_alive()# 判断进程子进程是否还在活着
p.join(timeout)# 是否等待子进程执行结束,或者等待多少秒
p.terminate()# 不管任务是否完成,立即终止子进程
p.daemon = True # 设置守护进程
5. 线程池、进程池的使用:
# 进程池
from multiprocessing import Pool
# 线程池
from multiprocessing.dummy import Pool
pool = Pool(5) # 同时最大运行线程或者进程个数
def _excute(x,y):
print(x+y)
def _callback(self, temp): # temp必有参数
print("线程或进程任务完成后的回调")
pool.apply_async(target=_excute, callback=_callback)
poll.close()# 关闭Pool,使其不再接受新的任务;
poll.terminate()# 不管任务是否完成,立即终止;
poll.join()# 主进程阻塞,等待子进程的退出,必须在close或terminate之后使用
6. 进程或者线程的间通信工具--Queue
# 线程池、多线程 使用的Queue
from queue import Queue
# 多进程使用的queue
from multiprocessing import JoinableQueue as Queue
# 进程池使用的queue
from multiprocessing import Manager
queue = Manager().Queue()
queue = Queue()
queue.qsize()# 返回当前队列包含的消息数量。
queue.empty()# 如果队列为空,返回True,反之False。
queue.full()# 如果队列满了,返回True,反之False。
queue.put(item, block=True, timeout=None)
"""将item消息写入队列,block默认值为True;
如果block使用默认值,且没有设置timeout(单位秒),消息列队如果已经没有空间可写入,此时程序将被阻塞(停
在写入状态),直到从消息列队腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没空间,则抛
出"Queue.Full"异常;
如果block值为False,消息列队如果没有空间可写入,则会立刻抛出"Queue.Full"异常;
"""
queue.get(item, block=True, timeout=None)
"""
获取队列中的一条消息,然后将其从队列中移除,block默认值为True。如果block使用默认值,且没有设置
timeout(单位秒),消息列队如果为空,此时程序将被阻塞(停在读取状态),直到从消息列队读到消息为止,如果
设置了timeout,则会等待timeout秒,若还没读取到任何消息,则抛出"Queue.Empty"异常;
如果block值为False,消息列队如果为空,则会立刻抛出"Queue.Empty"异常;
"""
# get方法并不能让queue的计数-1,必须调用task_done
queue.task_done()
queue.join() # 主程序阻塞,等待队列计数为0时才继续向下执行
7. 什么是死锁呢?
若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不愿先解锁,互相干等着,程序无法执行下去,这就是死锁。GIL全局解释器锁(cpython): 限制多线程同时执行,保证同一时刻只有一个线程执行,所以cpython里的多线程其实是伪多线程! 所以Python里常常使用协程技术来代替多线程,协程是一种更轻量级的线程,进程和线程的切换时由
系统决定,而协程由我们程序员自己决定,而模块gevent下切换是遇到了耗时操作才会切换。三者的关系:进程里有线程,线程里有协程
8. CPython, Pypy, Jython
1.CPython
CPython是用C语言实现Pyhon,是目前应用最广泛的解释器。Python最新的语言特性都是在这个上面先实
现,Linux,OS X等自带的也是这个版本,CPython是官方版本加上对于C/Python API的全面支持,基本包
含了所有第三方库支持,例如Numpy,Scipy等。但是CPython有几个缺陷,一是全局锁使Python在多线程
效能上表现不佳,二是CPython无法支持JIT(即时编译),导致其执行速度不及Java和Javascipt等语言
2.Pypy
Pypy是用Python自身实现的解释器。针对CPython的缺点进行了各方面的改良,性能得到很大的提升。最重
要的一点就是Pypy集成了JIT。但是,Pypy无法支持官方的C/Python API,导致无法使用例如Numpy,Scipy
等重要的第三方库。
3.Jython
Jython是将Python code在JVM上面跑和调用java code的解释器。
9. 同步,异步,阻塞,非阻塞?
同步:多个任务之间有先后顺序执行,一个执行完下个才能执行。
异步:多个任务之间没有先后顺序,可以同时执行
阻塞:卡住调用者,调用者不能继续往下执行
非阻塞:调用者不会卡住,可以继续执行,就是说非阻塞的。
同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言。
10. Python中的进程与线程的使用场景?
多进程适合在 CPU 密集型操作(cpu 操作指令比较多,如位数多的浮点运算)。
多线程适合在 IO 密集型操作(读写数据操作较多的,比如爬虫、网络编程)。