当前位置: 移动技术网 > IT编程>脚本编程>Python > 海康威视面试python后端题

海康威视面试python后端题

2019年03月17日  | 移动技术网IT编程  | 我要评论

十九岁的纯情国语,南京机场大巴停靠点,hkship.exe已停止工作

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

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

   

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

  

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

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

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

 

  四次挥手: tcp连接的断开需要发送四次包,所以称之为四次挥手, 且client端和服务器端均可主动发出断开请求,在socket中,任何一方执行close()操作皆可产收挥手操作。

  

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

  ·第二次挥手: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的长连接和短连接本质上是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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网