python后端面试题目总结

此文作为面试题目记录,其中会有一些自己遇到过的和在网上看到的比较具有代表性的面试题,其中如果在前面文章中已经写过的就会比较简略,持续更新,没有顺序。

1、python中的浅拷贝与深拷贝,变量及其引用(python基础)
参https://blog.csdn.net/weixin_44806420/article/details/96456447
python中的赋值变量全部都是引用。

2、数据库的查询性能优化
①建立索引;
②优化SQL语句;
③数据库读写分离与主从负载均衡减轻压力;
④数据库分库与分表;
⑤数据库表设计时的空间换时间;
⑥利用缓存。

3、HTTP 1.0/1.1/2.0的区别
HTTP 1.0最早于1996年应用,主要用于处理一些简单的网页和请求,HTTP 1.1最早于1999年应用,也是当今应用最广泛的HTTP协议。

与HTTP 1.0相比,HTTP 1.1做了以下优化:
①添加支持了更多的缓存处理机制;
②允许控制只请求传输需要的某个部分,即206(Partial Content),有利于控制传输大小和带宽管理;
③新增了许多错误状态响应码,如409(Conflict);
④新增了host头域,这是由于虚拟主机技术的产生,使一台物理主机上可以有多台服务器,其共享相同的IP地址;
⑤支持长连接,在HTTP 1.1中默认开启长连接,即Connection: keep-alive。

HTTPS与HTTP区别:
①HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费;
②HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上(即多了SSL/TLS步骤),所有传输的内容都经过加密的;
:SSL(Secure Sockets Layer)及其继任者TLS(Transport Layer Security)在传输层对网络连接进行加密。
③HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443;
④HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。

SPDY是google在2012年提出的优化HTTP 1.1的方案,其优化如下:
①优化长连接:采用多路复用的方式,使一个TCP连接可以处理多个请求流,降低了延迟,并且允许对请求设置优先级;
②header压缩:双方传输过程中,每次请求的请求头(或响应的响应头)有很大一部分是相同的,通过合适的算法减少了这部分的消耗;
③基于HTTPS加密;
④服务端推送:将需要的静态资源直接推送到客户端电脑上,从本地读取文件当然比每次都发送请求从服务器获取要快捷的多。
SPDY工作于SSL/TLS与HTTP协议之间,可兼容HTTP1.0。

HTTP2.0基本上就是SPDY的升级版,其与SPDY的不同点在于:
HTTP2.0仍然支持使用TCP明文传输,SPDY强制使用HTTPS,且其header文件的压缩算法不同。

HTTP2.0相较于HTTP1.1的优化与改进:
①基于二进制格式:HTTP1.1基于文本格式,表现形式具有多样性,完全基于二进制格式的HTTP2.0使用方便且健壮;
②多路复用;
③header压缩;
④服务端推送,与上述相同。
且HTTP2.0向下兼容。

4、TCP三次握手与四次挥手
参https://blog.csdn.net/weixin_44806420/article/details/98481707
已详解。

5、进程与线程区别,包括进程/线程间通信,python中协程等问题
参https://blog.csdn.net/weixin_44806420/article/details/97406302
https://blog.csdn.net/weixin_44806420/article/details/97946124

6、redis数据库简介
参https://blog.csdn.net/weixin_44806420/article/details/90764203

7、5层与7层网络模型
参https://blog.csdn.net/weixin_44806420/article/details/98448069

8、TCP的流量控制与拥堵控制
在https://blog.csdn.net/weixin_44806420/article/details/98481707中有简单介绍,此处进行对比。

(1)流量控制
TCP通过滑动窗口机制进行流量控制,滑动窗口大小指的是无须等待确认应答而可以继续发送数据的最大值,即一次发送多条数据将等待应答时间叠加在一起,同时也将其应答合并为一条,发送端操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据才能从缓冲区删掉;
注意,发送窗口的大小不能超过接收窗口的大小。
其大致流程为:①TCP建立连接,建立连接时接收方告诉发送方其窗口大小;
②发送方发送数据,接收方接收数据,回复ACK报文并剩余窗口大小;
③当剩余窗口大小为0时发送方无法再发送数据,接收方在经过一段时间处理后(缓存区数据处理完毕)会对发送方回复现在窗口大小,当窗口大小不为0时发送方可继续发送数据。

