操作系统层面的基础原理笔记。点击进入:
- 用户态与内核态——权限级隔离、系统调用、切换开销与性能排查
操作系统层面的基础原理笔记。点击进入:
想象一次压测现场:接口 QPS 死活上不去,CPU 利用率却已经 90%+。打开 top 定睛一看,us(用户态)只占 40%,sy(内核态)却占了一半——CPU 忙了半天,一大半时间不是在跑你的业务代码,而是在替你跑内核的代码。
时间去哪了?要回答这个问题,得先搞懂这篇文章的主题:CPU 其实有两个"档位",你的代码和内核的代码,各在其中一个档位上跑。这两个档位怎么划分、什么时候切换、切换为什么有开销,就是"用户态与内核态"的全部内容。
文末附一个能自己跑的实测程序:纯用户态操作和"进内核"操作,单次耗时差了四五个数量级。这不
想象一个场景:活动页上线,两个入口同时在扣同一份库存,各扣 10 万次,运营对账时发现账对不上——凭空少了一截。日志里没有任何报错,把请求单独重放一遍,每一笔又都是对的。这种"单看每一步都对,合在一起就是错"的问题,十有八九出在并发。
volatile、synchronized、AtomicInteger、线程池——这些东西平时都在用,但"各自到底解决什么问题、为什么要配合着用",值得系统梳理一遍。这篇就按这条线走:先看多线程为什么会出事,再按"一个问题一把钥匙"讲每件工具,最后讲线程池怎么配。文中的示例代码都实际跑过(JDK 21),运
学了 ReentrantLock、读写锁、Semaphore、CountDownLatch 之后,可能有过一个疑问:这一堆工具,底层是不是各写各的?不是,它们底下全是同一个东西——AQS(AbstractQueuedSynchronizer,抽象队列同步器)。JUC 里大半的同步工具,都是在这一个框架上搭出来的。这篇把它拆开看:state 是什么、队列怎么排、线程怎么挂起又怎么被唤醒。理解了 AQS,上面那一堆工具就不再是几个孤立的 API,而是同一套机制的不同用法。
上游文章:《[ReentrantLock 详解](/ful
ReentrantLock 和 synchronized 有个共同点:同一时刻只允许一个线程进。可大量场景里,读和读之间根本不冲突——十个线程同时读一份配置、一个缓存被反复查询,互不干扰,凭什么排队?读写锁就是为"读多写少"准备的:读和读共享,只要有写就互斥。这篇梳理读写锁的规则、锁降级,以及 JDK 8 加的进阶版 StampedLock(乐观读,连读锁都可以不加)。
锁的全景地图在《锁的分类与实现原理》,`R
synchronized 日常够用了——简单、自动加锁释放,JDK 1.6 之后性能也优化得很好。但它有几个天生的限制:拿不到锁就一直傻等、等的时候不能被中断、所有线程抢锁不排队、也没有办法让线程"分拨"等待。这篇把 ReentrantLock 系统梳理一遍:它补齐了哪些能力、每个能力解决什么场景,以及什么时候其实还是 synchronized 更合适。
这是"锁"系列的一篇。各种锁概念的全景(本地锁/分布式锁/悲观乐观锁)在《[锁的分类与实现原理](/software-architecture/design-ideas/lock-o
这是一次真实接口优化的复盘。系统是一个固定资产管理系统,工作台是登录后的第一屏——今日统计、我的资产、待办审批、预警数字、最近操作,功能不复杂,但压测数据很难看:20 QPS 就饱和,P99 干到 1.7 秒。
这篇按当时的排查顺序写:先定位瓶颈在哪,再讲动了哪三刀,最后看数据。没有黑科技,全是朴素手段,但每一步的取舍值得说清楚——尤其是「为什么这个查询不能扔进异步线程」和「批量化引入的时序 bug」,都是踩过才知道的。
优化接口的第一原则:先搞清楚它到底干了多少事,而不是上来就加缓存
集成测试最大的坑不是代码,是环境造假。H2 内存数据库号称能模拟 MySQL,但 ON DUPLICATE KEY UPDATE、GROUP_CONCAT、JSON 字段、锁行为……这些 MySQL 方言它全跑不了。测试过了,一上真实环境就炸。
Testcontainers 的思路很直接:测试时用 Docker 起一个真的 MySQL/Redis/RabbitMQ,测完自动销毁。测的就是真实组件的真实行为。
本文是《[集成测试快速入门](/test-ops/integration/integration-test-qui
上一节《JMeter 快速入门》讲了工具怎么用,这篇是实战记录:对一台部署在云服务器上的管理后台(前端 + 后端 API)做了一次完整压测——从定目标、设计场景、跑梯度,到从数据里把瓶颈挖出来。所有数据都是真实跑出来的,瓶颈发现的部分比“怎么压”更值得看。
被测系统:一台 2 核云服务器,nginx 托管前端静态资源,反向代理后面的 Java 后端(Spring Boot + MySQL)。日常访问没问题,但“没问题”不等于“知
上一篇《一次真实的服务器压测实战》的续章里,写接口的数据出现过一次反转:第一版脚本测出写接口 270 QPS、"快过所有读接口";修正方法重测后只剩 38 QPS,前后差了 7 倍。这篇把这次"数据打假"的完整过程单独成篇——从发现数字对不上,到翻源码定位防重逻辑,到设计实验验证拦截规律,最后修正压测方法拿到真实水位。压测数据里的"假绿"比压不动更危险:它不报错,只骗人。
写接口压测(新增一条通知公告)跑完,把三份数据摆