自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Sam_Deep_Thinking

努力深入思考和总结

  • 博客(555)
  • 资源 (1)
  • 问答 (12)
  • 收藏
  • 关注

原创 所有的框架源码,最怕的就是被debug

知乎上有个问题:学编程是理解就行呢还是全部背?我的观点是:我是建议用debug的思维去做这个事情,并且写一些小的demo验证它。我之前在知乎写过一篇回答,redis 为什么是单线程的?我才不管的它是C语言,D语言,xxx语言写的。我想搞清楚它,那我就debug它,直接把整个redis在我的window11上运行起来。所有的问题,最怕的就是被debug。我就是想知道redis单线程是怎么回事,就算它是C语言实现的,照样debug。

2026-05-10 11:26:30 224

原创 为什么选微服务而不是动态扩容单体

动态扩容单体能不能做?能。单体应用部署成集群,前面挂个负载均衡,流量大了加机器。问题在于:选微服务的驱动力从来不是吞吐量。如果你面临的问题只是「流量扛不住了」,代码性能又不错,加机器就行,根本不需要微服务。选微服务是因为有些问题,你把单体复制100份也解决不了。

2026-05-09 11:21:41 458

原创 别人写的代码看不懂,到底是谁的水平有问题

你突然看到某段代码用了工厂模式,第一反应可能是:有必要吗?直接new一个对象不行吗?干嘛「故意」增加阅读难度?其实不是这样的,当你接触过的高手多了后,你会自然而然的认为:高手的代码,确实不太容易看懂,尤其你水平还不够的时候。我不是说你菜,只是每个人都会经历过这个阶段的。关键在于,你得分清楚一件事:到底是代码本身写得烂,还是你的知识面暂时还覆盖不到这里。

2026-05-09 10:07:34 600

原创 RocketMQ消息可靠性的三道关卡

RocketMQ的可靠性设计覆盖了消息流转的每个环节,但不是说用了RocketMQ消息就不会丢。它提供了机制,能不能用好取决于你怎么配、怎么写代码。任何一道关卡出问题,消息就可能丢。接下来分别看看RocketMQ在每道关卡上做了什么设计。

2026-05-08 14:01:57 584

原创 完结篇:28篇,一套完整的秒杀系统交付给你了

提醒」:是付费专栏,但是在知识星球里是免费的。写到这里,这个专栏正式完结了。整个项目一共写了从开篇词到全链路压测,28篇文章,前后持续了几周。写的过程比我预想的累很多。不是技术本身难,而是要把一套真实的生产系统拆开来,用文字讲清楚每一个设计决策背后的原因,同时还要保证前后28篇的技术细节完全一致、互相对得上,这个工作量远超写代码本身。有些章节反复改了三四遍。不是因为技术方案有问题,而是写出来之后发现读者如果没看过前面的某一篇,这段话就会看不懂。

2026-05-08 09:41:03 489

原创 批评下属不如当场展示解决方案

不一定是拥抱这么戏剧化的动作,但至少在后续的团队场合里,公开肯定她做得好的地方或者在群里说也行,让所有人知道你对她的认可没有变。有人问了这么一个问题:因为工作不到位,在部门全员会议上批评了下属,下属从此甩脸子不搭理,三个月过去了,组长职责也不履行了,部门内工作不好安排,念及感情和现实情况不知道如何处理。年轻人被说两句可能转头就忘了,但一个在团队里待了好几年、被你亲手提拔起来的人,她会觉得这是全盘否定,她会一直记着这个事的。对方承认了错误,回到工位上,她知道自己错了,但她不知道对的应该是什么样的。

2026-05-07 14:19:46 220

原创 打造高效团队的四个关键动作

很多新晋技术经理或者技术组长上任后,第一件事就是建流程、定规范、搞工具链。忙了几个月,发现团队效率并没有明显提升。问题出在哪?方向搞反了。流程和工具是锦上添花的东西,团队能不能打仗,取决于更底层的四件事。下面逐个展开。

2026-05-07 10:01:43 384

原创 帮同事不是顺手的事,是要停下来认真做的事

