NIO界最强“Hello World,2022最新Java面试题目

前言

这段时间也一直在学习Netty相关知识,因为涉及知识点比较多,也走了不少弯路。目前网上关于Netty学习资料玲琅满目,不知如何下手,其实大家都是一样的,学习方法和技巧都是总结出来的,我们在没有找到很好的方法之前不如按部就班先从基础开始,一般从总分总的渐进方式,既观森林,又见草木。
Netty是一款提供异步的、事件驱动的网络应用程序框架和工具,是基于NIO客户端、服务器端的编程框架。所以这里我们先以NIO和依赖相关的基础铺垫来进行剖析讲解,从而作为Netty学习之旅的一个开端。

  • SubReactorThreadGroup

从Reactor线程组,维护多个Reactor线程,并提供负载均衡。

  • SubReactorThread

从Reactor,主要负责IO读写,俗称IO线程。

在上源码之前我们再来看一下整个示例到时序图:

在这里插入图片描述

核心的关键点如下:

  • Acceptor主要是创建ServerSocketChannel,然后转发给MainReactor

  • MainReactor中维护一个NIO Selector事件选择器,注册OP_ACCEPT事件,每处理一个OP_ACCEPT,表示一个新的客户端连接,在服务端会创建一个SocketChannel对象,接着将该对象转发到从Reactor

  • SubReactorThreadGroup

主从多Reactor模型中的从Reactor组,包含多个从Reactor线程,新的连接会进行负载均衡,选择其中一个Reactor来处理特定的SocketChannel。

  • SubReactorThread

从Reactor线程,会维护一个Nio Selector,会将SocketChannel注册到该事件选择器,处理读、写请求,一个Selector中会包含多个Channel(SocketChannel),但一个SocketChannel在其生命周期中只会注册到一个Selector,这样可以简化处理模型。

程序员希望不服就干,接下来我将展示基于NIO实现多Reactor的代码,应该是全网目前第一个直接用代码实现。

温馨提示:为了便于排版,本文中的代码统一用截图进行展示,代码获取方式:私信回复 reactorcode 即可获取。

[](()2.1 Acceptor代码实现

Acceptor代码实现如下:

在这里插入图片描述

Acceptor代码实现比较简单,就是利用NIO提供的API创建ServerSocketChannel,并设置为非阻塞模式,并调用bind方法绑定端口,然后转发到MainReactor中。

[](()2.2 MainReactor代码实现

MainReactor代码实现如下图所示:

在这里插入图片描述

代码实现要点:

  • 创建Selector选择器对象,并注册OP_ACCEPT事件,用于监听客户端的链接

  • 创建从Reactor线程组

  • NIO事件选择经典使用方法,通过循环调用selector的select方法,此方法会返回当前就绪的事件,例如读事件就绪表明此时调用该通道的网络读API,一定会返回有效数据

  • 如果当前事件是OP_ACCEPT,则调用ServerSocketChannel的accept方法,创建一个SocketChannel对象,并转发到从Reactor线程组中。

[](()2.3 SubReactorThreadGroup代码实现

SubReactorThreadGroup的角色是充当从Reactor线程组,其代码实现如下图所示:

在这里插入图片描述

主要的关键点如下:

  • 内部持有一个业务线程池,用于执行业务逻辑,可类比Dubbo中的用于执行服务提供这各个Service的业务代码

  • 通过next()进行负载均衡,选择一个从Reactor。

  • 这里使用了NioTask,主要是因为Selector虽然是线程安全的,但其内部持有的Key Set是线程不安全的,故这里为保证Selector的现线程安全性,selector的任何方法只会在从Reactor线程中执行,这里只是添加到任务队列中,最终会由从Reactor线程去执行。

[](()2.4 SubReactorThread代码实现

该类是从Reactor到核心逻辑,接下来将详细介绍其实现。

在这里插入图片描述

主要是提供增加IO读写任务(NioTask)添加到任务队列中,并在执行业务逻辑时转发到业务线程池

接下来详细介绍SubReactorThread到run方法实现,重点关注读写事件的处理流程。

在这里插入图片描述

Step1:NIO事件处理的核心要点:

  • 事件选择器的常用套路,调用select进行事件就绪选择,然后遍历就绪集合。

  • 如果事件类型为写事件,直接将数据通过调用通道的write方法将数据写入到网络,这里的核心关键点:

调用SocketChannel的write方法会返回本次写入的字节数,如果等于0,并且数据还未全部写入,则说明写入缓存区已满,需要再次注册写事件

总结

以上是字节二面的一些问题,面完之后其实挺后悔的,没有提前把各个知识点都复习到位。现在重新好好复习手上的面试大全资料(含JAVA、MySQL、算法、Redis、JVM、架构、中间件、RabbitMQ、设计模式、Spring等),现在起闭关修炼半个月,争取早日上岸!!!

下面给大家分享下我的面试大全资料

  • 第一份是我的后端JAVA面试大全

image.png

后端JAVA面试大全

  • 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
[外链图片转存中…(img-NvpmUwkR-1649749852790)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

[外链图片转存中…(img-Yjxc7Lu4-1649749852790)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
阿里P7熬夜整理的《Java全套学习手册》,火爆IT圈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值