最新十二(3),Java进阶面试资料无偿分享

最后

为什么我不完全主张自学?
平台上的大牛基本上都有很多年的工作经验了,你有没有想过之前行业的门槛是什么样的,现在行业门槛是什么样的?以前企业对于程序员能力要求没有这么高,甚至十多年前你只要会写个“Hello World”,你都可以入门这个行业,所以以前要入门是完全可以入门的。
②现在也有一些优秀的年轻大牛,他们或许也是自学成才,但是他们一定是具备优秀的学习能力,优秀的自我管理能力(时间管理,静心坚持等方面)以及善于发现问题并总结问题。
如果说你认为你的目标十分明确,能做到第②点所说的几个点,以目前的市场来看,你才真正的适合去自学。

除此之外,对于绝大部分人来说,报班一定是最好的一种快速成长的方式。但是有个问题,现在市场上的培训机构质量参差不齐,如果你没有找准一个好的培训班,完全是浪费精力,时间以及金钱,这个需要自己去甄别选择。

我个人建议线上比线下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。

应该学哪些技术才能达到企业的要求?(下图总结)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

这里循环了10次,我发送了10个数据块

第五步:测试,启动服务端和客户端。观察控制台

在这里插入图片描述

问题比较明显,客户端发送了10次数据,服务端做了5次接收,第3次4次5次都出现了粘包的情况。

定义编码器解决粘包拆包问题


要解决粘包拆包的问题就要明确数据边界,尴尬的是面向流的通信是没有消息保护边界的。所以我们需要自定义传输协议来确定消息的边界,说的再直白一点就是我们如果能够明确服务端每次读取消息的长度,那就不会出现粘包拆包问题了。

如果要做到该效果,那么就需要自定义消息协议和编码解码器,我们先来处理客户端。

第一步:定义协议 , 指定消息长度和内容

//定义消息协议

public class MsgProtocol {

//内容长度

private int len;

//内容

private byte[] data;

public MsgProtocol(int len , byte[] data){

this.len = len;

this.data = data;

}

public MsgProtocol(){}

public int getLen() {

return len;

}

public void setLen(int len) {

this.len = len;

}

public byte[] getData() {

return data;

}

public void setData(byte[] data) {

this.data = data;

}

}

第二步:客户端的handler发送MsgProtocol对象

public class ClientHandler extends SimpleChannelInboundHandler {

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

//发送10个数据块

for (int i = 0; i < 10; i++) {

String data = “数据块”+i;

byte[] bytes = data.getBytes(CharsetUtil.UTF_8);

//长度

int len = bytes.length;

//构建一个MsgProtocol,并写去

ctx.writeAndFlush(new MsgProtocol(len,bytes));

}

}

}

第三步:继承MessageToByteEncoder,自定义编码器 ,把消息的长度和内容写出去

//定义直接的编码器:MessageToByteEncoder 把Messsage转换成 byte

public class MessageEncoder extends MessageToByteEncoder {

@Override

protected void encode(ChannelHandlerContext ctx, MsgProtocol msg, ByteBuf out) throws Exception {

//这里需要把内容的长度写给服务端

out.writeInt(msg.getLen());

//把内容写给服务端

out.writeBytes(msg.getData());

}

}

第四步:客户端指定编码器

public static void main(String[] args) {

NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();

Bootstrap bootstrap = new Bootstrap();

bootstrap.group(eventLoopGroup);

bootstrap.channel(NioSocketChannel.class);

bootstrap.handler(new ChannelInitializer() {

@Override

protected void initChannel(SocketChannel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();

//加入自定义的编码器

pipeline.addLast(new MessageEncoder());

pipeline.addLast(new ClientHandler());

}

});

ChannelFuture sync = null;

try {

sync = bootstrap.connect(“127.0.0.1”, 3000).sync();

sync.channel().closeFuture().sync();

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

eventLoopGroup.shutdownGracefully();

}

}

客户端的工作完成了,接下来我们处理服务端

第一步:编写解码器,需要把byte数据封装成MsgProtocol

//定义解码器,拿到数据长度和内容转换成MsgProtocol,交给handler处理

public class MessageDecoder extends ReplayingDecoder {

@Override

protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {

//拿到数据的长度

int len = in.readInt();

//拿到数据的内容

byte[] bytes = new byte[len];

in.readBytes(bytes);

//把解码后的数据交给下一个handler

out.add(new MsgProtocol(len,bytes));

}

}

ReplayingDecoder就是对ByteToMessageDecoder的 扩展和简化

第二步:服务端handler,这里接收的是MsgProtocol消息对象

public class ServerHandler extends SimpleChannelInboundHandler {

//服务端接收次数

private int num = 0;

@Override

protected void channelRead0(ChannelHandlerContext ctx, MsgProtocol msg) throws Exception {

System.out.println("接收消息,次数 = "+ num++);

//接收数据

System.out.println(new String(msg.getData(), CharsetUtil.UTF_8));

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

ctx.channel().close();

}

}

第三步:服务端指定解码器

public static void main(String[] args) {

NioEventLoopGroup bossGroup = new NioEventLoopGroup();

NioEventLoopGroup workGroup = new NioEventLoopGroup();

ServerBootstrap bootstrap = new ServerBootstrap();

bootstrap.group(bossGroup, workGroup);

bootstrap.channel(NioServerSocketChannel.class);

bootstrap.childHandler(new ChannelInitializer() {

@Override

protected void initChannel(SocketChannel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();

//添加解码器

pipeline.addLast(new MessageDecoder());

pipeline.addLast(new ServerHandler());

}

});

try {

ChannelFuture sync = bootstrap.bind(3000).sync();

sync.channel().closeFuture().sync();

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

bossGroup.shutdownGracefully();

workGroup.shutdownGracefully();

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

小米商场项目实战,别再担心面试没有实战项目:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

[外链图片转存中…(img-wFRhnr21-1715664320554)]

小米商场项目实战,别再担心面试没有实战项目:

[外链图片转存中…(img-pf6wnebB-1715664320555)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值