可能出现的问题及解决方案:
①当接收方上次回复窗口为0后,再回复的窗口大小报文丢失时,发送方不会继续发送数据,即发送方一直等待窗口不为0的报文,而接收方等待发送方发送的数据,即死锁;
②解决方案有添加计时器,0窗口探测报文,发送方强制发送(最大报文长度,发送方推送强制发送)等。

(2)拥堵控制
慢启动与拥堵避免机制,接收方维持一个网络状态变量,当拥堵窗口比它小时就使用慢启动算法增大拥堵窗口(乘法增长,速率大),当拥堵窗口比它大时就使用拥堵避免算法增大拥堵窗口(加法增长,速率小)。
快重传与快恢复机制,当发送方收到接收方连续三次ack相同时,将对应部分的报文重传,且认为当前网络有拥堵的可能性,将当前拥堵窗口的尺寸减半,重新开始慢启动。
注意当传输超时后,就认为网络拥堵,拥堵窗口从初始值开始慢启动。

流量控制简单来说就是接收方通过告知发送方当前窗口尺寸(当前最大接收数量),来控制发送方发送数据。
拥堵控制简单来说就是接收方通过控制拥堵窗口尺寸(发送方发送窗口尺寸与其大小相同),来试探并避免网络拥堵。
区分:流量控制重点在于根据接收方的接收能力控制发送方发送数据量,拥堵控制重点在于根据当前网络状态控制发送方发送的数据量,流量控制不考虑当前网络状态,拥堵控制不考虑接收方接收能力,在实际操作中发送方的窗口大小取决于拥堵窗口和接收窗口中的较小值。

9、session与cookie
(1)cookie:指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密),其最典型的例子为记住用户名,cookie的特点:
①由服务器生成,以键值对的方式存储在浏览器中(服务器生成后保存在HttpResponse对象中发送给浏览器);
②访问一个网站时,会将浏览器存储的所有与该服务器相关的cookie全部发送(保存在WSGIrequest对象.COOKIES中,是一个标准的python字典格式)
③cookie基于域名安全,即不同IP的cookie是不能相互访问的;

(2)session:指服务器为每个浏览器保存数据的机制(一般用于保存比较重要,敏感的信息)session的特点:
①由服务器生成,以键值对的方式保存在服务器中;
②session依赖于cookie(其唯一标识的session_key是使用cookie来保存的,称为sessionid);
③session指定的过期时间是cookie sessionID的过期时间。

session与cookie的联系与区别:
①session保存于服务器端,cookie保存于浏览器端并每次访问都携带;
②session依赖于cookie工作,其唯一标识的sessionid存在于cookie中;
③session用于保存重要的信息,cookie安全性不高;
④cookie中提出的值全为字符串格式,session中不改变其存储的格式;
⑤cookie的使用方式为response设置request携带,session的使用方式为request设置并在其他视图函数中request使用,但request其实只携带了sessionid,内容在服务器端,其依赖request中携带的sessionid来标识不同的浏览器。

注:session与cookie与前后端分离与令牌
在前后端不分离或前后端网站同源时,使用cookie与session并无问题,其设置方法本质上就是在响应头中添加set-cookie条目,但是如果前后端网站不同源时,在浏览器默认情况下基于安全考虑,不同源的网站不能共享cookie(当然包括在其中的sessionid也无效),此时可以通过一些设置和前端策略来实现共享session,但是安全性不高,此时常用的手段为token(令牌)。
基于token的身份验证机制流程如下:
①客户端使用用户名跟密码请求登录;
②服务端收到请求,去验证用户名与密码;
③验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端;
④客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;
⑤客户端每次向服务端请求资源的时候需要带着服务端签发的 Token;
⑥服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据。

JWT(JSON Web Tokens)
JWT 标准的 Token 有三个部分:
header(头部)
payload(数据)
signature(签名)
三部分内容以点分隔,使用 Base64 编码,因此直观来看是xxx.xxxx.xxxx三部分乱码,其中:
①header部分,包括了使用的算法(以字典形式表示,最终经过base64编码);
②payload部分,包括的标注字段如下:

iss:Issuer,发行者
sub:Subject,主题
aud:Audience,观众
exp:Expiration time,过期时间
nbf:Not before
iat:Issued at,发行时间
jti:JWT ID

