首页 / 资讯中心 / 文章详情

工程实践笔记:Git、Debug、测试与Linux实用技巧

工程实践笔记:Git、Debug、测试与Linux实用技巧 ★ FEATURED ARTICLE
开场四个绕不开的日常带过几个项目、看过无数遍代码评审之后我慢慢发现一个规律真正卡住人的往往不是算法多难、架构多玄而是日常工具和流程里的各种小问题。Git 操作失误回滚不回去、Bug 改了一下午没找到根因、测试跑绿了上线就翻车、Linux 排查半天才发现是磁盘满了……这些场景几乎每个开发者都遇到过。这个系列笔记的第一篇我就把 Git、Debug、测试、Linux 这四个最常打交道的方向放在一起聊聊我在实际工程里沉淀下来的方法和踩过的坑。内容不追求面面俱到只挑实践里真正有用的部分展开适合刚工作一两年、想把手头的开发流程梳理得更规范的同学也适合带新人时直接拿来当参考。这篇文章里的每一条都来自真实项目里的教训和复盘不是教科书式的罗列。有的地方我会给出具体命令有的地方会给出判断思路读完你至少能带走几套可以直接套用的操作模板。1. Git 使用习惯从“能用”到“用对”的进阶路径1.1 提交信息规范从源头减少沟通成本很多人不把提交信息当回事觉得代码写对了就行。直到某天线上出了问题git log 一看全是“fix bug”“update”“修改”你根本不知道哪个提交对应哪次变更整个历史跟没写一样。我在团队里推过一个很简单但效果很明显的规范提交信息统一采用 type(scope): subject 的格式。feat(user): 增加用户头像上传接口 fix(payment): 修复订单状态重复更新问题 docs(readme): 补充本地开发环境搭建步骤 refactor(utils): 抽取公共日期格式化函数type 控制类型scope 标注是哪个模块subject 用一句话说清楚这次改动做了什么。这么做最直接的好处是看 git log 跟看变更清单一样不需要打开代码就能知道历史脉络。配合 CI 里的提交信息校验比如用 commitlint格式不合法直接拒绝提交整个仓库的日志会变得非常干净。标题里只写“改了什么”还不够。我还会额外要求重要提交在正文里写明“为什么这么改”。为什么比改了什么更难保留——代码以后看得到但当时的决策背景靠记忆是撑不过三个月的。举一个典型的场景你发现某段代码性能有问题优化后快了十倍但引入了对某个运行时版本的最低要求。如果不写进提交正文三个月后有人升级环境导致线上故障排查起来会绕很大的弯。1.2 分支策略小团队最实用的方案一说到分支管理就有人搬出复杂的多人 Git Flow。但就我的经验而言三到十人的团队用主干加功能分支的方式就已经很够用了。核心就两条main 分支永远保持可发布状态任何新功能都在独立分支上开发合并前必须过 CI 和代码评审。git checkout -b feat/user-avatar # 开发、提交、推送远端 git push -u origin feat/user-avatar # 在仓库界面发起 Merge Request / Pull Request功能分支的生命周期尽量控制在几天以内最长不要超过一周。分支活得太久合并时的冲突成本和心理负担都会急剧上升。如果某个需求实在太大我习惯先用一个主线分支把骨架合并进去再拆分小分支逐步完善。每个合并进 main 的提交都应该对应一个能独立工作的状态而不是半成品。很多人忽略的一点是分支命名。命名里带上需求编号或者 Jira/工单号比如 feat/user-avatar-12345好处是分支和需求能直接对应排查时一条命令就能找到关联的提交。团队里约定清楚时间越长价值越大。1.3 冲突解决的实操思路冲突是 Git 日常操作里最烦人的一件事但说到底它的本质并不复杂两个分支改了同一处代码Git 不知道该听谁的。面对冲突很多新手的第一反应是慌然后看到一堆 标记就不知道从哪下手。我的做法是分三步走。第一步先理解冲突双方各自主张的语义别急着改。把冲突片段当成两个版本对比来看往往会发现两边改的其实是不同层面的东西只是恰好落在相邻几行。第二步是判断保留哪边、删掉哪边、还是两边都要这完全取决于业务意图不是技术问题。很多时候两个改动其实都要保留只是需要调整一下顺序或者重新组织逻辑。第三步是解决完冲突之后重新编译或跑一遍相关测试确保没有破坏任何一边的行为。还要提一个减少冲突频率的技巧多执行 git fetch少用 git pull 直接合并。每次开始工作前先把远端最新的 main 拉下来在自己的分支上做 rebase让变更基于最新的代码。虽然人们总觉得 rebase 听起来高级但它其实就是把变更重新放到一个新基点上用来保持分支历史线性减少后面合并时一次性爆出大量冲突的可能。需要说明的是rebase 更适合自己还没推送到远端的本地分支不要随意对共享分支做强制变基操作。1.4 出事之后的补救手段Git 最吓人的不是出错而是出错之后不知道能不能恢复。先说两个最常用的补救命令git revert 和 git reset。如果你的错误提交已经推到远端或者被别人拉下来继续开发了绝对不要用 git reset 去强行改写历史。正确做法是 git revert它会产生一个新提交把之前的改动反向撤销历史是完整的所有人后续拉取都安全。git revert 8f3a2b1如果你的错误提交还没推远端只是想重做最近几次提交git reset 更方便。区分两个常用参数soft 只移动 HEAD 指针工作区代码还在hard 会连工作区一起清空属于破坏性操作用之前想清楚。git reset --soft HEAD~2 # 撤销最近两次提交改动保留在暂存区 git reset --hard HEAD~2 # 撤销最近两次提交改动直接丢弃还有两个日常经常用到但容易被忽略的技巧。git stash 可以临时存放工作区的改动切换分支或者拉取代码前做个 stash事情办完再 pop 回来。git reflog 是最后的救命稻草就算你 reset --hard 误删了提交只要提交对象还在本地仓库里reflog 里就能找到对应的哈希值再 check 出来就能恢复。我靠这个操作救回过一次同事误删的整整两天的工作量这也是为什么我强烈建议每个开发者至少知道 git reflog 的存在。2. Debug 排查先定义问题再动手修2.1 复现是第一步也是最容易被跳过的Debug 最常见的失败模式是问题还没稳定复现就开始猜。猜中了叫运气好猜不中就在代码里到处打日志、加判断、改业务逻辑忙活半天发现根本不是那回事。我的经验是动手改代码之前先逼自己回答三个问题。第一这个 Bug 出现的条件是什么是必现还是偶发哪个用户、哪个操作路径、什么输入数据、什么环境版本第二预期行为是什么代码本来应该输出什么、返回什么、界面应该怎么展示第三实际行为是什么和预期差在哪里差多少如果这三个问题里有一个答不上来说明信息收集还不够现在不是修 Bug 的时机。复现的重要性在于它能把一个模糊的“坏了”变成一组确定的输入输出关系。很多偶现问题排查困难是因为你连触发条件都没找全。之前有一次线上偶发超时问题我让测试同事连续跑了几天用例都没复现最后发现是只在某台特定配置的机器上才会出现条件里必须包含特定 CPU 型号和特定并发量。一旦复现条件明确了定位就是时间问题。2.2 二分定位法把搜索空间快速变小面对一段几千行、逻辑复杂的代码从头到尾一行行读是效率最低的方式。工程上更实用的方法是二分定位把问题的搜索空间不断对半切割快速逼近出问题的具体区域。举个实际例子一个数据导入功能某个字段导入后总是丢失。与其全文查代码我先在入口处打日志确认原始数据还在再到中间转换层确认数据经过处理后是否还在再到数据库写入前确认最终值。三步下来几步之间的代码就是重点嫌疑区然后在这个区域里再按同样的方式逐层缩小范围。整个过程和玩“猜数字”一样每次排除一半的可能性十几步就能锁定到具体行。对付“之前好好的现在坏了”这类回归问题git bisect 是最强的工具。你只要告诉 Git 哪个提交是好的、哪个提交是坏的它会自动通过二分法拉取中间版本每到一个版本你只需要跑一次复现脚本回答“还好还是坏了”几步就能精确定位到引入问题的那个提交。git bisect start git bisect bad # 当前版本是坏的 git bisect good v1.2.3 # 已知某个版本是好的 # Git 会检出一个中间版本按结果持续标记 good / bad git bisect reset # 排查结束后退出这个方法有两个前提你有一份能快速判断好坏的测试脚本以及二分范围内的提交数量是合理的。如果几百个提交里全是半成品bisect 过程中可能会出现大量编译不过的情况这时候先把范围缩小到从上个稳定版本之后的功能提交会更现实。2.3 日志质量决定排查效率调试时日志不是打得越多越好而是每一行都要有信息量。只写一句 logger.error(error) 等于没写根本不知道哪里错、错在哪里、影响什么。我见过的优秀日志格式大概长这样2025-06-18 10:23:45.112 ERROR user-service [requestId8f3a2b1] 订单状态更新失败, orderId10086, currentStatusPENDING, targetStatusPAID, 错误详情: 库存扣减超时拆开来看一条合格日志至少要包含五个要素时间、级别、模块、上下文标识、错误内容。上下文标识里 requestId 是我特别想推荐大家配置的东西它能在微服务或跨系统调用场景里把一串日志串成一条完整的时间线。在某次线上排查里用户反馈“操作偶发失败”单看每个服务的日志都是正常的但把所有服务的日志按 requestId 拼起来之后立刻发现是下游服务特定时间段超时导致的雪崩。还有一个被低估的习惯日志里不要打敏感信息。手机号、身份证号、密码、Token 这些字段处理不好就是安全事故排查时宁可多查一步也不要直接打全明文。另外错误日志尽量带上必要的上下文参数而不是只打一个异常栈。上游传了什么值、当时什么状态、做了哪些处理有了这些参数排查问题的时间能少一半。2.4 典型问题的排查思路参考我没有统一的 Bug 分类法但工程现场里有些问题出现频率高、排查套路相对固定整理出来供参考。第一类是并发问题。症状通常是偶发、不可稳定复现、数据对不上。排查方向先看共享资源的访问是否加锁再看查询和更新的原子性最后看事务边界。很多时候你会发现问题不是没加锁而是加锁的粒度不对或者自认为安全的复合操作在另一个线程视角下并不是原子的。第二类是缓存问题。症状通常是“改了数据库但界面没变”“某些用户看到的数据不一样”。排查方向先确认缓存键和缓存策略再确认局部操作有没有清理或刷新缓存最后看缓存过期时长设置。热点数据缓存过期时间太短高频请求全打到数据库上也会表现出类似的“偶尔变慢”现象。第三类是一个比较容易被忽视的情况环境差异导致的问题。本地正常、测试环境正常、上线就异常的情况在环境对比上要下功夫。操作系统版本、依赖库版本、系统时区设置、文件系统行为差异都能成为问题源头。跟这个问题类似但形态相反的还有一类时区和格式化问题——本地打印出来是北京时间服务器上打印出来是 UTC一切看起来“错了”但代码没有一行是错的只是时区默认值不同。这类问题锻炼的其实是排查的思路顺序先确定问题只会出现在哪个范围再看上下文环境是否一致最后才深入业务逻辑。2.5 把问题讲清楚也是一种能力Debug 不全是对着代码的工作很大一部分是对着人。无论是向同事求助还是让测试复现问题描述的质量直接决定协作效率。我常用的描述模板固定在五个要素上操作步骤、预期结果、实际结果、出现频率、环境信息。描述问题避免使用“很奇怪”“它就是不工作”这类模糊表达改为“我点击 A 按钮之后页面没有跳到 B 页面而是停留在原页面并提示报错本地环境必现测试机上百分百复现版本是 1.3.2”。这样一个描述别人不需要额外追问太多就可以开始排查。还有一个小经验求助之前先自己排查十分钟把已经排除了什么、锁定到了哪里说清楚。这会让同事非常愿意帮你因为你不是甩一个烂摊子过去而是请他在关键位置帮你把一把方向。反过来收到求助的时候也不要上来就看代码先按上面的模板让对方把信息补全信息不够让你猜来猜去才是最消耗团队时间的事情。3. 测试工程化从完成任务到建立质量防线3.1 测试金字塔在现实里的样子理论上大家都会说测试金字塔底层是大量的单元测试、中间层是较少的集成测试、顶层是少量的端到端测试。现实里很多团队做出来的是个倒金字塔大量端到端测试慢而且容易挂单元测试没几个核心逻辑全靠手工确认。我的看法是测试策略不是越全越好而是应该根据项目的风险分布来决定。基础设施类、公共工具类的代码单元测试覆盖率可以要求高一些因为它们的改动影响面大、回归成本高。业务界面类的代码端到端测试只需要覆盖核心流程细枝末节的交互可以靠人工验证和少量针对关键逻辑的单测来兜底。写测试之前先问一句这个测试是要防止什么回归如果答不上来这个测试很可能只是在凑覆盖率数字。还有一个结构层面的建议测试代码和被测代码放在同一个仓库、同一套 CI 流程里跑。测试不是发完版之后的仪式而是功能完成的一部分。功能代码合入主干的条件就是测试通过。只要这个红线保持住整个团队的交付质量和速度都会明显提升。3.2 单元测试怎么写才有价值单元测试最容易踩的坑是把实现细节测了个结实等哪天重构一下内部写法代码行为完全一样测试却红了一片。正确做法是测试外部行为而不是内部实现。比如你要测一个计算订单总价的函数关心的是输入商品列表和优惠券后返回值是不是正确的总价而不是关心函数内部是不是用了某个循环、某个临时变量。写有价值的单元测试有一个很实用的清单。测正常输入下的正确输出测边界值比如空数组、零、负数、最大值测异常输入是不是按预期抛错或返回失败测特殊分支比如 if 的 else 路径、switch 的 default 分支。再往深一层有条件的话测一些随机数据或者属性特征比如“无论输入是什么返回值都不为负”“排序函数的返回结果长度永远和输入一致”这类测试能捕获很多边界场景里的偶发问题。下面的示例是一个典型的、有价值的单测结构用 JavaScript 的 Jest 风格做展示describe(calculateOrderTotal, () { test(应正确累加商品金额并应用优惠券抵扣, () { const items [{ price: 100, count: 2 }, { price: 50, count: 1 }]; const coupon { type: FIXED, value: 30 }; expect(calculateOrderTotal(items, coupon)).toBe(120); }); test(空商品列表返回 0, () { expect(calculateOrderTotal([], null)).toBe(0); }); test(优惠券面值大于总价时返回 0 而不是负数, () { const items [{ price: 10, count: 1 }]; const coupon { type: FIXED, value: 999 }; expect(calculateOrderTotal(items, coupon)).toBe(0); }); test(非法商品数据 (负价格) 应抛出异常, () { const items [{ price: -5, count: 1 }]; expect(() calculateOrderTotal(items, null)).toThrow(); }); });你能从这个例子里看到四个测试覆盖了常规、边界、异常、极值四种不同场景代码的防御能力也在写测试的过程中自然地得到加强。很多时候测试写不下去不是因为你不会写而是因为被测代码本身设计得不够干净——耦合太重、职责太多、副作用藏在深处。这其实是个重要的信号代码该重构了。3.3 Mock、Stub、Fake 没有你想的那么简单这几个词经常混着用但工程里用错的代价很大。一句话区分Stub 是给被测对象提供预设返回值的替身Mock 除了提供返回值还会记录调用行为并可以验证交互Fake 则是实现了一个简化版但行为基本真实的替身。单元测试里最常见的需求是 Stub比如让一个支付接口在测试环境里固定返回成功不需要真的去请求第三方服务。但用 Mock 有个明显的反面效果测试和实现绑得太紧。比如你 Mock 了一个下游方法然后断言“这个方法必须被调用两三次”只要实现稍微调整行为正确但测试挂了。我一般只在两处使用 Mock一是被测代码需要和外部服务交互且本地没有测试环境二是需要验证“某操作是否确实发生”这类行为本身比如发送日志埋点、触发通知回调。Fake 在集成测试里的价值更大。比如数据库访问层用一个轻量级的内存数据库当依赖跑测试的速度比真正的数据库快得多同时行为更接近真实环境。一个小提醒使用 Fake 之前要和真实依赖保持行为一致性否则会出现 Fake 全绿、上真实环境就挂的尴尬情况。曾经就有团队因为 Fake 的实现没有模拟真实存储的字段长度限制结果上线后数据截断而测试永远测不出来。3.4 集成测试和 CI 的关系单元测试跑得再全也管不了模块之间拼接的缝隙。集成测试的价值就是把模块接缝处的行为验证掉。最简单的做法是每次提交代码、或合并分支之前在 CI 流水线里跑一遍完整的集成测试套件。我建议 CI 里的测试分成两层。快速层每次 push 都跑单元测试和静态检查要求在几分钟内完成这样开发者有即时反馈不会等待太长时间。慢速层合入主干之前跑集成测试和核心端到端场景允许十几分钟因为合入主干的频率本来就低于每次 push。如果你把慢速层也放在每次 push 时跑最终的结果就是开发者为了赶进度开始跳过测试防线形同虚设。CI 里的测试还有个容易被忽略的点稳定性。套件里如果有“偶发挂掉、重跑就好”的测试这种不稳定本身就是质量缺陷一定要查到底。多次重跑才通过的测试会导致团队形成“红了先重试”的坏习惯而真正的回归问题就这样被掩盖过去了。我见过最严重的案例是一条端到端测试因为超时设置太短而频繁“闪挂”持续了两三个月没人管后来它真正抓到一个严重回归时所有人看到红的第一反应是点重试差点把一个线上事故放过去。3.5 TDD 不是万能的但在某些场景下很好用测试驱动开发这些年被捧过、也被唱衰过。我自己的体会是它不是银弹但确实有一类场景天然适合 TDD核心业务逻辑、算法、状态转换、规则引擎。因为这些逻辑特征明显——输入确定、输出可预期、边界能列举在写实现前用测试把行为定下来能让实现的思路清晰很多。这里有一个比较完整的 TDD 实践流程。先写一个针对核心逻辑的失败测试运行一次确认它是红的也就是失败状态接着写最小实现只求让当前测试通过不跳步然后运行全部相关测试确认没破坏其他行为最后重构在测试保护下调整代码结构让实现更清晰。整个过程依靠“红灯-绿灯-重构”的节奏每一步都有明确目标不知不觉中就得到了一套覆盖完整行为的测试用例。但也有不适合 TDD 的场景。UI 界面的交互流程、外部系统的对接、探索性的原型验证这些地方先花大量时间写测试很可能得不偿失。大前端项目的页面测试往往需要很长时间稳定下来这时与其硬上 TDD不如把核心逻辑抽成独立的函数/模块先对这些模块做 TDD界面层只保留少量冒烟测试。4. Linux 下的工程效率与系统排查4.1 高频命令组合拳不只是单个命令Linux 下面单看每个命令都简单真正的效率提升来自把命令组合成能直接解决问题的管道。下面这几组命令是我每天都会用到的整理出来供直接参考。# 在代码库里快速定位关键词忽略二进制和 .git 目录 grep -rn someFunction --include*.js --include*.py . # 查看日志文件最后 500 行并实时跟踪新增内容 tail -n 500 -f app.log # 按访问 IP 统计接口调用次数倒序展示 awk {print $1} access.log | sort | uniq -c | sort -rn | head -n 20 # 找出当前目录下占用空间最大的前 10 个文件 find . -type f -printf %s %p\n | sort -rn | head -n 10 # 批量替换目录下所有匹配文件里的旧版本号 find . -type f -name *.yaml | xargs sed -i s/1.2.3/1.3.0/g这些组合背后的思路是一样的每个命令做一件简单的事管道把上一段输出交给下一段继续加工。grep 负责筛选、awk 负责取列和统计、sort 和 uniq 负责排序去重、head 负责截取顶层结果任何一步的结果都能随时调整和替换。我用这套组合拳解决过大量的日志分析、配置检查和文件检索问题熟练之后比打开编辑器和图形工具快上一个数量级。4.2 资源瓶颈排查四板斧线上系统变慢先看资源。CPU、内存、磁盘、网络四类资源分别对应不同的排查工具和不同的解决路径。CPU 飙高时先用 top 确认高占用进程再用 top -H -p PID 看具体线程号配合 jstack 或 gdb 把线程栈抓下来就能定位到代码层面的热点函数。曾经排查过一次 CPU 100% 的问题前面花了很久在业务代码里找原因最后发现是 JDBC 连接池配置的请求超时时长过短导致无限循环重连而线程栈一眼就指出了问题所在。内存问题分两类内存不足和内存泄漏。free -h 可以快速看系统内存水位如果剩余充足但应用变慢可能是 GC 频繁如果内存持续减少且不释放多半是泄漏需要结合堆转储分析。日常我会重点关注持续一段时间的监控趋势单独的瞬时值参考意义有限。# 查看整体内存和交换分区使用情况 free -h # 动态查看系统负载、进程占用 top # 查看磁盘剩余空间-h 是人性化显示 df -h # 查看当前监听端口和连接状态 ss -tlnp磁盘和网络的排查里也有几个常见套路。磁盘空间满导致服务写不进日志或数据库是运维事故里频率最高的一种先 df -h 排除磁盘问题再排查业务代码可以少走很多弯路。网络层面端口占用用 ss 或 lsof -i:端口号 查看连接数异常、超时问题可以用 netstat 和 tcpdump 结合分析先用 netstat 看宏观连接分布再用 tcpdump 抓具体报文判断是否丢包或延迟。4.3 Shell 脚本健壮性能跑不算写好了很多人写 Shell 脚本只要能跑就行但生产环境里的脚本和本地跑的脚本要求完全不一样。我见过最糟糕的情况是一个定时任务脚本里没有 set -e中间某条命令失败后脚本继续往下执行最后把一堆不完整的数据同步到了线上等发现时已经晚了。从那以后我写的每个稍微正式一点的脚本都会加上#!/usr/bin/env bash set -Eeuo pipefail一行参数说明几个含义-e 遇到错误立即退出-u 使用未定义变量直接报错-o pipefail 管道中任何命令失败都让整体返回失败-E 让错误处理覆盖到函数和子 shell。这四件套加上之后大多数“静默失败”的机会都被堵住了。另外脚本开头用 shellcheck 做一次静态检查也是个好习惯。还有几个细节值得提。路径用双引号包裹防止空格和特殊字符出问题临时文件用 mktemp 生成而不是固定写死路径避免多个实例运行时互相覆盖脚本结束前用 trap 清理临时资源和句柄防止异常退出时留下脏文件变量拼接路径时使用 ${VAR:-default} 形式提供默认值避免环境变量未设置时报错。这些习惯看起来小累积起来能避免很多线上事故。#!/usr/bin/env bash set -Eeuo pipefail LOG_DIR${LOG_DIR:-/var/log/myapp} TMP_FILE$(mktemp) trap rm -f $TMP_FILE EXIT if [[ ! -d $LOG_DIR ]]; then echo 日志目录不存在: $LOG_DIR 2 exit 1 fi4.4 效率工具与真实排查案例复盘Linux 的日常工作里除了命令本身还有几个思路层面的提升。一个是别名机制把高频、易敲错的命令收成短别名。比如 alias gsgit status、alias llls -alF、alias dcdocker compose别名的价值在于把长串的参数打包成肌肉记忆减少每天的重复输入。当然别名只针对个人习惯团队共享的脚本里不要依赖任何别名保证脚本在干净环境里也能跑。另一个思路是用函数封装复杂逻辑。比如我需要频繁查看某个日志里某个用户的完整行为链路就写了一个函数接收用户 ID 作为参数自动组合 grep 和 awk 输出时间线。这个函数放在 .bashrc 或 .zshrc 里每次执行都能省掉一长串命令。下面分享一个真实排查案例的复盘。某天同事反馈某服务响应缓慢我按部就班做排查。先 free -h 看内存发现交换分区使用率很高内存明显不足再用 top 查看进程发现两个 Java 服务在同一台机器上其中一个堆内存配置过大再看日志发现大量文件句柄相关的报错判断是文件描述符限制或打开文件过多最终定位为服务 A 的堆内存上限设置过高挤占了服务 B 的可用内存导致服务 B 频繁换页。解决办法就是调整 JVM 参数同时检查两个服务的负载部署规划。整个排查思路就是从系统资源到进程再到应用日志逐层逼近每一步都用命令验证而不是靠猜。“无监控不排查”是我一直强调的观点。生产环境里如果没有系统性的监控和日志采集每次出问题都靠临时登录机器去看等于火情发生后才找消防水带。时间充裕的话优先把基础监控搭起来CPU、内存、磁盘、进程存活、核心业务接口的时延和错误率这些都值得有长期曲线。有了曲线很多问题的排查从“现在发生了什么”变成了“从什么时候开始变成这样”而后者定位起来要快得多。写在最后的一点个人体会这个系列笔记写到这里我很想把“工程实践”这个词落到更实处。它不是某个庞大的理论体系而是每天在命令行、调试器、测试代码和故障排查之间来回打磨出来的手感。Git 的那套分支规范也好、Debug 的二分思路也好、测试的分层设计也好、Linux 的排查套路也好单独拿出来都不难理解真正难的是在一次次项目压力下仍然坚持执行并不断地从错误中修正自己的判断。如果你刚接触这些内容我的建议很简单先从一到两个点入手比如这个月强制自己按规范写 Git 提交信息下个月试着在修复每个 Bug 前先写一条复现记录。这些小实践会在之后某次线上问题里派上用场那是所有资料和课程都替代不了的经验积累。下一篇笔记我会继续沿着工程实践的路径展开聊聊和代码评审、协作流程相关的内容也欢迎你先在底下回复你在实际工程里遇到的问题我们接着聊。
阅读完成 · 觉得有帮助?
咨询建站