python后端面试第二部分:网络编程--长期维护

##################    Python语法基础        #######################

1,tcp/ip协议,tcp和udp,

2,进程,线程,协程,

1. Python多线程能否充分利用CPU多核心,为什么?
这里回答的是GIL相关的东西,可深可浅,自己把握~

7. 同步/异步/阻塞/非阻塞都是什么?
感觉直接解释概念不好解释,这里我回答的思路是举例子,异步说白了就是任务不需要同步进行,比如用爬虫爬取一个数据,然后再保存数据,接下来再去爬另一个数据,这是同步;异步就是爬虫不用等着数据保存好,爬完一个直接去爬另一个,数据保存的事情交给别的逻辑去慢慢处理;阻塞和非阻塞也是基于此的,同步的情况下会阻塞爬虫,爬虫需要等待数据的保存.(非专业解释)

3.标准库线程安全的队列是哪一个?不安全的是哪一个?logging是线程安全的吗?

线程安全即解决线程同步问题。

Queue 是标准库中线程安全的队列,实现了(FIFO).

logging 是线程安全的,但不是 “Process-safe”的,进程安全?。

,http协议:

是建立在tcp之上的,

一次请求一次响应,然后断开连接(无状态,短连接)

请求和响应,

发送:请求头\r\n\r\n请求体,

响应:响应头\r\n\r\n响应体,

介绍下垃圾回收:引用计数/分代回收/孤立引用环;

    多进程与多线程的区别;CPU密集型适合用什么;

    进程通信的方式有几种;

    介绍下协程,为何比线程还快;

网络基础部分

    TCP/IP分别在模型的哪一层;

    socket长连接是什么意思;

    select和epoll你了解么,区别在哪;

    TCP UDP区别;三次握手四次挥手讲一下;

    TIME_WAIT过多是因为什么;

    http一次连接的全过程:你来说下从用户发起request——到用户接收到response;

    http连接方式。get和post的区别,你还了解其他的方式么;

    restful你知道么;

    状态码你知道多少,比如200/403/404/504等等;

Python的垃圾回收机制以及内存管理

垃圾回收机制:

Python的垃圾回收机制以引用计数为主, 标记清除、分代回收为辅。引用计数指:Python在内部维护了针对每一个对象的引用计数, 当一个对象创建或者被引用时,其引用计数将加1,当一个对象被销毁或作用域失效时, 其引用计数将减1。只有对象的引用计数为0时,这个对象将会被回收。引用计数的优点:简单、具有实时性。缺点:对象循环引用时将永远不会被销毁。对于对象循环引用的状况Python使用标记清除来解决,Python在内部实现了一个循环检测器, 不停的检测对象是否存在循环引用,如果两个对象互相循环引用并且不包含其他第三者对象时, 其将会被收回。在Python参考手册中有写道:

当一个对象无法获取时, 那么这个对象有可能被当成垃圾销毁了。Python将所有对象分成了三代, 对象存活时间越长就越晚被回收, 反之则越早被回收。

内存管理:

Python使用了内存池机制来管理内存,其内存以金字塔的形式对内存功能进行划分,-1、-2层主要用于对操作系统进行操作, 0层中是C的malloc,、free等等内存分配和释放函数。1、2层是一个内存池, 当对象小于265K时将直接由这片内存池进行分配内存,否则将调用第0层中的C函数来分配内存,当小于265K的对象被销毁时, 其内存也不会被销毁, 只是返回给了内存池以便二次利用。2层是对Python对象进行操作。

4.Python多线程

Python中多线程由于有GIL的影响, 导致在任意时间内只有一个线程在运行,所以Python的多线程在处理计算密集型任务上效果反而不如单线程, 只有在处理IO密集型任务上多线程才能发挥实力,在等待IO过程中Python C源码会释放GIL, 最终会导致线程在等待IO过程中会被暂停去执行其他的线程。python中GIL主要是由于历史原因导致Cpython虚拟机中的GIL难以移除,同时GIL的存在保证了多线程之间数据完整性以及状态同步。

python中协程?

Python中协程最初使用yield来实现, 当程序运行到yield语句时就会将控制权交出来去执行其他的函数, 在Python3之前只能通过原生yield、greenlet以及Gevent第三方库来实现协程, 在Python3 之后引入了yield from, yield from 用于重构生成器。在Python3.5之后引用了async和await, 其作为yield from, yield的完美替身来实现协程。

1.进程的有哪几种状态以及导致转换的事件。

进程有5种状态:

运行态:该进程正在执行。

就绪态:进程已经做好了准备,只要有机会就开始执行。

阻塞态(等待态):进程在某些事情发生前不能执行,等待阻塞进程的事件完成。

