线上出了Bug,全组排查到凌晨三点。最后发现是我改公共类导致的。检讨书写到一半,隔壁老兵说了句话,让我从“背锅侠“变成了“改革者“

15. GD32E230定时器实战:基于TIMER5的1秒LED闪烁中断配置详解 本文详细讲解了如何在GD32E230微控制器上配置TIMER5定时器,实现精准的1秒LED闪烁中断。内容涵盖从时钟开启、参数计算、中断设置到服务函数编写的完整流程,重点解析了预分频值与周期值的配置方法,帮助开发者掌握硬件定时器的核心应用。 阅读详情

故事是这样的。

凌晨两点,手机震了。

群里炸了,生产环境挂了,用户支付页面全白屏,客服电话被打爆。技术总监@全体成员,所有人立刻上线排查。

我迷迷糊糊爬起来,打开电脑,心里一个咯噔。

昨天下午我改了一个公共类,就加了两行代码,优化了一个工具方法的性能。代码审查过了,测试也跑通了,晚上八点发的版本。

不会是我吧。。。

不会吧不会吧。

群里消息刷得飞快,运维在查日志,前端在排查接口,后端在回滚代码。我手心开始冒汗,偷偷去看了一眼我改的那个类,越看越心虚。

凌晨三点半,真相大白。

就是我改的那个公共类,导致了支付模块的一个边界条件判断失效。影响范围,全站支付功能,持续时间,5个小时,损失。。。不敢想。

我当时脑子一片空白。

群里安静了几秒钟,然后技术总监发了一句,明天早上开复盘会。

我知道接下来会怎样,背锅,写检讨,可能还要扣绩效。我打开Word,开始写检讨书,「由于本人的低级失误,导致线上故障,给公司造成重大损失,我深刻反省。。。」

写到一半,隔壁工位的老张发了条私信过来。

老张是团队里的老兵,写了十几年代码,经历过无数次线上事故。他说,别急着写检讨,明天复盘会上听我的。

第二天早上,会议室里气氛凝重。

技术总监让我先说说情况,我硬着头皮把事情经过讲了一遍,然后说,这是我的失误,我愿意承担责任。

话音刚落,老张开口了。

他说,这不是某个人的失误,这是我们整个防御体系的失效。

会议室里所有人都看向他。

老张打开电脑,投屏了一张图,上面画着好几层奶酪,每层都有洞。他说,这叫瑞士奶酪模型,是1990年英国曼彻斯特大学一个教授提出来的,专门用来分析事故为什么会发生。

他指着那些奶酪说,你看,我们的防御体系就像这些奶酪,每一层都是一道屏障。第一层是代码审查,第二层是自动化测试,第三层是QA测试,第四层是预发布验证,第五层是生产环境监控。

理想状态下,每一层都应该是完好无缺的,但实际上,每一层都有漏洞。

他看着我说,你改公共类的时候,代码审查为什么没发现问题,自动化测试为什么没覆盖到这个边界条件,QA测试为什么没测到支付场景,预发布环境为什么没模拟出这个问题,生产环境监控为什么没有及时报警。

当所有层的漏洞恰好对齐的时候,事故就发生了。

会议室里安静了几秒钟。

技术总监若有所思地点了点头,说,继续说。

老张切换了一张PPT,上面是一张表格,我一眼就看到了那个数字,100x。

他说,你们知道软件缺陷在不同阶段修复的成本差异有多大吗,需求分析阶段发现问题,成本是1,设计阶段是3到5倍,编码阶段是10倍,测试阶段是15到20倍,生产环境,100倍起步。

这次事故,我们付出了100倍的代价,但这不是某个人的错,而是我们的防御体系在前面四个阶段全部失效了。

他看向技术总监,说,我们应该问的不是谁犯了错,而是我们的系统为什么没有拦住这个问题。

技术总监沉默了一会儿,说,你说得对。

然后他看向我,说,这次事故,你不需要写检讨,但我们需要一份完整的根因分析报告,不是追责,而是找出我们防御体系的每一个漏洞,然后补上。

我当时鼻子一酸。

会后,老张拉着我去楼下抽烟。

他说,你知道Google怎么处理线上事故吗,他们有一套叫Blameless Postmortem的文化,翻译过来就是无责复盘。核心理念就是,事故发生后,聚焦查找根本原因,而不是追究个人责任。

