网络编程
架构:程序员开发的一种模式python
c/s架构 客户端/服务器模式程序员
b/s架构 Browser浏览器/服务器模式面试
B/S 架构的优点:统一了应用的接口算法
mac地址:物理地址编程
mac地址是12位十六进制组成浏览器
ip地址:四位点分十进制组成(ipv4)安全
端口:操做系统 为每个应用程序分配一个端口号服务器
ip+端口号 惟一肯定某一个电脑上的某一程序网络
arp协议:经过目标ip地址,获取目标mac地址数据结构
肯定在局域网内:ip地址&子网掩码
路由器:
有一个路由表,记录了归他管的全部网段
协议:由多人制定的一种规则
TCP:安全可靠的通讯方式,面向链接,数据流形式传输
UDP:不安全,不可靠,可是速度快,数据包形式传输
tcp和udp的区别:
TCP---传输控制协议,提供的是面向链接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间创建一个TCP链接,以后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另外一端。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,可是并不能保证它们能到达目的地。因为UDP在传输数据报前不用在客户和服务器之间创建一个链接,且没有超时重发等机制,故而传输速度很快
tcp三次握手和四次挥手:
三次握手:创建了一个全双工的通讯连接
(面试回答)
首先,必须先由客户端发起链接的请求
接下来,服务器接收到请求以后,回复给客户端两个标识,一个syn表示
服务器接收到请求,一个ack表示服务器在作准备工做,两个标识一块儿
回复给客户端
最后,客户端接收到服务器的回复,客户端准备链接的全部资源,开始进行链接
发送给服务器一个ack表示客户端的链接准备工做已经完成
(此时表示客户端和服务器能够相互链接了)
若是面试官问你,哪句代码体现了三次握手?
回答: 服务器端的accept,客户端connect
四次挥手:
(面试回答)
(1)首先由链接双方任意一方发起断开链接的请求,发起方发送的请求表示
是我没有数据要继续发送了,能够断开链接了,可是你若是还有数据能够继续向我发送数据.
(2)接收方回复给发起方,表示接到了发起放的断开请求,开始着手准备断开事宜
(3)接收方准备完成后,给发起方发送一个标识,表示接受方没有数据继续发送了
能够断开链接了
(4)发起方接收到消息后,准备断开链接,回收资源
若是面试官问你,哪句代码体现了四次挥手?
回答: close()
ois七层模型:
应用层:py代码,应用
表示层
会话层
传输层:tcp和udp协议 四层路由器
网络层:ip协议 路由器 三层交换机
数据链路层:arp协议 网卡 交换机
物理层:网线,集线器
send 和 sendall 的区别:
对于程序员来讲,用起来是没有什么区别的
实际上,在socket底层对于两个方法的封装有却别:
send(num) 此方法会尝试先发送n个数据(n<num),接下来再尝试发送num-n
sendall(num) 此方法会尝试一次性将num个数据发送出去
基于文件类型的套接字: AF_UNIX
基于网络类型的套接字: AF_INET
黏包:就是由于接收端不知道如何接收数据,形成接收数据的混乱的问题
只发生在tcp协议上. 由于tcp协议的特色是面向数据流形式的传输
粘包的发生主要是由于tcp协议有两个机制: 合包机制(nagle算法),拆包机制
解决黏包的方案:使用struct模块来肯定传输了多少字节
tcp的聊天
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() # 关闭服务器套接字 srever
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)
socketserver
# 正常状况下,tcp协议的socket server,同一时刻只能处理一个请求
# 使用socketserver.ThreadingTCPServer就可让你的tcp协议的server端同时接受多个客户端的请求
# 基于socket实现的
# serverforever方法
# 启动了一个socket的server端
# socketserver启动以后就会一直对外提供服务
# 一个client服务结束了以后,socketserver会帮助你conn.close
# 可是sk对象永远不会中止服务
并发编程:
操做系统的三种基本类型:多道批处理系统(时空复用,空间隔离)、分时系统、实时系统。
操做系统是一个协调管理和控制计算机硬件资源和软件资源的控制程序.
进程:是系统进行资源分配和调度的基本单位,是操做系统结构的基础,进程是正在运行的程序的实例(an instance of a computer program that is being executed)。广义定义:进程是一个具备必定独立功能的程序关于某个数据集合的一次运行活动。它是操做系统动态执行的基本单元,在传统的操做系统中,进程既是基本的分配单元,也是基本的执行单元。
并发:
并发是指资源有限的状况下,二者交替轮流使用资源,好比一段路(单核CPU资源)同时只能过一我的,A走一段后,让给B,B用完继续给A ,交替使用,目的是提升效率。
进程的状态:就绪,运行,阻塞
同步:所谓同步就是一个任务的完成须要依赖另一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态能够保持一致。
异步:所谓异步是不须要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工做,依赖的任务也当即执行,只要本身完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务没法肯定,因此它是不可靠的任务序列
。
异步非阻塞:
效率更高,
由于打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,程序没有在两种不一样的操做中来回切换
。
好比说,这我的忽然发觉本身烟瘾犯了,须要出去抽根烟,因而他告诉大堂经理说,排到我这个号码的时候麻烦到外面通知我一下,那么他就没有被阻塞在这个等待的操做上面,天然这个就是异步+非阻塞的方式了。
进程的建立:系统初始化,一个进程运行过程当中开启了子进程,用户交互式请求,一个批处理做业初识化
进程的结束:正常退出,出错退出,严重退出,被其余进程杀死
进程中:建立进程,锁,队列,进程池
数据隔离:进程与进程之间内存中的数据是互相隔离的
主进程建立守护进程(报活)
其一:守护进程会在主进程代码执行结束后就终止
其二:守护进程内没法再开启子进程,不然抛出异常:AssertionError: daemonic processes are not allowed to have children
信号量的原理:锁+计数器
锁的分类:
在多个进程\线程同时访问一个数据的时候就会产生数据不安全的现象
# 多进程 访问文件
# 多线程
# 同时去访问一个数据
# 尽可能不要设置全局变量
# 只要在多线程/进程之间用到全局变量 就加上锁
互斥锁:
递归锁:
全局解释器锁:
死锁出现的缘由:多把锁同时应用在多个线程中
互斥锁和递归锁哪一个好
# 递归锁 快速恢复服务
# 死锁问题的出现 是程序的设计或者逻辑的问题
# 还应该进一步的排除和重构逻辑来保证使用互斥锁也不会发生死锁
# 互斥锁和递归锁的区别
# 互斥锁 就是在一个线程中不能连续屡次ACQUIRE
# 递归锁 能够在同一个线程中acquire任意次,注意acquire多少次就须要release多少次
事件 : 经过一个标记来控制对多个进程进行同步控制
IPC通讯
# 队列 管道+锁
# 管道 是队列的底层
管道 pipe
# IPC通讯的一种机制,队列就是基于管道来完成通讯的,可是管道是原生的通讯方式,
# 在进程之间会产生数据不安全的状况,须要本身手动加锁来处理.
# 管道在数据传输过程当中,还涉及到一个端口管理,这个须要咱们在代码中作处理才能使代码更完善.
(了解)# 数据共享 _ 进程就是数据隔离的
# Manager模块
# 数据类型 都可以进行数据共享
# 一部分都是不加锁 不支持数据进程安全
# 不安全的解决办法 加锁
# 进程池
# 进程不能无限开 会给操做系统调度增长负担
# 且真正能被同时执行的进程最多也就和CPU个数相同等
# 进程的开启和销毁都要消耗资源和时间
进程池
# 何时用进程池
# 面向高计算型的场景 采用多进程
# 若是开启的进程数超过5个
# 有几个CPU就可以同时运行几个进程
线程:线程
# 线程是CPU调度的最小单位
# 每一个进程中至少有一个线程
# 实际上执行代码的是线程
线程属于进程
# 进程负责获取操做系统分配给个人资源
# 线程负责执行代码
从代码的角度上来看
# 多进程
# 开启和结束 时间开销大
# 切换的效率低
# 内存隔离
# 多线程
# 开启和结束 时间开销很是小
# 切换效率高
# 内存不隔离
# 线程进程之间的对比
# 线程不能独立存在,必须在一个进程里
# 线程的开启 关闭以及切换的开销要远远小于进程
# 同一个进程之间的多个线程之间数据共享
# 何时才会有到CPU
# 程序计算的时候
# IO阻塞
# 是不会用到CPU的
池 和 信号量
# 池 效率高
# 池子里有几个一共就起几个
# 无论多少任务 池子的个数是固定的
# 开启进程和关闭进程这些事都是须要固定的开销
# 就不产生额外的时间开销
# 且进程程池中的进程数控制的好,那么操做系统的压力也小
# 信号量
# 有多少个任务就起多少进程/线程
# 能够帮助你减小操做系统切换的负担
# 可是并不能帮助你减小进/线程开启和关闭的时间
协程:
能在一条线程的基础上,在多个任务之间互相切换
# 节省了线程开启的消耗
# 是从python代码的级别调度的
# 正常的线程是CPU调度的最小单位
# 协程的调度并非由操做系统来完成的
须要安装第三方模块:greenlet,gevent