算法工程师面试题之Python(写给自己,不断更新)

 为什么python比较慢,全局解释器锁是什么, 如何解决其带来的限制

1)python慢有两大原因,一是python是动态型语言,边解释边执行。而是GIL无法利用多核GPU并发执行。

2)GIL是计算机程序语言解释器用于同步线程的机制,使得在任意时刻仅有一个线程在执行,是为了解决多线程之间数据完整性和状态同步的问题。

3)多线程threading机制依然是有用的,可以用于IO密集型计算,因为在I/O期间,线程会释放GIL,实现GPU和IO的并行。python提供了multiprocessing多进程机制,实现并行计算、利用多核CPU优势。

进程与线程的区别

1)进程是系统资源分配、调度和管理的最小单位。资源开销大,进程之间存在内存隔阂,进程之间互不影响。进程能高并发和高并行,适用于CPU密集型。

2)线程是CPU分配的最小单位,资源开销小。同一进程中的线程数据共享,如果一个线程奔溃,会影响道进程其他线程。因为全局解释器锁GIL的存在,线程能高并发不能高并行。适用于IO密集型,因为I/O时,会释放GIL,使得I/O可以与GPU并行。

3)关系:进程中第一个线程是主线程,主线程可以创建其他线程,其他线程也可以创建线程。所以一个进程至少有一个线程,可以有多个线程。

python字典的删除实现

1)clear()方法,删除字典全部元素,例如某一字典变量为 dic:dic.clear()

2)pop()方法,删除指定key的键值对,并返回被删除的键值对:print(dic.pop(key))

3)popitem()方法,随机删除某一个键值对,并返回被删除的键值对:print(dic.popitem())

4)del()全局方法,可以删除指定键值对,也可以清空字典:del dic[key]   del dic

迭代器与生成器的区别

1)迭代器支持next操作,可以看出是用for循环对容器进行一次遍历。迭代器从容器的第一个元素开始访问,直到访问完所有的元素,只能向前,不能向后,遍历一遍后,元素被取光了,如果还想用,就得重新生成(这一点与列表不同)。迭代器有两个实现方法iter,next

my_list = [5,3,9]
my_iter = iter(my_list)    # 通过iter()获得迭代器
print(next(my_iter))       # 输出5,使用next进行遍历
print(my_iter.__next__())  # 输出3
print(next(my_iter))       # 输出9
next(my_iter)              # 没有元素了,报错

2)生成器generator是一种特殊的迭代器,使用 yield 函数。生成器返回的是一个迭代器对象,但需要每次指向 yield 时再生成元素。调用生成器时,每次遇到yield就暂停,并保存当前所有的运行信息,返回yield值,并在下一次执行next()时从当前位置继续执行。

my_genertor = (x*x for x in range(3))  # 定义生成器,与列表类似,不过需要将[]换成()
my_genertor.next()  # 输出0
my_genertor.next()  # 输出1
my_genertor.next()  # 输出4
my_genertor.next()  # 异常

# yield方法
def fun_yield(n):
    print("starting the fun_yield") # 调用生成器只会打印一次这句话
    for i in range(n):
        yield i*i

g = fun_yield(3)  # 创建一个生成器
print(g)          # <generator object gen at 0x10bb46f50>
print(type(g))    # <type 'generator'>
next(g)           # 输出0

yield 和 return 区别

1)return:在程序函数中返回某个值,返回后函数不再继续执行,彻底结束

2)yield:带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后暂停。再次调用时,在暂停的地方继续执行

什么是装饰器

1)装饰器就是在步修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能。当我们想为一个已经定义好的函数添加额外的小功能时,例如计算该函数运行时长,输出某句话等,装饰器则就是在不改变原函数下,增加这些功能。此外若有很多函数需要增加相同的功能,一个一个修改函数是很麻烦的,此时可以定义装饰器,然后在每个函数前@装饰器即可。

# 原函数带参数,带返回值的装饰器例子(给原函数增加输出函数运行时长的功能)
def timer(func):             # 该装饰器的参数func指的是原函数
    def wrapper(*args):      # 表示非键值对可变参数
        start = time.time()
        val = func(*args)    # 运行函数,val为函数返回值
        end = time.time()
        print('total time:{:.4}'.format(end-start))  # 输出时间,保留四位有效数字
        return val
    return wrapper


@timer                       # 加在需要修饰的原函数前
def litter_fun(num):
    num *= num
    return num
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值