- 博客(100)
- 收藏
- 关注
原创 动态规划之回文串&&两个数组的dp问题
本文介绍了动态规划解决字符串问题的三个经典案例:回文子串计数、最长回文子串和编辑距离。回文子串问题通过构建布尔型DP表,从后向前遍历统计回文数量;最长回文子串则在DP表基础上寻找最大长度区间;编辑距离问题通过初始化边界条件,比较字符差异进行状态转移。三个问题都采用二维DP表,通过特定遍历顺序和边界处理实现高效求解,展现了动态规划在字符串处理中的典型应用模式。
2026-04-23 11:47:48
1206
原创 你了解synchronized吗
摘要:synchronized是Java中实现线程同步的关键字,通过对象监视器(Monitor)机制保证代码块或方法在同一时刻仅被一个线程执行。JDK1.6后优化为锁升级机制:无锁→偏向锁(首次获取)→轻量级锁(CAS自旋)→重量级锁(竞争激烈时)。实现原理涉及对象头MarkWord和Monitor对象,通过monitorenter/monitorexit指令管理锁状态。修饰不同元素时锁定范围不同:非静态方法锁当前对象,静态方法锁类对象。锁升级过程根据竞争强度动态调整,兼顾性能与线程安全。
2026-03-30 22:19:23
2063
原创 LRU缓存是什么&&手写LRU缓存
摘要:本文介绍了LRU缓存的两种实现方式。第一种使用LinkedHashMap,通过设置accessOrder为true实现访问顺序排序,并重写removeEldestEntry方法来自动淘汰最久未使用的节点。第二种是手动实现,采用HashMap+双向链表结构,通过虚拟头节点管理节点顺序,包含getNode、remove和pushFront等核心操作。两种方法都实现了LRU缓存的基本功能:get操作获取并更新访问顺序,put操作添加或更新节点并在容量满时淘汰最久未使用的节点。手动实现需注意节点操作的顺序,避
2026-03-17 22:35:51
450
原创 动态规划之子数组问题
本文总结了动态规划解题的新体会,重点在于处理边界条件和理清状态转移方程。通过分析力扣上的四道典型题目(最大子数组和、乘积为正数的最长子数组、乘积最大子数组、单词拆分),探讨了动态规划的实现步骤与技巧。文章强调在解题过程中要特别注意边界条件的处理,这是动态规划问题的主要难点之一。
2026-02-23 22:55:46
613
原创 谈谈SQL优化&&数据库常见问题
数据库主键选择:UUID全局唯一但无序,占用空间大且写入性能随数据增长下降;INT自增有序,空间小且写入性能高。UUID适合分布式系统避免ID冲突,INT适合单体架构追求性能。 慢查询排查:检查索引失效、服务器负载和锁等待。通过慢查询日志定位问题SQL,用EXPLAIN分析执行计划,监控CPU和I/O指标。锁等待指事务因资源被占用而阻塞。 索引失效场景:优化器基于成本估算,当结果集比例高或索引选择性差时可能放弃索引。即使使用索引,回表次数多、数据量大或网络传输也会导致查询缓慢。
2026-02-11 20:29:13
799
原创 Java的基础知识
本文摘要:Java核心概念解析,包括==与equals()的区别:==比较基本类型的值和引用类型的内存地址,equals()可重写用于比较对象属性;hashCode()用于快速定位对象,应与equals()保持一致。BigDecimal解决浮点数精度问题。自动装箱/拆箱原理。深/浅拷贝区别:深拷贝复制全部对象,浅拷贝复制引用。面向对象三大特征:封装、继承、多态。String的不可变性及常量池机制,StringBuilder/StringBuffer的线程安全差异。字符串拼接优化建议:少量用"+&q
2026-01-28 21:49:06
2245
原创 重走力扣hot的矩阵
摘要:本文介绍了三种矩阵处理算法及其优化方法。1. 矩阵置零:通过HashSet记录零元素位置(空间O(M+N)),优化后利用矩阵首行首列标记(空间O(1));2. 螺旋矩阵:按上、右、下、左边界顺序处理元素;3. 旋转图像:通过分层和偏移量实现顺时针旋转。最后还给出了搜索二维矩阵II的解法,利用矩阵特性进行高效搜索。各算法均配有详细实现代码和关键思路说明。
2026-01-26 21:42:17
522
1
原创 计算机网络基础
摘要: OSI七层模型和TCP/IP四层模型是两种主要的网络分层架构。OSI包含应用层到物理层7个层级,各层分工明确;TCP/IP则简化为应用层、传输层、网络层和网络接口层4层。分层设计使各层独立运作,提高系统灵活性和可维护性,类似软件设计中的"高内聚低耦合"原则。常见协议包括HTTP、DNS(应用层)、TCP/UDP(传输层)、IP/ICMP(网络层)等。分层架构将复杂网络通信问题分解为多个小问题,便于实现和管理。
2026-01-19 13:59:59
224
原创 TCP与UDP的探究
TCP和UDP是两种主要的传输层协议。TCP面向连接,提供可靠传输,但效率较低;UDP无连接,效率高但不保证可靠性。TCP通过三次握手建立连接、四次挥手断开连接,采用校验和、序列号、确认应答、超时重传等机制保证可靠性,并通过滑动窗口进行流量控制。TCP还通过慢启动、拥塞避免、快重传等算法实现拥塞控制。TCP存在粘包问题,需应用层通过分隔符或长度字段解决。UDP以数据包为单位传输,无粘包问题,适合实时性要求高的场景。两种协议各有特点,适用于不同场景。
2026-01-19 11:58:50
1619
原创 JVM中的类加载&&Minor GC与Full GC
本文摘要: Java类加载机制包括启动类加载器、扩展类加载器和应用类加载器,采用双亲委派模型确保核心类安全加载。但某些场景(如JDBC驱动加载)需要打破该模型。垃圾回收方面,MinorGC针对新生代,频繁快速;FullGC涉及整个堆内存,速度慢且触发条件包括老年代空间不足、大对象分配等。两者主要区别在于回收范围和发生频率,MinorGC在Eden区满时触发,FullGC则需满足特定条件才会执行。
2026-01-12 13:48:55
1449
原创 常见的垃圾回收器
本文介绍了Java中常见的垃圾回收器类型及其特点。垃圾回收器分为并行、并发和串行三种工作模式,其中并行模式采用多线程但会暂停用户线程(STW),并发模式则与用户线程同时执行。详细列举了Serial、ParNew、ParallelScavenge等新生代收集器,CMS、SerialOld等老年代收集器,以及整堆收集器G1。重点分析了CMS收集器的四个处理阶段(初始标记、并发标记、重新标记、并发清除)及其优缺点,以及G1收集器的Region设计理念和四个工作阶段。G1通过分区回收和优先级策略实现了吞吐量与低延迟
2026-01-12 13:46:20
1459
原创 接雨水的三种解法
本文介绍了LeetCode"接雨水"问题的三种解法:1. 动态规划法:预处理左右最大值数组,计算每个位置的储水量,空间复杂度O(n);2. 双指针法(最优):优化动态规划,通过左右指针实时更新最大值,空间复杂度O(1);3. 单调栈法:维护递减栈计算凹槽面积。作者推荐先理解动态规划再掌握双指针解法,并详细说明了各解法关键区别(如左右最大值是否包含当前位置)。代码示例展示了三种解法的具体实现,强调了核心思路和优化要点。
2026-01-12 07:00:00
344
原创 常见的垃圾收集算法
垃圾收集主要有三种基础算法:1)标记-清除算法(速度快但产生内存碎片);2)复制算法(适合新生代,无碎片但需双倍内存);3)标记-压缩算法(适合老年代,无碎片但效率低)。现代GC多采用分代收集算法,将堆分为新生代(使用复制算法)和老年代(使用标记-压缩算法)。新生代通过Minor GC回收短生命周期对象,老年代通过Full GC回收,但会暂停应用运行(STW)。分代收集平衡了不同算法的优缺点,优化了内存管理效率。
2026-01-10 20:06:15
1357
原创 JVM中的内存结构
本文介绍了JVM内存结构的关键知识点。JVM内存分为线程私有区域(程序计数器、虚拟机栈、本地方法栈)和共享区域(堆、方法区)。JDK1.6中方法区使用永久代实现,而JDK8改用元空间并移至本地内存。堆和栈的主要区别在于:栈存储方法调用信息且生命周期确定,堆存储对象实例且生命周期不确定;栈空间较小且线程私有,堆空间较大且线程共享。内存泄漏指无用对象未被回收导致内存减少,而内存溢出是申请内存时空间不足导致的错误,前者可能引发后者。
2026-01-02 22:45:05
1533
原创 Redis的分布式锁
摘要:分布式锁是解决超卖问题的有效方案,通过Redis设置key-value实现互斥访问。但需注意多个问题:1)校验机制防止锁误删;2)Lua脚本保证判断和删除操作的原子性;3)看门狗机制动态续约过期时间;4)RedLock(红锁)解决主从切换导致锁失效问题。这些机制共同确保分布式锁的可靠性和安全性。
2025-12-24 19:10:34
1154
原创 并发编程-CAS
CAS(比较再交换)是一种无锁并发机制,通过比较内存值确保线程安全。线程先读取共享变量旧值,计算新值后比较内存当前值,若未变则更新,否则自旋重试。该机制被广泛应用于AQS和原子类(如AtomicInteger)中。优点是无锁高效,缺点是自旋消耗CPU且存在ABA问题(值被多次修改后恢复原值)。ABA问题可通过版本号机制解决,如AtomicStampedReference类通过附加版本号确保数据完整性。
2025-12-23 15:14:58
859
原创 常见锁策略
摘要:悲观锁与乐观锁的主要区别在于冲突处理方式:悲观锁独占资源,性能开销大;乐观锁通过重试避免阻塞,性能更优。轻量级锁采用自旋方式应对低竞争,重量级锁涉及系统调度。读写锁区分读写操作提升并发性。可重入锁支持递归调用避免死锁,公平锁保证先来先服务但性能较低,非公平锁效率更高但牺牲公平性。不同锁机制适用于不同并发场景,需权衡性能与功能需求。
2025-12-23 15:13:00
455
原创 力扣hot图论部分
本文总结了LeetCode中四个典型算法问题的解法:1. 岛屿数量(FloodFill算法):使用BFS遍历相邻陆地,通过visit数组标记已访问节点;2. 腐烂的橘子(多源BFS):统计新鲜橘子数,多源点同时扩散,注意时间计数方式;3. 课程表(拓扑排序):建立邻接表统计入度,通过BFS检测环;4. 前缀树:实现Trie结构,支持插入和查询操作。每个问题都提供了核心思路和关键代码实现,重点讲解了算法细节和注意事项。
2025-12-18 13:46:51
740
原创 暴打力扣之优先级队列(堆)
本文探讨了解决TOP-K问题的三种方法:优先队列、手动实现堆和快速选择法。在LeetCode第215题和第347题中,作者分别使用这三种方法进行实现。优先队列方法简单直接,手动实现堆能更好理解堆结构,快速选择法通过三数取中优化达到平均O(N)时间复杂度。三种方法各有优劣:优先队列稳定但效率一般(O(NlogK)),快速选择法平均效率高但不稳定,手动实现堆则更具学习价值。文章详细展示了每种方法的代码实现,并比较了它们的适用场景,为处理TOP-K问题提供了全面的解决方案参考。
2025-12-01 22:11:06
981
原创 MySQL索引失效的情况
摘要:本文分析了导致MySQL索引失效的常见情况,包括:1)对索引列使用函数或表达式;2)隐式类型转换;3)LIKE以通配符开头的查询;4)违反联合索引最左前缀原则。重点阐述了联合索引的工作原理,说明查询必须包含最左列才能有效利用索引,否则会导致索引失效。同时解释了B+树索引结构决定了前缀匹配的高效性和后缀匹配的低效性。这些知识对优化SQL查询性能具有重要指导意义。
2025-12-01 21:46:55
2441
原创 暴打力扣hot的普通数组专题
本文总结了LeetCode三道题目的解题思路与代码实现:1. 除自身以外数组的乘积(238题)采用左右乘积数组法,时间复杂度O(n),空间复杂度O(n);2. 合并区间(56题)先排序后合并重叠区间,时间复杂度O(nlogn);3. 缺失的第一个正数(41题)提供了三种解法:排序二分查找(O(nlogn))、哈希集合(O(n))和原地哈希(最优解O(n))。其中原地哈希法通过元素归位策略实现最优时空复杂度,是推荐的解决方案。
2025-11-24 19:56:48
443
原创 日志(Redo Log、Undo Log、Binlog)
MySQL通过多日志机制实现事务特性与数据安全:RedoLog(物理日志)采用WAL技术,顺序IO记录数据页修改,确保事务持久性和崩溃恢复;UndoLog(逻辑日志)记录反向操作,支持事务回滚(原子性)和MVCC多版本控制,通过版本链和ReadView实现不同隔离级别;BinLog(逻辑日志)记录表结构变更和数据修改,用于主从同步和数据恢复。三大日志协同工作,RedoLog和UndoLog位于存储引擎层,BinLog在Server层,共同保障MySQL性能与数据一致性。
2025-11-24 19:33:07
3049
1
原创 暴打力扣hot中的链表专题
本文分享了力扣Hot链表专题中最具代表性的三道题目的解题思路和代码实现。23题合并K个升序链表提供了优先级队列和归并两种解法,其中归并分治的方法更为推荐;146题LRU缓存通过双向循环链表加哈希表实现,重点讲解了虚拟头节点的作用;148题排序链表采用归并排序,虽然迭代解法空间复杂度更优,但归并排序更具通用性。文章详细分析了每道题的解题思路和代码实现要点,难度依次递增,为链表问题提供了实用的解决方案。
2025-11-17 21:36:45
1659
2
原创 类的声明周期
Java类的生命周期包括加载、链接、初始化、使用和卸载五个阶段。加载阶段通过类加载器将字节码读入内存;链接阶段进行验证、准备和解析;初始化阶段执行静态代码块和变量赋值。被动引用(如访问父类静态字段)不会触发初始化。类的卸载需要满足实例被回收、Class对象无引用和ClassLoader被回收三个条件。常见异常包括NoClassDefFoundError和ClassNotFoundException。理解生命周期有助于优化内存管理和避免类加载问题。
2025-11-17 20:26:00
1713
1
原创 内存结构/运行时数据区
本文摘要: JVM内存结构分为运行时数据区和直接内存。运行时数据区包括线程私有的程序计数器、虚拟机栈、本地方法栈,以及线程共享的堆和方法区。其中,方法区在JDK1.7以永久代实现,位于堆内;JDK1.8改为元空间,使用本地内存。堆内存分为新生代和老年代,存储对象实例。直接内存属于操作系统内存,常用于NIO缓冲区。相比BIO的阻塞式I/O,NIO采用非阻塞模式,通过Channel和Selector实现高效I/O操作。这些改进提升了JVM性能,解决了永久代OOM等问题,使内存管理更灵活高效。
2025-11-14 21:56:30
2030
3
原创 重点理解线程池
摘要:线程池通过资源管理和线程复用避免了频繁创建销毁线程的性能损耗,其核心参数包括线程数量、存活时间、任务队列和拒绝策略等。任务提交遵循"核心线程→队列→临时线程→拒绝策略"流程。拒绝策略需根据不同业务场景选择,如AbortPolicy适合允许失败任务,而CallerRunsPolicy适合不能丢失任务的情况。线程数设置应考虑任务类型(CPU密集型或I/O密集型),并通过压测优化。不建议使用Executors创建线程池,因其可能导致OOM,推荐使用ThreadPoolExecutor方式
2025-11-10 21:44:33
1613
原创 线程需要重点掌握的部分
Java线程具有六种状态:新建(NEW)、就绪(Runnable)、阻塞(Blocked)、等待(Waiting)、计时等待(Timed_Waiting)和终止(Terminated)。线程通过调用特定方法在这些状态间流转,如start()进入就绪状态,遇到锁竞争进入阻塞状态等。创建线程的方式多样,包括继承Thread类、实现Runnable/Callable接口,以及使用线程池和lambda表达式。多线程技术广泛应用于耗时操作处理,如大文件传输、资源加载、聊天软件和服务器后台等场景,能显著提升程序执行效率
2025-11-10 21:36:44
431
原创 回溯专题之二叉树
本文分享了四道力扣热题二叉树问题的DFS递归解法。通过回溯训练后,作者发现递归在二叉树问题中非常巧妙。具体题目包括:199.二叉树的右视图(DFS遍历记录每层最右节点)、114.二叉树展开为链表(前序遍历重构)、437.路径总和III(双重递归统计路径)和124.二叉树最大路径和(后序遍历计算子树贡献值)。每道题都提供了思路分析和Java代码实现,展示了DFS+递归在不同场景下的灵活应用。通过这些问题,作者体会到递归思维对解决二叉树问题的重要性。
2025-11-10 21:29:16
427
原创 Redis中的分布式锁
摘要:Redis的SetNX命令通过设置唯一键实现分布式锁,需判断线程ID防止误删,建议使用Lua脚本保证原子性。Redisson提供更完善的分布式锁方案,支持可重入锁和看门狗机制自动续期。针对主从同步问题,可采用MultiLock或RedLock方案,通过多主节点投票确保加锁可靠性。RedLock要求半数以上节点加锁成功,并设置超时时间,适用于高可靠性要求的分布式场景。
2025-11-05 16:09:21
1434
9
原创 缓存击穿/穿透/雪崩
缓存击穿与穿透是两种不同问题:击穿指热点key失效导致大量请求直达数据库(解决方案:互斥锁或永不过期+逻辑过期);穿透指查询不存在的数据导致请求穿透缓存(解决方案:缓存空值或布隆过滤器)。缓存雪崩则是大量key同时过期或Redis宕机(解决方案:均匀设置过期时间、集群部署)。面试中需明确区分这几种情况及其对应解决方案。
2025-11-05 15:46:22
1353
原创 Redis集群中的故障判定和故障迁移流程
Redis集群故障检测与迁移机制:节点间通过定期随机发送ping/pong包交换状态信息。当节点B未响应ping时,A将其标记为PFAIL(主观下线);若超半数节点也认为B故障,则升级为FAIL(客观下线)。若B是主节点,其从节点将触发故障迁移:符合资格的从节点休眠不同时长后竞选(Raft算法),最早唤醒且获得多数主节点投票的从节点将晋升为主节点,接管原主节点的slots并通知集群更新拓扑。该机制通过随机心跳和分级休眠有效避免了N²级通信和选举冲突。
2025-11-05 10:26:43
1159
2
原创 回溯专题-N皇后/单词搜索
文章摘要:本文介绍了两种回溯算法的优化解法:N皇后问题和单词搜索。在N皇后问题中,通过使用三个布尔数组(列、左对角线、右对角线)替代传统四重循环检查,提升了效率。单词搜索则采用向量数组(dx/dy)简化四方向遍历,避免重复代码。两种解法均通过DFS+回溯实现,并强调恢复现场的重要性。相比力扣官方题解,这些技巧使代码更简洁高效,分别为N皇后问题和单词搜索问题提供了优化方案。
2025-11-03 22:37:22
522
2
原创 Redis的持久化
摘要:Redis提供RDB和AOF两种持久化机制。RDB默认开启,通过定时快照保存数据,恢复速度快但可能丢失部分数据;AOF记录每个写命令,数据更安全但文件较大。Redis 4.0引入混合持久化,结合两者优势:AOF文件开头采用RDB格式存储快照,后续追加AOF命令,既提升恢复速度又降低数据丢失风险。但混合格式不兼容旧版Redis。两种机制各有适用场景,RDB适合备份和全量复制,AOF则提供更高数据安全性。
2025-11-03 19:15:30
1344
2
原创 回溯专题:子集/全排列问题
摘要:本文分析了力扣78题(子集)和46题(全排列)的解题思路。两者都采用深度优先遍历(DFS)和回溯法,使用全局变量path和ret简化函数设计。子集问题通过递归遍历每个元素的选与不选两种情况,全排列问题则利用check数组剪枝。核心要点包括:决策树的构建、回溯时现场恢复、递归终止条件处理。两题解法高度相似,只要能列出所有情况(画出决策树),都可使用DFS+回溯法解决。(149字)
2025-10-30 22:18:51
523
1
原创 MySQL中的索引
MySQL索引选用B+树而非哈希或二叉树的深层原因:哈希虽快但无法范围查询;二叉树存在退化风险且IO效率低。B+树的核心优势在于非叶节点仅存索引实现高分支因子(降低树高)、叶子节点双向链表支持高效范围查询,同时避免B树数据分散存储的问题。索引分类中,主键索引即聚集索引存储完整记录,二级索引需回表查询;覆盖索引可避免回表,通过直接在二级索引中获取所需列提升性能。这种设计完美平衡了查询效率、范围操作与磁盘IO优化的需求。
2025-10-28 09:43:59
1401
2
原创 HashMap和ConcurrentHashMap的相关八股
摘要:HashMap在多线程环境下存在线程安全问题。JDK1.7中扩容时使用头插法可能导致环形链和数据丢失,而JDK1.8中插入空桶时可能发生数据覆盖。JDK1.8的优化包括:采用尾插法减少锁竞争、引入红黑树提升查询效率、改进扩容机制以及使用CAS操作确保数据一致性。这些改进显著提升了HashMap和ConcurrentHashMap在高并发场景下的性能和安全性。
2025-10-27 07:00:00
1386
4
原创 动态规划之两个字符组/两个数组的dp问题
本文分析了LeetCode上两道字符串动态规划问题:1143.最长公共子序列和72.编辑距离。最长公共子序列通过构建二维DP数组,当字符相同时取左上角值+1,否则取左或上较大值。编辑距离同样使用二维DP,初始化边界后,字符相同时取左上角值,不同则取左、上、左上最小值+1。两题都采用类似DP思路,但状态转移方程不同,体现了字符串匹配问题的不同解法。代码实现中均对字符串前补空格便于处理边界条件。
2025-10-20 22:49:49
1682
1
原创 动态规划之回文串相关问题
【摘要】本文介绍了回文子串问题的两种动态规划解法。对于647题(统计所有回文子串数量),通过构建n×n的布尔矩阵f[i][j]表示s[i..j]是否为回文,遍历时比较首尾字符并根据子问题结果填充矩阵,最后统计true的数量。5题(寻找最长回文子串)采用相同思路,在填充矩阵后记录最长回文子串的起始位置和长度。两题核心均为:f[i][j] = (s[i]==s[j]) && (j-i<2 || f[i+1][j-1]),时间复杂度O(n²),空间复杂度O(n²)。
2025-10-13 20:39:52
1574
原创 动态规划-子数组问题-单词拆分
该摘要介绍了力扣第139题"单词拆分"的动态规划解法。使用布尔数组f[i]表示前i个字符能否被拆分,初始化f[0]=true。通过双重循环遍历所有可能的子串,若f[j-1]为true且剩余子串在字典中,则f[i]置为true。最终返回f[n]即为答案,时间复杂度O(n²)。文中包含完整Java代码实现和测试用例。
2025-10-08 10:20:43
1355
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