海康威视面试python后端题

1. 请简述三次握手和四次挥手:html

 答:首先TCP是传输控制协议,提供可靠的链接服务,采用三次握手确认创建一个链接,在创建TCP链接时,须要客户端和服务器总共发送3个包。python

   

   三次握手的目的是链接服务器的指定端口、创建TCP链接、同步双方的序列号和确认号、交换TCP窗口大小信息,在socket编程中,客户端在执行connect()时将触发三次握手。linux

  

  第一次握手:创建链接时,客户端发送syn包到服务器,并进入SYN_SENT状态,等待服务器确认。  SYN:同步序列编号web

  第二次握手:服务器收到客户端的syn包,必须向客户端发送确认信号(ack ),而且向客户端页发送一个syn包,此时服务器进入SYN_RECV状态redis

  第三次握手:客户端收到服务器syn+ack,向服务器发送确认包ack,此包发送完毕,客户端和服务器端进入ESTABLISHED(tcp链接成功), 完成三次握手。数据库

 

  四次挥手: TCP链接的断开须要发送四次包,因此称之为四次挥手, 且Client端和服务器端都可主动发出断开请求,在socket中,任何一方执行close()操做皆可产收挥手操做。编程

  

  ·第一次挥手:Cilent端中止发送报文,并发出断开请求FIN,并将序列号置为X,此时客户端进入(终止等待1)状态。windows

  ·第二次挥手:Server端接收到FIN包后当即向Client端发送确认包ACK = X+1,并置序列号为Y,此时服务器进入关闭等待状态。浏览器

  ·第三次挥手:Server端在发送确认信号后也向Client端发送了关闭信号FIN和确认信号ACK,并将序列号置为Y,此时服务器进入(最后确认)状态。缓存

  ·第四次挥手:Client端接收到服务器发来的断开请求报文后,必须发出确认信号ACK = Y, 并置序列号为Z+1, 并进入(时间等待)状态,且此时链接尚未断,客户端须要等待2MSL时间才会断开

2. 为何握手三次且挥手四次?

  答:由于当Server端收到Client端的SYN链接请求报文后,能够直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。可是关闭链接时,当Server端收到FIN报文时,极可能并不会当即关闭SOCKET,

  因此只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端全部的报文都发送完了,我才能发送FIN报文,所以不能一块儿发送。故须要四步握手。

 

3.  为何第四次握手后要等待2MSL(最大报文生存时间)时间才会返回close状态?

  答:假象网络不可靠,当客户端发送ack后ack却丢失了,那么服务器端收不到确认信号,就会一直发送FIN请求,因此这时客户端不能当即关闭,必须等待2MSL时间才行(由于客户端发送ack须要MSL, 服务端发送FIN也须要MSL时间),

  若是在2MSL时间内没收到服务器端发来的FIN,就表明服务器端已经接收到了客户端的ack,词汇客户端才会关闭。

4。get和post请求的区别?

  答:首先定性:get和post并无什么本质的区别。

    w3schools的说法:

      GET在浏览器回退时是无害的,而POST会再次提交请求

      GET产生的URL地址能够被Bookmark,而POST不能够。

      GET请求会被浏览器主动cache,而POST不会,除非手动设置。

      GET请求只能进行url编码,而POST支持多种编码方式。

      GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

      GET请求在URL中传送的参数是有长度限制的,而POST么有。

      对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

      GET比POST更不安全,由于参数直接暴露在URL上,因此不能用来传递敏感信息。

      GET参数经过URL传递,POST放在Request body中。

  然而这不是本质,本质是:

    get和post是什么? 他们俩是http协议中的两种请求方式。

    http是什么呢?http是基于tip/ip的关于数据如何在万维网中通讯的协议

    http的底层是TCP/IP,那就是说get和post底层也是TCP/IP,也就是说,get和pos请求本质都是TCP链接,get请求和post请求能作的事儿是同样的。你要给get请求加上request body,给post请求带上url参数,技术上彻底行得通。

    可是不一样的浏览器和服务器对此作出了一些限制,如url长度不超过2k个字节等等。

  不过get和post请求仍是有一个重大区别的:GET产生一个TCP数据包;POST产生两个TCP数据包。

    get请求会将header和data一并发过去,服务器相应200

    可是post请求:浏览器先发送header, 服务器响应100 continue, 浏览器再发送data,服务器响应200.

    也就是说,GET只须要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,大家打开门迎接我”,而后再回头把货送过去。

