python面试题
一、自己总结
1、(此题有坑)下面代码打印的结果分别是?
def extendList(val,lst=[]):
# 默认值参数的默认值如果是可变的数据类型,每次使用的都是同一个
lst.append(val)
return lst
lst1 = extendList(10)
lst2 = extendList(123,[])
lst3 = extendList('a')
print('list1=%s' % lst1) # 结果为:list1=[10,'a']
print('list2=%s '% lst2) # 结果为:list2=[123]
print('list3=%s' % lst3) # 结果为:list3=[10,'a']
2、1.2 - 1.0 == 0.2 的结果是True还是False
1.2 - 1.0 == 0.2 # 结果为:False
3、lambda匿名函数多个返回值的问题
f = lambda x, y : x+y, 2 print(f) # 结果为:(<function <lambda> at 0x00000000028C9AE8>, 2) # 分析:首先看如下代码: a = 2, 3 print(a) # 结果为:(2, 3),变量a是一个元组,元素为等号后边的内容 # 所以这里的f不是匿名函数,而是由lambda x, y : x+y的结果和 2 构成的元组 # 因此lambda匿名函数想有两个返回值时要加上括号,如下代码: f = lambda x, y : (x+y, 2) print(f(2,3)) # 结果为:(5, 2)
4、简述MVC和MTV
MVC设计模式是一种使用Model View Controller(模型-视图-控制器)设计创建web应用程序的模式:
所谓MVC就是把web应用分为模型层(Model),控制器层(Controller),视图层(View);他们之间以一种插件似的,松耦合的方式连接在一起。
模型层用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据;
视图层处理数据显示的部分,通常视图是依据模型数据创建的;
控制器用于处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据;
Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:
Model(模型):负责业务对象与数据库的对象(ORM);
Template(模版):负责如何把页面展示给用户;
View(视图):负责业务逻辑,并在适当的时候调用Model和Template;
此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template。MTV的响应模式如下所示:

5、OSI七层模型
应用层(HTTP、FTP)
表示层
会话层
传输层(TCP、UDP)
网络层(IP)
数据链路层
物理层
二、ssx给的what,how 。。。
1、什么是python?有什么特点?
python是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理。可以加入与其他语言的对比。下面是回答这一问题的几个关键点:
a. Python是一种解释型语言,python代码在运行之前不需要编译。
b. Python是动态类型语言,在声明变量时,不需要说明变量的类型。
c. Python适合面向对象的编程,因为它支持通过组合与继承的方式定义类。
d. 在Python语言中,函数是第一类对象。
e. Python代码编写快,但是运行速度比编译语言通常要慢。
f. Python用途广泛,常被用作“胶水语言”,可帮助其他语言和组件改善运行状况。
g. 使用Python,程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。
2、什么是python自省?
Python自省 --- 在运行时能够获得对象的类型,为程序员提供了极大的灵活性和控制力。
type(obj),判断对象类型
dir(), 带参数时获得该对象的所有属性和方法;不带参数时,返回当前范围内的变量、方法和定义的类型列表
isinstance(obj, class),判断对象是否是已知类型
hasattr(obj, 'x'),判断对象是否包含对应属性
getattr(obj, 'x'),获取对象属性
setattr(obj, 'x', val), 设置对象属性
3、什么是PEP8?举几个例子?
PEP8是一种编程规范,内容是一些关于如何让你的程序更具可读性的建议。每个缩进级别使用4个空格;
行的最大长度:
每行最大行宽不超过 79 个字符;
空行:
顶层函数和类的定义,前后用两个空行隔开;
类里的方法定义用一个空行隔开;
导入:
导入通常在分开的行;
导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前;
导入应该按照以下顺序分组,且在每一组导入之间加入空行:
标准库导入
相关第三方库导入
本地应用程序的库导入
注释:
代码更改时,相应的注释也要随之更改
命名:
命名要规范,通俗易懂;
类名一般使用首字母大写的约定;
函数名应该小写,如果想提高可读性可以用下划线分隔;
函数和方法参数:
始终要将 self 作为实例方法的的第一个参数;
始终要将 cls 作为类静态方法的第一个参数;
4、CSRF是什么?
CSRF是伪造客户端请求的一种攻击,CSRF的英文全称是Cross Site Request Forgery,字面上的意思是跨站点伪造请求。
5、如何在一个function里面设置一个全局的变量?
如果要给全局变量在一个函数里赋值,必须使用global语句。global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。
6、如何理解开源?
开源,即开放源代码。开源诞生于软件行业,它不仅仅代表软件源代码的开放,本身即意味着自由、共享和充分利用资源。开源是一种精神,是一种文化,如今已经成为软件业发展的大势所趋。
7、xrange和range的区别?
range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列。xrange 用法与 range 完全相同,所不同的是生成的不是一个list对象,而是一个生成器。要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间。range会直接生成一个list对象,而xrange则不会直接生成一个list,而是每次调用返回其中的一个值。
8、代码中要修改不可变数据会出现什么问题? 抛出什么异常?
不能正常运行,抛出 TypeError 异常。
9、a=1,b=2,不用中间变量交换 a 和 b 的值。
方法一:a,b = b,a
方法二:
a = a + b
b = a - b
a = a - b
10、下面这段代码的输出结果将是什么?请解释?
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass
print(Parent.x, Child1.x, Child2.x) Child1.x = 2 print(Parent.x, Child1.x, Child2.x) Parent.x = 3 print(Parent.x, Child1.x, Child2.x)
1 1 1 1 2 1 3 2 3
12、mysql的死锁是如何产生的?
如下是死锁产生的四个必要条件:
互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
13、如何对查询语句进行优化?
a. 应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
b. 应尽量避免在 where 子句中对字段进行 null 值判断,避免使用!=或<>操作符,避免使用 or 连接条件,或在where子句中使用参数、对字段进行表达式或函数操作,否则会导致全表扫描。
c. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
d. 使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。
e. 很多时候可考虑用 exists 代替 in。
f. 尽量使用数字型字段。
g. 尽可能的使用 varchar/nvarchar 代替 char/nchar。
h. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
i. 尽量使用表变量来代替临时表。
j. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
k. 尽量避免使用游标,因为游标的效率较差。
l. 在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF。
m. 尽量避免大事务操作,提高系统并发能力。
n. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
14、mysql数据库如何分区、分表?
分表可以通过三种方式:mysql集群、自定义规则和merge存储引擎。
分区有四类:
RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区。
LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
KEY 分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
15、python是如何进行内存管理的?
Python的内存管理是由私有heap空间管理的。所有的Python对象和数据结构都在一个私有heap中。程序员没有访问该heap的权限,只有解释器才能对它进行操作。为Python的heap空间分配内存是由Python的内存管理模块进行的,其核心API会提供一些访问该模块的方法供程序员使用。Python有自带的垃圾回收系统,它回收并释放没有被使用的内存,让它们能够被其他程序使用。
三、365道面试题
1、魔法函数(类的特殊成员)
| __setattr__ | 添加属性时触发 | f1.name = 1 | |
| __delattr__ | 删除属性时触发 | del f1.name | |
| __getattr__ | 调用不存在的属性时触发 | f1.name | |
| __getattribute__ | 有无属性均触发 | f1.name or f1.names | |
| __setitem__ | f1["name"] = 1 | ||
| __getitem__ | f1["name"] | ||
| __delitem__ | del f1["name"] | ||
| __init__ | 为空对象进行数据初始化 | Class() | |
| __new__ | 创建一个空对象 | Class() | Class中没有则调用父类Object中的,真正的构造方法 |
| __str__ | 类在被打印时触发 | print(class) | |
| __doc__ | 调用类中的描述 | class.__doc__ | |
| __call__ | 对象()时触发 | obj() | |
| __dict__ | 对象中封装的数据以字典形式返回 | obj.__dict__ | |
| __iter__ | 返回可迭代对象的迭代器 | obj.__iter__ |
2、什么是负载均衡?
负载平衡也称负载共享,是指对系统中的负载情况进行动态调整,以尽量消除或减少系统中各节点负载不均衡的现象。具体实现方法是将过载节点上的任务转移到其他轻载节点上,尽可能实现系统各节点的负载平衡,从而提高系统的吞吐量。负载共享有利于统筹管理分布式系统中的各种资源,便于利用共享信息及其服务机制扩大系统的处理能力。
3、[11, 33, 4, 2, 11, 4, 9, 2]去重并保持原来的顺序?
# 去重
lst = [11,33,4,2,11,4,9,2]
ret = list(set(lst))
# 按照原来的顺序排序
lst = sorted(ret, key=lst.index)
# ret是可迭代对象,key是传入一个函数名,函数的参数是可迭代对象类型中的每一项,根据函数的返回值大小进行排序
4、按照年龄从小到大排序。
list3 = [
{"name": "金老板", "age": 30},
{"name": "Eva_J", "age": 18},
{"name": "MJJ", "age": 29}
]
ret = sorted(list3, key=lambda x:x["age"])
5、深浅copy指的是什么? 请使用原生代码实现简单json对象深拷贝(补充)
import copy
l = [1,2,3,4,[1,3,4],5,6]
l1 = l
l2 = l.copy()
l3 = copy.deepcopy()
l[4].append(66)
l.append(22)
print(l) # [1,2,3,4,[1,3,4,66],5,6,22]
print(l1) # [1,2,3,4,[1,3,4,66],5,6,22] 赋值都变
print(l2) # [1,2,3,4,[1,3,4,66],5,6] 浅拷贝外层不变
print(l3) # [1,2,3,4,[1,3,4],5,6] 深拷贝都不变
6、简述编译型语言和解释性语言?
编译型语言:将程序全部编译成二进制机器码,再执行,修改一次要重新编译一次,执行效率高,但开发效率低;
解释性语言:程序运行时,一行一行解释执行,开发效率高;
7、位和字节的关系?
8位 = 1字节
8、b、B、KB、MB、GB 的关系?
1GB = 1024MB
1MB = 1024KB
1KB = 1024B
1B = 8b
9、字符串和列表如何相互转换?
字符串 --> 列表
s='oldboy'
lst = list(s)
列表 --> 字符串
li = ['0','1','2']
s = "".join(li)
10、写代码实现字符串反转,如:v = "oldboy"
v[::-1]
11、列举 Python2和Python3的区别?
python2没有nonlocal关键字,要修改临时变量只能将其改成可变数据类型,如数组。b=[a]
py3中的print()函数代替py2中的print语句
Python3加入 Unicode 字符串,用以编码存储字符串。比如用 utf-8可以用来输入中文
Python3去掉long类型,新增了bytes
Python 3整数之间做除法可以得到浮点数的结果,不需要进行数据格式转换1/2=0.5 ,Python 2整数int间除法结果为把运算结果去尾的整数1/2=0,3/2.0=1.5
Python3 中 range(),Python2 中 xrange()
python2中的不等于号可以是!=或者<>,python3只能是!=
python2中raw_input()用来输入字符串,而python3中使用input()来输入字符串
12、写一个装饰器计算函数执行时间?
import time def timmer(*args,**kwargs): def wrapper(f): def inner(*args,**kwargs): if flag: start_time = time.time() ret = f(*args,**kwargs) time.sleep(0.3) end_time = time.time() print('此函数的执行效率%f' % (end_time-start_time)) else: ret = f(*args, **kwargs) return ret return inner return wrapper flag = True @timmer(flag,2,3) def func1(): print('执行完毕!')
浙公网安备 33010602011771号