2024年前端最全源码研读Mycat1,2024年最新快手的前端面试难吗

最后:

总结来说,面试成功=基础知识+项目经验+表达技巧+运气。我们无法控制运气,但是我们可以在别的地方花更多时间,每个环节都提前做好准备。

面试一方面是为了找到工作,升职加薪,另一方面也是对于自我能力的考察。能够面试成功不仅仅是来自面试前的临时抱佛脚,更重要的是在平时学习和工作中不断积累和坚持,把每个知识点、每一次项目开发、每次遇到的难点知识,做好积累,实践和总结。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

/** 设置TCP属性 */

serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); //@1

serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024 * 16 * 2); //@2

// backlog=100

serverChannel.bind(new InetSocketAddress(bindIp, port), 100); //@3

this.serverChannel.register(selector, SelectionKey.OP_ACCEPT); //@4

this.factory = factory;

this.reactorPool = reactorPool;

}

重要属性一览:

  • port : 监听端口,例如默认mycat服务端口:8066,管理端口9066

  • selector : 选择器,主要关心OP_ACCEPT

  • factory : 前端连接工厂,用于将java.nio.SocketChannel包装成NioConnection。

  • reactorPool:从Reactor池。

代码@1,设置Socket选项,如果端口关闭,马上可再次使用。

代码@2,设置Socket的接收缓存区大小,32K。

代码@3,端口绑定。

代码@4,注册OP_ACCEPT事件。

1.2 run方法详解


