您的位置:首页 > 编程语言 > Python开发

常见的Python面试题

2017-11-10 09:31 239 查看

引言

面试Python开发岗位时,不仅仅要会手撸代码,还要对Python的原理以及整体的架构有一个了解。下面整理了面试时常问的Python问题。

常见问题

1、python的垃圾回收机制

Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。

引用计数

原理:当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1;当对象的引用计数减少为0时,就意味着对象已经没有被任何人使用了,可以将其所占用的内存释放了。

优点:简单,实时

缺点:

1、维护引用计数消耗资源

2、循环引用——致命弱点。(两个对象相互调用)时无法清理内存,发生内存泄露(无法及时清理内存造成系统浪费)。因此有下面两个方法的出现。

标记-清除

『标记清除(Mark—Sweep)』算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的『活动对象』打上标记,第二阶段是把那些没有标记的对象『非活动对象』进行回收。

对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。

分代回收

Python中使用了某些启发式算法(heuristics)来加速垃圾回收。例如,越晚创建的对象更有可能被回收。对象被创建之后,垃圾回收器会分配它们所属的代(generation)。每个对象都会被分配一个代,而被分配更年轻代的对象是优先被处理的。

2、Python是一门什么样的语言

解释型,运行前不需要编译

动态型,声明变量时不需要指定类型

面向对象。

(1)面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用,类是一个模板,模板中包装了多个“函数”供使用,对象是根据模板创建的实例,实例用于调用被包装在类中的函数

(2)面向对象三大特性:封装、继承和多态

封装

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

继承

Python可以继承多个类。Java只能继承一个类。

当类是经典类时,多继承情况下,会按照深度优先方式查找

当类是新式类时,多继承情况下,会按照广度优先方式查找

多态

当子类和父类都存在相同的方法时,子类拥有多个相同的方法,但子类的方法覆盖了父类的方法。

代码编写快,运行速度慢

具有丰富第三方模块,用途广(网络应用,自动化,科学建模,大数据应用)

3、对Python多线程的理解

Python中使用线程的两种方式:函数和类。

函数式

调用thread模块中的start_new_thread()函数来产生新线程



使用Threading模块创建线程,直接从threading.Thread继承,然后重写init方法和run方法

Python多线程机制

python无法高效使用多线程。

Python多线程机制是在GIL(Global Interpreter Lock)全局解释锁的基础上建立的

Python中的GIL是一个非常霸道的互斥实现,在任意时间只有一个Python解释器在解释Python bytecode。

使用GIL时,保护机制的粒度比较大,也就是我们似乎只需要将可能被多个线程共享的资源保护起来即可,对于不会被多个线程共享的资源,完全可以不用保护。但是,如果使用更细粒度的锁机制进行保护,那么,会导致大量的加锁和解锁功能,加锁和解锁对于操作系统来说,是一个比较重量级的动作,同时,没有GIL的保护,编写Python的扩展模块的难度也大大增加。

如果你的代码是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有上下文切换。如果你的代码是IO密集型,多线程可以明显提高效率。例如制作爬虫,绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行。

4、如何管理不同版本的代码?

git

5、“猴子补丁”(monkey patching)指的是什么?这种做法好吗?

“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。

举个例子:

import datetime

datetime.datetime.now = lambda: datetime.datetime(2012, 12, 12)

大部分情况下,这是种很不好的做法 - 因为函数在代码库中的行为最好是都保持一致。打“猴子补丁”的原因可能是为了测试。mock包对实现这个目的很有帮助。

未完待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 面试题 面试