Java 基于权重按比例分配算法

public class WeightRandomStrategy<K, V extends Number> {
    private TreeMap<Double, K> weightMap = new TreeMap<>();

    public WeightRandomStrategy(List<Pair<K, V>> list) {
        for (Pair<K, V> pair : list) {
            double lastWeight = this.weightMap.size() == 0 ? 0 : this.weightMap.lastKey();
            this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());
        }
    }

    public K random() {
        double randomWeight = this.weightMap.lastKey() * Math.random();
        SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);
        return this.weightMap.get(tailMap.firstKey());
    }
}
List<Pair<String, Integer>> list = new ArrayList<>();
list.add(new ImmutablePair<>("TR", 90));
list.add(new ImmutablePair<>("TX", 10));
WeightRandomStrategy<String, Integer> strategy = new WeightRandomStrategy<>(list);
int a = 0, b = 0;
for (int i = 0; i < 10000; i++) {
    switch (strategy.random()) {
        case "TR":
            a++;
            break;
        case "TX":
            b++;
            break;
        default:
            break;
    }
}
System.out.println("a=" + a + ", b=" + b);
System.out.println("a+b=" + (a + b));

---------------------------------------------------output
a=8993, b=1007
a+b=10000

ThreeTen Extra 时间日期处理利器

  最近一些需求有对多个时间区间进行判断,例如交集之类的,而2个时间区间可以多达13种情况,实现起来特别容易绕晕,正好找到这样一个工具类可以满足需求,只需要一个方法便可计算出结果,很方便。ThreeTen 的设计里面 Instant 表示时间点,Interval 表示时间段,使用Interval即可对区间进行判断。

  例如:判断是否有交集(Overlaps)

Instant startA = Instant.parse("2018-08-01T00:00:00Z");
Instant stopA = Instant.parse("2018-08-10T00:00:00Z");
Instant startB = Instant.parse("2018-07-30T00:00:00Z");
Instant stopB = Instant.parse("2018-08-02T00:00:00Z");

Interval areaA = Interval.of(startA, stopA);
Interval areaB = Interval.of(startB, stopB);
boolean flag1 = areaA.overlaps(areaB);

  同样的,还有是否邻接、包含、相等、之前,之后等等。当然,除了Interval,还有别的类可以用,非常强大。官方文档也非常详细。

  官网链接:https://www.threeten.org/threeten-extra/index.html

  Maven

<dependency>
    <groupId>org.threeten</groupId>
    <artifactId>threeten-extra</artifactId>
    <version>1.4</version>
</dependency>

Podam 一个Pojo填充随机值利器

  开发中常常遇到需要Mock数据来测试功能是否完整,手动一个一个填数据有点浪费时间,最近找到这样一个小工具,非常方便的给Pojo类所有字段填上随机值,非常好用,这里推荐下。

官网:https://mtedone.github.io/podam/

使用方法:

1、添加Maven依赖

<dependency>
    <groupId>uk.co.jemos.podam</groupId>
    <artifactId>podam</artifactId>
    <version>7.1.1.RELEASE</version>
</dependency>

2、基础使用

public class Case {
    private Long id;
    private Long applyId;
    private Long billId;
    // get/set ......
}

PodamFactory factory = new PodamFactoryImpl();
Case case = factory.manufacturePojo(Case.class);

  就这样简单的调用,case这个对象的三个字段都是随机值了,基本上满足测试需求,当然Podam远不止这么简单。

OAuth2 与 JWT 那些事

  自从微博流行后,OAuth2 概念自然也在开发圈里活跃起来,各种微博客户端雨后春笋般出现。到后来的 Web 前后端分离流行起来后,JWT 又映入眼帘。
  15年花图相册上线后,自认为在PC上看图已经有很好的体验了,做到极致的响应式页面能适配从手机屏到4K屏。经过一年多的使用,并没达到之前的预料,这一Geek般操作在实际使用中还是有很多不足,这里就不列举了。
  为此何不针对不同平台,分别做一套程序,并调整不同的功能。例如微信小程序,仅提供基础浏览,分享某一个相册,隔离其他相册。基于这些点的考虑,有很多技术方案选型。本文简单聊聊 OAuth2 和 JWT。

  Oauth2有四个角色非常重要

  Resource Owner 资源拥有者
  Resource Server 资源服务器
  Authorization Server 授权服务器
  Client 客户端

  举个例子:

  用户拥有花图相册上的照片资源(PC端upload),花图服务器提供存放这些照片资源,同时提供授权服务。这时候,如果有一个【花图App】用户将其装在手机上,选择使用花图账号登录,跳转到一个花图相册登录界面,随后进行授权确认。再返回App中,App便可以与花图服务器进行交互,获取到用户照片资源,显示出来。这里面还有很多细节如:AppId,AppSecret,Grant,Access_Token,Refresh_Token,Expires等不具体描述了。

  JWT本质只是提供了一种 Client 与 Server 间交互数据的协议,提供编码,防篡改等一些特性,通常与一些权限框架结合使用,例如 Shiro、Security 等。通过自定义 Token 签发一定程度上取代 Web 里面的 Session。

  Spring Boot 对着两种技术均有支持,还挺方便的,后续用到再细写。

Spring Boot 2.0 goes GA

  经过 17 个月的酝酿,来自 215 个不同开发者,超过 6800 个 commits 之后,终于迎来了一个全新的 2.0 版本现在如期而至!
  可以通过 repo.spring.ioMaven Central 下载使用。
  而此次发布距离 1.0 版本已经过去了4个年头,这也是第一个开始全面支持 Spring Framework 5.0 。

  主要包括以下新特性:
1、支持 Java 9,最低支持 Java 8
2、支持 Reactive Web 编程
3、对 Reactive Spring Data 提供自动配置项,包括 Cassandra/MongoDB/Couchbase/Redis
4、内嵌 Netty 高性能网络框架
5、内嵌容器 Tomcat/Undertow/Jetty 开始支持 HTTP/2
6、提供 Kotlin 语言支持
7、提供 Jersey 和 WebFlux 支持
8、提供全新的 Micrometer 统计支持
9、提供 Quartz 定时任务支持
10、安全配置优化

  更多新特性了解,可以浏览这里:release notes,老版本迁移看这里:migration guide,还有熟悉的start bootstrap:start.spring.io