新建态:刚刚创建的进程,操作系统还没有把它加入到可执行进程组中,通常是进程控制块已经创建但是还没有加载到内存中的进程。

退出态:操作系统从可执行进程组中释放出的进程,由于自身或某种原因停止运行。

导致转换的事件:

1. 空->新建:创建执行一个程序的新进程,可能的事件有:新的批处理作业、交互登录(终端用户登录到系统)、操作系统因为提供一项服务而创建、由现有的进程派生等。

2. 新建->就绪:操作系统准备好再接纳一个进程时,把一个进程从新建态转换为就绪态。

3. 就绪->运行:需要选择一个新进程运行时,操作系统的调度器或分配器根据某种调度算法选择一个处于就绪态的进程。

4. 运行->退出:导致进程终止的原因有:正常完成、超过时限、系统无法满足进程需要的内存空间、进程试图访问不允许访问的内存单元(越界)、算术错误(如除以0或存储大于硬件可以接纳的数字)、父进程终止(操作系统可能会自动终止该进程所有的后代进程)、父进程请求终止后代进程等。

5. 运行->就绪:最常见的原因是,正在运行的进程到达了“允许不中断执行”的最大时间段,该把处理器的资源释放给其他在就绪态的进程使用了;还有一中原因可能是由于具有更改优先级的就绪态进程抢占了该进程的资源,使其被中断转换到就绪态。

6.运行->阻塞:如果进程请求它必须等待的某些事件,例如一个无法立即得到的资源(如I/O操作),只有在获得等待的资源后才能继续进程的执行,则进入等待态(阻塞态)。

7.阻塞->就绪:当等待的事件发生时,处于阻塞态的进程转换到就绪态。

8.就绪->退出:在上图中没有标出这种转换,在某些进程中,父进程可以在任何时刻终止一个子进程,如果一个父进程终止,所有相关的子进程都被终止。

9.阻塞->退出:跟上一项原因类似。

2.进程与线程的区别。

进程是资源分配的最小单位,线程是程序执行的最小单位。

进程有自己的独立的地址空间, 线程共享进程中的数据,使用相同的地址空间。

进程自己通信方式主要使用特别的方式来进行通信。线程之间的通信非常的方便, 同一进程下的线程共享全局变量、静态变量等数据。

多进程程序更加的健壮,其中一个进程死掉了并不影响其他的进程,多线程中只要有一个线程死掉,那么整个进程也死掉了。

3.进程通信的几种方式。

进程之间进行通信常用的有几种方式:管道,消息队列, 信号量, 共享内存

管道通常指无名管道, 他的特点包括:

1.半双工:数据只能在一个方向流动,一端为读端,一端为写端

2.有关系进程通信: 管道只能在具有亲缘关系的进程之间进行通信,如父子进程、兄弟进程

3.文件: 管道是一种特殊的文件它有着像普通文件读写一样的API, 它只存在于内存中。

Python实现:

import os

from time import sleep

def child(wpipe):

    while 1:

        msg = "hello world!".encode()

        os.write(wpipe, msg)

        sleep(2)

def parent():

    rpipe, wpipe = os.pipe()

    pid = os.fork()

    if pid == 0:

        child(wpipe)

    else:

        os.close(wpipe)

        fb = os.fdopen(rpipe, 'r')

        while 1:

            recv = os.read(rpipe, 1024)

            print(recv.decode())

parent()

# 输出

"""

>>> python3.6 ./pipe.py 

hello world!

hello world!

hello world!

hello world!

hello world!

hello world!

hello world!

hello world!

hello world!

hello world!

"""

消息队列存放在内核中, 一个消息队列有一个标识符来标识, 它的特点:

1.消息队列是面向记录的, 其中消息具有特定的格式和特点的优先级

2.消息队列独立于发送方和接受方,即使进程终止,消息队列中的消息并不会被删除。所以它可以用于无关进程之间通信

3.消息队列可以对消息实现随机读取, 不需要按在特定的顺序来读取。

信号量属于系统层面, linux系统也是通过信号量来管理进程,进程一旦接收到信号就会打断原来的程序执行流程来处理信号。

import os

import signal

def handler(signalnum, frame):

    global receive_times

    print("收到信号", signalnum, frame)

def main():

    print(os.getpid())

    signal.signal(signal.SIGTERM, handler)

    while True:

        pass

if __name__ == '__main__':

    main()

运行上面程序, 在另一个终端输入 kill pid,程序将会打印

...收到信号 15 <frame object at 0x7ff6ea259630>

共享内存是最简单的通信方式, 他允许多个进程(无关进程, 有关进程)访问同一片内存, 一个进程改变其中的数据后, 其他的进程也能看见数据的变化。共享内存特点:

1.进程共享同一块内存

2. 访问共享内存和访问私有内存一样快

3.不需要系统调用和内核入口

4.不造成不必要的内存复制

Python可以使用multiprocessing中Value、Array、Manager等等实现

4.线程同步几种方式

线程同步通常有4中方式: 临界区、事件、互斥量、信号量。

临界区:拥有临界区的线程可以访问被保护起来的资源或者代码段, 其他线程如果想访问则被挂起, 直到拥有临界区对象放弃临界区为止。Python中使用:threading.Lock()实现。

事件:可以自定义一个事件, 如果这个事件一直不发生, 则这些线程将会阻塞, 直到事件发生。 Python中使用threading.Event()实现 。

互斥量:互斥量为资源引入了状态:锁定/非锁定, 某个线程要更改共享数据时, 先将其锁定, 此时其他线程不能对该资源进行操作, 直到资源被释放。Python中使用threading.Lock()实现 。

5.用户线程与内核线程的区别

用户线程的优点:

1.线程切换不需要内核态特权, 进程不需要为了线程管理而切换到内核态。

2. 可以为应用程序量身定做调度算法而不影响系统调度程序。

3.用户级线程可以再多个平台上运行, 不需要对内核进行修改以支持用户级线程。

用户线程的缺点:

1.当一个用户级线程执行一个系统调用时, 不仅这个线程会被阻塞, 进程中的所有线程都会被阻塞。

2.在用户级线程策略中, 一个多线程应用程序不能利用多处理技术。

内核级线程优点:

1.线程切换由内核控制,可以很好的利用多核CPU。

2.由操作系统内核创建和撤销, 一个内核级线程阻塞并不影响其他的线程运行。

内核级线程缺点:

1.由内核进行调度。不能跨平台。

用户级线程和内核级线程的区别:

1.内核线程是内核可感知的, 用户级线程是内核不可感知的。

2.用户级线程创建,撤销等等不需要内核的支持, 内核级线程创建,撤销等等都需要内核的支持。

3.用户级线程在调用系统指令是会导致其所属的进程被中断, 内核级线程在调用系统指令时, 只会导致该线程被中断, 与其他线程无关。

4.用户级线程CPU调度以进程为单位, 用户程序进行线程的控制, 内核级线程CPU以线程为调度单位, 由系统的线程调度程序负责线程的调度工作。

5.用户级线程的程序实体运行在用户态下程序, 而内核级线程的程序则可以运行在任何状态上。

6.进程池、线程池的原理?

线程池: 开启一定数量的线程并让其睡眠, 当需要一个线程去执行某种任务时, 唤醒某个线程让它执行任务, 任务执行完毕又让其睡眠。

进程池同理

7.进程为什么会产生死锁?

导致死锁的原因:

1.因为系统资源不足

2.进程运行推进顺序不合适

3.资源分配不当

导致死锁的四个必要条件:

1.一次一个进程只能访问一个资源, 其他进程不能访问已分配的资源。

2.当一个进程等待其他进程时, 继续占有已分配的资源时

3.不能强行抢占进程已有的资源

4.存在一个封闭的进程链, 导致每一个进程都占有下一个进程所需的资源

8.操作系统的四个特性?

1.并行: 并行是指两个事件以上(包含)在同一时刻发生既物理上这些事件是同时发生的。

2.共享: 系统中的资源可供内存中的多个进程共同使用, 由于资源的属性不同, 多个进程对资源共享方式也不同。

3.虚拟:操作系统中的虚拟通过分时技术将多个物理设备转换成若干个逻辑上的对应物。

4.异步:在多道程序设计环境下允许多个进程并发执行。

9.什么是缓冲区溢出?有什么危害?其原因是什么?

缓存区溢出指计算机在向缓存区填充数据时超过了缓存区的最大值, 溢出的数据覆盖在了合法数据上。

其危害: 程序崩溃, 导致拒绝服务。跳转并执行恶意代码。

造成缓存区溢出的原因主要是没有对用户的输入进行检查。

10.操作系统中进程调度策略有哪几种?

优先级服务,时间片轮换, 多级反馈

网络相关

1.TCP为什么需要3次握手

三次握手的目的是:防止已失效的连接请求报文又传入到服务端,导致错误。

2.TCP和UDP有什么区别?

tcp是传输控制协议,其提供面向连接、可靠的字节流服务,通信双方必须依照三次握手协议连接之后才能传输数据, tcp提供了超时重传、 丢弃重复数据、检验数据流量控制等功能。

UDP是用户数据包协议, 它提供了一个简单的不可靠的面向无连接的服务,在双方未连接时也能传输数据因而速度特别快。

3.TCP/IP的流量控制?

