
定时任务晚了一小时、接口明明只跑了两秒却被统计成负数、跨地区订单显示成“昨天”——这些问题往往不是计算写错了,而是程序把不同含义的“时间”混在了一起。时间处理的第一原则,不是统一格式,而是先明确用途。

定时任务晚了一小时、接口明明只跑了两秒却被统计成负数、跨地区订单显示成“昨天”——这些问题往往不是计算写错了,而是程序把不同含义的“时间”混在了一起。时间处理的第一原则,不是统一格式,而是先明确用途。

配置、缓存索引和本地状态看似只是“小文件”,却常在进程被杀、机器断电或两个实例同时写入时变成半截 JSON。可靠写入的关键不是多调用一次 write,而是分清原子可见性与持久化,并按正确顺序提交数据。

一次遗漏的输出转义、一个被污染的富文本字段,都可能让脚本进入页面。内容安全策略(Content Security Policy,CSP)能让浏览器只执行可信来源的资源,为 XSS 再加一道边界。但直接上线严格策略,往往先把统计脚本、字体和业务代码一起拦掉。更稳妥的办法是先观察、再收敛、最后阻断。

服务运行几天后突然报出 Too many open files,重启又恢复正常,通常不是“机器偶尔抽风”,而是某类文件描述符只打开、不释放。文件、Socket、管道和事件通知在 Linux 中都占用描述符;泄漏增长得很慢时,故障甚至会跨过多次常规监控窗口。定位它的关键,是先证明数量持续增长,再找出增长最快的资源类型,最后回到创建与关闭路径。

传统单元测试由开发者挑选几个输入,再核对预期输出。它对已知场景很有效,却容易漏掉空数组、极端整数和意外组合。Property-Based Testing(基于性质的测试)换了一个角度:先描述对所有合法输入都应成立的规则,再让工具批量生成数据、寻找反例,并把失败输入缩减到最容易理解的形态。

昵称限制 20 个“字符”、数据库字段最多 64 字节、前端把字符串截成 10 位——这些看似简单的需求,遇到重音符号、家庭 Emoji 或不同语言时就可能失效。问题不在 Unicode 太复杂,而在系统没有说清自己究竟在数什么。把文本的计量单位和规范化时机写进契约,才能避免乱码、半个 Emoji 和重复账号。

性能优化最怕“看起来应该是这里慢”。没有证据的优化,很容易把时间花在无关代码上,甚至把原本稳定的路径改复杂。Profiling 的价值是把 CPU、内存、锁等待和调用栈变成可比较的数据,再用火焰图把热点摊开,让团队围绕同一份事实讨论。

线上数据库迁移最怕的不是 ALTER TABLE 本身,而是应用版本、数据形态和回滚路径没有对齐。一次看似简单的改字段,可能同时影响旧代码读写、新代码灰度、历史数据回填、索引构建和报表查询。要把迁移做稳,关键是把“改表”拆成可观察、可暂停、可回滚的多个小步骤。

发布、扩容、缩容、节点维护都会让服务实例退出。退出本身不可怕,可怕的是进程收到 SIGTERM 后立刻消失:正在处理的请求被切断,队列任务做到一半,数据库事务悬着,负载均衡还在把新流量打进来。优雅关闭要解决的不是“退出得慢一点”,而是让实例从可接流状态,按顺序退到无副作用退出状态。

很多测试不稳定,并不是断言写错了,而是测试数据没有边界:上一条用例留下的用户还在库里,固定邮箱被并发任务重复创建,CI 里偶尔多一条历史订单,结果同一套测试今天过、明天红。测试数据管理的目标不是把数据造得越像生产越好,而是让每条用例都能清楚说明自己依赖什么、创建什么、清理什么。