很多团队都说提倡互助,领导也经常讲「干完自己的活,主动帮帮别人」。方向没问题,但落到执行层面,有个关键矛盾大多数团队没有解决:帮忙的时间从哪来?如果答案是「挤一挤」「顺手帮一下」,那这个互助基本是空转的。一个人一边赶自己的项目进度,一边帮别人看方案、写代码、排查问题,两件事都做不到位。帮忙的人心里惦记着自己的需求还没交付,被帮的人得到的也只是碎片化的指点,效果打折扣。我自己带团队,也提倡互助。但我做的不是喊口号,而是在排期和任务分配层面把互助这件事实施起来。

2026-05-07 09:51:43 300

原创 程序员如何接受工作内容毫无意义?

知乎上有人问:程序员如何接受工作内容毫无意义?他举了一堆例子。按钮文案从「氛围」改成「空间」,又改回来。一个按钮被疯狂点击后偶尔闪烁,测试提了bug,但觉得用户根本不会这么操作。git提交信息格式不对被打回。周报提交了领导根本不看。这些抱怨我见过太多了。每次看到,反应都一样:觉得工作没意义的人,十有八九不是工作本身没意义,是他还没走到能接触有意义工作的阶段。

2026-05-06 14:53:00 241

原创 代码能跑就别动?有AI之后其实未必

现在不都是通过流水线去解决这个问题的吗?不用那么担心了吧。我自己的AI IDE里配了不少skill,改完让AI跑一套分析和审核,比如说这3个skill有一个总的入口skill来串联,配置在SKILL.md里。改完代码后先在「改动点」界面逐个人工审核每处变更,确认没问题剩下全部交给AI了。另外我会再加上600多行的工程规则文件,告诉AI该怎么写代码,让它按我的风格和标准来。这套操作下来,对我这种工作多年经验丰富,业务又熟悉的人来说,重构的心理负担基本就没有了。

2026-05-05 17:24:21 492

原创 程序员过35岁之前,应该完成的三件事

作为一个「」过了35岁的人来说,可以聊这个话题。我觉得就「三件事」需要提早去做。我42了,还在一线撸代码。像我这种人,天天都在想一个问题:当我离职或者被离职了,我每天每周每个月,还能挣多少钱?这个问题才是最优先要考虑的。不是「怎么让自己不被裁」,而是「没有工作了,你能挣多少钱」。35岁危机的本质不是年龄歧视,是你的全部收入都绑在一份雇佣关系上。公司在,你有钱;公司不要你了,你归零。这种结构本身就是脆弱的,跟年龄没关系,只是年龄大了之后这种脆弱会被放大。想明白这一点,要做的事就三件。

2026-05-05 11:41:37 448

原创 别把业务逻辑塞进存储过程,适当用表驱动法

当然不建议将业务逻辑全部写在存储过程里,太难维护了。但是《代码大全》里的表驱动法的话,有些场景还是可以用的。这两件事看起来有点像,都是把逻辑「外置」到数据库层面,但本质区别很大。存储过程是把程序的执行流程搬到数据库里,而表驱动法是把数据和规则的映射关系存到表里,执行流程还是留在应用代码中。前者带来的问题远大于收益,后者在特定场景下确实能减少大量的条件判断代码。最近帮知识星球里的一个星友出了一套方案,他们公司正在做一件事:把存储过程全部迁移到Java实现。整个项目做了灰度、质检、回滚的全流程设计。为什么要迁移

2026-05-05 09:25:18 444

原创 为什么要做性能测试

因为性能测试能帮你找到你代码里的锁。我还在国内一家互联网大厂打工的时候,有次做完一轮性能测试,把报告交给leader审核。他瞄了一眼:CPU才压到40%?我很诧异,回了一句:并发数和环境都检查过了,已经是最优并发数了,接口的吞吐量确实也一直上不去。leader只说了一句:你的代码里有锁,线程在CPU里干活的效率很低很低,CPU的利用率太低了。先去检查代码。后来仔细检查代码,还真是有锁。

2026-05-04 09:28:48 786 1

