
Java
文章平均质量分 91
布道
专注但要有大局观(先大后小,思路为先,实验为辅)
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
畅谈Java模块化与微服务
微服务这2年的发展太热门了,这阵势很容易导致开发者一叶障目,首先微服务是需要一些技术沉淀的,其次和业务体量、开发团队的规模有关,这里不展开探讨微服务之殇。业务的复杂度继续堆积犹如潘多拉魔盒,本文将从依赖、模块化的视角来展开探讨。提前模块化,要从大神毕玄的osgi模块化中国社区谈起,模块对代码进行了更高一级的抽象作为一个基本单位,表现形式通常为一个jar或一个fat-jar。众所周知的,我们一般...原创 2019-09-08 16:07:54 · 10108 阅读 · 0 评论 -
堆外内存泄露揭秘
说实话jvm中堆外内存使用的场景非常多,它可降低GC、减少用户态与内核态切换及数据拷贝,已经成为性能提升的有效手段。比如通讯(netty之对象池Recycler),MQ(本地IO之零拷贝之类)。一般使用堆外内存要重点关注手动释放or 自动释放,从笔者的过往经验中谈,堆外内存一旦发生泄漏,排查起来相对的困难。你可能比较好奇,为何比较困难呢?笔者认为:涉及泄漏最终会定位到c的代码,一般都是内核级g...原创 2019-06-27 21:43:48 · 2597 阅读 · 0 评论 -
随机读写之DirectIO
在上一节中讲过MappedByteBuffer VS FileChannel它们称得上零拷贝技术,但留下了顺序读比随机读快,顺序写比随机写快的问题,在我们的实际应用场景中为了回避随机读写需求,通常的做法都是对其进行文件分片(又将随机变成了有序),而本节借助Direct IO来彻底解决该问题。注:只有 Linux 系统才支持 Direct IO,还被 Linus 喷过,据说在 Jdk10 发布之...原创 2019-06-14 22:28:09 · 11731 阅读 · 0 评论 -
论最强IO:MappedByteBuffer VS FileChannel
最近一直在研究MQ,开源社区中有很多高性能MQ:kafka、RocketMQ、ActiveMQ,抛开网络传输方式、数据结构设计、文件存储方式...等因素。Java 在 JDK 1.4 引入了 ByteBuffer 等 NIO 相关的类,使得 Java 程序员可以抛弃基于 Stream ,从而使用基于 Block 的方式读写文件。这些MQ有一个共同的特点就是:引入了 IO 性能优化之王MappedB...原创 2019-06-13 19:25:13 · 21431 阅读 · 6 评论 -
基本功:初探对象的内存布局
java中我们随处可见的都是对象,而对象成为我们与计算机内核交换的主要载体,使用起来也非常简单,然而一个对象是如何被JVM创建的却是极其的复杂,它要经历类加载机制、分片内存以及设置对象头的内存布局。下面讲介绍下Hotspot JVM下新建对象需要基本过程。前言-字节码new语句最会被编译而成的字节码,而它将包含用来请求内存指令。public class ObjectSizeMai...原创 2019-06-01 19:58:13 · 905 阅读 · 0 评论 -
基本功:线程上下文切换
由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。可以看另一篇《Java从线程安全到synchronized和Lock探索》时间片多任务系统往往需要同时执行多道作业。作业数往往大于机器的CPU数,然而一颗CPU同时只能执行一项任务,如何...原创 2019-05-31 22:06:42 · 31745 阅读 · 4 评论 -
再谈spring boot 优雅停机
再谈为了提醒明知故犯(在一坑里迭倒两次不是不多见),由于业务系统中大量使用了spring Boot embedded tomcat的模式运行,在一些运维脚本中经常看到Linux 中 kill 指令,然而它的使用也有些讲究,要思考如何能做到优雅停机。目录何为优雅关机kill指令Runtime.addShutdownHookspring 3.2.12spring boot何...原创 2019-05-24 10:24:33 · 11705 阅读 · 0 评论 -
基本功:ConcurrentArrayList
很多时候,如何保障你的代码高并发高性能,这的确是个很耐人寻味的话题。高性能意味着你要对采用的每一个容器、集合(数据结构)要非常讲究,而它往往是很多人不太注意的地方,这也行就是你不能专家级的一方面原因!so,基本功很重要,尽可能的接触底层实现。在java圈中,ArrayList 是非线程安全的,难道在多线程场景下我们只有Vector这一种线程安全的数组实现可以选择么?当然也有List sync...原创 2019-05-08 22:10:41 · 10954 阅读 · 0 评论 -
java冷知识:Java类型检测与提前类加载
提起Java提供了参数的动态检验,相信很多人对它的理解:仅仅是在执行期检测参数是否合法。常常我们觉得 classloader的加载顺序就应该在执行期。Java编译器会开启这种静态检测机制,会使用一组类型检测规则来检测Java字节码,检测这些字节码是否符合规则,如果不符合那么将会被拒绝。但是部分的检测还是在编译器的协助下完成的,而这一步要早于真正执行它。重要的说三遍:类型检测是早于执行的...原创 2019-05-02 20:13:43 · 1507 阅读 · 0 评论 -
响应式编程之数据访问:ADBA与R2DBC
这个世界在变,技术也一直在变化着。JDBC具有阻塞性 - 没有什么可以减轻JDBC的阻塞性质,什么时候可以使用API进行响应性关系数据库集成?先用有Oracle宣布推出ADBA,再有在SpringOne平台华盛顿大会上宣布的 R2DBC,用于针对关系型数据库进行反应式编程。最终目标是试图影响 ADBA规范。R2DBC的设计原则是基于以下四个原则:利用反应式流类型和模式 访问数据库的...原创 2019-04-30 22:19:47 · 6319 阅读 · 4 评论 -
java冷知识:Java 8 Reflection访问方法参数
在java中使用Reflection API获取构造方法或普通方法的参数名是一件比较麻烦的事情,而Java 8提供java.lang.reflect.Parameter类,它将提供有关参数名称及其修饰符的信息。在Java 8之前,我们不能直接获取方法或构造函数的参数名。当然,额外的有一个方便的方法Parameter.isNamePresent() 来验证参数名是不是可用。public cla...原创 2019-04-28 18:28:28 · 6478 阅读 · 0 评论 -
Class.forName和ClassLoader.loadClass
在上一节中讲到突破双亲委派模型的CurrentClassLoader和ContextClassLoader,接下来重点讲Class.forName和ClassLoader.loadClass ,众所周知它们都可以用来加载目标类,它们之间有一个小小的区别,那就是Class.forName() 方法可以获取原生类型的 Class,而 ClassLoader.loadClass则会报错。Cla...原创 2019-04-27 16:13:13 · 2278 阅读 · 0 评论 -
java冷知识:突破双亲委派模型的CurrentClassLoader和ContextClassLoader
java的ClassLoader机制真可谓最神秘的技术,在之前的文章中深入简出的介绍过。这里补充两方面的问题,第一个就是CurrentClassLoader(也称为Current ClassLoader)和ContextClassLoader,第二个就是深入的谈下Class.forName和ClassLoader.loadClass。首先,先看下面的示例代码。//代码1class A {...原创 2019-04-24 23:15:18 · 1857 阅读 · 0 评论 -
那些年我们追过的异步骚操作:ListenableFuture、CompletableFuture、RxJava(Observable)
Futures在Java 5(2004)中引入。它们是承诺在操作完成后保留操作结果的对象。调用者可以使用future对象来检查操作isDone(),或者等待它完成使用get()。Future模式一个最大的问题是何时调用问题(过早地阻塞Future.get(),这消除了异步执行的好处)。guava的 ListenableFuture、java8的CompletableFuture、RxJava的...原创 2019-03-13 22:07:26 · 6743 阅读 · 1 评论 -
自研数据聚合组件
随着服务化越来越多,单个VO或BO属性拆分之痛已成为业务系统日益突出的问题。大量重复的代码逻辑都是用来处理依赖(查询方面的数据聚合操作),而通讯方式通常都是rest-http。功能特性多数据源支持:springBean和普通类(理论上包含http-eureka、esb) 后置填充(目标方法执行后介入) 单VO及List支持 并发填充支持 List开启性能优化 接入方的参数传...原创 2019-03-13 09:53:02 · 933 阅读 · 0 评论 -
基本功:你不知道StringJoiner
StringJoiner是Java8新出的一个类,用于构造由分隔符分隔的字符序列,并可选择性地从提供的前缀开始和以提供的后缀结尾。StringJoiner nameJoiner = new StringJoiner(":", "[", "]");nameJoiner.add("George").add("Sally").add("Fred");System.out.println(nam...原创 2019-03-11 12:28:45 · 2700 阅读 · 0 评论 -
java冷知识:javac AbstractProcessor
Annotation Processor是javac的一个工具,它用来在编译时扫描和处理注解,通过Annotation Processor可以获取到注解和被注解类的相关信息,然后根据注解自动生成Java代码,省去了手动编写,提高了编码效率。目录它可以做什么?ProcessorAbstractProcessor源码实现一个打印可以API的功能google的 auto-se...原创 2019-03-06 22:11:53 · 15551 阅读 · 7 评论 -
java冷知识:程序Debug带来的启示
相信每一个java开发者都使用过IDEA 的 Debug,它能查看断点的上下文环境,并且提供了非常强大的可视化工具,更神奇的是我可以在断点处使用它的 Evaluate 功能直接执行某些命令,进行一些计算或改变当前变量。目录字节码技术-ASMNative AgentJava AgentVM.attach(Vitural Machine)SA.attach()PerfDat...原创 2019-02-25 19:46:04 · 713 阅读 · 0 评论 -
java冷知识:应用程序安全沙箱
在阅读jdk源码时经常遇到System.getSecurityManager();这样安全检查代码。它保证了jvm所运行程序的完整性,使得jvm不会因为运行有漏洞或恶意的代码而导致出现不可预期的状态。public class File implements Serializable, Comparable<File>{ public boolean canRead...原创 2019-02-25 18:55:49 · 7884 阅读 · 0 评论 -
基本功:你忽略的ClassLoader
ClassLoader 是 Java 届最为神秘的技术之一,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序。Class Loaders(类加载器)是JVM用于运行来动态加载类的,同时它们也是JRE的一部分,由于Class Loaders的存在,JVM运行Java程序的时候不需要知道底层文件或文件系统。目录1.基本概念2. 双亲委派2.1...原创 2019-02-20 21:22:19 · 4851 阅读 · 0 评论 -
ThreadPoolExecutor源码解析
在之前章节java并发中讲过线程池,java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。首先,我们带着问题去了解它。1. 线程池中shutdown、shutdownNow、isShutdown、isTerminated、awaitTermination的使用场景?shutdo...原创 2019-02-20 17:38:11 · 2265 阅读 · 0 评论 -
基本功:神奇的Java反射机制了解一下
在 Java中,反射机制(Reflection)非常重要,但对于很多开发者来说,这并不容易理解,在此献上一份Java反射机制的介绍。1.简介定义:Java语言中 一种动态(运行时)访问、检测 & 修改它本身的能力作用:动态(运行时)获取类的完整结构信息 & 调用对象的方法2.特点2.1 优点灵活性高。因为反射属于动态编译,即只有到运行时才动态创建 &...原创 2019-02-19 21:42:07 · 999 阅读 · 1 评论 -
基本功:魔法类-Unsafe
体验过多线程程序开发之后,可能问自己一个问题,Java 内置的锁是如何实现的?最常用的最简单的锁要数ReentrantLock,那线程是如何实现阻塞自己的?线程阻塞原语,底层实现是通过 Unsafe 类的 park(阻塞) 和 unpark (唤醒)方法做到的。但这两个方法都是 native 方法,它们本身是由 C 语言来实现的核心功能。/** * 锁数据结构正是通过调用 LockSu...原创 2019-02-19 17:58:48 · 978 阅读 · 0 评论 -
基本功:史上最全java并发攻略
上一篇《Java从线程安全到synchronized和Lock探索》大概是5年前发表,下图是去年在公司内部分享时整理的,可以收藏。误区1:自旋锁 VS 适应性自旋锁阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。在许多场景中,同步资源的锁定时间很短,为了这一小...原创 2019-02-15 09:33:01 · 30541 阅读 · 0 评论 -
java冷知识:桥接方法method.isBridge()
在JDK 1.5 引入泛型后就引入了桥接方法,也可以理解为桥接方法是泛型的本质(载体)泛型只是表象。熟悉泛型的童靴可能都知道,Java泛型的处理几乎都在编译器中进行,编译器生成的bytecode是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除。当然你只要记住以下几点:虚拟机中没有泛型,只有普通类和普通方法 所有泛型类的类型参数在编译时都会被擦除 创建泛型对象时...原创 2019-02-13 10:33:33 · 2378 阅读 · 0 评论 -
java冷知识:URL扩展协议与spring Resource的关联
在java中有一个非常重要的类URL(Uniform Resource Locator)中文名为统一资源定位符,它可以标识本地的文件资源或类路径资源(xml文件、properties文件),也可以标识网络资源(http、ftp)。首先我们在项目中经常可以看到下面这样的代码,对,非常普通!@Testpublic void go_loadPrjFile() { URL url = Re...原创 2018-12-29 16:47:49 · 1259 阅读 · 0 评论 -
java冷知识:java bean内省模式与spring bean的关联
最近一直整理着搜索引擎相关的主题,后续也准备多分享一些spring相关的技术。正所谓温故而知新,java bean内省模式对spring bean的影响非常深,真可谓是青出于蓝而胜于蓝。目录1.JavaBeanIntrospector1.1BeanDescriptor1.2MethodDescriptor1.3PropertyDescriptor1.4Param...原创 2018-12-21 12:55:52 · 5559 阅读 · 1 评论 -
有限状态机从设计到实践
基于java实现的有限状态自动机,轻松,快捷,高效的关联状态的扭转。背景在日常的开发中,我们有些业务单据有非常复杂流程(它有很多状态),如果靠传统的全局属性然后通过swich和if来判断的话,扩展性差,重复代码多。通过编写一个状态管理库来解决状态变化的优点有:代码整洁,可读性强 易拓展,可复用 维护成本小有限状态机有限状态机(Finite-state machine, FSM...原创 2018-12-19 22:29:33 · 1344 阅读 · 0 评论 -
你不知道的PreparedStatement预编译
大家都知道,Mybatis内置参数,形如#{xxx}的,均采用了sql预编译的形式,大致知道mybatis底层使用PreparedStatement,过程是先将带有占位符(即”?”)的sql模板发送至mysql服务器,由服务器对此无参数的sql进行编译后,将编译结果缓存,然后直接执行带有真实参数的sql。如果你的基本结论也是如此,那你就大错特错了。目录1. mysql是否默认开启了预编译功...原创 2018-11-28 15:05:37 · 7705 阅读 · 6 评论 -
响应式编程系列二《rxjava》
响应式编程是什么,在上一篇规约中已经提到过,这里不再赘述。那接下来我们将深入检出的掌握RxJava。目录1. RxJava背景2. 官方定义3. 实现原理3.1 基本实现步骤3.2Observer和Subscriber的区别4. Rx1.x4.1 事件流程4.2 Sync & Async4.3 操作符4.4 背压4.5 Schedule...原创 2018-10-16 15:55:29 · 2009 阅读 · 0 评论 -
响应式编程系列一《规约》
提升开发效率,降低维护成本一直是开发团队永恒不变的宗旨。近两年来国内的技术圈子中越来越多的开始提及ReactiveX,越来越多的应用和面试中都会有ReactiveX,响应式编程中RxJava可谓如鱼得水。目录1. 背景2. 响应式编程是什么2.1原理简析2.3与传统观察者模式不同2.2 Rx是Push还是Pull3. 优势 & 代价4. Reactiv...原创 2018-10-16 15:31:52 · 1791 阅读 · 0 评论 -
JPA之集成mongodb
JPA已成为ORM事实的标准,已经深入人心。不清楚的可以参阅《JPA之Spring Data JPA》目录1. 原生使用1.1 官方文档1.2 历史版本1.3 基本用法演示2. spring-data-mongodb2.1 官方文档2.2 环境要求2.3 历史版本2.4 基本用法演示2.5 spring-boot项目2.6 MongoTemplate...原创 2018-09-30 11:33:36 · 7164 阅读 · 0 评论 -
Java之size()>0 和isEmpt()性能考量
为何要写这篇呢?主要是要纠正一个长期以来的误区:size()>0 一定比isEmpt()性能差。以下内容是社区里的结论:方法一(数据量大,效率低): if(list!=null && list.size()>0){}方法二(数据量大,效率高): if(list!=null && !list.isEmpty()){}sonar的规范是...原创 2018-09-28 16:13:21 · 2116 阅读 · 0 评论 -
使用maven-docker工具快速构建可交付的java-web镜像
容器的出现让 Java开发人员比以往任何时候都更接近“编写一次,到处运行”的工作流程,然而在实际的工作中并非这样的~!要实现这样的诉求,首先你必须编写 Dockerfile,以 root身份运行 Docker守护进程,等待构建完成,最后将镜像推送到远程注册中心。说实话,Dockerfile有多复杂也有文章讲过,但并非所有的 Java开发人员都是容器专家。下面带着这些疑问,给大家介绍下java开源世...原创 2018-09-27 22:45:55 · 1559 阅读 · 0 评论 -
如何一步步设计一款微服务的补偿方案
背景随着微服务化的系统越来越多,系统间的交互也呈现几何倍增的趋势,系统间面临一致性问题越来越突出。为了保障服务提供方与服务消费方的一致性,特别是面临最大努力通知型或补偿性的技术需求,服务化前做法是服务提供方需手写重试策略及各种配置->持久化消息->定时去处理消息等。它带来的以下问题是:1.客户端(新微服务)要做的重复性工作越来越多?需每个开发者熟悉它,去实现它;2.这个为什么...原创 2018-09-20 16:29:13 · 4954 阅读 · 0 评论 -
一步步构建轻量级http-contract客户端
http-client-plus是一个类似于Feign一样的申明式ESB请求代理组件,使用ESB请求代理组件,面向SpringCloud微服务的,老的项目spring3.x也支持.背景习惯于玩rpc的同学都知道,透明化调用对客户端来说很高效及方便,同时组件升级和客户端升级(更新下jar版本)本来都是很轻松的事情。而http-client-plus是对XX公司mule-esb-api的简单封...原创 2018-08-08 12:17:19 · 1007 阅读 · 0 评论 -
JVM故障诊断调优
作为一名合格的架构师,如何能快速定位生产故障的根源,快速修复并恢复,已经成为其必备技能。以下是我整理的出想法:目录1.故障收集2. 必备技能2.1 网络与cup2.2HotSpot VM2.3 Mbean2.4JVM工具2.4.1jps2.4.2jinfo2.4.3jconsole2.4.4jvisualvm2.4.5jmap2....原创 2017-08-21 18:24:34 · 6098 阅读 · 1 评论 -
Java 程序员必须收藏的资源大全
古董级工具这些工具伴随着Java一起出现,在各自辉煌之后还在一直使用。 Apache Ant:基于XML的构建管理工具。官网 cglib:字节码生成库。官网 GlassFish:应用服务器,由Oracle赞助支持的Java EE参考实现。官网 Hudson:持续集成服务器,目前仍在活跃开发。官网 JavaServer Faces:Mojarra是J...转载 2017-08-21 18:10:33 · 2027 阅读 · 0 评论 -
新出炉的热门大厂java开源项目
1. Apache的开源软件列表http://www.oschina.net/project/apache2. Java开源Apache项目http://www.open-open.com/56.htm3. 阿里巴巴的开源软件列表http://www.oschina.net/project/alibaba4. 百度的开源软件列表http://www.osc...原创 2017-08-21 17:59:16 · 11973 阅读 · 1 评论 -
jvm 收集故障现场脚本
有时候监控系统显示XXX-java应用出现高cup、高io、高内存,该怎样去定位及解决呢,解决思路在《故障诊断》,以下是收集现场证据,便于定位问题 JAVA_HOME=/usr/java OUTPUT_HOME=~/output DEPLOY_HOME=`dirname$0` HOST_NAME=`hostname` DUMP_PIDS=`ps --no-h...原创 2017-06-20 21:28:00 · 2488 阅读 · 0 评论