我给本地缓存加了 TTL 和 LRU,踩了三个并发坑
从一个风控服务的真实场景出发,手写一个带过期时间和 LRU 淘汰的进程内缓存工具类。讲清链表与 Map 的并发删除竞态、时间源选择、清理线程的两个陷阱,以及缓存击穿的处理方式。
Blog
格达软件工程师的实战经验、技术选型与行业观察
从一个风控服务的真实场景出发,手写一个带过期时间和 LRU 淘汰的进程内缓存工具类。讲清链表与 Map 的并发删除竞态、时间源选择、清理线程的两个陷阱,以及缓存击穿的处理方式。
200 万条搜索词的前缀匹配,用 HashMap 做 Trie 吃掉 2.2 GB 内存。本文拆解这 2.2 GB 的具体构成,对比 26 叉数组、Radix Tree、双数组 Trie 和排序数组二分的真实开销,并记录空串、surrogate pair、热更新等边界上的踩坑。
把聚合 200 笔下游状态的页面从串行 40 秒改到 0.9 秒:讲清协程与事件循环的调度机制,以及三个不报错、只变慢的坑——协程里混入阻塞调用、并发不设上限、任务引用丢失与取消被吞。
`rm -rf $f` 遇到带空格的文件名会把一个路径拆成两个参数,删错目录。这篇文章拆开讲 shell 的分词与路径展开顺序、遍历文件名的正确写法、ssh/sudo 里引号被展开两层的陷阱,以及哪些地方加了引号反而是错的。
一个 Go 服务用最朴素的 Dockerfile 构建出来 1.11GB,改一行代码要等 47 秒。这篇拆开每一层看体积从哪来,用多阶段加 BuildKit 缓存把它降到 12.4MB、热构建 3 秒,并列出走到 distroless 和 scratch 之后必然会踩的坑:动态链接、CA 证书、时区、没有 shell。
断网后界面仍显示已连接、消息发出去石沉大海,这是 WebSocket 最常见的故障。文章从一次地铁切网的假在线排查出发,给出客户端应用层心跳、服务端协议级探活、全抖动指数退避重连的完整实现,并算清各层超时与心跳的流量代价。
面向跑了几年的 Java 老项目:在不改调用方的前提下,用接缝把 new、静态配置和系统时钟扒出来,配上可复制的 Mockito + JUnit5 示例、JaCoCo 增量覆盖率门禁,以及静态初始化、误连生产配置、H2 方言这三类实测踩过的坑。
订单表到了八千万行就必须拆?先看一条慢 SQL 再决定。这篇讲清分片键怎么选、基因法让订单号自带路由、跨分片分页与 count 的正确写法,以及事务、扩容、运维要付的真实代价。
排查一个内存只涨不降的服务,ASAN 报出几万个没释放的 Session,代码里一个 new 都没有。本文从这个可复现的循环引用案例出发,讲清三种智能指针该用在哪、代价是什么,以及 pImpl 不完整类型、make_shared 延迟释放、expired 与 lock 竞态这几个实际会踩的坑。
快排写不对,多半是 partition 的返回值和边界没搞清。本文给出 Lomuto、Hoare 和三路划分的可运行实现,指出重复元素、全相等数组、空区间等场景下的死循环和栈溢出,并给出测试代码。