他吐了口烟,说,你想想看,如果今天我们把你拉出来批评一顿,扣你绩效,下次再有人改公共类的时候,他会怎么做,他会隐瞒,会推责,会想尽办法证明这不是他的问题。

但如果我们把重点放在系统上,放在流程上,下次再有人改公共类的时候,他会主动提出来,这个改动影响范围有多大,我们需要加什么测试用例,需要在哪些环节加强审查。

这才是一个学习型组织应该有的样子。

我问他,那我们接下来应该怎么做。

他掐灭烟头,说,代码审查流程要改,公共组件的改动必须有至少两个资深工程师审查,而且要明确标注影响范围。然后自动化测试覆盖率要提上去,尤其是公共组件,必须有完整的单元测试,每次提交合并的时候必须通过所有测试,否则禁止合码。还有预发布环境要真正模拟生产环境,不能只是走个过场。另外生产环境监控要加强,关键业务指标要有实时报警。

他拍了拍我肩膀,说,这些都是我们这次事故暴露出来的问题,不是你一个人的问题。

回到工位,我打开那份检讨书,删掉了。

然后新建了一个文档,标题是「支付模块故障根因分析报告」。

我花了整整一周时间,把这次事故的每一个环节都梳理了一遍。代码审查环节,审查者没有意识到这是一个公共类,影响范围评估不足。自动化测试环节,这个工具方法的单元测试覆盖率只有60%,边界条件没有覆盖到。QA测试环节,测试用例里没有包含支付金额为0的场景。预发布环节,预发布环境的数据库配置跟生产环境不一致,导致这个问题没有暴露。监控环节,支付成功率的报警阈值设置得太宽松,5个小时后才触发报警。

五层防御,五个漏洞,恰好对齐。

报告写完后,技术总监组织了一次全员分享会,让我把这份报告讲给所有人听。

讲完之后,技术总监说,从今天开始,我们要建立一套完整的公共组件改动规范。公共组件必须有完善的单元测试,覆盖率不低于80%。公共组件的改动必须经过至少两个资深工程师的代码审查,并且要明确标注影响范围。我们要建立一个公共组件改动的checklist,每次改动都要过一遍。预发布环境要跟生产环境保持一致,包括数据库配置、中间件版本、网络环境。关键业务指标的监控报警要收紧,不能等到用户投诉了才发现问题。

他看着所有人,说,这些规范不是为了限制大家,而是为了保护大家。我们要建立的是一个学习型组织,而不是一个恐惧文化的组织。

会后,好几个同事过来跟我说,谢谢你把这件事讲出来,我们以前也遇到过类似的问题,但都不敢说。

我突然意识到,老张那句话的分量。

如果今天我们把这次事故定性为「个人低级失误」,那么下次再有人遇到类似的问题,他会选择隐瞒,会选择推责,会选择自保。但如果我们把它定性为「流程体系缺失」,那么下次再有人遇到问题,他会选择暴露,会选择分享,会选择改进。

这就是文化的力量。

三个月后,我们的公共组件改动规范已经完全落地了。代码审查通过率从原来的95%降到了70%,但线上事故率从每月3次降到了每月0.5次。自动化测试覆盖率从60%提升到了85%,预发布环境的问题发现率提升了3倍。

更重要的是,团队的氛围变了。

以前大家改代码都小心翼翼,生怕出问题,出了问题就互相推责。现在大家改代码更大胆了,因为知道有完善的防御体系在保护着,出了问题就一起复盘,一起改进。

有一次,前端的小李改了一个公共组件,结果在预发布环境发现了一个严重问题。他主动在群里@所有人,说这个问题如果流到生产环境会导致全站崩溃,然后详细分析了问题原因,并且提出了改进建议。

技术总监在群里发了个大拇指,说,这才是我们想要的文化。

我想起老张那天跟我说的话,他说,2024年亚马逊有个AI工具叫Kiro,一周内引发了4次最高级别事故,电商平台瘫痪了6小时。后来调查发现,不是技术问题,而是裁员1.6万人之后,运维团队减员,工程师超负荷工作,引发了连锁反应。

技术事故的背后,往往是组织层面的问题。

回到那个凌晨两点的夜晚,如果没有老张那句话,我可能会背着这个锅离开公司,然后在下一家公司继续小心翼翼地写代码,生怕再犯错。