原创 为什么你做技术方案总是漏掉边界情况

你缺的是一个好的环境。技术评审会上经常能看到这样的场景:同一份方案摆在桌上,有人扫一眼就能提出五六个问题,并发竞争怎么处理、数据量大了会不会拖慢查询、上下游服务挂了怎么兜底。你看了半天觉得方案挺好的,甚至觉得人家提的那些场景也太极端了,真实业务哪有这么多幺蛾子。过几个月,线上出了故障,一查根因,正是当初被别人提出来但没重视的那个边界情况。这种差距从哪来?多数人的反应是:我不够细心,或者我经验不够。这个归因方向有问题。

2026-05-04 08:06:59 537

原创 并发量就算只有2,该上锁还得上呀

先看一组真实的生产数据。一个有1000家门店的连锁企业,订货系统下单接口的峰值TPS是20。一个有2亿用户的平台,大促期间下单接口的TPS是2000。同一个平台的商品系统,整个域的峰值QPS是70万,分摊到单台机器大约3万多。大多数系统的实际并发量,比你想象中低得多。这组数据抛出来,很多人的第一反应是:那我们系统TPS才个位数,是不是不用考虑并发了?这个想法,每年都在制造线上事故。

2026-05-03 18:15:51 425

原创 如何让订单系统和营销系统解耦

订单系统在大多数电商公司里属于中后台服务,按理说应该是相对稳定的,不能老随着其他业务系统的节奏走。实际情况正好相反。很多团队的订单系统每周都在发版,翻一下发版记录会发现,大部分改动跟订单本身的逻辑没什么关系,全是在对接营销系统的活动。今天加个满减规则,明天改个优惠券的扣减逻辑,后天又来一个新的营销活动需要特殊处理。订单团队的发版节奏完全被营销团队带着走,自己的迭代计划永远排不下去。问题不在营销活动太多,在于订单系统和营销系统耦合在了一起。

2026-05-02 12:29:31 874

原创 一个跑了三年没出过问题的系统,我是怎么设计的

23年我入职了一家做连锁门店业务的公司。入职后接手的第一个事情,是从零到一设计门店进销存系统。这套系统到现在跑了三年,几乎没出过问题。前段时间CTO专门过来说了句,这套系统很稳定。管门店业务的老大,也很认可。我想聊聊这个设计背后的思路。不是因为这个设计有多精妙,恰恰相反,它并不复杂。任何一个愿意在动手之前多想一步的程序员,都能做出来。

2026-05-02 10:35:56 585

原创 第2篇:应付百万并发商品系统之需求文档

提醒:是付费专栏,但是在知识星球里是免费的。这不是一份产品经理写的功能需求文档。商品系统的重构需求来自技术团队,触发原因是一次大促事故。重构的范围不只是商品系统,而是公司所有核心系统从PHP到Java的整体迁移。后续的每一个技术方案,都要回到这份文档里找依据。

2026-05-01 10:46:11 416

原创 第1篇-开篇词:几亿用户规模下,我们是怎么做C端高并发商品系统的

我之前在一家几亿用户规模的互联网公司做Java高级开发,深度参与设计的核心项目之一就是C端商品系统。32台机器,70万并发读请求,这是某次大促时的峰值数据。现在的流量规模比这个数字大得多。商品系统在技术架构里的位置比较特殊。平时流量就不小,一到大促,商品域的流量在整个公司排第一。这套系统我从0参与设计,经历过无数次大促,扛住了每一次流量高峰。这个专栏把当时的设计思路、关键代码和踩过的坑完整写出来。

2026-04-30 14:15:11 458

原创 中小团队需要一个资源微服务

我这边是把所有资源密集型的操作从核心服务里拆了出来,单独起了一个微服务。做这个决定基于两个考虑:一个是系统稳定性,一个是微服务定位。

2026-04-29 18:16:55 708

原创 秒杀系统的幂等,只做一层Redis判重远远不够

