成为专业的程序员,需要什么样的态度、原则、行动?
本书记录了作者一生所做的“蠢事”,磕磕绊绊成为一名毫不逊色的专业程序员。
1.专业主义
测试工作:编写好代码,没有完全测试就交付了。后期维护所花的时间和精力都是现在的几十倍!
对不完美的代码负责,尽可能少点BUG。
不要破坏程序的结构,结构良好的代码更灵活。
所有软件项目要易于修改。
童子军训练守则:每一次检入代码都要比上一次更加简洁。
下面列出了每个专业开发人员必须精通的事项:
设计模式。必须能描述GOF书中的全部24种模式,同时还要有POSA书中的多数模式的实战经验。
设计原则。必须了解SOLID原则,而且要深刻理解组件设计原则。
方法。必须理解结构化设计。
实践。必须掌握测试驱动开发、面向对象设计、结构化编程、持续集成、结对编程
工件。必须了解如何使用UML图、DFD图、结构图、Petri网络图、状态迁移图表、流程图、决策表。
业精于勤。真正的专业人士往往勤学苦干,以求自身技能的纯熟精炼。
学习的第二个最佳方法是与他人合作。一起编程、一起练习、一起设计、一起计划、这样他们可以从彼此身上学到很多东西,而且能在短时间内更高质量的完成更多的工作。
了解业务领域。你未必需要成为该领域的专家,但你 仍需要勤勉,付出相当的努力来认识业务领域。开始新领域的时候,应当读一两本该领域的书,或者与客户、专家交流了解他们的原则和价值观念。
与客户保持一致。客户的问题就是你的问题,每次开发,都应该站在客户的角度去思考。
2.说“不”
专业的程序员遇到需求不能短时间完成时会坚决说不。
Mike:“我要整个登录界面,必须要能登录!”
Paula:“要完成需要2周的时间,现在可以给你做一个假的登录页面。如果你把密码忘记了,也没有办法修改密码的时候发邮箱;页面顶部不能有新闻栏在滚动;帮助按钮和浮出说明不能用;没法保存cookie以便下次登录;也不会有任何权限限制。但你确实可以登录,这样可以吗?”
Mike:“好极了!”
这个例子,他们达成了最佳结果。
为什么重要吗?
需要解释为什么登录要花那么长时间吗?其实,“为什么”远不如“事实”重要。事实是登录页面还需要2周来完成,为什么需要2周,只是个细节。
要有团队精神
格尽职守,意味着当其他队员遭遇困境时你要援手帮助。有团队精神的人会频繁与人交流,会关心队友,会尽最大可能做到尽职尽责。
试试看
“尝试”二字都这么讲究啊!作者的意思是:如果你对上级说了“我试一下”,说明还有余力可施,那么就意味着你在前面的工作中并没有尽全力;意思是你在加把劲可以达成目标;而且,这也是一种表示你将再接再厉去实现目标的承诺,这样压力就由你来扛了。
如果承诺“尝试”,你其实也在承诺将改变自己原来的方案。你是在承认原来的方案存在不足。如果承诺“尝试”,其实是在告诉他们,你有新方案。新方案是什么,你对自己的行为作出哪些改变?你说你“尝试”,那么你的做法将会有什么不同?
如果你此前并未有所保留,如果你没有新方案,如果你不会改变你的行为,如果你对自己原先对估计有充分对自信。从本质上讲,承诺“尝试”就是一种不诚实对表现。你这么做对原因可能是为了护住面子或避免冲突。
3.说“是”
我们常常会因为直觉摔跟头。有时我们轻信他人会说话算话说到做到,但事实上他并没有像承诺但那么去做。
真正的承诺听起来是怎样的?
真正的承诺是说话的人显得在“我”的掌控范围内,而不是表现的自己是某种情势的受害者。说出完全肯定的话语。
未做到言必信,行必果的原因
· 寄希望于别人身上做这件事
你只能承诺自己完全掌控的事。如果你的目标依赖于另一个团队的模块,你虽然无法自己承诺可以完成并无缝集成。但是你可以采取一些具体行动,你可以承诺:和基础设施组长谈谈,彻底理清模块间的依赖关系;在本周内,至少和负责构建的同时碰头三次,确保你对代码改动没有影响;编写自用的构建脚本,对模块进行集成测试。
· 不确信是否真的可以完成
如果无法在发布前修复余留的bug,你也应该坚持采取行动,缩短与最终目标的距离:把bug全部过一遍,努力重现这些bug;和发现bug的QA谈谈,看下bug重现的现场;用本周能支配的时间,尝试逐一修复bug。
· 也有真的无能为力
有些事情你可能没有预料到,这很现实。但如果你仍然希望自己能够不负众望,那就赶紧去调整别人对你的预期,越快越好。
场景:
Marge:XXX任务真的需要在下周一之前完成,真的至关重要。你能在想象其他办法吗?
Peter:这样,周末加班我能保证在下周一早上之前完成任务。甚至下周一早上我还会过来公司看看,确保进度顺利。不过之后我就会回家休息,知道周三才会来上班,你看这样行吗?
总结:
这样很公平,Peter知道自己如果加班的话,一定可以完成代码修改和文档编写的任务。但他也明白,在这之后需要几天休整,才有精力回来继续工作。专业人士对自己的能力极限了如指掌。他们十分清楚自己还能保持效率加班多长时间,也非常明白要付出的代价。
专业人士不需要对所有对请求都回答“是”。但是他们会努力寻找创新都方法,尽可能做到有求必应。当专业人士给出肯定回答时,他们会使用承诺术语,以确保各方面能明白无误都理解承诺内容。
4.编码
能够感知错误非常重要。如果你具备出错感知能力,说明你已经能够非常迅速的获得反馈,能够更快的从错误中学习。作者发现,要精熟掌握一项技艺,关键是要具备“信心”和“出错感知能力”。
下面是作者个人的一套编码原则:
· 编码要聚精会神,因为编码时你必须平衡互相牵制的多种因素。
首先,代码能够正常工作。必须了解当前要解决什么问题以及该如何解决。必须确保编写的代码忠实遵循解决方案。必须管理好解决方案的每一处细节,并且使语言、平台、现有架构以及当前系统的所有问题和平共处。
其次,代码必须能够帮你解决客户提出的问题。很多时候,客户提出的问题其实并没能真正解决他们的问题。这有赖于你去发现这些问题并与客户交流,以确保代码能够满足客户的真实需求。
代码必须要能和现有系统结合的天衣无缝。你的代码不能让系统变得更僵硬、更易碎、更晦涩,必须要落山管理好各种依赖关系。简而言之,编写代码时必须遵循稳健的工程原则。
必须保证其他程序员能读懂你的代码。这不仅包括要写好注释这类事,还包括要精心锤炼代码,使它能够表达你的编程意图。要做到这点很不容易。
同时还要平衡好所有这些关注点颇为困难。长时间维持高度的聚精会神是很有难度的。再加上在团队或阻止中工作时常会遭遇到各种问题与干扰,以及需要留和关注各种日常琐事。总之,编码时无可避免的会收到各种干扰。
在心烦意乱的状态下工作,只会造成严重的浪费。如果感到心烦意乱,千万不要编码。要找到一种方法来消除干扰,让心绪平静。
疲劳的时候,千万不要写代码。奉献精神和职业素养,更多意义上指要遵循纪律原则而非成为时间工作的工作狂。要确保自己已经将睡眠、健康的生活方式调整到最佳状况,这样才能做到每天的8小时工作时间内可以全力以赴。
· 焦虑时写代码
如果我为妻子发生的争吵、客户危机或者家中生病的小孩而感到忧心忡忡,就无法集中注意力。这时我不该写代码,而应该先解除焦虑情绪。
关键所在是学会如何关闭这些“后台进程”,或至少要能够降低其优先级,这样焦虑就不会造成持续的干扰。
我使用将时间分块的方法来解决问题。我会花专门的一块时间,也许是一个小时,来处理造成焦虑的问题,而不是强迫自己忍受着内心的焦虑煎熬继续编程。如果小孩生病来,我会打个电话询问一下情况;如果和妻子之间有争论,我会打电话和她好好沟通清楚;如果出现金钱问题,我会花些时间思考如何才能处理好财务问题。
专业开发人员善于合理分配个人时间,以确保工作时间中尽可能富有成效。也就是说,在家中就应该专门安排时间去解决焦虑,这样就不会把焦虑情绪带到办公室。
流态区(关于高效率状态)
一些曾经进入这种状态但终又从中摆脱出来的人给处了一点儿忠告:避免进入流态区。这种意识状态并非真的极为高效,也绝非毫无错误。这其实只是一种“浅层冥想”状态,为了追求所谓的速度,理性思考的能力会下降。问题就是,在流态区的状态下,你其实没有顾及全局,因此,你可能会做出一些后来不得不推到重来的决策。
我感觉自己要进入流态区时,就会走开几分钟换换脑筋。
中断
假设你在专心工作,有人打断了你,你会怎样回应?你会粗暴相待吗?粗暴相对的回应方式通常是因为流态区所致,你被他人从流态区拉出来。
但是,有时候并非是因为流态区的责任。而只是你正在努力理解一些十分复杂的东西,这要求你必须全神贯注。有一些解决办法可以应对:
结对是用以应对中断的好办法,当你被中断时你的搭档能很快的帮你恢复被打断前的思维。
另一种是采用TDD。如果有一个失败的测试,它就能帮你维护代码进度的上下文。
中断无法避免,总有干扰消耗你的时间。发生这种情况时,要记住一点,也许下次也会轮到你去打断别人请求帮助。因此,礼貌的表现出乐于助人的态度才是专业的态度。
阻塞
有时候,死活就是写不出代码。干坐在电脑前,但什么都写不出来。
这时候,通常你会去找一些其他事情干。去查看邮件,去翻阅推特,去翻看些书,检查进度或者读点文档。
哪些原因会导致这些阻塞呢?前面我们已经谈及许多因素。对于我而言,另外一个主要都因素就是睡眠。如果睡眠不足,我就什么代码也写不出来。其他因素还包括焦虑,恐惧和沮丧等。
· 有一个很简单都好办法可以解决问题,这个办法几乎屡试不爽:结对编程。
· “创造性输出”依赖于“创造性输入”
我平时广泛阅读,不放过各种各样都资料。包括软件、政治、生物、航天、物理、化学、数学等等,不过,科幻小说最能激发我的创造力。
保持节奏
软件开发是一场马拉松。你无法全程一直以最快都速度冲刺来赢得比赛,只有通过保存体力和维持稳定节奏来取胜。专业程序员同样也应该保存好自己的精力和创造力。
· 知道何时应该离开一会
没解决这个问题就不能回家?不,你应该回家。创造力和智力来自于大脑都高速运转。当你感到疲劳时,他们就不翼而飞了。
当你碰到困难而受阻时,当你感到疲倦时,就离开一会儿。
进度延迟
你总有一天会遭遇延迟都情况。管理延迟都诀窍,是早期检测和保持透明。你应该根据目标定期衡量进度,使用三个考虑到多种因素的期限:乐观预估,标称预估,悲观预估。尽量严守这三个时间点。
加班加点
你老板会说加班加点行吗,周末加班行吗?肯定有办法挤出时间准时完成开发需求的。加班确实游泳,而且有时也有必要。但是这么做风险很高,在额外加班20%的工作时间内,其实你并无法完成20%的额外工作。
因此,不应该采用额外加班加点工作方案,除非以下三个条件可以满足:个人能挤出时间;短期加班,最多加班两周;你的老板有后背预案。最后一条最关键。
交付失误
在各种不专业的行为中,最糟的是明知道任务没有完成却谎称已经完成!
定义“完成”
可以通过创建一个确切定义的“完成”标准来避免交付失误。最好的方法是让业务分析师和测试人员创建一个自动化的验收测试,只有完全通过这些验收测试,开发任务才能算完成。
帮助
编程并非易事,越年轻的程序员对此可能越没有什么感觉。毕竟代码只不过是一堆if和while语句,随着经验渐长,你会开始意识到把这些if和while语句组装在一起的方式十分重要。
编程很难,仅凭一己之力无法写出优秀的代码。即使你的技能很高,也肯定能从另外一名程序员的思考与想法中收益。
帮助他人
因此,互相帮助是每个程序员的职责所在。在帮助他人上,不要让自己看起来十分仓促,仿佛只是随便应付,要全情投入到任务中。当你离开时,可能会发现自己从中收获的东西比给予的还要多。
接受他人的帮助
如果有人向你伸出援手,要诚挚接受,心怀感激地接受帮助并诚意合作。不要因为自己进度压力很大,就推开伸来的援手,不妨给他半个小时的时间。如果到时那个人不能真正的帮助你,再礼貌的致歉用感谢结束谈话也不迟。要记住!如同要以乐于助人为荣一样,也要以乐于接受别人的帮助为荣。
辅导
辅导缺乏经验的程序员是那些经验丰富的程序员的职责。培训课程,书本都无法替代。因此,花时间手把手的辅导年轻程序员是资深程序员的专业职责所在。同样道理,向资深导师寻求辅导也是年轻程序员的专业职责。
5.测试驱动开发(TDD)
三项法则:
· 在编好失败单元测试之前,不要编写任何产品代码
· 只要有一个单元测试失败了,就不要在写代码;无法通过编译也是一种失败情况
· 产品代码恰好能够让当前失败的单元测试成功通过即可。不要多写。
7.验收测试
需求的沟通
通常业务方会突然更改需求,所以一般需要一个地方记录。
过早的精细化
业务方还没启动项目,就要精确知道最后能得到什么;开发方还没有评估整个项目,就希望精确知道要交付什么。
· 不确定原则:东西画在纸上和真正做出来是不一样的。业务方看到真正的运行情况就会意识到,自己想要的根本不是这样的。一看到已经满足的需求,关于到底要什么,他们会冒出更好的想法。
· 预估焦虑:开发人员也会掉进精确化的陷阱。首先,即便拥有全面准确的信息,评估也通常存在巨大的变数。
“完成”的定义
完成有各种说法,例如已经有足够的信心把这项功能部署到生产系统;可以准备QA程序;已经写完了代码并且跑通了;还没有真正测试过。
专业程序员所说的完成意味着代码都写完了,所有的测试都通过了,QA和需求方已经认可。
怎样达到这种程度的完成,同时不影响迭代的速度?你应该编写整套的自动化测试,他们全部通过意味着满足了所有的要求。专业开发人员会根据自动化验收测试来定义需求。他们与业务方和QA一起工作,确保自动化测试能够真正覆盖完成所需的各项指标。
验收测试
手工测试成本真的太高了,专业程序员会编写自动化测试验收自己的代码。
有许多开源的可以完成自动化的验收测试。借助这些工具,你不是程序员也可以阅读、理解、编写。
验收测试什么时候写,由谁来写?在理想状态下,是由业务方和QA写作编写测试,程序员来检查测试之间是否由冲突或矛盾。但实际上,业务方通常没有时间,或者有时间也难以达到所需要的细致程度,所以他们通常会把测试交给业务分析员、QA和开发人员。
如果只能由开发人员来写测试,应当确保写测试的程序员与开发测试功能的程序员不是同一个人。
通常,业务分析员测试“正确路径”,以证明功能的业务价值;QA测试错误路径、边界条件、异常、例外情况。
测试的协商与被动推进
写测试的人也是普通人,也可能犯错误。身为专业开发人员,与编写测试的人协商并改进测试是你的职责。绝不能被动接受测试,更不能对自己说:“测试是这么要求的,我就这么办”。请记住,你的职责是协助团队开发出最棒的软件。也就是说,每个人都需要关心错误,并协力改正。
验收测试和单元测试
验收测试不是单元测试。单元测试是程序员写的,它是正式的设计文档,描述了底层结构及代码的行为。关心单元测试结果的是程序员而不是业务人员。
验收测试是业务方写给业务方的(虽然可能最后是身为开发者的你来写)。它们是正式的需求文档,描述了业务方认为系统应该如何运行。关心验收测试结果的是业务方和程序员。
尽管两者测试的可能是同一个对象,其机制和路径却是不同的。单元测试是深入系统内部进行,调用特定类的方法;验收测试是系统内部,通常是API或者是UI级别进行。
单元测试和验收测试首先是文档,然后才是测试。它们的主要目的是如实描述系统的设计、结构、行为。但是,它们真正的价值不在测试上,而是在具体指标上。
图形界面与其他因素
尽可能的减少GUI测试。GUI很容易变化,GUI测试越多,维护它们的难度就越大。
持续集成
务必确保在持续集成系统中,单元测试和验收测试每天都能运行好几次。整套持续集成系统应该由源代码管理系统出发。只要有人提交了代码,持续集成系统就会开始构建,并运行所有的测试,测试结果会用电子邮件的方式发送给团队所有人。
持续集成如果失败了,团队里的所有人都应该停下手机的活,看看如何让测试通过。在持续集成系统里,失败的集成应该视为紧急情况。
总结
交流是件麻烦事。尤其是开发方和业务方交流关于程序的细节时,更是如此。通常,各方握手言欢,以为其他让都明白自己的意思。双方以为取得了共识,然后带着截然不同的想法离开,这种事太平常了。
要解决开发方和业务方沟通问题,我所知的唯一有效的办法是编写自动化测试的验收测试。这些测试很正式,所以结果具有权威性。它们是无可挑剔的需求文档。
9.时间管理
严格的时间管理的例子:
· 我每天早上5点起床,骑自行车上班,6点可以到办公室。这样,在一天的嘈杂开始之前,我有两个半小时安静时间。
· 一到公司,我就拟定当天的计划。以一刻钟为单位,写下这段时间要做的事情。
· 头3个小时安排的很满。每小时都会流出15分钟的激动时间,这样可以处理计划外的紧急状况,同时也不干扰计划内的工作。
· 午饭后的时间没有安排,因为那时候工作节奏并不快,我也得静心准备下午的工作。午后这段时间难得没有任何干扰,我会安心做最重要的事情,直到突发状况出现。
会议
会议的成本是每人每小时200美元。这个数字包含了工资、福利、设备损耗等因素。下次开会,不妨算算会议的成本。
有两条真理:会议是必须的;会议浪费了大量的时间。
拒绝
受到邀请的会议没有必要全部参加。参加的会议太多,只能证明你不够专业。你应该理智的使用时间,所以必须谨慎选择,应该参加哪些会议,礼貌拒绝哪些会议。
邀请你参加会议的人并不负责管理你的时间,为时间负责的只有你。所以,如果你受到会议邀请,务必确保出席会议可以给自己目前的工作带来切实且显著的成效,否则不必参与。
确定议程与目标
有时候确实需要所有参与者坐在一起来实现某个目标。为了合理使用与会者的时间,会议应该有清晰的议程,确定每个议题所花的时间,以及明确的目标。
如果收到会议邀请,务必弄清楚指定的议题是什么,每个议题花多长时间,要取得什么成果。如果得不到确切的答案,你可以礼貌拒绝。
迭代计划会议
在敏捷开发武器库中,这大概是难度最大的会议了。如果做的不好,可能浪费大量的时间。开好这种会议需要技巧。
迭代计划会议是用来选择下一轮迭代中实现的开发任务。在会议召开前必须完成两项任务:评估可选择任务的开发时间,确定这些任务的业务价值。如果组织得足够好,验收/组件测试也应当在会议召开前完成,或者至少要有概略方案。
凭我的经验,每轮迭代中,这类会议所花的时间不应当超过5%。如果一周为一个迭代周期,这类会议时间应当限制在2小时内。
迭代回顾和DEMO展示
这类会议在迭代的末尾召开。团队成员讨论本轮迭代中什么做的对,什么做的不对。业务方可以看到最新工作成果的demo。如果组织不当,这类会议可能浪费很多时间,所以不妨在最后一天下班前45分钟召开。20分钟回顾,25分钟来演示。请记住,这类会议只牵涉到最近一两周的工作,所以没有太多内容要讨论。
争论
Kent Beck 曾告诉我一个深刻的道理:凡事不能在5分钟内解决的问题,都不能靠辩说解决。争论之所以要花更多的时间,是因为各方都拿不出足够有力的证据。所以这类争论依据的不是事实,而是信念。
技术争论很容易走入极端。每一方都有各种说法来支持自己的观点,只是缺乏数据。在没有数据的情况下,如果观点无法在短时间内达成一直。唯一的出路是:用数据说话。
有人会表现的非常被动。他们同意结束争论,之后却消极对待结果,拒绝为解决问题出一份力。他们会安慰自己:既然其他人想这么办,就这样吧。这可能是非专业的行为中最糟糕的了。千万不要这样做。如果你同意了,就必须拿出行动来。
要小心这类会议:它们的目的是发泄情绪,或者让大家站队。如果会议上只有一面之辞,就要避免参加。
注意力点数
编程是需要持续投入精力和注意力的智力活动。注意力是稀缺的资源,它类似于魔力点数。如果你用光了自己的注意力点数,必须花一个小时或者更多时间做不需要注意力的事情,来补充它。
忧虑和分身也会消耗注意力点数。昨晚上的夫妻吵架,今儿早上的汽车剐蹭,上周忘记付款的账单,都会迅速耗光你的注意力点数。
睡眠
睡眠的重要性怎么强调都不为过。好好睡上7个小时。专业开发人员会安排好他们的睡眠,保证清晨有饱满的注意力点数去上班。
恢复
在你不集中注意力的时候,注意力点数可以缓慢恢复。漫步一段长路,与朋友聊天,看看窗外,都有助于恢复注意力点数。
或者沉思,反省,小睡一会。
时间拆分和番茄工作法
我用来管理时间最有效办法之一。其基本思想:把计时器设定到25分钟,倒计时期间不要任何事情打扰你工作。如果电话响了,接起来并礼貌告诉人家,请25分钟后打过来;如果有人来打断你的问题,礼貌的问他是否能过25分钟再来问。
计时器响后,停下手上的工作,去处理25分钟内遇到的其他的事情。之后休息5分钟。然后,在把定时器设定为25分钟,开始新的一个番茄时间。每完成4个番茄时间,休息30分钟左右。
总结
专业开发人员会用心管理自己的时间和注意力。他们知道优先级错乱的诱惑,他们也珍视自己的荣誉,所以会抵制优先级错乱。他们永远有多种选择,永远敞开心扉听取其他解决方案,他们从来不会执拗于无法放弃的解决方案。
10.预估
问题在于,不同的人对预估有不同的看法。业务方觉得预估就是承诺。开发方认为预估就是猜测。两者相差迥异。
预估个是一种猜测。它不包含任何承诺的色彩。它不需要做任何约定。预估错误无关声誉。我们之所以要预估,是因为不知道到底要花多长时间。
不幸的是,大多数开发人员都很不擅长预估。这不是因为他们没有掌握关于预估的诀窍—根据没有这样的诀窍。预估的偏差总是很大,原因在于我们并不理解预估的实质。预估不是定数,预估的结果是一个中概率分布。
专业开发人员能清楚的区分预估和承诺。只有在确切知道可以完成的前提下,他们才会给出承诺。此外,他们也会小心避免给出暗示性的承诺,他们会尽可能清楚的说明预估的概率分布,这样主管就可以做出合适的计划。
11.压力
不要惊慌失措
正确的应对压力。长夜漫漫无心睡眠,无助于更快的解决问题。呆坐着烦躁不按也于事无补。而你可能最会犯的最严重的错误就是鲁莽仓促。要避免产生孤注一掷的想法。相反,要放松下来。对问题深思熟虑,努力寻找可以带来最好结果的路径。
沟通
让你的团队和主管知道你正身陷困境之中。告诉他们你所定制的走出困境的最佳计划。请求他们的支援和指引,避免制造意料之外的诧异。
依靠你的纪律原则
当事情十分困难时,要坚信你的纪律原则。之所以你会将之奉为纪律,是因为它们可以指引你度过高压时期,这时候要更加留意全部的纪律原则。
寻求帮助
当你头难发热时,结对编程会让你前进的更快,而缺陷更少。结对伙伴会帮助你坚守原则纪律,防止你手足失措。搭档会捕捉住你疏忽一楼的事情,会提出有帮助的想法,会在你注意力迷失的时候接过你手中的工作继续前进。
总结
应对压力的诀窍在于,能回避压力时尽可能的回避,无法回避是则勇敢直面压力。
12.协作
当团队成员能够十分专业的互相协作时,整个团队是最为高效的。
也许我们不是因为编程可以和人互相协作才选择从事这项工作的。但真不走运,编程就意味着与人协作。我们需要和业务人员一起工作,我们之间也需要互相合作。
网友评论