文章目录
- 1. 计算机网络
- 1.1 TCP/IP四层模型与OSI七层模型
- 1.2 HTTP协议原理
- 1.2.1 消息结构
- 1.2.2 HTTP常见请求方法
- 1.2.3 常见状态码
- 1.3 HTTPS协议原理
- 1.4 TCP与UDP
- 1.4.1 TCP三次握手
- 1.4.2 TCP四次挥手
- 1.4.3 常见热点问题
- 1.4.4 浏览器输入URL并回车的过程以及相关协议?DNS查询过程?
- 2. 操作系统
- 2.1 进程与线程区别?
- 2.2 进程间通信方式-五种
- 2.3 线程间通信方式-四种
- 2.4 死锁
- 3. 五大常见算法
- 3.1 分治法
- 3.2 动态规划法
- 3.3 贪心法
- 3.4 回溯法(深度优先搜索所有解)
- 3.5 分支限界法(广度优先搜索最优解)
1. 计算机网络
1.1 TCP/IP四层模型与OSI七层模型
常用设备:
物理层:网卡,网线,集线器,中继器,调制解调器
数据链路层:网桥,交换机
网络层:路由器
网关工作在第四层传输层及其以上基于TCP的协议:HTTP、FTP、SMTP
基于UDP的协议:RIP、DNS、SNMP
1.2 HTTP协议原理
定义:HTTP是基于TCP/IP协议的超文本传输协议,即浏览器作为客户端通过URL向HTTP服务器发送所有请求。HTTP是无连接(每次连接只处理一个请求)、无状态(对事务处理没有记忆)、媒体独立的(传输任何类型的数据)。
1.2.1 消息结构
1. 客户端请求消息:请求行、请求头、请求数据
2. 服务器端响应消息:状态行、消息报头、响应数据
示例:
1.2.2 HTTP常见请求方法
GET: 请求指定的页面信息并返回实体
POST: 向特定的资源提交数据进行处理请求
PUT: 向服务器上传资源
DELETE: 请求服务器删除资源
GET和POST区别
GET | POST | |
---|---|---|
使用场景不同 | 从服务器端获取数据 | 向服务器端提交数据 |
可见性不同 | GET保存的数据显示在URL中,对所有人可见,且数据长度最长2KB | POST保存的数据不会显示在URL中,数据长度不受限制 |
安全性不同 | GET提交的数据在页面会被浏览器缓存,不安全 | POST保存的数据不能被缓存,安全性较高 |
1.2.3 常见状态码
100: 服务器仅接收到部分请求,一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。
101: 服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。
102: 由WebDAV(RFC 2518):扩展的状态码,代表处理将被继续执行200 OK: 请求成功(其后是对GET和POST请求的应答文档。)
201 Created: 请求被创建完成,同时新的资源被创建。
202 Accepted: 供处理的请求已被接受,但是处理未完成。
203 Non-authoritative Information: 文档已经正常地返回,但一些应答头可能不正确
204 No Content: 没有新文档。浏览器应该继续显示原来的文档。
205 Reset Content: 没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
206 Partial Content: 客户发送了一个带有Range头的GET请求,服务器完成了它。300 Multiple Choices: 多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
301: 永久重定向
302: 暂时重定向400 Bad Request: 服务器未能理解请求。
401 Unauthorized: 被请求的页面需要用户名和密码。
403 Forbidden: 对被请求页面的访问被禁止。
404 Not Found: 服务器无法找到被请求的页面。500 Internal Server Error: 请求未完成。服务器遇到不可预知的情况。
501 Not Implemented: 请求未完成。服务器不支持所请求的功能。
502 Bad Gateway: 请求未完成。服务器从上游服务器收到一个无效的响应。
503 Service Unavailable: 请求未完成。服务器临时过载或宕机。
504 Gateway Timeout: 网关超时。
1.3 HTTPS协议原理
超文本传输协议HTTP被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如:银行卡号、支付密码等敏感信息。
为了解决HTTP协议明文传输、通信数据不安全这一缺陷,需要使用另一种协议:安全套接字层SSL超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信数据加密。
对称加密: 加解密密钥相同
非对称加密:公钥加密,私钥解密【公私钥不一致,私钥保存好,任有公钥的人可以确认该信息被私钥加密过】
HTTPS链接建立的过程1、客户端向服务器端发送请求,例如www.baidu.com2、服务器端接收请求,并发送SSL证书给客户端3、客户端根据SSL保存的公钥校验证书真实性【完成验证服务器身份,非对称加密】4、若证书为真,使用证书保存的公钥对对称密钥加密5、服务器端根据私钥进行解密,得到对称密钥进行数据加密6、客户端通过对称密钥进行数据解密【完成通信加密,对称加密】
HTTP与HTTPS区别?
HTTP | HTTPS | |
---|---|---|
安全性 | HTTP明文传输数据未加密,安全性差 | HTTPS传输过程SSL加密,安全性高 |
默认端口 | 80 | 443 |
速度 | HTTP响应速度快、消耗资源少 | HTTPS响应速度慢、消耗资源多 |
1.4 TCP与UDP
1.4.1 TCP三次握手
参考链接:https://blog.csdn.net/qzcsu/article/details/72861891
第一次握手:TCP客户端向服务器发出报文连接请求。该报文首部中SYN=1、初始序列号 seq=x 。请求发送后,**TCP客户端进程进入了 SYN-SENT(同步已发送状态)。**TCP规定SYN报文段(SYN=1的报文段)不能携带数据,因此需要消耗掉一个序号seq。
第二次握手:服务端收到连接请求报文段后,如果同意连接,则会发送一个应答消息确认报文,该确认报文中应该 SYN=1,ACK=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,TCP服务器进程进入了SYN-RCVD(同步收到)状态。
第三次握手:当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
TCP报文首部
1. 紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
2. 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
3. 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
4. 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
5. 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
1.4.2 TCP四次挥手
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
第一次握手:客户端停止发送数据,并发送连接释放请求FIN【FIN=1,seq=u】。此时客户端进入FIN-WAIT-1(终止等待1)状态。
第二次握手:服务器收到连接释放请求后,发出确认释放TCP连接请求【ACK=1,ack=u+1,服务器序列号seq=v】,服务端就进入了CLOSE-WAIT(关闭等待)状态。(但是因为 TCP 连接是双向的,所以服务器端仍旧可以发送数据给客户端)
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2**(终止等待2)状态**,接收服务器剩余数据,并等待服务器发送释放连接请求。
第三次握手:服务器将最后的数据发送完毕后,就向客户端发送连接释放报文【FIN=1,ACK=1,ack=u+1】,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为【seq=w】,此时,服务器就进入了LAST-ACK(最后确认)状态。
第四次握手:客户端收到服务器的连接释放报文后,必须发出确认应答【ACK=1,ack=w+1,自己的序列号是seq=u+1】。此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
1.4.3 常见热点问题
问题一:什么原因造成TIME_WAIT过多?怎么解决TIME_WAIT过多问题?
1、在高并发的场景下,会出现大量的 TIME_WAIT 连接
2、大量的短连接存在解决:
1、客户端,调整短链接为长链接,HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间
2、服务器端允许 time_wait 状态的 socket 被重用缩减 time_wait 时间,设置为 1 MSL(即,2 mins)
问题二:TCP如何保证可靠传输?【连接(三次握手、四次挥手)、超时重传、流量控制、拥塞控制、校验和、ARQ协议】
超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
拥塞控制: 当网络拥塞时,减少数据的发送。
校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。TCP 的接收端会丢弃重复的数据。
ARQ 协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
问题三:TCP与UDP的区别?
问题四:TCP为何采用三次握手来建立连接?若采用二次/四次握手可以吗?
参考:https://blog.csdn.net/m0_67698950/article/details/127074121
1.三次握手才可以阻止重复历史连接的初始化造成混乱(主要原因)
2.三次握手才可以同步双方的初始序列号
3.三次握手才可以避免资源浪费不使用「两次握手」和「四次握手」的原因:
「两次握手」:无法防止历史连接的建立,无法可靠的同步双方序列号,会造成双方资源的浪费。
「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
问题五:为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
1.建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
2.而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
1.4.4 浏览器输入URL并回车的过程以及相关协议?DNS查询过程?
1、DNS域名解析: 浏览器查找域名DNS对应的IP地址(浏览器缓存、路由器缓存、DNS缓存)
2、TCP连接: 根据IP三次握手建立TCP连接
3、HTTP请求: 浏览器向服务器发送HTTP请求
4、HTTP响应: 服务器端处理请求返回HTTP报文
5、浏览器进行渲染
2. 操作系统
2.1 进程与线程区别?
- 进程是资源分配的最小单位、线程是CPU进行任务调度与执行的最小单位
- 一个进程可以包含多个线程,多个线程可以共享进程的堆区、方法区资源
- 进程通信资源消耗大、线程通信资源消耗少
2.2 进程间通信方式-五种
-
管道
-
消息队列
-
socket(在客户端和服务器之间通过⽹络进⾏通信)
-
信号量(信号量是⼀个计数器,⽤于多进程对共享数据的访问)
-
共享数据(直接读写同一块内存空间)
2.3 线程间通信方式-四种
-
方式一:使用 volatile 关键字
基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。
-
方式二:使用Object类的wait() 和 notify() 方法
Object类提供了线程间通信的方法:wait()、notify()、notifyAll(),它们是多线程通信的基础,而这种实现方式的思想自然是线程间通信。
注意: wait和 notify必须配合synchronized使用,wait方法释放锁,notify方法不释放锁 -
方式三:使用JUC工具类 CountDownLatch
jdk1.5之后在java.util.concurrent包下提供了很多并发编程相关的工具类,简化了我们的并发编程代码的书写,CountDownLatch基于AQS框架,相当于也是维护了一个线程间共享变量state
-
方式四:基本LockSupport实现线程间的阻塞和唤醒
LockSupport 是一种非常灵活的实现线程间阻塞和唤醒的工具,使用它不用关注是等待线程先进行还是唤醒线程先运行,但是得知道线程的名字。
2.4 死锁
-
定义:死锁是指多个进程因竞争资源而造成互相等待的僵局,若无外力作用,这些进程都将无法向前推进。
-
原因:
- 系统资源的竞争:系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁。
- 进程运行推进顺序不合适
-
四个条件:
1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。
4.循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
-
死锁预防:由于资源互斥是资源使用的固有特性是无法改变的。
- 破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
- 破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
- 破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。当资源有序分配时,很明显是破坏了循环等待条件
- 死锁避免
死锁避免的基本思想:系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,如果分配后系统可能发生死锁,则不予分配,否则予以分配,这是一种保证系统不进入死锁状态的动态策略。
常见方法:
1、避免一个线程同时获取多个锁
2、避免一个线程同时占用多个资源,尽量保证每个锁只占用一个资源
3、尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
4、对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
3. 五大常见算法
3.1 分治法
将一个难以直接解决的大问题,分割成一些规模较小的相同子问题,以便各个击破,分而治之。(无重叠子问题、具有最优子结构)
特征:(能分、能解、能合并)
- 该问题的规模缩小到一定的程度就可以容易地解决
- 该问题可以分解为若干个规模较小的相同子问题,即该问题具有最优子结构性质。
- 该问题所分解出的各个子问题是相互独立的,即子问题之间无重叠子问题。
- 利用该问题分解出的子问题的解可以合并为该问题的解;
基本步骤:
1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
3 合并:将各个子问题的解合并为原问题的解。适用分治法求解的经典问题:
1)二分搜索 2)大整数乘法 3)Strassen矩阵乘法
4)归并排序 5)快速排序 6)汉诺塔
3.2 动态规划法
将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。(有重叠子问题、具有最优子结构)
特征:
(1) 最优子结构:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。
(2) 有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)
(3) 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。基本步骤:
(1)分析最优解的性质,并刻画其结构特征。
(2)递归的定义最优解。
(3)以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值
(4)根据计算最优值时得到的信息,构造问题的最优解动态规划求解的经典问题:
矩阵连乘、最长公共子序列(LCS) 、背包问题、双调欧几里得旅行商问题
3.3 贪心法
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解,贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。
基本步骤:
1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。适用贪心法求解的经典问题:
Huffman编码,Dijkstra算法(求解最短路径),最小生成树算法
3.4 回溯法(深度优先搜索所有解)
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
思想策略:
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。基本步骤:
(1)针对所给问题,确定问题的解空间:首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解。
(2)确定结点的扩展搜索规则
(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。回溯法求解的经典问题:
八皇后问题、图的着色问题、批处理作业调度问题
3.5 分支限界法(广度优先搜索最优解)
类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
基本策略:
在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展对点。为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。与回溯法的区别:
1、方式不同:回溯法采用深度优先搜索堆栈活结点的所有可行子结点,分支限界法广度优先或最小消耗优先搜索队列。
2、目标不同:回溯法找出满足约束条件的所有解,分支限界法满足约束条件的一个解或特定意义下的最优解
3、活节点:回溯法的一个结点有多次机会成为活结点,分支限界法的一个结点只有一次机会成为活结点