java -- 95




1 2 3 4 5 6 7 8 9 10
概述在我们的开发中,api 接口调用异常是经常会遇到的,任何接口都会有不同概率的异常情况,对于可以重入的接口,为了避免偶发性异常造成的服务的不可用,重试机制就非常有必要了通常我们的接口超时都是符合正态分布的,即 99.9% 的请求超时时间都不会大于某个值,将这个值设置为请求的超时时间是比较合理的,因为即使将超时时间设置为该值的两倍或更高,按照正态分布的概率来看,请求成功率并不会有明显提高,而使用该值作为超时时间可以保证在 99.9% 的情况下请求正常返回,对于异常情况我们添加重试机制就可以大概率减少失败但是需要注意的是,我们的调用链通常是非常长的,如果在多个层级上都添加重试,那么最终将会造成雪崩效应,最底层将受到指数扩大的请求次数,这对于底层服务的压力是非常大的,因此重试的设置需要非常谨慎,这在底层服务出现问题时尤为明显,过度的重试将会成倍加剧问题的严重性,因此,在重试机制的同时增加递增的重试间隔时间或者熔断机制也是非常有必要的,有时间的话博主将会在博客中介绍用于业务熔断组件 Hystrix,敬请期待 guava 提供了非常优雅、方便的重试工具类 -- retryer maven 依赖<dependency> <groupId>com.g
#读书笔记    #技术帖    #龙潭书斋    #技术分享   
概述上一篇日志中,我们介绍了 Retryer 类guava 重试工具库 -- Retryer由于 Retryer 类构造方法参数较多,较为复杂,而使用 RetryerBuilder 要更加简洁明了,也是更加常用的方式 RetryerBuilder 的创建 -- newBuilderRetryerBuilder 的构造方法是 private 的,这也意味着我们不能通过 new 的方式直接创建 RetryerBuilder 对象RetryerBuilder 提供了一个 static 方法:public static <V> RetryerBuilder<V> newBuilder()  通过:RetryerBuilder retryer = RetryerBuilder.newBuilder(); 就可以创建一个 RetryerBuilder 了 Retryer 对象的创建通过 RetryerBuilder 提供的 build 方法就可以创建出一个 
#读书笔记    #技术帖    #龙潭书斋    #技术分享   
概述上一篇日志中,我们介绍了 guava 的 RangeSet 容器:区间集合 -- RangeSet本篇日志我们来介绍区间容器家族的另一个成员 -- RangeMapRangeSet 是一组区间的集合,然而有时,我们需要通过区间映射到一个值,也就是需要一个 map,他的 key 是 Range,value 是我们需要的值,这就是 RangeMap 的强大功能对于不同的时间段内,展示不同的文案等类似的功能,使用 RangeMap 将十分便捷 RangeMap 的实现类及创建方法RangeMap 的实现RangeMap 和 RangeSet 类似,拥有两个实现:TreeRangeMap -- 基于红黑树实现的拥有排序的 RangeMapImmutableRangeMap -- 不可变的 RangeMap 下面我们以 TreeRangeMap 为例来进行介绍 RangeMap 的创建方法TreeRangeMap 提供了 create 
#技术帖    #apache    #龙潭书斋    #java   
概述jdk 为我们提供了各式各样的容器,用来解决不同场景下的集合问题,但很多时候,我们需要维护的集合是连续跨度的范围,甚至是多段范围跨度的交集、并集,jdk 的容器就很难去支持了Guava 提供了 Range 类型,用来定义连续跨度的范围边界,并且这个连续跨度是一个可以比较的类型在此基础上,Guava 还提供了 RangeSet、RangeMap 实现多段范围边界集合的维护,在例如营业时间、允许的范围区间等问题的处理上,提供了前所未有的方便性一个 Range 对象定义了一段区间,对于一个区间,数学上有开区间和闭区间的区分,Range 的创建方法同样提供了对应的构造方式: 区间的创建Range 对象创建方法区间创建方法(a..b)open(C, C)[a..b]closed(C, C)[a..b)closedOpen(C, C)(a..b]openClosed(C, C)(a..+∞)greaterThan(C)[a..+∞)atLeast(C)(-∞..b)lessThan(C)(-∞..b]atMost(C)(-∞..+∞)all() 示例:Range.closed("left", "right"); //字典序
#java    #range    #集合    #guava   

