FWDD.NET · 技术文档站

范文多多

聚焦后端工程实践:语言教程、功能实现、面试题与运维脚本。每篇都从真实踩坑场景出发,给出可直接复用的代码与取舍依据。

用 errgroup 控制并发任务的首错取消与信号传播

写 Go 并发的时候,最常踩的坑不是「不会起 goroutine」,而是「起了收不回来」。典型场景:一批 RPC 要并发发起,只要有一个失败就立刻停掉其余请求并返回第一个错误;或者一批 worker 在跑,用户在终端按下 Ctrl+C,需要让所有 worker 收到信号、优雅收尾。手写 sync.WaitGroup + context.WithCancel

itertools.groupby 分组的预排序陷阱与替代写法

itertools.groupby 是 Python 标准库里最容易被误用的函数之一。它的签名看起来像 SQL 的 GROUP BY,但语义完全不同:它只合并相邻的相同键,不做全局汇总。于是「忘了先排序」成了高频事故——数据没报错、结果却悄悄少了行或者多了组。这篇教程把 groupby 的真实语义、四种常见翻车现场、排序键的挑选技巧,以及 sort + gr

用 trap 与 PID 文件实现 Shell 脚本互斥锁防止并发重入

日常运维里最容易出事的不是磁盘满,而是同一个备份脚本被 crontab 和手动执行同时拉起来两份。两份 rsync 抢同一个目标目录,两份 mysqldump 同时往同一个 .sql 里写,两份日志清理脚本同时 find -delete,结果往往是文件损坏、任务卡死、负载飙高,而排查时又抓不到现场。本文给出一个不依赖 flock 之外的额外软件、只用 She

端口占用排查脚本:lsof 与 ss 输出对比与自动清理

线上服务起不来,最常见的报错之一是 bind: Address already in use。这时运维第一反应是 lsof -i:8080,但你是否遇到过:ss 明明显示端口被占用,lsof 却空空如也;或者反过来,lsof 列出一堆进程,ss 只给一个 LISTEN。两个工具走的是完全不同的内核数据源,理解差异才能写出靠谱的排查与清理脚本。本文给出一套可直

用 INSERT … ON DUPLICATE KEY UPDATE 实现幂等写入

消息队列重投、用户连点两次提交、定时任务因为上一次超时被重新调度——这些场景都会让同一条业务数据被写入两次。如果写入逻辑是「先 SELECT 判断存在再 INSERT」,在并发下会稳定地漏判:两个事务同时 SELECT 都没查到,然后都去 INSERT,最后要么产生两条脏数据,要么撞唯一索引报 Duplicate entry。把判断和写入压进一条 SQL,交

缓存穿透、击穿、雪崩的判定与各自对策

面试里问到 Redis 缓存问题,最常见的失分点不是不知道三个名词,而是把三者的触发条件讲混。很多候选人能把「布隆过滤器」「互斥锁」「随机过期时间」背出来,但面试官追问一句「一个不存在的 user_id 反复打进来,命中率没掉但 DB 的 QPS 涨了,这算哪种」,就答不上来了。本文按「怎么判定 → 为什么会发生 → 具体对策 → 代码怎么写 → 线上怎么验

Go 的 context.WithCancel 与 goroutine 泄漏排查要点

线上 Go 服务跑着跑着 RSS 从 80MB 涨到 900MB,GOMAXPROCS 没变、QPS 没涨,runtime.NumGoroutine() 却在单调上升——这类问题十有八九和 context.WithCancel 用得不对有关。本文从一次真实的内存增长切入,讲清 WithCancel 的传播语义、四种最常见的泄漏写法、如何用 pprof 和 g

inotify 监控目录并触发告警的轻量脚本

线上服务器经常出这种事:某个目录本该只读,结果被人手动改了个配置文件;或者 /etc/nginx/conf.d 下突然多出一个 .conf,reload 之后整站 502。事后翻 ~/.bash_history 往往已经断档,审计日志又重又慢。真正需要的是一层极轻的「哨兵」:目录内容一变,几秒内就把变更路径、事件类型、操作者推到你面前。 inotify 是