程序员的职业素养,程序员的职业素养之代码整

作者: 冶金矿产  发布:2019-10-06

题图来自Pixabay

图片 1程序员的职业素养之代码整洁之道

2017年最后一周,我按计划把《The Clean Coder》读完了,大约100页左右。

不想成为优秀程序员的码农,那和咸鱼有什么区别?李清照有句诗:生当作人杰,死亦为鬼雄。也许我们不必、也可能永远都不会是最优秀的程序员,但我们至少可以成为一名职业的程序员。我们也想成为一名专业人士

此处悼念1986年1月28日挑战者号航天飞机事故中丧生的七名优秀的宇航员

第6章 练习

这一章的内容是专业人士如何刻意练习。Bob大叔提到40年来他使用的电脑综合性能(内存硬盘容量和速度,显示分辨率的提升;提及能耗价格等的缩减)提升了10的22次方倍,但是实际上计算机程序的本质并没有变化,是可以通过一些基础程序的练习来不断提升自己的技能的。为了让22次方更形象,Bob大叔用了一个乔布斯经常用的技巧,把它转换成人可以理解的其他东西:是从这里到半人马座阿尔法星的距离(以埃为单位),是1美元硬币里的电子数,是地球质量与个人质量的比例。

今天,编译不再需要程序员等待。现在仍然有些程序员必须等待构建,这是悲剧,也是不够仔细的征兆。如今,构建时间应该用秒来衡量,而不是分钟,更不是小时。

构建时间这么细节的问题体现了专业性,比如前段时间大家关注解决的flex编译时间的问题,只是通过申请更好的机器就把整个项目的编译时间从90分钟缩减到20分钟,这应该是最便宜的投资了。不过还没达到Bob大叔说的秒级构建的水平,这里还有进一步提升的空间,但是也需要有专业人士的投入才行,需要学习和尝试下flex的增量编译框架fcsh和flex编译支持maven的工具flexmojos,也许会有帮助。

对于练习方式,作者给出了几种形式,一些练习套路,可以尝试在公司里设计相关的课程。

Chapter 1. 专业主义

接下来大家带着以下问题去阅读此书《程序员的职业素养之代码整洁之道》也可以阅读此文章 本人尽可能将书中精华总结于此文章中

卡塔

在武术里,卡塔是一套设计好的、用来模拟搏斗一方的招式。与之类似,编程卡塔也是一整套敲击键盘和鼠标的动作,用来模拟编程问题的解决过程。联系着不是在解决真正的问题,因为你已经知道了解决方案。相反,你是在练习解决这个问题所需要的动作和决策。

编程卡塔的最终目标,也是逐步练习以达到纯熟。反复的练习会训练大脑和手指如何动作和反应。在不断练习当众,你或许会发现动作的细微进步,或者解决问题效率的小幅提升。

要学习热键和导航操作,以及测试驱动开发、持续集成之类的方法,找整套的卡塔来练习都是相当有效的。

Bob大叔给出了一些卡塔,参考网站

真正的挑战是把一个卡塔练习到炉火纯青,你可以窥见其中的韵律。要做到这一点可不容易。

作为一名“专业人士”,不仅仅是一种荣耀,它更多的意味着义务,正所谓欲戴王冠,必承其重。当项目中有某个“临时工”犯了错误,他大可不必承担责任,只需要摊摊手,说几句自我安慰的话;如果是“职业”人员,你必须为自己写的每一行代码负责,出了bug必须承担相应的责任。
“职业”的程序员也应当有自己的职业道德,Bob大叔把它概括为以下8点:

  • 什么是专业人士
  • 软件专业人事如何行事
  • 软件专业人士如何处理冲突,应对很紧的工期,如何和不讲道理里的管理人员打交道
  • 软件专业人士何时应该说"不" 怎么说
  • 软件专业人士如何应对压力

瓦萨

瓦萨基本可以说是两个人的卡塔。其中的招式需要精确地记忆,反复演练。一个人负责攻,另一个人负责守。攻守双方互换时,各种动作要一而再、再而三地反复。

程序员可以用一种叫“乒乓”的游戏来进行类似的练习:两个人选择一个卡塔,或者一个简单问题,一个人写单元测试,另一个人写程序通过单元测试,然后交换角色。

