python 面试相关


非技术性的问题就是以上这么多,作为参考稍加准备,面试的时候就能对答如流。下面讲一下在面试中的技术性问题。个人感觉技术性的问题面试官问的没有特别多,一般考察2-3个,由浅到深。

  1. 简述函数式编程

    在函数式编程中,函数是基本单位,变量只是一个名称,而不是一个存储单元。除了匿名函数外,Python还使用fliter(),map(),reduce(),apply()函数来支持函数式编程。

  2. 什么是匿名函数,匿名函数有什么局限性

    匿名函数,也就是lambda函数,通常用在函数体比较简单的函数上。匿名函数顾名思义就是函数没有名字,因此不用担心函数名冲突。不过Python对匿名函数的支持有限,只有一些简单的情况下可以使用匿名函数。

  3. 如何捕获异常,常用的异常机制有哪些?

    如果我们没有对异常进行任何预防,那么在程序执行的过程中发生异常,就会中断程序,调用python默认的异常处理器,并在终端输出异常信息。

    try...except...finally语句:当try语句执行时发生异常,回到try语句层,寻找后面是否有except语句。找到except语句后,会调用这个自定义的异常处理器。except将异常处理完毕后,程序继续往下执行。finally语句表示,无论异常发生与否,finally中的语句都要执行。

    assert语句:判断assert后面紧跟的语句是True还是False,如果是True则继续执行print,如果是False则中断程序,调用默认的异常处理器,同时输出assert语句逗号后面的提示信息。

    with语句:如果with语句或语句块中发生异常,会调用默认的异常处理器处理,但文件还是会正常关闭。

  4. copy()与deepcopy()的区别

    copy是浅拷贝,只拷贝可变对象的父级元素。 deepcopy是深拷贝,递归拷贝可变对象的所有元素。

  5. 函数装饰器有什么作用(常考)

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

  6. 简述Python的作用域以及Python搜索变量的顺序

    Python作用域简单说就是一个变量的命名空间。代码中变量被赋值的位置,就决定了哪些范围的对象可以访问这个变量,这个范围就是变量的作用域。在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域。Python的变量名解析机制也称为 LEGB 法则:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)

  7. 新式类和旧式类的区别,如何确保使用的类是新式类

    为了统一类(class)和类型(type),python在2.2版本引进来新式类。在2.1版本中,类和类型是不同的。

    为了确保使用的是新式类,有以下方法:

    放在类模块代码的最前面 __metaclass__ = type
    从内建类object直接或者间接地继承
    在python3版本中,默认所有的类都是新式类。

  8. 简述__new__和__init__的区别

    创建一个新实例时调用__new__,初始化一个实例时用__init__,这是它们最本质的区别。

    new方法会返回所构造的对象,init则不会.

    new函数必须以cls作为第一个参数,而init则以self作为其第一个参数.

  9. Python垃圾回收机制(常考)

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

    1 引用计数

    PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。

    优点:

    简单 实时性 缺点:

    维护引用计数消耗资源 循环引用

    2 标记-清除机制

    基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

    3 分代技术

    分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

    Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

  10. Python中的@property有什么作用?如何实现成员变量的只读属性?

    @property装饰器就是负责把一个方法变成属性调用,通常用在属性的get方法和set方法,通过设置@property可以实现实例成员变量的直接访问,又保留了参数的检查。另外通过设置get方法而不定义set方法可以实现成员变量的只读属性。

  11. *args and **kwargs

    *args代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。**kwargs代表的关键字参数,允许你使用没有事先定义的参数名,另外,位置参数一定要放在关键字参数的前面。

  12. 有用过with statement吗?它的好处是什么?具体如何实现?

    with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

  13. *args,**kwargs的作用是什么?如何使用?                                      
  14.   *args和**kwargs通常使用在函数定义里,*args允许函数传入不定量个数的非关键字参数,**kwargs允许函数传入不定量个数的关键字参数
  15. 描述yield作用。
    1. 保存当前运行状态(断点),然后暂停执行,即将函数挂起
    2. 将yeild关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用,当使用next()、send()函数让函数从断点处继续执行,即唤醒函数。
  16. 装饰器。
    1. 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
    2. 功能:1.引入日志;2.函数执行时间统计;3.执行函数前预备处理;4.执行函数后清理功能;5.权限校验;6.缓存
  17. 你对多线程和多进程的理解。
    1. 进程是系统进行资源分配和调度的一个独立单位,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源;
    2. 一个程序至少有一个进程,一个进程至少有一个线程;
    3. 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高;
    4. 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率 ;
    5. 线线程不能够独立执行,必须依存在进程中;
    6. 优缺点:线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。
  18. 线程中start方法和run方法的区别?
    1. 若调用start,则先执行主进程,后执行子进程;
    2. 若调用run,相当于正常的函数调用,将按照程序的顺序执行
  19. linux命令 grep awk sed是怎么用的?
    1. grep:Global Regular Expression Print
    2.  
  20. python是怎么进行内存管理的?
    1. 引用计数:python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。
      1. 引用计数加1的情况:
        1. 对象被创建:x=4
        2. 另外的别人被创建:y=x
        3. 被作为参数传递给函数:foo(x)
        4. 作为容器对象的一个元素:a=[1,x,'33']
      2. 引用计数减少情况
        1. 一个本地引用离开了它的作用域。比如上面的foo(x)函数结束时,x指向的对象引用减1。
        2. 对象的别名被显式的销毁:del x ;或者del y
        3. 对象的一个别名被赋值给其他对象:x=789
        4. 对象从一个窗口对象中移除:myList.remove(x)
        5. 窗口对象本身被销毁:del myList,或者窗口对象本身离开了作用域
    2. 垃圾回收
      1. 当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:当两个对象相互引用时,他们本身其他的引用已经为0了。
      2. 垃圾回收机制还有一个循环垃圾回收器, 确保释放循环引用对象(a引用b, b引用a, 导致其引用计数永远不为0)。
    3. 内存池机制:在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
      1. Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
      2. Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的 malloc。另外Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
  21. 什么是lambda函数?他有什么好处? lambda函数是匿名函数;使用lambda函数能够创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤; 例:
     
  22. python中tuple和list的转换
  23.  

    # tuple ---> list

    tuple1 = (1,2,3)

    list1 = list(tuple1)

    # list ---> tuple

    list2 = [1,2,3]

    tuple2 = tuple(list2)

  24. python中如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)
    答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

    浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

    深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

你可能感兴趣的:(Python)