利用滑动窗口实现流量控制

4.HTTP的长连接和短连接?

短连接: 客户端与服务端每进行一次HTTP操作就建立一次连接,请求结束就断开连接。

长连接:客户端与服务器进行第一次HTTP操作后, TCP连接并不会断开连接, 下次请求将复用这条TCP通道

http://5.IO中同步与异步,阻塞与非阻塞区别

同步和异步关注的是消息通信机制。

同步:发出一个调用时, 在没有得到结果之前这个调用不会返回结果, 如果调用返回那么说明得到结果了。

异步:发出一个调用后立刻返回, 但是返回时没有结果的。

阻塞与非阻塞关注的是程序在等待调用的结果

阻塞:调用结果被返回前该线程被挂起, 直到得到结果后,该线程继续运行。

非阻塞:不能立刻得到结果之前, 该函数不会阻塞当前线程, 会立刻返回。

Cookies 和 Session的区别

cookies是一种保存在客户端上的字符串用于用户与服务端会话持久的保持数据

Session是一种保存在服务器的字符串, 其功能与cookies相同, 但是session是在cookies基础上实现的。

7.什么是TCP粘包、TCP粘包发生了怎么处理?

TCP粘包是指发送方发送了若干个包到接收方接受时都粘成了一个包, 从缓存区来看后一个包的头部数据紧紧的接着前一个包的尾部。

对于TCP粘包的情况有两种处理方式:

1. 接收方: 可以选择关闭tcp默认的nagle算法来避免粘包

2.应用层处理: 格式化数据, 对于每一条数据都采用相同的格式必须有开始符以及结束符, 这样即使发生粘包也可以通过开始符和结束符判断数据边界, 也可以在数据开头就将该条数据的长度填充进数据中, 如果发生粘包则可以使用数据长度来区分每一条数据。

UDP不会发生粘包, 因为UDP没有使用块的合并优化算法,导致接收端的缓存区内按照链式的结构来储存每一个UDP包, 并且每一个UDP包都有消息头,这样接收方就很好的进行拆包。

8.TCP中的time_wait是什么情况?出现过多的close_wait可能是什么原因?

timewait值tcp中主动断开连接一方的一个状态, 当主动断开连接的一方发送给对方FIN包,且对方回复了ACK+FIN时, 主动断开连接的一方将进入time_wait状态, 并持续到2msl后进入CLOSE状态。

出现过多的close_wait的原因:被动关闭方未关闭socket造成。

解决办法:

1.为socket设置超时

2.调整系统参数, 包括句柄参数和TCP/IP参数

9.epoll,select的区别?边缘触发,水平触发区别?

epoll将每一个监听事件都储存在了红黑树中并且只返回被触发的事件。epoll在睡眠结束后只需要检测就绪链表是否为空。

select则将时间都放入一个列表中, 当其中某个事件被触发时,select将所有的事件返回给用户。select睡眠结束后需要遍所有的监听事件。

10. tcp三次握手, 四次挥手

三次握手:

客户端 服务端

->SYN=1, seq=x

<-ACK=1, ack=x+1, seq=y, SYN=1

-> ACK=1, ack=y+1, seq=x+1

<-> data

四次挥手:

主动关闭方 被动关闭方

<-> data

->FIN=1, seq=x

<- ACK=1, seq=y, ack=x+1

<- FIN=1, ACK=1, seq=z, ack=x+1

-> ACK=1, ack=z+1, seq=x+1

谈谈你对http协议的认识。
流程:
1.域名解析
域名解析检查顺序为:浏览器自身DNS缓存---》OS自身的DNS缓存--》读取host文件--》本地域名服务器--》权限域名服务器--》根域名服务器。如果有且没有过期,则结束本次域名解析。域名解析成功之后,进行后续操作
2.tcp3次握手建立连接
3.建立连接后,发起http请求
4.服务器端响应http请求,浏览器得到到http请求的内容
5.浏览器解析html代码,并请求html代码中的资源
6.浏览器对页面进行渲染,展现在用户面前
2. 谈谈你对websocket协议的认识。
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
特点:
事件驱动
异步
使用ws或者wss协议的客户端socket

能够实现真正意义上的推送功能

缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别。
http://www.cnblogs.com/best/p/5695570.html#_label1

