设为首页 收藏本站
查看: 564|回复: 0

[经验分享] 学习Hadoop之基于protocol buffers的RPC

[复制链接]

尚未签到

发表于 2015-7-14 07:07:50 | 显示全部楼层 |阅读模式
原文链接:http://standalone.iteye.com/blog/1727544

现在版本的hadoop各种server、client RPC端通信协议的实现是基于google的protocol buffers的,如果对这个不熟悉,读code的时候会比较痛苦一些,所以花了些时间学习了一下,然后仿照写了个比较简单的例子,麻雀虽小,五脏俱全,看懂了我这个或许对你读hadoop的code有帮助! :)
我现在实现一个简单的server-client方式的calculator,client将计算请求序列化成protocol buffers形式然后发给server端,server端反序列化后将完成计算然后将结果序列化后返回给client端。
先看一下最后整体的package结构(模仿hadoop的包命名,便于比较)
package org.tao.pbtest.api:
org.tao.pbtest.api.Calculator
org.tao.pbtest.api.CalculatorPB
org.tao.pbtest.api.CalculatorPBServiceImpl
package org.tao.pbtest.server.business
org.tao.pbtest.server.business.CalculatorService
package org.tao.pbtest.ipc
org.tao.pbtest.ipc.Server
package org.tao.pbtest.proto
org.tao.pbtest.proto.Calculator
org.tao.pbtest.proto.CalculatorMsg
package org.tao.pbtest.proto.test
org.tao.pbtest.proto.test.TestCalculator


  • step 1:


首先看一下Calculator这个接口:





Java代码 DSC0000.gif DSC0001.png DSC0002.gif

  • package org.tao.pbtest.api;   
  •   
  • public interface Calculator {   
  •    public int add(int a, int b);   
  •    public int minus(int a, int b);   
  • }  

package org.tao.pbtest.api;
public interface Calculator {
public int add(int a, int b);
public int minus(int a, int b);
}


这个计算器就进行简单的两种运算,两个整数的加减。


  • step 2:

然后定义两个proto文件:CalculatorMsg.proto和Calculator.proto。
第一个是运算的参数消息、返回结果消息,输入时两个整数,返回结果是一个整数。具体protocol buffers的语法此处不做解释了,可以参看google的文档。






Java代码

  • option java_package = "org.tao.pbtest.proto";   
  • option java_outer_classname = "CalculatorMsg";   
  • option java_generic_service = true;   
  • option java_generate_equals_and_hash = true;   
  •   
  • message RequestProto {   
  •    required string methodName = 1;   
  •    required int32 num1 = 2;   
  •    required int32 num2 = 3;   
  • }   
  •   
  • message ResponseProto {   
  •    required int32 result = 1;   
  • }  

option java_package = "org.tao.pbtest.proto";
option java_outer_classname = "CalculatorMsg";
option java_generic_service = true;
option java_generate_equals_and_hash = true;
message RequestProto {
required string methodName = 1;
required int32 num1 = 2;
required int32 num2 = 3;
}
message ResponseProto {
required int32 result = 1;
}


第二个proto文件定义service:





Java代码

  • option java_package = "org.tao.pbtest.proto";   
  • option java_outer_classname = "Calculator";   
  • option java_generic_service = true;   
  • option java_generate_equals_and_hash = true;   
  •   
  • import "CalculatorMsg.proto"  
  •   
  • service CalculatorService {   
  •    rpc add(RequestProto) returns (ResponseProto);   
  •    rpc minus(RequestProto) returns (ResponseProto);   
  • }  

option java_package = "org.tao.pbtest.proto";
option java_outer_classname = "Calculator";
option java_generic_service = true;
option java_generate_equals_and_hash = true;
import "CalculatorMsg.proto"
service CalculatorService {
rpc add(RequestProto) returns (ResponseProto);
rpc minus(RequestProto) returns (ResponseProto);
}


然后用protoc将此两个文件编译,生成两个java文件:
org.tao.pbtest.proto.Calculator
org.tao.pbtest.proto.CalculatorMsg


  • step 3:

然后定义一个CalculatorPB接口extends刚才生成的org.tao.pbtest.proto.Calculator.CalculatorService.BlockingInterface, 这是一个过渡作用的接口。






