Python面试重点(进阶篇)

Posted lingege

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面试重点(进阶篇)相关的知识,希望对你有一定的参考价值。

Python面试重点(进阶篇)

注意:只有必答题部分计算分值,补充题不计算分值。

第一部分 必答题

  1. 简述 OSI 7层模型及其作用?(2分)

    应用层   表现层    会话层     传输层     网络层   数据链路层     物理层
    实际开发中是 应用层       传输层     网络层   数据链路层     物理层 
    --------------------------------作用---------------------------------------
    应用层  在两个应用能够通信的基础上又封装了一些应用独有的关系内容 http协议 https协议 ftp协议 
    
    ?     传输层  选择具体的传输协议,tcp/udp 以及封装应用的端口
    
    ?     网络层 封装了ip协议 ipv4 ipv6
    
    ?     数据链路层  封装了mac地址 并且 arp/rarp协议
    
    ?     物理层 将上述内容进行转换在网线上进行数据的传输
  2. 简述 TCP三次握手、四次回收的流程。(3分)

    --------------------------三次握手-------------------------------------
    TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
    TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
    TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
    TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
    当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。 
    -------------------------------------四次挥手----------------------------------
     数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。服务端也可以主动关闭,一个流程。
    
    客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
    服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
    服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
    客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2??MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
    服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
    
    
  3. TCP和UDP的区别?(3分)

    tcp 面向连接 传输可靠  速度慢
    
    udp 面向报文 可靠性差 速度快
  4. 什么是黏包?(2分)

    tcp协议数据无边界的特点 导致了多条分散发送的数据粘合在一起变成了一条数据 
    第一次消息太大,另一端一次只能接收部分内容
  5. 什么 B/S 和 C/S 架构?(2分)

    B/S  web项目
    
    C/S   桌面项目
  6. 请实现一个简单的socket编程(客户端和服务端可以进行收发消息)(3分)

    server
    
    import socket
    udp_sk = socket.socket(type=socket.SOCK_DGRAM)   #创建一个服务器的套接字
    udp_sk.bind(('127.0.0.1',9000))        #绑定服务器套接字
    msg,addr = udp_sk.recvfrom(1024)
    print(msg)
    udp_sk.sendto(b'hi',addr)                 # 对话(接收与发送)
    udp_sk.close()                         # 关闭服务器套接字
    client
    
    import socket
    ip_port=('127.0.0.1',9000)
    udp_sk=socket.socket(type=socket.SOCK_DGRAM)
    udp_sk.sendto(b'hello',ip_port)
    back_msg,addr=udp_sk.recvfrom(1024)
    print(back_msg.decode('utf-8'),addr)
    
    
  7. 简述进程、线程、协程的区别?(3分)

    1. 进程,协程,线程的区别:三个都可以提高并发
    
        进程是计算机中资源分配的最小单位,线程是计算机中cpu可调度的最小单位:
    
        协程 又称为 '微线程' 是基于认为创造的,而进程和线程是真是存在的,一个进程可以有多个线程,一个线程可以创建多个协程
    
    2. 计算密集型------使用多进程
    
    3. IO密集型-------使用多线程/协程+IO切换
    
    4. 单纯的协程是没有办法提高并发的,只是代码之间的来回切换,加上 IO 自动切换才有意思,有IO操作使用协程
  8. 什么是GIL锁?(2分)

    GIL,全局解释器锁
    同一时刻保证一个进程中只有一个线程可以被cpu调度,所以在使用Python开发时要注意:
     计算密集型,用多进程.
     IO密集型,用多线程. 
    
  9. 进程之间如何进行通信?(2分)

    IPC:基于第三方工具(redis) 基于管道 队列 
  10. Python如何使用线程池、进程池?(2分)

    concurrent.futures.ThreadPoolExecutor
    
    concurrent.futures.ProcessPoolExecutor
    
  11. 请通过yield关键字实现一个协程? (2分)

     def consumer():
         while True:
             n = yield
             print('处理数据%s' % n)
    
     def producer():
         cg = consumer()
         next(cg)
         for i in range(100):
             print('生产了一个%s'%i)
             # yield i  # 每生产一个数据就停止
             cg.send(i)
    
     producer()
  12. 什么是异步非阻塞? (2分)

     同步join input     异步 : terminate    
    
     阻塞不占用cpu   非阻塞 :占用cpu
    
     同步阻塞 : name  = input() ;pwd  = input()
    
     同步非阻塞 : say();say2()
    
     异步阻塞 : 比如启动多线程和多个客户端进行tcp通信
    
     ?                 可以同时和多个人通信,但是每个人的通信中recv仍然会发生阻塞
    
     异步非阻塞 : 可以启动多线程 设置setblocking(False)
    
     ?                可以同时和多个人通信,并且在过程中没有阻塞   
  13. 什么是死锁?如何避免?(2分)

     用一把锁 : 一把递归锁 /一把互斥锁
  14. 程序从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
  15. 程序从flag a执行到falg b的时间大致是多少秒?(2分)---0-----

    import threading
    import time
    def _wait():
        time.sleep(60)
    # flag a
    t = threading.Thread(target=_wait)
    t.setDeamon(True)
    t.start()
    # flag b
  16. 程序从flag a执行到falg b的时间大致是多少秒?(2分)-----0-----

    import threading
    import time
    def _wait():
        time.sleep(60)
    # flag a
    t = threading.Thread(target=_wait)
    t.start()
    t.join()
    # flag b
  17. 读程序,请确认执行到最后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()
  18. 读程序,请确认执行到最后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()
  19. MySQL常见数据库引擎及区别?(3分)

     innodb   5.6之后的默认 : 支持行级锁 事务 外键 
    
     ?  开启事务 查询这个用户还是不是一个公户+锁,如果是改成私户 提交事务
    
     ?  select xxx from 表 where id = 1 for update
    
     myisam  5.5之前的默认 只支持表锁
    
     memory  内存 
    
     blackhole 黑洞 
    
     ?  create table 表名() charset=utf8 engine=blackhole;
  20. 简述事务及其特性? (3分)

    一致性   原子性    隔离性     持久性
  21. 事务的隔离级别?(2分)

  22. char和varchar的区别?(2分)

    定长255    高效     浪费空间
    
    变长65535   低效    节省空间
  23. mysql中varchar与char的区别以及varchar(50)中的50代表的含义。(2分)

    最长50个字符
  24. MySQL中delete和truncate的区别?(2分)

     delete :可以删除部分数据 auto_incement清除不掉
    
     truncate :清空表 并且重置auto_increment为1
  25. where子句中有a,b,c三个查询条件, 创建一个组合索引abc(a,b,c),以下哪种会命中索引(3分)

    1  有1的都会       (a)
    (b)
    (c)
    1                (a,b)
    (b,c)
    1                (a,c)
    1               (a,b,c)
  26. 组合索引遵循什么原则才能命中索引?(2分)

     最左前缀原则 不能用范围 最好用and 
  27. 列举MySQL常见的函数? (3分)

     count sum avg max min now year month day hour minute second week sub_date
    
     concat group_count concat_ws user password database
  28. MySQL数据库 导入、导出命令有哪些? (2分)

     mysqldump 备份
  29. 什么是SQL注入?(2分)

    通过一些输入的内容绕过sql的判断机制 
    
     pymysql
    
     execute('se..',[参数,])
  30. 简述left join和inner join的区别?(2分)

    left join以左表为准
    
    inner join 选两张表都有的,一一相等的
  31. SQL语句中having的作用?(2分)

     以聚合函数作为条件过滤分组
  32. MySQL数据库中varchar和text最多能存储多少个字符?(2分)

    65535
  33. MySQL的索引方式有几种?(3分)

     主键索引 唯一索引 普通索引 联合主键 联合唯一 联合普通
  34. 什么时候索引会失效?(有索引但无法命中索引)(3分)

  35. 数据库优化方案?(3分)

     读写分离 
    
      分库分表 
    
      用定长字段代替变长字段
    
      添加索引,尽量加在区分度高的,数量小的列上
  36. 什么是MySQL慢日志?(2分)

  37. 设计表,关系如下: 教师, 班级, 学生, 科室。(4分)
    科室与教师为一对多关系, 教师与班级为多对多关系, 班级与学生为一对多关系, 科室中需体现层级关系。

    1.  写出各张表的逻辑字段
    2.  根据上述关系表
        a.查询教师id=1的学生数
        b.查询科室id=3的下级部门数
        c.查询所带学生最多的教师的id