public void run() {

final Selector tSelector = this.selector;

for (;😉 {

++acceptCount;

try {

tSelector.select(1000L);

Set keys = tSelector.selectedKeys();

try {

for (SelectionKey key : keys) {

if (key.isValid() && key.isAcceptable()) {

accept(); //@1

} else {

key.cancel();

}

}

} finally {

keys.clear();

}

} catch (Exception e) {

LOGGER.warn(getName(), e);

}

}

}

利用select()的多路复用技术,监听客户端的连接事件,并处理,重点关注代码@1,accept()方法的实现:

private void accept() {

SocketChannel channel = null;

try {

channel = serverChannel.accept();

channel.configureBlocking(false);

FrontendConnection c = factory.make(channel); //@1

c.setAccepted(true);

c.setId(ID_GENERATOR.getId());

NIOProcessor processor = (NIOProcessor) MycatServer.getInstance()

.nextProcessor();

c.setProcessor(processor); //@2

NIOReactor reactor = reactorPool.getNextReactor();

reactor.postRegister©; //@3

} catch (Exception e) {

LOGGER.warn(getName(), e);

closeChannel(channel);

}

}

代码@1,将客户端的Socket连接,包装成Mycat的业务对象,Connection,Connection工厂的作用主要是初始化Socket相关参数,以及为通道关联相关的业务处理器(Handler)。稍候重点浏览一下工厂相关的代码。

代码@2,每个通道从Mycat服务器的NioProcessor池中获取一个,在通道的整个生命周期中,只会与一个NioProcessor打交道。

代码@3,从从Reactor池中轮询获取一个Reacotr,注册该通道的读事件。

1.2.1 关于代码@1,Connection工厂代码如下

关于ServerConnectionFactory,这里有个非常重要的作用,就是设置相关Handler,比如ServerQueryHandler

,LoadDataInfileHandler,ServerPrepareHandler。从这里可以看出,Hander是线程通道安全的,线程安全的。

由代码@3处引出下一个主角,NioReactor,NioReactor将接管通道余下的所有关于读、写操作。

2、源码研读NIOReactor

================

在NIOAcceptor中,轮询获取一个NIOReactor,调用其postRegister()方法,将连接注册到事件分发器上(Selector),接下来从postRegister方法开始分析。

2.1 postRegister(AbstractConnection c)


final void postRegister(AbstractConnection c) {

reactorR.registerQueue.offer©;

reactorR.selector.wakeup();

}

mycat Reactor使用的是ConcurrentLikedQueue,无界队列,该方法将连接加入到任务队列尾部,然后唤醒selector.select()方法。

2.2 run 方法详解


@Override

public void run() {

final Selector selector = this.selector;

Set keys = null;

for (;😉 {

++reactCount;

try {

selector.select(500L);

register(selector); //@1

keys = selector.selectedKeys();

for (SelectionKey key : keys) {

AbstractConnection con = null;

try {

Object att = key.attachment();

if (att != null) {

con = (AbstractConnection) att;

if (key.isValid() && key.isReadable()) {

try {

con.asynRead(); // @2

} catch (IOException e) {

con.close(“program err:” + e.toString());

continue;

} catch (Exception e) {

LOGGER.warn(“caught err:”, e);

con.close(“program err:” + e.toString());

continue;

}

}

if (key.isValid() && key.isWritable()) {

con.doNextWriteCheck(); //@3

}

} else {

key.cancel(); //@4

}

} catch (CancelledKeyException e) {

if (LOGGER.isDebugEnabled()) {

LOGGER.debug(con + " socket key canceled");

}

} catch (Exception e) {

LOGGER.warn(con + " " + e);

} catch (final Throwable e){

// Catch exceptions such as OOM and close connection if exists

//so that the reactor can keep running!

// @author Uncle-pan

// @since 2016-03-30

if(con != null){

con.close("Bad: "+e);

}

LOGGER.error("caught err: ", e);

continue;

}

}

} catch (Exception e) {

LOGGER.warn(name, e);

} catch (final Throwable e){

// Catch exceptions such as OOM so that the reactor can keep running!

// @author Uncle-pan

// @since 2016-03-30

LOGGER.error("caught err: ", e);

} finally {

if (keys != null) {

keys.clear();

}

}

}

}

NIOReactor是mycat线程模型的关键,而NioReactor的关键又是run方法,特别是对读写事件的处理。

代码@1,将主Reactor新接收的连接(SocketChannel)注册到从Reactor,用来监听读、写事件。

代码@2,读事件处理。

代码@3,写事件处理逻辑。

代码@4,如果键无效,则取消该键,该键关联的通道将会被关闭。

2.2.1 关于run()方法代码@1详解

private void register(Selector selector) {

AbstractConnection c = null;

if (registerQueue.isEmpty()) { //@1

return;

}

while ((c = registerQueue.poll()) != null) { //@2

try {

((NIOSocketWR) c.getSocketWR()).register(selector); //@3

c.register(); //@4

} catch (Exception e) {

c.close(“register err” + e.toString());

}

}

}

代码@1,如果没有新的连接,直接跳过注册这一步。

代码@2,将任务队列中的SocketChannel注册到该Selector上。

代码@3,NIOSocketWR,该类为通道的IO处理类,主要实现asynRead()、doNextWriteCheck()方法。直接调用通道的注册方法。

NIOSocketWR的register方法:

public void register(Selector selector) throws IOException {

try {

基础学习:

前端最基础的就是 HTML , CSS 和 JavaScript 。

网页设计:HTML和CSS基础知识的学习

HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

CSS样式是表现。就像网页的外衣。比如,标题字体、颜色变化,或为标题加入背景图片、边框等。所有这些用来改变内容外观的东西称之为表现。

动态交互:JavaScript基础的学习

JavaScript是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单。或鼠标滑过表格的背景颜色改变。还有焦点新闻(新闻图片)的轮换。可以这么理解,有动画的,有交互的一般都是用JavaScript来实现的。

就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[外链图片转存中…(img-tKp9286g-1715537469745)]

CSS样式是表现。就像网页的外衣。比如,标题字体、颜色变化,或为标题加入背景图片、边框等。所有这些用来改变内容外观的东西称之为表现。

[外链图片转存中…(img-z5Vp5wbi-1715537469746)]

动态交互:JavaScript基础的学习

JavaScript是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单。或鼠标滑过表格的背景颜色改变。还有焦点新闻(新闻图片)的轮换。可以这么理解,有动画的,有交互的一般都是用JavaScript来实现的。

[外链图片转存中…(img-lrvIA0tB-1715537469747)]

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值