在今天的数字化世界中,数据交换是互联网和软件应用程序中不可或缺的一部分。为了在不同系统之间传输数据,我们通常会使用各种数据交换格式。在本文中,我们将重点介绍两种常见的数据交换格式:JSON 和 Hessian。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它易于人类阅读和编写,同时也易于机器解析和生成。JSON采用键/值对的形式组织数据,数据之间使用逗号分隔,而键和值之间使用冒号分隔。这种简洁的结构使得JSON非常适用于前端与后端之间的数据交换,也被广泛应用于Web开发和API设计中。
与JSON不同,Hessian 是一种二进制数据交换格式,它旨在提高数据传输的效率和性能。Hessian采用紧凑的二进制表示形式,相比于文本格式如JSON,它在网络传输时占用的带宽更少。这使得Hessian特别适用于对网络带宽和速度要求较高的场景,比如移动应用程序开发和分布式系统通信中。
虽然JSON和Hessian都是数据交换格式,但它们在很多方面有着显著的区别。下面我们将比较这两种格式的特点,以便更好地理解它们各自的优势和适用场景。
随着互联网和移动应用的快速发展,JSON和Hessian已经在许多领域找到了广泛的应用。以下是它们常见的应用场景:
JSON和Hessian作为不同类型的数据交换格式,各有其优势和适用范围。在实际开发中,我们应根据具体的应用场景和需求选择合适的数据交换格式,以确保数据传输的高效性和可靠性。希望通过本文的介绍,您能更好地了解JSON和Hessian,并在相关项目中做出明智的选择。
在当今数字化时代,不同的数据传输格式扮演着至关重要的角色。其中,hessian 和 json 是两种常用的数据传输协议,它们分别具有各自的特点和优势。
Hessian 是一种基于二进制协议的数据传输格式,旨在实现快速且高效的数据交换。它使用了基于二进制的数据编码方式,在数据传输时能够更加节省带宽和提高传输效率。因此,hessian 在一些对性能要求较高的应用场景中备受青睐。
相比于一些文本协议,hessian 具有更快的传输速度和更小的数据包大小。这意味着在网络传输过程中,hessian 可以减少延迟,并缩短数据传输的时间。另外,hessian 对于不同编程语言的兼容性也相对较好,使得不同系统间的数据交换更加便捷。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有易读性和便于理解的特点。它基于文本,采用键值对的方式组织数据,在前后端数据交互中被广泛应用。
由于其简洁明了的结构和跨语言的特性,json 在 Web 开发中被广泛采用。无论是用于前端页面与后端服务器之间的数据传输,还是作为配置文件的存储格式,json 都展现出了其强大的应用价值。
虽然 hessian 和 json 都是用于数据传输的格式,但它们在一些方面存在明显的差异。 hessian 更加注重于性能和效率,适合于对速度有较高要求的系统。而 json 则更注重于易读性和通用性,适合于需要跨语言交互的场景。
在实际应用中,开发者需要根据项目需求和具体场景来选择合适的数据传输格式。如果注重性能和效率,可以考虑使用 hessian;而如果更看重易用性和通用性,json 可能更为适合。
在当前信息交互日益频繁的环境下,选择合适的数据传输格式显得尤为重要。Hessian 和 JSON 作为两种常用的数据传输协议,在不同的场景下各具优势,开发者可以根据项目的具体需求来灵活选择,以实现最佳的数据交换效果。
hessian和dubbo的二者主要区别是协议不同
dubbo协议 Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。 连接个数:单连接连接方式:长连接传输协议:TCP 传输方式:NIO异步传输序列化:Hessian二进制序列化适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。适用场景:常规远程服务方法调用 为什么要消费者比提供者个数多: 因dubbo协议采用单一长连接, 假设网络为千兆网卡(1024Mbit=128MByte), 根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考), 理论上1个服务提供者需要20个服务消费者才能压满网卡。 为什么不能传大包: 因dubbo协议采用单一长连接, 如果每次请求的数据包大小为500KByte,假设网络为千兆网卡(1024Mbit=128MByte),每条连接最大7MByte(不同的环境可能不一样,供参考), 单个服务提供者的TPS(每秒处理事务数)最大为:128MByte/ 500KByte = 262。单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为:7MByte/ 500KByte = 14。如果能接受,可以考虑使用,否则网络将成为瓶颈。 为什么采用异步单一长连接: 因为服务的现状大都是服务提供者少,通常只有几台机器, 而服务的消费者多,可能整个网站都在访问该服务, 比如Morgan的提供者只有6台提供者,却有上百台消费者,每天有1.5亿次调用, 如果采用常规的hessian服务,服务提供者很容易就被压跨, 通过单一连接,保证单一消费者不会压死提供者, 长连接,减少连接握手验证等, 并使用异步IO,复用线程池,防止C10K问题。
2.
RMI RMI协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式 Java标准的远程调用协议。 连接个数:多连接连接方式:短连接传输协议:TCP 传输方式:同步传输序列化:Java标准二进制序列化适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。适用场景:常规远程服务方法调用,与原生RMI服务互操作
3.
hessian Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现 基于Hessian的远程调用协议。 连接个数:多连接连接方式:短连接传输协议:HTTP 传输方式:同步传输序列化:Hessian二进制序列化适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。适用场景:页面传输,文件传输,或与原生hessian服务互操作
4.
http 采用Spring的HttpInvoker实现 基于http表单的远程调用协议
设 A 是n阶方阵,如果存在数m和非零n维列向量 x,使得 Ax=mx 成立,则称 m 是A的一个特征值(characteristic value)或本征值(eigenvalue)。非零n维列向量x称为矩阵A的属于(对应于)特征值m的特征向量或本征向量,简称A的特征向量或A的本征向量。
Hessian矩阵的特征值就是形容其在该点附近特征向量方向的凹凸性,特征值越大,凸性越强。你可以把函数想想成一个小山坡,陡的那面是特征值大的方向,平缓的是特征值小的方向。而凸性和优化方法的收敛速度有关,比如梯度下降。如果正定Hessian矩阵的特征值都差不多,那么梯度下降的收敛速度越快,反之如果其特征值相差很大,那么收敛速度越慢
Hessian和Dubbo都是用于分布式系统中的远程调用框架,但它们的实现方式有所不同。Hessian是一种基于HTTP协议的轻量级RPC框架,使用Java语言开发,支持多种编程语言间的远程调用。Hessian的特点包括:
1. 简单易用:Hessian可以直接将Java对象序列化成二进制数据传输到服务器端,从而实现远程方法调用。这使得开发者无需手动编写序列化和反序列化代码,从而大大简化了分布式系统的开发难度。
2. 高效性:Hessian采用二进制数据传输格式,并对传输数据进行了压缩处理,因此可以提供较高的网络传输性能。
3. 跨语言支持:Hessian不仅支持Java语言开发,还可以与其他编程语言进行交互,例如C++, C#, Python等。
Dubbo是一个面向服务治理的RPC框架,同时也支持通信协议的扩展。Dubbo在Hessian的基础上做了许多扩展和优化,并引入了插件机制、服务治理、负载均衡、集群容错等关键功能。Dubbo针对企业级应用场景设计而成,并且已经有着广泛的应用基础。
Dubbo的特点包括:
1. 高性能:Dubbo采用Netty作为通信模块,使用NIO异步处理网络请求,因此可以提供高并发、低延迟的服务。
2. 配置灵活:Dubbo允许开发者通过XML或注解配置服务提供者和消费者的相关参数,同时还可以基于ZooKeeper等中间件进行集群管理和服务治理。
3. 丰富功能:Dubbo提供了丰富的功能支持,包括负载均衡、集群容错、服务路由等,可以应对不同场景下的应用需求。
总之,Hessian和Dubbo都是优秀的远程调用框架,具有各自独特的特点和优势,在实际项目中需要根据具体业务需求进行选择。
区别:
dubbo 默认协议:
单一 TCP 长连接,Hessian 二进制序列化和 NIO 异步通讯
适合于小数据包大并发的服务调用和服务消费者数远大于服务提供者数的情况
不适合传送大数据包的服务
hessian 协议:
底层 Http 通讯,Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现
可与原生 Hessian 服务互操作
通讯效率高于 WebService 和 Java 自带的序列化
参数及返回值需实现 Serializable 接口,自定义实现 List、Map、Number、Date、Calendar 等接口
适用于传输数据包较大,提供者比消费者个数多,提供者压力较大。
dubbo 默认协议:
单一 TCP 长连接,Hessian 二进制序列化和 NIO 异步通讯
适合于小数据包大并发的服务调用和服务消费者数远大于服务提供者数的情况
不适合传送大数据包的服务
hessian 协议:
底层 Http 通讯,Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现
可与原生 Hessian 服务互操作
通讯效率高于 WebService 和 Java 自带的序列化
参数及返回值需实现 Serializable 接口,自定义实现 List、Map、Number、Date、Calendar 等接口
适用于传输数据包较大,提供者比消费者个数多,提供者压力较大。
设 A 是n阶方阵,如果存在数m和非零n维列向量 x,使得 Ax=mx 成立,则称 m 是A的一个特征值(characteristic value)或本征值(eigenvalue)。
非零n维列向量x称为矩阵A的属于(对应于)特征值m的特征向量或本征向量,简称A的特征向量或A的本征向量。 Hessian矩阵的特征值就是形容其在该点附近特征向量方向的凹凸性,特征值越大,凸性越强。
你可以把函数想想成一个小山坡,陡的那面是特征值大的方向,平缓的是特征值小的方向。
而凸性和优化方法的收敛速度有关,比如梯度下降。
如果正定Hessian矩阵的特征值都差不多,那么梯度下降的收敛速度越快,反之如果其特征值相差很大,那么收敛速度越慢。
关于这个问题,Hessian协议和HTTP协议的主要区别在于它们的用途和性能。
Hessian协议是一种二进制协议,旨在为Java对象提供高效的远程调用服务。它使用了Java序列化技术,可以快速地序列化和反序列化Java对象,因此在处理大量对象时效率很高。Hessian协议不需要HTTP协议的额外的请求头和响应头,因此可以减少网络传输的开销。
HTTP协议则是一种基于文本的协议,它主要用于Web应用程序之间的通信。HTTP协议的优势在于它的通用性和可扩展性。它可以通过添加自定义的请求头和响应头来扩展功能,而且可以使用各种不同的传输协议(如TCP/IP、SSL等)来保证数据传输的安全性和可靠性。
总的来说,Hessian协议适用于需要高效的远程调用服务的场景,而HTTP协议则适用于Web应用程序之间的通信和扩展。
之前看了Mahout官方示例 20news 的调用实现;于是想根据示例的流程实现其他例子。网上看到了一个关于天气适不适合打羽毛球的例子。
训练数据:
Day Outlook Temperature Humidity Wind PlayTennis
D1 Sunny Hot High Weak No
D2 Sunny Hot High Strong No
D3 Overcast Hot High Weak Yes
D4 Rain Mild High Weak Yes
D5 Rain Cool Normal Weak Yes
D6 Rain Cool Normal Strong No
D7 Overcast Cool Normal Strong Yes
D8 Sunny Mild High Weak No
D9 Sunny Cool Normal Weak Yes
D10 Rain Mild Normal Weak Yes
D11 Sunny Mild Normal Strong Yes
D12 Overcast Mild High Strong Yes
D13 Overcast Hot Normal Weak Yes
D14 Rain Mild High Strong No
检测数据:
sunny,hot,high,weak
结果:
Yes=》 0.007039
No=》 0.027418
于是使用Java代码调用Mahout的工具类实现分类。
基本思想:
1. 构造分类数据。
2. 使用Mahout工具类进行训练,得到训练模型。
3。将要检测数据转换成vector数据。
4. 分类器对vector数据进行分类。
接下来贴下我的代码实现=》
1. 构造分类数据:
在hdfs主要创建一个文件夹路径 /zhoujainfeng/playtennis/input 并将分类文件夹 no 和 yes 的数据传到hdfs上面。
数据文件格式,如D1文件内容: Sunny Hot High Weak
2. 使用Mahout工具类进行训练,得到训练模型。
3。将要检测数据转换成vector数据。
4. 分类器对vector数据进行分类。
这三步,代码我就一次全贴出来;主要是两个类 PlayTennis1 和 BayesCheckData = =》
package myTesting.bayes;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.ToolRunner;
import org.apache.mahout.classifier.naivebayes.training.TrainNaiveBayesJob;
import org.apache.mahout.text.SequenceFilesFromDirectory;
import org.apache.mahout.vectorizer.SparseVectorsFromSequenceFiles;
public class PlayTennis1 {
private static final String WORK_DIR = "hdfs://192.168.9.72:9000/zhoujianfeng/playtennis";
/*
* 测试代码
*/
public static void main(String[] args) {
//将训练数据转换成 vector数据
makeTrainVector();
//产生训练模型
makeModel(false);
//测试检测数据
BayesCheckData.printResult();
}
public static void makeCheckVector(){
//将测试数据转换成序列化文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"testinput";
String output = WORK_DIR+Path.SEPARATOR+"tennis-test-seq";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean参数是,是否递归删除的意思
fs.delete(out, true);
}
SequenceFilesFromDirectory sffd = new SequenceFilesFromDirectory();
String[] params = new String[]{"-i",input,"-o",output,"-ow"};
ToolRunner.run(sffd, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件序列化失败!");
System.exit(1);
}
//将序列化文件转换成向量文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-test-seq";
String output = WORK_DIR+Path.SEPARATOR+"tennis-test-vectors";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean参数是,是否递归删除的意思
fs.delete(out, true);
}
SparseVectorsFromSequenceFiles svfsf = new SparseVectorsFromSequenceFiles();
String[] params = new String[]{"-i",input,"-o",output,"-lnorm","-nv","-wt","tfidf"};
ToolRunner.run(svfsf, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("序列化文件转换成向量失败!");
System.out.println(2);
}
}
public static void makeTrainVector(){
//将测试数据转换成序列化文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"input";
String output = WORK_DIR+Path.SEPARATOR+"tennis-seq";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean参数是,是否递归删除的意思
fs.delete(out, true);
}
SequenceFilesFromDirectory sffd = new SequenceFilesFromDirectory();
String[] params = new String[]{"-i",input,"-o",output,"-ow"};
ToolRunner.run(sffd, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件序列化失败!");
System.exit(1);
}
//将序列化文件转换成向量文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-seq";
String output = WORK_DIR+Path.SEPARATOR+"tennis-vectors";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean参数是,是否递归删除的意思
fs.delete(out, true);
}
SparseVectorsFromSequenceFiles svfsf = new SparseVectorsFromSequenceFiles();
String[] params = new String[]{"-i",input,"-o",output,"-lnorm","-nv","-wt","tfidf"};
ToolRunner.run(svfsf, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("序列化文件转换成向量失败!");
System.out.println(2);
}
}
public static void makeModel(boolean completelyNB){
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-vectors"+Path.SEPARATOR+"tfidf-vectors";
String model = WORK_DIR+Path.SEPARATOR+"model";
String labelindex = WORK_DIR+Path.SEPARATOR+"labelindex";
Path in = new Path(input);
Path out = new Path(model);
Path label = new Path(labelindex);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean参数是,是否递归删除的意思
fs.delete(out, true);
}
if(fs.exists(label)){
//boolean参数是,是否递归删除的意思
fs.delete(label, true);
}
TrainNaiveBayesJob tnbj = new TrainNaiveBayesJob();
String[] params =null;
if(completelyNB){
params = new String[]{"-i",input,"-el","-o",model,"-li",labelindex,"-ow","-c"};
}else{
params = new String[]{"-i",input,"-el","-o",model,"-li",labelindex,"-ow"};
}
ToolRunner.run(tnbj, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("生成训练模型失败!");
System.exit(3);
}
}
}
package myTesting.bayes;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.mahout.classifier.naivebayes.BayesUtils;
import org.apache.mahout.classifier.naivebayes.NaiveBayesModel;
import org.apache.mahout.classifier.naivebayes.StandardNaiveBayesClassifier;
import org.apache.mahout.common.Pair;
import org.apache.mahout.common.iterator.sequencefile.PathType;
import org.apache.mahout.common.iterator.sequencefile.SequenceFileDirIterable;
import org.apache.mahout.math.RandomAccessSparseVector;
import org.apache.mahout.math.Vector;
import org.apache.mahout.math.Vector.Element;
import org.apache.mahout.vectorizer.TFIDF;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Multiset;
public class BayesCheckData {
private static StandardNaiveBayesClassifier classifier;
private static Map<String, Integer> dictionary;
private static Map<Integer, Long> documentFrequency;
private static Map<Integer, String> labelIndex;
public void init(Configuration conf){
try {
String modelPath = "/zhoujianfeng/playtennis/model";
String dictionaryPath = "/zhoujianfeng/playtennis/tennis-vectors/dictionary.file-0";
String documentFrequencyPath = "/zhoujianfeng/playtennis/tennis-vectors/df-count";
String labelIndexPath = "/zhoujianfeng/playtennis/labelindex";
dictionary = readDictionnary(conf, new Path(dictionaryPath));
documentFrequency = readDocumentFrequency(conf, new Path(documentFrequencyPath));
labelIndex = BayesUtils.readLabelIndex(conf, new Path(labelIndexPath));
NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), conf);
classifier = new StandardNaiveBayesClassifier(model);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("检测数据构造成vectors初始化时报错。。。。");
System.exit(4);
}
}
/**
* 加载字典文件,Key: TermValue; Value:TermID
* @param conf
* @param dictionnaryDir
* @return
*/
private static Map<String, Integer> readDictionnary(Configuration conf, Path dictionnaryDir) {
Map<String, Integer> dictionnary = new HashMap<String, Integer>();
PathFilter filter = new PathFilter() {
@Override
public boolean accept(Path path) {
String name = path.getName();
return name.startsWith("dictionary.file");
}
};
for (Pair<Text, IntWritable> pair : new SequenceFileDirIterable<Text, IntWritable>(dictionnaryDir, PathType.LIST, filter, conf)) {
dictionnary.put(pair.getFirst().toString(), pair.getSecond().get());
}
return dictionnary;
}
/**
* 加载df-count目录下TermDoc频率文件,Key: TermID; Value:DocFreq
* @param conf
* @param dictionnaryDir
* @return
*/
private static Map<Integer, Long> readDocumentFrequency(Configuration conf, Path documentFrequencyDir) {
Map<Integer, Long> documentFrequency = new HashMap<Integer, Long>();
PathFilter filter = new PathFilter() {
@Override
public boolean accept(Path path) {
return path.getName().startsWith("part-r");
}
};
for (Pair<IntWritable, LongWritable> pair : new SequenceFileDirIterable<IntWritable, LongWritable>(documentFrequencyDir, PathType.LIST, filter, conf)) {
documentFrequency.put(pair.getFirst().get(), pair.getSecond().get());
}
return documentFrequency;
}
public static String getCheckResult(){
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String classify = "NaN";
BayesCheckData cdv = new BayesCheckData();
cdv.init(conf);
System.out.println("init done...............");
Vector vector = new RandomAccessSparseVector(10000);
TFIDF tfidf = new TFIDF();
//sunny,hot,high,weak
Multiset<String> words = ConcurrentHashMultiset.create();
words.add("sunny",1);
words.add("hot",1);
words.add("high",1);
words.add("weak",1);
int documentCount = documentFrequency.get(-1).intValue(); // key=-1时表示总文档数
for (Multiset.Entry<String> entry : words.entrySet()) {
String word = entry.getElement();
int count = entry.getCount();
Integer wordId = dictionary.get(word); // 需要从dictionary.file-0文件(tf-vector)下得到wordID,
if (StringUtils.isEmpty(wordId.toString())){
continue;
}
if (documentFrequency.get(wordId) == null){
continue;
}
Long freq = documentFrequency.get(wordId);
double tfIdfValue = tfidf.calculate(count, freq.intValue(), 1, documentCount);
vector.setQuick(wordId, tfIdfValue);
}
// 利用贝叶斯算法开始分类,并提取得分最好的分类label
Vector resultVector = classifier.classifyFull(vector);
double bestScore = -Double.MAX_VALUE;
int bestCategoryId = -1;
for(Element element: resultVector.all()) {
int categoryId = element.index();
double score = element.get();
System.out.println("categoryId:"+categoryId+" score:"+score);
if (score > bestScore) {
bestScore = score;
bestCategoryId = categoryId;
}
}
classify = labelIndex.get(bestCategoryId)+"(categoryId="+bestCategoryId+")";
return classify;
}
public static void printResult(){
System.out.println("检测所属类别是:"+getCheckResult());
}
}