但现在,我学会了用系统性思维去看待问题。

不是说个人不需要负责任,而是说,个人的责任应该体现在如何帮助团队建立更好的防御体系,而不是背锅和自责。

就像瑞士奶酪模型告诉我们的,事故的发生,从来不是因为某一层奶酪有洞,而是因为所有层的洞恰好对齐了。

我们要做的,不是去指责哪一层奶酪有洞,而是去填补每一层的洞。

这才是工程师文化的底色。

最后说一句,如果你的团队还在用「个人低级失误」来定性线上事故,那可能是时候引入「流程体系缺失」的视角了。

不是为了推卸责任,而是为了建立一个真正的学习型组织。

毕竟,我们写代码,不是为了背锅,而是为了创造价值。

Open3D 体素下采样【2026最新版】 体素滤波,博客长期更新,本文最近更新时间为:2026年4月11日。 阅读详情

相关推荐

Excel VBA | 一键批量生成对账单

根据对账单总表一键批量生成N家独立的客户对账单。

Microgoblins的博客 6987

让 AI 修一个 Bug,怎样避免它顺手改坏其他功能?

这个按钮偶尔会触发两次,帮我修一下。需求只有一句。等改动出来,除了按钮处理,还可能包含公共函数调整、默认值变化,以及一批看起来更整齐的代码。如果这些改动混在一起,审查时就得重新确认:哪些是修复必需的,哪些会影响其他入口,已有数据还能不能正常读取?我现在让 AI 修问题时,会把这几件事提前说清楚。上一篇写了功能改完以后怎么验收,这次聊聊怎样控制修复范围,以及拿到代码后先看什么。

qq_26483133的博客 104

简单说说Python中的pip如何换源

【安装包】:pip install 【升级包】:pip install --upgrade 【卸载包】:pip uninstall 【查看已安装的包】:pip list【搜索包】:pip search (注意:pip search功能在pip 10.0.0之后被弃用,建议使用其他方式搜索包,如访问PyPI官网或使用其他搜索引擎)

一捌柒的博客 2668

fix bug

当你通过 cpolar 域名外网访问时,请求到达你本机的 Apache 时,如果 Apache 的虚拟主机配置(如。)默认匹配了本地环境,或者反向代理透传了本地 Host,它依然可能表现为本地地址。$_SERVER['REMOTE_ADDR']也永远指向127.0.0.1。

huxyc的博客 72

虚拟机安装Centos8.5

Centos8.5

weixin_63604047的博客 960

全球半导体设备氧化钇熔射服务行业规模预测:预计未来六年CAGR为7.8%

本文将对“半导体设备氧化钇熔射服务”行业进行深度分析,探讨市场趋势的演变、核心竞争者的战略布局、供应链结构的内外特点、研发创新的最新进展、法规政策环境的适应性调整以及投资机会与风险评估。这一稳健的增长趋势表明半导体设备氧化钇熔射服务在电子行业中的重要性逐渐增强。由于全球对于高效、高精度和可靠的电子解决方案的需求增加,对能够提供这些功能的半导体设备氧化钇熔射服务的需求日益增长。由于半导体设备氧化钇熔射服务主要为就地服务型,其“配送”主要依赖于专业团队和技术设备的及时调配,强调服务的时效性和高质量。

CC1239777的博客 571

2026年Bug跟踪管理系统推荐:研发与测试协作的关键枢纽

回到最初的问题,2026年的Bug跟踪管理系统推荐,核心不是列出一串名字,而是找到一条适合自己组织的协作链路。中大型企业优先看闭环、测试深度、权限治理与部署边界;工程团队优先看代码关联和工作流效率;流程稳定的团队可以把自托管工具作为起点。选型时先定流程,再用真实Bug和真实用例做试点,并以数据复盘。能把研发与测试协作串起来的系统,才配得上“关键枢纽”这个位置。本文基于公开资料与产品文档整理,具体功能、部署方式与服务范围以官方说明和实际试用为准。更新时间:2026年11月。

zentao_pms的博客 176

基于C#的ASP.NET开发的党史学习网站课设

