python面试复习_2

python面试

1.Python里面如果拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

赋值:l1=l2,对于赋值运算来说,他们指向的是同一个内存地址,修改任意一个则会影响到另一个。

浅拷贝:l2=l1.copy(),对于浅copy来说,只是在内存中重新创建了一个空间存放一个新的列表,但是新列表中的元素与

原列表中的元素是公用的。

深拷贝:l2=copy.deepcopy(l1),列表是重新创建的,列表中可变的数据类型是重新创建的,不可变的数据类型是公用的。

公用是:指向同一内存地址。深拷贝可以说是几乎与原来的对象不一样,拷贝的更加彻底。

2.可变和不可变数据类型

集合:可变的数据类型,但是里面的元素是不可变的数据类型,无序,不重复,{}

不可变类型:常数,字符串,元祖

可变类型:列表,字典,自定义类对象,集合,即可以增,删,改,查

3.Python里面的match()和search()的区别?

re模块中的match(pattern,string[,flags]),检查的是string的开头是否与pattern匹配

re模块中的search(pattern,string[,flags]),在string搜索pattern的第一个匹配值。

4.有没有一个工具可以帮忙查找python的bug和进行静态的代码分析?

PyChecker是一个python的代码的静态分析工具,他可以帮助查找python的代码的bug,会对代码的复杂度和格式提出警告。

5.简要描述Python的垃圾回收机制(garbage collection)

Python垃圾回收主要是以引用计数为主,分代回收为辅。

引用计数法的原理是每个对象都维护了一个ob_ref,用来记录当前对象被引用的次数。当指向该对象的内存的引用计算器为0的

时候,该内存就会被python虚拟机销毁。

偶尔也会出现引用循环,标记清除算法为了解决循环引用问题,作为Python的辅助垃圾收集技术主要处理的是一些容器对象,

比如list、dict、tuple,instance等,因为对于字符串、数值对象是不可能造成循环引用问题。

Python中也是用了分代回收来加速垃圾回收。例如,越晚创建的对象更有可能被回收。对象被创建之后,垃圾回收器会分配它们

所属的代。每个对象都会被分配一个代,而被分配更年轻代的对象是优先被处理的。

引用循环:

list1 = []

list2 = []

list1.append(list2)

list2.append(list1)

计数+1:对象被创建;对象被引用;对象被作为参数,传入函数中;对象作为一个元素,存储在容器中。

计数-1:对象的别名被显示销毁时del a ;对象的引别名被赋予新的对象,a=26;

一个对象离开它的作用域,例如 func函数执行完毕时,函数里面的局部变量的引用计数器就会减一(但是全局变量不会);

将该元素从容器中删除时,或者容器被销毁时。

6.什么是lambda函数?它有什么好处?

lambda表达式,通常是在需要一个函数,但是又不想去命名一个函数的场合下使用,也就是匿名函数。

例子:a=lambda x,y:x+y,a(3,11)

7.请写出一段Python代码实现删除一个list里面的重复元素。

1)使用set函数,set(list)

2)使用字典函数

a = [1,2,3,4,5,5,6,6,7,7,7]

b = {}

b = b.fromkeys(a) 创建一个新字典,dict.fromkeys(seq[, value]),以序列 seq 中元素做字典的键,

value 为字典所有键对应的初始值

c = list(b.keys())

print(c)

8.用Python匹配HTML tag的时候,<.*> 和 <.*?>的区别?

<.*>贪婪匹配,<.*?>非贪婪匹配

9.如何在一个function里面设置一个全局的变量?

在function的开始插入一个global声明

10.编程用sort进行排序,然后从最后一个元素开始判断去重。

b = [1,4,2,5,6,4,3,6,8,4,9,5]

b.sort() # 从小到大排序

last = b[-1]

for i in range(len(b)-2,-1,-1): # 去重

if last == b[i]:

del b[i]

else:

last = b[i]

print(b)

11.在Python3中//是一直执行整除,/是不执行整除的。例如5/2=2.5 或者5./2=2.5