Java代码

  • package org.tao.pbtest.server.api;   
  •   
  • import org.tao.pbtest.proto.Calculator.CalculatorService.BlockingService;   
  •   
  • public interface CalculatorPB extends BlockingInterface {   
  • }  

package org.tao.pbtest.server.api;
import org.tao.pbtest.proto.Calculator.CalculatorService.BlockingService;
public interface CalculatorPB extends BlockingInterface {
}




  • step 4:

还需要一个发送、接受信息的ipc server/client端。这里偷懒只实现一个最最简单的server端,什么并发啊,异常处理啊,nio啊统统不考虑,因为这不是重点。






Java代码

  • package org.tao.pbtest.ipc;   
  •   
  • import java.io.DataInputStream;   
  • import java.io.DataOutputStream;   
  • import java.io.IOException;   
  • import java.net.*;   
  • import com.google.protobuf.*;   
  • import com.google.protobuf.Descriptors.MethodDescriptor;   
  • import com.tao.pbtest.proto.CalculatorMsg.RequestProto;   
  • import com.tao.pbtest.proto.CalculatorMsg.ResponseProto;   
  •   
  • public class Server extends Thread {   
  •    private Class protocol;   
  •    private BlockingService impl;   
  •    private int port;   
  •    private ServerSocket ss;   
  •   
  •    public Server(Class protocol, BlockingService protocolImpl, int port){   
  •       this.protocol = protocol;   
  •       this.impl = protocolImpl;   
  •       this.port = port;   
  •    }   
  •   
  •    public void run(){   
  •       Socket clientSocket = null;   
  •       DataOutputStream dos = null;   
  •       DataInputStream dis = null;   
  •       try {   
  •            ss = new ServerSocket(port);   
  •        }catch(IOException e){   
  •        }      
  •        int testCount = 10; //进行10次计算后就退出   
  •   
  •        while(testCount-- > 0){   
  •           try {   
  •                clientSocket = ss.accept();   
  •                dos = new DataOutputStream(clientSocket.getOutputStream());   
  •                dis = new DataInputStream(clientSocket.getInputStream());   
  •                int dataLen = dis.readInt();   
  •                byte[] dataBuffer = new byte[dataLen];   
  •                byte[] result = processOneRpc(dataBuffer);   
  •                dos.writeInt(result.length);   
  •                dos.write(result);   
  •                dos.flush();   
  •            }catch(Exception e){   
  •            }   
  •        }   
  •        try {   
  •            dos.close();   
  •            dis.close();   
  •            ss.close();   
  •        }catch(Exception e){   
  •        };   
  •   
  •    }   
  •   
  •    public byte[] processOneRpc (byte[] data) throws Exception {   
  •       RequestProto request = RequestProto.parseFrom(data);   
  •       String methodName = request.getMethodName();   
  •       MethodDescriptor methodDescriptor = impl.getDescriptorForType().findMethodByName(methodName);   
  •       Message response = impl.callBlockingMethod(methodDescriptor, null, request);   
  •       return response.toByteArray();   
  •    }   
  • }  

package org.tao.pbtest.ipc;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import com.google.protobuf.*;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.tao.pbtest.proto.CalculatorMsg.RequestProto;
import com.tao.pbtest.proto.CalculatorMsg.ResponseProto;
public class Server extends Thread {
private Class protocol;
private BlockingService impl;
private int port;
private ServerSocket ss;
public Server(Class protocol, BlockingService protocolImpl, int port){
this.protocol = protocol;
this.impl = protocolImpl;
this.port = port;
}
public void run(){
Socket clientSocket = null;
DataOutputStream dos = null;
DataInputStream dis = null;
try {
ss = new ServerSocket(port);
}catch(IOException e){
}   
int testCount = 10; //进行10次计算后就退出
while(testCount-- > 0){
try {
clientSocket = ss.accept();
dos = new DataOutputStream(clientSocket.getOutputStream());
dis = new DataInputStream(clientSocket.getInputStream());
int dataLen = dis.readInt();
byte[] dataBuffer = new byte[dataLen];
byte[] result = processOneRpc(dataBuffer);
dos.writeInt(result.length);
dos.write(result);
dos.flush();
}catch(Exception e){
}
}
try {
dos.close();
dis.close();
ss.close();
}catch(Exception e){
};
}
public byte[] processOneRpc (byte[] data) throws Exception {
RequestProto request = RequestProto.parseFrom(data);
String methodName = request.getMethodName();
MethodDescriptor methodDescriptor = impl.getDescriptorForType().findMethodByName(methodName);
Message response = impl.callBlockingMethod(methodDescriptor, null, request);
return response.toByteArray();
}
}

   


  • step 5:

