一行代码引发的恐惧

从代码重构恐惧到安全重构实践:破解遗留系统维护困局 在软件工程领域,代码重构是提升系统可维护性和可扩展性的核心实践。其基本原理是在不改变外部行为的前提下,通过调整代码内部结构来改善设计、消除冗余并提升可读性。这一过程的技术价值在于显著降低后续维护成本、减少缺陷引入概率,并为团队协作与新功能开发奠定坚实基础。在实际应用场景中,开发者常面临遗留系统的高耦合模块、缺失的测试覆盖以及复杂的业务逻辑依赖,这些因素共同导致了普遍的“代码能跑就不要动”的保守心态。本文聚焦于如何通过建立有效的风险评估框架和测试先行的安全网,将重构实践系统化,帮助团队在保障系统稳定性的前提下 阅读详情

640?wx_fmt=jpeg

作者:大飞

来源:公众号“大飞码字”

1

我工作的前5年,都是从事基础系统研发相关的工作。做过后台的接入层,后台的存储系统,RPC框架。说来不怕你笑话,那个时期里面,我对代码一直有一种恐惧感。这种恐惧是怎么来的呢?且让我慢慢说来。

我们所构建的基础系统,都是使用在亿级甚至十亿级用户产品的业务系统之上的。从客户端(前端)到后台业务逻辑层,再到基础架构层,所写的代码是跑在整个调用链路的最后端的。

你可以认为,几乎每个用户的每个请求都会跑到我们写得那部分的代码。

这个对系统带来的影响是: 一,代码出问题后,影响的用户范围会很大;二,在这亿级甚至十亿级用户量的情况下,每天所带来的请求可能是千亿级,万亿级的,在如此庞大请求量的情况下,几乎各种奇葩的异常,你都会遇到,代码要极其的健壮,一个小异常没处理好就会带来大麻烦。

这让我想起来,我们故障时候的情形。

几年前,我们每做完一次版本变更,晚上基本都会睡不好,担心变更的代码有问题。对手机的报警短信特别敏感,一有风吹草动,立马就会打开电脑vpn看看,即使是在深夜凌晨的时候。

我自己有个习惯,每次变更完,都要间隔几个小时去看看监控曲线和日志,看看有没有异常的苗头,一旦发现有不对劲地方,就会立即着手排查,直到确保没有问题为止。

不过即使如此,还是不可避免的会出现问题。

半夜两三点的时候,你的手机突然响起,报警语音机器人跟你说,你有一个重要的监控曲线出现异常,请查看。然后你的血压立马升高,心跳加速,你从床上,一跃而起,打开电脑,连上公司的VPN,立马着手排查起来。

几分钟后,QA(质量工程师)电话过来,告知你,这个故障目前已经上报到部门故障系统,目前影响的用户有XXX的数量,请你加快处理的速度,然后你的心跳再次加速。

半小时后,终于有了眉目,这时,你的leader, 电话过来,询问你是怎么回事,大概还需要多长的时间,才能处理完毕。待你语焉不详地回复完你的leader, 你又开始埋头,一行行的排查故障。

一个小时后,你终于,将问题定位出来,执行了故障处理方案,例如回滚新的代码,或者屏蔽某些机器等。你才终于有了喘息的时间。

(ps: 这里正确的流程是,出问题后,立马回滚代码,但存储系统因为数据的关系,在没有确定原因前不太敢回滚,怕对数据有影响)

你赶紧爬上床去,睡上2-3个小时,因为第二天还要早起,赶到公司,去处理故障的后遗症,数据损坏和数据错乱。

2

那个时期,我们写代码都是特别小心的,变更,更是极度的谨慎。所以使得自己对代码变更有了一种焦虑和恐惧的心理。至少在那时候,写代码不是一件轻松的事情。

这个事情,我现在回过头来看。你可以认为有一部分是人的原因,但仔细的想想,写代码不出bug ,几乎也是极难做到,所以这里在研发流程上,其实也是有缺失的。

前期因为业务发展太快,团队的整体人力跟不上,所以,一开始很多流程,都是很原始的,那时候,是想做但客观条件不允许。

后来,业务稳定了,流程就规范了不少。比如引入了coverity的代码检查,也推行过测试用例覆盖,持续集成等。

但最终,并不是所有的流程都延续了下去。比如,代码测试用例覆盖,有的团队到后面就放弃了,需求变化太快,测试用例成本太高。

coverity倒是自动化程度高,没啥人力投入,执行了下来。

