Guava

全栈的自我修养: 0005 Java 包扫描实现和应用(Jar篇)

徘徊边缘 提交于 2020-08-11 15:07:47
全栈的自我修养: 0005 Java 包扫描实现和应用(Jar篇) It's not the altitude, it's the attitude. 决定一切的不是高度而是态度。 Table of Contents 依赖的 Jar 思路 完整代码 整合后代码 如果你曾经使用过 Spring , 那你已经配过 包扫描路径吧,那包扫描是怎么实现的呢?让我们自己写个包扫描 上篇文章中介绍了使用 File 遍历的方式去进行包扫描,这篇主要补充一下 jar 包的扫描方式,在我们的项目中一般都会去依赖一些其他 jar 包, 比如添加 guava 依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.2-jre</version> </dependency> 我们再次运行上次的测试用例 @Test public void testGetPackageAllClasses() throws IOException, ClassNotFoundException { ClassScanner scanner = new ClassScanner("com.google.common.cache", true, null, null); Set<Class<?>>

guava refreshAfterWrite 的使用

对着背影说爱祢 提交于 2020-08-11 15:04:57
曾经有个面试官我我guava的exipre和reflush的区别 我只指定,expire在更新缓存时会阻塞住所有线程 好伤心 其实reflush只会阻塞住一个线程,然后其他线程获取到原先的值,这样就不会将所有线程都阻塞了,代码如下 package com.test; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import java.time.LocalDateTime; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Client { public static void main(String[] args) throws ExecutionException {

Redis中的布隆过滤器及其应用

丶灬走出姿态 提交于 2020-08-11 12:27:41
一、 什么是布隆过滤器 布隆过滤器(Bloom Filter)是由Howard Bloom在1970年提出的一种比较巧妙的概率型数据结构,它可以告诉你某种东西 一定不存在 或者 可能存在 。当布隆过滤器说,某种东西存在时,这种东西可能不存在;当布隆过滤器说,某种东西不存在时,那么这种东西一定不存在。 布隆过滤器相对于Set、Map 等数据结构来说,它可以更高效地插入和查询,并且占用空间更少,它也有缺点,就是判断某种东西是否存在时,可能会被误判。但是只要参数设置的合理,它的精确度也可以控制的相对精确,只会有小小的误判概率。 二、Redis中布隆过滤器 之前的布隆过滤器可以使用Redis中的 位图(BitMap) 操作实现,直到Redis4.0版本提供了插件功能,Redis官方提供的布隆过滤器才正式登场。布隆过滤器作为一个插件加载到Redis Server中,就会给Redis提供了强大的布隆去重功能。 三、布隆过滤器的基本使用 在Redis中,布隆过滤器有两个基本命令,分别是: bf.add : 添加元素到布隆过滤器中,类似于集合的 sadd 命令,不过 bf.add 命令只能一次添加一个元素,如果想一次添加多个元素,可以使用 bf.madd 命令。 bf.exists : 判断某个元素是否在过滤器中,类似于集合的 sismember 命令,不过 bf.exists

创建线程池的正确姿势,请给它指定一个有意义的名字

坚强是说给别人听的谎言 提交于 2020-08-11 02:12:07
为什么我们创建线程或者线程池的时候,需要指定有意义的线程名称? 最终目的是为了方便回溯。 我们在日常开发中,一个项目中会创建很多个线程池用来资源隔离,但是如果我们没有一个好的命名的话,出问题的时候就会难以定位。 public class Demo5 { ​ public static void main( String[] args ) throws IOException { new Thread(()->{ System.out.println("保存用户信息.........."); ​ try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } throw new NullPointerException(); }).start(); System.in.read(); } } 上面代码是启动一个线程来保存用户信息,然后抛出异常! 报错信息如下: 从运行错误可以分析,Thread-0 抛出了空指针,那么单从这个日志根本无法判断用户模块线程抛出的异常。我们先分析一下Thread-0是怎么来的。 我们先看下创建线程的代码: public Thread(Runnable target) { init(null, target, "Thread-" +

限流工具类RateLimiter

陌路散爱 提交于 2020-08-10 21:58:04
https://www.cnblogs.com/LBSer/p/4083131.html 实战限流(guava的RateLimiter) https://blog.csdn.net/boling_cavalry/article/details/75174486 三种常见限流算法 https://www.cnblogs.com/linjiqin/p/9707713.html 来源: oschina 链接: https://my.oschina.net/u/3847203/blog/4418019

Guava系列之Cache

孤人 提交于 2020-08-09 20:30:53
缓存是日常开发中使用很频繁的一种提升性能的方式,它其实解决的是硬件层面性能不对等的问题,比如CPU、内存、硬盘之间性能的巨大差异,会严重影响数据的读取与传输,而缓存就是用来平衡这种性能差异的手段 缓存在很多系统和架构中广泛使用,如: CPU缓存 操作系统缓存 数据库缓存 分布式缓存 本地缓存 日常开发中的使用场景 在我们日常的开发中,当多次获取同一份数据而数据变化不频繁时,我们可以考虑使用缓存。 这里用到的就是内存和硬盘的性能不对等,我们知道内存的读取速度很快,而硬盘相对来说比较慢 而传统的关系型数据库把数据存储在硬盘上,这样在高并发读写的场景下,就会出现性能瓶颈 这个时候,如果在数据库前面加一层缓存,把数据库里面的热点数据缓存一份到内存中,读取的时候直接从内存中取,这样就可以大大的提升读取的性能 Guava中的缓存实现 Guava中的缓存是本地缓存的实现,与ConcurrentMap相似,但不完全一样。最基本的区别就是,ConcurrentMap会一直保存添加进去的元素,除非你主动remove掉。而Guava Cache为了限制内存的使用,通常都会设置自动回收 Guava Cache的使用场景: 以空间换取时间,就是你愿意用内存的消耗来换取读取性能的提升 你已经预测到某些数据会被频繁的查询 缓存中存放的数据不会超过内存空间 示例代码 @Test public void

线程池最佳实践!安排!

﹥>﹥吖頭↗ 提交于 2020-08-09 11:16:26
大家好,我是 Guide 哥,一个三观比主角还正的技术人。今天再来继续聊聊线程池~ 线程池最佳实践 这篇文章篇幅虽短,但是绝对是干货。标题稍微有点夸张,嘿嘿,实际都是自己使用线程池的时候总结的一些个人感觉比较重要的点。 线程池知识回顾 开始这篇文章之前还是简单介绍一嘴线程池,之前写的 《新手也能看懂的线程池学习总结》 这篇文章介绍的很详细了。 为什么要使用线程池? 池化技术相比大家已经屡见不鲜了,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。 线程池 提供了一种限制和管理资源(包括执行一个任务)。 每个 线程池 还维护一些基本统计信息,例如已完成任务的数量。 这里借用《Java 并发编程的艺术》提到的来说一下 使用线程池的好处 : 降低资源消耗 。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度 。当任务到达时,任务可以不需要的等到线程创建就能立即执行。 提高线程的可管理性 。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 线程池在实际项目的使用场景 线程池一般用于执行多个不相关联的耗时任务,没有多线程的情况下,任务顺序执行,使用了线程池的话可让多个不相关联的任务同时执行。

看完这篇Redis缓存三大问题,保你面试能造火箭,工作能拧螺丝。

不问归期 提交于 2020-08-09 10:33:40
前言 日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题。 一旦涉及大数据量的需求,如一些商品抢购的情景,或者主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度问题有严重的性能弊端,详细的磁盘读写原理请参考这一片 在这一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。 为了克服上述的问题,项目通常会引入NoSQL技术,这是一种基于内存的数据库,并且提供一定的持久化功能。 Redis 技术就是 NoSQL 技术中的一种。 Redis 缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。 但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。 另外的一些典型问题就是,缓存穿透、缓存击穿和缓存雪崩。本篇文章从实际代码操作,来提出解决这三个缓存问题的方案,毕竟Redis的缓存问题是实际面试中高频问点,理论和实操要兼得。 缓存穿透 缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据库的访问压力就会增大,缓存穿透的解决方案,有以下两种:

图解resilience4j容错机制

早过忘川 提交于 2020-08-09 10:33:23
Resilience4j是一个轻量级、易于使用的容错库,其灵感来自Netflix Hystrix,但专为Java 8和函数式编程设计。轻量级,因为库只使用Vavr,它没有任何其他外部库依赖项。相比之下,Netflix Hystrix对Archaius有一个编译依赖关系,Archaius有更多的外部库依赖关系,如Guava和Apache Commons。 Resilience4j提供高阶函数(decorators)来增强任何功能接口、lambda表达式或方法引用,包括断路器、速率限制器、重试或舱壁。可以在任何函数接口、lambda表达式或方法引用上使用多个装饰器。优点是您可以选择所需的装饰器,而无需其他任何东西。 有了Resilience4j,你不必全力以赴,你可以选择你需要的。 https://resilience4j.readme.io/docs/getting-started 概览 本文将介绍resilience4j中的四种容错机制,不过鉴于容错机制原理的通用性,后文所介绍的这几种容错机制也可以脱离resilience4j而独立存在(你完全可以自己编码实现它们或者采用其他类似的第三方库,如 Netflix Hystrix )。下面将会用图例来解释舱壁( Bulkhead )、断路器( CircuitBreaker )、限速器( RateLimiter )、重试( Retry

Redis-避免缓存穿透的利器之BloomFilter

依然范特西╮ 提交于 2020-08-09 04:02:03
Redis-避免缓存穿透的利器之BloomFilter 你知道的越多,你不知道的也越多 点赞再看,养成习惯 github.com/JavaFamily GitHub github.com/java… 上已经开源,有面试点思维导图,欢迎 【Star】 和 【完善】 # 前言 你在开发或者面试过程中,有没有遇到过 海量数据需要查重,缓存穿透怎么避免等等这样的问题呢?下面这个东西超屌,好好了解下,面试过关斩将,凸显你的不一样。 Bloom Filter 概念 布隆过滤器(英语:Bloom Filter)是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。 Bloom Filter 原理 布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。 Bloom Filter跟单哈希函数Bit-Map不同之处在于:Bloom Filter使用了k个哈希函数,每个字符串跟k个bit对应