Python面试重点(进阶篇)
注意:只有必答题部分计算分值,补充题不计算分值。
第一部分 必答题
-
简述 OSI 7层模型及其作用?(2分)
# 应用层:文件传输,文件管理,电子邮件的信息处理# 表示层:确保一个系统的应用层发送的消息可以被另一个系统的应用层读取,编码转换,数据解析,管理数据的解密和加密# 会话层:验证访问和会话管理# 传输层:为应用程序之间提供端对端的逻辑通信。# 网络层:选择合适的网间路由完成两个计算机之间的多个数据链路,通过路由协议和地址解析协议(ARP)。IP,RIP(路由信息协议),OSPF(最短路径优先协议)# 数据链路层:在物理层提供的比特流的基础上,建立相邻节点之间的数据链路,不可靠的物理介质提供可靠传输 ppp协议# 物理层:规定通信设备,通信链路的特性
-
简述 TCP三次握手、四次回收的流程。(3分)
# 第一次握手:客户端首先向服务端发起连接,这时TCP头部中的SYN标识位值为1,然后选定一个初始序号seq=x(一般是随机的),消息发送后,A进入SYN_SENT状态,SYN=1的报文段不能携带数据,但要消耗一个序号。# 第二次握手:服务端收到客户端的连接请求后,同意建立连接,向A发送确认数据,这时TCP头部中的SYN和ACK标识位值均为1,确认序号为ack=x+1,然后选定自己的初始序号seq=y(一般是随机的),确认消息发送后,服务端进入SYN_RCVD状态,与连接消息一样,这条消息也不能携带数据,同时消耗一个序号。# 第三次握手:客户端收到服务端的确认消息后,需要给服务端回复确认数据,这时TCP头部中的ACK标识位值为1,确认序号是ack=y+1,自己的序号在连接请求的序号上加1,也就是seq=x+1,此时客户端进入ESTABLISHED状态,当服务端收到客户端的确认回复后,服务端也进入ESTABLISHED状态,至此TCP成功建立连接,客户端和服务端之间就可以通过这个连接互相发送数据了。#第一次挥手:客户端首先向服务端发送断开连接消息,这时TCP头部中的FIN标识位值为1,序号是seq=m,m为客户端前面正常发送数据最后一个字节序号加1得到的,消息发送后客户端进入FNI_WAIT_1状态,FIN=1的报文段不能携带数据,但要消耗一个序号。# 第二次挥手:服务端收到客户端的断开连接请求需要发出确认消息,这时TCP头部中的ACK标识位值为1,确认号为ack=m+1,而自己的序号为seq=n,n为服务端前面正常发送数据最后一个字节序号加1得到的,然后服务端进入CLOSE_WAIT状态,此时就关闭了客户端到服务端的连接,客户端无法再给服务端发数据,但是服务端仍然可以给客户端发数据,同时服务端端通知上方应用层,处理完成后被动关闭连接。然后客户端收到服务端的确认信息后,就进入了FIN_WAIT_2状态。# 第三次挥手:服务端端应用层处理完数据后,通知关闭连接,服务端向客户端发送关闭连接的消息,这时TCP头部中的FIN和ACK标识位值均为1,确认号ack=m+1,自己的序号为seq=k,消息发送后服务端进入LAST_ACK状态。# 第四次挥手:客户端收到服务端的断开连接的消息后,需要发送确认消息,这是这时TCP头部中的ACK标识位值为1,确认号ack=k+1,序号为m+1(因为客户端向服务端发送断开连接的消息时消耗了一个消息号),然后客户端进入TIME_WAIT状态,若等待时间经过2MSL后,没有收到服务端的重传请求,则表明服务端收到了自己的确认,客户端进入CLOSED状态,服务端收到客户端的确认消息后则直接进入CLOSED状态。至此TCP成功断开连接。
-
TCP和UDP的区别?(3分)
#TCP协议 上传下载\发邮件、可靠、面向连接、速度慢、能传递的数据长度不限、流式传输、全双工(连接上之后,server端和client端可以相互通信)# UDP协议 即时通讯工具、不可靠、面向数据报、速度快、能传递的数据长度有限、不管对方在不在,直接发送、应用:短消息类、在线观看视频不占连接、随时可以收发消息
-
什么是黏包?(2分)
# 当多条消息发送时接收变成了一条或者出现接收不准确的情况
-
什么 B/S 和 C/S 架构?(2分)
# B/S:B浏览器,S服务端,在浏览器输入地址就可以直接使用的一种网络架构,浏览器充当客户端# C/S:C客户端,S服务端,需要安装客户端使用的网络架构
-
请实现一个简单的socket编程(客户端和服务端可以进行收发消息)(3分)
server端:import socketsk = socket.socket()sk.bind(('127.0.0.1',8898)) sk.listen() conn,addr = sk.accept() ret = conn.recv(1024) print(ret) conn.send("你好".encode("utf-8")) conn.close() sk.close() client端:import socketsk = socket.socket() sk.connect(('127.0.0.1',8898)) sk.send(b'hello!')ret = sk.recv(1024) print(ret) sk.close()
-
简述进程、线程、协程的区别?(3分)
# 进程是计算机中资源分配的最小单位# 线程是计算机中能被cpu调度的最小单位# 协程又称为微线程,是基于代码人为创造的,而进程和线程是计算机中真实存在的# 一个进程中可以有多个线程,一个线程中可以有多个协程# 计算密集型用多进程# IO密集型用多线程/协程+IO操作# 单纯的协程是没办法提高并发的,只是代码之间的来回切换,加上IO自动切换才有意义,应用场景,有IO操作用协程
-
什么是GIL锁?(2分)
#全局解释器锁,为了同一时刻保证一个进程中只有一个线程可以被cpu调度
-
进程之间如何进行通信?(2分)
# 默认进程之间无法进行资源共享,如果主要想要通讯可以基于:文件/网络/Queue.
-
Python如何使用线程池、进程池?(2分)
# 进程池:调用ProcessPoolExecutor模块创建进程池,通过submit执行进程# 线程池:调用ThreadPoolExecutor模块创建进程池,通过submit执行进程
-
请通过yield关键字实现一个协程? (2分)
#
-
什么是异步非阻塞? (2分)
#异步: 一个程序在执行中调用了另一个 但是不等待这个任务完毕 就继续执行#非阻塞:cpu工作
-
什么是死锁?如何避免?(2分)
# 由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行# 避免lock锁两次(嵌套锁),避免RLock 多个锁交叉使用
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threadingimport timedef _wait(): time.sleep(60)# flag at = threading.Thread(target=_wait)t.setDeamon(False)t.start()# flag b# 60s
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threadingimport timedef _wait(): time.sleep(60)# flag at = threading.Thread(target=_wait)t.setDeamon(True)t.start()# flag b# 0s
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threadingimport timedef _wait(): time.sleep(60)# flag at = threading.Thread(target=_wait)t.start()t.join()# flag b# 60s
-
读程序,请确认执行到最后number是否一定为0(2分)
import threadingloop = int(1E7)def _add(loop:int = 1): global number for _ in range(loop): number += 1def _sub(loop:int = 1): global number for _ in range(loop): number -= 1number = 0ta = threading.Thread(target=_add,args=(loop,))ts = threading.Thread(target=_sub,args=(loop,))ta.start()ta.join()ts.start()ts.join()# 0
-
读程序,请确认执行到最后number是否一定为0(2分)
import threadingloop = int(1E7)def _add(loop:int = 1): global number for _ in range(loop): number += 1def _sub(loop:int = 1): global number for _ in range(loop): number -= 1number = 0ta = threading.Thread(target=_add,args=(loop,))ts = threading.Thread(target=_sub,args=(loop,))ta.start()ts.start()ta.join()ts.join()# 不一定为0
-
MySQL常见数据库引擎及区别?(3分)
# MySQL常见的三种存储引擎为InnoDB、MyISAM和MEMORY# 区别:# 1、事务安全:InnoDB支持事务安全,MyISAM和MEMORY两个不支持。# 2、存储限制:InnoDB有64TB的存储限制,MyISAM和MEMORY要是具体情况而定。# 3、空间使用:InnoDB对空间使用程度较高,MyISAM和MEMORY对空间使用程度较低。# 4、内存使用:InnoDB和MEMORY对内存使用程度较高,MyISAM对内存使用程度较低。# 5、插入数据的速度:InnoDB插入数据的速度较低,MyISAM和MEMORY插入数据的速度较高。# 6、对外键的支持:InnoDB对外键支持情况较好,MyISAM和MEMORY两个不支持外键。
-
简述事务及其特性? (3分)
# 事务是访问并可能更新数据库中各种数据项的一个程序执行单元# 特性:原子性、一致性、隔离性、持续性# 原子性:一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。# 一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。# 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。# 持久性:持续性也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
-
事务的隔离级别?(2分)
# 读未提交、不可重复读、可重复读、串行化
-
char和varchar的区别?(2分)
# char 定长(固定长度,不够补空字符串),节省时间,浪费空间 varchar 变长(长度不固定),节省空间,浪费时间
-
mysql中varchar与char的区别以及varchar(50)中的50代表的含义。(2分)
# # char 定长(固定长度,不够补空字符串),节省时间,浪费空间 varchar 变长(长度不固定),节省空间,浪费时间# 50指长度为50
-
MySQL中delete和truncate的区别?(2分)
# delete可以条件删除数据,而truncate只能删除表的所有数据# delete效率低于truncate,delete是一行一行地删除,truncate会重建表结构# truncate是DDL语句,需要drop权限,因此会隐式提交,不能够rollback;delete是DML语句,可以使用rollback回滚。# 触发器:truncate 不能触发任何Delete触发器;而delete可以触发delete触发器
-
where子句中有a,b,c三个查询条件, 创建一个组合索引abc(a,b,c),以下哪种会命中索引(3分)
(a)(b)(c)(a,b)(b,c)(a,c)(a,b,c)# (a),(a,b),(a,c),(a,b,c)
-
组合索引遵循什么原则才能命中索引?(2分)
#最左前缀原则
-
列举MySQL常见的函数? (3分)
# concat:拼接,count 计数 max 最大值 min 最小值 avg 平均值 sum 求和
-
MySQL数据库 导入、导出命令有哪些? (2分)
# 导出表结构+数据:mysqldump -u用户名 -p 数据库名 > 数据库名.sql# 导出表结构:mysqldump -u用户名 -p -d 数据库名 > 数据库名.sql# 导出全部数据库:mysqldump -uroot -p --all-databases > alldb.sql# 导入数据库:mysql -u用户名 -p 数据库名 < 数据库名.sql
-
什么是SQL注入?(2分)
# SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息
-
简述left join和inner join的区别?(2分)
# left join:拼接两张表,数据多的在左边# inner join:对两张表的相同部分进行拼接
-
SQL语句中having的作用?(2分)
# 过滤
-
MySQL数据库中varchar和text最多能存储多少个字符?(2分)
# varchar:21839# text:65535
-
MySQL的索引方式有几种?(3分)
# fulltext:全文索引# hash# btree# rtree
-
什么时候索引会失效?(有索引但无法命中索引)(3分)
# 1、如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)# 2、对于多列索引,不是使用的第一部分(第一个),则不会使用索引# 3、like查询是以%开头# 4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引# 5、如果mysql估计使用全表扫描要比使用索引快,则不使用索引
-
数据库优化方案?(3分)
# SQL语句中IN包含的值不应过多# SELECT语句务必指明字段名称# 当只需要一条数据的时候,使用limit 1# 如果排序字段没有用到索引,就尽量少排序# 如果限制条件中其他字段没有索引,尽量少用or# 分段查询# 避免在where子句中对字段进行null值判断# 避免在where子句中对字段进行表达式操作# 对于联合索引来说,要遵守最左前缀法则
-
什么是MySQL慢日志?(2分)
# mysql的慢查询日志是msyql提供的一种日志记录,它用来记录在msyql中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的sql,则会被记录到慢查询日志中。
-
设计表,关系如下: 教师, 班级, 学生, 科室。(4分) 科室与教师为一对多关系, 教师与班级为多对多关系, 班级与学生为一对多关系, 科室中需体现层级关系。
1. 写出各张表的逻辑字段'create table department(id int primary key,dname char(12),pid int);''create table teacher(id int primary key,tname char(16),did int,foreign key(did) references department(id));''create table class(id int primary key,cname char(12));''create table teach_cls(id int,cid int,tid int,foreign key(cid) references class(id),foreign key(tid) references teacher(id));''create table student(id int primary key,sname char(16),cid int,foreign key(cid) references class(id));'insert into department VALUES(1,'校长室',0),(2,'教学处',1),(3,'办公室1',2),(4,'办公室2',2);insert into teacher VALUES(1,'王老师',1),(2,'张老师',2),(3,'孙老师',3),(4,'李老师',3),(5,'伊老师',4);insert into class VALUES(1,'1班'),(2,'2班'),(3,'3班');insert into teach_cls VALUES(1, 3, 1), (2, 3, 2), (3, 3, 3), (4, 2, 1), (5, 2, 2), (6, 1, 3);insert into student VALUES(1,'赵雷',1),(2,'钱电',1),(3,'孙风',1),(4,'李云',2),(5,'周梅',2),(6,'吴兰',3),(7,'郑竹',3);2. 根据上述关系表 a.查询教师id=1的学生数# select count(cid) from student where cid in (select cid from teach_cls where tid=1); b.查询科室id=3的下级部门数# select count(*) from department where pid = 2; c.查询所带学生最多的教师的id#
来源:https://www.cnblogs.com/sunyongchao/p/12371411.html