但问题是Redis不是万无一失的,宕机恢复后可能丢数据(取决于AOF的fsync策略),SETNX的key可能消失。在订单表的traceId字段上建唯一索引,即使Redis层漏过了重复请求,数据库的DuplicateKeyException也会阻止重复插入。在实际的秒杀系统中,幂等做一层是扛不住的,我们的方案是三层防护,从外到内:Redis SETNX抢占、数据库唯一索引、业务状态机,三层各管各的范围,缺一层就有漏洞。另外后续我新写的所有对外的付费专栏,在星球内都是免费的,且可以拿到所有源代码。

2026-04-29 09:26:50 209

原创 用工厂模式和模板方法统一封装所有第三方的Access Token

是抽象基类,也是整个设计的核心。它定义了获取AccessToken的完整流程:查本地缓存、查Redis、加分布式锁、调第三方API、存缓存。这些步骤对所有平台都一样,全部在基类里实现。

2026-04-28 10:22:17 712

原创 秒杀系统里的RocketMQ,不是发个消息那么简单

不是泛泛地讲RocketMQ怎么用,而是在秒杀这个具体场景下,每个配置为什么这么选,背后的考量是什么。每个订单的超时是独立的,不需要批量扫描。还有一个容易踩的坑:顺序消费模式下,maxReconsumeTimes的默认值是Integer.MAX_VALUE,相当于无限重试。有问题的,找知心的Sam哥,支持无限次语音一对一解决你遇到的难题。另外后续我新写的所有对外的付费专栏,在星球内都是免费的,且可以拿到所有源代码。很多人理解的MQ就是「生产者发消息,消费者收消息」,但在秒杀场景下,光把消息发出去远远不够。

2026-04-28 08:27:22 79

原创 秒杀下单,用户点一下按钮,后端要过六道关卡

我正在写的「秒杀系统实战」专栏,目前已经更新到第11篇,从需求PRD、技术方案设计、基础框架搭建,到网关限流、分库分表、多级缓存、机审校验、用户级限流、小黑屋,再到这篇的下单入口,每一篇都带完整的代码实现和设计决策的推导过程。预检读的是Redis里的库存快照,不是精确值。预检的目的不是精确判断,而是快速拦截已经售罄的情况,减少无效的MQ消息量。还有一个实际运维的考量:每个校验环节是独立的Service,大促期间某个环节出问题(比如机审误杀率突然升高),通过Nacos把对应的开关关掉就行,不影响其他环节。

2026-04-27 09:23:40 242

原创 适合中小型企业的出口入口网关微服务

23年入职现在这家公司,到岗后我做的第一件事不是接业务需求,而是先搭了快速开发框架和模版微服务工程,然后紧接着搭了这个出口入口网关微服务。这个决定跟之前的经历有关。待过几家公司,每家都要对接不少第三方系统,钉钉、企业微信、金蝶、各种外卖平台、电子签章,零零散散加起来十几个。对接代码散落在各个微服务里,A服务对接了钉钉的用户接口,B服务也要用,又对接了一遍。接口一改,两边都得改。新人来了想找对接钉钉的代码,得翻好几个工程才能找全。这个问题在中小型团队里特别明显。

2026-04-26 15:01:06 512

原创 秒杀系统怎么区分真实用户和黄牛脚本?

大致思路:用户打开活动页时,前端悄悄调一个预检接口,服务端生成一个随机串和时间戳,用时间戳决定在随机串的某个位置插入一个标记字符,结果存进Redis,30秒过期。这是我正在写的秒杀专栏里的一个片段。每篇都有真实项目的代码和配置,不是画架构图讲概念,是拿过去改一改就能落地的那种。用户体验差是一方面,更关键的是秒杀的时间窗口太短,多一步交互就多一层流失。我在做6000万会员的秒杀系统时,用的是一套四层防刷体系。如果你正在做秒杀相关的项目,或者想系统地补一下高并发场景的实战经验,可以看看。

2026-04-26 11:13:21 281

原创 别让一个超时的第三方http接口拖垮所有接口