其中标准字段是可选的,也可以添加自定义字段;
③signature部分,其组成为header.payload的base64编码与secret字段共同加密后返回的编码,乱码形式。

10、python中的import机制、循环嵌套与垃圾回收机制、内存泄漏
参https://blog.csdn.net/weixin_44806420/article/details/97049807

内存泄漏指的是由于种种原因造成的不能释放已经不再使用的内存的现象,其一般会出现在循环引用、未命名函数、无限循环等场景,在python等高级语言中都有其语言自带的垃圾回收机制,就是为了避免内存泄漏产生。
①可以使用标准库中的gc模块来查看相关对象信息;
②重写__del__方法时要非常慎重,如果处理不当很容易出现内存泄漏,也可以使用弱引用的方式解决循环引用;
③python标准库中的tracemalloc模块可以统计内存使用状况。

Python的内存是由私有的heap空间管理的,所有的Python对象和数据结构都在一个私有heap中,程序员没有访问heap的权限,只有解释器才能进行操作。为Python的heap空间分配内存是由Python的内存管理模块进行的,其核心API会提供一些访问该模块的方法供程序员使用。Python有自带的垃圾回收机制,它回收并释放没有被使用的内存,让他们能够被其他程序使用。

11、shell与bash
操作系统其实就是一组软件,其用于控制硬件(CPU/内存/磁盘等)工作和管理系统的活动监测,也被称为内核(kernel),这部分软件不可以被没有管理能力的终端随意使用,但是又需要对于操作系统进行控制,因此就有了在操作系统上层发展的应用程序,也被称作壳程序(shell)。

操作系统的角色:①硬件,如CPU、内存、硬盘、声卡等;②内核,内核直接参考硬件规格写成,因此同一个操作系统程序不能够在不一样的硬件架构下运行;③系统调用,为了保护内核,也为了让程序员可以比较容易开发软件,操作系统除了内核外还会提供一套API,也就是系统调用层,内核和系统调用共同组成操作系统;④应用程序(壳程序),应用程序其实就是调用操作系统提供的API,完成自己的功能,因此即使要实现相同的功能在不同的操作系统上其应用程序也是一定不同的,也就是通常所说的兼容性问题。

shell:用户用于指挥内核的壳程序,这个壳程序可以调用其他软件,在linux中,shell狭义上专指命令行软件(如bash等,即终端),广义上也包括图形用户界面模式的软件,图形用户界面本身也是一个壳程序,其可以操作各种应用程序来调用系统内核工作,且由于各种linux内核的shell。
(在没有图形界面的操作系统中,用户想要执行任何动作(不论是其他应用程序或是操作系统调用),都需要通过命令行来执行,因此其为最外层,shell)

shell的种类:①sh,Bourne shell,早期版本,现在已经被bash替代;②bash,GNU Bourne Again Shell,许多linux平台的内定shell(Ubuntu的终端默认打开的就是这个shell);③csh,tcsh,使用类似于C语言语法的shell;④rbash,受限的bash,可以用于启动一个限制命令的终端如作为中转服务器等;⑤dash,Debian Almquist Shell,其是简略版的bash,总体体积比bash小得多,支持的命令也少很多。

:①可以使用alias为命令设置别名,如alias lm='ls -la'
②使用echo $mynameecho ${myname}可以声明变量,然后可以使用myname = 'xxx'来给变量赋值;
③前述的linux命令其实都是bash中自带的应用程序,其相当于使变量指向应用程序,并通过bash来调用它;
④在Ubuntu中,默认的shell执行命令指向dash,因此在执行一些脚本文件时可能其中的命令在dash中没有,就会出现错误,可以强制使用bash解析或自行设置将shell执行命令指向bash。

12、python中的print函数

print(value,....,sep=' ',end='\n',file = sys.stdout, flush = False)

value,要打印的值,以逗号隔开;
sep,输入多个值时分隔符,默认空格;
end,print结束后默认换行;
file,输入到,默认是标准输出即终端,还可以用于向文件中输出,可以是open对象或者其他字节流;
flush,刷新,正常情况下print到f中的内容先从到内存中,当文件对象关闭时才把内容输出到文件中,当flush=True时它会立即把内容刷新存到文件中,也常用于如在线即时聊天,正常情况下是请求结束后输出到标准输出,改为True后立刻输出。

你可能感兴趣的:(后端基础,面试题目)