200x200


概述刚刚接触 java 的同学通常会被 java 百花齐放的日志体系搞晕,错综复杂的日志框架包之间总是发生冲突,令人抓狂本篇日志就从历史上各个版本的 

#技术帖    #技术分享    #log    #java   

200x200


概述有时,多个对象需要依赖某个对象状态的变化,这就是典型的“发布-订阅”模式这样的系统由一系列相互协作的类构成,如何处理一对多的耦合呢?观察者模式就是为了处理这样的场景而存在的一个目标对象可能有任意数

#读书笔记    #技术帖    #龙潭书斋    #java   
概述在前面的博文中,我们介绍了 guava 的 Multimap 容器Key 可重复的 Map -- MultimapMultimap 是一种键可重复出现的 Map 容器,可以看作是实现了 Map<K, List<V>> 功能的容器在实际的使用中,有时我们还需要 Map<K, Map<T, V>> 这样的结构,例如,我们的一个超市中有多个货架,货架上有水果,我们需要通过货架 ID、对应货架上的水果 ID 获取到某种水果的信息,这样的数据结构如果用 Map<K, Map<T, V>> 这样的容器来存储和表示就显得非常丑陋了Guava 提供的 Table 容器解决了这个问题Guava 的 Table 是一个三元组,每一条记录需要用两个 Key 进行索引,也可以看做是一个 Map<K, Map<T, V>> 结构,每一个 V 的确定都必须提供&nbs
#技术帖    #龙潭书斋    #容器    #java   

200x200


概述其实各种面向对象编程语言大多提供了迭代器模式的实现和具体的工具类迭代器模式主要是提供一种顺序访问一个聚合对象中的各个元素的方法,而不需要关心具体对象的类型和内部表示,在有些语言中,也被称为“游标”

#技术帖    #龙潭书斋    #java    #面向对象   
概述有时我们需要维护一个双向映射,也就说,有时我们需要一个 key-value 的集合的同时还需要一个 value-key 的集合,那么,为了解决这个问题,我们需要维护两个 Map:Map<Long, String> fruitIdToName = new HashMap<>(); Map<String, Long> fruitNameToId = new HashMap<>(); fruitIdToName.put(2L, "apple"); fruitIdToName.put(3L, "banana"); fruitNameToId.put("apple", 2L);  上面的代码维护了两个 HashMap,分别是水果 Id 到水果名称的映射,和水果名称到水果 Id 的映射然而,维护两个 HashMap 的成本是很高的,你会发现在例子中,我们将无法通过 fruitIdToName 中存在的 banana 值作为 key 查找到 fruitNameToId&n
#技术帖    #龙潭书斋    #java    #集合   
概述上一篇日志中,我们介绍了 Guava 的可重复 key 的 Set -- Multiset 类型元素可重复的 Set -- Multiset本篇日志中,我们就来介绍 Guava 提供的另一个容器,可重复 key 的 Map -- Multimap 假设我们需要经营一家超市,超市中有若干库区,我们创建一个水果类,其中有两个字段,分别是水果的名称和所在库区号,那么现在我们需要了解一批水果中,每个库区各有多少水果,分别是什么,那么我们就需要这样的代码:package com.techlog.test.testspring.service; import java.util.*; /** * Created by techlog on 2017/4/3. */ public class WorkMain { private final static List<Fruit> FRUITS = Arrays.asList(new Fruit("apple", 1), new Fruit("bnana", 1), new Fruit("
#技术帖    #龙潭书斋    #容器    #list   
1 2 3 4 5 6 7 8 9 10



京ICP备15018585号