面试官不讲码德,欺负我一个年轻的开发工程师,问如果是你怎么设计RPC? RPC也不是很难啊,教你如何使用socket加动态代理与反射实现Rpc

先来解释解释一下rpc,首先很多人以为rpc是一种协议,其实这个就是出错误的,rpc:是远程过程调用;
看他的全程英文Remote Position Control 他其实是一种设计思想而已,解决分布式各个系统之间的调用关系。
我们今天就用socket方式实现一套rpc调用框架,不多说上代码

package rpc.socket;
//先定义一个clinet接口
public interface Clinet<T> {T  getService(Class<T> tClass);}

这是我个人写的一个实现类,给位大牛可以尝试实现
这里是采用动态代理。把调用大的过程交给代理对象,这样就可以屏蔽掉底层的网络和整个调用过程,
对于客服而言只用给一个接口的class对象,他会帮你去找到服务端实现类,实现远程调用

package rpc.socket;import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
import java.util.Properties;public class RpcClint implements Clinet {final static String  RPC_SERVER_HOST="RPC_SERVER_HOST";
final static String  RPC_SERVER_PORT="RPC_SERVER_PORT";@Overridepublic Object getService(Class aClass) {return Proxy.newProxyInstance(aClass.getClassLoader(), new Class[]{aClass}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//读取配置文件Properties properties = new Properties();InputStream resourceAsStream = aClass.getClassLoader().getResourceAsStream("rpc/RpcConfig.properties");properties.load(resourceAsStream);String host = properties.getProperty(RPC_SERVER_HOST);Integer port =new Integer((String) properties.get(RPC_SERVER_PORT));//RPC注册过程Socket socket = new Socket(host, port);OutputStream in= socket.getOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(in);//告诉服务端调用的是哪个类objectOutputStream.writeObject(aClass.getName());//告诉服务端调用的是哪个方法objectOutputStream.writeObject(method.getName());//告诉服务端调用方法传入的参数objectOutputStream.writeObject(args);//告诉服务端调用方法的参数类型objectOutputStream.writeObject(method.getParameterTypes());//完成序列化,刷新objectOutputStream.flush();//接受服务端响应结果ObjectInputStream  returnObj=new ObjectInputStream(socket.getInputStream());Object o = returnObj.readObject();//关闭流objectOutputStream.close();returnObj.close();resourceAsStream.close();socket.close();return o;}});}
}

这是服务端接口

package rpc.socket;import java.io.IOException;public interface Server {void Handler() throws IOException;
}

这是我实现的服务端rpc,就是采用一个nio接受客服端数据,然后去调用服务端的方法

package rpc.socket;import rpc.socket.service.GODService;
import rpc.socket.service.GODServiceImpl;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class RpcServer implements Server {//装用实现类的benastatic Map<String,Class> RESmap;//加载所有需要注册的额服务static {//这里可以用Aop 加注解的方式来把需要暴露的服务,注册到服务列表里面去RESmap=new ConcurrentHashMap<>();//把服务注册到注册表RESmap.put(GODService.class.getName(),GODServiceImpl.class);}@Overridepublic void Handler() throws IOException {ServerSocket serverSocket = new ServerSocket(8080);//采取传统的bio处理while (true){//等待客服端链接Socket accept = serverSocket.accept();new Thread(()->{try {//等待客户端输入ObjectInputStream in= new ObjectInputStream(accept.getInputStream());//获取客户端传过来的类名称String className = (String) in.readObject();//获取客户端客服端传过来的方法名称String methodName=(String) in.readObject();//获取客户端传过来的参数Object[] args = (Object[]) in.readObject();//获取客服的端传过来的参数类型Class[] argsType = (Class[]) in.readObject();//从注册表中获取服务的字节码Class aClass = RESmap.get(className);//通过字节码对象获取构造器Constructor constructor = aClass.getConstructor();constructor.setAccessible(true);//通过反射的方式创建对象并且执行对象的方法Object invoke = aClass.getMethod(methodName,argsType).invoke(constructor.newInstance(), args);//把返回结果写回给客户端ObjectOutputStream returnObject=new ObjectOutputStream(accept.getOutputStream());returnObject.writeObject(invoke);//关闭流in.close();returnObject.close();accept.close();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}).start();}}}

这里我们来建立一个服务端
首先定义一个接口

package rpc.socket.service;public interface GODService {String getGod(String lockMessage,String  offerings);
}

实现类

package rpc.socket.service;public class GODServiceImpl implements  GODService {@Overridepublic String getGod(String lockMessage, String  offerings) {System.out.println("的供品:"+ offerings);System.out.println("你的愿望:"+lockMessage);return "年轻人还是少做梦!";}
}

写一个服务端的启动类

package rpc.socket.demo;import rpc.socket.RpcServer;import java.io.IOException;public class ServiceStart {public static void main(String[] args) throws IOException {new RpcServer().Handler();}
}

然后是客服端去调用

package rpc.socket.demo;import rpc.socket.Clinet;
import rpc.socket.RpcClint;
import rpc.socket.service.GODService;public class clintDemo {public static void main(String[] args) {Clinet Clint = new RpcClint();GODService service = (GODService)Clint.getService(GODService.class);String lockReturn = service.getGod("请给让我中彩票吧", "献祭我老板的二十年寿命!");System.out.println(lockReturn);}
}

我们来看两遍的结果
客服端结果

我来看服务端结果


很显然调用成功了
现在我们来画图模拟一下调用过程
你学废了吗

面试官不讲码德,欺负我一个年轻的开发工程师相关推荐

  1. 浏览器渲染机制面试_面试官不讲码德,问我Chrome浏览器的渲染原理(6000字长文)...

    前言 对于HTML,css和JavaScript是如何变成页面的,这个问题你了解过吗?浏览器究竟在背后都做了些什么事情呢?让我们去了解浏览器的渲染原理,是通往更深层次的开发必不可少的事情,能让我们更深 ...

  2. 看看那些不讲码德的坏习惯

    在码农中有两种人:程序员与好的程序员.也许我们从事编程工作已经很多年了,并不是所有人都可以像称职的好程序员那样写出高效的代码.下面是Mehreen Tahir在 他的博客里 总结出几种不讲码德的坏习惯 ...

  3. 想成为一个Web前端开发工程师,需要掌握哪些知识?

    前端工程师已经成为目前互联网企业极具竞争力的人才,为了招聘到优秀的Web前端开发工程师,企业不断的提升薪资水平.因此,有越来越多的人加入到了学习Web前端行列.那么,想成为一名web前端开发工程师需要 ...

  4. 想成为一个Web前端开发工程师,需要掌握的详细知识总结

    前端工程师已经成为目前互联网企业极具竞争力的人才,企业不断提升薪资水平为了招聘到优秀的Web前端开发工程师.因此,越来越多的人想要学习Web前端.那么呢?Web前端的学习路线是什么? 想成为一个Web ...

  5. 成为一个大数据开发工程师的学习步骤--文字版

    本博客搬运自我知乎所出视频成为一个大数据开发工程师的学习步骤? - 知乎大数据的学习是有条件限制的,首先你需要是一名普通的工程师,如果你是Java工程师的话更好,但如果你是小-https://www. ...

  6. Android:面试官死亡问答,如何优化一个网络请求?大牛多个网络优化方案帮你解决!

    面试官:小萧啊,我好想你啊,你都好久没来找我面试了呀. 小萧:emmmmmmm,这不是怕被你打击吗. 面试官:ok,看来是有备而来,那么我们今天聊聊网络优化咋做吧. 小萧:我大意了,没有闪.老头子,你 ...

  7. 《面试官不讲武德》对Java初级程序猿死命摩擦Http协议

    前言 我被Hr领进了一个小黑屋,让我在这里等面试官,过来一会,一位穿着拖鞋的中年男子走了进来,看着他绝顶聪明的发际线,知道这肯定是位大佬,我心里倍感到了压力: 面试官果然不是盖的,刚坐下后就开始立即暴 ...

  8. 头条面试官:在浏览器地址栏输入一个URL后回车,背后会进行哪些技术步骤?

    本题为头条校招测开经典面试题,如果你去看过头条面经合集,会发现3次面试里至少出现有1次,也是非常基础的一个知识点. 好了,不说废话. 先上答案,一共6个步骤: DNS解析 TCP连接 发送http请求 ...

  9. 面试官:我就问了一个JVM,没想到他能吹半个小时

    前言: 作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识. JVM知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准. 在这里我们将详细的整理常见的 JV ...

最新文章

  1. mini2440系统引导(四)存储控制器
  2. 泥鳅般的const(一个小Demo彻底搞清楚)
  3. 之前出的一道背包题面,暂无题解
  4. 超链接显示网站 A,访问后进入网站 B
  5. ZeroClipboard / jquery.zclip.min.js跨浏览器复制插件使用中遇到的问题解决
  6. Python 定时任务的几种实现方式
  7. 保持简单:纪念丹尼斯•里奇
  8. ios重签工具避免双重认证
  9. php 项目如何运行_运行PHP项目(phpstorm+wampserver)
  10. Python 决策树计算熵、gini系数、误分率
  11. 专为轻运动而生的南卡NEO全新发布,定位骨传导运动耳机新标杆!
  12. serverless-OpenWhisk安装
  13. head 10字节_优秀了!10万系谱,计算近交系数,不到1秒!
  14. 首次回收重型猎鹰火箭全部助推器,SpaceX再创历史!
  15. 手把手教你读财报----银行业---第十课
  16. R语言提取字符串的一部分substring函数
  17. matlab三维 旋转矩阵,matlab旋转矩阵来旋转三维模型+meshlab旋转模型+matlab基础常用...
  18. 黑鹰基地VIP美工教程系列笔记
  19. 《c语言入门题目19》判断一个数是不是质数(素数)
  20. CTCS-3级列控系统

热门文章

  1. How to be better
  2. vue访问php时做增删改查,node连接mysql生成接口,vue通过接口实现数据的增删改查(一)...
  3. 用计算机来编辑文本文档教案,新疆版四年级上册信息技术教案(全册).doc
  4. vulhub的安装与简单使用
  5. 如何在 R 中绘制 Beta 分布
  6. 灵芝燕窝、鱼油钙片成为天猫双11中老年群体囤货首选
  7. 动画交互应用——神秘力量
  8. vega prime天气切换
  9. Revit二次开发之获取参数绑定的类别【比目鱼原创】
  10. nginx https代理http ,以及代理外网