但我相信不是所有的公司,所有的团队,都会有这种规范的流程。一个是研发流程成熟度建设的问题,但除此,还有成本,业务迭代速度。在互联网,产品高速迭代的时候,产品都还没有存活下来,成熟流程就更不太可能有了。

综合来看,一种规范,但相对较重的研发流程的建立,应该也是根据具体情况而定的。需要考虑产品的形态,产品迭代的速度,团队的人力预算成本,产品的生命周期等等。当然,无论怎么说,反正这不是个人可以决定的事情,如果你所在的团队有完善的研发流程,那是最好的事情,但如果没有那么完善,自己又能够做些什么呢?

我的经验来看,以下的一些措施,对于个人而言也有不错的效果

测试驱动的开发(TDD)

有段时间,因为业务高速发展,对性能的要求不断提高,存储模型也跟随着不断迭代改进,所以那段时间的代码修改是比较多的,那个时间的焦虑感也特别重。

我记得是在 《重构:改善既有代码的设计》中了解到TDD的。

简单来说, 就是先构建测试用例,再开始写你的功能代码。在设计测试用例之前,你需要先定义好模块对外的接口,包括接口的种类,参数,返回值等。

然后,你针对定义好的接口,编写测试用例。这过程中,你可能会发现接口设计不合理的地方,也需要随着修改。待你测试用例写完,基本你的接口也被修改的比较好了,所以TDD还能改善你的接口设计。

后续再为每个接口实现特定的代码逻辑。

我当时将这种方法运用到了一个磁盘存储引擎中,发现相当不错。我特地花了一周左右的时间写测试用例。后面,每天实现部分的功能后,都立马跑测试用例,每次跑完通过,你的心里都有稳的一B的感觉。有种妈妈再也不担心我写的代码有bug,被被老板叼,导致扣工资了。

因为有了完善的测试用例,而且随着你测试用例不断的增加和覆盖,你的信心会越来越足,焦虑自然减少了很多。

不过这种方式,比较适合底层的系统和核心稳定的系统。对于需求多变的系统,构建测试用例的人力付出太大,而且需求一变,已有的测试用例可能失效,导致投入产出比不够高。

灰度发布

简单来说,就是一个特性要上线的时候,不是一下就开放给所有的用户使用。有点像产品上的内测,只不过是用在技术上。

比如我新增加了一个产品需求,例如就微信里面的 “看一看”入口,不是一开始就对所有用户开放的。

首先会上线一个新的客户端版本,代码逻辑已经预埋,但设计了一个开关,对所有用户都是关闭的。前期,可能会找个千分之一,甚至万分之一的用户(随机或者特定的用户群体),让他们使用。

这过程中,收集各种log ,监控,用户的反馈。来确认和fix 系统存在的各种问题。一般经过两三周后,如果没有大问题,就会进一步的放开使用的用户。比如变成百分之一,十分之一,一直迭代,直至覆盖全部用户。

灰度这个思想,在互联网是特别常用的。客户端,前端,后台都可以使用。比如后台,上线一个新修改后,也不是一下就开放给所有用户。而是按照某种规则,例如以QQ用户为例,可能是这种规则

计算Hash值(QQ号) % 1000 <= 灰度用户的比例(取0 --- 1000)

放量的最小力度就是千分之一,被灰度到的用户,看到新功能,没灰度到的用户不受影响。

这招用在新功能,用在系统优化,代码重构上都很不错。

付出的额外成本不大,有的公司有自研的灰度系统,那最好。没有的话,在重大且没有把握的功能上,自己加上几行灰度控制代码也不难。

监控和log

监控和log不是什么新鲜的东西。

工作第一年,我们的技术总监在一次会议上跟我们说:你写完的代码是死的,只有在线上跑的代码是活的。监控和log(特别是监控),就像是你代码的体征信息,随时反应着你代码在实际环境中的运行情况,要高度的重视。

这段话,在后面,我深有感触。通过完善设计的监控和log,预先发现了很多的问题,也避免了很多,或代码bug,或系统设计缺陷导致重大故障。

后面,监控和log的设计,也成了我们方案设计的一部分。一般都会在方案最后,加上必须的监控的点和log点,例如请求数,成功数,失败数,各种异常数,极端逻辑执行次数等等。

你应该要意识到监控和log的重要性,而且应该要花时间特别地设计。

经过良好设计的监控和log,能发挥的价值,是那种凭感觉随便加的监控log不可比拟的。

