- 博客(189)
- 收藏
- 关注
原创 Hot100之技巧
本文解析了多个算法题目的解题思路和代码实现。首先,通过异或操作的性质,解决了“136只出现一次的数字”问题,利用异或操作找出唯一不重复的数字。接着,通过排序和取中间值的方法,解决了“169多数元素”问题,找到数组中出现次数超过一半的元素。对于“75颜色分类”问题,使用双指针技术将数组中的0、1、2分类排序。在“31下一个排列”问题中,通过找到并交换特定位置的元素,然后反转部分数组,得到下一个更大的排列。最后,通过环形链表的思路,解决了“287寻找重复数”问题,找到数组中唯一的重复数字
2025-05-13 16:43:33
860
原创 JVM之JMM
Java内存模型(JMM)是Java并发编程的核心规范,旨在解决多线程环境下的内存一致性问题。JMM定义了线程与主内存之间的交互规则,确保共享变量的可见性和一致性。由于CPU缓存和指令重排序可能导致数据不一致,JMM通过happens-before原则来约束编译器和处理器的优化行为,保证程序执行的正确性。JMM还抽象了主内存和本地内存的概念,规定线程间的通信必须通过主内存进行。通过遵守JMM规范,开发者可以编写出并发安全的程序,而无需深入了解底层硬件细节
2025-05-13 14:44:28
770
原创 JVM之虚拟机运行
文章主要讨论了Java虚拟机(JVM)中的异常处理机制、类的生命周期、类加载器及其工作原理、双亲委派模型以及热部署的实现。异常处理通过异常表和栈展开实现,确保异常被捕获和处理。类的生命周期包括加载、连接、初始化、使用和卸载五个阶段。类加载器负责将类的字节码加载到JVM中,生成Class对象,且大部分类采用懒加载机制。双亲委派模型确保类加载的稳定性和安全性,避免核心API被篡改。热部署通过自定义类加载器实现,允许动态更新类文件而无需重启应用
2025-05-13 14:38:19
1211
原创 JVM之垃圾回收器
Java垃圾回收器(GC)是JVM内存管理的核心组件,负责自动回收不再使用的对象以释放内存。JDK8默认使用Parallel Scavenge(新生代)和Parallel Old(老年代)组合,而JDK9及以后默认采用G1垃圾回收器。G1通过分代收集和Region分区管理,实现了可预测的停顿时间,适合大内存堆场景。CMS垃圾回收器则专注于低延迟,适用于对停顿时间敏感的应用程序,但存在内存碎片问题。三色标记法是CMS和G1等并发垃圾回收器的关键技术,通过并发标记减少停顿时间
2025-05-12 09:53:23
837
原创 JVM之垃圾回收
垃圾回收(GC)是Java虚拟机(JVM)自动管理内存的机制,旨在自动释放不再被引用的对象所占用的内存,减少内存泄漏和管理错误。GC通过引用计数法和可达性分析法判断对象是否死亡,并采用标记-清除、标记-复制、标记-整理和分代收集等算法进行回收。其中,标记-复制算法分为标记、对象转移和重定位三个阶段。GC的触发条件包括内存不足、手动请求、JVM参数设置及对象数量或内存使用达到阈值。FullGC的开销大于YoungGC,主要因为回收范围更广、标记整理过程复杂、停顿时间更长及内存碎片化问题
2025-05-12 09:40:10
726
原创 分布式事务快速入门
分布式事务是处理跨数据库或跨服务事务的关键技术,主要分为刚性事务和柔性事务。刚性事务如2PC和3PC,基于数据库层面保证强一致性,但存在同步阻塞和部分数据不一致的问题。柔性事务如TCC、Saga和MQ事务,通过业务代码或中间件实现最终一致性,减少了对数据库的依赖。TCC通过Try、Confirm、Cancel三个阶段实现事务管理,而Saga则将长事务分解为多个短事务,通过补偿机制处理失败。MQ事务如RocketMQ和Kafka,将消息的生产、消费和处理整合为原子操作。这些方法各有优缺点,适用于不同的业务场景
2025-05-10 21:57:11
983
原创 JVM之内存管理(二)
JDK从1.6到1.8版本中,内存区域发生了显著变化,主要体现在方法区的实现上。JDK1.6使用永久代实现方法区,常量池位于永久代。JDK1.7将字符串常量池和静态变量移至堆内存,而类常量池和运行时常量池仍保留在方法区。到了JDK1.8,永久代被彻底移除,取而代之的是直接内存中的元空间,运行时常量池和类常量池也移至元空间。这些变化主要是为了优化内存管理和垃圾回收效率,减少内存溢出的风险,并提高加载类的数量限制。元空间的使用使得内存管理更加灵活,不再受固定大小的限制,而是根据系统的实际可用内存动态调整
2025-05-10 21:55:00
722
原创 JVM之内存管理(一)
JVM内存结构主要包括堆、栈、方法区等区域。堆用于存储对象实例,是所有线程共享的内存区域。栈是线程私有的,用于存储局部变量和方法调用的上下文。方法区存储类信息、常量、静态变量等。栈帧包含局部变量表、操作数栈、动态链接和方法返回地址。对象创建涉及类加载检查、内存分配、初始化和设置对象头等步骤。类加载过程包括加载、连接、初始化等阶段。内存分配可通过指针碰撞或空闲列表实现。引用类型包括强引用、软引用、弱引用和虚引用,分别用于不同场景下的内存管理。内存泄露和内存溢出是常见问题,前者指无用对象无法被回收,后者指内存不
2025-05-09 19:32:24
1726
原创 JVM虚拟线程快速入门
虚拟线程是JDK引入的轻量级线程,旨在提高阻塞IO任务的并发量,减少线程创建和销毁的开销。与传统线程不同,虚拟线程由JVM管理,运行在用户空间,一个平台线程可承载多个虚拟线程。虚拟线程在阻塞时,平台线程可切换执行其他虚拟线程,避免了资源浪费。虚拟线程适用于I/O密集型任务,简化异步编程,使代码更易维护,但不适用于CPU密集型计算。尽管虚拟线程提升了资源利用率和并发性能,但其与某些第三方库的兼容性仍需注意。虚拟线程的引入优化了线程调度,减少了上下文切换成本,进一步释放了硬件资源的潜力
2025-05-09 12:16:52
838
原创 ElasticSearch基本概念
Elasticsearch是一种高效的搜索引擎,主要用于提供快速、近实时的数据检索功能,与传统的关系型数据库如MySQL相比,它在处理非结构化数据和复杂查询方面具有明显优势。Elasticsearch支持多种数据类型,包括数值、地理信息等,并提供丰富的分词器和相关性搜索功能。其核心特性包括倒排索引,这大大提高了查询效率,尽管建立和维护倒排索引的成本较高。Elasticsearch的基本概念包括索引(Index)、文档(Document)、映射(Mapping)、节点(Node)、集群(Cluster)、分片
2025-05-08 22:47:26
1496
1
原创 零拷贝的简单复习
PageCache是Linux内核中的磁盘高速缓存,用于提高磁盘读写性能。传统文件传输涉及四次数据拷贝和四次上下文切换,效率较低。DMA(直接内存访问)技术通过分担CPU的IO工作,减少了CPU的参与,提高了数据传输效率。零拷贝技术通过mmap+write和sendfile等方法,减少了上下文切换和数据拷贝次数,进一步优化了文件传输性能。PageCache通过缓存最近访问的数据和预读功能,减少了磁盘IO,但在大文件传输时,PageCache可能不适用,建议使用直接IO+异步IO技术
2025-05-08 22:41:25
660
原创 Caffeine快速入门
expireAfterAccess(10, TimeUnit.SECONDS)设置在缓存被访问后的10分钟过期。expireAfterWrite(10, TimeUnit.SECONDS) 设置在缓存写后的10分钟过期。refreshAfterWrite(Duration.ofMinutes(1)) 写入一分钟后触发自动刷新。recordStats()//开启统计。
2025-05-06 19:07:51
275
原创 CompletableFuture的底层ForkJoinPool
答案要点ForkJoinPool 是 Java 7 引入的线程池,专为分治任务设计,支持递归任务拆分(Fork)和结果合并(Join)。工作窃取算法(Work-Stealing):空闲线程从其他线程的任务队列尾部窃取任务,提高 CPU 利用率任务拆分与合并:天然支持递归任务的并行化,而普通线程池需要手动拆分任务适用场景:ForkJoinPool 适合CPU 密集型任务(如并行计算),普通线程池适合通用异步任务。
2025-05-06 14:56:02
693
原创 简单介绍分布式定时任务XXL-JOB
XXL-JOB 由 调度中心 和 执行器 两大部分组成。调度中心主要负责任务管理、执行器管理以及日志管理执行器主要是接收调度信号并处理。另外,不同于 Elastic-Job 的去中心化设计, XXL-JOB 的这种设计也被称为中心化设计和 Quzrtz 类似 XXL-JOB 也是基于,存在性能瓶颈是要连的时候,要使用一个相同的token就是我们通过xxl-job注解里面的bean的名字,去查找对应的不同的方法不过,一般在任务量不是特别大的情况下,没有什么影响的,可以满足绝大部分公司的要求。
2025-05-06 14:53:29
1210
原创 垂直表-通过范式关系优化表结构
所以有一个总表一开始是插入所有level的,存在的字段设值,不存在的字段设为null,这样子我们保证了一开始的总表有所有数据,及时字段个数对不上但所有level的物料还是能存。因为不同的物料其实字段数量是不同的,例如level1可能比level2多一个code字段,level2可能比level3少3个字段。相同的字段都一样,例如 相同字段:id,唯一Id,物料等级level。这个表的内容字段会有7成相同的字段和3成不同的字段。:适合属性差异大的场景(如不同实体的字段完全不同):大数据量时效率低(需行转列)
2025-04-28 11:02:43
311
原创 分布式链路追踪理论
三个基本概念:Trace追踪,Span服务,Context上下文(用来传递信息)分布式链路追踪 = Trace ID串联全局 + Span记录局部 + 上下文传递Span中包含starTime,endTime,SpanContetx(上下文用来传递信息,包含TraceId,SpanId),SpanTag(服务的标签),SpanLog(服务的日志信息)TraceSegment(追踪段):一个进程中所有的Span的集合。
2025-04-28 11:02:31
1184
原创 TCP四大特性面试回答引导
TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。了解决网络波动问题所以有了cwnd拥塞窗口,拥塞控制的目的是避免「发送方」的数据填满整个网络。,也就是接收到最新的ACK就说明前面的数据都收到了,没必要接收所有的ACK)如果出现了重传【超时重传】【快速重传】,就说明网络出现了拥塞。收到新的ACK,说明网络波动没问题了,直接将cwnd变回原样。【快速重传】,收到三次相同的ACK,进行快速重传。拥塞窗口,发送窗口,接收窗口是不同的。
2025-04-23 16:30:22
390
原创 运行java程序的时候cpu飙高有很多原因,随便说几条并说说怎么排查
如果我们有读取文件的场景就会有大量的io占用线程。按 CPU 使用率排序,找到占用 CPU 最高的 Java 进程。,连接到目标 Java 进程,查看 CPU、内存、线程等信息。:实时监控 CPU、内存等。
2025-04-23 10:34:44
726
原创 说一下Redis的发布订阅模型和PipeLine
Redis 的是一种基于的允许发送者(发布者)向频道发布消息,接收者(订阅者)订阅频道并接收消息Subscribe订阅,Publish发布消息传递的通道,订阅者需先订阅频道才能收到发布者发送到该频道的消息。向指定频道发送消息的客户端(无需订阅频道)。订阅一个或多个频道的客户端,实时接收这些频道的消息(阻塞等待)。
2025-04-23 10:31:13
1314
原创 KRaft面试思路引导
Kafka实在2.8之后就用KRaft进行集群管理了和Zookeeper管理一样,会选出一个Broker作为Controller去管理整个集群,但是元数据存储不同了Zookeeper是树形结构存储,为每个ZNode,每个分区有一个ZNode节点而KRaft就是用日志存储的
2025-04-21 17:22:18
697
1
原创 Kafka面试题精简总结
基本概念主题,分区,副本(Leader+Follower)一个主题可以有多个分区一个分区可以有多个副本一个Broker就是一个Kafka节点单个消费者组消费同一个主题是消息队列模型多个消费者组消费同一个主题是发布订阅模型每个消息的唯一offset是不同的(offset值可能相同,但是总体不同),是Kafka中定位一条消息的完整方式。
2025-04-21 17:19:26
777
原创 EasyExcel结合多线程+控制sheet页全量导出
同时因为该平台是多用户的,所以不仅要控制当前方法的sheet页的总量,还要估算多用户场景下sheet页加起来的量大小,如果规定每个写入的sheet页的量级为50w,那么10个用户并行导出的时候是不是500w的量级?因为EasyExcel的sheet页是放到一个List里面的,如果把百万量级的数据放到sheet页中全量写入会有OOM风险,所以最终选择的方案是分sheet页写入。那就会出现OOM问题,为了严格控制sheet页的和总量,就要细致化到控制每个线程的每次写入的sheet页的量。
2025-04-08 21:58:25
575
2
原创 总结一下常见的EasyExcel面试题
EasyExcel主要解决的poi的内存瓶颈和读取效率问题poi使用的是传统的全量加载,而EasyExcel是流失加载,也就是事件驱动+及时刷盘poi读取的时候,必须要把整个文件加载到内存中读取poi写入的时候必须一次性全量写入而EasyExcel读取的时候是流式读取,逐行扫描,读取完的数据从内存中扔掉,不占用内存EasyExcel写入的时候是流式写入,我们分sheet页写入,这个sheet页写入完就及时释放资源,实现及时刷盘不占用内存。
2025-04-08 21:49:33
883
2
原创 说一下java的探针agent的应用场景
Java探针通常是指Java Agent它是一种可以在JVM启动时或运行时加载的组件,用来修改或增强字节码,从而监控或改变程序的行为注册转换器:通过注册。拦截类加载:JVM 加载类时调用转换器修改字节码。动态增强:在目标方法中插入监控、日志、链路追踪等逻辑。运行时生效:修改后的类被 JVM 直接使用,无需重启应用。
2025-04-07 21:23:55
713
原创 说一下分布式组件时钟一致性的解决方案
用「粗略的挂钟时间」+「自增的流水号」,既容忍时间误差,又能保证事件顺序不乱物理时间:取本地时钟(比如用NTP同步,允许有误差,比如差几秒)。逻辑计数器:当物理时间相同或需要修正时,用计数器进一步排序时间_计数器排序例如A的时间是是10点整,B的事件是9.59分A执行完,B再执行,如果单纯从时间戳的角度来看的话是B比A先,但实际上是A比B先A执行完后会有个逻辑时钟记录,10.0.0_1B执行的时候,我们要拉最新的逻辑时钟,这样子就能保证不同时间戳差异导致的问题B的9.59时间对比最新的记录。
2025-04-07 21:23:28
847
原创 如何理解TCP是面向字节流的协议
我们可以自定义一个消息结构,由包头和数据组成,其中包头是固定大小的包头里有一个字段来说明紧随其后的数据有多大比如这个消息结构体,首先 4 个字节大小的变量来表示数据长度,真正的数据则在后面struct {} message;当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整的用户消息来处理了。
2025-04-05 00:27:09
874
原创 Redisson中BitMap位图的基本操作
本文内容是Redisson简单使用BitMap位图的一些基本API操作,让你能简单上手操作BitMap位图
2025-04-02 10:47:22
245
原创 Redisson中的RateLimiter令牌桶限流简单使用
通过Redisson自带的RateLimiter令牌桶限流进行限流,本文章让你了解RateLimiter的基本使用
2025-04-02 10:46:39
1075
原创 如何排查java程序的宕机和oom?如何解决宕机和oom?
用jmap生成我们的堆空间的快照Heap Dump(堆转储文件),来分析我们的内存占用用可视化工具,例如java中的jhat分析Heap Dump文件 ,它分析完会通过一个浏览器打开一个可视化页面展示分析结果根据oom的类型来调整我们的内存配置
2025-03-29 16:34:32
931
空空如也
想学springboost和spring有啥区别吗?
2023-08-04
TA创建的收藏夹 TA关注的收藏夹
TA关注的人