12.有一种通信方式,加入发送方发送个数为4,接收方回传2个;发送方发送一组数如[11,12,43,21],则接收方通过检测

这组数里的二进制一的个数,返回最多的几个。[11,12,43,21]对应的二进制为[1101,0011,110101,10101],所以分别对应的1

的个数为[3,2,4,3];所以应该返回43和11或21

list_number = [11, 12, 43, 21] # 应该在调换bit_number位置时list_number也一起调换

N = len(list_number)

element = 2

bit_number = [] # 每个数1的个数

def int2binary_func(x): # 将x转化为二进制

bit = []

while(x) > 0:

bit.append(x%2)

x = x//2

return bit

def count(bit): # 计算1的个数

num = 0

for i in bit:

if i == 1:

num += 1

return num

def sort_func():

for i in range(N-1):

for j in range(i+1,N):

if bit_number[i] < bit_number[j]:

bit_number[i],bit_number[j] = bit_number[j],bit_number[i]

list_number[i],list_number[j] = list_number[j],list_number[i]

for i in list_number:

print(int2binary_func(i))

bit_number.append(count(int2binary_func(i)))

sort_func()

for i in range(element):

print(list_number[i])

13.单例模式

单例模式主要的目的是确保某一个类只有一个实例存在。

比如:某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间

,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个

AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,

我们希望在程序运行期间只存在一个实例对象。

知识点一:super()函数是用于调用父类的一个方法,调用方法是super().xxx,MRO就是继承父类方法时的顺序表,class名.mro()

知识点二:__new__方法主要是当你继承一些不可变的class时(比如:int,str,tuple),提供给你一个自定义这些类的实例化过程的途径

知识点三:hasattr(obj,name):检查是否存在一个name的属性

知识点四:单下划线开头,即是保护类型只能允许其本身与子类进行访问,不能用于from module import *

双下划线开头表示的是私有类型的变量,只能是允许这个类本身进行访问。

实现方法一:使用__new__

class Singleton:

def __new__(cls, *args, **kwargs):

print('创建一个对象')

if not hasattr(cls,'instance'):

cls.instance = super().__new__(cls)

print('对象不存在,重新创建')

return cls.instance

obj1 = Singleton() # __init__是用来初始化对象的,cls指的是本类

obj2 = Singleton()

实现方法二:使用装饰器

def Singleton(cls):

_instance = {}

def inner(*args,**kwargs):

if cls not in _instance:

_instance[cls] = cls(*arg,**kwargs)

return _instance[cls]

return inner

@Singleton # A = Singleton(A) = inner 做了两步操作,第一是创建了_instance,第二是放回inner函数名

class A:

a = 1

def __init__(self,x=0): # self值得是对象本身

self.x = x

a1 = A(2) # 直接指向inner(2)

a2 = A(3)

实现方法三:使用import方法

# 作为Python模块时是天然的单例模式

#创建一个sington.py文件,内容如下:

class Singleton(object):

def foo(self):

pass

mysington = Singleton()

# 运用

from sington import mysington

mysington.foo()

14.二分查找法

l1 = [1, 2, 4, 5, 7, 9]

def two_search(l,aim,start=0,end=None):

end = len(l)-1 if end is None else end

mid_index = (end - start) // 2 + start

if end >= start:

if aim > l[mid_index]:

return two_search(l,aim,start=mid_index+1,end=end)

elif aim < l[mid_index]:

return two_search(l,aim,start=start,end=mid_index-1)

elif aim == l[mid_index]:

return mid_index

else:

return '没有此值'

else:

return '没有此值'

print(two_search(l1,9))

15.Python是如何进行类型转换的?

强制类型转换内置函数,比如int float str

16.Python是如何进行内存管理的?

Python的内存管理是由python的解释器负责的,开发人员可以从内存管理实务中解放出来。

17.如何反序的迭代一个序列?

如果是List,则是list.reverse()

如果不是:

for i in range(len(sequence)-1,-1,-1):

x = sequence[i]

18.字符串排序

def strNums(stringList):

numList = []

for i in range(len(stringList)):

