面试题python语法以及其他基础部分

1.列表推导list comprehension和生成器的优劣?

列表解析代替了可以代替lambda, map, filter函数, 减少函数调用次数, 提高效率。
受到内存限制,列表容量肯定是有限的, 创建一个一百万元素的列表, 如果我们只用到前面几个元素, 那么绝大部分空间都被浪费了。
生成器表达式并不创建一个真正的列表, 返回一个生成器, 每次调用next返回下一个元素,遍历完抛出stopIteration的异常, 并且我们经常通过for循环来迭代它, 从而不需要关心stopIteration异常。


2.什么是装饰器;如果想在函数之后进行装饰,应该怎么做?

可以在让其它函数不做任何变动的情况下提供额外的功能, 前些日子我在用flask开发web程序的时候用到了@before_app_request这个装饰器, 钩子函数的作用是检查如果是已登录未验证用户要重定向要未验证页面, 我们不可能在每个路由里面添加这个判断, 那样会产生大量重复代码, 用了装饰器以后,我们就可以减少代码的重复量。
把装饰器函数(被装饰函数)赋值给被装饰函数。

3.手写个使用装饰器实现的单例模式?
单例模式:
  1,一个类只能有一个实例
  2,自己创建这个实例

  3,整个系统都要使用这个实例

def single01(cls):

    a = []

    def wrap(*args, **kwargs):

        if not s:

            s.append(cls(*args, **kwargs))

        return s

    return wrap


@single01

class A(object):

    def __init__(self, name):

        self.name = name

A("tmac") = single01(A)("tmac") = wrap("tmac")

a = A("tmac")

b = A("kobe") = wrap("kobe")


4.使用装饰器的单例和使用其他方法的单例,在后续使用中,有何区别??


5.手写:正则邮箱地址;

登录名@主机名.域名

r'^[0-9a-zA-Z_]{0, 19}@[0-9a-zA-Z]{0-13}\.(com|net|cn)$'


6.介绍下垃圾回收:引用计数/分代回收/孤立引用环;

引用计数: python里一切皆为对象, 比方说赋值操作x=1, y=1, x和y的地址是相同的, 都指向1这个对象, 这时1的引用计数是2, 再执行赋值语句x=2, y=2, 那么x和y都指向2这个整型对象, 1的引用计数变为0, 于是1被回收机制回收, 从内存删除。

何时进行垃圾回收:频繁的垃圾回收会影响工作效率, 于是在内存中分配对象和取消分配对象的差值达到一定阙值的时候, 才会进行垃圾回收, gc模块的get_threshold函数可以查看该阙值, 调用返回(700, 10, 10), 700就是我们之前说的阙值, 后面两个10与后面的分代回收有关。

分代回收: 这一策略的基本假设是存活越久的对象, 越不可能在后面的程序中变成垃圾, 我们将所有的对象分为0, 1, 2三代, 垃圾扫描时, 每次都扫面0代对象, 达到一定次数时转为扫描0, 1代对象, 再达到一定次数时, 扫描0,1,2代对象, 上面所说的两个次数就是get_threshold返回的元组的后两个值。

我们可以用set_threshold来改变阙值, 增加1代或2代对象的扫描频率。

孤立引用环:

a = []

b = [a]

a.append(b)

此时a所引用的兑现指向b所引用的对象, b所引用的对象指向a所引用的对象, 即使删除了a,b两个引用, 两个对象的引用计数也不为0, 不会被回收, 但程序已经无法利用这两个对象了。

如何回收引用环?

为了回收这样的引用环, python复制每个对象的引用计数, 记为gc_ref, 对象i的引用计数记为gc_ref_i, python会遍历所有的对象, 对象i引用的对象j的引用计数gc_ref_j会减1;

在结束遍历后, gc_ref不为0的对象, 和该对象引用的对象, 以及下游被引用的对象都会保留, 其它的对象会被回收。

7.多进程与多线程的区别;CPU密集型适合用什么?

进程是cpu资源分配的最小单位,线程是cpu调度的最小单位, 一个进程包含多个线程。

多进程和多线程的区别, CPU密集型适合什么?

多进程的稳定性高, 但创建进程的代价大
多线程的效率高, 但稳定性低
适合C语言多线程;主要消耗CPU资源, 代码运行效率至关重要;采用C语言;

IO密集型适合脚本语言多线程, 绝大部分时间用在等待IO操作上, 采用运行效率高的C语言不合算, 于是采用开发效率高的python语言。

8.进程通信的方式有几种?   

管道,FIFO,消息队列,信号量,共享内存区

9.介绍下协程,为何比线程还快?

协程类似于线程, 基于线程, 但是协程允许一个执行过程A中断, 转而执行过程B, 然后再执行过程A;

优势在于:

协程理论上数量有无限个, 没有线程之间的切换动作,所以比较快;

没有锁机制, 因为所有协程都在一个线程中;

10.range和xrange的区别?

range返回一个列表, xrange返回一个生成器, 数据比较多的时候用xrange比较省内存, 不会一上来就开辟一个很大的内存空间;




猜你喜欢

转载自blog.csdn.net/sinat_34927324/article/details/79724552