继续之前的例子(netty5心跳与业务消息分发实例),我们在NettyClientHandler把业务消息改为阻塞性的:

package com.wlf.netty.nettyclient.handler;

import com.wlf.netty.nettyapi.javabean.Header;
import com.wlf.netty.nettyapi.javabean.NettyMessage;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.concurrent.TimeUnit; /**
* 客户端处理类
*/
@Slf4j
public class NettyClientHandler extends ChannelHandlerAdapter { private static final String AUDIO_PATH = "D:\\input\\寒号鸟.wav"; @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
NettyMessage nettyMessage = (NettyMessage) msg; // 接收控制数据响应消息成功,每5秒发送pcm数据
if (nettyMessage.getHeader() != null && nettyMessage.getHeader().getType() == (byte) 0) {
// ctx.writeAndFlush(buildClientRequest());
// }
// 音频文件总时长,单位:秒
int audioTotal = 122;
try (RandomAccessFile raf = new RandomAccessFile(AUDIO_PATH, "r")) { // 读结束标志
boolean readFinish = false; // 文件总字节数
long audioLength = raf.length(); // 每次发送字节数
long eachLength = audioLength * 5 / audioTotal; // 音频数据
byte[] audioData = null;
byte[] bytes = new byte[1024]; long cuccrentLength = 0L; // 读取音频文件
while (true) {
// 休眠5秒
TimeUnit.SECONDS.sleep(5); // 获取当前时间
long startTime = System.currentTimeMillis();
while (cuccrentLength <= eachLength) { // 获取5秒内的音频字节流
int len = raf.read(bytes);
if (len == -1) {
readFinish = true;
break;
} bytes = Arrays.copyOf(bytes, len);
audioData = ArrayUtils.addAll(audioData, bytes);
cuccrentLength += len;
} // 发送5秒的数据包
NettyMessage nettyClientApi = buildNettyClientRequest(audioData, startTime);
log.info("[client] send client msg : {}", nettyClientApi);
ctx.writeAndFlush(nettyClientApi); // 读完了
if (readFinish) {
log.info("The audio data send finish...");
break;
} // 重置
cuccrentLength = 0L;
}
}
}
} /**
* long转字节
*
* @param values
* @return
*/
private byte[] longToBytes(long values) {
byte[] buffer = new byte[8];
for (int i = 0; i < 8; i++) {
int offset = 64 - (i + 1) * 8;
buffer[i] = (byte) ((values >> offset) & 0xff);
}
return buffer;
} /**
* 将两个数组合并起来
*
* @param array1
* @param array2
* @return
*/
private byte[] addAll(byte[] array1, byte... array2) {
byte[] joinedArray = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
return joinedArray;
} /**
* 在处理过程中引发异常时被调用
*
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("[Client] netty client request error: {}", cause.getMessage());
ctx.close();
} /**
* 创建请求消息体
*
* @param audioData
* @param time
* @return
*/
private NettyMessage buildNettyClientRequest(byte[] audioData, long time) {
NettyMessage nettyMessage = new NettyMessage();
Header header = new Header();
byte[] data = buildPcmData(audioData, time);
header.setDelimiter(0xABEF0101);
header.setLength(data.length);
header.setType((byte) 1);
header.setReserved((byte) 0);
nettyMessage.setHeader(header); // 设置数据包
nettyMessage.setData(data);
return nettyMessage;
} /**
* 构造PCM请求消息体
*
* @return
*/
private byte[] buildPcmData(byte[] audioData, long time) {
byte[] timeByte = longToBytes(time); return addAll(timeByte, audioData);
} }

  重启客户端,会发现输出变成这样:

23:35:34.339 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] control response is OK, header : Header{delimiter=-1410399999, length=8, type=0, reserved=0}. sid : 56, interval : 5000
23:35:48.216 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@60deb0fd}
23:35:53.259 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=323592, type=1, reserved=0}, data=[B@6f7f091e}
23:35:58.319 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=485384, type=1, reserved=0}, data=[B@1c9231b2}
23:36:03.361 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=647176, type=1, reserved=0}, data=[B@35f278be}
23:36:08.433 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=808968, type=1, reserved=0}, data=[B@20be6fa5}
23:36:13.496 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=970760, type=1, reserved=0}, data=[B@371eb555}
23:36:18.607 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1132552, type=1, reserved=0}, data=[B@3a8c0da5}
23:36:23.694 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1294344, type=1, reserved=0}, data=[B@1c9da5c2}
23:36:28.855 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1456136, type=1, reserved=0}, data=[B@4f0d32b3}
23:36:33.974 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1617928, type=1, reserved=0}, data=[B@d7b821a}
23:36:39.134 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1779720, type=1, reserved=0}, data=[B@57404735}
23:36:44.272 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=1941512, type=1, reserved=0}, data=[B@26825baa}
23:36:49.410 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2103304, type=1, reserved=0}, data=[B@bc7d63}
23:36:54.650 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2265096, type=1, reserved=0}, data=[B@5106443c}
23:36:59.816 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2426888, type=1, reserved=0}, data=[B@4aac8c6}
23:37:05.009 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2588680, type=1, reserved=0}, data=[B@30419cf2}
23:37:10.200 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2750472, type=1, reserved=0}, data=[B@53f5b8fc}
23:37:15.416 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=2912264, type=1, reserved=0}, data=[B@3031311a}
23:37:20.633 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=3074056, type=1, reserved=0}, data=[B@628f3322}
23:37:25.886 [nioEventLoopGroup-1-0] INFO com.wlf.netty.nettyclient.handler.NettyClientHandler - [client] send client msg : NettyMessage{header=Header{delimiter=-1410399999, length=3235848, type=1, reserved=0}, data=[B@5e95858d}

  心跳根本没进来,因为业务消息占用了事件循环的IO线程,还轮不到心跳消息的发送,除非当前的业务消息发送完了。反之亦然,如果是先发送心跳,那业务消息就别指望有机会发送了,因为心跳根本就停不下来。怎么办?两种解决方案,一种是采用netty自带的IdleStateHandler来做心跳,它不会占用IO线程,因为它采用的是事件检测;另一种就是把业务消息和心跳消息糅合到一起,既然都是定时发送,那就放一起好了,只不过这样一来定时的时间间隔就必须一致了。我们在心跳Handler中带上业务消息:

package com.wlf.netty.nettyclient.handler;

import com.wlf.netty.nettyapi.javabean.Header;
import com.wlf.netty.nettyapi.javabean.NettyMessage;
import com.wlf.netty.nettyapi.util.CommonUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.ScheduledFuture;
import lombok.extern.slf4j.Slf4j; import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.concurrent.TimeUnit; @Slf4j
public class HeartBeatClientHandler extends ChannelHandlerAdapter {
private static final String AUDIO_PATH = "D:\\input\\寒号鸟.wav";
private volatile int interval = 5000;
private volatile ScheduledFuture<?> heartBeat; @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
NettyMessage nettyMessage = (NettyMessage) msg; // 接收控制数据响应消息成功,发送心跳给服务端
if (nettyMessage.getHeader() != null && nettyMessage.getHeader().getType() == (byte) 0) {
byte[] data = nettyMessage.getData();
ByteBuf buf = Unpooled.buffer(8);
buf.writeBytes(data);
int sid = buf.readInt();
interval = buf.readInt();
log.info("[client] control response is OK, header : {}. sid : {}, interval : {}", nettyMessage.getHeader(), sid, interval); // 每interval(默认5000)豪秒发送一次心跳请求到服务端
// heartBeat = ctx.executor().scheduleAtFixedRate(new Runnable() {
// @Override
// public void run() {
// NettyMessage heartBeat = buildHeartBeat(sid);
// log.info("[client] Client send heart beat message to server : ----> {}", heartBeat);
// ctx.writeAndFlush(heartBeat);
// }
// },
// 0, interval, TimeUnit.MILLISECONDS); // 音频文件总时长,单位:秒
int audioTotal = 122;
try (RandomAccessFile raf = new RandomAccessFile(AUDIO_PATH, "r")) { // 读结束标志
boolean readFinish = false; // 文件总字节数
long audioLength = raf.length(); // 每次发送字节数
long eachLength = audioLength * 5 / audioTotal; // 音频数据
byte[] audioData = null;
byte[] bytes = new byte[1024]; long cuccrentLength = 0L; // 读取音频文件
while (true) {
// 休眠5秒
TimeUnit.SECONDS.sleep(5); // 获取当前时间
long startTime = System.currentTimeMillis();
do { // 获取5秒内的音频字节流
int len = raf.read(bytes);
if (len == -1) {
readFinish = true;
break;
} bytes = Arrays.copyOf(bytes, len);
audioData = ArrayUtils.addAll(audioData, bytes);
cuccrentLength += len;
} while (cuccrentLength <= eachLength); // 发送心跳
NettyMessage heartBeat = buildHeartBeat(sid);
log.info("[client] Client send heart beat message to server : ----> {}", heartBeat);
ctx.writeAndFlush(heartBeat); // 发送5秒的数据包
NettyMessage nettyClientApi = buildNettyClientRequest(audioData, startTime);
log.info("[client] Client send business message to server : ----> {}", nettyClientApi);
ctx.writeAndFlush(nettyClientApi); // 读完了
if (readFinish) {
log.info("The audio data send finish...");
break;
} // 重置
cuccrentLength = 0L;
audioData = null;
}
}
} else if (nettyMessage.getHeader() != null && nettyMessage.getHeader().getType() == (byte) 2) {
log.info("[client] receive server business : {}", nettyMessage);
} else {
ctx.fireChannelRead(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("[Client] heart request error: {}", cause.getMessage());
if (heartBeat != null) {
heartBeat.cancel(true);
heartBeat = null;
}
ctx.fireExceptionCaught(cause);
} /**
* 构造心跳请求消息体
*
* @return
*/
private NettyMessage buildHeartBeat(int sid) {
NettyMessage message = new NettyMessage();
Header header = new Header();
byte[] data = buildData(sid);
header.setDelimiter(0xABEF0101);
header.setLength(data.length);
header.setType((byte) 3);
header.setReserved((byte) 0);
message.setHeader(header); // 设置数据包
message.setData(data);
return message;
} /**
* 构建心跳响应消息体
*
* @param sid
* @return
*/
private byte[] buildData(int sid) {
ByteBuf result = Unpooled.buffer(4);
result.writeInt(sid);
return result.array();
} /**
* 创建请求消息体
*
* @param audioData
* @param time
* @return
*/
private NettyMessage buildNettyClientRequest(byte[] audioData, long time) {
NettyMessage nettyMessage = new NettyMessage();
Header header = new Header();
byte[] data = buildPcmData(audioData, time);
header.setDelimiter(Delimiter.DELIMITER);
header.setLength(data.length);
header.setType(MessageType.PCM_TYPE.getType());
header.setReserved((byte) 0);
nettyMessage.setHeader(header); // 设置数据包
nettyMessage.setData(data);
return nettyMessage;
} /**
* 构造PCM请求消息体
*
* @return
*/
private byte[] buildPcmData(byte[] audioData, long time) {
byte[] timeByte = CommonUtil.longToBytes(time); return addAll(timeByte, audioData);
} /**
* long转字节
*
* @param values
* @return
*/
private byte[] longToBytes(long values) {
byte[] buffer = new byte[8];
for (int i = 0; i < 8; i++) {
int offset = 64 - (i + 1) * 8;
buffer[i] = (byte) ((values >> offset) & 0xff);
}
return buffer;
} /**
* 将两个数组合并起来
*
* @param array1
* @param array2
* @return
*/
private byte[] addAll(byte[] array1, byte... array2) {
byte[] joinedArray = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
return joinedArray;
} }

  至于原来的NettyClientHandler相当于废了,在引导类中名存实亡。重启NettyClient,输出如下:

15:45:07.442 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] control response is OK, header : Header{delimiter=-1410399999, length=8, type=0, reserved=0}. sid : 94, interval : 5000
15:45:12.499 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@2bf023ed}
15:45:12.504 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send business message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@b1ad25a}
15:45:17.519 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@44fb731d}
15:45:17.520 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send business message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@253b550c}
15:45:22.551 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@f7ef50d}
15:45:22.552 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send business message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@52ab6eba}
15:45:27.565 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@4d578c69}
15:45:27.565 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send business message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@323b23fa}
15:45:32.598 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@4a957e2d}
15:45:32.598 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send business message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=161800, type=1, reserved=0}, data=[B@43c2077b}
15:45:37.623 [nioEventLoopGroup-1-2] INFO com.wlf.netty.nettyclient.handler.HeartBeatClientHandler - [client] Client send heart beat message to server : ----> NettyMessage{header=Header{delimiter=-1410399999, length=4, type=3, reserved=0}, data=[B@3207ffae}

netty5心跳与阻塞性业务消息分发实例的更多相关文章

  1. netty5心跳与业务消息分发实例

    继续基于我们之前的例子(参见netty5自定义私有协议实例),这次我们加上连接校验和心跳机制: 只要校验通过,客户端发送心跳和业务消息是两个不同的事件发送的,彼此互不干扰.针对以上流程,我们需要增加4 ...

  2. .net 分布式架构之业务消息队列

    开源QQ群: .net 开源基础服务  238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...

  3. Android 消息分发机制

    Android 中针对耗时的操作,放在主线程操作,轻者会造成 UI 卡顿,重则会直接无响应,造成 Force Close.同时在 Android 3.0 以后,禁止在主线程进行网络请求. 针对耗时或者 ...

  4. cocos creator主程入门教程(六)—— 消息分发

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 本篇开始介绍游戏业务架构相关的内容.在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦. ...

  5. 一个可以代替冗长switch-case的消息分发小框架

    在项目中,我需要维护一个应用层的字节流协议.这个协议的每条报文都是一个字节数组,数组的头两个字节表示消息的传送方向,第三.四个字节表示消息ID,也就是消息种类,再往后是消息内容.时间戳.校验码等……整 ...

  6. 使用Netty4实现基本的消息分发

    示例工程代码 可从附件下载 具体的说明和用法在后面介绍 需求与目的 一个游戏服务端需要处理各种业务逻辑,每一种业务逻辑都对应着一个请求消息和一个响应消息.那么服务端需要把这些不同的消息自动分发到对应的 ...

  7. Kafka分片存储、消息分发和持久化机制

    Kafka 分片存储机制 Broker:消息中间件处理结点,一个 Kafka 节点就是一个 broker,多个 broker 可以组成一个 Kafka集群. Topic:一类消息,例如 page vi ...

  8. 深入详解美团点评CAT跨语言服务监控(四)服务端消息分发

    这边首先介绍下大众点评CAT消息分发大概的架构如下: 图4 消息分发架构图 分析管理器的初始化 我们在第一章讲到服务器将接收到的消息交给解码器(MessageDecoder)去做解码最后交给具体的消费 ...

  9. nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模块的Javascript

    Javascrip本身不带IO功能,nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模 ...

随机推荐

  1. python 字符串操作list[::-1]的几种用法

    1.list[-1],此时只有一个参数,作用是通过下标访问数据,-1是倒数第一个. 2.list[:-1],作用是返回从start_index = 0到end_index = -1的一串数据这里的li ...

  2. js与jquery中html() text() val()中的区别

    首先html() text() val() 是jquery方法. 1.html()取得内容可以包含标签. 2.text()取得内容为元素文本内容. 3.val()只有value属性的元素才能使用该方法 ...

  3. Linux 物理机虚拟化

    前言 我有一台安装了 RHCA 资源的磁盘,然而每次开机时需要切换启动项为该磁盘.于是我想将它实现物理虚拟化. 工具 Windows 10 RHCA Disk Virtualbox 5.1 Virtu ...

  4. select下拉选中显示对应的div隐藏不相关的div

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. (尚015)Vue过滤器(对显示的数据进行格式化)

    现在日期为:当前时间-1970年1月1日0时0分0秒的时间差 日期格式化:百度搜索moment 1.test015.html <!DOCTYPE html><html lang=&q ...

  6. 使用socket.io实现多房间通信聊天室

    websocket的实现有很多种,像ws和socket.io,这里使用的是socket.io来实现多房间的效果. 这里的使用没有使用socket.io官方提供的namespace和room,而是完全通 ...

  7. AJAX里使用模板引擎

    一.概述: 处理响应数据渲染可以使用模板引擎(实际上就是一个API,目的是更容易的将数据渲染到HTML中) 目前市面上有许多模板引擎,可以参考 推荐使用artTemplate,它采用作用域预声明的技术 ...

  8. OPCode详解及汇编与反汇编原理

    1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的 ...

  9. 2017.10.3 国庆清北 D3T3 解迷游戏

    题目描述 LYK进了一家古董店,它很想买其中的一幅画.但它带的钱不够买这幅画. 幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它. 老板有一个n*m的矩阵,他想 ...

  10. 22、BlockManager原理剖析与源码分析

    一.原理 1.图解 Driver上,有BlockManagerMaster,它的功能,就是负责对各个节点上的BlockManager内部管理的数据的元数据进行维护, 比如Block的增删改等操作,都会 ...