大多数Java项目在调第三方HTTP接口时,会封装一个工具类,里面用懒加载或者静态变量持有一个全局的OkHttpClient实例。所有业务方调第三方接口,都走这一个实例。平时这么用没什么问题。OkHttpClient本身是线程安全的,官方也推荐复用实例来减少连接开销。问题在于,第三方系统是不可控的。你对接的第三方可能有5个、10个,每个第三方的稳定性、响应速度、限流策略都不一样。某天其中一个第三方的接口响应变慢了,从正常的几百毫秒变成了十几秒甚至超时,这时候事情就不是「那一个接口变慢了」这么简单。

2026-04-24 15:32:35 691

原创 C端多渠道用户体系设计:从需求到落地

C端产品接入多渠道,最常见的技术债是在用户表上为每个渠道加一组字段。微信来了加wx_open_id和wx_session_key,支付宝来了加alipay_user_id和alipay_access_token,抖音来了再加一组。等渠道到了四五个,这张表已经有十几个渠道字段了,其中大部分对任何一个具体用户来说都是空的。更麻烦的是,每次新增渠道都要改表结构、改实体类、改查询逻辑、改缓存策略,改动面大到让人不敢动。换一个思路:把用户身份和渠道接入拆成两层。

2026-04-24 12:45:51 1115

原创 写了十几年代码,聊聊什么样的人能做好Java开发

有个现象,做了若干年之后回头看特别明显:起点差不多的人,三五年后差距就拉开了。有些人三年能独当一面,带着团队做核心系统。有些人干了七八年,还在接需求写接口,稍微复杂一点的任务交不到他手上。差距来自哪?技术天赋有一点影响,但说实话不大。编程不是数学竞赛,不需要你智商超群。学历也不是决定性因素,我见过不少学历一般但成长飞快的人,也见过名校出来但几年下来原地踏步的。观察了这么多年,我发现真正起作用的是三个层面的东西:你这个人本身的特质,你思考问题的方式,以及你选择走什么样的路。

2026-04-23 14:33:41 438

原创 如何理解 Spring 当中的 Bean?

面试里经常被问到一个问题:什么是Spring Bean?工作三五年的开发者,大部分人的回答是「被Spring管理的对象」。这个回答不算错,但信息量约等于零。所有关键的东西都藏在「管理」这两个字里。管理了什么?怎么管理的?为什么需要管理?追问一层就接不住了。问题出在哪里?这个定义是用Spring来解释Bean,没有跳出框架去理解它。你记住了一个说法,但追问一层你会发现自己说不清楚。

2026-04-23 09:55:00 770

原创 从DDD的仓储层反向依赖,理解DIP、IOC和DI

我从23年开始在公司的技术团队里落地DDD,领域驱动设计开发。落地过程中有一个问题反复被团队成员问到:基础设施层为什么反过来要去依赖领域层?这个问题问得好。因为从这个问题入手,能一次性把DIP、IoC、DI这三个经常被混淆的概念理清楚。打开我们项目基础设施模块的pom.xml,能看到这样的依赖声明:</</</基础设施模块依赖领域模块。再看领域模块的pom.xml,里面没有任何对基础设施模块的依赖。

2026-04-22 10:04:26 609

原创 程序员懂业务,到底要懂到什么程度

我面过不少候选人,聊到业务理解的时候,大部分人的回答都是在描述自己做过的功能:我负责过订单模块、我做过支付对接、我写过库存扣减的逻辑。这些是工作经历,不是业务理解。区别在哪?工作经历是「我做过什么」,业务理解是「我知道这个行业在解决什么问题,以及什么方案在什么条件下效果最好」。前者绑定在某一家公司的某一个项目上,离开了就带不走。后者是可迁移的认知资产,换个公司照样能用。这两者的市场价值差距非常大。

2026-04-21 13:15:01 658

原创 项目经理要注意的三件事

项目经理最重要的三个能力是什么?硬要回答这个问题,不太好说,因为「能力」这个词太抽象了,聊起来容易变成正确的废话。换个方式来回答可能更有用:项目经理最该注意哪些事?

2026-04-21 09:40:29 338

原创 学数据结构到底有什么用

