酷游 发布的文章 - 第 109 页 - 酷游博客
首页
关于
友链
Search
1
阿里的简历多久可以投递一次?次数多了有没有影响?可以同时进行吗?
45 阅读
2
Java中泛型的理解
40 阅读
3
Java 14 发布了,再也不怕 NullPointerException 了!
38 阅读
4
Java中的可变参数
37 阅读
5
该如何创建字符串,使用" "还是构造函数?
29 阅读
技术
登录
/
注册
找到
556
篇与
酷游
相关的结果
- 第 109 页
2025-01-22
我出书了!
大家好,我是Hollis,今天要和大家说个事儿。 那就是,大家期待已久的新书终于出版了,来,先给大家亮个相: 这本书是在5.1之前就送去印刷了,放假回来之后预售就开启了,可是还没等我在公众号告知大家,预售第一天就登上了京东的新书热销榜第一名。 以至于很多读者都来问我”为啥悄咪咪的就上线了,也没正式的通知一下。” 写了啥 本书是《Java 工程师成神之路》系列丛书的第一本,所谓”基础不牢,地动山摇”,这本书就是来给大家筑基的! 之前经常有人问我,到底达到一个什么样的水品,可以称之为高级工程师?会哪些东西,才能叫做Java技术专家? 抛开那些高大上的框架、中间件、分布式什么的理论,我把所有我认为一个Java开发者需要掌握的基础知识全部都放到这本书里面了。 全书一共有23个章节,比较丰富全面的覆盖到了Java开发者日常工作中用到的几乎所有基础知识。 我比较喜欢《道德经》里面的一句话”有道无术,术可成;有术无道,止于道“,那到底什么是”道”什么是”术”呢? 在写这本书之前我也一直在探索,但是在写完之后,把这个本书全部通读一遍之后,我豁然开悟。 原来我在书中提出的那些问题,那些问题背后的思考,以及思考背后的原理解析,就是我一直所追寻的”道”。 所以,我又改了第二版、第三版、第四版….不断地删除了原来的一些”概念”、”用法”,不断地新增进去更多的”原理”和”思考”,不断地尝试着通过各种通俗的语言、例子把这些道理讲清楚。 适合谁 但是,虽然我穷尽了各种办法,想让他的内容通俗易懂,但是,我还是想说:这本书并不是适合所有人的。 以下几类人群不适合读这本书: 1、完全没有编程经验的人;这本书不是cook book,不能帮你21天掌握Java,并没有从安装虚拟机、配置classpath讲起。 2、认为代码写出来能跑就行,抵制一切”八股”的人;这本书中很多的知识点都是来源于工作中遇到的”坑”、书中分析了很多源码,是一本深入原理的书籍。一本十足的”八股”宝典。 其他人,无论是刚工作一两年的新手,还是工作了五六年的老司机;无论是准备找工作需要一本面试宝典,还是需要一本书来帮你躲避工作中的那些坑;无论是体系化学习作为知识体系,还是日常学习作为查缺补漏。 这本书,都适合你。 怎么买 所谓一图胜前沿,为了方便大家理解,这本书中我画了很多图。为了给大家带来更好的阅读体验,这本书采取的是彩印版。全书500多页,全部都是彩印。 现在书籍已经在京东、当当等平台开启预售了。现在京东、当当自营的价格是7折的。 但是,作为我自己的亲粉丝,怎么能没有专属优惠呢? 给大家申请了专享6折的优惠,但是是限时限量的,所以,欲购从速喽。扫描下方二维码,就可以直达优惠链接了。 另外,随书附送的还有一个史无前例的小惊喜给到大家,我把这个惊喜称之为”卧槽彩蛋”,就是看到之后会忍不住喊一声”卧槽”的那种。 因为现在还在预售,一方面出版社还在加班加点的印制中,另外受全国各地的疫情原因,具体发货及到手时间现在真的没办法确定。 但是,可以确定的是,这几天下单的人,一定是第一批拿到书的! 还等啥,上车吧。
技术
# 其他
酷游
1月22日
0
5
0
2025-01-22
[转]使用JMockit编写java单元测试
JMockit是基于JavaSE5中的java.lang.instrument包开发,内部使用ASM库来动态修改java的字节码,使得java这种静态语言可以想动态脚本语言一样动态设置被Mock对象私有属性,模拟静态、私有方法行为等等,对于手机开发,嵌入式开发等要求代码尽量简洁的情况下,或者对于被测试代码不想做任何修改的前提下,使用JMockit可以轻松搞定很多测试场景。 通过如下方式在maven中添加JMockit的相关依赖: com.googlecode.jmockit jmockit 1.5 test com.googlecode.jmockit jmockit-coverage 0.999.24 test JMockit有两种Mock方式:基于行为的Mock方式和基于状态的Mock方式: 引用单元测试中mock的使用及mock神器jmockit实践中JMockit API和工具如下: (1).基于行为的Mock方式: 非常类似与EasyMock和PowerMock的工作原理,基本步骤为: 1.录制方法预期行为。 2.真实调用。 3.验证录制的行为被调用。 通过一个简单的例子来介绍JMockit的基本流程: 要Mock测试的方法如下: public class MyObject { public String hello(String name){ return "Hello " + name; } } 使用JMockit编写的单元测试如下: @Mocked //用@Mocked标注的对象,不需要赋值,jmockit自动mock MyObject obj; @Test public void testHello() { new NonStrictExpectations() {//录制预期模拟行为 { obj.hello("Zhangsan"); returns("Hello Zhangsan"); //也可以使用:result = "Hello Zhangsan"; } }; assertEquals("Hello Zhangsan", obj.hello("Zhangsan"));//调用测试方法 new Verifications() {//验证预期Mock行为被调用 { obj.hello("Hello Zhangsan"); times = 1; } }; } JMockit也可以分类为非局部模拟与局部模拟,区分在于Expectations块是否有参数,有参数的是局部模拟,反之是非局部模拟。 而Expectations块一般由Expectations类和NonStrictExpectations类定义,类似于EasyMock和PowerMock中的Strict Mock和一般性Mock。 用Expectations类定义的,则mock对象在运行时只能按照 Expectations块中定义的顺序依次调用方法,不能多调用也不能少调用,所以可以省略掉Verifications块; 而用NonStrictExpectations类定义的,则没有这些限制,所以如果需要验证,则要添加Verifications块。 上述的例子使用了非局部模拟,下面我们使用局部模拟来改写上面的测试,代码如下: @Test public void testHello() { final MyObject obj = new MyObject(); new NonStrictExpectations(obj) {//录制预期模拟行为 { obj.hello("Zhangsan"); returns("Hello Zhangsan"); //也可以使用:result = "Hello Zhangsan"; } }; assertEquals("Hello Zhangsan", obj.hello("Zhangsan"));//调用测试方法 new Verifications() {//验证预期Mock行为被调用 { obj.hello("Hello Zhangsan"); times = 1; } }; } 模拟静态方法: @Test public void testMockStaticMethod() { new NonStrictExpectations(ClassMocked.class) { { ClassMocked.getDouble(1);//也可以使用参数匹配:ClassMocked.getDouble(anyDouble); result = 3; } }; assertEquals(3, ClassMocked.getDouble(1)); new Verifications() { { ClassMocked.getDouble(1); times = 1; } }; } 模拟私有方法: 如果ClassMocked类中的getTripleString(int)方法指定调用一个私有的multiply3(int)的方法,我们可以使用如下方式来Mock: @Test public void testMockPrivateMethod() throws Exception { final ClassMocked obj = new ClassMocked(); new NonStrictExpectations(obj) { { this.invoke(obj, "multiply3", 1);//如果私有方法是静态的,可以使用:this.invoke(null, "multiply3") result = 4; } }; String actual = obj.getTripleString(1); assertEquals("4", actual); new Verifications() { { this.invoke(obj, "multiply3", 1); times = 1; } }; } 设置Mock对象私有属性的值: 我们知道EasyMock和PowerMock的Mock对象是通过JDK/CGLIB动态代理实现的,本质上是类的继承或者接口的实现,但是在java面向对象编程中,基类对象中的私有属性是无法被子类继承的,所以如果被Mock对象的方法中使用到了其自身的私有属性,并且这些私有属性没有提供对象访问方法,则使用传统的Mock方法是无法进行测试的,JMockit提供了设置Mocked对象私有属性值的方法,代码如下: 被测试代码: public class ClassMocked { private String name = "name_init"; public String getName() { return name; } private static String className="Class3Mocked_init"; public static String getClassName(){ return className; } } 使用JMockit设置私有属性: @Test public void testMockPrivateProperty() throws IOException { final ClassMocked obj = new ClassMocked(); new NonStrictExpectations(obj) { { this.setField(obj, "name", "name has bean change!"); } }; assertEquals("name has bean change!", obj.getName()); } 使用JMockit设置静态私有属性: @Test public void testMockPrivateStaticProperty() throws IOException { new NonStrictExpectations(Class3Mocked.class) { { this.setField(ClassMocked.class, "className", "className has bean change!"); } }; assertEquals("className has bean change!", ClassMocked.getClassName()); } (2).基于状态的Mock方式: JMockit上面的基于行为Mock方式和传统的EasyMock和PowerMock流程基本类似,相当于把被模拟的方法当作黑盒来处理,而JMockit的基于状态的Mock可以直接改写被模拟方法的内部逻辑,更像是真正意义上的白盒测试,下面通过简单例子介绍JMockit基于状态的Mock。 被测试的代码如下: public class StateMocked { public static int getDouble(int i){ return i*2; } public int getTriple(int i){ return i*3; } } 改写普通方法内容: @Test public void testMockNormalMethodContent() throws IOException { StateMocked obj = new StateMocked(); new MockUp() {//使用MockUp修改被测试方法内部逻辑 @Mock public int getTriple(int i) { return i * 30; } }; assertEquals(30, obj.getTriple(1)); assertEquals(60, obj.getTriple(2)); Mockit.tearDownMocks();//注意:在JMockit1.5之后已经没有Mockit这个类,使用MockUp代替,mockUp和tearDown方法在MockUp类中 } 修改静态方法的内容: 基于状态的JMockit改写静态/final方法内容和测试普通方法没有什么区别,需要注意的是在MockUp中的方法除了不包含static关键字以外,其他都和被Mock的方法签名相同,并且使用@Mock标注,测试代码如下: @Test public void testGetTriple() { new MockUp() { @Mock public int getDouble(int i){ return i*20; } }; assertEquals(20, StateMocked.getDouble(1)); assertEquals(40, StateMocked.getDouble(2)); } 原文链接: http://blog.csdn.net/chjttony/article/details/17838693
技术
# Java
酷游
1月22日
0
15
0
2025-01-22
接口优于反射
接口优于反射 写在前面:最近在做一个需求:要针对不同的度量模型来执行不同的方法,同时要让后面接手的开发同学用最少的代码、最简单的方式来复用并实现更多度量模型。该需求一方面学到了一个新的设计模式——模板方法设计模式。另外一方面还得到一个经验————接口优于反射。 Effective Java的作者说接口优先于反射机制,这个之前就有看过,但是当时也没搞明白接口和反射能有啥联系,直到最近。才发现这句话的确是有道理的。 我的需求:有一批度量模型,要根据这些度量模型定义的规则给所有应用计算分数,不同的度量模型的计算方法需要对应不同的算法。整个计算过程需要离线计算(通过定时任务定时执行)。 我刚开始的做法(使用反射): 定义一个枚举: public enum MeasureModelEnum { CHECK_SPECIFIC_DEV_OWNER("execute","com.alibaba.intl.batch.sla.service.impl.SpecificDevOwnerCalculator"); /** * 要执行的方法名 */ String method; /** * 要执行的类的全路径名 */ String clazz; private MeasureModelEnum(String method ,String clazz){ this.method = method; this.clazz = clazz; } public String getMethod(){ return this.method; } public String getClazz(){ return this.clazz; } } 然后用以下代码遍历枚举项,执行对应的方法: for(MeasureModelEnum measureModel :MeasureModelEnum.values()){ String calculateMethod = measureModel.getMethod(); String calculateClass = measureModel.getClazz(); Class class1 = null; class1 = Class.forName(calculateClass); Method method = class1.getMethod(calculateMethod,List.class,LeafMeasureModel.class); method.invoke(class1.newInstance(),items,measureModel); } 后来的做法(使用接口): 定义一个枚举: public enum MeasureModelLeafNode { CHECK_SPECIFIC_DEV_OWNER(new SpecificDevOwnerCalculator()); //SpecificDevOwnerCalculator是AbstractNodeCalculator的实现类 /** * 实现类 */ AbstractNodeCalculator calculateNode ; private MeasureModelLeafNode(AbstractNodeCalculator calculateNode){ this.calculateNode = calculateNode; } public AbstractNodeCalculator getMeasureModel(){ return this.calculateNode; } } 然后用以下代码遍历枚举项,执行对应的方法: for(MeasureModelLeafNode measureModel:MeasureModelLeafNode.values()){ measureModel.getMeasureModel().execute(items, measureModel); } 总结 以上两部分代码的内容都是遍历枚举项,然后执行execute()方法进行逻辑处理。区别在于一个使用反射调用方法,一个使用接口+多态的形式执行方法。
技术
# Java
酷游
1月22日
0
20
0
2025-01-22
附加说明
关于本书 本电子书由和 联合出品,书中内容大部分来自作者Hollis原创,少部分来源于网络的内容均已注明出处。 本书为系列的第一部分,该系列共包含基础篇、底层篇、进阶篇、高级篇、架构篇以及扩展篇,共6部分。 主要迭代的时间点及变更信息如下: 主要版本 更新时间 备注 v3.0 2020-03-31 知识体系完善,在v2.0的基础上,新增20%左右的知识点调整部分知识的顺序及结构,方便阅读和理解通过GitHub Page搭建,便于阅读 v2.0 2019-02-19 结构调整,更适合从入门到精通;进一步完善知识体系;新技术补充; v1.1 2018-03-12 增加新技术知识、完善知识体系 v1.0 2015-08-01 首次发布 目前正在更新中… 欢迎大家参与共建~ 关于作者 Hollis (http://www.hollischuang.com/ ),阿里巴巴技术专家,51CTO专栏作家,CSDN博客专家,掘金优秀作者,《程序员的三门课》联合作者,《Java工程师成神之路》系列文章作者;热衷于分享计算机编程相关技术,博文全网阅读量数千万。 在线阅读地址 GitHub Pages 完整阅读:https://hollischuang.github.io/toBeTopJavaer Gitee Pages 完整阅读:http://hollischuang.gitee.io/tobetopjavaer 版权声明 本着互联网的开放精神,本项目采用开放的[GPL]协议进行许可,转载请保留本声明及作者信息,禁止用于任何商业用途。 参与共建 如果您对本书中的内容有建议或者意见、欢迎提出专业方面的修改建议。您可以直接在GitHub(https://github.com/hollischuang/toBeTopJavaer )上以issue或者PR的形式提出。 另外,如果本书中的内容侵犯了您的任何权益,欢迎通过邮箱(hollischuang@gmail)与我联系。 联系我们 欢迎关注作者的公众号,如果您有任何意见、建议,或者想与作者交流,都可以直接后台留言。 如果想要获取《Java工程师成神之路最新版思维导图》,请在公众号后台回复:”成神导图”
技术
# 未分类
酷游
1月22日
0
8
0
2025-01-22
面试官:你知道Dubbo怎么做优雅上下线的吗?你:优雅上下线是啥?
最近无论是校招还是社招,都进行的如火如荼,我也承担了很多的面试工作,在一次面试过程中,和候选人聊了一些关于Dubbo的知识。 Dubbo是一个比较著名的RPC框架,很多人对于他的一些网络通信、通信协议、动态代理等等都有一定的了解,这位候选人也一样。 但是,我接下来问了他一个问题:你们在使用Dubbo的时候,应用如果重启,怎么保证一个请求不会被中断处理的呢? 他没怎么说的上来,我以为他不理解我的问题,我接着问他:我就是想问下Dubbo是如何做优雅上下线的你知道吗? 接着他问我:优雅上下线是啥?? 好吧。 这篇文章,我来介绍一下这个知识点吧。 优雅上下线 关于”优雅上下线”这个词,我没找到官方的解释,我尝试解释一下这是什么。 首先,上线、下线大家一定都很清楚,比如我们一次应用发布过程中,就需要先将应用服务停掉,然后再把服务启动起来。这个过成就包含了一次下线和一次上线。 那么,”优雅”怎么理解呢? 先说什么情况我们认为不优雅: 1、服务停止时,没有关闭对应的监控,导致应用停止后发生大量报警。 2、应用停止时,没有通知外部调用方,很多请求还会过来,导致很多调用失败。 3、应用停止时,有线程正在执行中,执行了一半,JVM进程就被干掉了。 4、应用启动时,服务还没准备好,就开始对外提供服务,导致很多失败调用。 5、应用启动时,没有检查应用的健康状态,就开始对外提供服务,导致很多失败调用。 以上,都是我们认为的不优雅的情况,那么,反过来,优雅上下线就是一种避免上述情况发生的手段。 一个应用的优雅上下线涉及到的内容其实有很多,从底层的操作系统、容器层面,到编程语言、框架层面,再到应用架构层面,涉及到的知识很广泛。 其实,优雅上下线中,最重要的还是优雅下线。因为如果下线过程不优雅的话,就会发生很多调用失败了、服务找不到等问题。所以很多时候,大家也会提优雅停机这样的概念。 本文后面介绍的优雅上下线也重点关注优雅停机的过程。 操作系统&容器的优雅上下线 关于操作系统,我之前有一篇文章专门介绍过这个话题,可能大家没有注意到,那时候介绍的主题是为什么不能在线上机器中随便执行kill -9。 其实,这背后的思考就是优雅上下线。 我们知道,kill -9之所以不建议使用,是因为kill -9特别强硬,系统会发出SIGKILL信号,他要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略。 这个过程显然是不优雅的,因为应用立刻停止的话,就没办法做收尾动作。而更优雅的方式是kill -15。 当使用kill -15时,系统会发送一个SIGTERM的信号给对应的程序。当程序接收到该信号后,具体要如何处理是自己可以决定的。 kill -15会通知到应用程序,这就是操作系统对于优雅上下线的最基本的支持。 以前,在操作系统之上就是应用程序了,但是,自从容器化技术推出之后,在操作系统和应用程序之间,多了一个容器层,而Docker、k8s等容器其实也是支持优雅上下线的。 如Docker中同样提供了两个命令, docker stop 和 docker kill docker stop就像kill -15一样,他会向容器内的进程发送SIGTERM信号,在10S之后(可通过参数指定)再发送SIGKILL信号。 而docker kill就像kill -9,直接发送SIGKILL信号。 JVM的优雅上下线 在操作系统、容器等对优雅上下线有了基本的支持之后,在接收到docker stop、kill -15等命令后,会通知应用进程进行进程关闭。 而Java应用在运行时就是一个独立运行的进程,这个进程是如何关闭的呢? Java程序的终止运行是基于JVM的关闭实现的,JVM关闭方式分为正常关闭、强制关闭和异常关闭3种。 这其中,正常关闭就是支持优雅上下线的。正常关闭过程中,JVM可以做一些清理动作,比如删除临时文件。 当然,开发者也是可以自定义做一些额外的事情的,比如通知应用框架优雅上下线操作。 而这种机制是通过JDK中提供的shutdown hook实现的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子。 例子如下: package com.hollis; public class ShutdownHookTest { public static void main(String[] args) { boolean flag = true; Runtime.getRuntime().addShutdownHook(new Thread(() -> { System.out.println("hook execute..."); })); while (flag) { // app is runing } System.out.println("main thread execute end..."); } } 执行命令: jps 6520 ShutdownHookTest 6521 Jps kill 6520 控制台输出内容: hook execute... Process finished with exit code 143 (interrupted by signal 15: SIGTERM) 可以看到,当我们使用kill(默认kill -15)关闭进程的时候,程序会先执行我注册的shutdownHook,然后再退出,并且会给出一个提示:interrupted by signal 15: SIGTERM Spring的优雅上下线 有了JVM提供的shutdown hook之后,很多框架都可以通过这个机制来做优雅下线的支持。 比如Spring,他就会向JVM注册一个shutdown hook,在接收到关闭通知的时候,进行bean的销毁,容器的销毁处理等操作。 同时,作为一个成熟的框架,Spring也提供了事件机制,可以借助这个机制实现更多的优雅上下线功能。 ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制。 开发者可以实现ApplicationListener接口,监听到 Spring 容器的关闭事件(ContextClosedEvent),来做一些特殊的处理: @Component public class MyListener implements ApplicationListener { @Override public void onApplicationEvent(ContextClosedEvent event) { // 做容器关闭之前的清理工作 } } Dubbo的优雅上下线 因为Spring中提供了ApplicationListener接口,帮助我们来监听容器关闭事件,那么,很多web容器、框架等就可以借助这个机制来做自己的优雅上下线操作。 如tomcat、dubbo等都是这么做的。 这里简答说一下Dubbo的,在Dubbo的官网中,有关于优雅停机的介绍:  应用在停机时,接收到关闭通知时,会先把自己标记为不接受(发起)新请求,然后再等待10s(默认是10秒)的时候,等执行中的线程执行完。 那么,之所以他能做这些事,是因为从操作系统、到JVM、到Spring等都对优雅停机做了很好的支持。 关于Dubbo各个版本中具体是如何借助JVM的shutdown hook机制、或者说Spring的事件机制昨的优雅停机,我的一位同事的一篇文章介绍的很清晰,大家可以看下: https://www.cnkirito.moe/dubbo-gracefully-shutdown/ 在从Dubbo 2.5 到 Dubbo 2.7介绍了历史版本中,Dubbo为了解决优雅上下线问题所遇到的问题和方案。 目前,Dubbo中实现方式如下,同样是用到了Spring的事件机制: public class SpringExtensionFactory implements ExtensionFactory { public static void addApplicationContext(ApplicationContext context) { CONTEXTS.add(context); if (context instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext) context).registerShutdownHook(); DubboShutdownHook.getDubboShutdownHook().unregister(); } BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); } } 总结 本文从操作系统开始,分别介绍了Linux、Docker、JVM、Spring、Dubbo等对优雅停机的支持。 可以看到,一个简单的优雅停机功能,上下游需要这么多底层基础设施和上层应用的支持。 相信通过学习本文,你一定对优雅上下线有了更多的了解。 除此之外,我还希望你,通过本文以后,遇到一些实际问题的时候,可以想到文中提到的shutdown hook机制、Spring的event机制。很多时候,这些机制都能帮助我们解决很多问题。 我在工作中,就有很多次使用过这样的机制的实例,后面有机会给大家介绍几个实例。 参考 : https://zhuanlan.zhihu.com/p/29093407 https://www.cnkirito.moe/dubbo-gracefully-shutdown/
技术
# 微服务
酷游
1月22日
0
11
0
上一页
1
...
108
109
110
...
112
下一页
易航博客