自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

aty

虽有嘉肴,弗食,不知其旨也;虽有至道,弗学,不知其善也。是故学然后知不足,教然后知困。知不足,然后能自反也;知困,然后能自强也。

  • 博客(340)
  • 资源 (1)
  • 收藏
  • 关注

原创 【招聘】欢迎热衷于微服务框架、中间件、云原生方向的同志!

OPPO基础技术部,支撑OPPO移动互联网业务,海量用户和数据,等你来!希望能招募到热衷于高并发、高可用、高性能,面向云原生技术架构的同志!有意向的同志,欢迎发简历到[email protected]!岗位名称:数据库中间件工程师工作内容:1、负责数据库网格产品的架构设计和系统研发,不断优化产品的性能、扩展性和可用性2、指导并协助公司多业务线使用数据库网格产品,降低业务线的开发运维成本3、践行开源社区理念和价值观,逐步推广和运营数据库网格产品任职要求:1、扎实的计算机和编程

2021-01-26 17:04:05 657 1

原创 maven资源过滤导致打包后文件变大

使用maven进行资源过滤的时候,只要过滤需要过滤的文件,一些二进制文件,比如https证书等,就不要参与资源过滤,否则打包后会破坏文件内容。

2017-02-15 14:32:44 5273 2

原创 java泛型的一些常见用法

java泛型常见写法

2017-02-09 08:57:30 4250

原创 遍历java集合或数组的几种方式

以数组为例,基本上有下面4种常见的遍历方式:方式1:多次调用函数,而这些调用是不必要的,浪费。方式2:引入了额外的length变量,而且该变量在整个方法作用域内都可见,有变量作用域污染问题。方式3:不存在方式1的浪费,不存在方式2的作用域污染,唯一不好的地方在于多定义一个变量。方式4:不存在方式1的浪费,不存在方式2的作用域污染,唯一不好的地方在于丢失了索引信息。总之:不需要索引的时候使用方式4,需要索引的时候使用方式3

2017-02-06 20:12:32 2278

原创 熟练使用java的Enum、EnumSet、EnumMap

对java枚举一直没有系统学习过,之前就是用枚举来替代接口中的常量,今天看到同事写的一段代码使用了EnumSet,不是特别熟悉。于是重新学习了Enum、EnumSet、EnumMap。

2017-02-06 19:56:44 9232 1

原创 JDK8新特性:使用stream、Comparator和Method Reference实现集合的优雅排序

大家对java接口Comparator和Comparable都不陌生,JDK8里面Comparable还和以前一样,没有什么改动;但是Comparator在之前基础上增加了很多static和default方法。本文主要结合JDK的stream编程,学习下Comparator。stream().sorted()/Comparator.naturalOrder()/Comparator.reverseOrder(),要求元素必须实现Comparable接口。

2017-02-05 13:23:55 27745

原创 JDK8新特性:使用Method References实现方法复用,简化lambda表达式

之前的文章已经介绍了函数式接口与lambda表达式,这篇文章主要学习下方法引用。使用方法引用,可以减少lambda表达式的书写,在Stream API中很常用。我们想实现整数list的排序,使用lambda我们还得自己编写一个Comparator对象(虽然也很简单),实际上JDK类库已经提供了类似的实现,我们通过Integer::compare就可以引用已经存在的方法。

2017-01-18 10:36:19 1880 1

原创 JDK8新特性:使用Optional避免null导致的NullPointerException

Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

2017-01-15 20:00:13 111762 9

原创 消息摘要、MAC(消息认证码)、数字签名扫盲贴

消息摘要与MAC的区别,消息摘要只能保证消息的完整性,MAC不仅能够保证完整性,还能够保证真实性。MAC不能保证消息的不可抵赖性,而数字签名可以保证。

2017-01-14 15:56:50 16478

原创 SimpleDateFormat不是线程安全的类

SimpleDateFormat不是线程安全的类,可能报各种异常

2017-01-13 09:24:32 795

原创 JDK8新特性:编译器保留方法参数名字

很长一段时间里,Java程序员一直在发明不同的方式使得方法参数的名字能保留在Java字节码中,并且能够在运行时获取它们(比如Paranamer类库)。最终,在Java 8中把这个强烈要求的功能添加到语言层面(通过反射API与Parameter.getName()方法)与字节码文件(通过新版的javac的–parameters选项)中。

2017-01-12 13:19:34 7696 1

原创 JDK8新特性:重复注解Repeating Annotations

