- 博客(41)
- 收藏
- 关注
原创 天津小公司面经
面试总结 一面考察了WebSocket优化、短链接缓存、MySQL索引设计等技术问题。亮点包括使用布隆过滤器优化缓存访问路径,以及在分类需求中设计树形表结构和联合索引。二面则聚焦于Java并发控制和SpringBoot组件开发,对于考试排名场景题的解决方案引发了争议,面试官更倾向纯MySQL方案而非Redis缓存策略。整体展现出扎实的基础知识,但在部分场景题的理解深度和方案选择上仍有提升空间。
2025-10-08 00:17:16
347
原创 情感雷达-AI 聊天帮手
简介:基于苹果快捷指令的小工具。当你不知道怎么回复的时候,可以让 ai 帮你想想。目前都要 25S 左右。还没想到什么优化方式。最近写了一个小玩具,大家觉得有什么应用场景吗?
2025-09-19 19:19:10
102
原创 小小面试,也算是处女面吧。
摘要:本文记录了Java面试经历,面试官考察了Java基础、集合、多线程等知识点。虽然部分内容记不太清(如IO流、线程状态),但通过策略模式讲解多态、区分重载重写等回答还算顺利。MyBatis参数传递、Spring事务等八股问题都能应对,但线程状态和wait/sleep区别回答得不太理想。整体感觉面试难度适中,主要考验基础知识的掌握程度。
2025-08-31 20:00:38
315
原创 热题 100-53.最大子数组和
摘要:LeetCode第53题要求找出整数数组中具有最大和的连续子数组。采用动态规划思想,维护两个变量:当前累加值sum和最大结果ans。当sum>0时继续累加,否则重新赋值。示例代码演示了O(n)解法,核心在于比较和更新sum与ans的值。进阶挑战是使用分治法实现。典型示例如输入[-2,1,-3,4,-1,2,1,-5,4]时,最大子数组[4,-1,2,1]的和为6。(149字)
2025-08-30 09:58:09
397
原创 数据结构与算法-算法-239. 滑动窗口最大值
【摘要】本文介绍了LeetCode 239题「滑动窗口最大值」的解法。该问题要求在一个整数数组中,找出所有长度为k的滑动窗口中的最大值。核心解法是使用双端队列维护一个单调递减的队列结构,队列头部始终存储当前窗口最大值的索引。通过两次循环处理:第一次移除超出窗口范围的索引,第二次移除小于当前元素的索引以保持队列单调性。当窗口首次完整时开始记录结果。该方法的时间复杂度为O(n),空间复杂度为O(k),能高效处理大规模数据。代码示例展示了具体的Java实现过程。
2025-08-28 12:40:40
879
原创 数据结构与算法-算法-42. 接雨水
文章摘要:本文介绍了力扣第42题"接雨水"的解法。该问题要求计算给定柱子高度数组中能接住的雨水量。通过使用单调栈的数据结构,可以在O(n)时间复杂度内解决。关键点在于处理栈内元素时正确计算雨水区域的宽度和高度,并注意边界条件。文章提供了Java实现代码,通过维护一个高度单调递减的栈,当遇到更高柱子时触发弹栈并计算可存储的雨水量。这种方法能高效处理各种复杂情况,如示例输入[0,1,0,2,1,0,1,3,2,1,2,1]输出6个单位雨水。
2025-08-28 11:02:31
1057
原创 java 并发编程八股-线程池篇
本文主要介绍了线程池的使用原理及设计要点。线程池通过池化技术复用线程,降低创建销毁开销,推荐使用ThreadPoolExecutor创建。其核心参数包括线程数、队列、拒绝策略等,执行流程遵循核心线程→最大线程→队列→拒绝策略的顺序。参数设计需结合具体任务和服务器性能,而非简单套用CPU/IO密集型理论。shutdown()和shutdownNow()关闭方式不同,后者无法立即终止所有任务。最后提到可通过Future对象控制提交任务的执行。文章强调在实际项目中需通过测试优化线程池配置,并设计合理的兜底方案处理
2025-08-26 16:16:13
268
原创 java 并发编程八股-并发安全篇
摘要 本文主要介绍了Java并发编程中的核心概念和工具。首先概述了JUC包下的常用组件,包括线程池(ThreadPoolExecutor)、并发集合(ConcurrentHashMap、CopyOnWriteArrayList)和同步工具类(CountDownLatch、CyclicBarrier、Semaphore)。其次详细解析了Java中的锁机制,重点比较了synchronized和ReentrantLock的特性及锁升级过程。文章还深入探讨了ThreadLocal的实现原理及其内存管理问题,分析了C
2025-08-26 15:45:21
1033
原创 java 并发编程八股-多线程篇
Java线程操作在虚拟线程出现前直接使用系统线程,存在性能问题;虚拟线程通过引入中间层优化了性能。多线程编程需关注原子性、可见性和有序性。创建线程可通过继承Thread类、实现Runnable接口或使用线程池,其中线程池能复用线程但需合理配置参数。线程停止方式包括优雅停止(通过标记中断)和暴力停止(已废弃)。线程生命周期包含初始、可运行、阻塞、等待和终止状态。sleep和wait的区别在于锁的释放,notify和notifyAll的区别在于唤醒线程数量。线程间通信可通过volatile、synchroniz
2025-08-25 21:16:00
663
原创 数据结构与算法-算法-三数之和
本文介绍了LeetCode第15题"三数之和"的解法。题目要求找出数组中所有不重复的三元组,使其和为0。核心解法是:先排序数组,然后固定一个数,将问题转化为两数之和,使用双指针法寻找解。代码示例展示了递归实现,通过dfs2函数处理三数之和,twoSum2函数处理两数之和。解题过程中需注意去重和边界条件。文章还提供了视频讲解链接,建议参考黑马程序员的详细讲解。该题比两数之和更为复杂,是需要重点掌握的中等难度算法题。
2025-08-23 10:14:13
831
原创 数据结构与算法-算法-盛最多水的容器
【摘要】B站视频《进阶数据结构和算法-334-盛水最多容器-Leetcode11》讲解了力扣第11题。该题要求找到两条垂线,使其与x轴构成的容器能盛最多水。解题关键是使用双指针法,从数组两端向中间移动,每次计算当前容器的水量(距离×较小高度),并移动较小高度的指针以寻找更大值。视频提供了Java代码示例,解释了为何要从两边开始而非单边,并通过实例[1,8,6,2,5,4,8,3,7]演示最大水量49的计算过程。这道题考察双指针技巧,是算法学习的重要内容。
2025-08-22 10:25:31
1021
原创 数据结构与算法-算法-283移动零
该题目要求原地将数组中的零移动到末尾,保持非零元素顺序。解题关键在于双指针技巧:指针i标记已处理非零元素边界,指针j遍历数组寻找非零元素。当nums[j]非零时,与nums[i]交换并使i前进。该方法仅需一次遍历(O(n)时间复杂度),无额外空间消耗(O(1)空间复杂度),高效实现零元素后移。示例代码展示了双指针交换的核心逻辑,通过逐步扩大非零区间完成排序。
2025-08-22 09:53:42
293
原创 深入浅出的 RocketMQ-面试题解析
摘要:本文讨论了RocketMQ中的几个关键问题:1)订阅关系一致性,强调消费者组内订阅内容需一致以避免消息丢失;2)Broker集群搭建方式,对比单主、多主、主从同步/异步及Dledger架构的优缺点;3)消息可靠性机制,包括生产者重试、Broker持久化和消费者确认;4)消息重复问题及业务ID幂等解决方案;5)消息堆积场景分析,提出环境区分处理和线程池拒绝策略等应对方案。最后以敏感信息审核为例说明实际业务中的异步编排应用。
2025-08-15 20:53:35
717
原创 深入浅出的 RocketMQ-顺序消费,消息过滤
顺序消费与消息过滤机制解析 顺序消费分为全局顺序和分区顺序两种实现方式,其中分区顺序通过消息ID取模确定队列,既保证顺序又兼顾性能。消费者端通过三把锁机制(分布式锁、synchronized锁、ReentrantLock锁)确保单线程消费并防止重平衡干扰。消息过滤主要在Broker端完成,分为tag和SQL两种方式:tag过滤通过hash快速比对但可能存在碰撞,需二次验证;SQL过滤精准但性能较差。实际应用中,tag过滤能满足大部分场景需求,在性能和准确性间取得较好平衡。
2025-08-13 10:38:27
631
原创 深入浅出的 RocketMQ-消息消费
消息消费主要有推送和拉取两种模式。推送模式实时性强但Broker压力大,需要维护消费者状态;拉取模式减轻Broker负担但存在消息延迟问题。RocketMQ采用拉取+长轮询的混合机制,既降低Broker负载又减少延迟。系统通过NameSrv管理Broker信息,消费者启动时先获取Topic对应的Broker地址。重平衡机制用于动态调整消费者负载,而NameSrv集群通过心跳检测Broker状态。这些设计在保证消息可靠传递的同时,兼顾了系统性能和实时性需求。
2025-08-12 10:17:34
313
原创 深入浅出的 RocketMQ-每天一点点
摘要:本文讨论了MQ系统中的两个核心问题:消息消费盲区和消息存储机制。针对消费盲区问题,指出关键在于协调分区与消费者数量关系,避免消费者数量超过分区导致盲区。在存储方面,分析了采用文件存储(日志)方案的优势,包括可靠性、顺序写入优化,以及通过索引文件和偏移量管理实现高效查询。同时探讨了存储优化策略,如在messageQueue中保存消息长度以避免随机IO。这两个问题的解决方案共同构成了MQ系统高并发处理能力和数据可靠性的基础。
2025-08-10 15:57:03
325
原创 数据结构与算法-算法-最常见的单词
题目要求找出字符串段落中出现频率最高的非禁用词。解决思路是:1)将段落转为小写并拆分成单词数组;2)使用哈希集合存储禁用词;3)遍历单词数组,统计非禁用词频率到哈希表;4)找出频率最高的单词。关键在于处理大小写不敏感、忽略标点和过滤禁用词。Java实现时需注意使用toLowerCase()统一大小写,正则表达式"[^a-z]+"分割单词,以及利用stream的max()方法查找最高频词。代码示例展示了如何通过Set.of()、HashMap和Stream API高效解决问题。
2025-06-26 09:45:20
1465
原创 数据结构与算法-算法-字符串中的第一个唯一字符
《字符串中的第一个唯一字符问题解析》 摘要: 该问题要求找出字符串中第一个不重复的字符并返回其索引。解决方法采用计数排序思想:1)使用长度为26的数组统计每个小写字母出现频率;2)再次遍历字符串,找到第一个频率为1的字符。算法时间复杂度为O(n),空间复杂度O(1)。示例代码通过两次遍历实现,第一次统计频率,第二次查找首个唯一字符。该解法适用于包含小写字母的字符串,是哈希表思想的简化应用。
2025-06-26 09:17:57
408
原创 SpringAI+RAG 上手教程
在 springAI 中要使用 RAG 我们要先准备一些文档,当然文档的要求是具有“很高的结构化”,意思就是像 ai 一点就可以。在这里咱们使用 markdowm 格式的文件(当然我用的是鱼皮的文档,大家可以自己让ai 写一个)
2025-06-26 08:30:15
582
原创 springAI :ai-agent的学习日记:RAG 基础知识
所谓了 RAG(检索增强生成) 就是将我们的知识库,提前向量化,存储到向量数据库中,在我们用户进行提问的时候,可以通过用户的提示词进行数据检索,相关检索。让后将搜索到的相关知识,封装成“提示词”。对的就是提示词,然后一起发送给 ai 让 ai 进行相关性回答,来实现额外知识的能力。
2025-06-23 21:16:05
326
原创 springAI :ai-agent的学习日记:自定义 advisor
*** 自定义日志 Advisor* 打印 info 级别日志、只输出单次用户提示词和 AI 回复的文本*/@Slf4j//你的内容其实就是在初始化客户端的时候加进去就行。// 自定义日志 Advisor,可按需开启.build();
2025-06-22 14:52:41
352
原创 springAI :ai-agent的学习日记:springAI 初体验
测试是针对 springAI-alibaba名词解释:chatClient:就类似于我们使用的高效自定义的 ai 客户端,可以配合 advisors(顾问)实现上下文存储方式。同时得益于高效的自定义能力,我们也能内嵌自己的系统提示词等。advisors:是一个常用的ai 访问顾问。当然通俗了来说就是一个拦截器,实现了循环增强的能力。不仅能“前置”去检测提示词的合规性,也能“后置”去记录一个信息,比如,token 的使用量等等。
2025-06-22 13:50:38
245
原创 数据结构与算法-算法-存在重复元素
这个题总体不难,关键点就是要知道,set 的去重特性,同时如果插入不进去,他会返回一个布尔值。当然,暴利循环也可以
2025-06-21 16:03:57
331
原创 数据结构与算法-算法-字母异位词分组
这个题目的突破点就是,异位词(String)转为 char 数组之后被 sort 排序的结果相同,将相同的结构当做 key,不同的样本当做 value,遇到排序后 map中存在,就是有相同样本,直接插入 list 集合即可。
2025-06-21 15:54:49
1365
原创 数据结构与算法-算法-无重复最长子串
这个题还是很经典的,不管是力扣还是codetop,都是很火,考的频率很多的一个题。首先,这给题利用了一个简单的滑动窗口思想,【begin,end)(因为 end 从 0 开始,所以+1 就能包围)在 map 中存储的 key就是字符,value 就是字符对应的位置下标,滑动窗口遇到新的就会更新 value。
2025-06-16 10:59:59
424
原创 数据结构与算法-算法-罗马数字转换整数
这道题呢最初的想法是利用 map只存储简单的内容,但是涉及一些复杂的计算,反而不好操作。然后去匹配两个字符,或者一个字符。所以,索性将能提前定好的都定好。13. 罗马数字转整数。
2025-06-15 15:04:02
353
原创 数据结构与算法-数据结构-堆
堆是一种完全二叉树堆序性:每个节点的值必须满足与子节点的大小关系。大顶堆:父节点 ≥ 子节点(堆顶最大)小顶堆:父节点 ≤ 子节点(堆顶最小)完全性:除最后一层外,其他层必须填满,且最后一层节点靠左排列。。
2025-06-15 14:15:48
435
原创 数据结构与算法-算法-合并多个有序链表
针对关键的合并核心来说,和上一节的(合并两个有序链表)是一样的。这个题就是上一个的扩展,核心思想就是利用一种的思路。
2025-06-14 21:09:02
168
原创 数据结构与算法-算法-合并两个有序链表
简单的思路就是利用双指针(类似思想)、一个容器链表。每次循环都检测两个指针的大小,小的那个指针将数据放到容器中,链表后移。边界情况:在边界情况下,会出现连个数组长度不统一,所以循环的结束条件就是双指针有一个为空。然后将没有为空的数组剩下的样本数据,排序直接放入容器链表。
2025-06-14 20:50:53
169
原创 数据结构与算法-排序-计数排序
所谓的计数排序,就是利用一个频率数组,存储样本数据中,对应数据出现的频率,然后将频率,按照(频率数组)的下标存储。这样我们只要顺序读取频率数组,输出频率对应的下标就可以。(样本中的数据,就是频率数组中的下标。频率数组中的值就是样本数据出现的频率。1.每个非零的频率输出一次,我们就能实现原始样本的去从。2.每个非零的频率多次输出,就能实现不去重排序。
2025-06-14 13:43:09
238
1
原创 数据结构与算法-排序-快速排序
快速排序是一种高效的比较排序算法,通过分区递归实现排序。文中介绍了两种分区方法:单边循环(Lomuto分区)选择最右侧为基准点,i和j从左向右遍历交换;双边循环(Hoare分区)选择最左侧为基准点,i从左、j从右双向遍历交换。两种方法最终都将基准点置于正确位置并返回其索引。为优化性能,建议随机选择基准点以避免最坏情况。文章还提供了两种分区的Java代码实现示例。
2025-06-14 11:17:49
159
原创 数据结构与算法-排序-归并排序
摘要:归并排序采用分治思想,将数组递归拆分为最小单元后合并。核心步骤包括:1)分-从中间切分数组;2)治-处理单个元素为有序;3)合-合并两个有序数组。代码实现中,merge方法处理有序数组合并,split方法进行递归拆分,最终通过System.arraycopy完成数据复制。该算法时间复杂度为O(nlogn),是稳定的排序方法。示例演示了对数组[9,3,7,2,8,5,1,4]的排序过程。
2025-06-10 15:27:22
151
原创 数据结构与算法-排序-希尔排序
摘要:Shell排序通过逐渐缩小的间隔(gap)对数组进行分组插入排序。代码实现中,初始gap设为数组长度的一半,每次循环gap减半,直至为1。在每个gap值下,从gap位置开始遍历数组,将当前元素与同组前驱元素比较并插入正确位置。该方法通过粗到细的排序策略提升效率,最终完成整个数组的排序。示例展示了如何使用该算法对数组{9,3,7,2,5,8,1,4}进行排序。
2025-06-10 15:22:25
186
原创 数据结构与算法 -排序-冒泡算法
摘要:冒泡排序通过双层循环两两比较相邻元素,将最大值逐步交换到数组末尾。本代码实现优化版冒泡排序,改进点包括:1)使用变量x记录每轮最后交换位置,动态调整下一轮比较边界;2)当x为0时提前终止循环。该方法减少了不必要的比较次数,时间复杂度最坏O(n²),最好O(n)。示例演示了对数组[6,5,4,3,2,1]的排序过程,注释说明算法核心是逆序交换与边界优化。
2025-06-10 11:07:24
257
原创 数据结构与算法-排序
Java排序算法选择需根据数据特征动态调整,没有绝对最优解。Arrays.sort实现考虑了多种排序算法的优势:冒泡、选择排序适合小数据量;插入排序对近乎有序数据高效;希尔排序通过gap序列优化;归并排序稳定但需额外空间;快速排序平均性能好但需注意枢轴选择。堆排序需先理解堆结构。不同算法在时间复杂度、空间复杂度、稳定性上各有特点,需结合数据分布和规模选择。实际应用中常采用混合策略,如快速排序与插入排序结合,以平衡各种场景下的性能表现。
2025-06-10 10:52:50
288
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