numList.append(int(stringList[i][-6:])

numList.sort() # 排序

for i in numList:

print(i)

19.Python里面如何实现tuple和list的转换?

函数tuple(seq)可以把所有可迭代的(iterbrable)序列转换成一个tuple,元素不变,排序也不变。

函数list(seq)可以把所有的序列和可迭代的对象转换成一个list元素不变。

20.Python文件操作的面试题

1.如何用python删除一个文件?

使用os.remove(filename) 或者os.unlink(filename)

2.Python如何copy一个文件?

使用shutil模块有一个copyfile函数可以实现文件拷贝

21.Python里面如何生成随机数?

使用random模块

import random

random_number = random.random()

他会返回一个随机的0和1之间的浮点数。

randint(start,end)

22.如何使用Python来发送邮件?

可以使用smtplib标准库

23.如何用python来进行查询和替换一个文本字符串?

可以使用sub()方法来进行查询和替换,sub方法的格式为:

import re

p = re.compile('(blue|white|red)')

print(p.sub('color','blue socks and red shoes')

print(p.sub('color','blue socks and red shoes',count=1)

结果:

color socks and color shoes

color socks and red shoes

subn()方法执行的效果和sub一样,不会它返回的是一个二维数组,包括替换后的新的字符串和总共替换的数量

24.介绍一下except的用法和作用?

Python的except用来捕获所有异常,因为Python里面的每次错误都会抛出一个异常,所以每个程序的错误都被当做一个运行时

错误。

import sys

try:

foo = open('file')

except IoError as e:

print(e)

25.Python中的Pass语句的作用是什么?

Pass语句什么也不做,一般作为占位符或者创建占位程序,pass语句不会执行任何操作。

26.range(-10,-100,-30),得到的是-10,-40,-70

27.一行代码实现1--100之和

print(range(0,101))

28.5个Python标准库

os:提供了与操作系统相关联的函数

sys:通常用于命令行参数

re:正则

math:数学运算

datetime:处理日期时间

29.字典如何删除键和合并两个字典

del和update方法,del dic['name'] dic.update(dic2)

30.python的GIL

GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器

(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时

操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。

多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时

运行,缺点是进程系统资源开销大

31.*args,**kwargs

*args:用来发送一个非键值对的可变数量的参数列表给一个函数

**kwargs:用来发送一个不定长度的键值对给函数

32.python2和python3的range(100)的区别

python2返回列表,python3返回迭代器,节约内存

33.python内建数据类型有哪些

整型--int

布尔型--bool

字符串--str

列表--list

元组--tuple

字典--dict

34.简述面向对象中__new__和__init__区别

_init__是初始化方法,创建对象后,就立刻被默认调用了,可接收参数

__new__是来实例化类的。

35.列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25]

list = [1,2,3,4,5]

def fn(x):

return x**2

ret = map(fn,list)

ret = [i for i in ret if i>10]

print(ret)

36.避免转义给字符串加哪个字母表示原始字符串?

r , 表示需要原始字符串,不转义特殊字符

37.python中断言方法举例

assert() 方法,断言成功,则程序继续执行,断言失败,则程序报错

38.数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句

select distinct name from student

39.10个Linux常用命令

ls pwd cd touch rm mkdir tree cp mv cat more grep echo kill vi

40.python2和python3区别?列举5个

1、Python3 使用 print 必须要以小括号包裹打印内容,比如 print('hi')

Python2 既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比如 print 'hi'

2、python2 range(1,10)返回列表,python3中返回迭代器,节约内存

3、python2中使用ascii编码,python中使用utf-8编码

4、python2中unicode表示字符串序列,str表示字节序列

python3中str表示字符串序列,byte表示字节序列

5、python2中为正常显示中文,引入coding声明,python3中不需要

41.s = "ajldjlajfdljfddd",去重并从大到小排序输出"adfjl"

s = "ajldjlajfdljfddd"

s = set(s)

s = list(s)

s.sort(reverse=True) # s.sort()从小到大排序

res = ''.join(s)

print(res)

42.用lambda函数实现两个数相乘

sum = lambda a,b:a*b

print(sum(2,4))

43.字典根据键从小到大排序

dict={"name":"zs","age":18,"city":"深圳","tel":"1362626627"}

list = sorted(dict.items(),key=lambda i:i[0],reverse=False) # dict.items()结果是字典的键值对元组

# i[0]表示表示值,i表示lambda传入的参数

print(list) # 结果是元素是元组的列表

new_dict = {}

for i in list:

new_dict[i[0]] = i[1]

print(new_dict)

44.利用collections库的Counter方法统计字符串每个单词出现的次数"kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

from collection import Counter

a ="kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

res = Counter(a)

print(res)

46.字符串a = "not 404 found 张三 99 深圳",每个词中间是空格,用正则过滤掉英文和数字,最终输出"张三 深圳"

import re

a = "not 404 found 张三 99 深圳"

lst = a.split(' ')

res = re.findall('\d+\.?\d*|[a-zA-Z]+',a)

for i in res:

if i in lst:

list.remove(i)

new_str = ' '.join(list)

print(new_str)

47.filter方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。该接收两个参数,

第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True

的元素放到新列表

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def fn(x):

return x%2 == 1

new_lst = filter(fn,a)

print(new_lst) # 返回的是一个filter 对象

new_lst = [i for i in new_lst]

print(new_lst)

48.列表推导式求列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

res = [i for i in a if i%2 ==1]

print(res)

49.正则re.complie作用

re.compile是将正则表达式编译成一个对象,加快速度,并重复使用

50.两个列表[1,5,7,9]和[2,2,6,8]合并为[1,2,2,3,6,7,8,9]

extend可以将另一个集合中的元素逐一添加到列表中,区别于append整体添加

51.log日志中,我们需要用时间戳记录error,warning等的发生时间,请用datetime模块打印当前时间戳 “2018-04-01 11:38:54”

import datetime

a = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+'星期:'+str(datetime.datetime.now().isoweekday()))

print(a)

52.数据库优化查询方法

外键、索引、联合查询、选择特定字段等等

53.简述Django的orm

实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要修改代码只需要面向对象编程,orm操作本质

上会根据对接的数据库引擎,翻译成对应的sql语句,所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、

sqlite....,如果数据库迁移,只需要更换Django的数据库引擎即可

54.[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]

a = [[1,2],[3,4],[5,6]]

x = [j for i in a for j in i]

55.举例说明异常模块中try except else finally的相关意义

try..except..else没有捕获到异常,执行else语句

try..except..finally不管是否捕获到异常,都执行finally语句

56.举例说明zip()函数用法

zip()函数在运算时,会以一个或多个序列(可迭代对象)做为参数,返回一个元组的列表。同时将这些序列中并排的元素配对。

zip()参数可以接受任何类型的序列,同时也可以有两个以上的参数;当传入参数的长度不同时,zip能自动以最短序列长度为准

进行截取,获得元组。

a = [1,2]

b = [3,4]

res = [i for i in zip(a,b)]

print(res)

结果:[(1,3),(2,4)]

57.写5条常用sql语句

show databases;

show tables;

desc 表名;

select * from 表名;

delete from 表名 where id=5;

update students set gender=0,hometown="北京" where id=5

58.提高python运行效率的方法

1、使用生成器,因为可以节约大量内存

2、循环代码优化,避免过多重复代码的执行

3、核心模块用Cython PyPy等,提高效率

4、多进程、多线程、协程

5、多个if elif条件判断,可以把最有可能先发生的条件放到前面写,这样可以减少程序判断的次数,提高效率

59、简述mysql和redis区别

redis: 内存型非关系数据库,数据保存在内存中,速度快

mysql:关系型数据库,数据保存在磁盘中,检索的话,会有一定的Io操作,访问速度相对慢

60、遇到bug如何处理

1、细节上的错误,通过print()打印,能执行到print()说明一般上面的代码没有问题,分段检测程序是否有问题,

如果是js的话可以alert或console.log

2、如果涉及一些第三方框架,会去查官方文档或者一些技术博客。

3、对于bug的管理与归类总结,一般测试将测试出的bug用teambin等bug管理工具进行记录,然后我们会一条一条进行修改,修改的过程也是理解业务逻辑和提高自己编程逻辑缜密性的方法,我也都会收藏做一些笔记记录。

4、导包问题、城市定位多音字造成的显示错误问题

61.列出常见的状态码和意义

200 OK

请求正常处理完毕

400 Bad Request

请求报文语法错误或参数错误

404 Not Found

无法找到请求资源(服务器无理由拒绝)

500 Internal Server Error

服务器故障或Web应用故障

304 Not Modified

发送的附带条件请求未满足

62.简述同源策略

同源策略需要同时满足以下三点要求:

1)协议相同

2)域名相同