双写,双读验证

这招,新业务代码用的不多。更多用于基础系统或者核心系统的优化和重构上面。而且有前置条件,需要一个操作可以重复执行(例如只读操作和幂等的数据操作)。

简单来说,就是将新旧代码,划分为两个流程(两个接口),上线到实际环境,然后在同个模块里面调用。

一个请求进来后,两个流程分别执行一次,逐字节做对比(例如 memcmp)新旧流程的结果。新流程的结果只用于对比,返回得依旧是旧流程的结果,所以不影响线上业务。

如果对比失败,就可能存在异常,要查找并解决,在实际环境跑了几天后,都没问题,就可以采用灰度的方式,进一步放量。不过,一般业务不常使用,在基础系统上使用比较多,这里就不展开了。

其他

另外,对于客户端,还有热补丁机制,客户端log收集系统等。不过这种需要的开发量比较大,一个人不一定可以搞定,可能需要有个小团队来完成。

最后

软件工程是个庞大的话题,我也没能力论述这么大的话题。这里给大家讲了个以前的故事,并且分享了我常用的一些低成本,但可以提高线上代码质量的方法,给大家参考参考。大家有好的做法,也欢迎在留言里分享出来。


你可能会喜欢

关于老刘和码农翻身

我是一个线程

我是一个Java Class

面向对象圣经

TCP/IP之大明邮差

CPU阿甘

负载均衡的原理

一个故事讲完HTTPs

编程语言的巅峰

Java:一个帝国的诞生

JavaScript:一个屌丝的逆袭

C语言:春节回家,我发现只有我没有对象

640?wx_fmt=jpeg

Python一行代码能做什么,30个实用案例代码详解 Python语法简洁,能够用一行代码实现很多有趣的功能,这次来整理30个常见的Python一行代码集合。1、转置矩阵2、二进制转十进制103、字符串大写转小写。 阅读详情

相关推荐

听觉线索依赖恐惧条件反射的Matlab实现详解

Matlab(Matrix Laboratory的缩写)是一种高性能的数值计算环境和第四代编程语言,由MathWorks公司开发。它广泛应用于工程计算、控制设计、信号与图像处理、数据统计分析等领域。Matlab之所以受到科研人员的青睐,原因在于其强大的计算能力、丰富的函数库、便捷的矩阵运算和直观的图形用户界面。主要功能包括但不限于:数值计算:提供广泛的数学函数,支持矩阵运算、线性代数、统计分析等。图形绘制:能够创建二维、三维图形以及动画,帮助科研人员直观展示数据。

weixin_29301059的博客 892

20 个非常有用的 Python 单行代码

有用的 Python 单行代码片段,只需一行代码即可解决特定编码问题! 在本文中,我将分享20 个 Python 一行代码,你可以在 30 秒或更短的时间内轻松学习它们。这种单行代码将节省你的时间,并使你的代码看起来更干净且易于阅读。 1 一行 For 循环 for 循环是一个多行语句,但是在 Python 中,我们可以使用列表推导式方法在一行中编写 for 循环。以过滤小于250的值为例,查看下面的代码示例。

m0_59162248的博客 1084

手把手教你设计MTBF加速寿命试验:从阿伦尼斯模型到卡方计算(含Excel模板)

本文详细介绍了如何设计MTBF加速寿命试验,从阿伦尼斯模型到卡方计算,帮助工程师在合理时间内获得准确的MTBF数据。通过工业电源模块的实例演示,涵盖活化能确定、温度应力设计、样本量计算及数据记录规范,并提供Excel模板实现自动化计算,显著提升测试效率。

weixin_42563415的博客 541

为何程序员在运行代码时会产生“恐惧感”

这种适度的紧张感并非全然负面,它能促使程序员更加严谨对待自己的工作,通过反复调试、优化代码来减少错误发生的可能性,从而提高工作效率和软件质量。程序员在编码过程中,尽管已经进行了逻辑推敲和错误预判,但他们深知计算机执行的严格性和无情性,任何细微的语法错误、逻辑漏洞或是边界条件考虑不周,都可能导致程序无法正常运行。再者,编程语言的复杂性和不确定性也加剧了这种感觉。尤其在处理大型系统或新颖技术问题时,由于系统的耦合性和并发性等特性,程序员难以完全预测代码的实际运行效果,这也成为引发“运行恐惧”的重要因素。

用心关注科技未来 827

RS485接口EMC设计:三级防护与滤波隔离方案