列举Http请求中常见的请求方式?
请求方法有8种,分别为:
GET:请求获取由 Request-URI 所标识的资源。
POST:在 Request-URI 所标识的资源后附加新的数据。
HEAD:请求获取由 Request-URI 所标识的资源的响应消息报头。
OPTIONS:请求查询服务器的性能,或查询与资源相关的选项和需求。
PUT:请求服务器存储一个资源,并用 Request-URI作为其标识。
DELETE:请求服务器删除由 Request-URI所标识的资源。
TRACE:请求服务器回送收到的请求信息,主要用语测试或诊断。
CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
16. 列举Http请求中的状态码?
常见的响应状态码有以下几种,在各种下面分别列几个常见的状态码: 
1开头(信息)
2开头(成功)
200(OK):请求成功
202(Accepted):已接受请求,尚未处理
204(No Content):请求成功,且不需返回内容
3开头(重定向)
301(Moved Permanently):被请求的资源已永久移动到新位置
301(Moved Temporarily):被请求的资源已临时移动到新位置
4开头(客户端错误)
400(Bad Request):请求的语义或是参数有错
403(Forbidden):服务器拒绝了请求
404(Not Found):未找到请求的资源
5开头(服务器错误)
500(Internal Server Error):服务器遇到错误,无法完成请求
502(Bad Getway):网关错误,一般是服务器压力过大导致连接超时 
503(Service Unavailable):服务器宕机
17. 列举Http请求中常见的请求头?
Accept:
浏览器端可以接受的媒体类型,通配符 * 代表任意类型
Accept-Encoding:
浏览器申明自己接收的编码方法,例如: Accept-Encoding: zh-CN,zh;q=0.8
Accept-Language:
浏览器申明自己接收的语言,
Connection:
如Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,
如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
Referer:
当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。
User-Agent:
告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本.
Cookie:
Cookie是用来存储一些用户信息以便让服务器辨别用户身份的(大多数需要登录的网站上面会比较常见),比如cookie会存储一些用户的用户名和密码,
当用户登录后就会在客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie的信息去服务器上验证并通过后会判定你是合法用户,从而允许查看相应网页。

1. 简述 OSI 七层协议。
a) 四层协议:应用层、传输层、网络层、网络接口层

b) 五层协议:

应用层:用户使用的应用程序都归属于应用层,作用为规定应用程序的数据格式。

传输层:网络层帮我们找到主机,但是区分应用层的应用就是靠端口,所以传输层就是建立端口到端口的通信。(端口范围0-65535,0-1023为系统占用端口)

网络层:区分不同的广播域或者子网(否则发送一条数据全世界都会受到,是灾难)。

数据链路层:定义电信号的分组方式。

物理层:基于电器特性发送高低点电压(电信号),高电压对应数字1,低电压对应数字0。

c)七层协议:(应用层、表示层、会话层)、传输层、网络层、(数据链路层、物理层)
2. 什么是C/S和B/S架构?
1.什么是C/S结构
C/S (Client/Server)结构,即客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。
C/S结构可以看做是胖客户端架构。客户端实现绝大多数的业务逻辑处理和界面展示,作为客户端的部分需要承受很大的压力,从分利用客户端的资源,对客户机的要求较高。
其实现可以是客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据;另一种是Socket服务器端,服务器端的程序通过Socket与客户端的程序通信。
目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server 应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向。
传统的C/S体系结构虽然采用的是开放模式,但这只是系统开发一级的开放性,在特定的应用中无论是Client端还是Server端都还需要特定的软件支持。由于没能提供用户真正期望的开放环境,C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,加之产品的更新换代十分快,已经很难适应百台电脑以上局域网用户同时使用。而且代价高, 效率低。

2.什么是B/S结构
B/S(Browser/Server)结构即浏览器和服务器结构。它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本(TCO)。
B/S结构可以看作是瘦客户端,只是把显示的较少的逻辑交给了Web浏览器,事务逻辑数据处理在放在了Server端,这样就避免了庞大的胖客户端,减少了客户端的压力。B/S结构的系统无须特别安装,只有Web浏览器即可。当然AJAX\Flex等等的普遍使用也有富客户端的发展方向。
以目前的技术看,局域网建立B/S结构的网络应用,并通过Internet/Intranet模式下数据库应用,相对易于把握、成本也是较低的。它是一次性到位的开发,能实现不同的人员,从不同的地点,以不同的接入方式(比如LAN, WAN, Internet/Intranet等)访问和操作共同的数据库;它能有效地保护数据平台和管理访问权限,服务器数据库也很安全 。特别是在JAVA这样的跨平台语言出现之后,B/S架构管理软件更是方便、快捷、高效。
https://blog.csdn.net/sinat_35111396/article/details/51535784
3. 简述 三次握手、四次挥手的流程。
1 三次握手
客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为随机数 A。
服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。
最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。
2 四次挥手
注意: 中断连接端可以是客户端,也可以是服务器端. 下面仅以客户端断开连接举例, 反之亦然.

