- 博客(51)
- 资源 (9)
- 问答 (2)
- 收藏
- 关注
原创 cpu飚高的排查思路
cpu的衡量指标使用率util:代表的是单位时间内CPU繁忙情况的统计。操作系统对cpu的管理就是利用周期的tick时钟中断,将cpu的使用划分时间片。每个时间片内去执行不同进程/线程里的代码。所以cpu的使用率统计其实也是以tick为单位的:统计周期内,有多少个tick是在执行进程/线程里的指令的。top、pidstat等工具查看到的cpu使用率是指统计周期内cpu的占用情况load:平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,
2023-06-06 09:02:47
2778
原创 jdk中juc多线程编程工具
Future其实是对将来某个时刻会发生的结果进行建模,封装了一种异步计算,返回这个异步计算结果的引用,通过这个引用可以获得运算的状态,以及当运算结束后可以通过这个引用获取异步运算的结果。这比直接使用Thread会好用很多。通过Future之所以能够获得子线程异步计算的结果,其本质是因为父子线程是共享使用了进程分配的资源。
2023-05-03 07:46:59
1112
原创 redis集群及数据淘汰简介
redis通过在slave上执行replicaof 主节点ip 主节点port来建立主从关系,当执行了这个命令时:建立主从关系会执行一次全量数据同步从节点发送psync请求给主节点主节点收到请求后,会生成一个全量的rdb文件,然后将rdb文件传输给从节点从节点收到rdb文件后,会先清空自己本地的数据,然后加载rdb文件。ps:这个过程是消耗比较大的。后续增量的修改,都会将修改命令异步同步给从节点。主从关系建立后,主节点所有对数据修改的命令都会同步给从节点,以此保证主从数据的一致。
2023-04-16 08:38:38
363
原创 基于redis实现分布式锁
中将锁的本质分成了两部分,来分析理解锁的本质,并结合了java中的锁从这两部分来分析理解锁标志的存储加锁时,遇到锁被占用该怎么办。分布式锁的本质也是个锁,其实同样是从这两方面来分析。锁标志的存储。对于线程锁,锁标志的存储就需要放到所有线程都可以访问的地方,而线程都是共享进程的资源的,所以毫无疑问,锁标志都是放到进程中的,这样进程下的线程都是可以访问到。
2023-04-16 08:08:37
449
原创 BIO/NIO/AIO/IO多路复用简介
bio、nio、aio、io多路复用、reactor模式io,在将IO的时候,是不是都遇到过这些概念,也有种傻傻分不清?甚至别人在大谈特谈的时候,一会nio,一会io多路复用,一会又搞到reactor模式上去了?这些概念到底是什么?什么关系?这些都是我曾经的疑问。这里说明一下这些概念,帮助理解redis的单线程+io多路复用实现高性能,因为很多其他这种需要IO的也使用了多路复用,但并不是单线程,比如netty,也实现了高性能的io,啥区别呢?下面就结合掌握的只是和理解,来尝试理清楚这些概念。
2023-03-31 20:14:36
795
原创 redis的IO及高性能
linux环境下,redis客户端和服务端的是通过linux提供的socket接口来实现网络通信的。这里简单介绍小socket的缓冲区,操作系统内核会为每个socket分配一个读缓冲区和写缓冲区,即socket的缓冲区是内核空间中内存区域:对于接收网络数据,内核是将接收的数据先存放在缓冲区的,应用线程是去缓冲区读取数据。如果应用线程读取数据的时候,缓冲区是空的,那就会阻塞应用线程(当然也有非阻塞的方式)
2023-03-30 19:55:59
871
原创 基础数据结构及常见应用
这个和查找第一个相等元素一模一样,无非就是第一个是向前找;而最后一个是向后找// 查找最后一个相等的int l = 0;if (mid == arr.length - 1) {// 防止mid+1越界return mid;// 最后一个小于等于int l = 0;// 中间比target大,那么第一个比target小的一定在左边} else {return mid;} else {
2023-03-27 11:41:14
708
原创 redis的数据结构
redis的全局hash表的桶位存储是个Entry结构,Entry里的value指针指向的是一个RedisObject结构,这个RedisObject才是真正承载value数据的结构。前面简单介绍了RedisObject包含两部分元数据和指针,其8字节的元数据进一步分成了4个字段8字节的元数据:type:value的类型,包括了redis内置的string、list、map、set、sortedset、hyperloglog。
2023-03-26 21:41:45
502
原创 结合java中的锁聊聊锁的本质
在操作系统里面,也会遇到什么信号量、互斥量,然后说利用互斥量、信号量可以实现锁的功能,而操作系统提供的原语有又mutex锁在学习数据库的时候,什么表锁、行锁、读锁、写锁、排它锁、意向锁、meta锁等等,各种各样的锁的概念蜂拥而至在学习java的时候,我们会学习到synchronize关键字、jdk里的Lock接口,然后有各种各样的Lock的实现;然后在聊synchronize的时候又会又各种锁的概念出来:自旋锁、偏向锁、轻量级锁、重量级锁。
2023-02-28 20:55:58
713
原创 springmvc统一日志打印request和response内容
在web项目中,有不少场景需要统一处理一些和实际业务基本不相关的逻辑,比如rest接口的监控、出入参日志、操作记录、统一异常处理(避免将错误堆栈等信息直接打到web端)。如果你觉得日志打印rest接口出入参非常简单,直接getParameter()就好了,那么多思考3s继续看吧。
2023-01-19 13:48:12
4367
原创 缓存Caffeine之W-TinyLFU淘汰策略
我们常见的缓存是基于内存的缓存,但是单机的内存是有限的,不能让缓存数据撑爆内存,所有需要缓存淘汰机制。中大概说明了LRU的缓存淘汰机制,以及基于LRU的著名实现guava cache。除了LRU淘汰策略外,其是常见的还有FIFO以及LFU,只是说目前用的最多的是LRU。
2023-01-19 11:13:48
2365
原创 java的垃圾回收浅谈
垃圾回收过程其实都包含两步:标记+回收。综合来看,复制算法适合在垃圾回收执行时存活对象比较少的场景;整理算法适合在垃圾回收时存活对象较多但是不能有内存碎片的场景;而清理算法因为会产品内存碎片,实际的场景其实并不多,CMS使用该算法,但也诟病比较多。对于一个java进程中的对象,经过统计发现,大部分对象生命期都是比较短的,活不过一次垃圾回收,而少部分生命期比较长,多次gc后依然存在,甚至和java进程生命期相同。针对这种情况,就对java的内存进行了分区,不同分区使用不同的回收算法,来达到最大的收集效果。
2022-12-16 14:41:40
1337
转载 积极拥抱毒瘤
至于实体充血不充血,我本来就是微服务了,业务粒度本来就很小了,要怎么写是我的自由,改造也是我自己的成本,我并不需要按照你那一套来。原谅我使用“限界上下文”这样的名词来解释一下:你只要把我的服务边界划分清楚了,你管我后面是怎么实现呢,设计模式和架构模式,我的工具箱多的很,并不缺CQRS、事件溯源这样的名词。这三个词,很伟大,它们有一个共同点,都是很容易说服非技术但能决策的人员,然后向下铺开,非常具有营销型,是职业经理人和CTO的最爱。你搜一下DDD的文章,不论什么文章,都有一个特点,那就是不能好好的说人话。
2022-11-16 21:14:11
72
原创 什么是惊群效应
这个话题来自一个面试,当问到Socket编程中的accept()是否有惊群问题,引深又文档epoll多路复用中epoll_wait()是否有惊群问题。因为没有准备背过八股文,突然问到这个问题,还是稍微有点措手不及,当然就没有背过的那么快速干脆了,而对方在强调结果,也没给我思考分析的时间,我还在仔细回想这个里哪里存在惊群问题的时候,对方已经打断我说好了。所以这里就记录分析一下,到底什么是惊群效应,以及在并发编程中的应对方式。
2022-10-22 08:25:42
2820
2
原创 C10K问题与IO多路复用
操作系统早期的IO都是阻塞式的,所以为了一个应用能够支持并发的IO操作,所以基本的做法就是每来一个IO请求,就创建一个线程来专门处理。当IO并发不大的情况,这中方式工作的很好但随着IO并发越来越大,到了每秒需要支持1000的并发量的时候,那么就需要创建1000个线程来支持。随着线程越来越多,极大的超出了cpu的核心数,那么随之而来的就cpu调度成本增加、大量的上下文切换、以及线程的内存消耗等,这些都将成为并发量继续增加的瓶颈。所以并发量很大的情况下,就不再适合用这种模型来处理。
2022-10-22 08:22:15
420
原创 BIO和NIO消耗的cpu和内存比较
这个其实是遇到的一道面试题,其题目描述也很简单,BIO和NIO消耗的cpu和内存哪个比较大。因为确实从来没遇到过去从这个角度去比较NIO和BIO的,所以我尝试变结实原来,边分析,但是整个过程对方三次认为我跑题了,强调回到他问题的本身,先给出答案,所以整个过程其实并没有真的深入去分析。但我觉得这个问题有点意思,就记录一下,从我掌握的知识来分析一下。..............................
2022-08-27 08:34:54
996
原创 记一次线程池使用导致的死锁
top统计的是当前统计窗口里的情况。一般情况下,只要不是宿主机上的所有容器负载都很大,超卖是没有影响的,即只要没有把物理机cpu打满,超卖就超卖,反正也用不完,但是只要某一时刻兄弟们要求的12个cpu都要用的时候,那就完了,物理机cpu使用率飙高,这个时候进程上下文切换更加频繁,雪上加霜,系统会更慢的。但还有一点人性没有泯灭,当时这么写的时候,其实有点膈应,但是一个闪念的想法让我就这么写了:任务里的操作其实会很快,因为有两层缓存,即走到了db,也一定走上索引,应该不会慢的,就这样吧,应该问题不大。
2022-08-19 15:38:05
1084
原创 分布式系分发展概览
整体的发展历程推动数据库技术大发展的一个重要功能就在于,通信技术领域和计算机科学领域的量大领域的碰撞催生出的互联网行业,在互联网中各种各样的创新业务不断涌现,百花齐放,企业数据量也呈现出了爆发式的增长,读写性能要求也越来越高。围绕解决数据存储和访问的各种问题,出现了各种各样的技术。...
2022-07-26 08:58:39
285
原创 guava之限流RateLimiter
常用的限流方式和场景有:限制总并发数(比如数据库连接池、线程池) 限制瞬时并发数(如nginx的limitconn模块,用来限制瞬时并发连接数,Java的Semaphore也可以实现) 限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limitreq模块,限制每秒的平均速率) 其他:比如如限制远程接口调用速率、限制MQ的消费速率。另外还可以根据网络连接数、网络流量、CPU或内存负载等来限流。我们常说的限流,其实更多的都是指时间窗口内的平均速率,所以往往这种限流方式成了
2022-05-07 08:38:27
14220
原创 高性能内存队列-Disruptor
Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题。基于Disruptor开发的系统单线程能支撑每秒600万订单。2010年在QCon演讲后,获得了业界关注。2011年,企业应用软件专家Martin Fowler专门撰写长文介绍。同年它还获得了Oracle官方的Duke大奖。martin fowler的的大作:原文、参考译文ps:恕我浅薄,直接看大神的文章,说实话,是有些看不明白的,包括有些观点确实还不能消化,因为高度不够,看不清其背后的逻辑本质
2022-01-06 17:53:31
3291
转载 JAVA日志框架适配、冲突解决方案
完全复制转发自:可能是全网最全,JAVA日志框架适配、冲突解决方案,可以早点下班了!你是否遇到过配置了logback,启动时却提示log4j错误的情况?像下面这样:log4j:WARNNoappenderscouldbefoundforlogger(org.example.App).log4j:WARNPleaseinitializethelog4jsystemproperly.log4j:WARNSeehttp://logging.apache.org/log...
2021-12-20 09:34:33
229
原创 jdk中线程池的promise模式-Future
https://blog.csdn.net/sinat_14913533/article/details/104918942这篇说明了线程池的基本原理。但是在使用线程池的时候,我们会发现我们可以:1向线程池中提交Runnable任务,也可以提交Callable任务,但是Thread只能驱动Runnable任务,那线程池是怎么实现Callable到Runnable的转换的。 我们还可以通过ExecutorService#submit()方法返回的Future#get()方法去检查任务的执行状态,以及获.
2021-08-28 09:45:59
466
原创 ThreadLocal那些事
ThreadLocal其实是操作了Thread#threadlocals变量,因为这是Thread的私有变量,所有每个线程实例都有自己的,从而达到线程不共享的目的。如果我们要跨线程传递变量,那就要自己显示的去实现跨线程传递。jdk中还有一个ThreadLocal的子类,可以实现跨线程传递:子线程可以读取父线程的本地变量,那就是InheritableThreadLocal,Thread中还有一个变量inheritableThreadLocals,这个变量的类型和Thread#t...
2021-07-03 08:30:01
325
1
原创 guava之guava cache
caffine的原文翻译https://segmentfault.com/a/1190000008751999细读这个:https://www.chinacion.cn/article/5629.htmlCount-Min Sketch算法,就是BloomFilter的升级版本,BloomFilter是判断一个对象存在or不存在的,Count-Min Sketch是用来记录一个对象的次数的。BloomFilter的问题,也同样存在Count-.
2021-04-23 09:33:10
1322
原创 guava之EventBus
观察者模式这个讲的地方特别多,随便百度就好,这里随意贴了一个别人的链接http://c.biancheng.net/view/1390.html解决的问题观察者模式解决的场景就是:解耦。将一些和主业务逻辑不强相关的逻辑可以解耦出来,统一处理。EventbusEventBus提供了两种观察方式:同步和异步同步方式:post()和对应的事件处理器EventHandler逻辑在同一个线程执行。 异步方式:事件处理器EventHandler逻辑在指定线程池中执行,和post()事件的线
2021-04-19 16:07:24
1769
原创 guava之Retryer
Retryer看结构上是比较简单的,但是就是用这个简单结构实现了比较通用的重试框架。它之所以用入册简单的结构能实现通用的重试框架,它对重试这件事情抽象的是很好的,所以我们看一下重试需要哪些事情:需要用一个机制来表达重试的任务。Retryer采用的是使用Callable这个接口来表示一个重试任务。并且通过AttemptTimeLimiter封装实现了多种执行任务的方式。 需要一种判断什么时候重试、什么时候结束。Retryer使用了Predicate这个函数式接口来让用户来决定什么时候表示执行成功
2021-04-15 19:24:59
2014
原创 jdk中的CAS实现乐观锁 vs 数据库乐观锁
悲观锁读写锁乐观锁基本思想,java实现、数据库实现。自旋锁、轻量锁、偏向锁mvcc不共享不共享资源单线程
2021-04-14 17:51:39
814
2
原创 用户态vs内核态、进程vs线程
用户态、内核态,进程、线程这些概念经常是脱口而出,但是并没有特别理解这些概念背后的含义。比方说,对于java的多线程,有的地方说java多线程线程切换的时候会涉及用户态切换到内核态、进程上线文切换、线程上下文切换,会耗时,我们真的了解这些个过程到底是在干啥,为啥会耗时么?有的时候傻傻分不清楚。所以学习观摩了一下,整理成读书笔记,记录自己的理解。所以这个文档仅仅是尝试将自己学习了解的,用我熟悉的理解方式记录下来,对linux底层的东西我并不熟悉,所以不是在传递linux编程的知识点,只是一些我认为的通俗易
2021-04-09 16:28:35
890
原创 浅谈深分页问题
曾经面试被问到怎么解决深分页问题,因为以前项目用来es,所以重点问的是es的深分页问题,问我怎么解决深分页的问题,我的回答就是没解决。因为我觉得深分页就解决不了(先别浮现出各种网上解决深分页的方式,然后反驳这句话)与其讨论什么从技术上去解决,还不如换个解读想下:什么样的场景下会触发深分页? 当真的出现深分页问题的时候,如何实现系统的自我保护?对第一个问题:我觉得就两种情况:第一:正常的业务流量,用户真的闲得蛋疼了,真的就一页一页的往下翻,翻到了几千上万页(只有闲得蛋疼的才会去做这件事情,否则根.
2021-04-09 14:57:10
5115
4
原创 如何理解CMS回收器降低gc停顿时间
不管采用什么回收算法,垃圾回收都会包含两个大的过程:标记、回收。标记:标记的目的就是识别出哪些对象是垃圾了。这个阶段按道理一定是STW的,否则就标记不出所有的垃圾对象,因为如果有并发,一边标记、一边会有垃圾产生,这个理论上永远标记不完。 回收:就是将标记出的垃圾对象回收,腾出内存。这个阶段分回收算法。这个看算法,比如标记-清理算法,在清理阶段是不需要STW的,因为清理阶段只是标记内存可重用就好了。而标记-整理我理解是需要的,因为整理的时候会改变对象的内存地址,同理复制算法也是。分代收集的理论基础:标
2021-03-31 09:59:07
1122
原创 大话持久性与redolog
持久性一说到关系型数据库,就会说道事务,以说到事务,什么事务的4大特性,隔离界别,咔咔的,滚瓜烂熟。关于这方面的文章网上或者书籍数不胜数,不过我个人感觉说的都太精确或者说准确了,挑不出任何毛病,以至于不太好理解。所以这里记录下自己学习过程中的一些思考和理解,以大白话的方式来理解一下。首先明明确一点:并不是所有数据库都支持事务的,具体到mysql,使用不同的存储引擎,就有可能不支持事务,如m...
2020-03-17 14:06:39
246
原创 jdk线程池实现原理分析
目录为什么需要线程池生产者-消费者模式promise模式ThreadPoolExecutor生产者-消费者实现promose模式实现使用为什么需要线程池先来看看数据库连接池吧。我们在实际生产中使用数据库,基本上应该没人是直接使用jdbc的吧,而是都心照不宣的使用了数据库连接池。那么为什么?最简单的回答就是为了连接复用。那么我们为什么需要复用数据库连接呢?简单...
2020-03-17 13:58:44
404
1
转载 MySQL字段 不推荐使用 Null 的理由
MySQL 一千个不用 Null 的理由https://www.techug.com/post/you-should-not-use-null-in-mysql.html
2020-03-15 16:32:31
2098
原创 Innodb的B+树索引到底能存多少数据
Innodb的B+树能存多少数据Innodb的数据组织的最小单位是page,默认情况下,page的大小为16K。索引B+树的组织方式是:主键索引树是按照聚簇索引的方式,即叶子节点存数据,非叶子节点存线索,也就是说,一张Innodb表一定会有一棵主键索引树。并且非叶子节点的大小保持相等等于16K(为了IO方便,一次IO从磁盘读取一个page的大小,写入的时候也是一次IO写入一个page的大小...
2020-03-14 09:58:26
2608
2
原创 深入剖析单例模式的实现
单例的实现饿汉模式最朴实无华且能保证没有并发问题的就是提前初始化(饿汉模式,忽略这个叫什么,不重要)。public class LazyInstance{ private static ExpensiveObject instance = new ExpensiveObject(); public static ExpensiveObject getInstan...
2020-03-13 11:21:15
150
原创 隔离级别RR、间隙锁、幻读
在每个讲mysql的资料中,应该都会讲到事务的这4个特性:ACID。而这4个特性又会着重讲的就是隔离性,因为在mysql的实现中在并发度和隔离性上作了权衡和取舍,分为了4个隔离级别。在不同的隔离级别会支持一定的并发度,但是也会存在右并发带来的一些问题。隔离级别从低到高:RU-->RC-->RR-->Serializable,隔离级别越高,并发度越低,并发问题也就越少。如下就是...
2020-03-07 08:03:42
743
原创 HashMap的线程安全
学习java的人都知道,HashMap是线程不安全的,不能在多线程环境下共享一个HashMap变量,在jdk1.7中的HashMap的实现,多线程下共享HashMap会导致死循环(有hash冲突的时候,链表上可能存在环导致死循环),但是在jdk8中对这个写法作了优化,不会导致死循环了,但是依然是线程不安全的,多线程下数据是不准确的。这里不是想说HashMap为什么不安全,然后分析他的源码,然后...
2019-11-30 10:21:33
872
1
原创 从线程状态机上看如何优雅停止线程
目录如何优雅的终止线程暂停线程的方法RUNNALBE-->BLOCKEDRUNNALBE_WAITING/TIMING_WAITINGLock等待锁,Condition等待条件LockSupport.parkObject.waitThread.sleep()Thread.join()其他如何优雅的终止线程Thread中提供了stop()等方法,...
2019-11-30 09:05:49
1249
2
c3p0 jar包
2017-04-25
快速排序的时间复杂度问题
2016-07-15
求助:关于多行输入:输入多行后结束(不用自己定义的结束条件,如下描述)
2016-04-07
TA创建的收藏夹 TA关注的收藏夹
TA关注的人