注解并不是什么新鲜东西了,比如spring中存在大量注解简化我们的配置。但是在JDK8之前,我们是不能使用重复注解的,即某个位置相同注解只能出现一次。这里有个使用@Repeatable( Schedules.class )的注解类Schedule,Schedules仅仅是Schedule注解的数组,但Java编译器并不想让程序员意识到Schedules的存在。这样对使用者而言,Target就拥有了两个Schedule注解,而不是1个Schedules注解。同时,反射相关的API提供了新的函数getAnnot

2017-01-12 09:20:28 3076

原创 JDK8新特性:lambda入门

lambda其实就是为@FunctionalInterface服务的,能够用一种全新的、简洁的语法创建函数式接口的对象。当然如果一个接口不符合函数式接口的定义,是不能通过lambda表达式来创建其对象的。lambda其实就是定义入参、函数体、返回值,然后可以生成任意一个接口(符合该函数入参和返回值的函数式接口)的对象。

2017-01-11 09:26:39 2163

原创 maven项目构建:maven-antrun-plugin插件实现文件内容拷贝和文件重命名

maven-antrun-plugin插件实现文件内容拷贝和文件重命名

2017-01-10 20:07:32 9038

原创 JDK8新特性:函数式接口@FunctionalInterface的使用说明

通过JDK8源码javadoc,可以知道这个注解有以下特点:1、该注解只能标记在"有且仅有一个抽象方法"的接口上。2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。

2017-01-06 14:03:29 119686 18

原创 JDK8新特性:接口的静态方法和默认方法

在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的。JDK8及以后,允许我们在接口中定义static方法和default方法。静态方法,只能通过接口名调用,不可以通过实现类的类名或者实现类的对象调用。default方法,只能通过接口实现类的对象来调用。

2017-01-06 10:46:53 36569 21

原创 Guava库:Preconditions实现优雅校验

实际开发中需要做入参校验的情况比比皆是,比如开发一个rest接口,肯定要对参数各种校验,防止错误的输入导致程序出错。我们可以使用Preconditions(前置条件),这样我们自己代码中就不会出现大段的if代码了。Preconditions类似我们写junit单元测试或者spring中的assert。

2017-01-05 09:58:30 8259

原创 guava-retrying重试工具库: Retryer.call()使用注意事项

前面我们介绍了如何通过RetryerBuilder构造一个Retryer对象,现在我们学习下如何使用 Retryer.call()。这个API很重要,对于这个方法的入参、返回值、可能抛出的异常要了解清楚。入参:很简单,就是一个实现了业务逻辑的Callable对象;返回值:某次尝试成功后,Callable的返回值。我们主要关注下可能的异常:RetryException和ExecutionException。ExecutionException产生:传入的Callable执行过程中产生了异常,但是我们在构建Re

2016-12-27 14:17:07 13411

原创 guava-retrying重试工具库: AttemptTimeLimiter

AttemptTimeLimiter和guava的TimeLimiter基本是一样的,是为了限制某个任务的执行时间。比如我希望一个Callable任务执行时间不超过5s,如果超过抛异常TimeoutException。

2016-12-27 13:59:25 2806

原创 guava-retrying重试工具库: RetryListener

当发生重试之后,假如我们需要做一些额外的处理动作,比如发个告警邮件啥的,那么可以使用RetryListener。每次重试之后,guava-retrying会自动回调我们注册的监听。可以注册多个RetryListener,会按照注册顺序依次调用。

2016-12-27 13:26:59 5219 2

原创 guava-retrying重试工具库: 阻塞策略BlockStrategy

什么是阻塞策略呢?通过前面的学习,我们知道guava-retrying是可以设置2次重试的时间间隔的。比如第一次失败后,需要等待200ms再开始第二次尝试,也就是说线程需要等待200ms。实现200ms等待有多种方式,比如通过sleep方式,比如通过自旋的方式,比如锁、wait等多种控制手段,这其实就是并发策略。guava-retrying默认是使用睡眠方式来实现阻塞的。

2016-12-27 13:14:16 3377 1

原创 guava-retrying重试工具库: 隔多长时间重试

noWait失败后立刻重试,fixedWait间隔固定时间之后重试,WaitStrategies.randomWait间隔随机时间后重试,incrementingWait增量重试,fibonacciWait按照斐波那契数列重试,exponentialWait按照指数递增(2的n次方)来重试,exceptionWait根据抛出的异常来决定等待的时间长短,join组合多个重试间隔逻辑。

