面试(一)
1.python中__new__ 与 __init__ 方法的区别:
类先调用__new__方法,返回该类的实例对象,这个实例对象就是__init__方法的第一个参数self,即self是__new__的返回值。

self是类(Class)实例化对象,cls就是类(或子类)本身,取决于调用的是那个类。
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
2.什么是匿名函数:
lambda函数能接收任何数量(可以是0个)的参数,但只能返回一个表达式的值,lambda函数是一个函数对象,直接赋值给一个变量,这个变量就成了一个函数对象。 语法:lambda 参数:表达式
使用场景:只有一个地方会使用这个函数,不会在其他地方重用,可以使用lambda函数
1.与map()函数一起使用:
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回遍历序列,对序列中每个元素进行函数操作,最终获取新的序列。
li = [1,2,3,4,5,6,7,8,9] print(list(map(lambda x:x*x,li))) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
2.与reduce()函数使用:
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(func,[1,2,3]) 等同于 func(func(1,2),3)。对于序列内所有元素进行累计操作
#接受一个list并利用reduce()求积 from functools import reduce li = [1,2,3,4,5,6,7,8,9] print(reduce(lambda x,y:x * y,li)) # 结果=1*2*3*4*5*6*7*8*9 = 362880
3.与filter()函数一起使用:
filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。对于序列中的元素进行筛选,最终获取符合条件的序列
# 在一个list中,删掉偶数,只保留奇数 li = [1, 2, 4, 5, 6, 9, 10, 15] print(list(filter(lambda x:x % 2==1,li))) # [1, 5, 9, 15]
3.简要概述一下python中生成器和迭代器?
(1)迭代器:迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。迭代器有两个基本的方法:iter() 和 next()。
迭代器协议:对象需要提供next()方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常(用于标识迭代的完成,防止出现无限循环的情况),以终止迭代。
可迭代对象:实现了迭代器协议对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter(),把这些都变成Iterable(可迭代器对象)。
for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,遇到StopIteration的异常后循环结束。
(2)生成器:使用了 yield 的函数被称为生成器(generator),生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True: try: print (next(f), end=" ") except StopIteration: sys.exit()
将列表生成式中[]改变为()数据结构会改变,从列表变为生成器;
列表受内存限制,所以没有必要创建完整的列表(节省大量内存空间),在python中我们可以采用生成器:边循环边计算的机制;
生成器是只能遍历一次的。生成器是一类特殊的迭代器。还能使用 def 定义函数,但是,使用yield而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。
4.Python的垃圾回收机制(garbage collection)
(1)当gc模块的计数器达到阈值,垃圾自动回收
(2)当调用gc.collect(),垃圾收到回收
(3)程序退出的时候,python解释器来回收垃圾
5.函数装饰器的作用?
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
6.进程、线程的区别?
(1)定义的不同
进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
(2)区别
- 一个程序至少有一个进程,一个进程至少有一个线程。
- 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。
- 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
- 线线程不能够独立执行,必须依存在进程中。
(3)优缺点
线程执行开销小,但不利于资源的管理和保护;而进程正相反。
7.函数的闭包
闭包概念:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。

在函数startAt中定义了一个incrementBy函数,incrementBy访问了外部函数startAt的变量,并且函数返回值为incrementBy函数(注意python是可以返回一个函数的,这也是python的特性之一)
闭包无法修改外部函数的局部变量。
8.Python里的拷贝
Copy浅拷贝,只拷贝父元素,deepcopy深拷贝,递归拷贝可变对象的所有元素。
- 通过类构造函数对list1进行了浅拷贝,通过id(list1)和id(list2)可知list1与list2是两个不同的对象,但是list1和list2共享内部对象的引用(由list1与list2中的各个元素的id(ele)可知)
- 通过copy模块中的deepcopy对list1进行了深拷贝得到list2,由list1与list2的id可知list1与list2是两个不同的对象。由list1和list2中各个元素的id可知,lis1与list2t中的可变对象不共享对象引用。深浅拷贝的差异仅对复合对象有意义,比如列表,类实例。
9.什么是事务?
事务(Transaction)是并发控制的基本单位。所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转帐工作:
从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。
事务四大特性:
原子性:事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行;
一致性:几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致;
隔离性:事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的;
持久性:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
10. 主键和外键的区别?
主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;
外键和另一张表的主键关联,不能创建对应表中不存在的外键。
11. 在数据库中查询语句速度很慢,如何优化?
(1)建索引;
(2)减少表之间的关联;
(3)优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面;
(4)简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据;
(5)数据库做好读写分离。
12.对if __name__ == 'main'的理解?
“ if __name__ == '__main__':”
在Python中分为两类:一种是直接执行,另外一种是作为模块时才被调用。
__name__ 作为模块的内置属性,即".py"文件的调用方式。如果等于“__main__"就直接执行本文件,如果是别的就是作为模块被调用。
13.tcp和udp的区别?
TCP 和 UDP 是传输层的两个协议

TCP建立连接:三次握手,中断连接:四次挥手
TCP 的顺序问题,丢包问题,流量控制都是通过滑动窗口来解决的。拥塞控制时通过拥塞窗口来解决的
14. http协议与https协议的区别?
http是超文本传输协议在互联网上应用最为广泛的一种网络协议,所有www文件都必须遵守这个标准,基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)连接。
https是超文本传输安全协议,是一种网络安全传输协议。http协议传输的数据都没有加密,一些私密的信息不安全,https经由超文本传输协议(http)进行通信,利用SSL/TLS来加密数据包,https开发的主要目的就是为了保护数据传输的安全性。
HTTPS和HTTP的区别:
1) https协议要申请证书到ca,需要一定经济成本
2) http是明文传输,https是加密的安全传输
3)连接的端口不一样,http是80,https是443
4)http连接很简单,没有状态;https是ssl加密的传输,身份认证的网络协议,相对http传输比较安全。
15.参数按值传递和引用传递是怎样实现的?
Python中的一切都是类,所有的变量都是一个对象的引用。引用的值是由函数确定的,因此无法被改变。
但是如果一个对象是可以被修改的,你可以改动对象。
16.python中search()和match()的区别
match从起始位置开始往后查找,如果不是起始位置匹配成功,则返回none
search任何位置开始往后查找,返回第一个符合规则的匹配
17.请描述一下try……except……else……finally执行的顺序?
try:
#尝试实现某个操作,
#如果没出现异常,任务就可以完成
#如果出现异常,将异常从当前代码块扔出去尝试解决异常
except 异常类型1:
#解决方案1:用于尝试在此处处理异常解决问题
except 异常类型2:
#解决方案2:用于尝试在此处处理异常解决问题
else:
#如果没有出现任何异常,将会执行此处代码
finally:
#管你有没有异常都要执行的代码
18.GET和POST是什么?
二者都是HTTP协议中的两种发送请求的方法。GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

19.重载和重写
重载:是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。重载是让类以统一的方式处理不同类型数据的一种手段。python是没有重载的,第二个同名的函数会把第一个覆盖掉。第一因为python没有类型,第二python有可变参数
重写:子类不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
参考链接:https://www.zhihu.com/column/c_1022803622949715968

浙公网安备 33010602011771号