3)端口相同

63、简述多线程、多进程

进程:

1、操作系统进行资源分配和调度的基本单位,多个进程之间相互独立

2、稳定性好,如果一个进程崩溃,不影响其他进程,但是进程消耗资源大,开启的进程数量有限制

线程:

1、CPU进行资源分配和调度的最小单位,线程是进程的一部分,是比进程更小的能独立运行的基本单位,一个进程下的多个

线程可以共享该进程的所有资源

2、如果IO操作密集,则可以多线程运行效率高,缺点是如果一个线程崩溃,都会造成进程的崩溃

应用:

IO密集的用多线程,在用户输入,sleep 时候,可以切换到其他线程执行,减少等待的时间

CPU密集的用多进程,因为假如IO操作少,用多线程的话,因为线程共享一个全局解释器锁,当前运行的线程会霸占GIL,

其他线程没有GIL,就不能充分利用多核CPU的优势

67、列出几种魔法方法并简要介绍用途

__init__:对象初始化方法

__new__:创建对象时候执行的方法,单列模式会用到

__str__:当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

__del__:删除对象执行的方法

68、请将[i for i in range(3)]改成生成器

生成器是特殊的迭代器,

1、列表表达式的[]改为()即可变成生成器

2、函数在返回值得时候出现yield就变成生成器,而不是函数了;