自由练习

自由练习就是不限制形式的搏击。模拟搏斗与编程并不是特别贴合。不过,很多编程练习场中都会玩一种叫做“自由练习”的游戏。它很像由两个参与者解决问题的瓦萨,只是自由练习是有很多人参与的,而且规则是可以延续的。在自由练习中,屏幕被投影到墙上,一个人写测试,然后坐下来,另一个人写程序通过测试,再写下一个测试。桌子边的人一个个轮流接下去,或者有兴趣的人可以自己排队参加。无论怎么安排,都是非常有趣的。

上面这三种方式,无一不是以TDD的方式进行,和上一章的内容吻合。另外还有在业余时间参与开源社区,也是推荐的练习方法,总之,专业人士需要不断的练习。

无论如何,专业人士都需要练习。他们这么做,是因为它们关心自己能做到的最好结果。更重要的是,他们用自己的时间练习,因为它们知道保持自己的技能不落伍是自己的责任,而不是雇主的责任。练习的时候你是赚不到钱的,但是练习之后,你会获得回报,而且是丰厚的回报。

  • 了解你的领域
  • 坚持学习
  • 练习
  • 合作
  • 辅导
  • 了解业务领域
  • 与雇主/客户保持一致
  • 谦逊

一 专业主义

第7章  验收测试

Bob大叔举了一个和业务人员一起以不断探索的方式写应用程序的例子,并总结了一些经验。其实是再一次阐述了敏捷的一些原则,强调变化是一定会有的,过早精细化是不必要的,业务方自己很可能并不知道自己要什么。应对方式是推迟精细化,用验收测试驱动开发。验收测试要自动化。几年前测试团队做过相关的尝试,当时觉得在验收自动化测试上投入有点高,没有继续进行下去,2018年是不是可以再尝试一下,改变一下PO和BA的工作方法?

Chapter 2. Say No

1.1 专业主义

专业主义的精髓就在于将公司利益视同个人利益.也就是意味着担当责任

验收测试和单元测试

验收测试是写给业务方看的,单元测试是写个程序员的,它们并不重复。它们的主要功能其实不是测试,测试只是附属功能。它们首先是文档,其次才是测试。

职业的程序员敢于与现实抗争,敢于说“不”。尤达说过:“能就是能,不能就是不能。不要说‘试试看’”。如果某项任务你无法胜任,拒绝接受总比临近交付日期才告诉产品经理你无法完成好;同样的,如果没办法在某个时间内完成,就不要说“试试看”。试试看意味着你会尝试着去完成,而大多数人都是乐观主义者,这样说无异于一种承诺。碍于情面的人也许觉得不妥,需要指出的是:“say no”并不意味着拒绝合作,而且为了团队更好的发展。

1.2 担当责任

图形界面的测试

这里提到了增加ID和分层测试服务两种方式,都是以前曾经尝试过的,关键是要找到项目真实的落地。

Chapter 3. Say Yes

1.3 首先不行损害之事
  • 1.3.1 不要破坏软件功能所谓专业人士就是能对自己的犯下的错误负责的人,哪怕那些错误实际上在所难免,失误率永远不可能为零 但是你有责任让他无线接近于零简单的做到以下几点:
    • 尽可能的让 QA 找不出问题
    • 要确信代码正常运行
    • 自动化 QA
  • 1.3.2 不要破坏结构成熟的专业开发人员知道 聪明的人不会为了发布新功能而破坏结构 ,结构良好的代码更灵活, 以牺牲结构为代价,得不偿失, 将来必回追悔莫及所有软件项目根本指导原则是:软件要易于修改

持续集成

这里重点提到的是持续集成的纪律,集成失败必须立即修复,这是优先级最高的事情。实际做起来是需要全员意识上的改变的。

如果你觉得“say no”让你很难为情,那么,“say yes”(做出承诺)也很有挑战性。做出承诺包含了三个步骤:

1.4 职业道德

