Netty 系列之经典面试题汇集
Posted Dream_it_possible!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty 系列之经典面试题汇集相关的知识,希望对你有一定的参考价值。
面试官:
1. 请您说一下netty的线程组模型?
我:
线程组就是EventLoopGroup, 一般客户端和服务端用2个线程组就够,一个Boss线程组,一个worker线程组,boss线程组的数量为1, workd线程组的数量为默认的数量。
面试官:
2. 设置boss线程组的数量为什么为1,有什么讲究嘛?
我:
设置boss线程组数量为1,就是只需要一条线程就能够监听socketChannel里的连接,然后将socketChannel包装成NiosocketChannel, 另外Boss线程组会将NioSocketChannel注册到worker线程组的selector里,同时监听OP_WRITE和OP_READ事件,使用一个线程组即为了节省资源开销,如果监听的socketChannel数量比较多,可以稍微增加主线程组数。
面试官:
3. 当worker线程监听到某个SocketChannel 有I/O事件时,会进行哪些操作?
我:
(1) worker线程组首先会向内存池中分配内存,读取I/O数据流。
(2) 然后将读取到的数据转交给解码器Handler进行解码,如果能够解析出完整的数据包,那么会将数据包转交给业务逻辑处理的Handler处理。
(3) 将业务逻辑处理器Handler 处理完后,在返回响应结果前,交给编码器进行数据加密。
(4) 最终写到缓存区,并由I/O worker 线程将缓存区的数据输出到网络中,最终到达客户端。
面试官:
4. 那怎么解决数据传输过程的粘包问题呢?
我:
常用的解决方案有三种:
(1) 将换号符号或特殊标识符号加入到数据包中(如 \\n , \\r\\n等), 比如HTTP和FTP。
(2) 将消息分为head和Body, head里包含body 里消息的长度。
(3) 固定长度的数据包,如固定100个字节,不足用空格补全。
三种方案的具体实现:
(1) Netty的解码器 lineBasedFrameDecoder, 可以判断字节中是否出现了‘\\n’ 或 '\\r\\n'。
(2) Netty有编码器LengthFieldPrepender和解码器 lengthFieldBasedFrameDecoder, 可以在消息中加入消息体的长度值。
(3) 使用固定数据包长度的解码器, FixedLengthFrameDecoder。
面试官:
5. 你知道哪些序列化方式,分别有什么有优缺点呀?
我:
常见的有三种: java自带的序列化方式, Protostuff序列化(ProtoBuf的升级版)框架、Kryo序列化框架。
序列化方式 | 说明 | 注意事项 |
java 自带序列化 | 使用简单,但在网络传输中很少使用,因为性能很低。 | |
Protostuff 序列化 | Protosttuff 是Protobuf 的升级版,不需要编写 . phto文件,只对属性的value做序列化,给属性分的长度是固定的,当类属性个数小于128时,每个属性名只需要1B即可,对属性字段添加@Tag注解标记。 | (1)protostuff不会将类序列化进去,如果对象的属性是一个泛型并且有继承的情况,Protostuff不能进行反序列化,还原子类信息。 |
Kryo 序列化 | 它是一个快速高效的Java对象图形序列化框架,主要是性能、高效易用,有2种序列化方式,第一种为 默认的序列化方式FieldSerializer, 适用于字段类型数据不更改的系统,因此不适用业务数据更换频繁的系统,另外一种序列化方式TaggedFieldSerializer,只需要添加@Tage注解即可。 | (1) 如果选择Kryo 4.0.2版本,需要设置setKipUnknownTags(true)还要在@Tage注解里添加属性 annexed=true。 (2) kryo 是非线程安全的,可以采用ThreadLocal将其缓存下来。 |
以上是关于Netty 系列之经典面试题汇集的主要内容,如果未能解决你的问题,请参考以下文章
前端经典面试题 | 吊打面试官系列 之 说说你对TypeScript 和 JavaScript的理解