python面试手册(补充ing)

一、理论部分(语言特性)

1. 元类metaclass

2. args,*kwargs

当函数的参数前面有一个星号*号的时候表示这是一个可变的位置参数,两个星号**表示这个是一个可变的关键词参数。
星号``*把序列或者集合解包(unpack)成位置参数,两个星号**把字典解包成关键词参数。
或者我们希望以元组(tuple)或者列表(list)的形式传参数

2.1 重载

结论放在前:python 不需要函数重载
函数重载主要是为了解决两个问题。

  1. 可变参数类型。(Python可以接受任何类型的参数)
  2. 可变参数个数。(设置缺省参数)

一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函数的功能其实不同,那么不应当使用重载,而应当使用一个名字不同的函数

3. 装饰器(decorator)

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

4. 垃圾回收机制

Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅。

  • 引用计数:Python在内存中存储每个对象的引用计数,如果计数变成0,该对象就会消失,分配给该对象的内存就会释放出来。
  • 标记-清除:一些容器对象,比如list、dict、tuple,instance等可能会出现引用循环,对于这些循环,垃圾回收器会定时回收这些循环(对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边)。
  • 分代收集:Python把内存根据对象存活时间划分为三代,对象创建之后,垃圾回收器会分配它们所属的代。每个对象都会被分配一个代,而被分配更年轻的代是被优先处理的,因此越晚创建的对象越容易被回收。

5. 多线程(multi-threading)

Python并不支持真正意义上的多线程,Python提供了多线程包。Python中有一个叫Global Interpreter Lock(GIL)的东西,它能确保你的代码中永远只有一个线程在执行。经过GIL的处理,会增加执行的开销。这就意味着如果你先要提高代码执行效率,使用threading不是一个明智的选择,当然如果你的代码是IO密集型,多线程可以明显提高效率,相反如果你的代码是CPU密集型的这种情况下多线程大部分是鸡肋。

6. os,sys模块的不同

  • os模板提供了一种方便的使用操作系统函数的方法
  • sys模板可供访问由解释器使用或维护的变量和与解释器交互的函数
    os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。sys模块负责程序与Python解释器的交互,提供了一系列的函数和变量用户操作Python运行时的环境。

7. lambda表达式

lambda表达式一般的形式是:关键词lambda后面紧接一个或多个参数,紧接一个冒号“:”,紧接一个表达式。lambda表达式是一个表达式不是一个语句。

8. 深浅拷贝

copy.copy:浅拷贝,只拷贝父对象,不拷贝父对象的子对象。
copy.deepcopy:深拷贝,拷贝父对象和子对象。

import copy
myList = [1, 2, [3, ]]
myCopyList = myList
myCCopyList = copy.copy(myList)
myDCopyList = copy.deepcopy(myList)
myList[2].append(4)
print("复制:{} || 浅拷贝: {} || 深拷贝:{} ".format(myCopyList, myCCopyList, myDCopyList))

>>复制:[1, 2, [3, 4]] || 浅拷贝: [1, 2, [3, 4]] || 深拷贝:[1, 2, [3]]

9. Python2.x与3.x版本区别

9.1 print函数

2是语句 3是函数

9.2 Unicode

  • Python 2 有 ASCII str() 类型,unicode() 是单独的,不是 byte 类型
  • Python 3有了 Unicode (utf-8) 字符串,以及一个字节类:byte 和 bytearrays
  • Python3.X 源码文件默认使用utf-8编码

9.3 除法运算

  • Python中的除法有两个运算符,/和//
  • 在python 2.x中/除法就跟我们熟悉的大多数语言,比如Java啊C啊差不多,整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果
  • 在python 3.x中/除法,对于整数之间的相除,结果也会是浮点数。
  • 而对于//除法,这种除法叫做floor除法,会对除法的结果自动进行一个floor操作,在python 2.x和python 3.x中是一致的。

9.4 异常

捕获异常的语法由 except exc, var 改为 except exc as var。

9.5 xrange

9.6 八进制字面量表示

在Python 3.x中,表示八进制字面量的方式只有一种,就是0o1000。
原来的形式0777不能用了
二进制必须写成0b111

9.7 不等运算符

Python 2.x中不等于有两种写法 != 和 <>
Python 3.x中去掉了<>, 只有!=一种写法

9.8 数据类型

Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
新增了bytes类型,对应于2.X版本的八位串,定义一个bytes字面量的方法如下:b = b'china'
str对象和bytes对象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互转化

10. newinit的区别

__init__为初始化方法,__new__方法是真正的构造函数。
__new__是实例创建之前被调用,它的任务是创建并返回该实例,是静态方法
__init__是实例创建之后被调用的,然后设置对象属性的一些初始值。 
__new__方法在__init__方法之前被调用,并且__new__方法的返回值将传递给__init__方法作为第一个参数,最后__init__给这个实例设置一些参数。

我们可以分别使用__metaclass__,__new____init__来分别在类创建,实例创建和实例初始化的时候做处理

11. 方法中单下划线和双下划线

  • __name__:一种约定,Python内部的名字,用来与用户自定义的名字区分开,防止冲突
  • _name:一种约定,用来指定变量私有
  • __name:解释器用_classname__name来代替这个名字用以区别和其他类相同的命名

12. python自省

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型。
type()、dir()、getattr()、hasattr()、isinstance()

13. 单例模式

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

1.用__new__方法
class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance

class MyClass(Singleton):
    a = 1

2.共享属性
创建实例时把所有实例的__dict__指向同一个字典,这样它们具有相同的属性和方法.
class Borg(object):
    _state = {}
    def __new__(cls, *args, **kw):
        ob = super(Borg, cls).__new__(cls, *args, **kw)
        ob.__dict__ = cls._state
        return ob

class MyClass2(Borg):
    a = 1

3.装饰器版本
def singleton(cls):
    instances = {}
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
  ...

4.import方法
作为python的模块是天然的单例模式
# mysingleton.py
class My_Singleton(object):
    def foo(self):
        pass
my_singleton = My_Singleton()
# to use
from mysingleton import my_singleton
my_singleton.foo()

本文参考Github 关于Python的面试题

你可能感兴趣的:(python面试手册(补充ing))