- 博客(214)
- 收藏
- 关注
原创 ES 面试
Elasticsearch 是分布式全文检索引擎,底层基于 Lucene。它搜索快的核心原因是倒排索引,也就是提前记录“某个词出现在哪些文档里”。业务上通常用 MySQL 存主数据,用 ES 做搜索副本。一个 index 会拆成多个 shard,每个 shard 底层本质上是一个 Lucene index,而 Lucene 又会把索引组织成多个 segment。写入时数据会先进入内存和 translog,经过 refresh 后生成新的 segment,此时数据才对搜索可见;
2026-04-14 22:05:17
412
原创 Spring 事务传播机制 速记
是需要一个新的事务,所以不管外面有没有都单独开一个;Spring 事务传播机制里,英文其实就很好记。是支持事务,所以有就加入,没有也能执行;有事务我就加入,没有事务我就自己建一个。是需要事务,所以有就加入,没有就新建;是不支持事务,表示要以非事务方式执行;NOT_SUPPORTED:不支持事务。是绝不能有事务,有事务就报错;有事务,我支持一下,跟着进去。不支持事务,外面有事务也先挂起。是强制的,表示必须在事务里;MANDATORY:必须有事务。如果当前有事务,直接报错。支持事务,有就进,没有也行。
2026-04-13 21:34:40
358
原创 Redis 数据类型
Redis 数据类型与底层实现总结 Redis 提供多种高效数据类型,包括 String、Hash、List、Set 和 ZSet 五种基础类型,以及 Bitmap、HyperLogLog 等特殊类型。每种类型针对不同场景设计,底层实现也各不相同:String 使用 SDS 实现二进制安全;Hash 根据数据量在 listpack 和 dict 间切换;List 采用 quicklist 兼顾内存和效率;ZSet 使用 skiplist+dict 实现快速查找和排序。Redis 的高性能源于内存存储、高效数
2026-04-13 20:39:12
397
原创 RabbitMQ消费者处理失败
这是一个非常经典的分布式消息队列问题。简单来说,,具体取决于是在讨论 RabbitMQ 原生的机制,还是所使用的客户端框架(比如在 Java 后端开发中极常用的 Spring AMQP)的封装机制。为了把这个问题说透,我们需要将它分为和来看。
2026-04-09 23:14:24
707
原创 RabbitMQ
死信即无法被正常消费的消息。消息被消费者拒绝(人不要)消息 TTL 到期,超时无人消费(过期了)队列已满,最早的消息成为死信(没人要放不下)消息发送到 MQ 后不立即被消费,而是等待指定时间后才允许消费者获取。
2026-04-05 12:01:17
505
原创 索引下推ICP
索引下推(ICP)是MySQL 5.6引入的优化技术,它允许存储引擎在扫描索引时提前应用WHERE条件过滤,减少不必要的回表操作。以联合索引(name,age)为例,查询"name LIKE '王%' AND age=30"时,无ICP时存储引擎只根据name条件回表4次,Server层再过滤;有ICP后存储引擎直接在索引中判断age条件,仅回表2次。ICP特别适用于联合索引中前缀列使用范围查询、后缀列能过滤大量数据的情况,可显著降低I/O开销。但覆盖索引和分区表等场景下ICP可能无效。
2026-04-04 12:47:22
410
原创 深分页与游标
比如你有一个表,里面有 1000 万条数据,你想看第 10 万页,每页 10 条数据。这里的1000000就是偏移量(OFFSET),表示跳过前 100 万条,再取 10 条。这种写法在数据量很大、页码很深的时候会特别慢,因为数据库必须先把前 100 万条数据找出来,再扔掉,最后只返回 10 条。即使有索引,它也要做很多无用功。假设你刚才看了第 1 页,最后一条记录的id是 100。那么看第 2 页的时候,不要用OFFSET,而是直接取id > 100LIMIT 10;
2026-03-27 17:42:04
285
原创 2PC+Redo Log、Binlog 和 Undo Log 的写入顺序
Undo Log 在事务执行时先写,用于回滚;Redo Log 先进入 Prepare 状态,等待 Binlog 写入成功后转为 Commit,形成两阶段提交,保证两份日志最终一致。
2026-03-27 17:05:14
395
原创 Spring 的三级缓存,两级够吗
Spring通过三级缓存机制解决循环依赖问题,确保AOP代理的正确性。一级缓存存储初始化完成的单例Bean,二级缓存存放未完全初始化的早期Bean,三级缓存保存对象工厂用于生成早期引用。关键点在于AOP代理的生成时机:正常流程在初始化后创建,但循环依赖时需要提前生成代理。三级缓存通过ObjectFactory延迟决策,既避免两级缓存的对象不一致问题,又维持了AOP的正常处理顺序。这种设计平衡了循环依赖和代理生成的复杂性,是Spring容器设计的核心机制之一。
2026-03-20 16:09:06
451
原创 JUC AQS
AQS(AbstractQueuedSynchronizer)是Java并发包的基础框架,它封装了实现同步器(如ReentrantLock、Semaphore等)所需的核心逻辑,让开发者能轻松构建自定义的并发工具。
2026-03-13 16:04:54
247
原创 Redis分布式锁
想象多个服务(比如订单服务部署了3台机器)同时操作一个共享资源(比如库存),如果不加控制,就会出现超卖、数据不一致等问题。分布式锁就是用来保证同一时刻只有一个服务实例能访问这个共享资源。基础版:SET NX EX + 线程标识 + Lua 解锁,满足基本互斥,但功能简单。进阶版(Redisson)可重入(Hash 结构)可重试(发布订阅)自动续期(看门狗)解决主从一致性问题(联锁)终极理论:Redlock,但实践中很少用。
2026-03-12 15:57:46
484
原创 请你说说hashCode()和equals()的区别,为什么重写equals()就要重写hashCode()
摘要:equals()比较对象内容,hashCode()返回哈希码。重写equals()必须同时重写hashCode(),以保证相等的对象哈希码相同,确保哈希表正常工作。重写时,equals()比较所有相关属性,hashCode()使用相同属性计算,可用Objects.hash()简化实现。这是Java规范要求的重要契约,标准类库都遵守此规则。
2025-12-18 12:17:55
253
原创 流量控制和拥塞控制的步骤?流量控制和拥塞控制的步骤?
发送端计算可用窗口:min(rwnd, cwnd),只要已发送但还未收到ACK确认字节数 < (Win)当前发送窗口,就可继续发送。发送端发完报文后,将其置入’已发送未ACK队列。接收端收到数据后,释放缓冲并更新 rwnd = BufferSize - 已占用,发送端收到新ACK,滑动发送窗口,继续发送。三个重复ACK意味着网络还有一定的传输能力(至少还能传送重复的ACK),所以网络并不完全拥塞,只是个别报文段丢失。收到新数据的ACK后,cwnd = ssthresh,进入第3步(拥塞避免)。
2025-12-16 22:13:36
396
原创 说说线程的生命周期和状态
摘要:Java线程的生命周期包含6种状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超时等待)和TERMINATED(终止)。RUNNABLE状态对应操作系统的就绪和运行态,而WAITING/TIMED_WAITING/BLOCKED状态的线程在操作系统层面处于挂起状态。线程状态转换由JVM和操作系统调度器控制,理解这些状态对多线程编程和调试至关重要。Java线程状态既包含操作系统状态抽象(如RUNNABLE),也包含特有的协作状
2025-12-16 21:23:25
517
原创 大表(千万级)查询 / 维护该怎么办?
慢查询日志定位瓶颈,针对性优化索引和SQL,并建立冷热数据归档机制。如果数据量或并发量持续增长到亿级,我会主导进行分库分表的技术选型(如ShardingSphere),核心是设计好分片键和解决分片后带来的查询挑战,通常会结合Elasticsearch来应对复杂查询。整个过程,我会特别注意方案的可灰度、可回滚,以及与团队的充分协作。“在项目中处理千万级大表时,我理解这不是一个单纯的SQL优化问题,而是一个需要从。当单库单表的写入和存储成为瓶颈,就必须进行分片。当单表优化触及天花板,就该进行架构升级。
2025-12-15 14:57:50
543
原创 MySQL 的存储引擎
MySQL存储引擎对比摘要:InnoDB是最可靠的"银行经理",支持事务、行锁和外键,适合重要业务场景;MyISAM是过时的"图书馆管理员",只读快但修改性能差;Memory是临时的"白板",速度快但数据易丢失。当前推荐选择InnoDB作为默认引擎,它能满足绝大多数严肃应用的需求,而其他两种引擎已基本被淘汰或替代。核心差异在于事务支持、锁机制和数据持久性,InnoDB在可靠性和并发性能方面具有明显优势。
2025-12-15 14:30:59
469
原创 Java中如何检测死锁?如何预防和避免线程死锁?
本文提供了Java死锁从检测到预防的完整解决方案。首先介绍使用jps、jstack等JDK工具检测死锁,以及Arthas的高级诊断能力。随后深入讲解四种预防策略:通过ThreadLocal破坏互斥条件,统一资源申请破坏请求保持条件,超时机制破坏不可剥夺条件,以及资源排序破坏循环等待条件。每种策略均配有具体Java代码实现,帮助开发者从设计层面避免死锁问题,构建更健壮的并发系统。
2025-12-14 17:00:55
763
原创 说说Redis的单线程架构
Redis采用单线程模型处理核心网络I/O和命令执行(6.0版本前),确保原子性操作且避免多线程开销。其高效性源于内存操作、I/O多路复用和优化的数据结构。单线程简化了实现,但存在CPU密集型操作阻塞的风险。Redis 6.0+引入多线程I/O处理网络请求,核心执行仍保持单线程,平衡性能与原子性。这种设计在特定场景下最大化性能,同时通过演进解决瓶颈问题。
2025-12-13 19:29:49
990
原创 G1收集器
G1垃圾回收器采用分区化内存管理策略,将堆划分为多个大小相等的Region,动态扮演不同分代角色。其核心机制是通过微观复制(每次回收选定Region的存活对象复制到空闲区)逐步实现宏观上的标记-整理效果。G1创新性地引入停顿预测模型,优先回收收益最大的Region,平衡吞吐量与低延迟需求。工作流程包含初始标记、并发标记、最终标记和筛选回收四个阶段,通过增量式并发回收实现可预测的停顿时间。这种设计使G1特别适合大内存、多核服务器环境,在保持较高吞吐量的同时提供较短的停顿时间。
2025-12-12 14:26:23
664
原创 详细描述一条 SQL 在 MySQL 中的执行过程
MySQL执行SQL语句分为服务层和存储引擎层两阶段处理。服务层负责连接管理、SQL解析、优化器生成执行计划,执行器调用存储引擎接口;存储引擎层负责实际数据存取,以InnoDB为例,通过缓冲池、日志机制等实现高效读写。整个过程涉及权限校验、索引选择、事务处理等关键环节,最终将结果返回客户端。优化器决策和存储引擎I/O效率是性能关键,更新操作还需处理事务日志以保证ACID特性。
2025-12-11 15:09:07
852
原创 MySQL主从同步
MySQL主从同步通过二进制日志实现数据复制,主库记录变更到binlog,从库I/O线程读取并写入relay log,SQL线程执行变更。该机制提供三大核心价值:1)高可用性,主库故障时可快速切换;2)读写分离,提升并发能力;3)数据备份,不影响主库性能。典型架构包括一个主库负责写操作,多个从库承担读请求,实现数据冗余和负载均衡。
2025-12-11 14:55:13
989
原创 Java中栈和队列的实现
本文介绍了Java中使用Deque实现栈和队列的两种写法。对于栈的实现,使用ArrayDeque的push、pop和peek方法;队列实现则通过Queue接口的offer、poll和peek方法操作。两种方式都支持size()和isEmpty()等常用操作,ArrayDeque作为双端队列能高效实现这两种数据结构。这些方法在算法题中经常使用,简洁高效。
2025-12-10 14:41:14
231
原创 如何使用 EXPLAIN 分析查询?关注哪些列?
MySQL查询性能优化关键指标分析:type列反映查询速度(const最快,ALL最慢);key列显示实际使用索引(NULL表示未用索引);rows列预估扫描行数(越小越好);Extra列提示额外操作(Using index最优,Using filesort/temporary需优化)。重点关注type=ALL、key=NULL、rows过大或出现Using temporary/fi lesort的情况,这些是查询效率低下的重要信号。
2025-12-10 13:52:51
283
原创 为什么需要四次挥手
TCP连接关闭需要四次挥手,本质是由其全双工特性决定的。四次挥手分别关闭两个独立的数据通道:主动方先发送FIN关闭发送通道,被动方回复ACK确认;被动方处理完数据后发送FIN关闭自己的通道,主动方最后回复ACK。由于ACK和FIN通常无法合并(ACK立即回复,FIN需等待数据处理完毕),因此必须四次交互。只有在被动方无数据发送时,ACK和FIN才能合并为三次挥手。
2025-12-09 10:57:36
479
原创 TCP 的粘包 / 拆包机制
TCP粘包和拆包是应用层数据在TCP字节流中的表现形式问题,本质是应用层未正确定义消息边界。粘包指接收端一次读取到多个发送端消息,拆包指接收端只读取到部分消息。主要原因包括TCP缓冲区的数据合并、Nagle算法优化等。解决方案包括:1)固定长度消息;2)使用特定分隔符;3)最常用的长度字段+内容方式,即在消息头中定义长度字段。在Java中,可使用原生NIO手动处理,或借助Netty框架的解码器(如LengthFieldBasedFrameDecoder)高效解决。这是TCP作为字节流协议的特性而非缺陷,需要
2025-12-08 20:24:07
1159
原创 MySQL 的锁类型有哪些
摘要:数据库锁机制根据锁定粒度分为全局锁、表级锁和行级锁。全局锁锁定整个数据库实例,适用于全库备份;表级锁包括表锁和元数据锁(MDL),MDL自动管理表结构变更的并发控制;行级锁针对单行记录,并发度高但开销大。三种锁在锁定粒度、开销、加锁速度和并发度上各有特点,适用于不同场景,如全局锁用于备份,表级锁用于DDL操作,行级锁用于高并发事务更新。
2025-12-08 18:14:05
367
原创 讲一下 Spring 中用到的设计模式
工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;单例模式:Bean默认为单例模式。代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
2025-12-07 16:15:16
756
原创 介绍一下你知道的锁
本文系统梳理了Java并发编程中的锁机制,从多个维度对锁进行分类:乐观锁与悲观锁(思想层面)、公平锁与非公平锁(调度策略)、可重入锁与非可重入锁(重复进入能力)、独享锁与共享锁(读写特性)以及自旋锁与互斥锁(等待策略)。重点分析了synchronized关键字的锁升级过程(偏向锁→轻量级锁→重量级锁)和ReentrantLock基于AQS的实现原理,比较了二者的特性差异。同时介绍了CAS机制及其在原子类中的应用,指出了ABA问题等局限性。文章为理解Java并发控制提供了清晰的技术框架。
2025-12-07 15:42:07
684
原创 读写锁 (ReadWriteLock)
Java读写锁(ReadWriteLock)是一种高效并发控制机制,它允许多个线程同时读取共享数据,但写入时保证独占访问。核心特点是"读读共享、读写互斥、写写互斥",特别适合读多写少的场景(如缓存、配置管理)。Java通过ReentrantReadWriteLock实现该功能,支持锁降级(写锁降为读锁)和公平性选择。使用时需注意避免写锁饥饿问题,确保在finally块中释放锁。相比synchronized,读写锁在读取频繁的场景下能显著提升性能,但写操作频繁时反而不适用。典型应用包括图书
2025-12-06 18:35:25
508
原创 2PC协议:两阶段提交协议
摘要:2PC(两阶段提交)是分布式系统中确保事务原子性的经典协议,分为准备阶段(参与者投票)和提交/回滚阶段(协调者决策)。其优点是强一致性,但存在同步阻塞、单点故障和数据不一致风险。现代系统多采用Saga、TCC等替代方案。2PC作为理论基础,对理解分布式一致性至关重要。
2025-12-05 09:01:28
850
原创 说说你对反射的了解
Java反射机制是运行时动态分析和操作类的能力,通过Class、Constructor等核心API实现。它在Spring、MyBatis等框架中广泛应用,支撑IOC、AOP等核心功能。反射虽提供灵活性,但存在性能开销和破坏封装的风险,需通过缓存优化。现代Java模块化对反射访问进行了限制。面试回答应结合具体框架应用、性能优化方案和模块化影响等要点,展现对反射机制的深入理解。
2025-12-04 14:52:34
553
原创 ==与equals()
=运算符基本数据类型:比较的是值本身引用数据类型:比较的是对象的内存地址(是否指向同一个对象)equals()方法Object类的默认实现与==相同// Object类的equals方法源码// 默认就是==,比较地址但是,很多类(如String、Integer等)重写了equals方法,使其比较的是对象的内容是否相等。因此,对于这些类,equals方法用于比较两个对象的内容是否相同。
2025-12-03 21:23:13
439
原创 String、StringBuffer、Stringbuilder有什么区别?
StringBuilder的方法与StringBuffer完全一致,只是没有synchronized修饰。单线程用StringBuilder,多线程用StringBuffer String不可变,每次修改生成新对象;StringBuffer和StringBuilder可变。StringBuffer线程安全但性能较低,StringBuilder非线程安全但效率更高。单线程用StringBuilder,多线程用StringBuffer。
2025-12-03 21:09:04
380
原创 Java中的深拷贝,浅拷贝和引用拷贝
引用拷贝:复制对象引用地址,新旧变量指向同一对象。浅拷贝:创建新对象,复制基本类型值,引用类型仍指向原对象。深拷贝:完全复制对象及关联的所有子对象,新旧对象完全独立。实现方式:浅拷贝常用clone()方法(需重写),深拷贝需递归复制或序列化实现。核心区别:深拷贝隔离数据修改,浅拷贝和引用拷贝存在数据关联性。
2025-12-02 15:37:17
157
原创 消息队列如何保证顺序消费
保证顺序消费的关键点:生产者端相同业务ID的消息发送到同一个队列/分区使用同步发送或有限重试Broker端利用消息队列的队列/分区机制合理设置分区策略消费者端单线程消费同一队列手动提交偏移量处理失败时暂停消费业务层设计幂等操作使用状态机验证准备降级方案明确场景:不是所有消息都需要顺序消费分层次:生产者、Broker、消费者各层如何保证讲权衡:顺序性与性能的权衡提方案:根据业务场景选择合适的消息队列和方案说实践:监控、降级、测试等生产经验。
2025-12-02 15:22:40
930
原创 谈谈 HTTP 的缓存机制,服务器如何判断缓存是否过期?
时间基准:通过或Expires设置新鲜期验证基准:通过ETag或验证内容是否变更合理配置缓存策略可以显著提升网站性能,减少服务器负载,改善用户体验。
2025-12-02 14:57:44
450
原创 分布式事务
分布式事务是跨多个服务或节点的业务操作,需保证数据一致性。解决方案分为强一致性和最终一致性两类。强一致性如2PC/3PC,通过协调者管理事务提交,但存在性能瓶颈和单点问题。最终一致性方案如TCC(分Try/Confirm/Cancel三阶段)、本地消息表、事务消息(如RocketMQ)和Saga模式(带补偿机制),通过异步和重试实现最终一致。Seata框架整合多种模式,简化开发。选型需权衡一致性、性能和复杂度,实际应用中TCC适合短事务,Saga适合长流程,事务消息用于异步解耦。
2025-12-01 15:33:46
721
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅
4