开展党史学习教育,就是要以史为镜、以史明志,把苦难辉煌的过去、日新月异的现在、光明宏大的未来贯通起来,在鉴往知来中砥砺前行,在乱云飞渡中把准航向,在凝心聚力中团结奋斗,共同创造新的历史伟业。登陆按钮与数据库进行连接,逻辑实现是如图3.1.3所示,自己定义一个SQL查询语句,将账号、密码放入SQL查询语句中,用sqlDataReader.HasRows语句进行逐一比较,找出结果,将用户名存入session并调用cookies,如果结果存在就关闭数据库,进行数据跳转,并弹出登陆成功的提示框,并关闭数据库。

m0_62408555的博客 975

不收 PR、让 Agent 自己修 Bug:3,900 Star 的 Rust UI 框架 Rune,为“AI 写界面“重新设计

Rune:GPU 渲染的 Rust 原生 UI 框架,headless 模式让 Agent 渲染 PNG、导出元素树、脚本驱动输入并自检——UI 框架第一次把可被 AI 观测作为架构需求。更激进的是:它不收 PR,贡献和维护两端都是 Agent。

话梅糖の优快云 Blog 596

Python爬虫实战:高效爬取CNKI知网文献数据的技术解析

本文将详细介绍如何使用Python最新技术构建一个高效的CNKI知网文献爬虫系统。我们将从爬虫基础知识讲起,逐步深入到高级反反爬技术、分布式爬取、智能解析等前沿内容。文章包含完整的代码实现,涵盖请求模拟、数据解析、持久化存储等关键环节,并特别针对CNKI的反爬机制提供解决方案。通过本文,读者将掌握构建专业级学术文献爬虫的全套技术栈。关键词:Python爬虫、CNKI爬取、反反爬技术、文献数据挖掘、Scrapy框架本文详细介绍了如何使用Python最新技术构建CNKI知网文献爬虫。

2201_76125261的博客 2075

英飞凌TC3xx之一起认识GTM系列(四)如何实现GTM与GPIO关联的配置(ATOM/TIM实例)

本文详细描述了针对英飞凌TC3xx芯片,如何运用GTM与GPIO之间的连接性,根据实际应用的需要对TOM和TIM相关寄存器进行配置。

无所适从的我的博客 3490

Bug跟踪管理系统怎么搭?从提交到关闭全流程最佳实践

搭一套Bug跟踪管理系统,真正要解决的不是把问题记下来,而是让每个问题从提交到关闭都有明确的责任人、进入条件和退出证据。,这三样决定Bug管理能不能长期跑下去。软件Bug的代价并不抽象。美国国家标准与技术研究院(NIST)2002年发布的一项委托研究测算,软件Bug每年给美国经济造成约595亿美元损失。对研发组织来说,越晚发现、越晚闭环,返工和沟通损耗越高。

zentao_pms的博客 194

从数据到行为的可控暴露:SAP RAP 中的 BO Projection 与 BO Interface 全面实践指南

本文系统梳理了ABAP RAP中BO Projection与BO Interface的定位与实现方式。BO Projection面向业务服务(如UI/API),通过CDS投影视图(as projection on)和行为定义裁剪字段与操作,实现差异化暴露;BO Interface则为EML代码和跨组件复用提供稳定访问层,使用transactional_interface标识。两者均遵循C_/I_命名规范,通过分层设计实现封装性、安全性和灵活性。文中结合真实案例展示了如何通过不同投影满足多角色需求,并详细说明

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 258

React 前端工程化在秒杀活动中的性能优化与 Bug 修

措施名称 | 实施成本 | 预期收益 | 风险等级 | |----------|----------|-----------|------------| | 使用 Redux Toolkit 管理状态 | 中等 | 提高可维护性和性能 | 中等 | | 引入 Suspense / Lazy Loading | 高 | 显著提升用户体验 | 高 | | 使用 Error Boundaries 捕获异常 | 中等 | 提高系统健壮性 | 中等 |在大型互联网企业中,秒杀与抢购活动是高频的业务场景之一。

wuchangjian的专栏 208

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

IINA BUG 正在播放的视频不显示原始文件名

视频播放时标题异常显示为录屏软件名,源于内部元数据干扰。通过在IINA中配置Lua脚本,强制使用文件原始名称作为媒体标题,实现播放列表正确显示。脚本路径为~/.config/iina/scripts/filename-title.lua,需在高级设置中添加scripts选项指向该文件。重启IINA后验证生效,不影响原文件与元数据。适用于macOS版IINA,可随时移除脚本恢复原行为。

