学习必看Python面试宝典之Pyt

为了帮助大家更好的吸收和加强python知识,yuan老师特此完成一篇关于python最精华的面试题册,通过对这两年每一期毕业学生的实际面试题的收集和整理,代表着当前市场对于python的最实际的需求和前沿方向,希望能帮助到大家。

1、print调用Python中底层的什么方法

#print方法默认调用sys.stdout.write方法,即往控制台打印字符串。

2、输入一个字符串,返回倒序排列的结果如:abcdef,返回fedcba

#法1

name=helloyuan

print(name[::-1])

#法2

name=helloyuan

tmp=list(name)

tmp.reverse()

print(.join(tmp))

3、将‘pythonisshell’转为‘nohtypsillehs’

s=pythonisshell

print(.join(map(lambdax:x[::-1],s.split())))#nohtypsillehs

4、字符串a=“notfound张三99深圳”,每个词中间是空格,用正则的方法,最终输出张三深圳

importre

a=notfound张三99深圳

res=re.findall([\u4e00-\u9fa5]{2},a)

print(.join(res))#张三深圳

5、_dict={‘a’:1,‘b’:2,‘c’:3},要求根据value值从大到小输出key

_dict={a:1,b:2,c:3}

print(sorted(_dict.keys(),key=lambdax:_dict[x],reverse=True))#[c,b,a]

6、将两个列表[1,5,7,9],[2,2,6,8]合并为[1,2,2,5,6,7,8,9]

7、如何实现[‘1’,‘2’,‘3’]变成[1,2,3]

l=[1,2,3]

print(list(map(int,l)))#[1,2,3]

8、模块互导

现在有b、c两个模块,且各自的代码如下:

#c.py

importb

deffoo():...

b.foo()#AttributeError:modulebhasnoattributefoo

#b.py

importc

deffoo():...

c.foo()

#正如上面例子所示,在模块c中导入模块b,在模块b中导入模块c。此时我们运行模块c,会发生什么样的事情?

9、xrange和range的区别?

10、对数值1.四舍五入保留2位小数点

11、一条语句把L=[(1,2),(3,4)]转换成[(1,3),(2,4)],可以写下不同的方法

12、从0-99这个数中随机取出10个,要求不能重复,可以自己设计数据结构

importrandom

li=range(1,)

print(random.sample(li,10))

13、a=[1,{a:12}];b=a;a[1][a]=1;print(b)输出什么?并且简述下原因

14、短路计算

v1=1or3

v2=1and3

v3=0and2and1

v4=0and2or1

v5=0and2or1or4

v6=0orFalseand1

15、ascii、unicode、utf-8、gbk区别?

16、python的三元运算

a,b=1,2

result=TrueifabelseFalse

print(result)#False

17、a=range(10),a[::-3]的结果是

a=range(10)

print(a[::-3])#range(9,-1,-3)

print(list(a[::-3]))#[9,6,3,0]

18、Python中哪些是可变类型,哪些是不可变类型

19、解释下Python的深浅拷贝

20、

l1=[1,2,3,[yuan,alvin]]

l2=l1[:]

l2[1]=

print(l1)

l2[3][0]=张三

print(l1)

21、一行代码实现1-的求和

print(sum(range(1,)))