你应该计划每周工作60个小时, 前40个小时是给雇主的,后20个小时是给自己的, 在这剩余的20个小时里 ,你应该多看书, 练习, 学习, 或者做其他能提升职业能力的事情

  • 1.4.1 了解你的领域
  • 1.4.2 坚持学习软件行业的飞速改变 意味着软件开发人员必须坚持广泛学习才不至于落伍 : 时刻记住不写代码的架构师必然遭殃,他们很快会发现自己跟不上时代了,不学习新语言的程序员同样会遭殃,他们只能眼睁睁的额看着软件业一路发展,把自己抛在后边,学不会新规矩和新技术的开发人员更可怜他们只能在日渐沦落的时候看着身边人越来越优秀
  • 1.4.3 练习业精于勤荒于嬉
  • 1.4.4 合作学习的第二个最佳方式就是与他人合作
  • 1.4.5 辅导俗话说教学相长想迅速牢固的掌握某些事实和观念 最好的办法就是与你负责的人交流这些内容
  • 1.4.6 了解业务领域每开发一个新领域项目的时候 就要了解自己开发的解决方案所对应的业务领域 如果你编写财务系统 你就应该对财务领域有了解,如果你编写旅游应用程序 那么你需要去了解旅游业
  • 1.4.7 与雇主/客户保持一致
  • 1.4.8 谦逊

第8章 测试策略

“QA应该找不到任何错误”,这是对专业人士的要求。QA的主要职责不是发现程序员的错误,保证程序没有错误是程序员自己的职责。那QA做什么?

QA在团队中要扮演的是需求规约定义者(specifier)和特性描述者(characterizer)。

需求规约定义者:QA的任务是和业务人员一起创建自动化验收测试,作为系统真正的需求规约文档。

特性描述者:QA的另一项任务是遵循探索式测试的原则,描述系统运行中的真实情况,将之反馈给开发人员和业务人员。在这项任务中,QA并没有解析需求,而是在鉴别系统的真实情况。

  • 口头上说自己将会去做
  • 心里认真对待做出的承诺
  • 真正付诸行动

二 说 "不"

能就是能 不能就是不能 不要说"试试看" ----尤达

专业人士应该懂得说"不" 事实上 优秀的经理人对于敢于说"不"的人总是求贤弱渴 因为只有敢于说 "不" 的人 才能真正做成一些事情

自动化测试金字塔

专业开发人员遵循测试驱动开发的要求来创建单元测试。专业开发团队使用验收测试定义系统需求,使用持续集成保证质量稳步提升;同时,这些测试又属于全局测试体系。拥有一套单元测试和验收测试的同时,还需要有更高层次的测试,这样QA才找不出任何错误。

Bob大叔给出了五层的自动化测试金字塔,和我们经常看到的三层的金字塔不太一样,从下到上依次是:单元测试、组件测试、集成测试、系统测试、人工探索式测试。

单元测试是程序员自己编写自己使用,并且要做到接近100%的覆盖率,通常在90%以上,并且是真实的覆盖率,而不是那种虽然能通过但并不关心运行结果的错误的单元测试。

组件测试和集成测试都是针对API进行的测试。组件测试针对单个组件,集成测试针对多个组件。组件测试由QA和业务人员编写,开发人员提供辅助。常用的工具是FitNesse, JBehave, Cucumber。针对GUI的是Selenium或Watir等工具。组件测试要覆盖差不多系统的一半,主要是成功路径。异常路径是要靠单元测试来覆盖的。集成测试主要针对大型系统,是编排性测试,主要不是测试业务规则,而是测试组件装配在一起时是否协调。集成测试一般由系统架构师或主设计师来编写,用于确认系统架构层面的结构是否正确无误。集成测试时间运行比较长,一般不会作为持续集成的一部分。

系统测试大约占测试的10%,由系统架构师和技术负责人编写,一般是在GUI层次。

人工探索性测试不是自动化测试,它需要使用人类的创新能力,对系统进行深入研究和探索。预先编写测试计划反而会削弱这类测试的效果。可以考虑一些全员“抓虫”行动。覆盖率不是探索性测试的目标。

“职业的”程序员对自己做出的承诺会做到言必行,行必果,甚至承担相应的责任,职场上可不允许随便说说而已。

2.1 对抗角色