烨之魅儿的专栏 266

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?

你正在把项目从 UniTask 迁移到 Unity 6 原生的 Awaitable。你觉得这很合理——就像 Task 一样,同一个 Awaitable 等多次又能怎么样呢?栏目:Unity Bug挑战 | 期号:NO.012 | 日期:2026-10-31 | 4星 · 中高级 | Bug挑战 | Unity 6+ · 异步编程 / Awaitable / 对象池。标签:Unity、Bug挑战、Awaitable、异步编程、死锁、Unity6、对象池、游戏开发、C#

crystal_WJT的博客 202

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

bug?nacos跑满内存!!!

手上一台 2 核 2G 阿里云服务器,用 docker-compose 搭微服务基础环境:Nacos、MySQL、Redis、RabbitMQ。本来以为拉起来就能用,结果直接翻车,Xshell 连不上服务器,折腾半天,终于找到根源。

2501_90507065的博客 244

【Unity Bug挑战】第10期 SerializeReference 内存泄漏之谜

你翻了一下代码,项目里大量使用了 [SerializeReference] 特性来做技能系统的多态序列化——大概有 200 多个不同的技能效果类,都挂在 SkillData 这个 ScriptableObject 上,通过 Addressables 动态加载和释放。Unity 的 Native 对象是引用计数管理的,而 C# 托管对象是 GC 管理的。SerializeReference 的多态对象,它们的 Native 侧表示是什么样的?托管堆内存 | 加载后释放,回到初始水平 | 正常,符合预期。

crystal_WJT的博客 690

Git 分支管理详解:从 HEAD、合并原理到冲突解决与 Bug 修复

现在再回到“功能开发到一半,线上突然需要修 Bug”的场景:先检查工作区,把现场提交到合适的功能分支或暂存进 stash;从需要修复的版本创建 Bug 分支,修复并验证后合入主线;回到功能分支恢复现场,再把主线修复同步过来,完成集成和测试;最后合入功能并清理临时分支。分支引用标记提交位置,HEAD 标记当前落点,提交推进当前分支,合并整合历史,未提交修改需要单独照顾。把这几条规则与提交图对应起来,分支管理就会从一组需要死记的命令,变成能够推导和解释的开发过程。

2601_94861874的博客 225

让 AI 修 AI 平台自己的 Bug:我用 SoduWork 给 SoduWork 提了一个 PR

签收是硬约束:打回后需求真的停在"进行中",源码里有对应的 blocker。能在真实仓库里做真实工程:读贡献指南、跑基线、TDD、多语言环境复现、处理 CRLF,产出一个能直接提交的 PR。返修体验好:打回意见会自动带进下一轮,并要求"在现有交付上返修"。权限沙箱设计扎实:只读白名单、受保护路径、授权指纹、指令文件防篡改。启动器负责任:数据隔离、没有默认密码、只绑本机。

努力是为了站在万人之中,成为别人的光 3669

ESP32-S3 语音玩具全链路打通实录:12 个坑、4 个字节级协议 Bug

ESP32-S3 语音玩具全链路打通实录:12 个坑、4 个字节级协议 Bug 一块 N16R8、一块 2.4 寸 ILI9341、一个 INMP441、一块 MAX98357A、一个裸喇叭,加上火山

lpfasd123的博客 253

嵌入式故障诊断-Bug002-局部大数组压栈高温必死机

摘要(148字): P2电动沙发控制器在高温下3~8分钟必死机,根因是overheat_report()中1024B局部数组栈溢出。常温不触发,NTC≥65℃时任务栈需求骤增至1984B,超1792B限额192B,踩坏堆内存。修复方案:静态化数组、分段发送、栈扩容至2560B,填充0xDEADBEEF监控水位。成本:RAM+768B,Flash+412B;收益:高温季0客诉,栈状态可量化。

u011697185的专栏 398
上一篇: 线上出了Bug,全组排查到凌晨三点。最后发现是我改公共类导致的。检讨书写到一半,隔壁老兵说了句话,让我从“背锅侠“变成了“改革者“
下一篇: 线上出了Bug,全组排查到凌晨三点。最后发现是我改公共类导致的。检讨书写到一半,隔壁老兵说了句话,让我从“背锅侠“变成了“改革者“
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值