大家好,我是小林。
我的图解网站上线也有 1 个月了,好在大家比较友善,没有被攻击过(也可能是因为不出名,大家看不上哈哈)。
网站每天都有几千人在学习,大家平均学习时长接近 20 分钟。
然后,我现在手上有大家的摸鱼时间表,喏,就是下面这个:
10 点~11 点、16 点~17点、20 点~21点,这三个时间段是全天里访问量最高,前面这两个时间段肯定是大家上班摸鱼的时间,后面晚上这个时间段不知道是大家在家里学习的时间,还是在公司里加班摸鱼的时间了
网站每天都有很多人留言,留言的内容有勘误的、有提问的、有打卡学习的、有催更的,所以我的邮箱每天都收到很多邮件。
我每天会在晚上时间统一回答大家的提问和修正文章的小问题。期间,发现有读者的留言的内容还是挺不错的,这里就贴出来给大家看看。
图解网络篇的问答
「HTTP 常见面试题」的问答
小林回答:
这是 HTTP/1.1 规范说的:服务器必须按照接收请求的顺序发送对这些[管道化]请求的响应。
HTTP/1.1 的管道化可以使得浏览器同时并发多个请求,但是服务端接收请求的顺序是由 TCP 协议保证的。
比如,如果浏览器先发送了请求 A,后发送了请求 B。即使服务端先收到了请求 B,服务端其实不能够从内核读取到请求 B 的数据,因为在还有收到请求 A 时, 请求 B 的 TCP 字节其实是乱序的,所以无法被服务端读取到。所以,服务端是会按浏览器发出请求的顺手来顺序响应请求的。
那么,如果服务端在处理 A 请求时耗时比较长,那么后续的请求的处理都会被阻塞住,这称为「队头堵塞」。
所以,HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞。
「HTTP/2 牛逼在哪?」的问答
小林回答:
是的,针对服务端主动推送的时候,stream 是偶数,比如这张图:
小林回答:
不是这个角度看的。http1.1的数据是面向文本的,http2的数据是面向数据结构的。
比如状态码200,在http1.1是用'2''0''0' 三个字符来表示(二进制:110010 110000 110000),如图:
在http2是用数字200表示(二进制:11001000),如图:
「TCP 三次握手与四次挥手面试题」的问答
小林回答:
会的,这件事情是内核做的事情,跟应用层没关系。
小林回答:
下一次的 seq = 上一次 seq len(数据包长度)。
因为第二次挥手是 ACK 报文,len是0,所以第三次挥手的 seq = 上一次seq 0,所以还是一样的。
小林回答:
没关系的,其实三次握手、四次挥手都是操作系统的工作。进程只是告诉内核什么时候(调用connect)发起发起连接建立,什么时候(调用close)发起断开连接。
小林回答:
- 如果客户端处于 establish 状态,还收到服务端的 syn-ack 报文的话,客户端会回challenge ack(至于什么是challenge ack,可以看这篇:已建立连接的 TCP,收到SYN会发生什么?)
- 如果服务端发送了 5 次SYN-ACK还是没收到回应,服务端的内核就会释放连接,不会发送任何报文。
「如何优化 TCP?」的回答
小林回答:
不是说「RTT越小网络越好,应该发送更多的数据」。
而是要让网络稳定在某个期望的RTT,比如我们期望网络的RTT延迟期望在1ms,那么就以这个标准来计算带宽延时积,然后相应调整发送缓冲区大小,避免发送缓冲区大小超过带宽延时积而发生RTT延迟增高。
「TCP 连接,一端断电和进程崩溃有什么区别?」的问答
小林的回答:
总结的很好。
不过,你说的「其他进程占用了该端口,那么由于 ip port 四元组不匹配」这里说的不太清楚,其他进程是同一个客户端的其他进程,还是不同客户端?如果是同一个客户端的其他进程,那么 ip port 四元组是匹配的,如果是不同的客户端,那么 ip port 四元组就是不匹配的。
图解系统篇的问答
「进程间有哪些通信方式?」的问题
小林的回答:
嗯嗯,我就留言区补充下吧,udp的connect不是建立连接,而是绑定ip和port,也就是建立(UDP 套接字——目的地址 端口)之间的映射关系。
如果 UDP 不使用 connect 方式,每次发送报文都会需要这样的过程:
- 连接套接字→发送报文→断开套接字→连接套接字→发送报文→断开套接字 →………
而如果 UDP 使用 connect 方式,就会变成下面这样:
- 连接套接字→发送报文→发送报文→……→最后断开套接字
连接套接字是需要一定开销的,比如需要查找路由表信息。所以,UDP 客户端程序通过 connect 可以获得一定的性能提升。
图解Redis篇的问答
「主从复制是怎么实现的?」的问答
小林的回答:
Redis 保证的是「最终一致性」,而不是「强一致性」。
从节点会努力追赶主节点,最终从节点的状态会和主节点的状态将保持一致。如果网络断开了,主从节点的数据将会出现大量不一致,一旦网络恢复,从节点会采用多种策略努力追赶上落后的数据,继续尽力保持和主节点一致。
图解MySQL篇的回答
「为什么 MySQL 采用 B 树作为索引?」的问答
小林的回答:
B 树的高度在 3 层时存储的数据可能已达千万级别,但对于跳表而言同样去维护千万的数据量那么所造成的跳表层数过高而导致的磁盘io次数增多,也就是使用B 树在存储同样的数据下磁盘io次数更少。
「update 没加索引会锁全表?」的问答
小林的回答:
网上很多人都说 update 不带索引就锁表,其实这是不对的。innodb 源码里面在扫码记录的时候,都是针对记录这个单位去加锁的, update 不带索引就是全表扫扫描,也就是表里的记录都加锁,所以大家误以为加了表锁,因此我的文章标题后面带了个问号
innodb 不会对select、insert、delete、update语句加表锁的,表锁在 inoodb 应用场景很少。
最后
最后说件事。
现在网站已经支持 PWA(渐进式Web 应用)啦。
如果你之前没有了解过 PWA,大概率可能也不明白这是个什么效果,没有关系,我们直接看一个 PWA 应用示例,我们打开 https://xiaolincoding.com/
,这里是在电脑端打开的:
然后点击安装,接着把应用复制到桌面。
这样,下次看图解时,就直接点击这个应用就可以了,还是挺很方便的。