Bob 大叔的《代码整洁之道》一书,曾经让我受益匪浅,这本书从编码上很小的细节着手,讲解如何编写出高质量的代码。最近我又拜读了 Bob 大叔去年出的一本新书《程序员的职业素养》,这本书未深入讲解编程的知识细节,而是从程序员工作的角度描述哪些行为是不专业的、哪些行为可能会导致项目延期、哪些行为会导致工作效率低下等等事情,其中也有很多非常好的专业建议。

提升职业素养,使自己成为一个专业的程序员,这并非一件简单的事情,技术能力、沟通技巧、工作态度等等都构成了评价一个员工专业性的因素,缺少任何一个可能都会令我们显得不够专业,如果能把书中的理论知识持之以恒地应用到工作之中,可以说对我们的职业生涯将大有裨益。

我对书中的一些关键点做了一些摘要,以便自己可以经常回过头来看一看,思考自己是否有将理论和实践结合起来以及怎样才能做的更好。培根在《论读书》中说过,有的书可以请人代读,然后看他的笔记摘要就行了,但这只应限于不太重要的书,否则一本书将像被蒸馏过的水,变得淡而无味了。我下面列举的摘要,就像是蒸馏过的水一样,虽然读起来没什么味道,但是一些观点确实是引人深思的,希望对大家有所帮助。

第一章 - 专业主义

  1. 专业主义意味着担当责任
  2. 不行损害之事
    不破坏软件功能,失误率不可能等于零,但专业的程序员有责任让它无线接近零;让 QA 找不出任何问题,发送明知有缺陷的代码,这种做法是极其不专业的,记住那些你没把握的代码都可以看做是有某种缺陷的,QA 不是抓虫机器。自动化 QA——单元测试和验收测试;不要破坏结构,无情重构和坚持代码设计原则。
  3. 职业道德
    工作时间用来解决雇主的问题,而不是你自己的问题;了解工作领域;坚持学习。
  4. 练习——软件开发技能和效率也可以通过训练来提高,可以坚持重复做一些简单的练习,这种练习可称作“卡塔”,卡塔的形式是一个有待解决的简单编程问题,做卡塔的目的不是找出解决方法,而是训练你的手指和大脑。
  5. 合作
    一起编程、一起练习、一起设计、一起计划。
  6. 辅导——教学相长。
  7. 了解业务领域
  8. 与雇主保持一致,站在雇主的角度来思考。
  9. 谦逊
    对自己的能力充满自信,并因此勇于承担有把握的风险;清楚自己的自负。

第二章 - 说“不”

“能就是能,不能就是不能。不要说试试看。”

  1. 对抗角色
    掌握沟通技巧,杜绝说“试试看”,交流应该保持明确性,当可能存在风险时,保持自己的立场。
  2. 高风险时刻
    最需要说“不”的是那些高风险的关键时刻,把最明确的信息传递给上级。
  3. 要有团队精神
    真正为团队努力的人,会根据自己最好的能力状况,明确说明哪些是做得到的事,哪些是做不到的事。
  4. 说“是”的成本
    急于完成,必然要做出某些牺牲,比如代码质量。

其他:有时候,提供太多细节,只会招致更多的微观管理

第三章 - 说“是”

  1. 承诺用语
    口头上说。心里认真。付诸行动。
  2. 识别缺乏承诺的征兆
    话语中包含“需要/应当”、“希望/但愿”、“让我们”等词语时,很可能是缺乏承诺的征兆
  3. 真正的承诺听起来是怎样的
    关键在于,你对自己将会做的某件事做了清晰的事实陈述,而且还明确说明了完成期限/时间。
  4. 信守承诺将使你成为一名严谨负责的开发人员
  5. 专业人士给出肯定回答时,会使用承诺用语,以确保各方能明白无误地理解承诺内容。

第四章 - 编码

  1. 做好准备
    代码要能正常工作、解决问题、跟现有系统结合、具有高的可读性。
  2. 确保将睡眠、健康和生活方式调整到最佳状况,这样才能在工作中全力以赴,产生优秀的代码。
  3. 流态区
    这是一种编码时会进入的一种意识高度专注但思维视野却会收拢到狭窄的状态,在这种状态下能够进行非常高效的代码编写,但它也有不利的一面,那就是思维视野收拢,此时可能无法估计到代码的全局层面。
  4. 中断、阻塞
    中断会打断思维,而阻塞是一种无法思考的状态,结对编程可以从某些方面表面这些问题,同伴能在被中断之后恢复之前被打断的思维,同伴也能在你思维阻塞的时候重新激活你的思维。
  5. 创造性输入
    广泛地阅读,学习各种各样的知识,能激活人的创造力和增加很多灵光一闪的机会。
  6. 保持节奏
    要适当分配精力,不要一直困在解决问题的状态中,暂时从问题中脱离出来,有助于大脑以不同且更具创造性的方式搜寻解决方案。
  7. 进度延迟
    根据目标定期衡量进度,使用三个考虑到多种因素的期限:乐观预估、标称预估、悲观预估。
  8. 无法完成任务时,不要轻易让步,不要让其他人抱有期望,不要盲目冲刺,若要加班,一定要提供说明加班失败的后备方案。
  9. 定义“完成”
    完成不是往源代码管理系统中提交已经写完的代码,团队应该对“完成”有一个清晰的定义,一般来讲,只有当代码完全通过验收测试,开发任务才算完成。

