08.python面试之设计模式

设计模式是对各种问题进行提炼和抽象而形成的解决方案。这些方案是前人不断试验,考虑了封装性、复用性、效率、可修改、可移植等因素的高度总结。

对设计模式的理解,简述你了解的设计模式?

设计模式是经过总结,优化的,对我们经常会碰到的一些编程问题的可重用解决方案。一个设计模式并
不像一个类或一个库那样能够直接作用于我们的代码,反之,设计模式更为高级,它是一种必须在特定
情形下实现的一种方法模板。
常见的是工厂模式和单例模式

请手写一个单例

1
2
3
4
5
6
7
8
class Singleton:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
a = Singleton()
b = Singleton()
print(id(a), id(b))
2449262346824 2449262346824

单例模式的应用场景有那些?

单例模式应用的场景一般发现在以下条件下:

资源共享的情况下,避免由于资源操作时导致的性能或损耗等,如日志文件,应用配置。

控制资源的情况下,方便资源之间的互相通信。如线程池等,1,网站的计数器 2,应用配置 3.多线程池 4.数据库配置 数据库连接池 5.应用程序的日志应用…

用一行代码生成[1,4,9,16,25,36,49,64,81,100]

[x*x for x in range(1,101)]

对装饰器的理解,并写出一个计时器记录方法执行性能的装饰器?

装饰器本质上是一个callable object ,它可以让其他函数在不需要做任何代码变动的前提下增加额外功
能,装饰器的返回值也是一个函数对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import time
import random
def wrapper(func):
def innner():
start = time.perf_counter()
func()
end = time.perf_counter()
print(f"{func}用时:{end-start}")
return innner

@wrapper
def test():
for i in range(3):
time.sleep(random.random()*2)
print("test运行完了")

test()


test运行完了
<function test at 0x0000023A43675AF8>用时:3.7451501

解释以下什么是闭包?

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。

函数装饰器有什么作用?

装饰器本质上是一个callable object,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能。装饰器的返回值也是一个函数的对象,它经常用于有切面需求的场景。比如:插入日志,性能测试,事务处理,缓存。权限的校验等场景,有了装饰器就可以抽离出大量的与函数功能本身无关的雷同代码并发并继续使用。

生成器,迭代器的区别?

迭代器是遵循迭代协议的对象。用户可以使用 iter() 以从任何序列得到迭代器(如 list, tuple,dictionary, set 等)。另一个方法则是创建一个另一种形式的迭代器 —— generator 。要获取下一个元素,则使用成员函数 next()(Python 2)或函数 next() function (Python 3) 。当没有元素时,则引发 StopIteration 此例外。若要实现自己的迭代器,则只要实现 next()(Python 2)或 next ()(Python 3)

生成器(Generator),只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)

区别: 生成器能做到迭代器能做的所有事,而且因为自动创建iter()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常。

X是什么类型?

1
X= (i for i in range(10))

X是 generator类型(生成器)

请用一行代码 实现将1-N 的整数列表以3为单位分组

1
2
results = [list(range(20))[i:i+3] for i in range(1,20,3)]
print(results)
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18], [19]]

Python中yield的用法?

yield就是保存当前程序执行状态。你用for循环的时候,每次取一个元素的时候就会计算一次。用yield的函数叫generator,和iterator一样,它的好处是不用一次计算所有元素,而是用一次算一次,可以节省很多空间,generator每次计算需要上一次计算结果,所以用yield,否则一return,上次计算结果就没了