面试之 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基础的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

经典Python面试题之基础80问 Python开发

python之基础篇——模块与包

每日面试之 面试基础1

《Python学习之路 -- Python基础之切片》

Java语言基础之方法的设计