团队士气直接影响运营:员工觉得自己受重视、有干劲,参与度、留存率和工作质量都会有看得见的改善。要让士气一直保持在高位,管理者得在好几个方面持续用心,包括怎样落实价值观、怎样认可成绩、怎样组织沟通、怎样支持员工成长。下面六种做法,分别对应其中一个方面。 关键要点 公司文化要靠行动持续强化,光喊口号不够 尊重、培养和认可员工,能直接提高动力,降低流失率 开放的沟通和对工作与生活平衡的支持,会让团队内部多一分信任和忠诚度 公司价值观保持高士气,先要让公司价值观落在日常做事上,而不只写在宣言里。如果日常运营和决策中看不到价值观的影子,它也就不再是组织可以依靠的准绳。强化价值观的实用方法:
提升代码审查:最佳实践指南
好代码很少出自一个人闭门苦写,它往往是在围绕实现方案的有来有回的讨论中打磨出来的。协作式代码审查当然能抓出错误,但它更大的价值在别处:知识在团队里流动起来,写法保持一致,共同的标准逐渐成形,正是这些让大型工程项目多年之后依然好维护。
要点
好的审查离不开相互尊重、建设性反馈和明确标准的团队文化
代码审查能改善代码质量和稳定性,让错误和漏洞更少
自动化和迭代让整个团队的审查更快、更清楚,也更有收获
引言
代码审查同时在多个运营维度产生价值。其主要功能是缺陷检测,但二次效果 — 知识转移、一致性强制和问责制 — 随时间推移积累成结构性改进,这些是个别审查会议看不见地产生的。具体来说,代码审查有助于:
- 提高代码质量: 外部视角识别作者在同一代码库上长时间工作后可能会错过的逻辑错误、潜在错误、安全漏洞和性能问题。结果是更稳定和可靠的软件。
- 传播知识: 当一名开发者审查另一人的代码时,他们同时在学习新方法、模式和项目特定的决策。这是团队内最有效的知识转移机制之一 — 对于新员工培训和分散对复杂子系统的理解尤其有价值。
- 确保一致性: 代码审查强制统一的编码风格、结构模式和架构惯例。这种一致性对长期可维护性至关重要,特别是当团队组成随时间变化时。
- 加强团队合作: 代码审查是一种协作行为,创建了一个开发人员相互支持成长的环境。结果是更紧密和绩效更高的团队。
- 减少技术债务: 定期审查及早识别和解决有问题的决策,在它们嵌入代码库并变得难以消除之前。
- 增强问责制: 知道代码将由同事审查,从一开始就为产生更深思熟虑、可读和结构良好的工作创造了自然的激励。
审查准备
提交审查之前先做好准备,审查者省力,花在审查上的时间也更值。
- 分成小部分: 不要一次提交横跨许多文件和函数的大改动。改动越小越集中,就越容易看懂和审查,实际操作中可以把每个拉取请求控制在100-200行改动左右。改动确实很大时,把它拆成几个能各自独立审查的逻辑单元。
- 自我审查: 提交前作者先自己过一遍,确认代码能编译、测试能通过、逻辑讲得通、格式统一、命名清楚。这样审查者就不必再指出一堆机械性的小问题,精力可以放在真正要紧的地方。
- 全面描述: 拉取请求的描述要写清楚、写完整:改了什么,为什么改,解决了什么问题,和项目目标有什么关系。需要审查者特别留意的地方也要点出来。任务跟踪器里对应事项的链接必须附上。
- 删除注释和未使用的代码: 拉取请求里只应该有真正起作用的代码。被注释掉的片段和没用到的变量只会添乱,让人看不清到底改了什么。
- 本地测试: 提交前,所有自动化测试(单元测试和集成测试)都应在本地跑通。如果还需要手动测试,就在拉取请求描述里写明。
文化和沟通
代码审查做得好不好,不只看技术流程,还要看参与者之间怎么打交道。团队默认的相处规矩,决定了审查是一种高效的日常实践,还是团队摩擦的来源。
- 要建设性,不要批判性: 审查的对象是代码,不是写代码的人。像"这里可以再改进一下"或"要不我们试试这样?"这种针对代码的说法,比评价作者本人管用得多。
- 建议解决方案,而不仅仅是问题: 发现缺陷时,给出具体的改法要比单纯指出问题有用得多。"这里用forEach会更好读"就比"循环写得很糟"更容易落实。
- 询问,而不是指示: 用提问把作者引向正确的方案,比如"这里考虑过用工厂模式吗?",往往比直接改正效果更好,带新人时尤其如此。
- 要具体: 评论要清楚,有理有据,别说空泛的话。能举例就举例,能附文档链接或编码规范出处就附上。
- 注意语调: 文字交流很难把握语气。措辞礼貌一些,可能产生歧义时直接说明本意,评论就不容易被当成针对个人的批评。
- 回应评论: 作者要及时回应审查者的问题和意见,可以解释自己的决定,可以接受建议,也可以讲清理由提出不同看法。
- 承认审查者的贡献: 审查者花了时间和心思,说一声谢谢能让合作更顺,以后的审查也更有成效。
审查者的焦点
审查要有条理,先想清楚看什么。一份固定的检查清单能避免漏掉重要的方面:
- 功能性: 代码是否完成了任务要求?是否解决了描述中的问题?
- 正确性和逻辑: 有没有逻辑错误?边界情况处理得对不对?出错的情况(空指针、除以零、网络故障)有没有处理?
- 安全性: 有没有潜在漏洞,比如SQL注入、XSS、对用户数据的不安全处理?
- 性能: 代码会不会带来瓶颈?有没有哪个算法在预期的数据量下会慢得无法接受?
- 可读性和可维护性: 第一次读这段代码的人能不能看懂?变量、函数和类的命名是否清楚?该有注释的地方有没有注释?代码是否符合团队的编码规范?
- 测试: 新功能有没有单元测试?现有测试能否通过?修复错误时有没有补上回归测试?
- 代码重复: 这次提交有没有引入项目里别处已经有的代码?
- 架构和设计: 改动是否符合项目的整体架构?新代码有没有引入反模式?
审查的目的,并非按审查者自己的喜好把代码重写一遍,它是对照团队共同标准,系统地找出真正的错误和值得改进的地方。
工具和自动化
风格检查、跑测试、扫描漏洞这些例行工作交给自动化,审查者就能把注意力从机械检查转到对逻辑本身的判断上。
1. 支持PR/MR的版本控制系统: GitHub、GitLab和Bitbucket都提供统一的界面来创建、查看和评论拉取/合并请求,评论可以直接挂在具体的代码行上。
2. CI/CD集成: 每个拉取请求都应自动触发以下检查:
- 自动化测试套件: 每次提交都会运行的单元测试、集成测试和功能测试
- 代码linter和格式化工具: ESLint、Prettier、Black、SwiftLint自动执行风格规范,审查者不用再管格式问题
- 静态代码分析: SonarQube、Bandit(Python)、Semgrep在人工审查开始之前就能找出潜在错误、漏洞和质量问题
- 依赖项漏洞扫描: 自动检查第三方库的安全性
3. 拉取请求模板: 用统一的PR/MR模板设好必填项,包括改动说明、任务链接、跑过哪些测试、想请审查者回答的问题,作者就会把审查所需的背景交代清楚。
4. 行内评论: 大多数平台都支持把评论关联到具体的行,讨论有了上下文,审查者也不必另外写行号。
迭代和学习
代码审查的做法不是一成不变的,团队和项目在变,它也应该跟着变。
- 迭代方法: 复杂的改动通常要经过几轮评论和修改。每一轮往前推进一点就好,不必指望一次就改到位。
- 回顾会议: 定期开会专门回顾审查流程,看看哪些做法有用,哪些地方容易起摩擦,哪些意见总在反复出现,有了这些信息才能有针对性地改进流程。
- 学习和指导: 在团队里,审查是最好的学习途径之一。初级开发者从经验更丰富的审查者那里学东西,资深开发者也借此练习带人。如果某个开发者的提交里总出现同样的错误,也许说明他需要系统的培训或结对编程。
- 规则适应: 项目逐渐成熟、团队人员变动时,编码规范和审查标准也要跟着调整。小团队时期合用的规范,代码库变大以后可能就得修改。
- 及时审查: 审查拖得越久,作者的进度越受阻,合并冲突也越容易出现。团队内部给审查定一个周转时限,通常是24-48小时,开发就能顺畅地往前走。
- 保护专注时间: 审查时间要有安排,可以留出固定的时间段,也可以分给几位审查者,免得审查请求不停打断需要专注的工作。
一个有趣的事实
1970年代,Bell Labs开发第一个UNIX版本时就已经有了同行评审的雏形:所有代码都要经过人工检查和集体讨论。这种协作式的检查让UNIX变得可靠、经久耐用,也帮助它成为计算机史上影响最大的操作系统之一。
相关文章:
想系统地做好任务可视化和优先级排序,可以读一读用Kanban提升生产力:有效任务管理的技巧。
如何在倦怠拖垮工作之前识别并预防它,请看如何避免倦怠:维持福祉的关键策略。
用甘特图把项目时间线画出来并加以管理,请参阅什么是甘特图? 可视化和管理项目时间线的指南。了解更多:个人生产力软件。
结论
只要准备有标准、沟通讲方法、工具能自动化、流程不断改进,代码审查就不再只是一道检查手续,而是团队传递知识、保证质量的一套机制。它的长期收益,包括更少的缺陷、更好维护的代码、分散在整个团队里的专业经验,取决于上面这些做法坚持得有多一贯。
推荐阅读
"Code Complete"
讲如何写出干净、好维护的代码的全面参考书,其中不少内容正是做好同行评审所需要的。
"The Art of Readable Code"
教你写出意图一目了然的代码的实用指南,代码好读,审查才能给出有分量而不是流于表面的意见。
"Team Geek"
涵盖软件开发中的人为因素 — 协作、沟通以及决定代码审查等实践在实践中成功或失败的人际动态。延伸阅读:远程团队管理软件。