第一部分 Python基础篇(80题)
面试题,来自配齐老师的315题,个人整理用~
基础题(80题):
1.为什么学习Python?
2.通过什么途径学习的Python?
3.Python和Java、PHP、C、C#、C++等其他语言的对比?
4.简述解释型和编译型编程语言?
解释型语言编写的程序不需要编译,每个语句都是执行的时候才翻译,边执行,边编译。
用编译型语言写的程序执行之前,需要一个专门的编译过程,通过编译系统,把源高级程序编译成为机器语言文件(先编译,再执行)
5.Python解释器种类以及特点?
CPython
当 从Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解释器:Cpython,这个解释器是用C语言开发的,所以叫 CPython,在命名行下运行python,就是启动CPython解释器,CPython是使用最广的Python解释器。
IPython
IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器虽然外观不同,但内核其实是调用了IE。
PyPy
PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。
Jython
Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython
IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
在Python的解释器中,使用广泛的是CPython,对于Python的编译,除了可以采用以上解释器进行编译外,技术高超的开发者还可以按照自己的需求自行编写Python解释器来执行Python代码,十分的方便!
6.位和字节的关系?
最小的存储单位称为位(bit);只能容纳两个值(0或1)之一,不能在一个位中存储更多的信息。位是计算机存储的基本单位。
字节(byte)是常用的计算机存储单位。字节的标准定义:一个字节均为8位。由于上述所讲每个位或者是0或者是1,所以一个8位的字节包含256种可能的0,1组合
7.b、B、KB、MB、GB 的关系?
8.请至少列举5个 PEP8 规范(越多越好)。
空白: (1) 使用space(空格)来表示缩进,而不要用tab(制表符) (2) 和语法相关的每一层缩进都用4个空格来表示 (3) 每行字符数不应该超过79个 (4) 对于占据多行的长表达式来说,除了首行之外的其余各行都应该在通常的缩进级别之上再加4个空格 (5) 文件中的函数与类之间应该用两个空行隔开 (6) 同一个类中,各方法之间应该用一个空行隔开 (7) 使用下标来获取元素、调用函数或给关键字参数赋值的时候,不要在两边加空格 (8) 为变量赋值的时候,赋值符号的左侧和右侧应该各自加上一个空格 命名:略 表达式和语句:略
9.通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
十进制转换成二进制:v = 18
八进制转换成十进制:v = “011”
十进制转换成八进制:v = 30
十六进制转换成十进制:v = “0x12”
十进制转换成十六进制:v = 87
10.请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
11.python递归的最大层数?
答案:998,不超过1000。这是python专门设置的一种机制用来防止无限递归造成Python溢出崩溃。
12.求结果:
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or Flase and 1
13.ascii、unicode、utf-8、gbk 区别?
14.字节码和机器码的区别?
15.三元运算规则以及应用场景?
16.列举 Python2和Python3的区别
17.用一行代码实现数值交换:
a = 1
b = 2
18.Python3和Python2中 int 和 long的区别?
19.xrange和range的区别?
20.文件操作时:xreadlines和readlines的区别?
readline()方法从字面意思可以看出,该方法每次读出一行内容,所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。
readlines()方法读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。
21.列举布尔值为False的常见值?
22.字符串、列表、元组、字典每个常用的5个方法?
23.lambda表达式格式以及应用场景?
24.pass的作用?
25.*arg和**kwarg作用
*arg和**kwarg 可以帮助我们处理上面这种情况,允许我们在调用函数的时候传入多个实参 *arg会把多出来的位置参数转化为tuple **kwarg会把关键字参数转化为dict
26.is和==的区别
==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等 is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同 例子: >>> x = y = [4,5,6] >>> z = [4,5,6] >>> x == y True >>> x == z True >>> x is y True >>> x is z False
27.简述Python的深浅拷贝以及应用场景?
导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。所以对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等. 对于数字和字符串的深浅拷贝都只是将变量的索引指向了原来的内存地址,例如在sum,sum1,sum2三个变量中,无论修改任意其中一个变量,只是将其指向了另一个内存地址,其他两个变量不会变,字符串同理。因此,对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。 深浅拷贝都是对源对象的复制,占用不同的内存空间 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象(如:字符串和数字类型) 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象
28.Python垃圾回收机制?
Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』
『引用计数法』的原理是:每个对象维护一个ob_ref字段,用来记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数ob_ref加1,每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0,该对象立即被回收,对象占用的内存空间将被释放
它的缺点是需要额外的空间维护引用计数,这个问题是其次的,不过最主要的问题是它不能解决对象的“循环引用”,因此,也有很多语言比如Java并没有采用该算法做来垃圾的收集机制。
29.Python的可变类型和不可变类型?
Python的每个对象都分为可变和不可变,主要的核心类型中,数字、字符串、元组是不可变的,列表、字典是可变的。
对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其他变量引用原有对象的话(即引用计数为0),原有对象就会被回收)。
30.求结果:
v = dict.fromkeys(['k1','k2'],[])
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
31.求结果
def num():
return [lambda x : i*x for i in range(4)]
print ([m(2) for m in num()])
32.列举常见的内置函数?
33.filter、map、reduce的作用?
(1) filter, 遍历序列中每个元素,判定每个元素得到的布尔值,如果是True,则留下来,一般用于过滤作用 (2)map, 处理系列中每个元素,得到的结果是个“列表”,该列表元素个数和位置与原来一样 (3)reduce, 处理一个序列,然后把序列进行合并操作(在python3中需要导入模块,from funtools import reduce)
34.一行代码实现9*9乘法表
print "\n".join("\t".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10))
35.如何安装第三方模块?以及用过哪些第三方模块?
36.至少列举8个常用模块都有那些?
37.re的match和search区别?
match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找匹配; 也就是说match()只有在0位置匹配成功的话才有返回, 如果不是开始位置匹配成功的话,match()就返回none。 例如: print(re.match(‘super’, ‘superstition’).span()) 会返回(0, 5) 而print(re.match(‘super’, ‘insuperable’)) 则返回None search()会扫描整个字符串并返回第一个成功的匹配 例如:print(re.search(‘super’, ‘superstition’).span())返回(0, 5) print(re.search(‘super’, ‘insuperable’).span())返回(2, 7)
38.什么是正则的贪婪匹配?
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab.*c)。 非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab.*c)。 默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
39.求结果: a. [ i % 2 for i in range(10) ] b. ( i % 2 for i in range(10) )
40.求结果: a. 1 or 2 b. 1 and 2 c. 1 < (2==2) d. 1 < 2 == 2
41. func(a,b=[]) 这种写法有什么坑?
def func(a,b=[]): b.append(a) print(b) func(1) func(1) func(1) func(1) 看下结果 [1] [1, 1] [1, 1, 1] [1, 1, 1, 1] 函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储,所以三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。
42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
43.如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
44.比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?
45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100]
46.一行代码实现删除列表中重复的值 ?
47.如何在函数中设置一个全局变量 ?
有一个全局file_content 的list,在函数内部向其append数据,是可以的,不需要加global 修饰,
但是当 在函数内部进行对其 赋值操作时,需要用global修饰该全局变量,因为赋值操作默认作为局部变量,
对全局变量进行赋值修改,需要进行显示global声明
每一次读取file_content时候,读取完或者开始读取的时候要重新对该list清空,
防止每次读取都会将上一次内容读重复读取到,所以在赋值为空的时候 就必须用到global修饰该list变量,
48.logging模块的作用?以及应用场景?
Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。
使用场景的,比如说:开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件。
49.请用代码简答实现stack
50.常用字符串格式化哪几种?
第一种:最方便的 缺点:需一个个的格式化 print('hello %s and %s'%('df','another df')) 第二种:最好用的 优点:不需要一个个的格式化,可以利用字典的方式,缩短时间 print('hello %(first)s and %(second)s'%{'first':'df' , 'second':'another df'}) 第三种:最先进的 优点:可读性强 print('hello {first} and {second}'.format(first='df',second='another df'))
51.简述 生成器、迭代器、可迭代对象 以及应用场景?
迭代器的应用场景 1). 如果数列的数据规模巨大 2). 数列有规律,但是依靠列表推导式描述不出来
52.用Python实现一个二分查找的函数。
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] def binary_search(dataset,find_num): if len(dataset) > 1: mid = int(len(dataset) / 2) if dataset[mid] == find_num: # find it print("找到数字", dataset[mid]) elif dataset[mid] > find_num: # 找的数在mid左面 print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid]) return binary_search(dataset[0:mid], find_num) else: # 找的数在mid右面 print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid]) return binary_search(dataset[mid + 1:], find_num) else: if dataset[0] == find_num: # find it print("找到数字啦", dataset[0]) else: print("没的分了,要找的数字[%s]不在列表里" % find_num) binary_search(data,20)
53.谈谈你对闭包的理解?
54.os和sys模块的作用?
os模块提供了一种方便的使用操作系统函数的方法。
sys模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。
总结就是,os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
55.如何生成一个随机数?
56.如何使用python删除一个文件?
57.谈谈你对面向对象的理解?
58.Python面向对象中的继承有什么特点?
https://www.cnblogs.com/emily-qin/p/7059638.html
59.面向对象深度优先和广度优先是什么?
60.面向对象中super的作用?
61.是否使用过functools中的函数?其作用是什么?
Python自带的 functools 模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数。换言之,就是能使用该模块对可调用对象进行处理。
具体参考:http://www.cnblogs.com/Roc-Atlantis/p/9438983.html
62.列举面向对象中带爽下划线的特殊方法,如:__new__、__init__
63.如何判断是函数还是方法?
64.静态方法和类方法区别?
65.列举面向对象中的特殊成员以及应用场景?
1. __doc__ #输出:类的描述信息 2. __module__ 和 __class__ __module__ 表示当前操作的对象在那个模块 __class__ 表示当前操作的对象的类是什么 3. __init__ 构造方法,通过类创建对象时,自动触发执行。 4. __del__ 析构方法,当对象在内存中被释放时,自动触发执行。 5. __call__ 对象后面加括号,触发执行。即: 对象() 或 类()() 6. __dict__ 类或对象中的所有成员 7. __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。 8. __getitem__ __setitem__ __delitem__ 类似字典一样索引的操作,以上分别表示获取,设置,删除。(当在类外面做了这些操作后触发这些函数,甚至可删除不存在的数据) 9. __new__ 用来将类实例化的
66.1、2、3、4、5 能组成多少个互不相同且无重复的三位数
67.什么是反射?以及应用场景?
其实,反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
使用场景:基于反射机制模拟web框架路由,
可插拔式,
动态导入模块
68.metaclass作用?以及应用场景?
69.用尽量多的方法实现单例模式。
70.装饰器的写法以及应用场景。
参考博客:https://blog.csdn.net/xiangxianghehe/article/details/77170585
71.异常处理写法以及如何主动跑出异常(应用场景)
72.什么是面向对象的mro
MRO 列表 事实上,对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序,我们可以使用下面的方式获得某个类的 MRO 列表: >>> C.mro() # or C.__mro__ or C().__class__.mro() [__main__.C, __main__.A, __main__.B, __main__.Base, object] 1 2 >>> C.mro() # or C.__mro__ or C().__class__.mro() [__main__.C, __main__.A, __main__.B, __main__.Base, object] 那这个 MRO 列表的顺序是怎么定的呢,它是通过一个 C3 线性化算法来实现的,这里我们就不去深究这个算法了,感兴趣的读者可以自己去了解一下,总的来说,一个类的 MRO 列表就是合并所有父类的 MRO 列表,并遵循以下三条原则: 子类永远在父类前面 如果有多个父类,会根据它们在列表中的顺序被检查 如果对下一个类存在两个合法的选择,选择第一个父类
73.isinstance作用以及应用场景?
使用场景:用于判断一个对象是否是一个类或者其子类的实例。
在Python中可以使用type()与isinstance()这两个函数判断对象类型,而isinstance()函数的使用上比type更加方便。
用到场景,个人观点:
可能用于比较2个值的数据类型是否一致
74.写代码并实现:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
75.json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
76.json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
dumps时指定ensure_ascii=False
77.什么是断言?应用场景?
断言其实是防止程序意外出错的一种宏,如果其参数计算为假,则程序发出警告,且退出。
最常见的用法就是在函数入口处保证输入参数的正确性。
断言条件为真时代码继续执行,否则抛出异常,这个异常通常不会去捕获他.我们设置一个断言目的就是要求必须实现某个条件
78.有用过with statement吗?它的好处是什么?
with语句的作用是通过某种方式简化异常处理,它是所谓的上下文管理器的一种 文件操作时使用过. with语句下代码完成后调用求值语句返回对象的__exit__方法,可以实现一些操作,比如关闭文件。 with语句会在嵌套的代码执行之后,自动关闭文件。这种做法的还有另一个优势就是,无论嵌套的代码是以何种方式结束的,它都关闭文件。如果在嵌套的代码中发生异常,它能够在外部exception handler catch异常前关闭文件。如果嵌套代码有return/continue/break语句,它同样能够关闭文件。
79.使用代码实现查看列举目录下的所有文件。
# 递归的方式 def print_directory_contents(sPath): import os for sChild in os.listdir(sPath): sChildPath = os.path.join(sPath, sChild) if os.path.isdir(sChildPath): print_directory_contents(sChildPath) else: print(sChildPath)
80.简述 yield和yield from关键字。
yield : 生成器函数关键字 yield from : 相当于for i in obj : yield i