python面试答案整理 网络编程和并发(34 题)
第二部分 网络编程和并发(34 题)
-
简述 OSI 七层协议。
应 表 会 传 网 数 物
-
什么是 C/S 和 B/S 架构?
C/S 客户端/服务器架构 客户端指运用程序,需要安装运行 B/S 浏览器/服务端架构 通过网页访问网址,通过HTTP请求服务端相关资源
-
简述 三次握手、四次挥手的流程。
三次握手: 客户端 发送 syn请求 给服务端 服务端发送, syn + ack 请求给客户端 客户端发送ack请求 握手成功 四次挥手: 客户端发送syn请求给服务端请求断开连接 服务端发送ack请求同意断开 服务端处理完数据后, 发送SYN请求 给客户端请求断开 客户端发送ACK请求同意断开
-
什么是 arp 协议?
ARP协议是“Address Resolution Protocol”(地址解析协议)的缩写。其作用是在以太网环境中,数据的传输所依懒的是MAC地址而非IP地址,而将已知IP地址转换为MAC地址的工作是由ARP协议来完成的。在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。在以太网中,一个主机和另一个主机进行直接通信,必须要知道目标主机的MAC地址。但这个目标MAC地址是如何获得的呢?它就是通过地址解析协议获得的。所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。
-
TCP 和 UDP 的区别?
TCP(transport control protocol,传输控制协议)面向连接、 面向流的Nagle算法优化:将多次间隔小的小数据合并数据块,封包 接受端难以分辨、需要提供科学的拆包机制。即面向流的通信是无消息保护边界的收发消息不能为空,需要添加空消息处理机制可靠、粘包: tcp协议数据不会丢失, 未接受的下次继续,总是能收到,数据可靠,但是粘包UDP(user datagram protocol,用户数据报协议)面向消息的通信有消息保护边界。采用链式结构来记录每一个到达UDP包,每个UDP包中有消息头,容易区分处理可以发送空消息,封装消息头发送 不可靠、不粘包: udp的recvfrom是阻塞的,一个recvfrom(x) 必须对唯一一个sendinto(y),
-
什么是局域网和广域网?
局域网(Local Area Network),简称LAN,是指在某一区域内由多台计算机互联成的计算机组。 广域网(Wide Area Network),简称WAN,是一种跨越大的、地域性的du计算机网络的集合,通常跨越省、市,甚至一zhi个国家。广域网包括大大小小不同的子网,子网可以是局域网,也可以是小型的广域网。
-
为何基于 tcp 协议的通信比基于 udp 协议的通信更可靠?
tcp协议一定是先建好双向链接,发一个数据包要得到确认才算发送完成,没有收到就一直给你重发; udp协议没有链接存在,udp直接丢数据,不管你有没有收到。 TCP的可靠保证,是它的三次握手双向机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,udp信息发出后,不验证是否到达对方,所以不可靠。不过UDP的速度是TCP比不了的,而且UDP的反应速度更快
-
什么是 socket?简述基于 tcp 协议的套接字通信流程。
socket 套接字 用于描述IP地址和端口,是一个通信链的句柄, 可以用来实现不同虚拟机或不同计算机之间的通信。 在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。 基于tcp 协议的套接字通信流程: 1). 服务器先用 socket 函数来建立一个套接字,用这个套接字完成通信的监听。 2). 用 bind 函数来绑定一个端口号和 IP 地址。因为本地计算机可能有多个网址和 IP,每一个 IP 和端口有多个端口。需要指定一个 IP 和端口进行监听。 3). 服务器调用 listen 函数,使服务器的这个端口和 IP 处于监听状态,等待客户机的连接。 4). 客户机用 socket 函数建立一个套接字,设定远程 IP 和端口。 5). 客户机调用 connect 函数连接远程计算机指定的端口。 6). 服务器用 accept 函数来接受远程计算机的连接,建立起与客户机之间的通信。 7). 建立连接以后,客户机用 write 函数向 socket 中写入数据。也可以用 read 函数读取服务器发送来的数据。 8). 服务器用 read 函数读取客户机发送来的数据,也可以用 write 函数来发送数据。 9). 完成通信以后,用 close 函数关闭 socket 连接。
-
什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
粘包:同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包。原因和现象黏包现象只发生在tcp协议中:从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
-
IO 多路复用的作用?
多路复用IO (IO multiplexing)也称这种IO方式为事件驱动IO(event driven IO)。我们都知道,select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
-
什么是防火墙以及作用?
,防火墙是一个位于被认为是安全和可信的内部网络与一个被认为是不那么安全和可信的外部网络(通常是Internet)之间的一个封锁工具。 1.过滤不安全服务 基于这个准则,防火墙应封锁所有信息流,然后对希望提供的安全服务逐项开放,对不安全的服务或可能有安全隐患的服务一律扼杀在萌芽之中。 这是一种非常有效实用的方法,可以造成一种十分安全的环境,因为只有经过仔细挑选的服务才能允许用户使用。 2.过滤非法用户和访问特殊站点 基于这个准则,防火墙应先允许所有的用户和站点对内部网络的访问,然后网络管理员按照IP地址对未授权的用户或不信任的站点进行逐项屏蔽。 这种方法构成了一种更为灵活的应用环境,网络管理员可以针对不同的服务面向不同的用户开放,也就是能自由地设置各个用户的不同访问权限。 好文要顶 关注我 收藏该文 作用: 1.过滤进出网络的数据 2.管理进出访问网络的行为 3.封堵某些禁止业务 4.记录通过防火墙信息内容和活动 5.对网络攻击检测和告警
-
select、poll、epoll 模型的区别?
1) select 是三者当中最底层的,它的事件的轮训机制是基于比特位的。每次查询都要遍历整个事件列表。 2) poll 可以认为 poll 是一个增强版本的select,因为 select 的比特位操作决定了一次性最多处理的读或者写事件只有 1024 个,而 poll 使用一个新的方式优化了这个模型。 3)epoll 是一个更加高级的操作,上述的 select 或者 poll 操作都需要轮询所有的候选队列逐一判断是否有事件,而且事件队列是直接暴露给调用者的,比如上面 select 的 write_fd 和 poll 的fds,这样复杂度高,而且容易误操作。epoll 给出了一个新的模式,直接申请一个 epollfd 的文件,对这些进行统一的管理,初步具有了面向对象的思维模式。
-
简述 进程、线程、协程的区别 以及应用场景?
快速理解进程、线程、协程的概念,它们的区别和共同点,以及应用场景。
1、进程 ——进程是资源分配的最小单位 实质上的理解:——先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。进程的生命周期有调入,执行,保存的过程。 2、线程 ——线程是CPU调度的最小单位 实质上理解:——一个应用程序的执行可能有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块;这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,单核任务中划分更为细小的CPU时间段 3、协程 ——协程是线程的一种表现形式。 实质上理解:——协程又称微线程。在单线程上执行的多个任务,用函数切换,开销极小。 应用场景 1)如果是 I/O 密集型,且 I/O 请求比较耗时的话,使用协程。 函数切换,占用资源少 2)如果是 I/O 密集型,且 I/O 请求比较快的话,使用多线程。 由操作系统切换,占用资源大,越快处理完越好 3)如果是 计算 密集型,考虑可以使用多核 CPU,使用多进程。 进程之间资源不共享,还可以用到多个CPU,如果使用线程的话,还要考虑到数据的安全性,使用互斥锁
-
GIL 锁是什么鬼?
GIL锁: 全局解释器锁 GIL在任意时刻,在主循环中只有一个线程在解释器中运行。
-
Python 中如何使用线程池和进程池?
最早期的Python2中是没有线程池这一概念的,只有进程池。直到Python3的出现才引入了线程池,其实关于他们的使用都是非常简单,而且接口也是高度统一甚至说一模一样的。 而线程池与进程池的作用即是为了让我们能够更加便捷的管理线程或进程。 我们先说一下,如果需要使用线程池或进程池,需要导入模块 concurrent.futures 。 from concurrent.futures import ThreadPoolExecutor # 线程池执行器 from concurrent.futures import ProcessPoolExecutor # 进程池执行器
-
threading.local 的作用?
threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,如果你在开发多线程应用的时候 需要每个线程保存一个单独的数据供当前线程操作,可以考虑使用这个方法,简单有效。 举例:每个子线程使用全局对象a,但每个线程定义的属性a.xx是该线程独有的,Python提供了 threading.local 类,将这个类实例化得到一个全局对象,但是不同的线程使用这个对象存储的数据其它线程不可见(本质上就是不同的线程使用这个对象时为其创建一个独立的字典)。
-
进程之间如何进行通信?
# 进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等
-
什么是并发和并行?
# 并发:同一时刻只能处理一个任务,但一个时段内可以对多个任务进行交替处理(一个处理器同时处理多个任务) # 并行:同一时刻可以处理多个任务(多个处理器或者是多核的处理器同时处理多个不同的任务) # 类比:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。
-
进程锁和线程锁的作用?
线程锁: 大家都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法 / 代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块的。 进程锁: 也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制(操作系统基本知识)。 分布式锁: 当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。
-
解释什么是异步非阻塞?
'非阻塞': 遇到IO阻塞不等待(setblooking=False),(可能会报错->捕捉异常) - sk=socket.socket() - sk.setblooking(False) '异步': 回调(ajax),当达到某个指定状态之后,自动调用特定函数
-
路由器和交换机的区别?
1. 路由器可以给局域网自动分配IP,虚拟拨号。交换机则只是用来分配网络数据的。 2. 路由器可以把一个IP分配给很多个主机使用,这些主机对外只表现出一个IP。 交换机可以把很多主机连起来,这些主机对外各有各的IP。 3. 交换机工作在中继层,根据[MAC](http://product.yesky.com/os/mac)地址寻址,不能处理TCP/IP协议。 路由器工作在网络层,根据IP地址寻址,可以处理TCP/IP协议。 4. 路由器提供[防火墙](http://product.yesky.com/wirelessrouter/fhq/)服务,交换机不能提供该功能。
-
什么是域名解析?
# 在网上,所有的地址都是ip地址,但这些ip地址太难记了,所以就出现了域名(比如http://baidu.com)。 # 而域名解析就是将域名,转换为ip地址的这样一种行为。 # 例如:访问www.baidu.com,实质是把域名解析成IP。
-
如何修改本地 hosts 文件?
'hosts': Hosts就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库” 可以用来屏蔽一些网站,或者指定一些网站(修改hostsFQ) '修改': # windows: 位置:C:\Windows\System32\drivers\etc 也可以通过第三方软件,我用的火绒,可以直接进行编辑hosts # linux: 位置:/etc/hosts 修改:vi /etc/hosts
-
生产者消费者模型应用场景及优势?
# 处理数据比较消耗时间,线程独占,生产数据不需要即时的反馈等。
-
什么是 cdn?
# 用户获取数据时,不需要直接从源站获取,通过CDN对于数据的分发, # 用户可以从一个较优的服务器获取数据,从而达到快速访问,并减少源站负载压力的目的。
-
LVS 是什么及作用?
是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统 LVS主要用于多服务器的负载均衡。它工作在网络层,可以实现高性能,高可用的服务器集群技术。
-
Nginx 是什么及作用?
Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。
-
keepalived 是什么及作用?
Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层交换机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现的故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。
后来Keepalived又加入了VRRP的功能,VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)出现的目的是解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,因此Keepalvied 一方面具有服务器状态检测和故障隔离功能,另外一方面也有HA cluster功能,下面介绍一下VRRP协议实现的过程。
-
haproxy 是什么以及作用?
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代 理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上, 完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架中, 同时可以保护你的web服务器不被暴露到网络上。 参考:
-
什么是负载均衡?
Load balancing,即负载均衡,是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
-
什么是 rpc 及应用场景?
RPC,就是将数据序列化之后传递给接收的服务器,然后获取一个序列化后的返回值。 在网络通信中,不管是TCP 还是UDP,我们都要在传输层上设计自己的应用层协议,使得前后端的数据可以相互通信传输一个可以识别的内容。 后来,人们期望能够更方便一点地让前后端进行交互,于是提出了RPC,就像调用函数一样来让前后端来进行通信,屏蔽掉复杂的应用层协议
-
简述 asynio 模块的作用和应用场景。
asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。asyncio的异步操作,需要在coroutine中通过yield from完成。 event loop 对象包含两个部分:event 和 loop。event 负责 I/O 事件通知而 loop 负责循环处理 I/O 通知并在就绪时调用回调。这里 event 的含义与 select 中的 event mask 类似。 协程可以处理IO密集型程序的效率问题,但是处理CPU密集型不是它的长处,如要充分发挥CPU利用率可以结合多进程+协程。
-
简述 gevent 模块的作用和应用场景。
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程, 在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
-
twisted 框架的使用和应用?
twisted网络框架的三个基础模块:Protocol, ProtocolFactory, Transport Protocol:Protocol对象实现协议内容,即通信的内容协议 ProtocolFactory: 是工厂模式的体现,在这里面生成协议 Transport: 是用来收发数据,服务器端与客户端的数据收发与处理都是基于这个模块