1、TCP 粘包/拆包的原因及解决方法?
-
原因
- 粘包 Nagle算法影响了每次发送数据的大小,当多次发送小数据,只会再第一次发送小片数据,收到ACK之后尽量将剩余的小片数据整合为一个接近MSS(“最大段大小”)大小的数据包再发送出去。
- 拆包 还有一种就是当发送的数据超过了MSS的大小,哟与Nagle算法的存在,会将数据拆成两部分。有部分发,有部分放在传冲去
-
拆包粘包解决方案
- 数据包投添加长度字段,接收方根据长度字段判断数据包 边界
- 特殊字符作为数据包开始结束标志
- 封装为固定长度(空闲空间用0填充)
- 关闭Nagle算法
- 发送的数据按照MSS大小分段,一段作为一个数据包。
2、请概要介绍下序列化
序列化时将对象状态转为可保存或可传输的格式的过程
3、Netty是如何解决JDK中的Selector BUG的?
- 对Selector的select操作周期进行统计,每完成一次空的select操作进行一次计数。
- 在某个周期内如果连续N次空轮询,则说明触发了JDK NIO的epoll死循环bug。
- 创建新的Selector,将出现bug的Selector上的channel重新注册到新的Selector上。
- 关闭bug的Selector,使用新的Selector进行替换。
4、如何让单机下java的应用程序支持几十万乃至百万长连接?
-
突破局部文件句柄
- 文件句柄限制 ulimit -n
- sudo vi /etc/security/limits.conf
- 末尾加上 软限制和硬限制
- * hard nofile 1000000
- * soft nofile 1000000
-
突破全局文件句柄
``` sodu vi /etc/sysctl.conf 在/etc/sysctl.conf文件末尾加上下面的内容。 fs.file-max=1000000 ```
5、select、poll、epoll的区别?
- select 事件复杂度O(n)。限制为1024或者2048个fd监听数量
- pool 事件复杂度O(n)。但是没有最大连接数,因为用的链表
- epoll 复杂度降低到了O(1)。epoll会把哪个流发生了怎样的I/O事件通知我们。没有最大数限制。
6、什么是水平触发(LT)和边缘触发(ET)?
- 水平触发:
- 只要文件描述符关联的读内核缓冲区非空,就一直发可读信号。
- 只要文件描述符关联的写内核缓冲区不满,就一直发可读信号。
- 边缘触发:
- 文件描述符关联的读内核缓冲区空转为非空,发一次可读信号。
- 文件描述符关联的写内核缓冲区空满转为不满,发一次可写信号。
7、直接内存比堆内存快在哪里?
- 堆内存 要拷贝到直接内存,才能发。所以直接用堆外内存少一步。
- 进行网络IO操作其实底层调用的是C的函数write,该函数对应的字节数组的地址不能变化,如果是用java堆作为底层write函数的地址,可能一个gc就把数据从新生代移动到老年代,地址就变化了。
8、啥是零拷贝
- 计算机执行操作时,CPU不需要先将数据从某处内存肤质到另一个特定区域。
- 零拷贝基数可以减少数据拷贝次数,提高传输效率。节约CPU周期和内存带宽。
- 减少用户进程地址空间和内核地址空间之间上下文切换带来的开销
- 不是不要拷贝是减少不必要的拷贝
9、零拷贝解析
- DMA 一种允许外围设备直接访问系统主内存的机制。基于DMA,系统主内存与硬盘或者网卡之前的数据传输可以绕开CPU的全程调度。
- 其实就是sendfile和内存映射
2块缓冲区公用一块物理内存