- 博客(28)
- 收藏
- 关注
原创 从一次关注到最终一致:Canal、Outbox 与 Kafka 如何解决关系链双写问题
内容是关于解决关系链双写问题,涉及Canal、Outbox和Kafka。摘要应简洁概括核心问题、技术方案和解决思路。 我们从文章中提取关键点:问题:一次关注需要更新多个数据(following、follower、缓存、计数),同步双写导致事务一致性和扩展性问题。方案:请求只写following并记录Outbox事件,通过Canal或Outbox将事件异步发布到Kafka,由事件处理器生成follower、更新缓存和计数。好处:核心事
2026-09-06 18:37:57
223
原创 知识社区的一次点赞如何经过 Redis 位图、Kafka 聚合桶和 SDS
<think>好的,用户要求基于一篇关于知识社区点赞系统的技术文章生成一个不超过150字的摘要。文章内容相当具体,描述了点赞操作如何通过Redis位图、Kafka聚合和SDS(简单动态字符串)等组件实现的完整流程。 需要提取核心信息:点赞动作拆分为同步事实写入和异步汇总写入。具体路径是:Redis位图保存用户状态,Lua脚本保证幂等;状态变化后发送Kafka消息,消费者累加增量到Redis Hash;定时任务将净增量写入固定长度的Redis String作为计数快照。关键设计要点是分片位图和Lua原子操作,
2026-09-04 16:39:12
187
原创 短信任务写入成功后 Kafka 消息没发出去,Outbox 是否值得引入
<think>我们根据用户请求,需要生成≤150字的文章摘要。用户提供了一篇长文,讨论短信任务写入成功后Kafka消息没发出去,是否引入Outbox。摘要需要概括核心观点。需要简洁。</think>短信任务写入MySQL后,Kafka可能发送失败。项目因任务表本身可作为待发布清单,删除Outbox,直接扫描任务表发送消息,并用消费端幂等、手动提交等补偿。该方案仅适合单任务ID触发、无复杂事件的场景;若需可靠发布状态、审计或一对多事件,Outbox仍是更好的选择。
2026-09-02 18:59:50
217
原创 AI- meeting项目:一次答题请求的完整旅程:三层锁与一条心跳线程
摘要 本文剖析了一个面试系统后端处理答题请求的三层防护机制。第一层基于请求ID防重放,第二层按题号防并发,第三层通过答案指纹防重复计算。核心创新在于心跳线程与业务线程的分离设计:心跳线程独立运行,仅验证进程存活,不影响业务线程执行;而业务线程卡顿时,依赖预设超时而非心跳检测来触发故障转移。系统采用分段式键名设计(请求ID+所有者令牌)避免心跳线程误操作,并通过状态与结果分离存储确保数据一致性。该架构有效解决了重复提交、并发冲突和节点故障三大问题,但存在对业务线程卡死检测不足的边界,未来需结合流式调用或进度点
2026-08-19 20:48:48
209
原创 一次 Redis SETNX 的小插曲,我重新理解了原子性
本文通过 Redis 的 SETNX 命令探讨了原子操作的真正含义。作者发现虽然 EXISTS 和 SET 都是原子操作,但组合使用时仍会产生并发问题,因为两个操作之间存在执行间隙。这种"检查-执行"模式(Check-Then-Act)在多线程环境下容易产生竞态条件。SETNX 通过将检查存在性和条件写入合并为一个原子操作解决了这个问题。文章还延伸到分布式锁场景,解释了为什么推荐使用 SET NX EX 命令来同时设置锁和过期时间。最后总结了原子性、原子边界和竞态条件等关键概念,强调在并发编程中需要关注多个
2026-08-18 22:07:44
160
原创 Redis 与 Single-flight 的分工与协作
Redis与Single-flight的分工协作机制 本文探讨了在AI问答、报告生成等耗时业务场景中,如何利用Single-flight和Redis协作解决重复请求问题。 核心要点: 问题背景:用户重试、前端超时、负载均衡等会导致相同请求被多次执行,造成资源浪费和业务异常。 解决方案架构: Single-flight负责请求合并规则:识别相同请求(requestKey)、确定执行者/等待者、结果共享机制 Redis提供分布式协调功能:状态存储、所有权仲裁、心跳维护、结果缓存和事件通知 关键技术点: 使用Lu
2026-08-15 23:33:47
245
原创 大模型专业术语详解
本文通俗解释了AI领域的多个核心概念及其相互关系。首先通过类比人的工作方式,将LLM比作大脑,Prompt比作任务说明,Agent比作执行者等。随后分类介绍了AI基础概念(AI、机器学习、深度学习、生成式AI)、LLM的本质与局限(不等于数据库、搜索引擎或Agent)、技术术语(Token、Transformer、推理等)、Prompt设计方法(模板、示例技巧)以及上下文管理(Context Window与Memory的区别)。最后提及结构化输出等高级功能。全文旨在帮助读者建立对这些术语的直观理解,明确区分
2026-08-14 23:42:14
171
原创 AI 面试相同请求为什么会重复调用,如何解决
AI 面试中的并发控制:Single-flight 模式实现 摘要:在 AI 面试系统中,当多个请求同时提交相同答案时,会导致重复调用 AI 评分接口,浪费资源且结果不一致。本文介绍使用 Single-flight 模式解决这一问题,通过 ConcurrentHashMap 和 CompletableFuture 的组合实现并发控制:相同请求只执行一次计算,其他请求共享结果。相比 Redis 缓存解决历史结果复用问题,Single-flight 专注于处理"正在计算中"的场景。实现核心包括:1) 使用 Co
2026-08-05 12:40:43
202
原创 给大家讲解并且推荐一个新的架构模式
文章摘要 本文介绍了一个AI面试项目的分层架构设计,重点阐述了各层的职责划分: Controller层:负责HTTP请求的接收与响应,进行基础参数校验 Facade层:组织完整的用户操作流程,协调前置/后置处理 Workflow层:定义业务流程能力并分派任务到正确路线 Pipeline层:管理复杂流程的固定执行步骤(如答题流程包含15个有序步骤) Service层:实现具体业务能力 架构采用横向业务模块+纵向技术职责的双重拆分方式,各层职责明确:Controller管接口边界,Facade管用例完整性,Wo
2026-08-04 16:52:26
151
原创 后端事务(结合项目讲解)
本文深入解析了Spring事务的核心机制与常见问题。Spring事务本质是通过AOP代理控制数据库事务(开始/提交/回滚),底层仍依赖JDBC。关键点包括:1)@Transactional应作用于Service层以包裹完整业务逻辑;2)异常必须抛出才能触发回滚;3)同类内部调用会导致事务失效,需通过代理对象调用;4)方法必须是public的。文章还阐述了AOP原理,说明其通过动态代理在不修改源码的情况下插入事务管理等横切逻辑,并强调事务范围由最外层@Transactional方法界定。典型错误案例展示了异常
2026-06-02 20:43:18
163
原创 用户登录模块,解析cookie,session,jwt的关系与应用
本文介绍了用户登录模块中Cookie、Session和JWT的关系与应用。Cookie是浏览器本地保存并自动携带的数据机制;Session是服务器保存的用户会话数据,属于有状态认证;JWT则是自带用户信息的无状态令牌。文章还详细解析了app端登录实现:注册时使用加盐MD5存储密码,登录时通过比对加盐摘要验证,并采用JWT Token方式,将签名保存在localStorage中,每次请求主动携带。这种设计避免了传统Cookie+Session的依赖,实现了更灵活的认证机制。
2026-05-18 20:15:25
356
原创 SpringMVC 三级缓存详解
级别名称说明一级HandlerMapping 缓存缓存 URL 到处理器的映射二级ViewResolver 缓存缓存视图解析器三级View 缓存缓存视图对象HandlerMapping 缓存- URL 到 Handler 的映射ViewResolver 缓存- 逻辑视图到物理视图的解析View 缓存- 视图对象的复用三级缓存协同工作,有效减少了路由匹配和视图解析的开销,是 SpringMVC 高性能的重要保障。写作时间:2026/04/27。
2026-05-03 23:55:37
238
原创 乐观锁和悲观锁
摘要:乐观锁与悲观锁是两种并发控制机制。悲观锁假设数据会被修改,获取锁时直接锁定数据,实现简单但效率低;乐观锁假设数据不会被修改,通过版本控制实现,效率高但需自行处理冲突。黑马点评案例展示了两种实现:悲观锁使用synchronized锁定代码块,乐观锁通过SQL条件(如stock>0)实现CAS机制。乐观锁的核心原理是比较预期值与当前值是否相同,相同则更新,不同则失败,避免了显式锁定的开销。悲观锁适合写多读少场景,乐观锁适合读多写少场景。
2026-04-28 19:56:54
181
原创 后端项目的分页计算问题
本文介绍了后端项目中实现分页查询的计算方法。通过Controller层接收页码参数,Service层计算偏移量offset=(page-1)*pageSize,确保安全处理异常页码。Mapper层使用LIMIT offset,pageSize语法执行SQL查询。整个流程展示了从接收参数到数据库查询的分页实现细节,重点解释了offset计算公式和页码安全处理机制。
2026-04-16 20:49:55
165
原创 苍穹外卖day10(黑马程序员)
WebSocket是一种全双工网络通信协议,相比HTTP的请求-响应模式,它允许客户端和服务器建立持久连接后双向实时通信。本文介绍了WebSocket的核心特点:通过HTTP升级握手建立长连接,以帧为单位传输数据,适合高频实时场景。通过对比表格清晰展示了WebSocket与HTTP在通信模型、连接方式、实时性等方面的差异。文中还包含一个完整的Java WebSocket服务端实现代码,使用@ServerEndpoint注解定义端点,通过Session管理客户端连接,支持消息接收和群发功能。代码逐行解析了关键
2026-04-02 17:05:21
349
原创 苍穹外卖day07(黑马程序员)
文章摘要 本文分析了外卖系统缓存优化方案和购物车功能实现。在菜品查询优化部分,针对高频读场景提出引入Redis缓存,通过先查缓存再查数据库的策略降低MySQL压力,提高响应速度。关键点包括缓存key设计(dish_分类id)、缓存命中逻辑及数据一致性处理。购物车功能则通过ThreadLocal获取用户ID,构建查询条件后从数据库获取购物车列表,实现分层架构(Controller-Service-Mapper)。整体方案兼顾性能优化与功能实现,通过缓存和分层设计提升系统响应能力。
2026-03-30 09:09:32
378
原创 苍穹外卖day06
本文介绍了使用HttpClient进行HTTP请求测试的方法。主要内容包括:1) 测试GET请求,通过HttpGet对象请求后端接口并解析响应状态码和响应体;2) 测试POST请求,使用JSONObject构建请求体并发送登录请求,演示了如何将JSON数据封装到HTTP请求体中。文章通过实际代码示例展示了HttpClient模拟前端请求的过程,包括请求发送、响应接收和资源释放等关键步骤,适用于测试后端API接口的功能和正确性。
2026-03-28 23:01:24
348
原创 苍穹外卖day05(黑马程序员)笔记+Redis笔记
Redis是一款基于内存的高性能键值数据库,主要用于缓存和临时数据存储。它支持五种数据结构:字符串(String)用于简单键值对,哈希(Hash)存储对象字段,列表(List)实现有序队列,集合(Set)存储不重复元素,有序集合(Zset)用于带分数的排序场景。Redis提供快速读写能力,适合缓存热点数据、存储临时信息(如验证码)和实现计数功能。与MySQL相比,Redis侧重高速访问,MySQL则保证数据持久性。常用命令包括set/get(字符串)、hset/hget(哈希)、lpush/lrange(列
2026-03-27 17:01:10
391
原创 苍穹外卖day03笔记(黑马程序员)
本文介绍了如何使用AOP面向切面编程实现公共字段自动填充功能。通过自定义@AutoFill注解标记需要自动填充的方法,创建切面类AutoFillAspect拦截mapper层方法。该切面会判断操作类型(INSERT/UPDATE),利用反射自动为实体对象填充创建/更新时间、操作人ID等公共字段。这种方法避免了在Service层重复编写字段赋值代码,提高了开发效率和代码可维护性。核心实现包括定义切入点表达式、编写前置通知逻辑,以及通过反射动态设置实体属性值。
2026-03-24 19:45:25
395
原创 苍穹外卖day02记录
本文摘要:文章介绍了苍穹外卖项目员工管理模块的实现,重点讲解了新增员工功能的三层架构实现(Controller、Service、Mapper层),使用DTO对象进行前后端数据转换。同时介绍了ThreadLocal的线程隔离特性及其在用户ID传递中的应用,以及分页查询的实现原理,包括PageHelper插件的使用方法和PageResult对象的封装。整个实现过程遵循前后端分离开发规范,通过分层架构和工具类提高代码可维护性。
2026-03-22 15:46:14
419
原创 苍穹外卖day01记录
本文介绍了苍穹外卖项目中的Nginx反向代理配置和SpringMVC相关配置。主要内容包括: Nginx反向代理实现前后端分离访问,将前端8088端口请求转发到后端8080端口,并详细解析了路径替换规则和代理优势(提高安全性、访问速度及扩展性) MD5加密用于保护数据库密码安全 WebMvcConfiguration配置类实现三大功能: 注册JWT拦截器(拦截/admin/路径请求,排除登录接口) 使用Knife4j生成接口文档 配置静态资源映射 这些配置共同构建了项目的基础架构,实现了前后端分离、安全控制
2026-03-20 20:34:00
382
原创 TCP(初识网络编程)
TCP是一种可靠的面向连接传输协议,通过Socket实现客户端与服务器的通信。客户端使用Socket连接指定服务器,获取输出流发送数据后调用shutdownOutput()结束传输;服务器端通过ServerSocket监听端口,accept()接收连接后获取输入流读取数据。双方通信完成后需关闭资源。示例代码展示了客户端连接、发送数据和服务器监听、接收数据的完整流程,涉及关键方法如getInputStream()、getOutputStream()等。该机制确保了TCP传输的可靠性和有序性。
2026-01-20 15:52:41
163
原创 初识网络编程
本文介绍了网络编程的基础知识,重点讲解了IP地址、端口号和协议三大要素。主要内容包括:IPv4和IPv6的区别、特殊IP地址127.0.0.1的作用、常用网络命令ipconfig/ifconfig和ping的使用。详细说明了UDP和TCP协议的特点及Java实现,通过快递站类比解释了DatagramSocket和DatagramPacket的关系:DatagramSocket负责通信行为(发送/接收),DatagramPacket负责数据内容(包括IP地址和端口号)。最后提供了UDP协议发送和接收数据的Ja
2026-01-19 15:30:54
638
原创 MySQL学习记录(黑马程序员)——子查询
我们下面来看一个实际的例子,我们现在有这样一个需求:查询与 "张无忌"的薪资及直属领导相同的员工信息:我们要进行匹配需要一个emp里面某个元组里面的特定的两个属性:薪资和直属领导,而这个刚好是通过行的形式呈现的。,我们通过一个例子来说明,比如我们有个这样的需求:查询 "销售部"和“市场部”的所有员工的信息。我们来看下面一个例子我们有如下需求:查询比财务部所有人工资都高的员工信息,首先我们需要把财务部的工资都用表格的形式呈现出来,也就是子查询的第一步。总结:标量子查询是一种只返回单个值的子查询,常用在。
2025-10-25 20:38:53
1908
原创 MySQL学习记录(黑马程序员)——自连接
我们发现如果想要关联两张表如果只是自己等于自己比如设第一个表为A第二个为B 如果条件只是A.id=B.id那么其实没有什么意义因为还是跟没有加限制条件一样我们可以通过结论得出来。自连接说白了就是自己和自己连接,相当于自己和自己进行外连接,所以这个东西的理解方式完全可以参考外连接。那么连接的条件是什么呢我们先观察一下emp这张表格。这样就可以保证左表完整保证连接的完整性这一点可以看我的另一篇文章。通过这个查询语句就可以找到员工对应的主管信息。总结:内连接的本质就是。
2025-10-18 22:52:32
302
原创 MySQL学习记录(黑马程序员)——外连接
总结:外连接用于在两张表连接时保留一方的全部数据,即使另一方无匹配记录也会以NULL填充。其本质是在保留一张表完整数据的基础上,将另一张表中能匹配的部分补充进来,未匹配的以NULL表示。我们发现第17条数据 陈友谅是没有部门对应的但是却还是保留了,所以而且是保留了left表也就是emp表的所有元组的内容,而且通过观察我们还可以发现:即使左表的内容在右表找不到但是还是会默认用null填充这说明外连接本质就是。我们发现结论和刚刚的一样。是的外连接有两种一种是左外连接,一种是右外连接,通过观察我们发现。
2025-10-12 10:36:55
1977
原创 MySQL学习记录(参考黑马程序员)——内连接
这是MySQL比较难学的部分,接下来我会带着大家通过直观的学习接下来我们通过黑马程序员的MySQL教程中的实例来学习。
2025-10-12 09:48:49
1480
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