Python面试重点(进阶篇)
注意:只有必答题部分计算分值,补充题不计算分值。
第一部分 必答题
-
简述 OSI 7层模型及其作用?(2分)
- 应用层
- 表示层 这一层的主要功能是定义数据格式及加密
- 会话层 他定义了如何开始、控制和结束一个会话,包括对多个双向小时的控制和管理
- 传输层 定义一些传输数据的协议和端口。传输协议同时进行流量控制,或是根据接收方接收数据的快慢程度,规定适当的发送速率,解决传输效率及能力的问题
- 网络层 控制子网的运行,如逻辑编址,分组传输,路由选择最小单位——分组(包)报文
- 数据链路层 主要是对物理层传输的比特流包装,检测保证数据传输的可靠性,将物理层接收的数据进行MAC(媒体访问控制)地址的封装和解封装,也可以简单的理解为物理寻址。交换机就处在这一层
- 物理层 定义物理设备的标准,主要对物理连接方式,电气特性,机械特性等制定统一标准,传输比特流,
-
简述 TCP三次握手、四次挥手的流程。(3分)
- 服务端向客户端发送SYN=1 ,seq=j
- 服务端收到SYN=1 知道客户端等待连接,将SYN和ACK置为1,ack = j+1 随机产生seq=K ,并将这些数据打包发送给Client
- 客户端收到确认数据,检查ack=j+1 ACK=1 正确将ACK置为1
ack = K+1 并发送数据给服务端 服务端检查数据没问题连接建立成功
-
TCP和UDP的区别?(3分)
- TCP是面向连接的,可靠性高;UDP是基于非连接的,可靠性低
- 由于TCP是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差,同时过程复杂,也使其易于攻击;UDP没有建立连接的过程,因而实时性较强,也稍安全
- 在传输相同大小的数据时,TCP首部开销20字节;UDP首部开销8字节,TCP报头比UDP复杂,故实际包含的用户数据较少。TCP在IP协议的基础上添加了序号机制、确认机制、超时重传机制等,保证了传输的可靠性,不会出现丢包或乱序,而UDP有丢包,故TCP开销大,UDP开销较小
- 每条TCP连接只能时点到点的;UDP支持一对一、一对多、多对一、多对多的交互通信
-
什么是黏包?(2分)
- UDP没有粘包,TCP有,因为TCP是面向流的消息格式。
1.由于你设置的接收大小小于你收到的消息的大小,那么剩余的消息的部分会和下一次接收一次被接收到
2.快速连续发送两个很小的消息,两个小消息会被合到一起被一次接收拿到。本质上就是因为接收端不知道发送端发送消息的大小导致的。
- UDP没有粘包,TCP有,因为TCP是面向流的消息格式。
-
什么 B/S 和 C/S 架构?(2分)
- B/S 架构 浏览器与服务端架构,实际上是C/S架构中的一种,更节省资源 不用更新 不依赖环境
- C/S 架构 客户端与服务端架构,安全性更好,但程序比较庞大
-
请实现一个简单的socket编程(客户端和服务端可以进行收发消息)(3分)
-
简述进程、线程、协程的区别?(3分)
-
进程是计算器最小资源分配单位 .
-
线程是CPU调度的最小单位 .
-
进程切换需要的资源很最大,效率很低 .
-
线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下) .
-
协程切换任务资源很小,效率高(协程本身并不存在,是程序员通过控制IO操作完成) .
-
多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发
-
-
什么是GIL锁?(2分)
全局解释器锁 CPython在执行多线程的时候并不是线程安全的,所以为了程序的稳定性,加一把全局解释锁,能够确保任何时候都只有一个Python线程执行。 -
进程之间如何进行通信?(2分)
- Queue
- Pipe
-
Python如何使用线程池、进程池?(2分)
- 引入进程池与线程池
- 使用ProcessPoolExecutor进程池,使用ThreadPoolExecutor线程池
-
请通过yield关键字实现一个协程? (2分)
def consumer():
r = ''
while True:
n = yield r #执行的中断点
if not n:
return
print('[消费者] 正在消费:{0}'.format(n))
r = '200 人民币'
def produce(c):
c.send(None) #启动消费者(生成器)——实际上是函数调用,只不过生成器不是直接象函数那般调用的
n = 0
while n < 5:
n = n + 1
print('[生产者] 正在生产:{0}'.format(n))
r = c.send(n) #给消费者传入值——实际上也是函数调用
print('[生产者] 消费者返回:{0}'.format(r))
c.close()
c = consumer()#构造一个生成器
produce(c)
-
什么是异步非阻塞? (2分)
- 程序执行时,A调用B,不用等待B返回结果,而是去做其他事情,等B有结果时通知A
-
什么是死锁?如何避免?(2分)
- 线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.setDeamon(False) t.start() # flag b
60s
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.setDeamon(True) t.start() # flag b
0.01s
-
程序从flag a执行到falg b的时间大致是多少秒?(2分)
import threading import time def _wait(): time.sleep(60) # flag a t = threading.Thread(target=_wait) t.start() t.join() # flag b
60s
-
读程序,请确认执行到最后number是否一定为0(2分)
import threading loop = int(1E7) def _add(loop:int = 1): global number for _ in range(loop): number += 1 def _sub(loop:int = 1): global number for _ in range(loop): number -= 1 number = 0 ta = threading.Thread(target=_add,args=(loop,)) ts = threading.Thread(target=_sub,args=(loop,)) ta.start() ta.join() ts.start() ts.join()
不一定
-
读程序,请确认执行到最后number是否一定为0(2分)
import threading loop = int(1E7) def _add(loop:int = 1): global number for _ in range(loop): number += 1 def _sub(loop:int = 1): global number for _ in range(loop): number -= 1 number = 0 ta = threading.Thread(target=_add,args=(loop,)) ts = threading.Thread(target=_sub,args=(loop,)) ta.start() ts.start() ta.join() ts.join()
一定为0
-
MySQL常见数据库引擎及区别?(3分)
-
简述事务及其特性? (3分)
- 事务是用户定义的数据库操作序列,这些操作要么都成功,要么都失败,不可分割,
- 原子性,所有操作要么都做。要么都不做
- 一致性,是数据控从一个一致状态变成另一个一致状态
- 持续性,事务一旦提交,对数据库的改变是永久的
- 隔离性,一个事务内部的操作及使用的数据对并发的其他事务是隔离的
-
事务的隔离级别?(2分)
- 读未提交
- 读提交
- 可重复读取
- 可序列化
-
char和varchar的区别?(2分)
char是定长类型:最多存放255个字符
varchar是可变类型:最大长度为65535个字节,varchar可存放的字符数跟编码有关 -
mysql中varchar与char的区别以及varchar(50)中的50代表的含义。(2分)
char是定长类型:最多存放255个字符
varchar是可变类型:最大长度为65535个字节,varchar可存放的字符数跟编码有关
varchar(50)代表可以存放50个字节 -
MySQL中delete和truncate的区别?(2分)
delete和truncate都是删除表数据,但是trancate是删除整个表的数据 -
where子句中有a,b,c三个查询条件, 创建一个组合索引abc(a,b,c),以下哪种会命中索引(3分)
(a)
(b)
(c)
(a,b)
(b,c)
(a,c) -
组合索引遵循什么原则才能命中索引?(2分)
最左前缀 -
列举MySQL常见的函数? (3分)
AVG(col)返回指定列的平均值
COUNT(col)返回指定列中非NULL值的个数
MIN(col)返回指定列的最小值
MAX(col)返回指定列的最大值
SUM(col)返回指定列的所有值之和
GROUP_CONCAT(col) 返回由属于一组的列值连接组合而成的结果
28. MySQL数据库 导入、导出命令有哪些? (2分)
导出
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
导入
source 命令
29. 什么是SQL注入?(2分)
SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
30. 简述left join和inner join的区别?(2分)
left join 左关联,主表在左边,右边为从表。如果左侧的主表中没有关联字段,会用null 填满
inner join 内关联只会显示主表和从表相关联的字段,不会出现null
31. SQL语句中having的作用?(2分)
对由sum或其它集合函数运算结果的输出进行限制。
32. MySQL数据库中varchar和text最多能存储多少个字符?(2分)
根据编码类型长度不同:
varchar-65535
TEXT-65535
33. MySQL的索引方式有几种?(3分)
1.主键索引
2.唯一索引
3.普通索引
4.全文索引
5.联合索引
-
什么时候索引会失效?(有索引但无法命中索引)(3分)
-
数据库优化方案?(3分)
-
什么是MySQL慢日志?(2分)
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过指定阀值的SQL语句,运行时间超过long_query_time值的SQL,会被记录到慢查询日志中。 -
设计表,关系如下: 教师, 班级, 学生, 科室。(4分)
科室与教师为一对多关系, 教师与班级为多对多关系, 班级与学生为一对多关系, 科室中需体现层级关系。1. 写出各张表的逻辑字段 2. 根据上述关系表 a.查询教师id=1的学生数 b.查询科室id=3的下级部门数 c.查询所带学生最多的教师的id
-
有staff表,字段为主键Sid,姓名Sname,性别Sex(值为"男"或"女"),课程表Course,字段为主键Cid,课程名称Cname,关系表SC_Relation,字段为Student表主键Sid和Course表主键Cid,组成联合主键,请用SQL查询语句写出查询所有选"计算机"课程的男士的姓名。(3分)
-
根据表关系写SQL语句(10分)
- 查询所有同学的学号、姓名、选课数、总成绩;
- 查询姓“李”的老师的个数;
- 查询平均成绩大于60分的同学的学号和平均成绩;
- 查询有课程成绩小于60分的同学的学号、姓名
- 删除学习“叶平”老师课的score表记录;
- 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
- 查询每门课程被选修的学生数;
- 查询出只选修了一门课程的全部学生的学号和姓名;
- 查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;
- 查询两门以上不及格课程的同学的学号及其平均成绩;
第二部分 补充题
-
什么是IO多路复用?
-
async/await关键字的作用?
-
MySQL的执行计划的作用?
-
简述MySQL触发器、函数、视图、存储过程?
-
数据库中有表:t_tade_date
id tade_date 1 2018-1-2 2 2018-1-26 3 2018-2-8 4 2018-5-6 ... 输出每个月最后一天的ID