ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从能跑就行到敢改敢重构:工程师成长的核心能力与实战经验

从能跑就行到敢改敢重构:工程师成长的核心能力与实战经验 1. 从“能跑就行”到“敢改敢重构”工程师成长的第一个分水岭刚入行那几年我特别迷恋一种状态代码能跑通功能能交付线上不出事就觉得自己已经“会了”。直到有一次接手一个老项目需要改一个看似简单的业务逻辑我打开文件一看三千多行代码挤在一个类里方法之间互相调用像蜘蛛网改一处崩三处。那一刻我才意识到能跑通的代码和能维护的代码之间隔着一条很深的沟。这条沟就是工程师之路上的第一个分水岭。很多人卡在这里好几年不是因为技术能力不够而是因为没有人告诉他你写的代码不只是给机器执行的更是给人读的。机器不在乎你的变量叫a还是userAge但三个月后回来改需求的你自己会在乎。我后来总结出一个很朴素的判断标准如果你写的模块换一个人来接手他能不能在不问你的情况下看懂并安全地修改如果答案是否定的那这个模块的质量就是存疑的。这个标准听起来简单但它逼着你去思考命名、分层、边界、注释、测试这些平时容易被忽略的东西。1.1 命名这件事比你想象的重要十倍我见过太多项目里充斥着data、info、temp、flag、handle这类词。单独看没问题但放在一起就灾难了。比如一个函数叫handleData参数是data返回值是result——请问这个函数到底干了什么你只能点进去一行一行读。好的命名应该做到“自解释”。fetchActiveUsersByRegion比getUsers多出来的那几个词就是给未来读代码的人省下的几分钟。我自己的习惯是变量名用名词函数名用动词开头布尔值用is/has/can开头常量全大写。这些不是什么高深规则但坚持三个月你的代码可读性会有肉眼可见的提升。还有一个容易被忽略的点命名的长度应该和它的作用域成正比。循环里用i没问题因为作用域就三行但一个类的成员变量如果叫x那就是在给所有人添堵。我见过一个项目里有个全局配置叫cfg每次改配置都要全局搜索cfg然后靠上下文猜是哪个配置效率极低。1.2 分层不是架构师的专利每个工程师都该懂很多同学觉得“分层”是架构师才需要考虑的事自己写个业务模块没必要。但实际情况是不分层的代码在需求变化时几乎必然崩溃。我经历过一个项目业务逻辑、数据库操作、HTTP 请求全混在一个函数里后来要换数据库发现改动量等于重写。最基础的分层其实就三层接口层负责接收和返回业务层负责逻辑编排数据层负责持久化。哪怕你只是写一个脚本也可以把“读数据”“处理数据”“写数据”拆成三个函数。这样做的好处是当处理逻辑变化时你只需要改中间那层两头的代码不用动。我自己的经验是每当你发现一个函数超过 50 行就应该考虑拆。不是机械地拆而是问自己这里面有没有可以独立描述的步骤如果有就把它抽成一个有名字的函数。这个过程本身就是在梳理逻辑很多时候拆着拆着就发现原来的设计有问题。2. 调试能力才是真正的硬通货从“猜”到“定位”的进阶路线如果说写代码是工程师的日常那调试就是工程师的照妖镜。我面试过不少人简历上写着精通各种框架但给一个线上问题让他排查他的第一反应是“我加几行日志看看”。加日志当然可以但高效的调试不是靠猜而是靠系统性地缩小范围。我刚工作时遇到一个 bug页面偶尔白屏没有规律。我花了整整两天加日志、改代码、重新部署最后发现是一个异步请求在特定网络条件下返回了空数据而前端没有做空值判断。两天时间就为了一个if (!data) return;。这件事让我明白调试的核心不是解决问题而是定位问题。定位准了解决往往就是几行代码的事。2.1 二分法排查最笨的方法往往最快当你面对一个复杂系统不知道问题出在哪一层时二分法是最可靠的策略。具体做法是在数据流经的中间位置打一个观测点看数据到这里是否正常。如果正常问题在后半段如果不正常问题在前半段。然后继续二分直到锁定最小范围。举个例子一个请求从前端发出经过网关、服务 A、服务 B、数据库最后返回。你可以在服务 A 的入口打日志看请求有没有到到了就看服务 A 调服务 B 的返回值再到了服务 B 就看数据库查询结果。每一步都在缩小范围而不是盲目地到处加日志。这个方法听起来简单但很多人不用原因是“觉得慢”。实际上盲目猜测加日志再重新部署的时间往往比二分法多得多。尤其是在分布式系统里一次部署可能就要几分钟二分法能帮你把排查次数从十几次降到三四次。2.2 日志不是越多越好而是要“可检索”我见过一些项目日志打得密密麻麻一个请求几百行真出问题时根本找不到关键信息。好的日志应该具备三个特征有唯一请求标识、有明确的层级、有可检索的关键词。唯一请求标识就是常说的 traceId从入口生成一路透传下去。这样你搜一个 id 就能看到整个调用链。层级是指日志要能区分是哪个模块、哪个步骤打的比如[OrderService][createOrder]这样的前缀。可检索的关键词是指日志里要包含业务相关的标识比如订单号、用户 id而不是只打“开始处理”“处理完成”。我自己的习惯是在关键路径的入口和出口各打一条日志中间只在分支和异常处打。这样既不会太多也不会漏掉关键信息。另外日志级别要严格区分DEBUG给自己看INFO给运维看WARN和ERROR给监控看。不要把什么都打成ERROR否则真正的错误会被淹没。2.3 学会读堆栈别只看最后一行很多同学看异常堆栈时只扫一眼最后一行“Caused by”然后就开始搜解决方案。但堆栈的真正价值在于调用链。从最上面你自己的代码开始往下看每一层是谁调用了谁往往能发现问题的根源不在报错的那一行而在更早的某个环节。比如一个空指针异常报错在service.process(user)但真正的原因可能是上游传进来的user本身就是 null。如果你只看最后一行可能会在process方法里加一堆判空但正确的做法是在上游找到为什么传了 null。我自己的习惯是遇到异常先看“Caused by”链找到最底层的那个原因然后从自己的代码第一次出现的地方开始往上读。这个过程能帮你理解框架的内部调用逻辑时间长了你对整个系统的运行机制会越来越清晰。3. 从“完成任务”到“解决问题”需求理解力的差距工作几年后我发现工程师之间的差距很多时候不在技术能力上而在对需求的理解力上。同样一个需求有人拿到就开始写代码有人会先问几个问题再动手。结果往往是前者做完后被返工后者一次通过。我刚工作时就吃过这个亏。产品经理说“加一个导出功能”我花了两天做完结果他说“我要的是导出当前筛选结果不是全部数据”。两天白干。后来我学乖了每次拿到需求先用自己的话复述一遍确认理解一致再动手。这个习惯帮我省下了大量返工时间。3.1 需求背后的真实意图往往不在字面上产品经理说“用户希望列表能排序”字面意思是加个排序功能。但真实意图可能是“用户找不到想要的数据”。如果是后者那排序可能不是最优解搜索或筛选才是。工程师的价值不在于实现需求而在于找到更好的实现方式。我现在的做法是拿到需求后先问三个问题谁用在什么场景下用解决什么问题这三个问题能帮你跳出“实现细节”看到需求的本质。很多时候你会发现有更简单的方案或者这个需求根本不需要做。当然这不是让你去质疑产品经理而是在理解意图的基础上提出更合理的方案。比如你可以说“我理解你是想解决用户找不到数据的问题除了排序我们也可以加一个搜索框成本差不多但效果可能更好。”这样的沟通方式产品经理通常会很乐意接受。3.2 把“技术语言”翻译成“业务语言”工程师容易犯的一个错误是跟非技术同事沟通时满嘴技术术语。比如“这个需要加个缓存”“数据库要加索引”“接口要改成异步”。对方听不懂沟通效率就低。我后来学会了一个技巧用业务结果来描述技术方案。不说“加缓存”说“这样页面加载会快很多”不说“加索引”说“查询时间能从三秒降到零点几秒”不说“改异步”说“用户点完按钮不用等结果好了会通知他”。对方关心的是结果不是实现方式。这个能力在跨部门协作时特别重要。你能把技术方案翻译成业务价值别人就更愿意配合你也更容易理解你的工作。时间长了你在团队里的影响力会明显提升。3.3 学会说“不”但要有替代方案工程师经常遇到的情况是需求方什么都想要但时间和资源有限。这时候直接说“做不了”会得罪人硬着头皮做又会延期。我的经验是说“不”的同时给一个替代方案。比如对方要求“这个功能明天上线”你可以说“明天上线的话完整版做不完但我可以先做一个简化版满足核心流程剩下的下周补上。”这样既没有直接拒绝又给了对方选择。大多数时候对方会接受这个折中方案因为他的核心诉求是“尽快看到东西”而不是“必须完整”。这个思路的本质是把“能不能做”变成“怎么做”。工程师的价值不只是执行还包括在约束条件下找到最优解。4. 持续学习这件事方法比努力更重要技术更新快这是事实。但“学不完”不是焦虑的理由而是需要方法的原因。我见过很多人今天学这个框架明天学那个语言看起来很努力但真正掌握的东西不多。问题出在学习方式上。我自己的经验是学习要围绕“用”展开而不是围绕“学”展开。什么意思就是不要为了学而学而是遇到问题时去学。比如你要做一个新功能需要用到某个技术那就带着问题去查文档、看示例、动手试。这样学到的知识是“活”的因为你有具体的应用场景。4.1 建立自己的知识索引而不是知识仓库很多人喜欢收藏文章、保存教程觉得“以后会看”。但实际上收藏了就等于学会了这是一种错觉。我自己的做法是不收藏只记录“索引”。比如我看到一篇好文章不会保存全文而是记下“某某问题可以用某某方案解决关键词是某某”。下次遇到类似问题我能通过关键词搜到那篇文章。这样做的好处是知识是“按需调用”的而不是“囤积”的。你的大脑不需要记住所有细节只需要记住“遇到什么问题该找什么方向”。这就像图书馆的索引卡你不需要把书都背下来但你知道哪本书在哪个架子上。4.2 输出是最好的输入我有个习惯每学一个新东西就试着写一篇笔记或给别人讲一遍。这个过程会逼着你把模糊的理解变清晰。很多时候你以为自己懂了但一写出来就发现逻辑不通或者一讲就卡壳。这就是“知识漏洞”暴露的时刻。写笔记不一定要公开发布自己看也行。关键是用自己的话重新组织一遍而不是复制粘贴。我自己的笔记里经常会有“这里我没搞懂先记下来”这样的标注。过一段时间回头看往往就明白了。另外教别人是最高效的学习方式。如果你能把一个东西讲给完全不懂的人听并且让他听懂那说明你真的掌握了。我在团队里经常鼓励新人分享不是为了考核而是因为分享的过程本身就是最好的复习。4.3 深度比广度更重要但深度需要广度来支撑刚入行时我觉得“什么都会”很厉害。后来发现真正值钱的是“某一方面特别深同时其他方面不拖后腿”。深度让你有竞争力广度让你能协作。我的建议是先在一个方向上扎下去做到团队里最懂的那个人。比如你选后端开发那就把数据库、缓存、消息队列、并发这些核心东西吃透。等你在这个方向上有足够的深度后再向周边扩展比如了解前端、运维、产品。这时候你会发现之前的深度让你学其他东西更快因为底层逻辑是相通的。最怕的是什么都学一点什么都不精。简历上写“精通 Java、Python、Go、前端、运维”面试官一问细节就露馅。与其做“万金油”不如做“T 型人才”——一竖是深度一横是广度。5. 团队协作中的那些“潜规则”没人明说但很重要技术能力决定你能不能进一家公司但协作能力决定你能走多远。我见过技术很强但跟谁都合不来的人最后要么被迫离开要么一直原地踏步。也见过技术中等但协作顺畅的人一路晋升。这不是不公平而是因为现代软件工程本质上是团队运动。5.1 代码评审不是挑刺是知识共享很多团队有代码评审但流于形式。评审的人随便看看就点通过或者只挑格式问题。这其实浪费了一个很好的学习机会。好的代码评审应该关注三件事逻辑是否正确、边界是否处理、有没有更好的写法。我自己的习惯是评审时先理解作者的意图然后问自己“如果是我会怎么写”。如果发现更好的方案不会直接说“你这样不对”而是说“我有个想法你看这样是不是更简单”。语气很重要目的是让代码更好不是证明自己更聪明。作为被评审的人不要防御性太强。别人指出问题先想想有没有道理而不是急着解释。我早期也有这个毛病觉得别人在质疑我的能力。后来想通了代码评审是免费的指导别人花时间帮你看代码你应该感谢。5.2 文档不是写给别人的是写给未来的自己的很多人讨厌写文档觉得浪费时间。但不写文档的代价往往在几个月后才会显现。我经历过一个项目核心逻辑只有一个人清楚他离职后整个团队花了两个月才把系统摸清楚。如果当初有一份简单的设计文档这个成本可以降到几天。我自己的做法是不写大而全的文档只写“关键决策记录”。比如“为什么选 A 方案不选 B”“这个字段为什么这么设计”“这个接口的边界条件是什么”。这些信息在代码里看不出来但对后来者极其重要。文档不需要多正式一个 Markdown 文件就行。关键是及时更新。我见过很多过时的文档比没有文档更糟糕因为它会误导人。所以我的原则是要么不写写了就要维护。如果没时间维护就在文档开头标注“本文档可能已过时请以代码为准”。5.3 主动同步进度别等别人来问团队协作中信息不对称是最大的效率杀手。你以为别人知道你在做什么其实别人完全不清楚。等到 deadline 才发现进度落后这时候已经来不及了。我自己的习惯是每天花五分钟同步进度。不用很正式一条消息就行“今天完成了 A 和 B明天做 C目前没有阻塞。”如果遇到问题也及时说“C 遇到一个技术难点可能需要多花一天我正在尝试方案 X如果不行会找你讨论。”这样做的好处是让相关的人心里有数。产品经理知道能不能按时上线测试知道什么时候可以开始测领导知道项目有没有风险。主动同步的人往往也是被信任的人。6. 职业选择中的几个关键决策我踩过的坑和想明白的事工程师的职业生涯里有几个节点特别重要选什么方向、去什么公司、跟什么人、做什么项目。这些选择的影响往往比努力更大。我自己的经历不算顺利踩过一些坑也想过一些事分享出来供参考。6.1 第一份工作成长比薪资重要我刚毕业时手里有两个 offer一个薪资高但做的是维护老系统一个薪资低但做的是新项目。我选了前者因为“钱多”。结果一年下来技术没怎么提升每天都在改 bug 和写重复代码。后来跳槽时发现这一年几乎白干了。不是说薪资不重要而是第一份工作的核心价值是“让你快速成长”。新项目、有经验的 leader、规范的流程这些东西在早期比多几千块钱重要得多。因为你前几年的成长速度决定了你后面十年的薪资天花板。当然如果两个 offer 的成长机会差不多那当然选钱多的。但如果一个明显能学到更多东西我建议优先考虑成长。年轻时的学习成本最低回报周期最长。6.2 跟对 leader比进大公司更重要大公司有光环但你每天打交道的是你的直属 leader。一个愿意教你、给你机会、帮你扛事的 leader比公司品牌重要得多。我遇到过两种 leader一种是把任务丢给你就不管了做不好就批评另一种是会跟你一起分析问题、教你方法、在上级面前帮你说话。后者让我成长最快。怎么判断一个 leader 好不好面试时问他“你最近一次帮团队成员解决问题是什么时候”。如果他能具体讲出来说明他关注团队如果支支吾吾那就要小心了。另外看团队成员的流失率如果一年换一批人那大概率有问题。6.3 跳槽不是解决所有问题的万能药我见过一些人遇到问题就想跳槽。跟同事合不来跳项目没意思跳薪资不满意跳。结果跳了几次后发现同样的问题在新公司又出现了。因为问题可能不在环境而在自己。我的建议是跳槽前先问自己这个问题换个环境能解决吗如果是公司制度问题、行业问题那跳槽可能有用如果是自己能力问题、沟通问题那跳到哪里都一样。跳槽应该是“追求更好”而不是“逃避现在”。另外跳槽的频率很重要。太频繁会让面试官觉得你不稳定太慢又可能错过机会。我自己的经验是每段经历至少待够两年这样你才能完整经历一个项目周期学到该学的东西。7. 那些没人告诉你但迟早会明白的事最后这部分我想聊一些零散的体会。它们不是什么系统性的方法论但都是我在实际工作中撞过墙才明白的。技术不是全部但技术是底气。你可以不会沟通、不会管理但技术必须过硬。因为技术是你的立身之本其他能力是锦上添花。先有深度再谈广度。身体是革命的本钱这句话不是玩笑。我见过太多工程师年轻时熬夜加班三十岁后各种毛病。每天抽半小时运动比多写两小时代码重要。这不是鸡汤是过来人的教训。保持好奇心但不要焦虑。新技术层出不穷你不可能什么都学。选一个方向深耕其他的了解即可。看到别人学新东西就焦虑只会让你什么都学不好。记录自己的成长。我有个习惯每完成一个项目就写一段总结做了什么、遇到什么问题、怎么解决的、下次怎么改进。几年下来这些总结成了我最好的简历。面试时不用编直接讲真实经历就行。善待身边的人。无论是同事、下属还是合作伙伴口碑是长期积累的。技术圈很小你今天坑了别人明天可能就在另一家公司遇到。靠谱是最值钱的品质。工程师这条路说长不长说短不短。有人走得快有人走得慢但只要方向对每一步都算数。希望这些经验对你有用也欢迎你分享自己的故事。
返回列表