2016-12-27 11:17:41 5234 1

原创 guava-retrying重试工具库: 什么时候终止

当我们重试到一定阶段的时候,需要终止重试过程,比如重试了n次或者重试了n秒等。StopStrategies.stopAfterAttempt(n):在重试了n次后终止,这个实际中最常用。StopStrategies.neverStop():从不终止,一直重试,没有什么实际用处。StopStrategies.stopAfterDelay(10, TimeUnit.SECONDS):一直重试,指定时间过后终止。guava-retrying提供了StopStrategy接口,我们可以实现自己想要的终止逻辑。

2016-12-26 20:29:54 2182

原创 guava-retrying重试工具库: 什么时候重试

retryIfException,抛出runtime异常、checked异常时都会重试,但是抛出error不会重试。retryIfRuntimeException只会在抛runtime异常的时候才重试,checked异常和error都不重试。retryIfExceptionOfType允许我们只在发生特定异常的时候才重试,比如NullPointerException和IllegalStateException都属于runtime异常。上面我们看到了重试条件都是在发生异常的时候,实际上有时候没有发生异常,但是

2016-12-26 16:32:32 4369

原创 加密算法之:对称加密与非对称加密扫盲贴

对称加密:加密(encryption)与解密(decryption)使用的是同样的密钥(secret key)。优点:算法公开、计算量小、加密速度快、加密效率高,缺点:秘钥的管理和分发非常困难,不够安全。非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(简称公钥)和私有密钥(简称私钥)。优点:安全性更高,缺点:加密和解密花费时间长、速度慢。

2016-12-25 11:08:16 10174

原创 消息摘要及其算法扫盲贴

1、无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。2、只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同。3、消息摘要是单向、不可逆的。4.好的摘要算法,没有人能从中找到“碰撞”,虽然“碰撞”是肯定存在的。即无法找到两条不同消息,但是它们的摘要相同。消息摘要保证了消息的完整性,消息摘要不需要秘钥,不存在秘钥的保管和分发问题。

2016-12-24 15:10:40 6117 3

原创 java重试工具库: 实现业务逻辑与重试逻辑的解耦

对于开发过网络应用程序的程序员来说,重试并不陌生,由于网络的拥堵和波动,此刻不能访问服务的请求,也许过一小段时间就可以正常访问了。随着重试逻辑的不断变化,上面代码会越来越复杂。而且重试逻辑,其实是各个模块是差别不大的。最近遇到2个开源项目,都是将重试代码封装成专门的工具,方便使用,比如guava-retrying和spring-retry。

2016-12-23 15:57:06 6549 2

原创 maven项目常用技巧:将依赖打包到文件夹并生产可执行的jar

maven打包依赖到文件夹,并生成可执行jar

2016-12-16 14:12:52 1607

原创 maven项目常用技巧: profile与资源过滤

一般的项目都会运行在不同的环境上,比如我们有本地环境、开发环境、测试环境、生产环境等等。这些不同的环境,必然有不同的配置。比如日志级别,开发环境我们一般设置成debug,而生产环境一般设置成warn。我们肯定不希望:手动修改项目配置文件,然后才打包发布到不同的环境。通过maven的profile和资源过滤,我们只需要在不同的环境激活对应的profile,配置信息就会自动改变,不需要我们取修改项目中的代码或者配置文件,所有变量都是定义在pom.xml中的。

2016-12-16 13:35:00 2060 1

原创 Guava Cache特性:refreshAfterWrite只阻塞回源线程,其他线程返回旧值

真正加载数据的那个线程一定会阻塞,我们希望这个加载过程是异步的。这样就可以让所有线程立马返回旧值,在后台刷新缓存数据。refreshAfterWrite默认的刷新是同步的,会在调用者的线程中执行。我们可以改造成异步的,实现CacheLoader.reload()。

2016-12-07 13:13:05 27008 1

原创 Guava Cache特性:对于同一个key,只让一个请求回源load数据,其他线程阻塞等待结果

使用Guava确实可以做到:对于同一个key,无论有多少请求,都只会允许一个线程去加载数据。但是也有一个很致命的缺陷:上面8个线程中,有一个线程实际去加载数据,其余7个线程都被阻塞了。如果能做到,当一个线程去加载数据,其余线程发现这个数据正在加载中,那么直接读取老的数据,这样就不会阻塞了。既然是缓存,读取旧一点数据也没有多大问题,却可以提高系统吞度量。

