Python面试题分享(五)

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 密集型操作(读写数据操作较多的,比如爬虫、网络编程)。

猜你喜欢

转载自blog.csdn.net/qq_39581763/article/details/91949213