CalculatorServer.java,实现计算器服务的类,此类依赖ipc Server接受请求并处理计算请求,注意到其自身实现了Calculator接口,本质上的计算是由其来完成的。也就是,Server接受客户端请求要执行方法M,Server对象里有实现了CalculatorPB接口的对象A,那么请求就交给A处理(A其实是CalculatorPBServiceImpl类的对象,此类后面介绍),此时A对应的M方法的参数是pb的形式,另外A对象里其实包含对CalculatorService的一个引用,所以在A的M方法里,先对参数反序列化,然后将参数交给CalculatorService处理。






Java代码

  • package org.tao.pbtest.server.business;   
  •   
  • import java.lang.reflect.Constructor;   
  • import java.lang.reflect.InvocationTargetException;   
  • import java.lang.reflect.Method;   
  •   
  • import org.tao.pbtest.ipc.Server;   
  • import org.tao.pbtest.server.api.Calculator;   
  •   
  • import com.google.protobuf.BlockingService;   
  •   
  • public class CalculatorService implements Calculator {      
  •       
  •     private Server server = null;   
  •     private final Class protocol = Calculator.class;   
  •     private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();   
  •     private final String protoPackage = "org.tao.pbtest.proto";   
  •     private final String host = "localhost";   
  •     private final int port = 8038;   
  •       
  •     public CalculatorService (){   
  •            
  •     }   
  •       
  •     @Override  
  •     public int add(int a, int b) {   
  •         // TODO Auto-generated method stub   
  •         return a+b;   
  •     }   
  •   
  •     public int minus(int a, int b){   
  •         return a-b;   
  •     }   
  •       
  •       
  •     public void init(){   
  •         createServer();           
  •     }   
  •       
  •       
  •     /*
  •      * return org.tao.pbtest.server.api.CalculatorPBServiceImpl  
  •      */  
  •     public Class getPbServiceImplClass(){   
  •         String packageName = protocol.getPackage().getName();   
  •         String className = protocol.getSimpleName();   
  •         String pbServiceImplName =  packageName + "." + className +  "PBServiceImpl";           
  •         Class clazz = null;   
  •         try{   
  •             clazz = Class.forName(pbServiceImplName, true, classLoader);   
  •         }catch(ClassNotFoundException e){   
  •             System.err.println(e.toString());   
  •         }   
  •         return clazz;   
  •     }   
  •       
  •     /*
  •      * return org.tao.pbtest.proto.Calculator$CalculatorService  
  •      */  
  •     public Class getProtoClass(){   
  •         String className = protocol.getSimpleName();   
  •         String protoClazzName =  protoPackage + "." + className + "$" + className + "Service";   
  •         Class clazz = null;   
  •         try{   
  •             clazz = Class.forName(protoClazzName, true, classLoader);   
  •         }catch(ClassNotFoundException e){   
  •             System.err.println(e.toString());   
  •         }   
  •         return clazz;   
  •     }   
  •       
  •     public void createServer(){   
  •         Class pbServiceImpl = getPbServiceImplClass();   
  •         Constructor constructor = null;   
  •         try{   
  •             constructor = pbServiceImpl.getConstructor(protocol);   
  •             constructor.setAccessible(true);   
  •         }catch(NoSuchMethodException e){   
  •             System.err.print(e.toString());   
  •         }   
  •            
  •         Object service = null;  // instance of CalculatorPBServiceImpl   
  •         try {   
  •             service = constructor.newInstance(this);   
  •         }catch(InstantiationException e){   
  •         } catch (IllegalArgumentException e) {   
  •         } catch (IllegalAccessException e) {   
  •         } catch (InvocationTargetException e) {   
  •         }   
  •            
  •         /*
  •          * interface: org.tao.pbtest.server.CalculatorPB  
  •          */  
  •         Class pbProtocol = service.getClass().getInterfaces()[0];   
  •                   
  •         /*
  •          * class: org.tao.pbtest.proto.Calculator$CalculatorService  
  •          */  
  •         Class protoClazz = getProtoClass();   
  •            
  •         Method method = null;   
  •         try {   
  •   
  •             // pbProtocol.getInterfaces()[] 即是接口 org.tao.pbtest.proto.Calculator$CalculatorService$BlockingInterface   
  •   
  •             method = protoClazz.getMethod("newReflectiveBlockingService", pbProtocol.getInterfaces()[0]);   
  •             method.setAccessible(true);   
  •         }catch(NoSuchMethodException e){   
  •             System.err.print(e.toString());   
  •         }   
  •            
  •         try{   
  •             createServer(pbProtocol, (BlockingService)method.invoke(null, service));   
  •         }catch(InvocationTargetException e){   
  •         } catch (IllegalArgumentException e) {   
  •         } catch (IllegalAccessException e) {   
  •         }   
  •            
  •     }   
  •       
  •     public void createServer(Class pbProtocol, BlockingService service){   
  •         server = new Server(pbProtocol, service, port);   
  •         server.start();   
  •     }   
  •       
  •     public static void main(String[] args){   
  •         CalculatorService cs = new CalculatorService();   
  •         cs.init();   
  •     }   
  • }  