RS485总线在工业现场面临共模噪声、差模脉冲和地电位差三大电磁兼容挑战。通过三级防护架构(气体放电管、PTC热敏电阻、半导体放电管)实现能量梯次泄放,结合共模扼流圈和滤波电容形成完整防护链。该方案经实测可将6kV浪涌下的通信稳定性提升90%,特别适用于工业自动化、电力监控等严苛环境。设计要点包括防护器件选型计算、PCB分区布局及地处理策略,其中GDT通流能力与TSS箝位电压的配合是关键。

weixin_33419305的博客 525

【C++】 详解 lower_bound 和 upper_bound 函数(看不懂来捶我!!!)

这两个函数是我在 LeetCode 上做题见到,看到不熟悉的函数 lower_bound 和 upper_bound让我感觉很难受,于是在C++ 官网去学习,例子就一个是最基础的,我看明白了。虽然是两个函数的接口就两个,但是有时候看别人使用的时候,里面参数还可以放不同的仿函数,我懵逼了。就去网上搜,但是大家讲解的都是它的第一个接口。我只能再把文档一遍一遍过,代码一遍遍的尝试,调试。最终通过查阅资料将其总结如下。

weixin_45031801的博客 9万+

33个非常实用的JavaScript一行代码

33个非常实用的JavaScript一行代码

DWForYou_DJF 1153

思岚A1 上手教程

前言 寒假在家闲着也是闲着,索性就向是实验室借了一个思岚 A1激光雷达,来进一步完成自己的实验室实习项目。经过一个月在Linux上和ROS上的摸爬滚打,我已经对机器人开发和SLAM有了初步了解,现在就写个上手教程吧(以防自己以后忘了)。 Basic Support 硬件 一台电脑 思岚 A1激光雷达 软件 安装Virtual Box虚拟机 在虚拟机安装Ubuntu 16操作系统 在Ubuntu 16搭建ROS kinetic 简要步骤 1.现在w..

ajxdhe的博客 6384

为什么怕写代码(自己的亲身经历)

下班了,坐在工位不知不觉就又想起了刚开始接触java编程的日子,其实我觉得这个毛病也不在少数人,因为在我上学的时候班里面分组做项目,基本都是什么情况呢? 一人做好,全部就可以交任务了,最后导致了如果代码某个地方出错了,全班90%的都出错了,归根结底就是自己学习动力不足,而且基本都是1个老师带30+人。很难一个一个去手把手的去教每一个人,好吧,前面有点太伤感了, 让我感觉都鼻涕眼泪一直流了。 下面说...

kitonGao的博客 2925

Python爬虫实战:公共资源交易平台招标数据采集实战 - 从零构建企业情报系统(附CSV导出 + SQLite持久化存储)!

我长期专注 Python 爬虫工程化实战,主理专栏 👉 《Python爬虫实战》:从采集策略到反爬对抗,从数据清洗到分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上。

喵手的博客 1288

32、生物信息学中的符号、缩写及相关概念解析

本文详细解析了生物信息学中常用的符号、缩写及相关概念,涵盖概率理论、函数表示、模型结构、图与集合、维度参数、神经网络、隐藏马尔可夫模型、双向架构、语法系统、系统发育树、微阵列分析以及核方法与支持向量机等多个领域。通过表格和mermaid流程图的形式,系统梳理了各类符号的定义与应用场景,并介绍了常见缩写的全称与意义。文章旨在帮助研究人员准确理解生物信息学中的基础术语,提升对基因表达分析、序列建模、机器学习等技术的理解与应用能力。

rrr55的博客 146

人间真实!一行代码引发的恐惧

作者 | 大飞 本文经授权转自大飞码字 我工作的前 5 年,都是从事基础系统研发相关的工作。做过后台的接入层、后台的存储系统、RPC 框架。说来不怕你笑话,那个时期里,我对代码一直有一种恐惧感。这种恐惧是怎么来的呢?且让我慢慢道来。 我们所构建的基础系统,都是使用在亿级甚至十亿级用户产品的业务系统之上的。从客户端(前端)到后台业务逻辑层,再到基础架构层,所写的代码是跑...

程序人生的博客 2242

【Dify】知识库智能检索应用

