- 博客(59)
- 收藏
- 关注
原创 bean的生命周期
实例化属性赋值初始化使用(In Use)销毁下面我们详细讲解每个阶段的具体过程。描述:通过 JSR-250 注解定义初始化和销毁方法。示例@ComponentSystem.out.println("初始化方法");System.out.println("销毁方法");描述:通过实现接口,在 Bean 初始化前后执行自定义逻辑。示例@[email protected]("前置处理: " + beanName);@Override。
2025-09-11 15:59:08
822
原创 Spring常用注解介绍
Spring 注解极大地简化了开发流程,通过合理使用这些注解,可以减少 XML 配置,提高代码的可读性和可维护性。@Component@Service@Autowired@Qualifier@Bean@Value@Aspect@Before@After@Around掌握这些注解的使用场景和用法,是成为 Spring 开发专家的重要一步。希望本文对你有所帮助!
2025-09-11 15:17:30
638
原创 几种常用锁
特性syncVolatileCAS类型关键字(隐式锁)类(显式锁)变量修饰符原子操作指令主要作用保证原子性、可见性、有序性提供更丰富的锁功能保证可见性、有序性实现原子性更新原子性✅ (代码块/方法级)✅ (代码块级)❌ (仅单次读写)✅ (单变量)可见性✅✅✅❌ (需配合volatile有序性✅✅✅❌ (需配合volatile可重入✅✅❌❌公平性❌ (非公平)✅ (可选)❌❌中断响应❌✅❌❌超时获取❌✅❌❌条件变量❌ (仅✅❌❌开销较高。
2025-09-11 14:54:00
492
原创 并发编程之锁
特性/类型核心思想优点缺点适用场景互斥锁独占访问,同一时间只有一个线程能进入临界区。简单、直观,能保证绝对安全。性能较低,可能导致线程阻塞和上下文切换。通用场景,写操作频繁或临界区执行时间较长。读写锁读共享,写独占。读多写少时,并发性能远高于互斥锁。实现复杂,可能导致写饥饿。读操作远多于写操作的场景,如缓存。自旋锁获取锁失败时忙等待,不阻塞线程。避免了上下文切换,响应快。浪费 CPU 资源,可能造成活锁。锁持有时间极短,且不希望线程被阻塞的场景。可重入锁。
2025-09-11 14:51:10
827
原创 数据结构之跳表
想象一下,你有一本非常厚的电话簿,里面的名字是按字母顺序排列的。现在你想找 “Zhang San” 这个名字。方法一(链表/线性查找):从第一页的第一个名字 “A” 开始,一页一页地翻,直到找到 “Z”。这非常慢。方法二(跳表):聪明的电话簿出版商在书的侧面贴上了一些“索引标签”。比如:第一个标签指向 “B” 开头的部分。第二个标签指向 “G” 开头的部分。第三个标签指向 “M” 开头的部分。第四个标签指向 “S” 开头的部分。第五个标签指向 “Z” 开头的部分。
2025-09-11 14:37:42
273
原创 Java类
定义:用abstract修饰的类,不能实例化。特点可以有抽象方法和非抽象方法。子类必须实现所有抽象方法,除非子类也是抽象类。用于表示“is-a”关系。示例// 抽象方法,子类必须实现void sleep() { // 非抽象方法,子类可继承@Overridevoid eat() { // 必须实现抽象方法Java类的知识点围绕封装、继承、多态权限修饰符和关键字是实现封装和控制行为的关键;抽象类和接口是继承与多态的具体形式;Object类是所有类的根基,其方法需合理重写;
2025-09-10 15:37:32
482
原创 Java集合
Java集合框架(Java Collections Framework, JCF)是一套系统类库,用于统一管理对象的存储、查询和操作。其核心特点包括统一的接口设计、高效的实现类以及灵活的数据结构支持。在Java 2之前,已有特设类如Vector、Stack等,但集合框架通过标准化接口(如Collection、Map)进一步提升了代码的可复用性和一致性。集合类型推荐使用场景ArrayList查询多、增删少LinkedList增删多、查询少HashSet去重、不关心顺序TreeSet。
2025-09-10 14:13:14
678
原创 Spring循环依赖
循环依赖,顾名思义,就是两个或多个Bean相互依赖,形成了一个闭环。最简单的例子:A依赖B,B又依赖A。@Component@Autowired@Component@AutowiredSpring创建ServiceA,发现需要ServiceB。Spring去创建ServiceB,发现需要ServiceA。Spring又回头去创建ServiceA… 这样就陷入了无限循环,最终导致。问题答案什么是循环依赖?两个或多个Bean相互引用,形成闭环。Spring能解决哪种?
2025-09-03 11:14:41
692
原创 Spring事务
事务是数据库操作的一个执行单元,这个单元中的所有操作要么全部成功,要么全部失败。它是一个不可分割的工作逻辑单元。事务拥有四个核心特性,也就是我们常说的ACIDA - Atomicity (原子性):事务是一个原子操作,由一系列动作组成。事务的原子性确保这些动作要么全部完成,要么完全不起作用。C - Consistency (一致性):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态。数据不会被破坏。例如,A 向 B 转账,不论成功与否,A 和 B 的总金额应该保持不变。
2025-09-02 18:01:13
552
原创 Spring全家桶
Spring 是一个开源的、轻量级的 Java 开发框架,它的核心目标是简化 Java 企业级应用的开发。“轻量级”在这里指的是它对代码的侵入性很低,你可以很轻松地将 Spring 集成到你的项目中,而不需要让你的代码继承 Spring 的特定类。Spring 是一个基础框架,它通过 IoC 和 AOP 提供了一套完整的、解耦的、可测试的编程模型,是构建任何 Java 应用的坚实基础。Spring MVC(Model-View-Controller)是 Spring 框架的一个模块,它是一个。
2025-09-02 17:09:11
861
原创 Pipeline
是一种客户端技术,它允许客户端将多个 Redis 命令一次性发送给服务器,而不是一个一个地发送。然后,客户端会一次性读取所有命令的执行结果。简单来说,它把“请求-响应”的“一问一答”模式,变成了“批量提问-批量回答”模式。Redis Pipeline 是一个通过将多个命令打包、一次性发送和接收,从而显著减少网络往返时间,极大提升 Redis 性能的客户端技术。优势:大幅降低网络延迟带来的开销,性能提升可达数十倍。原理:变“一问一答”为“批量提问-批量回答”。关键限制不保证原子性。
2025-09-02 16:27:40
811
原创 RabbitMQ 和 Kafka
RabbitMQ 是一个开源的消息代理,它实现了高级消息队列协议。你可以把它想象成一个功能强大的“智能邮局”或“消息交换中心”。它的核心职责是接收、存储和转发消息,确保消息能够从生产者安全、可靠地送达消费者。RabbitMQ 最初由 Rabbit Technologies 公司开发,现在隶属于 VMware,拥有非常活跃的社区和广泛的企业应用基础。Kafka 最初由 LinkedIn 开发,现在是 Apache 软件基金会旗下的顶级开源项目。它不仅仅是一个消息队列,更是一个。
2025-08-30 09:46:14
1038
原创 消息队列MQ
消息队列是一种异步通信机制,允许应用通过发送/接收消息解耦交互。核心优势包括:异步提升性能(如注册后异步发邮件)、解耦增强健壮性(订单与库存系统隔离)、削峰填谷(应对秒杀流量)。典型架构含生产者、消息代理(Broker)、消费者和队列,支持点对点(单消费者)和发布订阅(多消费者)模式。主流产品各有侧重:RabbitMQ适合复杂路由,Kafka擅长高吞吐,RocketMQ支持事务消息。但引入MQ也带来可用性、一致性、重复消费等挑战,需通过幂等设计、持久化、监控等措施应对。正确使用可显著提升分布式系统能力。
2025-08-30 09:32:44
902
原创 多版本并发控制MVCC
MVCC 的全称是多版本并发控制。核心思想:在数据库中,同一份数据可以保留多个历史版本。当事务需要读取数据时,它会根据一定的规则(比如事务的开始时间)看到一个特定的、一致性的“快照”(Snapshot),而不是直接读取最新的、可能还未提交的数据。写操作则会创建一个新版本的数据。读操作:就像到某个特定的 commit 版本,你看到的是那个时间点的完整项目状态,即使之后有新的提交,你的视图也不会变。写操作:就像创建一个新的commit,它不会覆盖旧的commit,而是在旧版本的基础上生成一个新版本。
2025-08-28 10:25:52
750
原创 Redis分布式锁
分布式锁是一种控制分布式系统之间对共享资源进行同步访问的机制。互斥性:在任意时刻,只有一个客户端能持有锁。这是最基本的要求。高可用性:锁服务本身必须是高可用的,不能因为单点故障导致整个锁服务不可用。可重入性:同一个线程在已经持有锁的情况下,可以再次获取该锁而不会死锁。这是一个非常实用的特性。锁超时/自动释放:防止某个客户端在获取锁后突然崩溃,导致锁无法被释放,造成其他所有客户端都无法获取锁的“死锁”问题。锁必须有一个过期时间,即使客户端没有主动释放,锁也能自动失效。高性能与高并发。
2025-08-26 20:00:00
663
原创 Redis集群
方案优点缺点适用场景单机部署简单,性能高存在单点故障,容量和性能有上限开发、测试环境,或数据量极小、可用性要求不高的场景。主从复制读写分离,提高了读性能,数据有备份故障转移需要手动干预,写操作依然是单点读多写少,且对自动故障转移要求不高的场景。哨兵自动故障转移,系统高可用写操作依然是单点,难以实现水平扩容对高可用有要求,但数据量不大,写并发不高的场景。集群数据分片,解决了容量和性能瓶颈;高可用,自动故障转移架构复杂,有功能限制(多键操作等),运维成本高生产环境首选。
2025-08-26 18:45:00
656
原创 MySQL之索引
特性描述本质一种用于快速查询的数据结构,牺牲空间和写性能换取读性能。核心原理主要使用B+树,通过降低树高来减少磁盘I/O次数,实现高效查询。主要类型主键索引(聚簇)、唯一索引普通索引组合索引(最左前缀原则)、全文索引。关键概念聚簇索引(数据即索引)、非聚簇索引(需回表)、回表(二次查询)。设计原则在查询频繁、区分度高、更新少的列上创建索引。避免在小表、更新频繁的表上建索引。索引失效避免在索引列上计算、使用!LIKE '%xx'OR等导致索引失效的操作。掌握索引,就掌握了数据库性能优化的钥匙。
2025-08-26 17:33:47
633
原创 验证码流程
一个健壮、安全的验证码系统是在此基础上,通过增加时效性控制状态管理安全存储和防攻击策略来构建的。核心思想总结:唯一性:一个验证码对应一次请求和一个用户。时效性:验证码必须有明确的生命周期,用完即焚。一次性:验证码一旦成功使用,必须立即失效,防止重用。安全性:在生成、存储、传输、校验的每一个环节都要考虑安全风险,并采取相应措施。
2025-08-25 23:00:00
1016
原创 位图和布隆过滤器
本文对比了位图(Bitmap)和布隆过滤器(BloomFilter)两种数据结构。位图使用位数组高效存储布尔状态,适合整数查询、统计和去重,具有O(1)查询速度和简单实现,但仅支持整数且数据稀疏时浪费空间。布隆过滤器通过多个哈希函数和位数组判断元素是否存在,支持任意数据类型,空间效率高但存在误判且不支持删除。位图适用于精确场景如用户签到统计,而布隆过滤器适合缓存穿透防护、URL去重等允许误判的场景。选择时需根据数据类型、精确性需求和内存限制权衡。
2025-08-25 22:45:00
786
原创 缓存雪崩及解决方案(双删和双更新加消息补偿)
缓存雪崩是指在某一个时间段,缓存集中失效或缓存服务宕机,导致所有请求直接打到数据库上,造成数据库短时间内承受大量请求而压力骤增甚至宕机的现象。
2025-08-25 22:30:00
684
原创 LRU实现
特性实现HashMap+ 双向链表 实现代码量非常少,核心逻辑只需几行较多,需要定义节点和链表操作实现难度简单,只需了解特性中等,需要熟练掌握链表和HashMap性能优秀,与手写实现相当优秀,所有操作均为 O(1)适用场景生产环境、日常开发算法学习、技术面试核心思想利用 Java 库的现有功能从零构建,展示底层原理。
2025-08-25 22:00:00
1203
原创 BIO、NIO 和 AIO
I/O(Input/Output)模型定义了程序如何与外部设备(如磁盘、网络)进行数据交互。当程序发起一个 I/O 请求(比如读取一个文件或接收网络数据)时,如果数据还没准备好,程序该怎么办?BIO、NIO 和 AIO 代表了三种不同的处理策略,它们在阻塞行为、线程模型、编程复杂度和性能上有显著差异。特性阻塞行为阻塞非阻塞异步非阻塞核心思想一个连接一个线程一个线程管理多个连接(多路复用)操作系统完成后通知应用(回调)线程模型连接数与线程数 1:1连接数远大于线程数线程数非常少,不随连接数增加。
2025-08-25 21:30:00
731
原创 Redis常规指令及跳表
跳表是一种概率平衡的数据结构,可以看作是带有“快速通道”的有序链表。它通过在原始有序链表之上建立多级索引,来实现快速的查找、插入和删除操作,其平均时间复杂度为O(log N),最坏情况为 O(N)。为什么需要跳表?普通有序链表的查找效率是 O(N),因为必须从头开始逐个遍历。平衡二叉树(如红黑树)虽然能实现 O(log N) 的查找,但实现复杂,且在并发环境下需要复杂的锁机制来保证平衡。跳表提供了一种在实现上比平衡树更简单,且性能与之媲美的方案。Redis 常规指令。
2025-08-25 21:15:00
604
原创 Java内存模型
特性volatile本质轻量级同步机制,是一种变量修饰符。重量级锁(已优化),是一种代码块/方法修饰符。原子性不保证。仅保证单次读/写的原子性,不保证复合操作(如i++)的原子性。保证。确保被锁定的代码块内的操作是原子执行的。可见性保证。通过内存屏障,确保修改后立即刷新到主内存,读取时从主内存加载。保证。通过 Happens-Before 原则的“监视器锁规则”,解锁前将修改刷新到主内存,加锁时从主内存重新加载。有序性保证(部分)。禁止指令重排序,确保volatile变量相关的操作不会被重排序。
2025-08-24 08:00:00
610
原创 单例模式介绍
单例模式是一种创建型设计模式,它的核心思想是保证一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例。你可以把它想象成一个国家的国王或一个公司的CEO。在任何时候,都只能有一个人担任这个角色,所有人都通过统一的渠道(如朝廷、董事会)来向他/她汇报或请求指示。主要目的:控制资源访问:确保某个资源(如数据库连接池、线程池、配置管理器)在整个应用程序中只有一个实例,避免资源浪费和冲突。保证数据一致性:当多个地方需要共享和操作同一份数据时,单例可以确保数据的一致性。方便管理。
2025-08-23 14:00:00
976
原创 AQS模板方法
模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。将 AQS 的state定义为锁的持有计数。特性描述AQS 角色模板方法模式中的抽象父类。它定义了同步器的通用算法骨架。模板方法acquire()release()等。它们是final的,定义了获取/释放状态的完整流程,包括排队、阻塞、唤醒等不变逻辑。基本方法(钩子)等。它们是protected的,由子类实现,定义了“状态是否可获取/释放”的可变逻辑。
2025-08-22 21:30:00
1387
原创 浅拷贝,深拷贝
浅拷贝会创建一个新对象,然后将原对象的字段值逐个复制到新对象中。如果字段是基本数据类型,复制的是它的值。修改副本不会影响原对象。如果字段是引用数据类型,复制的是它的引用(内存地址)。这意味着,原对象和副本对象将共享同一个引用指向的对象。深拷贝不仅会创建一个新对象,还会递归地复制对象内部的所有引用类型成员,直到所有对象都是全新的副本。对于基本数据类型,行为和浅拷贝一样,复制值。对于引用数据类型,会创建一个全新的对象,并将新对象的引用赋值给副本。特性浅拷贝深拷贝基本类型复制值,互不影响。
2025-08-22 21:00:00
709
原创 B树,B+树,B*树
特性B树B+树B*树数据存储位置所有节点(键+数据)仅叶子节点(键+数据)仅叶子节点(键+数据)非叶子节点作用索引+数据仅索引仅索引叶子节点结构独立,无连接双向有序链表双向有序链表查询性能不稳定(可能在非叶子节点命中)稳定(必须到叶子节点)稳定(必须到叶子节点)范围查询效率低(中序遍历,随机I/O)效率极高(链表顺序遍历)效率极高(链表顺序遍历)节点填充率至少半满 (ceil(m/2)至少半满 (ceil(m/2)至少2/3满ceil(2m/3)分裂策略节点满则分裂成两个。
2025-08-22 20:30:00
539
原创 二叉搜索树(BST)、AVL树、红黑树
左子树的所有节点值均小于根节点的值。右子树的所有节点值均大于根节点的值。左、右子树也分别是二叉搜索树。没有键值相等的节点。(通常定义如此)8/ \3 10/ \ \1 6 14/ \ /4 7 13AVL树是最早被发明的自平衡二叉搜索树。它通过一个严格的平衡条件来确保树永远不会退化。它首先是一棵二叉搜索树。对于树中的任意一个节点,其左子树的高度与右子树的高度的差的绝对值不能超过1。这个差值就是平衡因子。AVL树中所有节点的平衡因子只能是 -1、0 或 1。
2025-08-22 20:00:00
668
原创 虚拟线程(高版本JDK)
特性描述最佳实践创建方式或优先使用。它与现有代码库兼容,并且是处理任务集合的标准方式。适用场景I/O 密集型任务。例如:Web 服务器、数据库访问、微服务调用、文件操作等。不要将虚拟线程用于CPU 密集型任务(如复杂计算、视频编码)。对于这类任务,平台线程或专门的工作线程池仍然是更好的选择,因为它们会长时间占用 CPU 核心,无法被“卸载”。代码风格编写简单的、同步的、阻塞式代码。拥抱(尽管有轻微的性能开销,但 JVM 正在优化)和传统的阻塞 I/O API(如Socket避免。
2025-08-22 19:45:00
939
原创 死锁避免之银行家算法
银行家算法是操作系统课程中学习死锁避免的经典模型。它通过精巧的“预分配-安全检查”机制,完美地展示了如何在保证系统不进入死锁的前提下,尽可能地满足进程的资源请求。尽管因其苛刻的前提条件和较高的计算开销而在通用操作系统中应用受限,但它所蕴含的“安全状态”和“避免”思想,对于理解并发控制和资源管理具有极其重要的意义。
2025-08-22 14:50:25
933
原创 JDK 工具
JVM 提供的工具链非常强大,从基础的进程查看到深度的内存、线程分析,应有尽有。熟练掌握这些工具,可以大幅提升你在排查 JVM 问题、优化性能时的效率。如果你有更复杂的监控需求(如分布式系统监控、自动化告警),可以结合这些工具与日志系统(如 ELK、Prometheus)一起使用,效果更佳。
2025-08-20 18:30:00
971
原创 强、软、弱、虚引用
在 Java 中,我们通常通过这样的方式创建对象,这里的obj就是一个强引用。软引用弱引用和虚引用。它们的主要区别在于垃圾回收器在不同时机回收它们所指向的对象,从而为开发者提供了更灵活的内存控制手段。强引用 > 软引用 > 弱引用 > 虚引用。强引用是我们最常见、最普遍的引用类型。只要一个对象存在强引用与之关联,垃圾回收器就绝对不会回收它,即使在内存不足时,JVM 宁愿抛出异常,也不会回收这些对象。软引用用来描述一些还有用但并非必需的对象。在内存足够时,垃圾回收器不会回收软引用关联的对象;但是,
2025-08-19 21:00:00
1498
原创 JVM之Java内存区域与内存溢出异常
例如,在JDK 6或更早版本中,String.intern() 方法会将其内容复制到永久代的字符串常量池中,如果调用 intern() 的字符串过多,也会导致永久代溢出。检查应用是否使用了动态生成类的技术,或者是否存在类加载器泄漏(例如,在Web容器中重复部署应用时,旧的类加载器及其加载的类没有被卸载)。,是指程序在申请内存时,没有足够的内存空间供其使用。如果是内存溢出,检查业务逻辑是否合理,或者考虑增加堆内存大小(-Xmx),优化数据结构(如使用更节省内存的结构),或者分批处理大数据。
2025-08-19 17:57:02
726
原创 HashMap底层结构与扩容机制
特性JDK 1.7JDK 1.8+底层结构数组 + 链表数组 + 链表 + 红黑树数据插入方式头插法尾插法哈希冲突处理链表法链表法,当链表长度 >= 8 且数组容量 >= 64 时,链表转为红黑树查询时间复杂度平均 O(1),最坏 O(n)平均 O(1),最坏 O(log n)扩容时节点迁移重新计算索引,头插法迁移根据拆分链表,尾插法迁移,保持顺序多线程问题扩容时可能死循环扩容不会死循环,但仍有数据覆盖等并发问题回顾:结构。
2025-08-18 17:50:01
953
原创 128陷阱
128陷阱”通常指的是在Java中,当你比较两个Integer对象是否相等时,对于某些范围内的数值(特别是128),使用==运算符会得到与预期不符的结果。// 输出 true// 输出 false// 手动装箱// 输出 falsea == b返回true。因为a和b都指向了同一个Integer对象。c == d返回false。因为c和d指向了两个不同的Integer对象。e == f返回false。因为new关键字强制创建了两个全新的、在内存中地址不同的对象。为什么127。
2025-08-18 12:46:24
768
原创 封装,继承,多态
特性封装继承多态核心思想数据隐藏,保护对象内部状态代码复用,建立 is-a 关系同一接口,不同实现解决的问题如何保护数据、降低耦合如何复用代码、建立结构如何提高灵活性、降低耦合关系独立,是OOP的基础是多态实现的前提是封装和继承的最终体现项目中的角色定义类的边界和行为构建代码的骨架和层次实现灵活、可扩展的业务逻辑在实际项目中,这三大特性是相辅相成、密不可分的。通过封装来保护数据,通过继承来构建代码结构,最终利用多态来实现高内聚、低耦合、易于扩展和维护的软件系统。
2025-08-18 12:31:39
733
原创 抽象类与接口
特性抽象类接口关系is-a(是一个)can-do(能做)继承单继承多实现方法可含抽象和具体方法Java 8+ 可含defaultstatic方法字段任意字段隐式构造器有无核心代码复用与模板能力定义与契约简单来说:如果你想复用代码并建立一族相关类的模板,用抽象类。如果你想定义一个行为规范,让不相关的类都能实现,并且需要多实现的能力,用接口。
2025-08-18 10:26:50
683
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人