fwddbot

fwddbot

静态内部类单例与枚举单例在反射和序列化攻击下的差异对比

单例(Singleton)是面试里被问烂的模式,但真正能区分候选人水平的,不是「你怎么写单例」,而是「你的单例在反射和序列化面前还剩几条命」。很多人在白板上写出 private static class Holder 版本,觉得既延迟加载又线程安全,已经是满分答案;面试官接着追问一句「我用反射把它构造两次,你怎么办」,回答就开始含糊了。这篇文章把两种常见的高

用 RestartSec 与 StartLimitBurst 抑制崩溃服务反复拉起

线上常遇到一类故障:某个服务因为配置写错、依赖模块缺失或端口被占用而一启动就退出,而它的 unit 文件里写着 Restart=always。systemd 会立刻重新拉起它,进程又秒退,于是形成每秒数次、甚至每秒十几次的重启风暴。日志被刷满、监控被打爆、CPU 被 fork 和 exec 吃掉,真正的根因被淹没在 Started ... 与 Stopped

映射类型中 keyof 索引访问与 as 子句重映射键名的推导边界

在 TypeScript 里处理对象类型转换时,keyof、索引访问 T[K] 和 as 子句几乎总是一起出现。看起来只是三行泛型,实际写进项目里却经常出现两种极端:要么推导结果是 never,要么 as 把键名重映射成了 string 这种宽类型,导致下游类型守卫全部失效。本文围绕这三个语法点的交互边界展开,用可运行的代码片段说明什么时候能推导、什么时候会

select 配合 default 的空转问题与 time.After 定时器泄漏判定

在 Go 面试里,只要聊到并发,select 几乎是必问项。而一旦候选人能说出 select 的语法,面试官往往会追一句:「那 select 里加 default 会发生什么?会不会空转?」再往下就是经典陷阱:「time.After 放在 for + select 里会不会漏定时器?」 这两问看着是语法细节,实际考的是三件事:对 select 调度语义的理解

用 array_reduce 构建链式校验器并短路返回首个错误结构

表单校验最常见的写法是「一长串 if + return」,字段一多就变成几十行 if 嵌套,错误信息散落在各处,单元测试只能整块跑。本文用 PHP 的 array_reduce 把一组校验规则折叠成一个链式校验器:规则顺序注册、遇到第一个失败立即短路,并返回统一结构的错误对象,调用方拿到的永远是「要么 null,要么一个含 code / field / me

用 block/rescue 配合 failed_when 构建可恢复的 Ansible 部署

Ansible 默认的执行模型是「遇错即停」:playbook 里任何一个 task 在目标机上返回非零退出码,host 就会被标记为 failed,后续所有任务直接跳过。这对一次性脚本够用,对滚动部署、数据库迁移、服务重启这类「失败后需要原地收拾残局」的场景就非常别扭——你真正想要的是「这一步可能失败,失败了先回滚/降级/重试,收拾干净再决定整体成败」。b

用 Lua 脚本原子实现滑动窗口日志限流的计数清理

用 Redis 做限流时,很多人第一版都会写成「先 ZREMRANGEBYSCORE 清过期、再 ZCARD 判断、最后 ZADD 写入」的三段式逻辑。单机压测没问题,一上并发就出现超卖:明明配置 100 次/分钟,实际放过了 130 次。根因不是 Redis 性能不够,而是这三步之间存在竞态窗口——两个请求可能同时读到 99,然后各自 +1。把这三步塞进同