InnoDB默认用B+树索引,B+树的非叶子节点只存索引键不存行数据,一个16KB的页能装大量键值,树的高度很矮,几次磁盘IO就能定位到数据行。用户ID做key,商品ID做field,数量做value。做了这么多年开发,我觉得数据结构的价值不在于你能手写多少种算法实现,而在于你面对一个具体的业务需求时,脑子里有足够多的候选方案,知道每种方案的优缺点和适用场景,能快速做出合理的选择并说清楚原因。

2026-04-20 10:20:24 423

原创 Spring AOP记录日志,生产环境的代码长什么样

网上的AOP日志教程,代码基本都长一样:定义一个注解,写一个切面,方法前后各打一行log.info。跑通了,教程结束。这种代码到了生产环境几乎没用。线上排查问题的时候,你需要的不是「某个方法被调了」这种信息。你需要知道这次请求的链路ID、调用方IP、传入的业务参数、方法耗时、异常类型和错误码。教程里那种只打方法名的日志,在日志平台里搜出来跟没搜一样。我从三个线上项目里提取了AOP日志的实现代码,整理出生产环境真正在用的写法。

2026-04-19 12:29:35 487

原创 回复星友提问:配了消费线程数为1,并发到底是1还是n

我从RocketMQ4.9.8的源码开始,把消费线程池的创建、消息从拉取到提交线程池的完整链路、LinkedBlockingQueue导致最大线程数失效的原因,都讲清楚了。还做了一张主动限流和被动限流的对比表,给出了消费线程数的具体计算方式,都是可以直接拿去用的。这些不是从文档里抄的,是在生产环境里实际踩过的。很多技术点我脑子里是有方案的,但为了保险起见,还是会再去翻源码核对一遍,确保写出来的东西经得起验证。星球里的回答我都是这么做的,碰到值得深入讲的问题,会写成一篇完整的长文,从原理到落地方案都给到。

2026-04-18 12:46:43 231

原创 秒杀系统需求PRD

第一次自由卡促销活动把核心交易系统打挂了。这件事之后,CTO拍板要做一套独立的秒杀系统。

2026-04-17 14:46:43 561

原创 开篇词:6000万会员规模下,我们是怎么做秒杀系统的

第一次自由卡促销活动,把核心交易系统打挂了。自由卡是一种虚拟预付卡,用户先充值,再用卡内余额购买商品。配合半价或大力度折扣时,对用户的吸引力非常强。活动一开始,瞬时并发请求直接把核心系统的数据库连接池打满,整个交易链路不可用。不光秒杀用户受影响,正常的下单、支付也全部阻塞。那次事故之后,CTO拍板:做一套独立的秒杀系统,和核心交易链路完全隔离。秒杀流量不管多大,不能影响正常交易。后端组建了两个技术小组:会员用户组和订单支付组,加起来十几位同学参与。前端有独立团队配合。

2026-04-17 14:32:51 864

原创 Spring Bean作用域的设计与使用

Spring Bean作用域设计与使用要点 Spring提供了6种bean作用域,但实际项目中90%以上使用默认的singleton。理解作用域设计的关键在于回答三个问题:是否需要共享实例?共享范围多大?生命周期跟随谁? Singleton:默认作用域,适用于无状态服务对象,容器缓存单实例,高效复用 Prototype:解决状态隔离问题,每次获取新实例,但需注意注入singleton时的陷阱 Web相关作用域:request/session/application/websocket,专为Web环境设计 特

2026-04-17 13:36:34 553

原创 再次理解 MySQL B+ 树:以每页 10 行的聚簇索引为例

本文通过简化模型分析了InnoDB主键聚簇索引B+树的演化过程。设定每页10行记录,展示了从单层到三层的树结构变化,包括根节点、中间节点和叶子节点的组织方式。重点说明了查找路径(如查找id=45的过程)和树高增长条件(当记录数超过120时需增加层级)。与其他结构对比表明,B+树因其范围查询能力、高扇出、低树高和顺序访问优势,成为关系型数据库的最佳选择。虽然存在LSM树等替代方案,但B+树在通用场景下仍是最均衡的索引结构。

2025-11-27 10:16:26 859

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除