三次握手
- 第一次握手
- 客户端向服务端发送连接请求报文段SYN=1。该报文段中包含自身的数据通讯初始序号seq=x。请求发送后,客户端便进入 SYN-SENT 状态。
- 第二次握手
- 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答ACK=1,该应答中也会包含自身的数据通讯初始序号seq=y,发送完成后便进入 SYN-RECEIVED 状态。
- 第三次握手
- 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文ACK=1。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
- 为什么 TCP 建立连接需要三次握手,而不是两次?这是因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。
TCP四次挥手
- TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
- 第一次挥手
- 若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。
- 第二次挥手
- B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明 A 到 B 的连接已经释放,不再接收 A 发的数据了。但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A。
- 第三次挥手
- B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。
- 第四次挥手
- A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态
- 当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞
OSI 5层,发送邮件属于哪一层,基于什么协议(传输层协议),为什么
-
利用E-mail软件收发电子邮件,我们需要设置POP3服务器和SMTP服务器的地址, POP3(Post Office Protocol 3)即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器 -
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,应用层 -
网络层协议:包括:IP协议、ICMP协议、ARP协议、RARP协议 传输层协议:TCP协议、UDP协议 应用层协议:FTP、Telnet、SMTP、HTTP、RIP、NFS、DNS、RSTP
TCP与UDP区别
UDP | TCP | |
---|
是否连接 | 无连接 | 面向连接 | 是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 | 连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 | 传输方式 | 面向报文 | 面向字节流 | 首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 | 适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
拥塞控制
- TCP的四种拥塞控制算法
1.慢开始 2.拥塞避免算法 3.快重传 4.快恢复 - 发送方维护着一个叫做拥塞窗口cwnd的状态量,其值取决于网络的拥塞程度,并且动态变化
- cwnd维护原则:只要网络没有出现拥塞,拥塞窗口就在增大一些,但只要出现拥塞,就减小一些
- 判断出现拥塞的依据:没有按时收到应到达的确认报文(即发生重传)
- 慢开始:假设当前的拥塞窗口值为1,而发生窗口(swnd)等于拥塞窗口(cwnd),因此发送方当前只能发送一个数据报文段(拥塞窗口cwnd的值是几,就能发送几个数据报文段),接收方收到该数据报文段后,给发送方回复一个确认报文段,发送方收到该确认报文后,将拥塞窗口的值变为2,发送方此时可以连续发送两个数据报文段,接收方收到该数据报文段后,给发送方一次发回2个确认报文段,发送方收到这两个确认报文后,将拥塞窗口的值加2变为4,当拥塞窗口cwnd的值已经等于慢开始门限值,之后改用拥塞避免算法。
- 拥塞避免算法:拥塞窗口cwnd只能线性加一,而不是像慢开始算法时指数增加。假设24个报文段在传输过程中丢失4个,接收方只收到20个报文段,给发送方依次回复20个确认报文段,一段时间后,丢失的4个报文段的重传计时器超时了,发送发判断可能出现拥塞,更改cwnd和ssthresh.并重新开始慢开始算法
- 快重传:发送方一旦收到连接的3个重复确认,就将相应的报文段重传,而不是等到报文段的重传计数器超时才重传。有时个别报文段在网络中丢失,但并未发生拥塞,这将导致发送方超时重传,并误以为发生了阻塞,发送方错误的启动慢开始算法,并将拥塞窗口cmnd又设置为1,从而降低了传输效率。
- 快恢复:一旦收到三个重复确认,不启动慢开始算法,而执行快恢复算法,发送方将,慢开始门限值和拥塞窗口值设为当前窗口的一半,开始执行拥塞避免算法
流浪控制
一、为什么需要流量控制?
二、如何控制?
三、发送方何时再继续发送数据?
- 当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。
二者区别
- 拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:( 1 )慢开始、拥塞避免( 2 )快重传、快恢复。
- 流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
HTTP响应码
- 100:服务器收到请求,客户端可继续发送信息
- 200:请求成功
- 300:多种选择,服务器没有任何标准可以遵循去代替用户来进行选择.200:请求成功
- 301:永久移动,URl地址永久改变
- 302:临时移动,URl地址临时改变
- 303:查看其他位置,需要客户端再get一下,再访问一个url
- 304: 未修改,可直接从浏览器缓存中获取该资源
- 305: 使用代理,由于安全原因必须使用代理才能访问
- 400:错误请求,请求语法错误。
- 401:未授权,需要身份验证
- 402:需要付款,为数字支付系统使用的
- 403:禁止访问,没有权利
- 404:未找到,服务端找不到请求
- 405:请求方法被服务器禁止
- 406:无法接受
- 407:需要代理身份验证
- 408:请求超时
- 500:内部服务器错误
- 501:未实现,服务器不支持的请求的方法
- 502:网关错误
- 503:服务不可用
- 504: 网关超时
- 505:http版本不支持
- 发生502,应该先查看什么,发生500应该先查看什么
然后问了下链表和数组的区别
- 数组静态分配内存,链表动态分配内存;
- 数组在内存中连续,链表不一定连续;
- 数组元素在栈区,链表元素在堆区;
- 数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
- 数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
有了解过排序吗,说说哪些排序是稳定的,哪些是不稳定的,时间复杂度是多少,空间复杂度
手写快排,说说思路
刚刚说了树,说一下树的应用场景(说了索引)
数据库
说说事务的隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|
读未提交(read-uncommitted) | 是 | 是 | 是 | 不可重复读(read-committed) | 否 | 是 | 是 | 可重复读(repeatable-read) | 否 | 否 | 是 | 串行化(serializable) | 否 | 否 | 否 |
- Mysql 隔离级别为 可重复读
- 快照读就是读取数据的时候会根据一定规则读取事务可见版本的数据。 而当前读就是读取最新版本的数据
- (快照读,不会加锁)(当前读,会在搜索的时候加锁)
- 如果事务中都使用快照读,那么就不会产生幻读现象,但是快照读和当前读混用就会产生幻读。
- 当前读为什么会阻塞新数据的插入,主要是间隙锁的加锁机制
什么是脏读、不可重复读、幻读
-
脏读读到了修改未提交到数据库的数据。就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。 -
不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读 -
幻读读到了其他事务新插入的数据,这种现象较幻读。事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据 称为幻读 -
不可重复读的重点是修改** : 同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了 幻读的重点在于新增或者删除 同样的条件 , 第 1 次和第 2 次读出来的记录数不一样
如何停止一个线程,会发生什么事情
- 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
- 使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。
- 使用interrupt方法中断线程。
碰到过哪些异常,OOM可以被捕获吗
-
OOM 能不能被 catch 住?在某些条件下可以。仅在我们可控的代码,并且在 try 块中存在申请大量内存的情况下,此时触发的 OOM,才是可以被 catch 住的。 当我们 catch 住 OOM 的时候,我们应该主动释放一些我们可控的内存,做好内存管理,避免在后续的操作中,立即又会触发 OOM,导致崩溃。 -
触发了 Error 时,它的执行状态已经无法恢复了,此时需要终止线程甚至是终止虚拟机。这是一种不应该被我们应用层去捕获的异常。 理论上我们不应该去主动 catch OOM。哪怕在此处 catch 住了,可 App 当前的状态也已经处于“濒危”状态。如果不采取措施,此时不崩,换一个地方也会崩,逃的了初一,逃不过十五。 正确的做法是,主动去管理内存。图片是吃内存的大户,而如果 App 内统一了图片加载库,例如 Glide,在内存吃紧的时候,就可以通过 Glide 主动释放掉一些内存,让 App 恢复到健康的状态。
反射了解吗
- 反射机制是指在程序运行过程中,对任意一个类都能获取其所有属性和方法,并且对任意一个对象都能调用其任意一个属性和方法。这种动态获取类和对象的信息,以及动态调用对象的方法的功能被称为Java语言的反射机制。
- 在Java中对象主要有2种类型:编译时类型和运行时类型,程序在编译期间无法预知该对象和类的真实信息,只能通过运行时信息来发现该对象和类的真实信息,而其真实信息(对象的属性和方法)通常只能通过反射机制来获取,这便是Java的反射机制的核心功能。
注解了解吗
- 其实说白就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。
Redis
用过Redis吗,用过缓存
Redis底层数据结构了解过吗?说了字典和跳表
-
Redis中的字典使用哈希表作为底层实现,每个字典带有两个哈希表,一个平时使用,另一个仅在进行rehash时使用。 当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算法来计算键的哈希值。 哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会连接成一个单向链表。 在对哈希表进行扩展或者收缩操作时,程序需要将现有哈希表包含的所有键值对rehash到新哈希表里面,并且这个rehash过程并不是一次性地完成的,而是渐进式地完成的。 -
跳表是在链表的基础上进行扩展的,为的是实现redis的sorted set数据结构。 level0: 是存储原始数据的,是一个有序链表,每个节点都在链上 level0+: 通过指针串联起节点,是原始数据的一个子集,level等级越高,串联的数据越少,这样可以显著提高查找效率。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dP9NKrLi-1633244540357)(C:\Users\liu990070251\AppData\Roaming\Typora\typora-user-images\image-20211003133503208.png)]
问答环节问知道Redis分布式锁吗(说了setnx),问我看过什么开源框架吗,了解过
- setnx()方法作用就是SET IF NOT EXIST
docker 、k8s吗
- Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
- k8s 把数量众多的服务器重新抽象为一个统一的资源池, k8s 是经典的一对多模型,有一个主要的管理节点
master 和许多的工作节点slaver
场景题:统计视频直播一天中哪个时间段人数最多
|