你的经理要求你在明天之前完成登录页面 这就是他在追求和捍卫的一个目标 那是进他的职责.如果你明知第二天之前不可能完成登录页面 嘴上却说"好的 我会试试的" 那么你就是失责了 这时候 尽职的文艺选择是说"不 . 这不可能"

结论

TDD、验收测试这些组合起来,最终目标还是让QA找不到任何错误。

Chapter 4. 编码

2.2 高风险时刻

越是关键时刻 "不"字就越有价值这一点应该不证自明 当公司存亡成败皆系于此时 你必须尽己所能 把最好的信息传递给你的经理 这往往意味着要说"不"

第9章 时间管理

“职业的”程序员应该具备良好的编码能力。代码要整洁、符合规范,特别是在赶进度的情况下。Bob大叔在《Clean Code》(《代码的整洁之道》)中说到,一个外科医生不会因为时间紧急而答应病人的请求——不要洗手就做手术,因为这样并不是职业的做法(更别说犯罪)。同样地,职业的程序员不会因为时间紧急就写出混乱的代码或者上百行代码的函数,这样谈不上快,只会让进度更加慢。整洁的代码也需要从平时不断的训练养成,这方面的书有《The Art of Readable Code》、Bob大叔的《Clean Code》、《Code Complete》。

2.3 要有团队精神

有团队精神的人会频繁与大家交流 会关心队友 会竭力做到尽职尽责

  • 2.3.1 试试看允诺"尝试" 就意味着你承认自己之前未尽全力 承认自己还有余力可施 允诺尝试意味着只要你在加把劲 还是可以达成目标的 而且这是一种表示你将再接再厉去实现的目标的承诺 因此只要你要允诺自己去尝试 你其实就是在承诺你会确保成功 这样 压力就是你来抗了 如果你的尝试 没有达到预期的效果 那就表示你失败了

会议

关于会议,有两条真理:

(1)会议是必需的;

(2)会议浪费了大量时间。

通常,两条真理同时适用于同一场会议。有些与会者认为这两条总结得非常好,有些则认为它们是正确的废话。

你需要为自己的时间负责,所以你需要选择哪些会议参加哪些会议不参加。Bob大叔提到Scrum的四会的问题,相关内容应该可以参考Scrum相关书籍。

Chapter 5. 测试

三 说 "是"

争论/反对

Kent Beck曾告诉我一个深刻的道理:“凡事不能在5分钟内解决的争论,都不能靠辩论解决。”

如果争论必须解决,就应当要求争论各方在5分钟时间内向大家摆明问题,然后大家投票。这样,整个会议花的时间不会超过15分钟。

Bob大叔的书有一个特点(虽然我只看过两本…),他会在不经意中特别地插入测试方面的内容。看他的书都会对TDD有一定的了解,此处略去n个字……
不管是否采用TDD的方式,“职业的”程序员都必须具有一定的测试能力。最为开发人员,写的最多就是单元测试,虽然单元测试不能保证程序一定不出错,但是写好的单测是对自己代码负责的一种体现。如果代码没有测试过就签入代码库,无异于放进去一个定时炸弹。《Code Complete》里面介绍了一些办法,可以在写更少量的单测的情况下覆盖到更多的代码,例如结构化的基础测试。

3.1 承诺用语

做出承诺,要包含三个步骤

  • 1 口头上说自己将会去做
  • 2 心里认真对待做出的承诺
  • 3 认真付诸行动

如果你能够一直信守承诺 ,大家会以为你是一名严谨负责的开发人员 在我们这行中 也是最有价值的评价了

注意力点数

现在是个争抢注意力的时代,每个人最稀缺的资源就是注意力,谁抢到更多的注意力就能赚钱。如何保持注意力?

首先需要保证睡眠。Bob大叔每晚需要睡7小时。年初有几个月我曾经每晚睡5小时,想多争取些时间工作和学习,靠每天早晨的咖啡来支撑,后来发现自己有点扛不住,就尽量往7小时睡眠靠了。前阵子听樊登讲《睡眠革命》,一个睡眠周期时间是1.5小时,如果在睡眠周期中间被闹醒,则整天都会受影响,所以睡眠时间最好是1.5小时的整数倍,一周累积睡到35个周期就没问题。正在尝试中,貌似挺有道理。

