编程技术
文章平均质量分 78
菠萝-琪琪
这个作者很懒,什么都没留下…
展开
-
缓存中间件Caffeine超详细源码解读
读源码是一件非常复杂、困难、枯燥的过程,这个复杂过程我给大家踩了,各位看官躺平看就行啦。原创 2023-02-12 18:28:11 · 2258 阅读 · 0 评论 -
Hbase 深度使用分析
循环put...那是不可能的..可以使用put(List puts) 需要注意的是当一部分数据插入成功后,此时某个RegionServer出现异常,之前的数据是不会回滚的,对于插入失败的数据hbase默认会进行重试直到到达最大重试次数还是失败即会结束重试(失败数据在写缓冲区),不过如果列族错误了,那么不会进行重试,直接抛出异常get(List gets) 返回一个Result数组,如果一部分数据失败,一部分数据查询成功,最终hbase还是会返回异常,如果你希望不要抛出异常而是返回成功部分......原创 2022-06-21 00:08:29 · 1094 阅读 · 0 评论 -
Java 函数式编程的妙用
Jdk8之后新增的一个重要的包 :java.util.function该包下所有的接口都是函数式接口, 按分类主要分为四大接口类型:Function、Consumer、Predicate、Supplier 接口 参数 返回值 说明 Supplier 无 T 供给型:无参,返回一个执行泛型对象 Consumer ...原创 2021-09-30 13:51:00 · 376 阅读 · 0 评论 -
Sonar-扫描插件自定义扩展
数据平台-研发一组-得物版Sonar开发规约已经制作完成阿里很早之前出过一个流传在坊间的《Java开发手册.pdf》,这个里面定义了很多开发规范,其中最基本必须要遵守的规范阿里出了一套Sonar插件来帮助扫描说的开发插件其实本质就是利用源设计者留下的入口拿到源事件然后进行实现,最终你的实现会在你不知道的时间,不知道的地点被调度执行,这就是设计模式的魅力,保证了开闭原则下进行了功能扩展那么Sonar的设计者为我们留下了哪些入口呢?这个时候我们经常会百度、谷歌,一...原创 2021-06-13 08:30:07 · 3898 阅读 · 1 评论 -
地球上目前最好的本地缓存框架:Caffeine
Guava Cache这个是一开始大家用的本地缓存框架,他极大的简化了我们操作缓存时需要考虑的丢弃策略、刷新策略等等....并且当时这个框架的各方面性能也是要高于Ehcache2框架的但是时代再次发生了变化 ----------------------------------------华丽的分割线Caffeine 框架横空出世显来几个性能测试报告来做开胃菜GuavaCache 和 Caffeine两个框架最根本的区别就在于淘汰策略的算法上:LRU 算法(G...原创 2021-05-17 17:28:30 · 1031 阅读 · 0 评论 -
Redis 优雅删除BigKey
危害内存空间不均匀(平衡):如 Redis Cluster 中,bigkey 会造成节点的内存空间分布不均匀 超时阻塞:由于 Redis 单线程的特性,操作 bigkey 会较耗时,意味着阻塞 Redis 可能性较大。 网络阻塞:获取 bigkey 的网络传输较大,不仅影响客户端,而且影响其他节点;如:bigkey 为 1MB,每秒 1000次,每秒产生的流量 1000MB/s如何发现redis-cli --bigkeys可统计 bigkey 的分布 判定一个 key 是否为 bigkey.原创 2021-05-05 20:39:50 · 564 阅读 · 0 评论 -
Redis 开发规范+Bigkey处理
一、键值设计1. key名设计(1)【建议】: 可读性和可管理性以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:idugc:video:1(2)【建议】:简洁性保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,例如:user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid}。(3)【强制】:不要包含特殊字符反例:包含空格、换行、单双引号以及其他转义字符详细解析2.原创 2021-05-02 20:51:20 · 178 阅读 · 0 评论 -
System.currentTimeMillis() 真的还能用吗?
很多同学在项目中会有需要打印代码执行时间的需求,那么我们的代码一般会是下面这样的可是你真的了解过当你的系统是一种高并发应用要求极限QPS的时候这种方式对你系统的伤害嘛?HotSpot源码的hotspot/src/os/linux/vm/os_linux.cpp文件中,有一个javaTimeMillis()方法,这就是System.currentTimeMillis()的native实现。调用gettimeofday()需要从用户态切换到内核态;gettimeofday()的表现受Linux系原创 2021-04-30 10:38:26 · 513 阅读 · 0 评论 -
Netty 自定义编码、解码器案例
Netty内置了很多编码、解码器,例如MsgPack、Protobuf,这些二进制编码器的性能都非常高,远远高于Java内置的序列化、反序列化的性能但是出于各种原因,我们有时候需要自定义编码、解码,一般做法都是将消息分为几段(消息头初始标记、消息体长度标识、消息校验Token、消息体内容),通过预定义的各个分段的长度直接获取进行匹配校验Netty也提供了各种扩展口给到上层应用自行扩展,下面就是一个Demo案例定义message类,消息的主类package netty.customco.原创 2021-04-07 22:17:08 · 882 阅读 · 0 评论 -
Netty中ChannelOption属性含义
属性 含义 ChannelOption.SO_KEEPALIVE Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE,该参数用于设置TCP连接,当设置该选项以后,连接会测试链接的状态,这个选项用于可能长时间没有数据交流的连接。 当设置该选项以后,如果在两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文。 ChannelOption.ALLOCATOR 也是默认值,使用对象池,重用缓冲区 Cha原创 2021-04-03 22:37:19 · 804 阅读 · 0 评论 -
Java 最优雅关闭线程池得两种方式
注册钩子函数 private static void shutDownThreadPool(){ Runtime.getRuntime().addShutdownHook( new ShutdownHookThread(log,() -> { poolExecuteConcurrentHashMap.forEach( (k,v) -> { if(Optional.ofNullable( v ).isPresent原创 2021-04-02 22:56:13 · 1071 阅读 · 1 评论 -
NIO-ByteBuffer API使用详解(堆外内存)
bytebuffer其实就是缓存区,缓冲区就是在内存中预留指定大小的存储空间对I/O数据作临时存储,这部分内存空间即为缓冲区。使用缓冲区可以减少动态分配和回数内存的次数。在java NIO中,缓冲区的作用也是用来临时存储数据。缓冲区可以看作通道(channel)与客户端(或服务器)的中转站,写入数据到channel或者从channel中读取数据,这样利于数据的高效读写。一、 Fields所有缓冲区都有四个属性:capacity、limit、position、mark,并遵循:mark <= p原创 2021-03-25 13:27:21 · 734 阅读 · 0 评论 -
Lambda底层原理最强解析
最近再次重温Lambda函数编程这本书的时候,思考起第一次看这本书只是为了了解如何深入使用Lambda,却没有去思考为什么可以Lambda了,话比较绕口~~哈哈你可能会好奇Java编译器是如何实现Lambda表达式,而Java虚拟机又是如何对它们进行处理的。如果你认为Lambda表达式就是简单地被转换为匿名类,那就太天真了。由于Lambda表达式提供了函数式接口中抽象方法的实现,这让人有一种感觉,似乎在编译过程中让Java编译器直接将Lambda表达式转换为匿名类更直观。不过,匿名类有着种种不尽如人原创 2021-03-20 10:52:57 · 1835 阅读 · 0 评论 -
AtomicInteger超级升级版LongAdder详解
LongAdder原理分析AtomicLong通过CAS提供了非阻塞的原子性操作,相比使用阻塞算法的同步器来说它的性能已经很好了,但是JDK开发组并不满足于此。使用AtomicLong时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS操作会成功,这就造成了大量线程竞争失败后,会通过无限循环不断进行自旋尝试CAS的操作,而这会白白浪费CPU资源。因此JDK 8新增了一个原子性递增或者递减类LongAdder用来克服在高并发下使用AtomicLong的缺点。既然Ato原创 2021-03-17 11:05:18 · 544 阅读 · 0 评论 -
大厂面试必问:FP/OOP 编程范式
函数式编程(Functional Programming, FP)是一种编程范式——一种构建计算机程序结构和元素的方式,它将计算视为数学函数的评估,并避免改变状态和可变数据。面向对象编程(Object-oriented Programming, OOP)是一种基于“对象”概念的编程范式,它可以包含字段(通常称为属性或属性)形式的数据,以及过程(通常称为方法)形式的代码。FP 与 OOP 的区别计算机著名定论:程序 = 数据结构 + 算法无论什么编程范式,都必须处理数据结构和算.原创 2021-03-11 10:51:05 · 2761 阅读 · 0 评论 -
CountDownLatch升级版同步器Phaser
Phaser得功能远比CountDownLatch和CyclicBarrier更加强大,在特定场景中可以发挥更加重要得作用用Phaser替代CountDownLatch从JDK7开始,新增了一个同步工具类Phaser,其功能比CyclicBarrier和CountDownLatch更加强大。1.用Phaser替代CountDownLatch考虑讲CountDownLatch时的例子,1个主线程要等10个worker线程完成之后,才能做接下来的事情,也可以用Phaser来实现此功能。在CountDow原创 2021-03-09 22:35:11 · 257 阅读 · 0 评论 -
DDD 领域驱动设计
领域驱动设计之领域模型2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。领域驱动设计分为两个阶段:以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;由领域模型驱动软件设计,用代码来实现该领域模型;由此可见,领域驱动设计的核心是建立正确的领域模型。为原创 2021-03-09 10:58:50 · 924 阅读 · 0 评论 -
面试经典必问:ReentrantLock 中CLH队列
ReentrantLock 中的加锁操作都是通过Syn这个抽象类来完成,具体解析在之前得博客已经分析过了,请参考:ReentrantLock AQS操作解析得不到锁的线程,如何排队?JUC中锁的排队策略,是基于CLH队列的变种实现的。因此,我们先看看啥是CLH队列CLH队列如上图所示,获取不到锁的线程,会进入队尾,然后自旋,直到其前驱线程释放锁。可能会有同学问为啥有2种指针在node上面,这个之后会在解释这样做的好处:假设有1000个线程等待获取锁,锁释放后,只会通知队列中的第一个线程原创 2021-03-05 13:58:07 · 1694 阅读 · 0 评论 -
Java 并发编程如何入门
书籍阅读:方腾飞的《Java并发编程的艺术》(虽然豆瓣上的评价一般,但是对于构建Java并发的整体映像还是有所提高的,至少我知道了有哪些东西要深入学习) 《The Art of Multiprocessor Programming》这本书比较艰涩,不是很好懂,但是过一遍还是好处多多,建议初学者了解下概念的过过,后期可以再来翻看 《Java Concurrency in Practice》这本书号称Java并发编程的圣经,确实可以看出作者有很丰富的并发实践经验学习心得 -- Java并发包的基础..原创 2021-03-04 13:32:13 · 223 阅读 · 1 评论 -
Netty 入门教程
Netty是Java程序员必须要掌握的一项技能,Netty是一个非常优秀的网络编程框架,熟练掌握可以让我们省下很大一部分网络编程的工作Netty是什么? 官方定义:Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。 简单地说Netty封装了JDK的NIO,不用再写一大堆复杂的代码。既然代替了原生的NIO,肯定有比它好的理由,主要有如下几点: 1.Netty底层IO模型可以随意切换,比如可以从NIO切换到BIO,但一般很少会这么做。 2.Net原创 2021-03-04 11:06:10 · 759 阅读 · 2 评论 -
EasyRules 简单版规则引擎
接触过Drools的同学都会被复杂的Api给难住,简直就是入门到放弃的一个过程,而EasyRule就是Drools的简化版,裁剪了部分使用场景非常少的复杂功能,也简化了很多Drools中的组件,这样我们在使用EasyRule的时候对于API理解就非常容易了什么是Easy Rules?Easy Rules是一个简单的JAVA开源规则引擎,它提供了规则抽象来创建带有评估条件和执行操作的规则,规则引擎API通过运行一组规则以评估条件和执行操作。框架特点轻量级类库 容易学习的API 基于POJO原创 2021-03-03 10:38:45 · 4220 阅读 · 1 评论 -
MongoTemplate 聚合查询
一、概述1.聚合的表达式MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。下表展示了一些聚合的表达式:表达式 描述 实例 $sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) $avg 计算平均值 db.my.原创 2021-03-02 21:23:25 · 4847 阅读 · 0 评论 -
Java 动态追踪技术
JDK 1.5出现的API:java.lang.instrument.Instrumentation看完文档之后,我们发现这么两个接口:redefineClasses和retransformClasses。一个是重新定义class,一个是修改class。这两个大同小异,看reDefineClasses的说明:This method is used to replace the definition of a class without reference to the existing class原创 2021-02-27 22:46:12 · 1026 阅读 · 0 评论 -
强大的语法生成器:Antlr 使用
ShardingJDBC内部使用的也是Antlr4来做语法生成器的,当初在看sharding源码的时候被很多.g4结尾的文件迷惑住了,后来才知道原来这个就是Antlr4Antlr他不单单只可以分析SQL,Druid内部使用的是Sql-parse框架来做SQL解析的,这个框架也很优秀但是局限于SQL解析Antlr 是一款强大的语法生成器工具,可用于读取、处理、执行和翻译结构化的文本或二进制文件。基本上是当前 Java 语言中使用最为广泛的语法生成器工具。Twitter搜索使用ANTLR进行语法分析,每原创 2021-02-23 22:51:05 · 2885 阅读 · 0 评论 -
面试经典问:现在有一个很大量的秒杀场景,应该怎么处理?
相信很多5年以上工作经验的同学在面试的时候经常会被问道:现在有一个很大量的秒杀场景,应该怎么处理?很多同学的第一反应回答80%都是: 用Redis来做缓存,防止超卖也能保证一定的性能...当你说出这个回答的时候恭喜你你已经成功入坑了,大多数面试官会直接跳过这个问题不在深入追问(因为你连第一个问题都没回答到面试官心坎里,面试官已经放弃问你这个问题了)那么我们应该怎么回答才能让伟大的面试官满意呢?需要同学门深思熟虑下面试官的意图,秒杀场景 == redis??显然不是这样的(太多同学的思维.原创 2021-02-18 11:05:47 · 2358 阅读 · 5 评论 -
解锁面试必问题:ThreadLocal 正确姿势
ThreadLocal 百度上面对于他的解释已经非常非常多了,但是很多其实都是复制来复制去,并且很多都是说的错的,最离谱的是百度上面头几页说ThreadLocal在Set的时候内部的ThreadLocalMap存放的Key是当前线程对象...,真的简直在虾扯蛋,不知道误导了多少人ThreadLocal的API非常简单,这里就不在描述了,主要针对他源码以及设计思路来分析设计者的用意,要了解ThreadLocal原理那么先要了解Thread和ThreadLocalMap是啥...Thread是Java种原创 2021-02-17 22:01:00 · 135 阅读 · 0 评论 -
Java 阻塞队列原理
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。阻塞队列提供了四种处理方法:方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e)原创 2021-02-15 19:48:56 · 1799 阅读 · 0 评论 -
SpringBoot 2.X启动流程解析
本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。总览: 上图为SpringBoot启动结构图,我们发现启动流程主要分为三个部分,第一部分进行SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器,第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块,第三部分是自动化配置模块,该模块作为springboot自动配置核心,在后面的分析中会详...原创 2021-02-07 15:23:13 · 395 阅读 · 0 评论 -
Java 实现归并排序
归并排序的流程其实很简单:先分解再合并,整个排序的时间复杂度是稳定的:nlongn,再百万级数据量的排序大致维持在0.5 ~ 1s内下面是拆分的流程图:下面是合并的流程图:动态效果图:代码实现:/** * <p>Title:归并排序</p> * <p>Description:</p> * * @author QIQI * @date */public class GuibinSort { public s原创 2021-02-03 14:59:15 · 140 阅读 · 0 评论 -
TCP 协议中的滑动窗口使用
滑动窗口协议:TCP协议的使用 维持发送方/接收方缓冲区 缓冲区是 用来解决网络之间数据不可靠的问题,例如丢包,重复包,出错,乱序在TCP协议中,发送方和接受方通过各自维护自己的缓冲区。通过商定包的重传机制等一系列操作,来解决不可靠的问题。问题一:如何保证次序?提出问题:在我们滑动窗口协议之前,我们如何来保证发送方与接收方之间,每个包都能被收到。并且是按次序的呢?发送方发送一个包1,这时候接收方确认包1。发送包2,确认包2。就这样一直下去,知道把数据完全发送完毕,这样就结束了.原创 2021-02-01 20:51:05 · 438 阅读 · 0 评论 -
ThreadPoolExecutor线程池实现原理及其实践
随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池:ThreadPoolExecutor类,帮助开发人员管理线程并方便地执行并行任务。了解并合理使用线程池,是一个开发人员必修的基本功。1.1 线程池是什么线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL。线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的原创 2021-01-28 00:46:45 · 535 阅读 · 0 评论 -
Lombok 安装以及使用大全
安装打开 IDEA 的 Settings 面板,并选择 Plugins 选项,然后点击 “Browse repositories”在输入框输入”lombok”,得到搜索结果,点击安装,然后安装提示重启 IDEA,安装成功;引入依赖在自己的项目里添加 lombok 的编译支持,在 pom 文件里面添加 dependency<dependency> <groupId>org.projectlombok</groupId> <a.原创 2021-01-26 17:51:32 · 117 阅读 · 0 评论 -
大厂面试中常问的栈排序
很多大厂的笔试题中都会要求面试者写一段栈排序,因为栈这个数据结构平时我们用的比较少,导致很多面试者一下子都有点懵逼,这里就来给大家解惑一下吧题目:一个栈中有10个随机大小的元素,这个是初始栈 可以让你申请一个空栈作为交换使用 不准使用任何其他数据结构进行存储 最终按照从小到大的顺序输出原始栈思路:Stack这个数据结构的核心API我们必须要了解下,不然真的无从下手,Pop,Push,Peek三种核心操作 Pop会让栈顶数据出栈,同时删除原始栈顶的数据 Push添加元素到栈顶 .原创 2021-01-26 00:31:13 · 148 阅读 · 0 评论 -
CMS 常见问题分析和解决方案
1.0引言自 Sun 发布 Java 语言以来,开始使用 GC 技术来进行内存自动管理,避免了手动管理带来的悬挂指针(Dangling Pointer)问题,很大程度上提升了开发效率,从此 GC 技术也一举成名。GC 有着非常悠久的历史,1960 年有着“Lisp 之父”和“人工智能之父”之称的 John McCarthy 就在论文中发布了 GC 算法,60 年以来, GC 技术的发展也突飞猛进,但不管是多么前沿的收集器也都是基于三种基本算法的组合或应用,也就是说 GC 要解决的根本问题这么多年一直都.原创 2021-01-25 00:34:17 · 6210 阅读 · 2 评论 -
聊聊JNDI
概念JNDI(Java Naming and Directory Interface ),类似于在一个注册中心注册一个东西,以后要用的时候,只需要根据名字去注册中心查找,注册中心返回你要的东西。web程序,我们可以将一些东西(比如数据库相关的)交给服务器软件去配置和管理(有全局配置和单个web程序的配置),在程序代码中只要通过名称查找就能得到我们注册的东西,而且如果注册的东西有变,比如更换了数据库,我们只需要修改注册信息,名称不改,因此代码也不需要修改。String jndiName= ...;原创 2021-01-17 22:37:36 · 102 阅读 · 0 评论 -
Java8 Optional优雅空值判断
API介绍先介绍一下API,与其他文章不同的是,本文采取类比的方式来讲,同时结合源码。而不像其他文章一样,一个个API罗列出来,让人找不到重点。1、Optional(T value),empty(),of(T value),ofNullable(T value)这四个函数之间具有相关性,因此放在一组进行记忆。先说明一下,Optional(T value),即构造函数,它是private权限的,不能由外部调用的。其余三个函数是public权限,供我们所调用。那么,Optional的本质,就是内原创 2021-01-15 12:48:06 · 3843 阅读 · 5 评论 -
Java11 ZGC垃圾回收器
一、简介Java 11包含一个全新的垃圾收集器--ZGC,它由Oracle开发,承诺在数TB的堆上具有非常低的暂停时间。 在本文中,我们将介绍开发新GC的动机,技术概述以及由ZGC开启的一些可能性。那么为什么需要新GC呢?毕竟Java 10已经有四种发布多年的垃圾收集器,并且几乎都是无限可调的。 换个角度看,G1是2006年时引入Hotspot VM的。当时最大的AWS实例有1 vCPU和1.7GB内存,而今天AWS很乐意租给你一个x1e.32xlarge实例,该类型实例有128个vCPU和3,90原创 2020-12-29 13:33:30 · 1141 阅读 · 0 评论 -
优秀的代码真的不需要注释吗?
我在很多地方看到这样一个观点,“请停止写注释,因为只有烂的代码才需要注释。”这个观点非常巧妙,它让我想起了孟子的一句话,“杨氏为我,是无君也;墨氏兼爱,是无父也。无父无君,是禽兽也。” 动不动就骂别人是“禽兽”,我总觉得有点不妥,这很不符合孟子的浩然之气啊。有些大牛也有孟子这样的觉悟,如果有人要他给自己的代码加上注释,就好像是对他的一种侮辱:“我的代码写...转载 2020-12-04 09:26:16 · 1069 阅读 · 1 评论 -
HashMap 死循定位以及JDK8对它的优化
HashMap 是非线程安全的,在多线程处理场景下,严禁使用。多线程要用ConcurrentHashMap。 大家都知道,相比于HashTable,HashMap是一个非线程安全的实现类。为什么说HashMap是非线程安全的呢?因为在高并发情况下,HashMap在一些操作上会存在问题,如死循环问题,导致CPU使用率较高。下面来看下怎么复现这个问题。如下代码所示,我们创建10个线程,这10个线程并发向一个HashMap种添加元素。package com.light.swordimport java..原创 2020-06-28 22:42:37 · 333 阅读 · 0 评论 -
Drools规则引擎接入详解
Drools是Jboss开源的一个规则引擎,简单来说就是一种运算速度极快且配置非常灵活的计算工具,这篇博客不分析底层实现了,因为互联网上面随便一搜就能发现很多介绍,但是真正去使用的博客却太少了,也许真正用的很深的不多大家都只是抄来抄去那些原理公司最近正好需要这么一个服务我们便开始研究起来并最终上线,其实在实践过程中遇到很多的坑,并且由于网上解决资料非常少导致耽误了不少时间,在这里写出来也是为了...原创 2019-09-04 16:00:42 · 5152 阅读 · 4 评论