本文介绍了一个基于大语言模型的知识库检索系统,实现从自然语言提问到智能回答的自动化流程。该系统通过知识检索节点定位相关信息,利用重排序模型优化结果,最后由大语言模型生成自然语言答案。核心模型包括InternLM2-7B和BCE重排序模型。工作流程包含输入问题、检索重排序、智能生成和答案输出四个阶段,适用于企业知识管理、客户支持、教育培训等多种场景,能显著提升信息检索效率和准确性。文章还提供了相关开发文档链接,涵盖AIGC工具平台搭建、常见问题解决等内容。

Mr数据杨 1000

恐惧是因为欠缺的庖丁解牛

维度关键点本质对自身资源不足以应对挑战的客观预警核心机制预测误差放大、威胁检测、资源审计五维欠缺信息、能力、准备、支持、确定性转化策略命名恐惧、最小化补缺、构建安全网、暴露疗法主要价值指引成长方向,驱动资源积累,促进系统升级PHP 隐喻公式终极心法恐惧的本质,是“成长的邀请函”。它标记了你的边界,也指明了你的路径。它在索取中见匮乏,在填补中见丰盛。于缺口中见方向,于行动中见圆满;以资源为尺,解情绪之牛,于生命进化中,求完整之真。行动指令诊断。

长风破浪会有时的博客 362

osgEarth 球上显示地形数据库

osgEarth 球上显示地形数据库 本文展示了一种由DSM和DEM得到Osgb工程,并在osgEarth球上显示的方法。其中DSM、DOM到Osgb工程的转换由VPB(VirtualPlanetBuilder)来实现,并采用Model图层将Osgb工程在球上显示。 本文主要解决一下问题: VPB编译 VPB生成地形 地形在球上显示 目录 1 前言 2 VPB编译与使用 3 地形在osgEarth球上显示 内容 1 前言 VirtualPlanetBuilder是一个开源代码工具,用于根据

CPWWHSU的博客 2436

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

为什么程序员都怕 “改一行代码,整个系统崩了”?看完原理懂了

隐藏依赖的存在,让代码修改的风险变得难以预测。例如,最初设计的用户模块只负责用户信息管理,后来开发的统计模块为了方便,直接读取用户模块的数据库表结构,而非通过接口获取数据,这种 “非正式” 的依赖在当时可能无人在意,但当用户模块修改表结构时,统计模块就会因为字段不匹配而失效,且开发者可能需要花费大量时间才能找到问题根源。例如,A 模块直接调用 B 模块的内部变量,而非通过规范的接口,当 B 模块修改该变量的名称或类型时,A 模块就会因为无法找到对应变量而崩溃,哪怕这次修改本身对 B 模块的功能毫无影响。

2503_92849134的博客 524

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

恐惧会让你成为一个更糟糕的程序员

有没有人写过关于恐惧+编程方面的文章?(这种害怕做出重要改变的思想如何使你成为一个更差的程序员?) 以及 我觉得在小心翼翼(优++)和恐惧(让你不敢去做一些必要工作)之间有一条重要的分界线。 然后各种有趣的讨论接踵而至。 我发现,当我们害怕担忧的时候,思想就会趋于保守,也不敢做任何改动,生怕有个万一。但是这会导致软件变得更糟!它实际上是另一种灾难。如果你害怕做出任何改变

dm菜鸟编程的专栏 679

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

程序员的恐惧……

我见过一些人,他们通常强调尽可能简单,但若事情突然变得比他们预期的还要简单很多,他们就开始感到不适,甚至拒绝接受这种简单,其实即使事物的发展方向和你的前进方向相一致,但如果发展速度大大超越了你,仍然有可能引发你内心对失控的恐惧。----引用自我眼中的C# 3.0 (Allen Lee) 每一个程序员都希望工具能够更进步,能够更好的服务自己,好让自己少加一些班,但是一旦它真的变好,好到自己已经...

weixin_30617695的博客 71

冲动控制与人工智能决策:如何应对人工智能引发的恐惧心理

1.背景介绍 随着人工智能技术的不断发展和进步,人们对于人工智能带来的恐惧心理也日益增强。这种恐惧主要体现在人工智能可能导致的冲动控制问题和人工智能决策带来的不确定性。为了应对这些问题,我们需要深入了解冲动控制和人工智能决策的原理,并开发出有效的算法和方法来解决这些问题。 在本文中,我们将从以下几个方面进行探讨: 背景介绍 核心概念与联系 核心算法原理和具体操作步骤以及数学模型公式详细讲解...

AI天才研究院 815
上一篇: 提交代码前问自己七个问题!(福利:留言送《统计之美》)
下一篇: 这些优秀的年轻人
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值