客户端发送一个数据分段, 其中的 FIN 标记设置为1. 客户端进入 FIN-WAIT 状态. 该状态下客户端只接收数据, 不再发送数据.
服务器接收到带有 FIN = 1 的数据分段, 发送带有 ACK = 1 的剩余数据分段, 确认收到客户端发来的 FIN 信息.
服务器等到所有数据传输结束, 向客户端发送一个带有 FIN = 1 的数据分段, 并进入 CLOSE-WAIT 状态, 等待客户端发来带有 ACK = 1 的确认报文.
客户端收到服务器发来带有 FIN = 1 的报文, 返回 ACK = 1 的报文确认, 为了防止服务器端未收到需要重发, 进入 TIME-WAIT 状态. 服务器接收到报文后关闭连接. 客户端等待 2MSL 后未收到回复, 则认为服务器成功关闭, 客户端关闭连接.
图解: http://blog.csdn.net/whuslei/article/details/6667471
4. 什么是arp协议?
ARP协议,全称“Address Resolution Protocol”,中文名是地址解析协议,使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址)。
https://www.cnblogs.com/luchuangao/articles/6053742.html
5. TCP和UDP的区别?
TCP 
收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。这样接收端就难于分辨,必须提供拆包机制。
如果利用TCP每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议)。关闭连接主要要双方都发送close连接。
如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储即可,也不用考虑粘包
如果双方建立连接,需要在连接后一段时间内发送不同结构数据,就需要考虑粘包问题。所以一般可能会在头加一个数据长度之类的包,以确保接收。
UDP
对于UDP,不会使用块的合并优化算法。实际上目前认为,是由于UDP支持的是一对多的模式(注意区分不是并发模式),所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中有消息头(消息来源地址,端口等信息),这样对于接收端来说,就容易进行区分处理了,所以UDP不会出现粘包问题。
6. 什么是局域网和广域网?
一、局域网 
局域网(Local Area Network),简称LAN,是指在某一区域内由多台计算机互联成的计算机组。“某一区域”指的是同一办公室、同一建筑物、同一公司和同一学校等,一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、扫描仪共享、工作组内的日程安排、电子邮件和传真通信服务等功能。局域网是封闭型的,可以由办公室内的两台计算机组成,也可以由一个公司内的上千台计算机组成。 
二、广域网 
广域网(Wide Area Network),简称WAN,是一种跨越大的、地域性的计算机网络的集合。通常跨越省、市,甚至一个国家。广域网包括大大小小不同的子网,子网可以是局域网,也可以是小型的广域网。 
三、局域网和广域网的区别 
局域网是在某一区域内的,而广域网要跨越较大的地域,那么如何来界定这个区域呢?例如,一家大型公司的总公司位于北京,而分公司遍布全国各地,如果该公司将所有的分公司都通过网络联接在一起,那么一个分公司就是一个局域网,而整个总公司网络就是一个广域网。
7. 为何基于tcp协议的通信比基于udp协议的通信更可靠?
tcp:可靠 对方给了确认收到信息,才发下一个,如果没收到确认信息就重发
udp:不可靠 一直发数据,不需要对方回应
8. 什么是socket?简述基于tcp协议的套接字通信流程。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。

服务端:创建socket对象,绑定ip端口bind(), 设置最大链接数listen(), accept()与客户端的connect()创建双向管道, send(), recv(),close()

客户端:创建socket对象,connect()与服务端accept()创建双向管道 , send(), recv(),close()
9. 什么是粘包? socket 中造成粘包的原因是什么?
粘包:数据粘在一起,主要因为:接收方不知道消息之间的界限,不知道一次性提取多少字节的数据造成的
数据量比较小,时间间隔比较短,就合并成了一个包,这是底层的一个优化算法(Nagle算法)
10. IO多路复用的作用?
I/O multiplexing就是所谓的select,poll,epoll,也称这种I/O方式为事件驱动I/O(event driven I/O)。
select/epoll的好处就在于单个进程就可以同时处理多个网络连接的I/O。 它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
I/O 多路复用的特点是通过一种机制使一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

多道技术的实现就是为了解决多个程序竞争或者共享同一个资源(比如cpu)的有序调度问题,解决方式即是多路复用。多路复用分为时间上的复用和空间上的复用,空间上的多路复用是指将内存分为几部分,每一部分放一个程序,这样同一时间内存中就有多道程序,前提保证内存是分割;时间上的多路复用是指多个程序需要在一个cpu上运行,不同的程序轮流使用cpu,当某个程序运行的时间过长或者遇到I/O阻塞,操作系统会把cpu分配给下一个程序,保证cpu处于高使用率,实现伪并发。
11. 什么是防火墙以及作用?

http://www.cnblogs.com/loneywang/archive/2007/09/30/912029.html
12. select、poll、epoll 模型的区别?