2016-12-06 19:48:44 6484 1

原创 Guava Cache之Cache接口

1、通过put或putAll手动向Cache中添加数据,guava不缓存value是null的key。我们可以在系统启动的时候,就将某些数据手动放入缓存中,这样就可以避免系统启动后,第一个用户访问缓存不能命中的情况。2、通过getIfPresent/getAllPresent/get读取缓存中的数据。3、如果明确知道某些缓存无用,我们可以通过invalidate/invalidateAll删除。4、通过调用cleanUp执行缓存清理操作,比如删除过期的key。

2016-12-06 19:06:55 5141

转载 pom配置之:<distributionManagement>snapshot快照库和release发布库

maven会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。如果是快照版本,那么在mvn deploy时会自动发布到快照版本库中,而使用快照版本的模块,在不更改版本号的情况下,直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。如果是正式发布版本,那么在mvn deploy时会自动发布到正式版本库中,而使用正式版本的模块,在不更改版本号的情况下,编译打包时如果本地已经存在该版本的模块则不会主动去镜像服务器上下载。

2016-11-25 11:23:45 71343 5

原创 spring+mybatis+druid数据源+sharding-jdbc分库分表

spring+mybatis+druid数据源+sharding-jdbc分库分表

2016-11-23 09:38:57 21095 7

原创 Guava Cache 缓存数据被移除后的监听器RemovalListener

guava的容量管理,有4种方式可以将数据从缓存中移除。有的时候,我们需要在缓存被移除的时候,得到这个通知,并做一些额外处理工作。这个时候RemovalListener就派上用场了。监听器有几个特点需要注意下:1、默认情况下,监听器方法是被同步调用的(在移除缓存的那个线程中执行)。2、创建cache的时候只能添加1个监听器,这个监听器对象会被多个线程共享,所以如果监听器需要操作共享资源,那么一定要做好同步控制。3、监听器中抛出的任何异常,在被记录到日志后,会被guava丢弃,不会导致监听器不可用。

2016-11-11 12:55:00 16204

原创 Guava Cache缓存容量管理

内存空间是有限的,一些不用的缓存数据需要及时清除,否则容器导致内存溢出。guava最简单一种管理方式是:基于缓存数据个数,让缓存条目始终不能超过一个上限。guava还提供基于权重的容量管理,相当于是让不同的缓存项占用不同的存储空间。最后guava还提供了基于引用的回收策略,CacheBuilder.weakKeys()、CacheBuilder.weakValues()、CacheBuilder.softValues()。当JVM回收弱引用指向的对象之后,会将弱引用加入到ReferenceQueue。通过轮

2016-11-10 20:40:27 9321

原创 Guava Cache的Ticker

缓存一般设置的都有过期时间,如果我们写单元测试代码需要验证这个功能(缓存过期,自动删除)。假如设置的过期时间是1个小时,我们来验证1h后缓存是否被删除,那我们总不能让单元测试代码运行1个小时吧。总之,ticker就是用来做测试用途,能够让我们改变时间源,模拟任何我们想要的时间流逝效果。

2016-11-10 13:37:28 2468

原创 windows下开启mySQL5.7的binlog

windows下开启binlog之后重启mysql服务即可(服务名是MySQL57)有一点需要注意下:my.ini配置文件并不在安装目录下,看

2016-11-10 12:59:32 6772 2

原创 Guava Cache的缓存统计

guava cache很适合做进程内的缓存,本文先学习下它的缓存统计功能,需要使用recordStats()打开缓存统计功能。有一点需要注意下:可以通过修改底层map给缓存添加数据,也可以获取数据。通过map获取数据,不会影响缓存统计;通过map添加数据,会影响evictionCount。

2016-11-08 10:53:33 7656

原创 spring容器初始化时候遇到的死锁问题

spring容器在初始化bean的时候,会对singletonObjects对象加锁;我们自己在afterPropertiesSet()方法中开启了一个线程,最终也会触发spring加载另外的bean。第一个线程(初始化spring的main线程)还没有释放锁,第二个线程(自己开启的线程),也需要获取singletonObjects对象锁,这样就出现了死锁

2016-11-04 17:46:02 4514 2

eclipse最常用的快捷键

这是我个人从网上整理出来的快捷键,日常很常用的列在这里。而且比较清晰,欢迎大家下载。在eclipse提高开发效率

2012-10-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除