package org.tao.pbtest.server.business;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.tao.pbtest.ipc.Server;
import org.tao.pbtest.server.api.Calculator;
import com.google.protobuf.BlockingService;
public class CalculatorService implements Calculator {   
private Server server = null;
private final Class protocol = Calculator.class;
private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
private final String protoPackage = "org.tao.pbtest.proto";
private final String host = "localhost";
private final int port = 8038;
public CalculatorService (){
}
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return a+b;
}
public int minus(int a, int b){
return a-b;
}

public void init(){
createServer();        
}

/*
* return org.tao.pbtest.server.api.CalculatorPBServiceImpl
*/
public Class getPbServiceImplClass(){
String packageName = protocol.getPackage().getName();
String className = protocol.getSimpleName();
String pbServiceImplName =  packageName + "." + className +  "PBServiceImpl";        
Class clazz = null;
try{
clazz = Class.forName(pbServiceImplName, true, classLoader);
}catch(ClassNotFoundException e){
System.err.println(e.toString());
}
return clazz;
}
/*
* return org.tao.pbtest.proto.Calculator$CalculatorService
*/
public Class getProtoClass(){
String className = protocol.getSimpleName();
String protoClazzName =  protoPackage + "." + className + "$" + className + "Service";
Class clazz = null;
try{
clazz = Class.forName(protoClazzName, true, classLoader);
}catch(ClassNotFoundException e){
System.err.println(e.toString());
}
return clazz;
}
public void createServer(){
Class pbServiceImpl = getPbServiceImplClass();
Constructor constructor = null;
try{
constructor = pbServiceImpl.getConstructor(protocol);
constructor.setAccessible(true);
}catch(NoSuchMethodException e){
System.err.print(e.toString());
}
Object service = null;  // instance of CalculatorPBServiceImpl
try {
service = constructor.newInstance(this);
}catch(InstantiationException e){
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
/*
* interface: org.tao.pbtest.server.CalculatorPB
*/
Class pbProtocol = service.getClass().getInterfaces()[0];
/*
* class: org.tao.pbtest.proto.Calculator$CalculatorService
*/
Class protoClazz = getProtoClass();
Method method = null;
try {
// pbProtocol.getInterfaces()[] 即是接口 org.tao.pbtest.proto.Calculator$CalculatorService$BlockingInterface
method = protoClazz.getMethod("newReflectiveBlockingService", pbProtocol.getInterfaces()[0]);
method.setAccessible(true);
}catch(NoSuchMethodException e){
System.err.print(e.toString());
}
try{
createServer(pbProtocol, (BlockingService)method.invoke(null, service));
}catch(InvocationTargetException e){
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
}
public void createServer(Class pbProtocol, BlockingService service){
server = new Server(pbProtocol, service, port);
server.start();
}
public static void main(String[] args){
CalculatorService cs = new CalculatorService();
cs.init();
}
}




  • step 6:

刚才提到的PB格式跟最终实现的桥梁类:CalculatorPBServiceImpl






Java代码

  • package org.tao.pbtest.server.api;   
  •   
  • import org.tao.pbtest.proto.CalculatorMsg.RequestProto;   
  • import org.tao.pbtest.proto.CalculatorMsg.ResponseProto;   
  •   
  • import com.google.protobuf.RpcController;   
  • import com.google.protobuf.ServiceException;   
  •   
  • public class CalculatorPBServiceImpl implements CalculatorPB {   
  •   
  •     public Calculator real;   
  •       
  •     public CalculatorPBServiceImpl(Calculator impl){   
  •         this.real = impl;   
  •     }   
  •       
  •     @Override  
  •     public ResponseProto add(RpcController controller, RequestProto request) throws ServiceException {   
  •         // TODO Auto-generated method stub   
  •         ResponseProto proto = ResponseProto.getDefaultInstance();   
  •         ResponseProto.Builder build = ResponseProto.newBuilder();   
  •         int add1 = request.getNum1();   
  •         int add2 = request.getNum2();   
  •         int sum = real.add(add1, add2);   
  •         ResponseProto result = null;   
  •         build.setResult(sum);   
  •         result = build.build();   
  •         return result;   
  •     }   
  •   
  •     @Override  
  •     public ResponseProto minus(RpcController controller, RequestProto request) throws ServiceException {   
  •         // TODO Auto-generated method stub   
  •         ResponseProto proto = ResponseProto.getDefaultInstance();   
  •         ResponseProto.Builder build = ResponseProto.newBuilder();   
  •         int add1 = request.getNum1();   
  •         int add2 = request.getNum2();   
  •         int sum = real.minus(add1, add2);   
  •         ResponseProto result = null;   
  •         build.setResult(sum);   
  •         result = build.build();   
  •         return result;   
  •     }   
  •   
  • }  

package org.tao.pbtest.server.api;
import org.tao.pbtest.proto.CalculatorMsg.RequestProto;
import org.tao.pbtest.proto.CalculatorMsg.ResponseProto;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
public class CalculatorPBServiceImpl implements CalculatorPB {
public Calculator real;
public CalculatorPBServiceImpl(Calculator impl){
this.real = impl;
}
@Override
public ResponseProto add(RpcController controller, RequestProto request) throws ServiceException {
// TODO Auto-generated method stub
ResponseProto proto = ResponseProto.getDefaultInstance();
ResponseProto.Builder build = ResponseProto.newBuilder();
int add1 = request.getNum1();
int add2 = request.getNum2();
int sum = real.add(add1, add2);
ResponseProto result = null;
build.setResult(sum);
result = build.build();
return result;
}
@Override
public ResponseProto minus(RpcController controller, RequestProto request) throws ServiceException {
// TODO Auto-generated method stub
ResponseProto proto = ResponseProto.getDefaultInstance();
ResponseProto.Builder build = ResponseProto.newBuilder();
int add1 = request.getNum1();
int add2 = request.getNum2();
int sum = real.minus(add1, add2);
ResponseProto result = null;
build.setResult(sum);
result = build.build();
return result;
}
}




  • step 7:

最后,偷懒没写客户端的东西,只是写了一个简单的测试例子:





Java代码

  • package org.tao.pbtest.proto.test;   
  •   
  • import java.io.DataInputStream;   
  • import java.io.DataOutputStream;   
  • import java.io.IOException;   
  • import java.net.Socket;   
  • import java.util.Random;   
  •   
  • import org.tao.pbtest.proto.CalculatorMsg.RequestProto;   
  • import org.tao.pbtest.proto.CalculatorMsg.ResponseProto;   
  • import org.tao.pbtest.server.api.Calculator;   
  •   
  • public class TestCalculator implements Calculator {   
  •   
  •     public int doTest(String op, int a, int b){   
  •         // TODO Auto-generated method stub   
  •         Socket s = null;   
  •         DataOutputStream out = null;   
  •         DataInputStream in = null;   
  •         int ret = 0;   
  •         try {   
  •             s= new Socket("localhost", 8038);   
  •             out = new DataOutputStream(s.getOutputStream());   
  •             in = new DataInputStream(s.getInputStream());   
  •                
  •             RequestProto.Builder builder = RequestProto.newBuilder();   
  •             builder.setMethodName(op);   
  •             builder.setNum1(a);   
  •             builder.setNum2(b);   
  •             RequestProto request = builder.build();   
  •                
  •             byte [] bytes = request.toByteArray();   
  •             out.writeInt(bytes.length);   
  •             out.write(bytes);   
  •             out.flush();   
  •                
  •             int dataLen = in.readInt();   
  •             byte[] data = new byte[dataLen];   
  •             int count = in.read(data);   
  •             if(count != dataLen){   
  •                 System.err.println("something bad happened!");   
  •             }   
  •                
  •             ResponseProto result = ResponseProto.parseFrom(data);   
  •             System.out.println(a + " " + op + " " +  b + "=" + result.getResult());               
  •             ret =  result.getResult();   
  •                
  •         }catch(Exception e){   
  •             e.printStackTrace();   
  •             System.err.println(e.toString());   
  •         }finally {   
  •             try{   
  •             in.close();   
  •             out.close();   
  •             s.close();   
  •             }catch(IOException e){   
  •                 e.printStackTrace();   
  •             }   
  •         }   
  •         return ret;   
  •     }   
  •     @Override  
  •     public int add(int a, int b) {   
  •         // TODO Auto-generated method stub   
  •         return doTest("add", a, b);   
  •     }   
  •   
  •     @Override  
  •     public int minus(int a, int b) {   
  •         // TODO Auto-generated method stub   
  •         return doTest("minus", a, b);   
  •     }   
  •   
  •     /**
  •      * @param args  
  •      */  
  •     public static void main(String[] args) {   
  •         // TODO Auto-generated method stub   
  •         TestCalculator tc = new TestCalculator();   
  •         int testCount = 5;   
  •         Random rand = new Random();   
  •         while(testCount-- > 0){   
  •             int a = rand.nextInt(100);   
  •             int b = rand.nextInt(100);   
  •             tc.add(a,b);   
  •             tc.minus(a, b);   
  •         }           
  •            
  •     }   
  •   
  • }  

package org.tao.pbtest.proto.test;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Random;
import org.tao.pbtest.proto.CalculatorMsg.RequestProto;
import org.tao.pbtest.proto.CalculatorMsg.ResponseProto;
import org.tao.pbtest.server.api.Calculator;
public class TestCalculator implements Calculator {
public int doTest(String op, int a, int b){
// TODO Auto-generated method stub
Socket s = null;
DataOutputStream out = null;
DataInputStream in = null;
int ret = 0;
try {
s= new Socket("localhost", 8038);
out = new DataOutputStream(s.getOutputStream());
in = new DataInputStream(s.getInputStream());
RequestProto.Builder builder = RequestProto.newBuilder();
builder.setMethodName(op);
builder.setNum1(a);
builder.setNum2(b);
RequestProto request = builder.build();
byte [] bytes = request.toByteArray();
out.writeInt(bytes.length);
out.write(bytes);
out.flush();
int dataLen = in.readInt();
byte[] data = new byte[dataLen];
int count = in.read(data);
if(count != dataLen){
System.err.println("something bad happened!");
}
ResponseProto result = ResponseProto.parseFrom(data);
System.out.println(a + " " + op + " " +  b + "=" + result.getResult());            
ret =  result.getResult();
}catch(Exception e){
e.printStackTrace();
System.err.println(e.toString());
}finally {
try{
in.close();
out.close();
s.close();
}catch(IOException e){
e.printStackTrace();
}
}
return ret;
}
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return doTest("add", a, b);
}
@Override
public int minus(int a, int b) {
// TODO Auto-generated method stub
return doTest("minus", a, b);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestCalculator tc = new TestCalculator();
int testCount = 5;
Random rand = new Random();
while(testCount-- > 0){
int a = rand.nextInt(100);
int b = rand.nextInt(100);
tc.add(a,b);
tc.minus(a, b);
}        
}
}


输出:
76 add 14=90
76 minus 14=62
20 add 84=104
20 minus 84=-64
4 add 16=20
4 minus 16=-12
56 add 4=60
56 minus 4=52
46 add 50=96
46 minus 50=-4

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-86320-1-1.html 上篇帖子: Hadoop中文乱码 下篇帖子: [大牛翻译系列]Hadoop(20)附录A.10 压缩格式LZOP编译安装配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表