前段时间听了百度技术培训中心章淼博士讲的《代码的艺术》直播课,章老师是业界大牛,课讲得娓娓道来,内容很丰富,很多点都戳到了我以前或现在的痛点,也激发了自己很多反思,总之收获很多,现在简单总结一下,主要分以下几点吧。
1.文档:
关于文档,很多工程师最讨厌两点:没有文档和自己写文档。我以前对文档也有很深的误解,比如经常觉得写文档有点儿浪费时间,总觉得码代码和Debug才更能显示出一名工程师的能力和价值。这其实是一个严重的错误。文档的重要性被严重低估了。
1.1 项目文档的重要性
(1) 文档的目的:提高沟通效率;提升对“思考过程”的管理。
(2) 项目中超过50%的时间用于沟通,沟通的方式:口头,文档,代码。
(3) 没有文档的设计不是设计。
(4) 不会写文档 = 不会做设计。
(5) 文档本身也是产出:coding的时间少于30%。
(6) 写文档是整理思路的过程。
(7) 没有文档,后期会浪费更多的时间,维护成本远高于写文档的时间。
(8) 修改文档,比修改代码的成本小的多。
(9) 没写文档,就开始写code,是极其错误的。
(10)简单的项目和问题,也需要写文档:项目的延续时间和复杂性往往超出预期;早期的“偷懒”,往往在后期付出更大的代价。
1.2 常见的问题:
(1) 没有接口文档:多人协作出现问题。
(2) 需求文档没写好:多次反复讨论同样的问题。
(3) 没有系统总体架构文档:每一个人都需要重新看代码,还不一定能看清。
(4) 缺少文档:新人无从入手;人员变动时,不好交接;团队内沟通效率很低;自己过两个月后,痛苦的回忆之前的思路。
1.3 什么时候需要写文档?
(1) 必须的文档:需求设计文档:需求,重点,取舍过程;接口文档:函数,参数,返回值;关键性的算法文档:思路,关键点;系统总体框架:全局的思路。
(2) 凡是不那么“显而易见”的地方。
(3) 不仅留下设计结果(what),也留下思考过程(why):留下决策的依据,便于后面的工作。
(4) 文档不是写完代码后补出来的:文档是设计过程中使用的工具、和设计过程的结果。
1.4 文档书写规范
关于书写规范,每家公司的要求都不太一样,大家遵守就好。国内芯片行业在文档这方面做的最好的应该就是海思了,我个人觉得海思芯片的成功,跟他的文档和管理密不可分。
- 项目管理
项目管理是另一个被忽视的重要的问题。引用《软件开发的201个原则》中的一句话,所有伟大的技术(CASE工具、技术、计算机、文字处理器等)都弥补不了拙劣的管理。好的管理,即使是在资源匮乏的情况下,也能产生巨大的效果。事实上,懂项目管理的工程师特别少。每一位工程师其实都是管理者(做好自己的管理),所有的工程师都应该懂项目管理。
2.1 原则:质量第一
质量必须放在首位,没有权衡的余地。无论如何定义质量,客户都不会容忍低质量的产品。质量必须量化,并建立可实施落地的机制,以促进和激励质量目标的达成。即使质量差、也按时交付产品,这似乎是政治正确的行为,但这是短视的。从中长期来看,这样做是自杀。
2.2 项目三要素的权衡
锁定1-2个要素,改变其他要素。人和月不能简单互换。
2.3 项目规划
(1) 明确项目约束(质量、范围、时间、成本),做出取舍。
(2) 制定项目里程碑计划,和相关方达成一致。
(3) 分配任务并制定进度表:梳理关键任务;搞清关键任务间的依赖关系;识别项目的关键路径。
2.4 项目周报和个人周报
(1) 做好下周计划,抓住重点。
(2) 每周对照计划,即使有变化,也应努力按计划执行。
(3) 反映工作量,周报首先是给自己看的。
(4) 周报需要目标和计划,也需要回顾和总结。
- 代码的艺术
代码反映了一个人/团队的精神面貌。一个优秀的工程师应该具有很高的综合素质。编码能力只是表象,不仅要懂验证,还要懂脚本,懂运维,懂设计、懂架构,懂产品。真正优秀的工程师任何时候都是稀缺的。
3.1 Coding is NOT so easy
(1) Coding的过程是:从无序变为有序;将现实世界中的问题转化为数字世界的模型;一个认识的过程(从未知变为已知)。
(2) Coding的过程中,需要把握问题的能力;建立模型的能力;沟通协作的能力;编码执行的能力。
(3) 写好代码首先需要建立品味
3.2 一流代码的特性
3.3 代码也是一种表达方式
代码主要是写给人看的,不是写给机器看的,代码的维护成本远高于开发成本。理想的场景:看别人的代码感觉和看自己的代码一样;看代码时能够专注于逻辑,而不是格式方面;Don’t make me think。
3.4 模块切分的原则
紧内聚,松耦合,有利于代码的复用:单一目的;明确对外接口;以数据为中心。
3.5 切分模块的方法
(1) 数据类模块(实现对数据的封装)。
(2) 过程类模块(不包含数据)。
3.6 数据类模块
(1) 主要完成数据封装:模块内部变量;类的内部变量。
(2) 对外提供明确的数据访问接口:数据结构和算法属于模块内部工作。
(3) 写程序要以数据为中心考虑:首先考虑有哪些数据类的模块。
3.7 过程类模块
(1) 本身不含数据。
(2) 调用“数据类模块”或“过程类模块”。
- 代码的评审(Code Review)
定义:通过阅读代码来检查源代码与编码标准的符合性以及代码质量的活动。在编写代码之外,代码评审和单元测试是两个最重要的工作。
4.1 代码评审的重要意义
(1) 提升代码质量:code review是提升代码质量最重要的方法。
(2) 有助于知识传递:code review是辅导他人编码最好的方法。
4.2 代码质量差造成的问题
(1) 重复编写类似的逻辑,缺少可复用的代码。
(2) 定位bug和修复bug。
(3) 代码的可读性差,阅读代码困难,费时。
(4) 踩坑/填坑,挖坑容易,从坑里爬出来难。
(5) 重构也需要时间。
(6) 无休止的加班的源泉。
(7) 职业危机,生存困境。
4.3 代码评审中的常见问题
(1) 拼写错误。
(2) 未优化的代码实现。
(3) 不必要的复杂代码。
(4) 重复实现已经存在的逻辑。
(5) 缺少必要的注释。
(6) 缺少必要的单元测试。
(7) 。。。。。
4.4 在代码评审中应有的态度
(1) 对所审代码完全看懂:yes:掌握情况就像自己写的一样;no: 对代码逻辑和背后的原因任很模糊。
(2) 不仅可以运行:优秀代码的标准:正确,可维护,可重用,可运维。google的标准:差一个空格也不行。
(3) 评审和编码一样重要:评审也有产出:更高质量的代码;评审比编码更辛苦:理解&找出问题。
(4) 以提升代码质量为最终目标:评审双方共同努力。
4.5 代码评审的步骤
(1) 推荐方式:自顶向下,对代码进行全面扫描。
(2) step1:系统全貌:模块划分的逻辑,模块间的关系。
(3) step2:模块级别:看清模块内的逻辑;关键数据,关键的类/函数(重点:功能,接口定义)。
(4) step3:类/函数的内部逻辑:逻辑正确性,实现合理性,段落划分合理性。
4.6 关于坏代码的简单判断
(1) 如果5分钟内不能看懂的代码,大概率有问题。
(2) 需要思考才能看懂的代码:好的代码:Don’t make me think。
(3) 需要来回翻屏才能看懂得代码:好的代码:在一屏内就是完整的逻辑。
(4) 没有空行/注释的代码:不会用段落,不会写注释,肯定不是好的程序员。
4.7 代码评审的注意事项
(1) 建立ower制度:所有提交的代码,必须由ower做最终确认;很多问题来源于“责任不明确”。
(2) 综合多种沟通机制:yes:面对面的沟通;提供设计文档;提交代码评审评论;no: 直接大规模评审会;仅口头沟通。
(3) 不放过任何一行代码:问题:只看大问题,不管小问题;推荐:对评审中发现的问题,一追到底。
5 技术的心法
5.1 如何发现问题
(1) 问题的发现常常需要经验,尤其是方向的指出。
(2) 写综述(survey),是一个很好的锻炼方法。
(3) 从自己的亲身体会去发现问题。
(4) 要有挑战权威的精神,别人说的不一定是对的。
(5) 一定不要有“想当然”的思想,书本上的不一定是正确的。
(6) 没有任何事情是完美的,实际工程中经常做“trade off”。
5.2 如何分析问题
(1) 概念(砖块):问题首先要有准确定义(正名);概念是大家的共识,是进行科学交流的基础;在搞清概念的过程中,也能发现机会。
(2) 逻辑(水泥):分析问题应言之有理,让人信服。
(3) 分而治之:大问题(无从下手)=>小问题(能够处理);细分和专业化是人类社会发展的趋势。
(4) 分类和比较:在过程中加深认识。
(5) 注意联系:问题之间的联系也包含信息;揭示事物之间的联系也很有意义。
5.3 如何解决问题
(1) 先解决重要问题:精力有限:不可能彻底解决所有问题;列出问题,然后再排序。
(2) 保持聚焦:在一定的阶段,要keep focus。
(3) 先易后难:解决简单问题=>解决复杂问题;模型方法:对问题进行简化
(4) 一般的过程:发现问题,分析问题,解决问题。
一流高手提问题,二流高手解问题,三流高手炒问题(炒冷饭)
最后的最后,好好学习,天天向上,行胜于言,与君共勉。
感谢关注微信公众号“芯片验证日记”,我们一起学习。