查看原文
其他

Python面试题(01)

Ahab杂货铺 2019-02-15

  点击上方“Ahab杂货铺”,选择“置顶公众号”

技术分享第一时间送达!



写在前面

这个周末没有更新粉丝还有增长挺开心的,感谢大家的支持。在学习python的时候看了很多面试题,以巩固自己学过的知识,自己会整理一下分享给大家,今天的十个题算是以往面试中出现频率较高的,自己这个模块的初衷就是希望分享的东西能够在面试过程中给大家提供一点帮助。


问题清单

1. python下多线程的限制以及多进程中传递参数的方式

2.  python多进程与多线程的区别

3. Python是如何进行内存管理的?

4. 介绍一下Python中webbrowser的用法?

5. 简单概述python的GIL?

6. 简述面向对象中_ _new_ _和_ _init_ _区别?

7. Python里面search()和match()的区别?

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

9. 这两个参数是什么意思:*args,**kwargs?我们为什么要使用它们?

10. 简述Python 中的垃圾回收机制


1、python下多线程的限制以及多进程中传递参数的方式


python多线程有个全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一个线程使用解释器,跟单cpu跑多个程序一个意思,大家都是轮着用的,这叫“并发”,不是“并行”。多进程间共享数据,可以使用 multiprocessing.Value 和 multiprocessing.Array。


2、python多线程与多进程的区别 

  • 在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie)。所以,有必要对每个Process对象调用join()方法 (实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。

  • 多进程应该避免共享资源。在多线程中,我们可以比较容易地共享资源,比如使用全局变量或者传递参数。在多进程情况下,由于每个进程有自己独立的内存空间,以上方法并不合适。此时我们可以通过共享内存和Manager的方法来共享资源。但这样做提高了程序的复杂度,并因为同步的需要而降低了程序的效率。



3、Python是如何进行内存管理的?

Python引用了一个内存池(memory pool)机制,即Pymalloc机制(malloc:n.分配内存),用于管理对小块内存的申请和释放。
内存池(memory pool)的概念:
  当 创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,致使效率降低。内存池的概念就是预先在内存中申请一定数量的,大小相等 的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片,提升效率。
内存池的实现方式有很多,性能和适用范围也不一样。
python中的内存管理机制——Pymalloc:
  python中的内存管理机制都有两套实现,一套是针对小对象,就是大小小于256bits时,pymalloc会在内存池中申请内存空间;当大于256bits,则会直接执行new/malloc的行为来申请内存空间。
  关于释放内存方面,当一个对象的引用计数变为0时,python就会调用它的析构函数。在析构时,也采用了内存池机制,从内存池来的内存会被归还到内存池中,以避免频繁地释放动作



4、介绍一下Python中webbrowser的用法?

webbrowser模块提供了一个高级接口来显示基于Web的文档,大部分情况下只需要简单的调用open()方法。
webbrowser定义了如下的异常:
exception webbrowser.Error, 当浏览器控件发生错误是会抛出这个异常
webbrowser有以下方法:
webbrowser.open(url[, new=0[, autoraise=1]])
这个方法是在默认的浏览器中显示url, 如果new = 0, 那么url会在同一个浏览器窗口下打开,如果new = 1, 会打开一个新的窗口,如果new = 2, 会打开一个新的tab, 如果autoraise = true, 窗口会自动增长。
webbrowser.open_new(url)
在默认浏览器中打开一个新的窗口来显示url, 否则,在仅有的浏览器窗口中打开url
webbrowser.open_new_tab(url)
在默认浏览器中当开一个新的tab来显示url, 否则跟open_new()一样
webbrowser.get([name]) 根据name返回一个浏览器对象,如果name为空,则返回默认的浏览器
webbrowser.register(name, construtor[, instance])
注册一个名字为name的浏览器,如果这个浏览器类型被注册就可以用get()方法来获取。



5、简单概述python的GIL?

    GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。

多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大

6、简述面向对象中_ _new_ _和_ _init_ _区别

_ _init_ _是初始化方法,创建对象后,就立刻被默认调用了,可接收参数。

1、_ _new_ _至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别

2、_ _new_ _必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))_ _new_ _出来的实例,或者直接是object的_ _new_ _出来的实例

3、_ _init_ _有一个参数self,就是这个_ _new_ _返回的实例,_ _init_ _在_ _new_ _的基础上可以完成一些其它初始化的动作,_ _init_ _不需要返回值

4、如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,那么实际创建返回的就是其他类的实例,其实就不会调用当前类的_ _init_ _函数,也不会调用其他类的_ _init_ _函数。


7、Python里面search()和match()的区别?

match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none

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


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

举个例子:

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

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



9、这两个参数是什么意思:*args**kwargs?我们为什么要使用它们?

如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args;如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargsargskwargs这两个标识符是约定俗成的用法,你当然还可以用*bob**billy,但是这样就并不太妥。



10、简述Python 中的垃圾回收机制


Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』,该算法最早George E. Collins在1960的时候首次提出,50年后的今天,该算法依然被很多编程语言使用,『引用计数法』的原理是:每个对象维护一个ob_ref字段,用来记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数ob_ref加1,每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0,该对象立即被回收,对象占用的内存空间将被释放。它的缺点是需要额外的空间维护引用计数,这个问题是其次的,不过最主要的问题是它不能解决对象的“循环引用”,因此,也有很多语言比如Java并没有采用该算法做来垃圾的收集机制。




            

欢迎您的点赞和分享

▲长按关注此公众号

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存