第五章 - 测试驱动开发

  1. TDD 的三项法则
    编好失败的单元测试之前,不编写产品代码;
    一个单元测试失败,就不再编写单元测试代码;
    产品代码刚好让失败的单元测试通过,不要多写。
  2. TDD 的优势
    确定性——通过测试能让你更加确信代码能正常工作 降低缺陷注入率
  3. 敢于重构的勇气
    拥有一套值得信赖的测试,便可完全打消对修改代码的恐惧。
  4. 文档
    遵循 TDD 的三项法则,所编写的每个单元测试都是一个示例,它们是最好的底层文档。
  5. 设计
    为了编写测试,必须找出函数跟其他函数解耦的方法; 事后写的测试只是一种防守,而现行编写的测试则是进攻,事后编写测试的作者已经受制于已有代码。
  6. TDD 的局限
    即使有全面的测试,也有可能产生糟糕的代码,因为写出的测试代码可能就很糟糕,所以应当把测试代码当做产品代码一样认真对待。

第六章 - 练习

一句话总结:任何事情要想做得快,都离不开练习,重复编码过程,要求你迅速做出决定,熟练之后大脑可以放心思考更高层次的问题。

第七章 - 验收测试

  1. 验收测试定义为业务方与开发方合作编写的测试,目的在于确定需求已经完成。
  2. 自动化
    验收测试应当自动进行,这可以节省不必要的成本。
  3. 持续集成
    务必确保在持续集成系统中,单元测试和验收测试每天都能运行。 保持持续集成系统的正常运行是非常重要的,集成一旦失败,应当立即处理。

第八章 - 测试策略

  1. 业务人员编写针对正常路径的测试(happy-pathtest),QA 则编写针对极端情况(corner)、边界状态(boundary)和异常路径(unhappy-path)的测试。
  2. 自动化测试金字塔
    使用测试驱动开发来产生单元测试;
    验收测试定义系统需求;
    持续集成保证质量稳步上升;
    系统测试确保正确的系统构造;
    人工探索式测试确保在人工操作下表现良好,同时富有创造性地找出尽可能多的“古怪之处”。

第九章 - 时间管理

  1. 关于会议的真理:会议是必须的;会议浪费了大量的时间。
  2. 谨慎选择应当参加哪些会议,必要时礼貌拒绝。
  3. 避免消耗注意力点数
  4. 避免优先级错乱

第十章 - 预估

  1. 不同的人对预估有不同的看法
    很多时候,业务方觉得预估就是承诺,开发方认为预估就是猜测,两者相差迥异。
  2. 预估是一种猜测,它不是定数,预估的结果是一种概率分布。

第十一章 - 压力

  1. 在压力下保持冷静的最好方式,便是规避会导致压力的处境,例如不要轻易承诺。
  2. “快速且脏乱”的抛弃型代码,是自相矛盾的说法,脏乱只会导致缓慢,让系统、代码和设计尽可能整洁,就可以避免压力。
  3. 危机中的纪律
    如果你遵守的纪律原则是工作的最佳方式,那么即使处于危机之中,也应当坚决秉持这些纪律原则。
    如果你在危机中放弃 TDD,那说明你并不真正相信 TDD 是有帮助的。
  4. 应对压力
    不要惊慌失措;保持沟通;依靠纪律原则;寻求帮助。

第十二章 - 协作

  1. 程序员与人
    我们并非是因为喜欢和人们在一起工作才选择做程序员。整个群体的平均状况便是如此,我们,程序员们,还是最享受面无表情的沉思,沉浸于问题思考中。
  2. 程序员与程序员
    不正常的团体最糟糕的症状是,每个程序员在自己的代码周边筑起一道高墙,拒绝让其他程序员接触到这些代码。这是招致灾难的“最佳秘诀”。
  3. 结对
    结对工作是分享知识的最好途径,也是复查代码的最好方式,系统中不应该包含未经其他程序员复查过的代码。

也许我们不是因为通过编程可以和人互相协作才选择从事这项工作,但真不走运,编程就意味着与人合作。

第十三章 - 团队与项目

  1. 成员克服个体差异,默契配合,彼此信任,才能形成真正有凝聚力的团队,当然这需要一个“发酵”的过程。
  2. 专业的开发组织会把项目分配给已形成凝聚力的团队,而不会围绕着项目来组建团队。