第1章 专业主义
专业主义就是担当责任;
1 担当责任
- 交付之前别忘记测试全部内容
- 尽其所能行有益之事
2 不行损害之事
不要破坏软件功能
* 对自己的不完美负责,对自己犯下的错误负责,勇于道歉;
* 让QA找不出任何问题,找到问题的时候应该羞愧;
* 确信代码正常运行,建议每一行代码都要覆盖测试;
* 难写测试,设计易于测试的代码,TDD;
* 自动化测试全覆盖;
不要破坏结构
* 软件要易于修改;
* 随时重构,无情重构;不敢修改,怕破坏代码结构,因为没有测试,所有要测试覆盖;
3 职业道德
* 雇主没有义务给你留时间学习;
* 工作上班时完成,学习使用自己的业余时间;
* 了解的你领域
* 设计模式:GOF书的24种模式
* 设计原则:solid原则
* 方法:xp,scrum,精益,看板,瀑布,结构化分析,结构化设计
* 实践:测试驱动开发,面向对象设计,结构化编程,持续集成,结对编程
* 工件:uml图,dfd图,结构图,流程图等;
* 坚持学习,看书文章,博客,技术大会等;
* 练习:10分钟的卡塔,解决简单的编程问题;
* 合作
* 辅导,教学相长
* 了解业务领域
* 与雇主和客户保持一致,他们的问题就是你的问题,弄明白这些问题,寻求最佳解决方案;
* 谦虚
* 专业人士知道自己自负,不会故作谦虚,但是也不会嘲笑别人的错,因为下一个很有可能就是你自己;
第2章 说“不”
不要说,”试试看“;
专业人士敢于说明真相而不屈从于权势,有勇气堆他们的经理说不;
1 对抗角色
- 面对艰难决定,直面不同角色的冲突时最好的办法;
- “协商过程试试看”:经理会把“试试看”,当做了“好的,没问题”;
- “轻松谈话”:经理和程序员双方都没尝试寻找最佳的可能结果,消极对抗;而是积极努力的寻找最佳的可能结果;
- 有时候,“为什么”不是很重要,提供太多的细节,会招致更多的微观管理;
2 高风险时刻
- 在高风险时刻,越是关键时刻,“不”子就越具价值
3 团队精神
- 团队精神的人频繁和大家交流,关心队友,竭力做到尽职尽责;
尝试,试试看的坏处
- 积极的举动,意味付出额外的精力;
- 许诺尝试,意味着你承认之前未尽全力,承认自己还有余力可施;
- 如果你的尝试没达到预期的结果,那就表示你失败了;
- 承诺尝试,你其实也在承诺改变自己原来的方案;
- 因此,如果此前未有所保留,没有新方案,不会改变你的行为,你对自己原先的估计有充分的信心,本质上来说,承诺尝试时一种不诚实的表现;
消极对抗
- 如果把各种谈话记录在档,这样,当灾难来临,可以证明自己在某事某刻给过建议啥的,这是一种消极对抗;
4 说“是”的成本
无论是外部客户,还是内部经理如何让开发人员快速写出代码?
- 告诉开发人员应用很简单;
- 挑剔职责开发团队没达到他们的需要,借机增加各种功能;
- 一而再的推后项目截至时期;没干完,加班几天,延迟几天,增加功能,循环;
5 如何写出好的代码
- “成为英雄”以及“解决问题”的诱惑诚然巨大,但是,如果牺牲各种专业原则以求全,并非问题的解决之道;
第3章 说“是”
1 承诺用语
- 口头上说自己将会做
- 心里认真对待做出的承诺
- 真正付出实际行动
识别缺乏陈诺的征兆
不在我掌控范围,不愿意承担个人责任
- 需要/应当: 我需要减肥
- 希望/但是:希望我们改天再见面
- 让我们:让我们(不是让我)回头再见;
真正的承诺
- 我将在…之前…: 我将在周二之前完成这个任务;
- 言必信,行必果
没能做到承诺的原因
- 之所以没成功,是因为我寄希望于某某区做这件事:你只能承诺自己能掌控的事
- 之所以没成功,事因为我不太确信是否真的完成的了:仍能全力前进
- 之所以没成功,是因为有些时候我真的无能为力:没预料到某些事,提前预警,
- 如果不尽早告诉他人可能的问题,就错失了让他们帮助我你完成目标兑现承诺的机会;
2 学习如何说“是”
- 试试的另一面,可能做得到,可能做不到;应该具体的说出可以完成的部分;
- 坚守原则:如果不写测试,快点完成任务;1. 假设错误,即使不写测试,也无法完成,2. 有责任根据标准规范自身工作,代码必须经过测试;
第4章 编码
熟练掌握某项技艺,关键是自信以及出错感知能力
1 做好准备
- 代码能工作,必须理解当前要解决的时什么问题以及该如何解决;
- 代码必须帮助客户解决提出的问题,发现问题与客户交流;
- 编码代码遵循稳健的工程原则
- 注释,精心锤炼代码,表达你的编程意图;
- 编码可能受到各种干扰,如果感到疲劳或者心烦意乱,千万不要编码;
凌晨三点写的代码
- 疲劳的时候千万不要写代码
焦虑时写的代码
- 时间分块,专门花时间解决焦虑的问题,然后编码;
2 流态区
- 高效率状态,称为流态;编码时进入的一种意识高度专注但思维视野会收拢到狭窄的状态;
- 避免进入流态区,为了追求速度,理性思考的能力会下降;
- 当你要进入流态区的时候,走开几分钟;结对编程;
音乐
- 边听音乐边写代码,有助于集中注意力;
- 音乐并没有帮助我们专注于代码,而是进入到流态区;
中断
- 粗暴相对的回应方式是因为流态区所致;
- 结对编程是一种应对中断的好方法,回去的时候,他能够帮你恢复被打断前的思维;
- 采用TDD,失败的测试能帮你维护住编码进度的上下文;
- 中断无法避免,下次轮到你打扰别的人请求帮助,礼貌的表现出乐于助人的态度是专业;
3 阻塞
- 睡眠不足,导致阻塞;
- 找一个结对编码,重新激活思维;
- 创造性输入,广泛阅读,找一些其他的事情干等;
4 调试
- 调试时间也属于编码时间,采用测试驱动开发,将调试时间降低;
5 保持节奏
- 保存体力和维持稳定的节奏啦取胜;
- 之道何时应该离开一会:让富有创造力的潜意识接管问题,精力分配得当;
- 开车回家的路上: 专注开车,暂时从问题中脱离,有助于大脑以不同的但更具创造力的方式搜索各种解决方案;
- 洗澡; 回家,吃顿好的,睡觉;
6 进度延迟
- 管理延迟的诀窍,早起检测和保持透明;
- 乐观估计,标准估计,悲观预估;
- 期望: 不要轻易松口退步,不要让其他任何人对此有期望;
- 盲目冲刺: 坚决维持你的估算,唯一能加快进度的时缩减范围;
- 加班加点:除非三个条件都满足:1. 个人能挤出时间 2.短期加班,最多2周 3. 老板有后备预案,防止加班失败;
- 交付失误:完成的标准;
- 定义完成:让业务分析和测试人员创建自动化的验收测试;
7 帮助
- 小心谨慎的将系统拆分为易于理解的小单元
- 帮助他人: 互相帮助,需要独处,直接、礼貌的方式告诉别人;
- 接受他人的帮助: 诚挚接受,心怀感恩,主动提出我要帮助;
- 辅导:资深的程序员辅导年轻的时职责;年轻的主动请教也是专业职责;
第5章 测试驱动开发
已成定论
- TDD确实可行,需要极高覆盖率的自动化单元测试;
三项法则
- 在编写好失败的单元测试之前,不要写任何的产品代码
- 只要有一个单元测试失败,就不要在写测试了,无法通过编译也是有中失败;
- 产品代码恰好能够让当前失败的单元测试成功通过即可,不要多写;
- 反复:单元测试,产品代码;
优势
- 确定性: 任何时刻有任何修改,运行手头的测试即可
- 缺陷注入率:显著降低;
- 勇气: 拥有值得信赖的测试,便可完全大小对修改代码的全部恐惧,整洁的代码易于理解,易于修改,易于扩展;
- 文档:编写的单元测试就是一个示例,用代码描述系统的用法;单元测试即使文档;
- 设计: 测试代码的问题是必须隔离出待测试的代码,需要考虑什么是好的设计,驱动你做出松耦合的设计;事后编写的测试时防守,事前编写的测试时进攻,后写的测试在深度和捕获错误的灵敏度方面逊色很多;
- 专业人士的选择;
局限
- 也可能写出糟糕的代码,因为写出的测试就可能很糟糕; 某些场合使用显得不切实际获不合适;
第6章 练习
更好的语言平台,但语言没有变
速度变了,也可慢下来仔细思考HDD;
速度来源于练习;
编程柔道场
- 测试驱动开发:保龄球,练习的卡塔;
- 卡塔: 模拟搏斗的招式,不断练习,需要的时候凭本能出招;
- http://katas.softwarecraftsmanship.org等;
- 保龄球,素因子,自动换行;
- 瓦萨:攻守双方互相练习;一人单测,一人程序,然后交换角色;
自身经验
- 解决问题的种类比较单一;
- 开源: 为开源项目贡献代码;
- 练习的职业道德:自己的时间练习;
第7章 验收测试
程序员要重视与团队以及业务部门的沟通,确保沟通的准确、流畅;
1 需求的沟通
过早的精细化
- 业务人员和程序员贪求不现实的精确性
- 不确定原则: 观察者效应; 每次你向业务方展示功能,他们获得后这些信息反过来影响他们对整个系统的看法;需求完成的越精细,就越容易被忽视,系统就谈不上完工;
- 预估焦虑: 1 即便有全面的准确信息,评估也存在变数; 2 因为不确定选哪个原则,不可能反复推敲实现过早的精确性;
- 需求是一定会变化的;
迟来的模糊性
- 避免过载精细化的办法是尽可能推迟精细化;
- 双方可能最后都搞错了需求,所以最后专业开发人员必须确认需求中没有任何不确定的因素;
2 验收测试
完成的定义
- 完成应为这所有的代码已经写完,所有的测试通过,QA和需求方已经认可;
- 专业开发人员根据自动化的验收测试来定义需求;
沟通
- 验收测试的目的是沟通、澄清、精确化,开发方、业务方、测试方达成共识;
自动化
- 验收测试都应当自动进行,因为考虑成本;
- 写这些测试不是额外的工作,是为了确定系统的各项指标符合需求;
- 业务方和QA协作写验收测试,程序员检查; 业务分析测试正确路径,QA测试错误路径、边界条件、异常;越晚越好;
额外的工作
- 确保系统的指标完成;满足需求;自动化测试;
验收测试和单元测试
- 单元测试时程序员自己写的,是正式的设计文档;深入系统内部的,调用特点类的方法;
- 验收测试是业务方写给自己看的;系统外部,api或者ui级别;
- 单元测试和验收测试首先是文档,然后才是测试;
持续集成
- 单元测试和验收测试每天运行好几次;
- 立刻中止: 当持续集成失败,所有人停下手里的工作,看看如何让测试通过;
第8章 测试策略
每个团队都有一套好的测试策略;
QA应该找不到任何错误
- QA也是团队的一部分,QA和开发人员不是敌对,应该紧密协作,携手保障系统的质量,QA扮演的时需求规约定义着和特性描述者;
- 需求规约定义者: 创建自动化测试; 业务人员正确路径,QA极端情况,边界状态,异常路径的测试;
- 特性描述者: QA遵循探索式的远侧,描述系统真实的运行情况,反馈给业务和开发人员;
自动化测试金字塔
- 单元测试 100% -> 组件测试 50% -> 集成测试 20% -> 系统测试 10% -> 人工探索式测试 5%
- 单元测试:程序员自己编写,90%以上;
- 组件测试:对系统的各个组件编写,系统的组件组装了业务规则;向组件中传入数据,然后收集输出数据,测试实际输出是否符合预期的输出; QA和业务人员编写,开发辅助;
- 集成测试:测试将组件配成组,测试彼此之间是否正常通行;集成测试是编排性测试,不会测业务规则,测试组件是否协调;
- 系统测试,针对整个集成完毕的系统来运行的自动化测试,最终的集成测试;系统架构师和负责人编写,目的不是确保正确的系统行为,而是确保正确的系统构造;
- 人工探索式测试: 人工介入,非自动化测试,需要人类创新能力,不是证明每条业务规则,而是确保系统在人工操作下表现良好,尽可能找出多的古怪之处;
第9章 时间管理
1 会议
- 会议室必需的;
- 会议浪费了大量的时间;
- 会议成本高,没有成效,主动拒绝;
拒绝
- 受到邀请的会议没必要全部都参加,为时间负责的只有你;确保参加的是可以给自己目前的工作带来切实且显著的成效;
- 1 感兴趣,但当下没必要参加的会;2 已经完成某项事项,对目前的工作没现实意义的;3 有职权的命令你参加,这时要问自己,他们的职权是否比自己的工作重要;
离席
- 如果会议让人厌烦,那么久离席;
- 选个合适的机会商量离席;
确定会议议程和目标
- 务必弄清会议的议题是什么,每个议题多久时间,取得什么样的成果;
立会
- 昨天,今天,问题
IPM 迭代机会会议
- 选择下一轮迭代中实现的开发任务,评估可选择任务的开发时间,确定这些任务的业务价值;
迭代回顾和DEMO展示
- 迭代末尾,团队讨论本迭代总什么做得对,什么做得不对;
争论反对
- 凡是不能再5分钟解决的争论,都不能靠辩论解决,因为双方拿不出有力的证据,这类争论依据的不是事实,而是信念;
- 唯一的出路,用数据说话; 有人尝试个人能力,提高嗓门,近距离和你对视,摆出不屑的姿势;有人表现的被动,同意结束争论,之后消极对待结果;
- 最好的办法,抛硬币决定如何选择;
- 小心这类会议目的是发泄情绪,让大家站队;
2 注意力点数
- 选择注意力充裕时刻编程,匮乏时做其他事情;
- 注意力点数随时间流逝而减少;
- 睡眠
- 咖啡因
- 恢复:沉思、反省、小睡
- 肌肉注意力:体力运动需要肌肉注意力,编程需要心智注意力;肌肉注意力有助于改善心智注意力;
- 输入与输出:平衡 ,看科幻书;
3 时间拆分和番茄工作法
- 番茄25分钟,不要让任何事情干扰你的工作,到了再去处理其他的事情;
- 番茄时间有生产率的,最大好处,再25分钟的高效工作时间段,有勇气拒绝任何干扰;
4 要避免的行为
优先级错乱
- 错乱:提高某个任务的优先级,之后又接口推迟真正急迫的任务;
- 自我麻醉的谎言,不能面对真正要做的事情;
死胡同
- 所有人都有可能遇到死胡同,你对这个决定越是坚持,浪费的时间越多; TimeBox
- 慎重的态度和积累的经验可以帮你避免死胡同,有足够的勇气回头,掉进坑里,别挖;
泥潭
- 泥潭减慢你的速度,不会让你彻底停下来,阻碍你前进,如果使劲全力,仍有进展;
- 要可以回头修正设计,也可以继续走下去; 走回头路看起来代价很高,是最简单的方法;
- 发现自己身处泥潭,仍要固执前进,是严重的优先级错乱;
第10章 预估
1 什么是预估
- 业务方觉得是承诺; 必须做到,关于确定性的,其他人会当真,据此拟定计划;
- 开发方觉得是猜测;偏差很大,不是个定数,是概率分布
- 莫非定理:如果可能出错,就一定会出错;
2 PERT
- 计划评审技术 Program Evaluation and Review Technique
- 三元分析法: 乐观估计 O; 标称估计:N 悲观估计:P
- u= (O+4N+p)/6
3 预估任务
- 德尔菲法: 一组人集合,讨论某项任务,预估完成时间,然后重复,直到意见统一。
- 亮手指: 伸出0-5手指,相同下一个任务,否则,讨论分歧,重复,意见统一;
- 预估的计量单位,会前确定,天数,或者乘以3等
- 规划扑克:向每位成员法不同的牌,同;
- 关联预估:
- 三元预估;
4 大数定理
- 把大任务拆分很多小任务,分开估计再加总,结果会比单独评估任务要准确很多;提高准确度;
第11章 压力
能回避压力时尽量回避,无法回避勇敢直面压力;
避免压力
- 承诺: 无法兑现业务方作出的承诺,必须要有人承担责任;
- 保持整洁: 让系统、代码、设计尽可能整洁,规避压力;
- 危机中的纪律: 了解自己的信念,危机中遵守这些纪律,困难降临时不改变自己的行为;
应对压力
预见压力、转移压力、消除压力
- 不要惊慌失措: 放松
- 沟通:团队和主管知道你深陷困境中
- 依靠你的纪律原则: 坚信
- 寻求帮助: 结对
第12章 协作
程序员与人
- 人际关系难以处理而且毫无规律,包裹自己,沉浸于思考中
程序员与雇主
- 首要职责满足雇主的需求;
- 最糟糕表现: 两耳不闻窗外事,只顾自己埋在技术堆里
- 专业人士深刻理解业务,协作;
程序员与程序员
- 代码个体所有:重复代码,模块间接口杂乱混淆而非正交;
- 协作的代码共有权: 整个团队共同拥有全部代码:专业人士不会阻止别人修改自己的代码;
- 结对: 分享知识的最好途径
小脑
小脑主要负责协调肌群而不是智商
- 专业人士会共同工作;
- 当工作琐碎无足轻重,个人工作是Ok的;和其他人紧密协作,才是最好的办法;
第13章 团队与项目
只是简单混合吗
- 一个程序员一半为A,一半为B,并不可行;
有凝聚力的团队
- 建立关系,相互协作,支持,激励对方;
- 发酵期: 配合默契,彼此信任; 不拆散团队;
团队、项目何为先
- 围绕项目组建团队不科学,应把项目分给有凝聚力的团队;
如何管理
- 点数;衡量自己的速度
- 紧急情况,改变优先级;
项目承包人
- 项目承包人失去安全感和权力;因为分给凝聚力的团队,同时做多个项目,改变项目的优先级;
- 组建和解散团队是人为的困难,如果优先级更高,应该要快速重新分配资源,承包人的职责所在;
第14章 辅导、学徒期与技艺
失败的学位教育
- 学校里所学的和工作的实际所需,巨大的差异;
辅导
- 手册学习,观察他人工作学习;
- 建立正确的价值观和反思内省;
学徒期
- 大师: 熟练的设计师和架构师;
- 熟练工
- 学徒/实习生:在熟练工的指导下工作,结对编程,学习;
- 现实情况:缺少技术层面的监督;
- 专业主义价值观、技术敏锐度需要不断传授、培育;;
技艺
- 工匠: 经验丰富,堪当重任
- 技艺是工匠的精神状态;
- 觉者觉人:自己成为表率;
参考: 《代码整洁之道-程序员的职业素养》