https://www.cnblogs.com/Anker/p/3265058.html
13. 简述 进程、线程、协程的区别 以及应用场景?
什么是进程
进程(有时称为重量级进程)是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。同一个程序执行两次,属于是两个不同进程。
什么是线程
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机; 运行状态是指线程占有处理机正在运行;
阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。
什么是协程
协程是“微线程”,并非实际存在;是由程序员人为创造出来并控制程序:先执行某段代码、再跳到某处执行某段代码。
如果遇到非IO请求来回切换:性能更低。
如果遇到IO(耗时)请求来回切换:性能高、实现并发(本质上利用IO等待的过程,再去干一些其他的事)

进程池与线程池
基于多进程或多线程实现并发的套接字通信,然而这种方式的缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这对服务端主机带来巨大的压力,于是必须对服务端开启的进程数或线程数加以控制,让机器在一个自己可以承受的范围内运行,这就是进程池或线程池的用途,例如进程池,就是用来存放进程的池子,本质还是基于多进程,只不过是对开启进程的数目加上了限制。

1、进程和线程的区别?

答:进程拥有一个完整的虚拟地址空间,不依赖于线程而独立存在;反之,线程是进程的一部分,没有自己的地址空间,与进程内的其他线程一起共享分配给该进程的所有资源。

比如:开个QQ,开了一个进程;开了迅雷,开了一个进程。在QQ的这个进程里,传输文字开一个线程、传输语音开了一个线程、弹出对话框又开了一个线程。所以运行某个软件,相当于开了一个进程。在这个软件运行的过程里(在这个进程里),多个工作支撑的完成QQ的运行,那么这“多个工作”分别有一个线程。所以一个进程管着多个线程。通俗的讲:“进程是爹妈,管着众多的线程儿子”。

参考自:https://www.zhihu.com/question/25532384

2、为什么说python的线程是伪线程?

答:在python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。

所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。

参考自:https://www.zhihu.com/question/23474039

3、python的append和extend有什么区别?

答:extend()接受一个列表参数,把参数列表的元素添加到列表的尾部,append()接受一个对象参数,把对象添加到列表的尾部。
14. GIL锁是什么鬼?
线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.对于io密集型任务,python的多线程起到作用,但对于cpu密集型任务,python的多线程几乎占不到任何优势,还有可能因为争夺资源而变慢。

解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).
15. Python中如何使用线程池和进程池?
进程池:就是在一个进程内控制一定个数的线程
基于concurent.future模块的进程池和线程池 (他们的同步执行和异步执行是一样的)
http://www.cnblogs.com/haiyan123/p/7461294.html
16. threading.local的作用?
a. threading.local 
作用:为每个线程开辟一块空间进行数据存储。

问题:自己通过字典创建一个类似于threading.local的东西。
storage={
4740:{val:0},
4732:{val:1},
4731:{val:3},
...
}

b. 自定义Local对象
作用:为每个线程(协程)开辟一块空间进行数据存储。

try:
from greenlet import getcurrent as get_ident
except Exception as e:
from threading import get_ident

from threading import Thread
import time

class Local(object):

def __init__(self):
object.__setattr__(self,'storage',{})

def __setattr__(self, k, v):
ident = get_ident()
if ident in self.storage:
self.storage[ident][k] = v
else:
self.storage[ident] = {k: v}

def __getattr__(self, k):
ident = get_ident()
return self.storage[ident][k]

obj = Local()

def task(arg):
obj.val = arg
obj.xxx = arg
print(obj.val)

for i in range(10):
t = Thread(target=task,args=(i,))
t.start()
17. 进程之间如何进行通信?
进程间通信主要包括管道, 系统IPC(包括消息队列,信号,共享存储), 套接字(SOCKET).
管道包括三种:
1)普通管道PIPE, 通常有两种限制,一是单工,只能单向传输;二是只能在父子或者兄弟进程间使用.
2)流管道s_pipe: 去除了第一种限制,为半双工,可以双向传输.
3)命名管道:name_pipe, 去除了第二种限制,可以在许多并不相关的进程之间进行通讯.
18. 什么是并发和并行?
如果某个系统支持两个或者多个动作(Action)同时存在,那么这个系统就是一个并发系统。如果某个系统支持两个或者多个动作同时执行,那么这个系统就是一个并行系统。并发系统与并行系统这两个定义之间的关键差异在于“存在”这个词。
在并发程序中可以同时拥有两个或者多个线程。这意味着,如果程序在单核处理器上运行,那么这两个线程将交替地换入或者换出内存。这些线程是同时“存在”的——每个线程都处于执行过程中的某个状态。如果程序能够并行执行,那么就一定是运行在多核处理器上。此时,程序中的每个线程都将分配到一个独立的处理器核上,因此可以同时运行。
我相信你已经能够得出结论——“并行”概念是“并发”概念的一个子集。也就是说,你可以编写一个拥有多个线程或者进程的并发程序,但如果没有多核处理器来执行这个程序,那么就不能以并行方式来运行代码。因此,凡是在求解单个问题时涉及多个执行流程的编程模式或者执行行为,都属于并发编程的范畴。