69.列表嵌套字典的排序,分别根据年龄和姓名排序

foo = [{"name":"zs","age":19},{"name":"ll","age":54},

{"name":"wa","age":17},{"name":"df","age":23}]

a = sorted(foo,key=lambda x:x['age'],reverse=True)

print(a)

70、python字典和json字符串相互转化方法

json.dumps()字典转json字符串,json.loads()json转字典

71.python传参数是传值还是传址?

Python中函数参数是引用传递(注意不是值传递)。对于不可变类型(数值型、字符串、元组),因变量不能修改,

所以运算不会影响到变量自身;而对于可变类型(列表字典)来说,函数体运算可能会更改传入的参数变量。

72.交集,差集,并集

交集:list(set(a).intersection(set(b)))

并集:list(set(a).union(set(b))))

差集:list(set(a).difference(set(b))) # a有b没有的

73.常见的网络传输协议

UDP、TCP、FTP、HTTP、SMTP等等

74.python是一门动态解释性的强类型定义语言

75.PEP 8是一个编码约定,一组推荐,关于如何编写Python代码更具可读性。

76.如何在Python中管理内存?

Python内存由Python私有堆空间管理。所有Python对象和数据结构都位于私有堆中。程序员无权访问此私有堆,

解释器负责处理此私有堆。

Python对象的Python堆空间分配由Python内存管理器完成。

77.什么是Python装饰器?

Python装饰器是我们在Python语法中进行的一项特定更改,可以轻松地更改函数。

78.Python的命名空间?

在Python中,引入的每个名称都有一个存在的地方,并且可以被挂钩。这称为命名空间。它就像一个框,

其中变量名称映射到放置的对象。每当搜索到变量时,将搜索此框以获取相应的对象。

79.Robot Framework常用的第三方库

request(请求网页),httplibrary(用来满足http需求,比如重定向,请求响应等的),Database-Library

selenium2Library(用来支持web测试的库),Djangolibrary(一个用Robot Framework测试Django的Web测试库)