- 博客(58)
- 收藏
- 关注
原创 Spring Bean 扫描及注册逻辑
最近需要做关于Mcp工具的依赖,需要关系到工具扫描,这个逻辑高度类似于Mapper之于Mybatis,Controller之于SpringMvc,Bean之于Spring,如下图所示:还记得初中第一堂课学的就是,人与动物的核心区别就是是否会使用工具,既然有了现成的对应最佳实践源码,那就直接拿来。
2025-04-05 01:46:26
153
原创 powerjob的部署及demo教程(比官网更官网)
首先先需要认识一下powerjob这个理念上较为突破的分布式任务调度框架,下面是截自官网的一些简介:PowerJob 的设计目标为企业级的分布式任务调度平台,即成为公司内部的任务调度中间件。整个公司统一部署调度中心 powerjob-server,旗下所有业务线应用只需要依赖 powerjob-worker 即可接入调度中心获取任务调度与分布式计算能力。QuartZxxl-jobSchedulerX 2.0PowerJob定时类型CRONCRONCRON、固定频率、固定延迟、OpenAPICRON、固定频率
2025-03-06 15:17:02
682
原创 经典内存泄漏问题
这个背景也是蛮离谱,由于客户的内网策略导致无法访问目标外网的任何资源,由于服务器资源也难以申请,也不能使用数据库等任何第三方,而且这是一个长连接(响应时间长会导致生产环境下触发超时策略)。那么我就只能这样设计,前端调后端接口带一个UUID,后端请求第三方api,把得到的数据及 UUID 作为 Key 存到内存里,然后前端拿着这个 uuid 去轮询,这样好像就万事大吉了。经理给我构思的也是这样,但是很明显这让我想到了,"内存泄漏",以前总是很难理解,只是记住定义:内存无法释放的情况是内存泄漏。
2025-03-03 21:44:02
895
原创 管理系统中经典审核功能实现
先简单交代和阐述一下业务背景和逻辑,该系统是一个综合类的音乐系统,上传音乐时,逻辑和qq音乐一样,前端页面就能体现出大概逻辑,如下图所示: 专辑和歌曲是密不可分的,而且歌曲的封面就是对应专辑的封面,提交审核的时候,也是同理,是一起打包提交的,sql层如下图所示: 由于后台管理系统,qq音乐的后台不予开放,那就自己设计一下,初步设想是这样:后端的话,逻辑大致如上。先建两个log表 由于业务逻辑是一次提交处理,本质上专辑的审核和歌曲的审核是父与子的关系,所以直接绑定一个专辑处理的id即可,音乐信息肯定不能去正式
2024-12-31 17:14:49
702
原创 经典系统重塑(sql层)
总体来说,这次改造可以使系统结构更加清晰,可扩展性,抗压性,稳定性,合理性都有了质的突破,因为如果不进行重塑,该系统下的其他功能将会很乱,变成屎山。比如musician_name和musician_id同时存在,就只单单查询这一条sql业务简单了一点点,可能速度快了一点点点,但是面对音乐人注销,音乐人改名,这个业务就会变得及其复杂,难以维护。
2024-12-17 19:22:44
520
原创 匿名发帖/匿名论坛功能设计与实现(编辑发帖部分)
还是之前的音乐系统,首页一直是没想好写些什么,想写一个基于数据分析筛选的歌曲推荐功能,但是目前技术选型没太有考究等以后再实现吧,昨天突然想到可以把首页设计成前40%页面是歌曲推荐后面接下来就是一段匿名论坛功能,说干就干,直接构思,设计,实现。
2024-12-01 20:34:31
715
原创 volatile关键字和内存/读写屏障的深入理解
简单来说,cpu内缓存和内存的关系就类似于应用层里的redis和DB的关系,在多线程情况下,默认取数据的时候都是从redis(缓存)里取,只有线程结束时才会写回DB(内存),这时,当A线程进行了修改一个变量但线程未结束,B线程如果不停需要根据这个变量计算结果,这是就会出现常见的问题,原理也就是这个:缓存还未写回内存。杂谈:这种设计对吗,当然是对的,但是就一定好吗,我感觉对于开发来说也许有失偏颇,不仅让代码变得复杂而且两种无论是相同的特性即使是毫无相关,分开也远比合在一起好得多,有一种偏锋的感觉。
2024-11-25 18:33:19
395
原创 经典业务场景仿淘宝客户对话功能
技术选型还是spring的websocket,比netty更加专一性;websocket实际上只能提供消息传输功能,根据业务逻辑对其进行中间件的选择增强,点开淘宝的客服页,进行前端解析。当从左侧选择商家时,每一次选择他都会有一个刷新的动作,但并没有请求接口,说明他并没有把聊天记录放到客户端(本地),而是每次的数据都是从服务器请求的,既然没有接口请求,那么就是通过websocket了,这三个ws请求中,有两个一样的ws请求,这个我不太理解是什么意思,知道的可以在评论区讲一下。
2024-11-23 20:50:46
503
原创 常见音乐的一起听功能设计与实现2
当发生接收邀请操作的时候,就会去检查过期时间,检查status等等,然后设置status;房间没有对其进行mysql的持久化,因为房间其属性,较为临时,而且重要性也不是很强,最坏情况,redis进行宕机,数据丢失,直接重新创建一个房间即可,房间只相当于一个容器,不存储什么重要信息。但其实这个系统并不完善,存在着诸多问题,比如房间问题,举例,当我创建一个A房间时并复制了A房间的链接,有人邀请我进入B房间,前端的房间变量变成B,但是A房间并未消失,允许别人进入,要做的就是在invite逻辑中删除该房间。
2024-10-20 17:14:30
529
原创 常见音乐软件的一起听功能设计与实现1
前端使用全局变量来控制播放的音乐,无论是前后切换歌曲还是点播,都只是传递的内个全局音乐id而不是操作本身,调用方只需要去修改,当id变化,将触发websocket的同步逻辑,这应当使用监听实现。
2024-10-15 17:10:52
1140
原创 消息通知系统的介入
然后发送消息,这个消息定义为一个Bo,这里需要注意一些东西,这个定义比较重要,功能的实现总是会很简单,但是同样一个功能好的公司总会很贴合用户体验,用户体验的好坏,也是业务设计的好坏,这里参考QQ音乐。目前大致考虑到两种情况,一种是。然后当无法查询到账号id时,就显示该用户已注销,查不到评论分两种,自己的评论删除了,和评论你的评论删除了,如下两图所示。分析图二,明明是4条评论怎么显示9条呢,是不是缓存问题,其实并不是,这是因为一个不太必要的bug,这是多级评论,一首音乐计算的时候QQ音乐把。
2024-10-01 15:19:38
455
原创 Leetcode 162.寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。你可以假设。你必须实现时间复杂度为O(log n)的算法来解决此问题。示例 1:输入:nums =[1,2,3,1]输出:2解释:3 是峰值元素,你的函数应该返回其索引 2。示例 2:输入:nums =输出:1 或 5解释:你的函数可以返回索引 1,其峰值元素为 2;或者返回索引 5, 其峰值元素为 6。i。
2024-09-26 09:25:49
321
原创 Leetcode 106. 从中序与后序遍历序列构造二叉树
}* }*/// 中序遍历是左中右,后序遍历是左右中,使用递归,用左右坐标来分割两个数组,每个小数组都是一个小树// 左右中,这是后序树的数组,那么这个子数组的最后一个元素一定是这个子树的根节点,然后中序序列里找// 左中右,找到中,就可以分割开左右子树,迭代分割,直到最小子树,无法分割// 最后一个必是根节点// 得到根节点坐标break;// 只有中序遍历知道左右子树的信息是不够的,还需要让后续遍历知道。
2024-09-24 12:19:34
356
原创 Leetcode 416. 分割等和子集(Medium)
给你一个的数组nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。true数组可以分割成 [1, 5, 5] 和 [11]。false数组不能分割成两个元素和相等的子集。
2024-09-20 14:38:18
333
原创 Leetcode 118.杨辉三角
给定一个非负整数 numRows生成「杨辉三角」的前 numRows行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。示例 1:输入: numRows = 5输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2:输入: numRows = 1输出: [[1]]
2024-09-18 11:23:33
319
原创 Leetcode 128.最长连续序列(Medium)
解释:最长数字连续序列是 [1, 2, 3, 4]。,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。输入:nums = [0,3,7,2,5,8,4,6,0,1]输入:nums = [100,4,200,1,3,2]请你设计并实现时间复杂度为。给定一个未排序的整数数组。
2024-09-18 09:27:57
196
原创 Leetcode 133. 克隆图(Medium)
给你无向图中一个节点的引用,请你返回该图的(克隆)。图中的每个节点都包含它的值valint) 和其邻居的列表(list[Node]简单起见,每个节点的值都和它的索引相同。例如,第一个节点值为 1(val = 1),第二个节点值为 2(val = 2),以此类推。该图在测试用例中使用邻接列表表示。是用于表示有限图的无序列表的集合。每个列表都描述了图中节点的邻居集。给定节点将始终是图中的第一个节点(值为 1)。你必须将作为对克隆图的引用返回。图中有 4 个节点。
2024-09-16 14:57:04
559
原创 完整版订单超时自动取消功能
前几天对实习还是继续学习技术产生了抉择,问了一个前辈,他抛给我一个问题,怎么做15分钟订单自动取消,我说然后到时间之后,自动执行这个订单关闭业务,比如把锁了的库存给解开等等操作,然后在数据库里肯定要有体现,比如抖音,查我的订单内一块,在前段应该显示已过期,把支付的按钮变灰或者取消,支付的时候不能直接对库存进行操作,应该是支付模块调用订单模块调用库存模块。然后把理论予以实现,发现需要考虑的点还是有一些的。
2024-09-15 19:32:11
1937
原创 Leetcode 160. 相交链表(Easy)
思路:相交的话,100%最后一个节点一定是相交的,所以他们最大开始相交的位置也就是lengthA-lengthB的绝对值,那么就直接让较长的那一个链表前进(lengthA-lengthB的绝对值)步,然后两个节点还是一起遍历,判断结点是否相同,相同就return节点,如果没有相同的最后就会返回null。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。在 B 中,相交节点前有 1 个节点。
2024-09-15 14:42:24
963
原创 Leetcode 165. 比较版本号(Medium)
给你两个version1和version2,请你比较它们。版本号由被点'.'分开的修订号组成。是它并忽略前导零。比较版本号时,请按依次比较它们的修订号。如果其中一个版本字符串的修订号较少,则将缺失的修订号视为0。-110-1version1 的第二个修订号为 "2",version2 的第二个修订号为 "10":2 < 10,所以 version1 < version2。0忽略前导零,"01" 和 "001" 都代表相同的整数 "1"。0。
2024-09-15 14:35:33
450
原创 Leetcode 116.填充每个节点的下一个右侧节点指针(Medium)
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:int val;Node *left;Node *next;填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为NULL。初始状态下,所有 next 指针都被设置为NULL。示例 1:输入:root = [1,2,3,4,5,6,7]输出:[1,#,2,3,#,4,5,6,7,#]
2024-09-12 09:06:26
500
原创 Leetcode 109.有序链表转换二叉搜索树(Medium)
给定一个单链表的头节点head,其中的元素 按升序排序 ,将其转换为 平衡 二叉搜索树。示例 1:输入: head = [-10,-3,0,5,9]输出: [0,-3,9,-10,null,5]解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。示例 2:输入: head = []输出: []head。
2024-09-11 09:36:34
490
原创 Leetcode 141.环形链表(Easy)
给你一个链表的头节点head,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从 0 开始)。pos。仅仅是为了标识链表的实际情况。如果链表中存在环,则返回true。否则,返回false。true链表中有一个环,其尾部连接到第二个节点。true链表中有一个环,其尾部连接到第一个节点。false链表中没有环。-1。
2024-09-11 00:21:16
317
原创 Leetcode 153. 寻找旋转排序数组中的最小值(Medium)
已知一个长度为n的数组,预先按照升序排列,经由1到n次后,得到输入数组。例如,原数组47注意,数组的结果为数组。给你一个元素值的数组nums,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的。你必须设计一个时间复杂度为O(log n)的算法解决此问题。1原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。0原数组为 [0,1,2,4,5,6,7] ,旋转 3 次得到输入数组。11原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
2024-09-08 14:13:24
480
原创 Leetcode 155. 最小栈(Medium)
设计一个支持pushpoptop操作,并能在常数时间内检索到最小元素的栈。实现MinStackMinStack()void pop()int top()--> 返回 -3.--> 返回 0.--> 返回 -2.topgetMinpushpoptopgetMin3 * 104。
2024-09-08 01:21:33
523
原创 Leetcode 152. 乘积最大子数组(Medium)
/ 当前数值// 最大值// 回退坐标值i++) {// 说明是负数或0,就记录一下while(!return max;
2024-09-07 11:15:13
289
原创 设计模式 第一次复学
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定他们的具体类。抽象工厂是工厂的升级版,工厂只能只能生产一种等级的产品,而抽象工厂可以生产多个等级的产品。它由四部分构成抽象工厂:提供不同的工厂方法。具体工厂:对抽象的工厂方法予以实现。抽象产品:定义了不同种产品的属性等,该模式有多种抽象产品。具体产品:主要是对相应的抽象产品予以实现。// 抽象产品类(接口)// 具体产品类// Windows 平台的按钮@Override// Windows 平台的文本框。
2024-09-07 07:02:11
1472
原创 设计原则 第一次复学
可见性主要分为三种:+:表示public-: 表示private#:表示protected属性的完整表示方式是: **可见性 名称 :类型 [ = 默认值]**方法的完整表示方式是: **可见性 名称(参数列表) [ : 返回类型]
2024-09-02 23:16:19
929
原创 Leetcode 146. LRU 缓存(Medium)
/ 题目中需要创建一个HashMap来存储参数,因为题目要求复杂度为O(1),顺序就需要通过双向链表的节点实现// 构造双向链表节点int key;int value;Node prev;Node next;// 由于LRU,是最近使用,所以为了将使用后的节点放到最前面,还需要一个头尾节点。// 容量大小// 现在的大小// get算使用,头插入// 查不到就实现节点的删除,然后头插入// 再头部插入。
2024-09-02 09:23:49
1013
原创 SpringMVC 第一次复学笔记
服务器启动时,创建spring容器;dispatcherServlet启动时,直接创建springmvc容器初始化一次,实现了springmvc和spring的整合。
2024-09-02 09:06:29
1306
原创 Spring第一次复学日记
Bean创建的生命周期Bean开始创建前叫做实例化阶段,Spring会根据BeanDefinition的信息来创建Bean,比如是否立即创建根据延迟加载属性。需要注入的信息通过BeanDefinition的属性properyValues进行存储。然后Bean开始进行初始化,此时的Bean,也就只分配了内存(外壳),还并没有进行属性填充,执行一系列Spring定义的接口方法比如。
2024-08-30 20:18:51
784
1
原创 Leetcode 130. 被围绕的区域 (Medium)
给你一个m x n的矩阵board,由若干字符'X'和'O'组成,所有'O''X'board'X'通过将输入矩阵board中的所有'O'替换为'X'来。在上图中,底部的区域没有被捕获,因为它在 board 的边缘并且不能被围绕。
2024-08-25 13:32:47
447
原创 Leetcode 129. 求根节点到叶节点数字之和 (Medium)
因此,数字总和 = 495 + 491 + 40 =因此,数字总和 = 12 + 13 =,树中每个节点都存放有一个。计算从根节点到叶节点生成的。给你一个二叉树的根节点。是指没有子节点的节点。
2024-08-23 16:48:50
335
原创 Leetcode 134. 加油站 (Medium)
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油。开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油。开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油。开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油。开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油。
2024-08-22 17:44:24
322
原创 Leetcode 131. 分割回文串 (Medium)
/ 本题100%是需要遍历的,双指针,当尾指针遍历到不属于回文串时,也应该继续遍历,直到到字符串的末尾比如aab不属于字符串但后面可能是aabbaa// 面对不同分支则使用递归+回溯+深拷贝解决return;i++) {// 回溯操作 分支操作// 如果左右字符不相等,则不是回文// 移动指针left++;right--;// 如果循环结束都没有返回false,则是回文。
2024-08-21 13:50:15
150
原创 Leetcode 105. 从前序与中序遍历序列构造二叉树 (Medium)
}* }*/// 思路就是前序遍历是先遍历根节点再遍历左右子树 而中序是左根右的顺序// preorder = [3,9,20,15,7], inorder = [9,3,15,20,7],拿这个举例子,先看前序3是根节点然后去中序里找3,// 然后3以前全是左子树 递归或循环解题 (一切只当不重复时才成立 恰好题中已给信息)// 前序遍历的第一个节点是根节点// 在中序遍历中找到根节点的位置break;
2024-08-20 23:55:24
251
原创 Leetcode 113. 路径总和 II(Medium)
思路: 就是一道典型的深度优先遍历,基本模型就是递归调用左右子树,这道题只需要多考虑一个问题,传递的队列存储问题,因为队列是引用的,就需要进行深拷贝在进行存储,拿示例一举例,当当前节点是11的时候,再向右子树走,满足题目条件(为叶子节点且满足target值),成功后进行add,但是该传递队列是引用的,为了避免后续修改对已经成功的影响,就进行拷贝后存储,然后每次遍历节点结束后,都应该把该节点也就是最后一个节点拿出去,保证顺序。路径总和等于给定目标和的路径。是指没有子节点的节点。
2024-08-14 15:56:32
353
原创 Leetcode 99. 恢复二叉搜索树(Medium)
就是找到两个要交换的节点 进行交换,交换的节点在他的上下文中必然是错误的,什么意思呢,就是破坏了二叉搜索树的性质,左小,右大。把这个二叉树用中序遍历抽象成链表,应该是从小到大递增的,找出两个故障的节点,然后进行交换。怎么找出来呢,就和链表一样,使用连续的前后两个节点,正常情况是前后,可以进行交换,然后一直交换到最后结束。或者也可以给他标识起来,前节点总是固定的,和冒泡排序类似,后节点就一直变,等最后进行一次交换就OK了。给你二叉搜索树的根节点root,该树中的两个节点的值被错误地交换。
2024-08-13 22:33:09
200
网页版微信,集成redis,mysql,knife4j,websocket等技术
2024-04-07
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人