5. 简述python 主流web框架特性。

  答:

    Django:Python 界最全能的 web 开发框架,battery-include 各类功能完备,可维护性和开发速度一级棒。常有人说 Django 慢,其实主要慢在 Django ORM 与数据库的交互上,因此是否选用 Django,

  取决于项目对数据库交互的要求以及各类优化。而对于 Django 的同步特性致使吞吐量小的问题,其实能够经过 Celery 等解决,倒不是一个根本问题。Django 的项目表明:Instagram,Guardian。

    Tornado:天生异步,性能强悍是 Tornado 的名片,然而 Tornado 相比 Django 是较为原始的框架,诸多内容须要本身去处理。固然,随着项目愈来愈大,框架可以提供的功能占比愈来愈小,更多的内容须要团队本身实现,

  而大项目每每须要性能的保证,这时候 Tornado 就是比较好的选择。Tornado项目表明:知乎。

    Flask:微框架的典范,号称 Python 代码写得最好的项目之一。Flask 的灵活性,也是双刃剑:能用好 Flask 的,能够作成 Pinterest,用很差就是灾难(显然对任何框架都是这样)。

  Flask 虽然是微框架,可是也能够作成规模化的 Flask。加上 Flask 能够自由选择本身的数据库交互组件(一般是 Flask-SQLAlchemy),并且加上 celery +redis 等异步特性之后,Flask 的性能相对 Tornado 也不逞多让,也许Flask 的灵活性多是某些团队更须要的。

6. 解释GIL

  答:(Global Interpreter Lock)全局解释器锁,是计算机程序设计语言解释器用于同步线程的一种机制,它使得任什么时候刻仅会有一个线程在执行,即便在多核处理器上,使用GIL的解释器也只容许同一时间执行一个程序,常见的使用GIL的解释器有CPython和Ruby MRI.

  CPython解释器的线程使用的是操做系统的原生线程,在linux下是pthread, 在windows下是Win thread,彻底由操做系统调度线程的执行。

  在讨论普通的GIL以前,有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(好比计算型的)。 若是你的程序大部分只会涉及到I/O,好比网络交互,那么使用多线程就很合适, 由于它们大部分时间都在等待。

  实际上,你彻底能够放心的建立几千个Python线程, 现代操做系统运行这么多线程没有任何压力,没啥可担忧的。

  Python的多线程在多核CPU上,只对于IO密集型计算产生正面效果;而当有至少有一个CPU密集型线程存在,那么多线程效率会因为GIL而大幅降低。

 7. 死锁的产生、避免、解决

  答:死锁的产生缘由:

      (1)由于系统资源不足。

      (2)进程运行推动的顺序不合适。

      (3)资源分配不当

    若是系统自资源充足,进程的请求均可以获得知足,死锁出现的可能就会很是低,不然就会因竞争有限的资源而陷入死锁,其次,进程运行推动顺序和速度不一样,也会产生死锁。

    产生死锁的四个必要条件:

      (1)互斥条件:一个资源每次只能被一个进程调用。

      (2)请求与保持条件:一个进程因请求资源而阻塞时,对已获取的资源保持不放。

      (3)不剥夺条件:进程已获取的资源,在未使用完以前,不能强制剥夺。

      (4)循环等待条件:若干进程之间造成一种头尾相接的循环等待资源关系。

    这四个是产生死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不知足,思索就不会发生。

8。redis崩溃了怎么办?

  答:首先是避免崩溃,保证redis高可用性,主从+哨兵 来避免redis全盘崩溃。

    其次是redis持久化,一旦redis重启,自动从磁盘上加载数据,快速回复缓存数据。

  ps: 缓存雪崩:存雪崩是指在咱们设置缓存时采用了相同的过时时间,致使缓存在某一时刻同时失效,或者某一时间缓存大范围挂掉,致使请求所有转发到DB,DB瞬时压力太重宕掉。

    缓存穿透:缓存穿透是指查询一个必定不存在的数据,因为缓存是不命中时被动写的,而且出于容错考虑,若是从存储层查不到数据则不写入缓存,这将致使这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

  在流量大时,可能DB就挂掉了

9. TCP和UDP:

  答: 1.基于链接与无链接
      2.TCP要求系统资源较多,UDP较少; 
      3.UDP程序结构较简单 
      4.流模式(TCP)与数据报模式(UDP); 
      5.TCP保证数据正确性,UDP可能丢包 
      6.TCP保证数据顺序,UDP不保证 

    

10. http的长链接和短链接:

  推荐这篇文章:http://www.javashuo.com/article/p-fiwikntb-bu.html

  答:HTTP的长链接和短链接本质上是TCP长链接和短链接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,

  使在网络上的另外一端收到发端发出的全部包,而且顺序与发出顺序一致。TCP有可靠,面向链接的特色。

  在HTTP/1.0中,默认使用的是短链接。也就是说,浏览器和服务器每进行一次HTTP操做,就创建一次链接,但任务结束就中断链接。若是客户端浏览器访问的某个HTML或其余类型的 Web页中包含有其余的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会创建一个HTTP会话。

但从 HTTP/1.1起,默认使用长链接,用以保持链接特性。使用长链接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive

  在使用长链接的状况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP链接不会关闭,若是客户端再次访问这个服务器上的网页,会继续使用这一条已经创建的链接。Keep-Alive不会永久保持链接,它有一个保持时间,能够在不一样的服务器软件(如Apache)中设定这个时间。实现长链接要客户端和服务端都支持长链接。

HTTP协议的长链接和短链接,实质上是TCP协议的长链接和短链接。

 

想了解更多Python关于爬虫、数据分析的内容,获取大量爬虫爬取到的源数据,欢迎你们关注个人微信公众号:悟道Python