38.有staff表,字段为主键Sid,姓名Sname,性别Sex(值为"男"或"女"),课程表Course,字段为主键Cid,课程名称Cname,关系表SC_Relation,字段为Student表主键Sid和Course表主键Cid,组成联合主键,请用SQL查询语句写出查询所有选"计算机"课程的男士的姓名。(3分)

39 .根据表关系写SQL语句(10分)

技术图片

  • 查询所有同学的学号、姓名、选课数、总成绩;

    select sc.sid,s.sname,count(sc.cid) cidNum,sum(sc.score) scoreSum from sc join student s on sc.sid=s.stid group by sc.sid;
    
  • 查询姓“李”的老师的个数;

    、select count(*) number from teacher where tname like ‘李%’;
    
  • 查询平均成绩大于60分的同学的学号和平均成绩;

    select sid,avg(score) avgScore from sc group by sid having avg(score)>60;
    
  • 查询有课程成绩小于60分的同学的学号、姓名

  • 删除学习“叶平”老师课的score表记录;

  • 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;

  • 查询每门课程被选修的学生数;

  • 查询出只选修了一门课程的全部学生的学号和姓名;

  • 查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;

  • 查询两门以上不及格课程的同学的学号及其平均成绩;

第二部分 补充题

  1. 什么是IO多路复用?

    网络数据传输监控机制 - 多个网络连接复用一个监听机制 -- select--1024
    
    select模块selectors模块
    
    操作系统提供的io多路复用的机制 select poll epoll
    
    epoll最好 用的是回调函数的机制
    
    select poll 的内部机制 是 轮询
    
  2. async/await关键字的作用?

    async用来定义一个协程函数的
    
    await用来控制一个可能发生io阻塞的任务的切入和切出
    
  3. MySQL的执行计划的作用?

    不执行sql,在之前先查看以下sql的顺序 索引的使用情况 从而去推测 优化sql语句
    
    explain select * from baobao1;
    
  4. 简述MySQL触发器、函数、视图、存储过程?

    1. 触发器 trigger:在用户对某张表做完某个固定的操作(insert update delete) 会自动在数据库中触发另一个动作
    
        insert 一条数据    苹果手机
    
        往对应的统计表中 把苹果这条数据 +1
    
    函数(function):根据参数进行判断 循环 得出一个结果 并返回,通过select 函数名(参数)来调用并查看结果
    
    视图(view) : 帮助我简化查询部分的连表操作 
    
    存储过程(procedure): 可以实现非常负责的sql逻辑 并对数据进行增删改查 且可以返回多个结果 call 名字(参数)调用
    
  5. 数据库中有表:t_tade_date

    id       tade_date
    1        2018-1-2
    2        2018-1-26
    3        2018-2-8
    4        2018-5-6
    ...
    输出每个月最后一天的ID
    
select last_day(tade_date) from t_tade_date group by month(tade_date) ;

select id from t_tade_date where tade_date in (select last_day(tade_date) from t_tade_date group by month(tade_date));



select id,max(tade_date) from t_tade_date group by month(2018-1-2) ;  

以上是关于Python面试重点(进阶篇)的主要内容,如果未能解决你的问题,请参考以下文章

Python面试重点(基础篇)

Python面试重点(基础篇)

Python面试重点(web篇)

Python面试重点(web篇)

Python面试重点(基础篇)

Python面试重点(web篇)