面试之 python基础
Posted fqh202
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试之 python基础相关的知识,希望对你有一定的参考价值。
1、简述 解释型 和 编译型 编程语言?
编译型语言:
- 1、预编译:源代码写好后,在执行之前,编译器直接将源代码编译成机器码,只编译一次,编译的时候根据对应的运行环境生成机器码,系统环境不同,编译后的可执行文件也不同;
- 2、链接:把各个模块的机器码和依赖库串联起来生成 可执行文件. 优点: 执行效率高; 缺点: 跨平台型差,开发效率低(修改代码需要重新进行预编译); 代表语言:c,c++,siwft
解释型语言:
- 不需要编译,只在运行程序的时候翻译成机器语言。
- 每运行一次就翻译一次.
- 优点: 跨平台型好(前提是安装解释器)、开发效率高(修改代码直接修改);
- 缺点: 执行效率低(每次运行之前都需要编译一次);
- 代表语言: javascript, python, php, perl;
2、Python解释器种类以及特点?
- CPython、Ipython、PyPy、Jython、IronPython
3、位和字节的关系?
- 位:bit,计算机最小单位,一个二进制数0或者1;
- 字节:1byte=8bit;
4、b、B、KB、MB、GB 的关系?
- 1 GB= 1024 MB ;1MB = 1024Kb;1KB=1024B;1B=8b
5、请至少列举5个 PEP8 规范?
- 每一级缩进使用4个空格;
- 函数命名使用全部小写的方式,可以使用下划线;
- 常量命名使用全部大写的方式,可以使用下划线;
- 所有行限制的最大字符数为79,换行可以使用反斜杠;
6、列举python2和python3的区别?
- print区别:py2直接使用
print ‘a‘
,py3使用print(‘a‘)
; - range区别:py2中
range(n)
返回列表,py3返回迭代器,节约内存; - 编码区别:py2使用ascii,py3使用utf-8编码;
- 字符串和字节串:py2中unicode表示字符串,str表示字节串;py3中str表示字符串,bytes表示字节串;
- input()函数,Py2中是
raw_input()
,py3中是input()
7、匿名函数?
需要使用函数但是又不行去命名的情况下使用。
foo = lambda x:x**2 foo() # 等价于 def foo(x): return x**2
8、pass的作用?
- 不会执行任何操作
- 保证格式完整
- 保证语义正确
9、*arg 和 **kwarg作用?
- 主要用于函数定义,将不定数量的参数传递给一个函数。
- *args:用来发送一个 非键值对 的 可变数量 的 参数列表 给一个函数
- **kwargs:允许你将 不定长度 的 键值对,作为参数传递给一个函数
10、is 和 == 的区别
- 是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等
- 比较判断指向的内存地址是否相同。
11、简述Python的深浅拷贝
- 浅拷贝:只拷贝不可变元素(
str,tuple
),对 可变容器中的元素(lst,dict
)进行内存地址引用,一旦容器中元素改变,那么引用都会改变; - 深拷贝:重新开辟空间保存所有元素,没有共享的内存引用。
12、Python垃圾回收机制? 2
- 1、引用计数算法。当有1个变量保存了对象的引用时,例如:
a=20,b=a
,此对象的引用计数就会加1。当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除; - 2、标记清除机制。等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象,打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。缺点就是必须顺序扫描整个堆内存。
- 3、分代技术。将系统中的所有内存块根据其存活时间划分为不同的集合,即“代”。垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。
13、Python的 可变类型 和 不可变类型?
- 1、不可变类型(数字、字符串、元组、不可变集合):不支持原地修改,只能重新申请内存空间;
- 2、可变类型(列表、字典、可变集合):可以原地修改,容器内存地址不会变。
14、列举常见的内置函数?
dir(__builtin__) # win列出所有内置函数
abs()
pow(x,y) # x**y
round()
dir()
str()
set()
list()
max()
min()
id()
getattr()
setattr()
15、一行代码实现 9*9 乘法表
ele = ''
for x in range(1,10):
for y in range(1,x+1):
ele= ele + '%sx%s=%s' % (x,y,x*y)+ ' '
ele+='
'
print(ele)
# 一行代码实现
print('
'.join(' '.join(['%sx%s=%s' % (x,y,x*y) for y in range(1,x+1)]) for x in range(1,10)))
16、列举常用模块都有哪些?
time、datetime、collection、re、os、random、json、pickle、hashlib、subprocess。
17、re的match和search区别?
- match:从左侧第一位开始匹配;
- search:从左至右逐个匹配。
18、正则表达式的贪婪和非贪婪匹配区别?
默认贪婪匹配,匹配越多越好, 非贪婪匹配在pattern后面追加
?
!In [16]: m = re.match('d+',s) In [17]: m Out[17]: <_sre.SRE_Match object; span=(0, 2), match='12'> In [18]: m = re.match('d+?',s) In [19]: m Out[19]: <_sre.SRE_Match object; span=(0, 1), match='1'>
19、如何实现[‘1’,’2’,’3’]
变成[1,2,3]
?
# 原地修改
lst = ['1', '2', '3']
for k,v in enumerate(lst):
lst[k] = int(v)
print(lst)
# 创建新列表
l1 = [int(x) for x in lst]
print(l1)
# map_reduce原地修改
lst = list(map(lambda x:int(x),lst))
print(lst)
20、如何用一行代码生成[1,4,9,16,25,36,49,64,81,100]
?
print([i**2 for i in range(1,11)])
21、谈谈你对闭包的理解?
- 1、函数中定义嵌套函数;
- 2、外层函数返回内层嵌套函数的引用;
- 3、内层函数引用外层函数的变量。
22、__new__
和__init__
区别?
__new__
是在实例创建之前被调用的,因为它的任务就是创建一个空实例然后将其返回,是个静态方法;__init__
是当实例对象创建完成后才被调用,可以设置对象属性的一些初始值。
23、你知道几种设计模式?
24、编码和解码你了解过么?
- 编码:将字符按照特定的规则转换成二进制;
- 解码:按照对应的解码规则 将二进制代码转换成字符;
编码规则有:
ascii 1byte gbk 2byte unicode 2byte 包含与所有字符的映射关系,内存中的通用格式 utf8 可变长,汉字3bytes,字母1byte,传输时候可以用utf8编码
25、列表推导list comprehension和生成器的优劣。
- 都是可迭代对象,可以使用for循环;
- 生成器存储的算法,当序列比较大的时候,生成器可以节约内存,但是生成器是一次性的,迭代完后就自动销毁
26、什么是装饰器?如果想在函数之后进行装饰,应该怎么做?
- 在不改变原函数的情况下对原函数的功能进行扩展,装饰器本质上是闭包函数。
27、手写个使用装饰器实现的单例模式?
def singleton(cls):
instance = {}
def _singleton(*args):
if cls not in instance:
# 调用类的init方法,采用dict模式其他类可以重复使用
instance[cls] = cls(*args)
return instance[cls]
return _singleton
@singleton
class People(object):
def __init__(self,name, age):
self.name=name
self.age=age
def add(self):
pass
s = People('alex',23)
s1 = People('kate',28)
print(s==s1) # True
28、使用装饰器的单例和使用其他方法的单例,在后续使用中,有何区别?
- 代码重用
29、手写正则邮箱地址
pattern = '[1-9a-z][email protected](qq|126|163|gmail|foxmail|yahoo).com'
import re
m = re.match(pattern,s)
print(m.group())
30、多进程与多线程的区别?CPU密集型适合用什么?
31、介绍下协程,为何比线程还快?
- 程下的并发,用户程序级别实现任务切换,而线程是解释器级别的;
- gevent模块实现伪多线程。
以上是关于面试之 python基础的主要内容,如果未能解决你的问题,请参考以下文章