python面试问题
python2 V.S. python3
1)默认编码方式
python2默认ascii编码,python3默认使用unicode(utf-8).
涉及中文,python2需在文件头出添加# -*- coding: utf-8 -*- 或在python的Lib\site-packages文件夹下新建一个sitecustomize.py,内容为:
- # encoding=utf8
- import sys
- reload(sys)
- sys.setdefaultencoding('utf8')
或在涉及到的每一个位置,s.decode(sys.getdefaltencoding()).encode('utf-8')
2)print:python3需要加括号。
3)整除:python2和python3都认为//是整除,不同的是 / ,3/2 python2是1,python3是1.5。 3./2 python2才是1.5.
4)迭代器
python2 xrange ; python3 range
字典dict.keys() dict.values() dict.items() python2返回列表,python3返回view对象,类似迭代器。
map filter 从函数变成了类,其返回结果从列表变成了可迭代对象
5)不等于运算符:python2 不等号可以是<>或!=;python3只有!=
6)数据类型:————
7)True和False:python2中True和Flase是两个全局变量,可被重新赋值;python3将其变为两个关键字,补个被赋值。
8)nonlocal:global可用于函数内部修改全局变量的值,而在嵌套函数中想要声明一个全局变量是没办法实现的,python3新增nonlocal关键字,实现了该功能。
9)解析用户输入python2 input()只接受数字,raw_input()接受字符串,python3中只有input() ,接收字符串。
单下划线和双下划线的区别
__foo__: 定义的是特殊方法,一般是系统定义名字,防止与用户定义的变量名冲突 ,类似 __init__() 之类的。 _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import * __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。如果子类想要访问父类中的私有变量或方法,可以使用 实例._父类名__foo
foo:就是public方法
设计模式有什么用
是前人对于代码的经验和思想的总结,包括代码的可重用性、可靠性,是否容易理解和扩展,是否容易维护。
重写和重载的区别
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载
的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
python中有垃圾回收机制,在以下情况下仍然会有内存泄漏的问题:
- 对象一直被全局变量所引用, 全局变量生命周期长.
- 垃圾回收机被禁用或者设置成debug状态, 垃圾回收的内存不会被释放.
- 循环引用过多, gc 无法及时释放
为什么python中的list不能当做dict的key
dict必须要保证当同样的内容进来的时候,能够找到该内容对应的值,也就是如果内容相同
对应的哈希值应当相同。
而对于list的hash函数,可能存在两种实现方式:
1)基于id。基于id实现hash可以保证,两个对象的hash值不同,他们的id不同,但是,
当两个对象的内容相同时,他们的id也可能不同,创建以个一模一样的list用字典查找永远
会得到一个KeyError.
2)基于内容。tuple就是这样做的,tuple不可修改,基于内容方法对于同一个tuple来说其hash值不会改变,而对于同一个list而言,list的内容改变了,其hash值就改变了,因此,对于某一个list来说,基于内容的方法不可能生成一个固定的哈希值。
python中已经有了list,为什么还要使用tuple?
1)tuple可以作为dict的key
2)如果我们想要把一个list传给一个函数,但又不想让该函数改变list的值,就可以把该list转化成tuple,通过类型的限制让函数不能更改。
3)由于tuple不可改变,因此在声明的时候,只需要分配恰好的内存即可,更节省空间,而list由于需要改变,声明时会分配更多的内存。