摘自:《并发的艺术》 — 〔美〕布雷谢斯
19. 进程锁和线程锁的作用?
线程锁:大家都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块的。

进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制(操作系统基本知识)。

分布式锁:当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。

http://www.cnblogs.com/intsmaze/p/6384105.html
20. 解释什么是异步非阻塞?
同步异步指的是在客户端
同步意味着客户端提出了一个请求以后,在回应之前只能等待
异步意味着 客户端提出一个请求以后,还可以继续提其他请求阻塞

非阻塞 指的是服务器端
阻塞意味着服务器接受一个请求后,在返回结果以前不能接受其他请求
非阻塞意味着服务器接受一个请求后,尽管没有返回结果,还是可以继续接受其他请求
21. 路由器和交换机的区别?
交换机工作于数据链路层,用来隔离冲突域,连接的所有设备同属于一个广播域(子网),负责子网内部通信。

路由器工作于网络层,用来隔离广播域(子网),连接的设备分属不同子网,工作范围是多个子网之间,负责网络与网络之间通信。
https://www.zhihu.com/question/20465477
22. 什么是域名解析?

域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成。
23. 如何修改本地hosts文件?
1)hosts文件的位置:C:\windows\system32\drivers\etc,文件夹中找到Hosts文件并用记事本打开。

2)按照 ip地址 域名 的格式添加单独的一行记录。例如
112.124.39.29 www.server110.com
注意,IP地址前面不要有空格,ip地址和域名之间,要有至少1个空格。
修改后,一定要记得保存文件。

3)如何知道域名的IP地址已经生效?
在您的电脑上请按如下步骤操作:开始-->运行-->输入cmd-->ping 域名-->回车查看结果
显示结果类似 Reply from 220.181.31.183: bytes=32 time=79ms TTL=53
中间的 220.181.31.183 就是域名的IP地址

* 注意:有些浏览器会保存DNS缓存,比如Chrome。多按几次F5刷新即可。
https://www.cnblogs.com/cl-blogs/p/4160483.html
24. 生产者消费者模型应用场景及优势?
生产者消费者模型

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

http://www.cnblogs.com/huchong/p/7454756.html
25. 什么是CDN?
CDN主要功能是在不同的地点缓存内容,通过负载均衡技术,将用户的请求定向到最合适的缓存服务器上去获取内容,比如说,是北京的用户,我们让他访问北京的节点,深圳的用户,我们让他访问深圳的节点。通过就近访问,加速用户对网站的访问。解决Internet网络拥堵状况,提高用户访问网络的响应速度。
CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
26. LVS是什么及作用?
LVS 是 Linux Virtual Server ,Linux 虚拟服务器;是一个虚拟的服务器集群【多台机器 LB IP】。LVS 集群分为三层结构:

1) 负载调度器(load balancer):它是整个LVS 集群对外的前端机器,负责将client请求发送到一组服务器[多台LB IP]上执行,而client端认为是返回来一个同一个IP【通常把这个IP 称为虚拟IP/VIP】
2) 服务器池(server pool):一组真正执行client 请求的服务器,一般是我们的web服务器;除了web,还有FTP,MAIL,DNS
3) 共享存储(shared stored):它为 server pool 提供了一个共享的存储区,很容易让服务器池拥有相同的内容,提供相同的服务[不是很理解]

https://blog.csdn.net/caoshuming_500/article/details/8291940
27. Nginx是什么及作用?
Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。
https://blog.csdn.net/b9x__/article/details/80400697
https://www.cnblogs.com/xiohao/p/6433401.html
28. keepalived是什么及作用?

https://baike.baidu.com/item/Keepalived/10346758?fr=aladdin
29. haproxy是什么以及作用?

https://baike.baidu.com/item/haproxy/5825820
30. 什么是负载均衡?
负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
https://baike.baidu.com/item/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1
31.什么是RPC及应用场景?
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
32.简述 asynio模块的作用和应用场景。

https://www.cnblogs.com/zhaof/p/8490045.html
33.简述 gevent模块的作用和应用场景。

https://www.cnblogs.com/zcqdream/p/6196040.html
34.twisted框架的使用和应用?

http://www.cnblogs.com/zhiyong-ITNote/p/7360442.html

猜你喜欢

转载自www.cnblogs.com/andy0816/p/12228495.html