肌肉注意力。体力活动需要肌肉注意力,编程需要心智注意力,两者的要求不相同。不过定期训练肌肉注意力可以提升心智注意力的上限。Bob大叔的做法是骑自行车1-2小时,大约30-50km,骑车的时候可以听播客或者音乐。我自己挺喜欢慢跑的,周六的早上慢跑听书是一种享受,也是一种放松。不过进入冬天雾霾重了就没怎么跑了。不过在家里做些俯卧撑也挺有好处。

Chapter 6. 预估

3.2 学会如何说 "是"

和学会说 同样重要的是 要学会说

专业人员不需要对所有请求都回答"是" 不过 他们应该努力寻找创新的方法 尽可能做到有求必应 当专业人士给出肯定回答是 他们会使用正式的承诺 一确保各方能明白无误的理解承诺的内容

时间拆分和番茄工作法

番茄工作法我用过一段时间,有时经常被打断或者自己内心没法静下来;有时又觉得25分钟时间好像有点短,专注的做一件事情时刚进入状态,番茄就结束了。看到有的文章说番茄时间设置成1小时比较好。不过按照Bob大叔前面的说法,其实进入心流状态并不是很好。也许25分钟的番茄钟就是很科学的。

要避免的行为是优先级错乱,或者不按优先级顺序来处理,这个事情在我身上也经常发生,明明知道有个事情是重要的,但总是拖到最后一刻才做,把自己逼到死角,搞得很忙乱。

番茄时间也需要回顾,感觉番茄工作法就是一个人的Scrum。我对自己的回顾就是对于每项事情的预估时间还是经常偏乐观,也许是因为自己有完美主义的倾向。这个和敏捷的思路并不太匹配,造成自己效率不高,需要调整。

软件开发过程中最常出现的问题就是延期交付,因为进度延迟往往导致开发人员需要连续的加班,甚至通宵达旦的赶进度,而这个日期很多时候都是由于项目组过于乐观的预估。

四 编码

死胡同和泥潭

死胡同:比如选择了走不通的技术道路,越是坚持浪费的时间越多。要记得,任何时候都有选择。

坑法则:如果你掉进了坑里,别挖。

比死胡同更糟糕的是泥潭。泥潭会减慢速度,但不会让你彻底停下来。但如果你使尽全力,你仍然可以取得进展。

之所以说泥潭比死胡同更麻烦,是因为在泥潭中,你仍然可以看到前进的道路,而且看起来总是比回头路要短(虽然实际不是这样)。

这两个道理一看就懂,可以如何分辨哪些是死胡同,哪些是泥潭,哪些是需要坚持挺过去的呢?感觉需要大智慧才行啊。

  • 时间预估——三元分析法
    三元分析法是1957年美国海军的潜艇极地航行计划中的一部分内容,是一种对预估的计算方法,这种技术简单而有效,把预估变成概率分布。你可以更具三个数字预估某项任务:

    • O:乐观预估。这是非常乐观的数字,也就是我们经常说的最快时间,快到程序没有异常,开发过程中不会出岔。实际上,为了保持乐观预估有意义,这个数字对应的概率应当小于1%(正常分布下具体数字是3个西格玛或者0.13%)。
    • N:标称预估。这个数字概率最大。如果画一张柱状图,标称预估就是最高的那个。
    • P:悲观预估。这是最糟糕的数字,因为它考虑到各种意外,比如飓风啊,战争啊。为了保证这个数字有意义,它的概率也应当小于1%。

    有了以上三个预估,我们可以这样描述概率分布:
    μ = (O+4N+P)/ 6
    μ 是任务的期望完成时间。
    σ = (P - O)/ 6
    σ 是任务的概率分布的标准差,用来衡量不确定性。数字大就表示非常不确定。
    所以一项任务的预估时间就是 μ/σ 。

4.1 做好准备

编码是一项 颇具挑战也十分累人的智力活动 相比其他类型的活动 编码要求更加聚精会神 因为在编码是你必须平衡互相牵制的多种因素如果感到疲劳或者心烦意乱,千万不要编码 相反要找到一种方法来消除干扰 让心绪平静下来