print((1+)*//2)#等差数列求和公式

print(sum([iforiinrange(1,)]))

22、列表去重

li1=[1,1,2,3,2,5]

#print(list(set(li1)))

23、如何能有t1,t2得到t3

t1=(a,b,c,d,e)

t2=(1,2,3,4,5)

t3={a:1,b:2,c:3,d:4,e:5}

#res=dict(zip(t1,t2))

24、一行print出1~偶数的列表,(列表推导式,filter均可)

print([iforiinrange(1,)ifi%2==0])

print(list(filter(lambdax:x%2==0,range(1,))))

25、

defadd(s,x):

returns+x

defgen():

foriinrange(4):

yieldi

base=gen()

fornin[1,10]:

base=(add(i,n)foriinbase)

print(list(base))

26、如何对一个列表去重后再由大到小排序,l=[1,2,56,31,2,44,31,,18]

print(sorted(list(set(l)),reverse=True))

27、请实现一个装饰器,限制该函数被调用的频率,如10秒一次

28、请合并下面两个字典a={“A”:1,“B”:2},b={“C”:3,“D”:4}

a.update(b)

29、请至少列举5个PEP8规范(越多越好)

#缩进:使用4个空格的缩进,不要使用制表符(Tab键),禁止空格与Tab键混用。

#换行:折行以确保其不会超过79个字符。这有助于小显示器用户阅读,也可以让大显示器能并排显示几个代码文件。

#空行:使用空行分隔函数和类,以及函数内的大块代码。顶级函数间空2行,类的方法之间空1行,同一函数内的逻辑块之间空1行,文件结尾空一行。

#注释:如果可能,注释独占一行。避免逐行添加注释,避免没有一个注释。

#空格:运算符周围和逗号后面使用空格,但是括号里侧不加空格,如:a=f(1,2)+g(3,4)。

#导入格式:每个导入独占一行,导入放在文件顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。导入应该按照从最通用到最不通用的顺序分组(标准库-第三方库-自定义库),每种分组中,应该根据每个模块的完整包路径按字典序排序,忽略大小写。不要使用fromxxximport*这种语法。

#变量命名:尽可能的使用有意义的变量名,词能达意。下划线命名法和驼峰命名法。包名、模块名、函数名、方法、普通变量名全部使用小写,单词间用下划线连接。类名、异常名使用首字母大写(CapWords)的方式,异常名结尾加Error或Wraning后缀。自定义的变量名、函数名不能和标准库中的函数名重名。

30、如何交换字典{“A”:1,“B”:2}的键和值

{v:kfork,vindict.items()}#字典推导式

31、Python垃圾回收机制

#python采用的是以引用计数为主,以分代回收和标记清除为辅的垃圾回收机制

#1引用计数

在python中,每创建一个对象,那么python解释器会自动为其设置一个特殊的变量,这个变量称为引用计数(初始值默认是1)。一旦有一个新变量指向这个对象,那么这个引用计数的值就会加1。如果引用计数的值为0。那么python解释器的内存管理系统就会自动回收这个对象所占的内存空间,删除掉这个对象。

引用计数+1的情况:

对象被创建,例如a=yuan

对象被引用,例如b=a

对象被作为参数,传入到一个函数中,例如fun(a)

对象作为一个元素,存储在容器中,例如data_list=[a,b]

引用计数-1的情况:

对象的别名被显式销毁,例如dela

对象的别名被赋予新的对象,例如a=24

一个对象离开它的作用域,例如func函数执行完毕时,func函数中的局部变量(全局变量不会)

对象所在的容器被销毁,或从容器中删除对象

#2分代回收

既然已经有引用计数了,那么为什么还要提出分代回收呢?原因就是引用计数没办法解决“循环引用”的情况。

a=[yuan,]#语句1

b=[rain,]#语句2

a.append(b)#语句3

b.append(a)#语句4

#此时对象的值:a=[yuan,b]b=[rain,a]

dela#语句5

delb#语句6

#执行完语句5和语句6是希望同时删除掉a对象和b对象

在执行dela语句之后,只是删除了对象的引用,也就是此时a变量这个名字被删除,也就是此时对象[yuan,b]的引用计数减1;执行delb语句也是同样的情况。但是,此时,由于显式指向它们的变量已经不存在了,所以也没办法删除了,就会导致它们一直存在于内存空间中。这就是循环引用出现的问题。此时,单靠引用计数没办法解决问题。所以便提出了分代回收

注意:在分代回收中,如果某对象的引用计数为0,那么它所占的内存空间同样也会被python解释器回收。

a、此时在python中每创建一个对象,那么就会把对象添加到一个特殊的“链表”中,这个链表称为零代链表。每当创建一个新的对象,那么就会将其添加到零代链表中。当这个零代链表中的对象个数达到某一个指定的阀值的时候,python解释器就会对这个零代链表进行一次“扫描操作”。这个“扫描操作”所做的工作是查找链表中是否存在循环引用的对象,如果在扫描过程中,发现有互相引用的对象,那么会让这些对象的引用计数都减少1。此时,如果某些对象引用计数变成0,那么就会被python解释器回收其所占用的内存空间;如果对象的引用计数仍然不为0,那么会把此时存活的对象迁移到“一代链表”中。

b、同样,python解释器也会在一定的情况下,也扫描“一代链表”,判断其中是否存在互相引用的对象。如果存在,那么同样也是让这些对象的引用计数都减少1。此时,如果某些对象引用计数变成0,那么就会被python解释器回收其所占用的内存空间;如果对象的引用计数仍然不为0,那么会把此时存活的对象迁移到“二代链表”中。

c、同样,python解释器也会在一定的情况下,也会扫描二代链表,判断其中是否存在互相引用的对象。如果存在,那么同样也是让这些对象的引用计数都减少1。此时,如果某些对象引用计数变成0,那么就会被python解释器回收其所占用的内存空间;如果对象的引用计数仍然不为0,那么会把此时存活的对象迁移到一个新的特殊的内存空间。此时重新进行零代链表-一代链表-二代链表的循环。

这就是python的分代回收机制。

#标记清除

那么既然已经有分代回收了,那么为什么又要提出标记-清除呢?

原因就是分代回收没办法解决“误删”的情况。

a=[yuan,]#语句1

b=[rain,]#语句2

a.append(b)#语句3

b.append(a)#语句4

#此时对象的值:a=[yuan,b]b=[rain,a].[yuan,b]、[rain,a]的引用计数都为2

dela#语句5

#此时[yuan,b]的引用计数为1,[rain,a]的引用计数为2

#执行完语句5只希望删除a对象,保留b对象

如果按照分代回收的方式来处理上述语句。那么,python解释器在执行完语句5之后。在一定的情况下进行查找循环引用对象的时候,会发现此时[rain,a]对象和[yuan,b]对象存在互相引用的情况。所以此时就会让这两个对象的引用计数减1。此时,[yuan,b]对象的引用计数为0,所以[yuan,b]对象被真正删除,但是其实此时[rain,a]对象中是有一个变量引用原来的[yuan,b]对象的。如果[yuan,b]对象被真正删除的话,那么此时时[rain,a]对象中的a变量就没有用了,就没有办法访问了。但是其实我们是希望它有用的,所以这个时候就出现“误删”的情况了。所以此时就需要结合“标记-清除”来解决问题了。

标记-清除:

此时同样是检测链表中的相互引用的对象,然后让它们的引用计数减1之后;

但是此时会将所有的对象分为两组:死亡组(death_group)和存活组(survival_group),把引用计数为0的对象添加进死亡组,其它的对象添加进存活组;

此时会对存活组的对象进行分析,只要对象存活,那么其内部的对象当然也必须存活。如果发现内部对象死亡,那么就会想方设法让其活过来,通过这样子就能保证不会删错对象了。

题目的重新分析:

在检查死亡组的时候,会发现[rain,a]对象中的a所指向的对象存在于死亡组中,所以就会想方设法让其复活,此时就能够保证[rain,a]对象中所有的对象都是存活的。

32、实现一个反转整数的函数,例如-–-

defreverse_str(value):

ifvalue-10andvalue10:

returnvalue

val_str=str(value)

ifval_str[0]!=-:

val_reverse=int(val_str[::-1])

else:

#-

val_reverse=-int(val_str[1:][::-1])

returnval_reverse

print(reverse_str())

33、Python是如何进行内存管理的?

34、is和==的区别

35、合并所有二维列表元素到一个列表:l=[[1,2],[3,4],[5,6]]

print([jforiteminlforjinitem])

36、输入某年某月某日,判断这一天是这一年的第几天?

importdatetime

date01=datetime.date(,12,31)

date02=datetime.date(,12,12)

#print(date.strftime(%j))

print(type(date02-date01))

print((date02-date01).days)

37、统计一段字符串中每个字符出现的次数,比如abcaabccab

s=abcaabccab

print(s.count(ab))

dic={}

foriins:

dic[i]=dic.get(i,0)+1

print(dic)

38、如何判断一个对象是否可调用

callable

39、__str__和__repr__的区别

#__str__的返回结果可读性强。也就是说,__str__的意义是得到便于人们阅读的信息

#__repr__存在的目的在于调试,便于开发者使用

#案例1:

classA():

...def__str__(self):

...returnstr

...

...def__repr__(self):

...returnrepr

...a=A()

a

repr

print(a)

str

#案例2:

importdatetime

date=datetime.datetime.now()

print(str(date))#-05-2:04:02.

print(repr(date))#datetime.datetime(,5,21,12,4,2,)

#案例3:

importjson

dic={name:yuan,age:23}

data=json.dumps(dic)

print(str(data))

print(repr(data))

40、什么是c3算法?

41、什么是断言(assert)?应用场景?

42、如何最快读取5个G的文件的行数

43、列举你了解的所有Python2和Python3的区别?

#Python2默认ASCII编码方式,Python3默认的编码方式是UTF-8。

#python2要求包必须有init文件,python3去除了一硬性要求

#python3的range不再返回列表,而是一个可迭代的range对象

#去除print语句,加入print()函数实现相同的功能。

#输入的区别。从键盘录入一个字符串,python2中是raw_input(helloworld),python3则是input(helloworld)。

#在Python3.x中取消了经典类,默认都是新式类,而且没必要显式的继承object,可是在Python2.x中,默认都是经典类,只有显式继承了object才是新式类。

44、实现一个Singleton单例类,要求遵循基本语言编程规范(用尽量多的方式)。



转载请注明地址:http://www.shiquanren.net/hzzz/hzzz/27126.html


  • 上一篇文章:
  • 下一篇文章: 没有了
  • 公司简介 广告合作 发布优势 服务条款 隐私保护 网站地图 版权声明