计网
分层模型 体系结构
http和https(+ssl):http端口80,通过明文通信,内容可能被窃听;不验证身份,容易遭到伪装;无法验证报文完整性,可能被篡改。
https端口443,使用ssl/tls证书安全认证。先用非对称加密方式(公钥+2密钥)确定公钥,再用对称加密方式传输数据。
http无状态?当浏览器第一次发送数据给服务器时,服务器响应了;如果同一浏览器,向服务器第二次发送请求时,它还是会响应,但服务器并不知道你就是刚才那个浏览器。简而言之,服务器是不会记住你是谁的,所以是无状态的。
解决无状态:加入cookie、token、jwt等。
TCP和UDP区别
面向连接、可靠传输(校验和、确认、窗口流量控制、超时重传、拥塞控制)、首部长、有状态、效率低、面向字节流传输(UDP面向报文)、只支持一对一。
从输入URL 到页面展示到底发生了什么?
DNS解析->TCP建立连接->发送HTTP请求->服务器处理请求并返回HTTP报文->浏览器解析渲染页面(HTML)->连接结束
http1.0和http1.1区别(连接方式、状态码等)
DNS系统:将域名解析为ip地址
浏览器缓存->hosts文件->本地服务器的本地缓存->根域名->顶级域名->二级域名->权威域名->浏览器
状态码
TCP三次握手、四次挥手
为什么是三次握手而不是两次
“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”
谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
如果两次握手而第二次丢包,接收方会一直等待接收,发送方不会发数据也不会接收接收方的数据;
而如果三次握手第三次丢包,接收方未收到ACK会重传第二次握手SYN。
为什么是四次挥手
因为数据传送是全双工的,接收方接收到FIN发送ACK后可能还有数据要发,接收方发送完数据后才发送FIN。
四次挥手释放连接时,客户端等待2MSL(报文最大存活时间)再CLOSED的意义
考虑第四次挥手ACK丢的情况,接收方没收到ACK就会重发FIN,这样报文一去一回最长时间就是2MSL。
流量控制
利用滑动窗口机制实现,防止发送过快,来不及接收,造成数据丢失。
拥塞控制
防止过多的数据注入到网络,不过载。
流量控制的对象是接收方,怕发送方发的太快,接收方来不及处理,是发送端和接收端之间点到点之间的控制;
拥塞控制的对象是网络,怕发送发发的太快,造成网络拥塞,使得网络来不及处理,是一个全局性的过程。
GET和POST区别
一个重大区别:对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200(返回数据)。在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视;而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。GET产生一个TCP数据包;POST产生两个TCP数据包。
https连接过程:
浏览器向服务器发送支持的加密算法;
服务器选择一套加密算法以证书方式发给浏览器;
客户端验证证书合法性,并生成密钥;
浏览器再次向服务器发请求,发送密钥;
服务器接到密钥后对数据加密,发送给浏览器;
浏览器接到加密数据后用密钥解密。
操作系统
硬链接和软连接
ln -s 创建软连接, ln 创建硬链接;
目录不能创建硬链接, 且不能跨分区系统创建;软连接支持文件和目录, 且能跨分区系统, 常用
硬链接文件与源文件 inode 相同, 而软连接是不同的;
删除软连接和硬链接, 对源文件没影响;删除源文件, 软连接失效, 硬链接无影响(还可访问内容),删除源文件和硬链接, 整个文件会被真正的删除。
算法
排序算法
参考程序员那些必须掌握的排序算法(上)_·wangweijun的博客-优快云博客
改进冒泡排序,设置标志位:开始循环时定义boolean变量为true,如果元素之间进行了交换,就将值置为false。所以,如果boolean变量为true,则证明没有元素进行交换,此时的数组元素已经完成排序,那么跳出外层循环即可。
高频算法
二分、快慢指针、滑动窗口、反转链表、二叉树遍历(层次 中序非递归)
List<List<Integer>> res=new ArrayList<>();//定义、操作二维列表
List<Integer> t=new ArrayList<>();
t.add(1);
res.add(t);
Queue<TreeNode> qu=new LinkedList<>();//队列定义
回溯
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
数据结构
树
二叉树
1.在二叉树的第i层上最多有2^(i-1)个节点,i>=1;
2.二叉树中如果深度为k,那么最多有(2^k)-1个节点,k>=1;
3.n0=n2+1,n0表示度数为0的节点,n2表示度数为2的节点;
4.具有n个节点的完全二叉树的深度为[logn]+1(向下取整);
n个节点的二叉树形态数有C(2n,n)/(n+1)种。
满二叉树,如果父节点的数组下标是 i(i>=1),那么它的左孩子就是 i*2 ,右孩子就是 i * 2 + 1。
平衡二叉树
每个节点的左子树和右子树的高度差至多等于1。
要求太严,每次插入/删除节点时,几乎都会破坏平衡树,需要通过左旋和右旋来进行调整,费时。
红黑树
1.根节点是黑色。
2.每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
3.如果一个节点是红色的,则它的子节点必须是黑色的。
4.从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。[这里指到叶子节点的路径]
包含n个内部节点的红黑树的高度是 O(log(n))
B树(m阶)
1.每个节点至多有m棵子树;
2.根节点至少有2棵子树;
3.其它每个分支节点至少有m/2棵子树;
4.根节点的关键字数量范围:1 <= k <= m-1;
5.非根节点的关键字数量范围:m/2 <= k <= m-1;
6.所有叶子节点在同一层上,B树的叶子节点可以看成一种外部节点,不包含任何信息;
7.有j个孩子的非叶结点恰好有j-1个关键码,关键码按递增次序排列。
B+树(m阶)
所有数据都存储在叶子节点,非叶子节点都是索引;
每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接;
父节点存有右孩子的第一个元素的索引。
已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。根据前序首个元素确定根结点,再通过中序分为左右子树,再在子树确定根结点,以此类推。
已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。根据后序最后元素确定根结点,再通过中序分为左右子树,再在子树确定根结点,以此类推。
但是已知前序遍历序列和后序遍历序列,是不能确定一棵二叉树的。
参考中序遍历和前序遍历确定一棵二叉树(笔算) - 知道了呀~ - 博客园
堆
- 插入元素 :先将元素放至数组末尾,再自底向上堆化,将末尾元素上浮。
- 删除堆顶元素 :删除堆顶元素,将末尾元素放至堆顶,再自顶向下堆化,将堆顶元素下沉。也可以自底向上堆化,只是会产生“气泡”,浪费存储空间。
堆排序(升序)的过程分为两步:
- 建堆,将一个无序的数组建立为一个堆(最大堆)。
- 排序,将堆顶元素取出,然后对剩下的元素进行堆化,反复迭代,直到所有元素被取出为止。