阅读:4919次   评论:0条   更新时间:2011-05-26    
书名:软件开发者路线图—从学徒到高手
原书名:Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman
作者:(美)Dave H. Hoover;Adewale Oshineye 著
译者:王江平 译
ISBN:978-7-111-31006-8
定价:35.00元
出版社:机械工业出版社
上市时间:2010年8月
豆瓣网讨论地址:http://book.douban.com/subject/4924164/
China-pub预订地址:http://www.china-pub.com/196977


内容简介:
作为一名软件开发者,你在奋力推进自己的职业生涯吗?面对今天日新月异和不断拓展的技术,取得成功需要的不仅仅是技术专长。为了增强专业性,你还需要一些软技能以及高效的学习技能。本书的全部内容都是关于如何修炼这些技能的。两位作者Dave Hoover和Adewale Oshineye给出了数十种行为模式,来帮你提高主要的技能。
本书中的模式凝结了多年的调查研究、无数次的访谈以及来自O’Reilly在线论坛的反馈,可以解决程序员、管理员和设计者每天都会面对的困难情形。本书介绍的不只是经济方面的成功,学徒模式还把软件开发看成一种自我实现的途径。读一读这本书吧,它会帮你充分利用好自己的生命和职业生涯。
厌倦了自己的工作?去找一个玩具项目来帮你重拾解决问题的乐趣吧,这叫“培养激情”。
感觉要被新知识淹没了?做点以前做过的事情,重新探索一下自己熟悉的领域,然后通过“以退为进”再次前进。
学习停滞了?那就去寻找一支由富有经验和才能的开发者组成的团队,暂时呆在里面“只求最差”。


作者简介:
Dave Hoover:Obtiva首席技师,喜欢在开发软件的同时培养软件开发者,他的专长是向企业家们交付项目。
Adewale Oshineye:软件工程师,从事过包括电子零售商销售网点系统、投资银行交易系统在内的各种大型项目开发。

专家推荐:
“了不起的作品!阅读本书就像置身于一部时间机器中,把我带回软件开发者职业生涯中的那些关键的学习时刻,那时,学习最佳的实践方法不需要通过艰苦的方式,在我从学徒到高手的每一步上,都有良师益友坐在旁边。我当然乐意把这本书介绍给大家。我多么希望14年前就拥有了这本书!”
——Russ Miles,OpenCredo CEO

本书解决的问题:
为立志成为软件开发高手的程序员量身定制
帮助刚进入软件行业的程序员修炼软技能和高效学习方法

寄语:
厌倦了自己的工作?去找一个玩具项目来帮你重拾解决问题的乐趣吧,这叫“培养激情”。
感觉要被新知识淹没了?做点以前做过的事情,重新探索一下自己熟悉的领域,然后通过“以退为进”再次前进。
学习停滞了?那就去寻找一支由富有经验和才能的开发者组成的团队,暂时呆在里面“只求最差”。



第1章 绪论 Top

本章内容
  ·  什么是软件技能
  ·  学徒期是什么
  ·  学徒模式是什么
  ·  模式来自哪里
  ·  下一步做什么

    学徒期(apprenticeship)很重要,因为它能把掌握技能的毕生热情灌输给你。它把永远学习的热情灌输给你,并且在此过程中,使软件学徒变成了卓越的开发者。
——Pete McBreen ,《Software Craftsmanship 》(软件工艺)

    本书是写给软件学徒(apprentice )的——写给对软件开发有一定体验并想继续深入,但同时又需要有人指导的那些人。无论你在享有声望的计算机科学专业拥有大学学历,还是完全靠自学的人,你看到世界上有一些优秀的开发者,而且渴望获得他们所拥有的精湛技能,那么本书就是为你而写的——不是为你的老板,不是为你的团队主管,也不是为你的教授。对于那些位置上的人,我们有很多其他的书可以推荐,但这一本是为刚刚启程的人准备的。
    在写作本书的过程中,我们被《Software Craftsmanship 》一书中的基本原则和思想深深影响。事实上,本书的书名也反映了这一点。学徒期的概念源于中世纪的手工艺模式,那时一小组从业者在一起工作,经验较少的学徒帮助学徒期满的熟练工(journeyman )和师傅(master) 完成工作。我们写作本书的目的之一就是鼓励那些热爱创作软件的人专注于他们的技能。这里我们所讨论的职业过程是从“Hello World! ”开始,但它何时结束呢?经常的情况是:一次向中层管理职位的晋升结束了这一过程。太多有才能的人未经深思熟虑就接受了这种职位晋升,然后在短短的几年后发现他们根本不热爱自己的工作,并开始向往退休的日子。而对那些拥有熟练的软件开发技能并热爱学习的人们来说,软件开发将是可以持续一生的职业,而且会是一次风光无限的旅程。
    在旅程开始之前,我们想告诉你Dave 译注1的故事,并提供一些解说。他的故事展示了一种组合使用各种模式的方式,通过这些方式,不同的学徒模式结合起来产生强大的外力来促进软件开发者的个人成长。另一方面,这些解说是一种尝试,尝试将形成软件技能基础的一整套思想收集在一起,尝试回答跟这些思想有关的常见问题。
Dave 的故事(讲述中包含了几个学徒模式的名字)
    我的“入门语言”是Perl ,但那也是之前两次学习编程失败之后的事。12 岁时,在观看了电影Tron 译注2之后,受到“一个完整的世界存在于我的电脑中”这种想法的激发,我尝试在自己的Apple IIe 机器上自学BASIC 。我买来一本由Apple 公司出版的BASIC 手册,但我想不出如何用这门语言做点让人觉得有趣的事情。当认识到除了基于文本的游戏,我根本写不出任何其他东西时,最终我放弃了。之后在25 岁时,我阅读一本傻瓜书译注3来尝试自学Java ,并慢慢地做各种练习,创建Java applet 。结果我感觉自己真的成了个傻瓜,一切看起来都是那么难,我因此又放弃。直到26 岁时,我找到了两位指导者,我的第一门语言才算学会了。那是在伊利诺伊州斯科基市,在“dot-com ”泡沫的浪尖上,我在Edventions 有限责任公司遇到了这两位指导者。公司的创始人Irv Shapiro 知道我想成为一名程序员(他当时雇我做在线内容编辑)而且需要让我学习Perl ,扑通一声,他把一本《Programming Perl 》(http:// oreilly.com/catalog/9780596000271/)(Perl 语言编程)放在我的桌子上,并描述了一个“质脆玩具”作为我的练习作业。接下来的几天里,我啃完了《Programming Perl 》,虽然对于像我这样的新手来说,这是本相当厚的书。为了继续探究Perl ,我从自己的阅读列表中挑了一本消化起来更容易的可视化快速入门指导(Visual QuickStart Guide )系列的书。我的另一位指导者是Steve Bunes, Edventions 公司的CTO ,他时常坐下来与我“密切交往”,为我演示一些强大的调试技术,直到今天我还使用这些技术。在我完成第一版“质脆玩具”的过程中,最难运用的一个模式就是向旁边工作间中的那些有经验的Perl 程序员和系统管理员“暴露无知”。

译注1: 本书作者之一David 的自称,英语中Dave 是David 的昵称,同样后面提到的Ade 就是本书的另一位作者Adewale 的昵称。
译注2: Tron ,中文名“电子世界争霸战”,Steven Lisberger 导演,1983 年上映的一部电影。讲述黑客Kevin 寻找安全系统程序Tron 助自己毁掉主脑操控程序,从而让虚拟世界和现实时界都恢复秩序的故事。
译注3: 傻瓜书(Dummies )系列是由John Wiley & Sons 公司出版的系列书籍,所涉及的学科门类范围很广,如编程语言方面的《C for Dummies 》、《C++ for Dummies 》、《Java for Dummies 》等。
    但收起自己的面子是值得的,因为他们给了我一些快速的指导,使我弄清了程序中的一些问题,并理解了UNIX 文件权限,这使我很快地完成了“质脆玩具”,让Irv 和Steve 大吃了一惊。
    两年之后,我开始寻找一些机会,让自己的职业生涯超越我心爱的(但也越来越无法升值的)Perl 并学习一些新技术。我一头扎进了极限编程(Extreme Programming,XP )和敏捷开发(Agile Development )中,让自己“提高带宽”,那时,极限编程和敏捷开发还处在宣传周期(Hype Cycle )的高潮中。我花了几天时间参加附近一所大学的XP/ 敏捷讨论会,从那里吸收新的信息。会见和聆听像Ron Jeffries 译注4、Martin Fowler 译注5、Bob Martin

译注4:
Ron Jeffries,XP 的3位奠基者之一,“敏捷宣言”最初的17 位签署者之一,著
有《Extreme Programming Installed 》,《Extreme Programming Adventures
in C# 》等书。

译注5:
Martin Fowler ,企业级软件领域的著名作者、演讲人和咨询师,著有
《Refactoring 》,《UML Distilled 》及《Analysis Patterns 》等软件领域的名
著,几乎本本都是畅销书。

    软“大叔”、Alistair Cockburn 译注6和Kent Beck 译注7面对这样的人,简直是一种令人陶醉的享受,我从讨论会中出来后便成了正式的面向对象和极限编程的超级崇拜者。我发现Joshua Kerievsky 正在写作《Refactoring to Patterns 》(重构与模式),这听起来真让人钦佩,于是我找了个“同道中人”一起学习。很快,我们发现我们都跑在自己前头了,因为我们甚至还不知道重构和模式是
什么。于是我开始寻找更适合自己经验水平的书。最终找到了《Object-Oriented Software Construction 》(影印版《面向对象软
件构造》,机械工业出版社引进)和《A Pattern Language 》(建筑模式语言)。我还是想以后再回过头来再看看《Refactoring to Patterns 》,于是把它加到了我的阅读列表中。

    还是跟那个“同道中人”一起,我从2002 年开始学习Ruby ,但我无法找到很多在日常工作中使用Ruby 的途径,直到出现了Ruby on Rails 。2005 年,我再次拾起Ruby ,努力寻找一些在日常工作中使用它的方法。我开始用它构建一个“质脆玩具”,却发现自己的思维方式太像Perl 程序员。对于任何一个精通其“入门语言”的程序员来说,当他学习一门新的语言时,都会遇到求 助于已有语言的标准和惯用法的诱惑。Ruby 拥有优雅、简洁的美誉,而我所写的代码让人感觉既丑陋又蹩脚,这让我觉得自己是在做错误的事情。我刻意决定系上“白色腰带”,于是把自己的Perl 经验丢在一边,开始深入钻研Ruby 文档。之后,我很快明白了我需要的是什么,并将那些费解的代码重构成精良、标准的函数调用(Ruby 程序员们好奇了?就是String #scan 那样的)。为了让所有这些新知识留在我的大脑中,我决定“暴露无知”:在网站上记下了自己学到的东西,让所有的人看。注1

译注6: Alistair Cockburn ,敏捷运动的发起者之一,著有《Agile Software Development 》、《Writing Effective Use Case 》等书。
译注7: 极限编程和测试驱动开发的缔造者之一,“敏捷宣言”最早的17 位签署者之一,著有《Extreme Programming Explained:Embrace Change 》、《Test-Driven Development: By Example 》等书。
注1: http://redsquirrel.com/cgi-bin/dave/craftsmanship/ruby.white.belt.html.

1.1 什么是软件技能 Top

    像工艺(craft )、技能(craftsmanship )、学徒(apprentice )、熟练工(journeyman )和师傅(master )这些简单的词汇,字典中的定义无法满足本书的需要。它们经常形成循环解释(“工艺”解释成“一个技师(craftsman )所拥有的技能”,而“师傅”被解释成“表现出技能水平的人”,而“技能”则被解释成“将手工艺传统中的技师连结在一起的一种品质”),很少基于特定国家行会体系的历史,而且常常被泛化到用于描述通过某种技能构建起来的任何东西。简而言之,这些定义没有排除任何东西,于是也就包含了所有东西。而我们需要的不止这些。

    关于“软件技能”(Software Craftsmanship ),网络搜索引擎列出了61 800 条引用,但对一个寻求职业指导的人来说,这些引用很少有提供有用解释的。让人郁闷的是,许多这样的文章都是由一些善意的程序员写出,他们发现在这些混乱的相关概念中隐藏着一些有用的东西,却没有能力把这些东西明确地提取出来。

    Pete McBreen 的《Software Craftsmanship 》是一次尝试,尝试为软件开发的新颖方法整理出一份宣言,一般认为“软件开发是一门工程学科或一门科学”,而McBreen 的书所瞄准的是那些做事并不基于此种假设的人。但这份鼓舞人心的工作仍有瑕疵。他没有把今天正在实践着的软件技能跟他希望实践的软件技能区分清楚。他也没有把他的愿景(vision )跟“隐形的行会监控高度成熟的行业”这种中世纪的手工艺观念做一个足够清楚的区分。他犯了一个从软件工程的反方向来定义软件技能,并要求读者在二者中做出选择的错误。而我们认为,一种工艺模型可以用更加积极的方式来定义,人们觉得构建软件工程学科还是有意义的,我们的定义不能把这些人排除在外。

    我们从中世纪直到工业革命前盛行于欧洲的手工艺制度(《The Craftsman 》(工匠),第52~80 页)中获得启示。在那种制度中,行会控制着师傅,师傅控制着那些工作和生活在工场中的人。师傅拥有工场并有绝对的权威。在这种严格的等级制度中,位于他们下方的是熟练工。他们通常都是能工巧匠,但仍需完成他们的“杰作”,以此表明他们的技艺已足够精湛,可以做师傅了。

    技工们四处游走,正是借助这一点,新技术才从一个城市传到另一个城市。除了引入新技术,技工们还要监管学徒们的日常工作。学徒们会为一位师傅工作多年,直到他们能证明自己已经掌握了基本技术,并理解了手工艺的价值,从而升级为一名熟练工。不能被安放到行会等级结构中的人是不能合法从业的。

    可以想象,这一系统在今天即使没有违法,也肯定要遭到唾骂,而且根本不切实际。我们不想再重复这种将手工艺制度推到了现代社会的边缘的错误。相反,我们相信完全可以放弃匠人工场的传奇式幻想,而采用现代工艺工作室,在那里我们可以在过去的基础上不断改进,而不仅仅是模仿它。

    我们从敏捷开发运动中学到的经验之一是:仅仅告诉人们去做事情并不能带来长久和可持续的变化。按照你的要求去做事的人如果遇到你的规则没有囊括的新情况,他们马上就会迷失。相反,还是同样的人,如果理解了支撑规则的底层因素,他们就能想出新的规则来适应任何情况。在这里,我们的目标不是简单地交给人们一本讲解规则的书,而是给予他们针对新情况创造新实践,进而将软件开发学科推向前进的能力。

    我们对软件技能的愿景,一部分是价值的提取,针对我们为写作本书所访问的技艺精湛的个人;另一部分是希望的表达,表达我们希望出现的社区类型。书中的思想是这一愿景的起点。因此,当我们使用短语“软件技能”,我们所说的是由一些相互交叠的价值所联结和定义的一整套实践,包括:

. 对Carol Dweck 所做的研究,即提倡“成长型思维模式”(Growth Mindset )的依属。这带来了一种信念:如果你愿意钻研一件事,
你就能做得更好,一切也将得以改善。用她的话说,“努力是使得你聪明能干的东西”(《Mindset 》(心理定向与成功),第16 页),而失败不过是引导你下次尝试不同方法的激励机制。这跟以下信念是相反的:我们每个人天生都带着固定数量的禀赋,而失败就是我们天资不够的证明。

. 基于你从周围世界获得的反馈,始终不断适应并做出改变的要求。Atul Gawande 将这说成是一种“从你所做的事情中寻找不足之处并寻求解决办法”的意愿(《Better 》(更好),第257 页)。

.一种对注重实效而非教条主义的向往。这包括一种肯于牺牲理论上的纯洁性和未来的完美而达到“今天把事情做完”的意愿。

. 一种认为分享知识胜过隐藏独享的信念。这常常关联到对自由和开源软件社区的参与。

.一种敢于实验并被证明错误的意愿。这意味着我们可以什么都试试。我们失败了。然后我们在下次实验中运用这些来自失败的经验。正如Virginia Postrel 所说:“并非每种实验和想法都是好的,但只有尝试新的想法我们才能获得真正的进步。要做的事情总是可以更多。每一次进步都可以被继续改善;每一种新的想法也会使更多的新组合成为可能”(《Future Enemies 》(未来的敌人),第59 页)。

. 一种心理学家称之为“内控倾向”(internal locus of control )的精神。注2这包括掌控自己的命运并为之负责,而不是等待别人给我们答案。

.一种对于个体而不是群体的关注。这不是一场“领导者-追随者”式的运动。相反,我们是一群想要提高自身技能的人,我们发现:争论、反对、分歧(而不是盲从于自诩的权威)正是到达目标的途径。我们相信我们都处在同样的旅途中,我们追寻的是自身的改变,而非世界的改变。这也解释了为什么本书不关注团队的调整,而关注提高自身技能的途径。

注2: http://en.wikipedia.org/wiki/Locus_of_control.

.一种包容性。我们不抵制企业级软件开发、计算机科学或软件工程(事实上,Ade 目前的职位头衔中就含有“工程师”一词)。相反,我们认为,一种有用的系统应该能够从软件开发社区的所有元素中识别并吸收那些最好的思想。

. 我们以技能为中心,而非以过程为中心。对我们来说,拥有高超的技能要比使用“正确”的过程更重要。基于这种思想可以得到一些推论。Gawande 问,“医学是一种工艺还是一种行业呢?如果医学是一种工艺,那么你应该关注如何教产科医师掌握一套工艺技能……你进行研究以发现新的技术。你承认并非每个人都能把事情搞定”(《Better 》(更好),第192 页)。这种思想隐含这样的意思:没有哪种过程或工具能使每个人都同样成功。尽管我们都能提高自己,但我们的技能水平总会有差异。

. 对Etienne Wenger 所谓“情景学习”(situated learning )的一种强烈偏好。注3这种思想是说,软件社区应该尝试抓住像“听力范围内的专家”(Expert in Earshot )这样的模式。注4其要旨是:最好的学习方法,就是同那些使用你要学习的技能来达到某种目标的人处于同一个房间里。这种价值体系针对不同的责任引出了不同的角色,正如后续的部分所讨论的。

做软件学徒意味着什么

    谈到做学徒意味着什么,我们的访谈者之一Marten Gustafson 说得最好:“我猜它基本上是指拥有这样一种态度:对于已经做完或者正在做着的事情,永远都有一种更好、更聪明或更快的方法来完成它。而学徒期就是这样一种状态或过程:不断演进并寻找更好的方法,找到能使自己学会那些更好、更聪明或更快方法的人、公司和情景。”我们认为,拥有这种“不依赖于任何人向你提供方案,靠自己找到处理问题的建设性方法”的内在动力是非常有价值的。Dweck 曾经写过:“它不是一种靠成功来增加并随失败而减少的内在数量……它不是一种我们只需告诉别人他有很高的智商就能给予那个人的东西。它是一种我们为别人提供装备然后让他们自己去获取的东西——方法是教他们重视学习而不是外在的聪明,教他们学会享受挑战,并将错误看作臻于精熟的通道。”(《Self-theories 》(自我理论),第4页)

注3:
http://c2.com/cgi/wiki?LegitimatePeripheralParticipation.

注4:
http://c2.com/cgi/wiki?ExpertInEarshot.


    虽然最理想的情况是把你放在一个拥有学徒伙伴、熟练工和师傅的小团队中,我们对于学徒期的理解并不要求这样的安排。你的学徒过程由你自己掌控,而最终的训练成果就是你的责任感。尽管学徒期的进展过程都由你自己来决定,但是否有人指导,以及指导人的品质也会对你的技能产生持久的影响。

    作为一名软件技师,学徒期是你旅程的开始。在这段时间里,你将首先内向地关注自身,下决心提高自己的技能。虽然你会受益于同伴的关注和经验更丰富的开发者的关注,但你必须学会自我成长,学会如何学习。做学徒意味着什么?本质就是这种对自身的关注和提高自身技能的要求。

    最终,学徒将从一个除了持续学习很少有其他责任的位置成长到一个拥有更多外向型责任的位置,我们一般会相信:这种转变只有在回首往事的时候才能看出来。在某个时间点,学徒得到了师傅或熟练工的评价,并被告知他在社区中的工作和角色已经处在熟练工的位置上了。在这种情况下,其实学徒早已经开始担当更多的责任了,像一只“被水煮的青蛙”,他经历了一种渐进而非离散的转变,从一种状态转到了另一种状态。一些人完成这种转变需要的时间会比别人更长。对某些人来说,这种转变所花的时间甚至超过了整个职业生涯。

做熟练工意味着什么

    在你的技能水平不断进步到新的阶段时,你会保留前一阶段的特征。因此,跟学徒一样,为了在技艺方面不断地进步,熟练工和师傅将保持一种内向的对于自身的关注。同时,另一种新的关注会出现在熟练工身上,那就是对从业者之间关系的关注,以及对团队内外的沟通渠道的关注。以前,熟练工会从一位师傅转到另一位师傅那里,并沿途在不同的团队中间散布思想。现代软件开发的现实是:你会在相当长的时间内与单个团队呆在一起,这时,你会关注如何改善团队内部人与人之间的相互关联。这种关注最终会扩展成一种为身边的人提供指导,并同其他业内人士保持沟通的责任。

    熟练工关注如何构建一些能彰显其技艺进步的更大的应用程序;他在不同的项目和师傅之间移来移去,力求拓展其技艺组合的广度和深度;他力求提升自己在社区中的位置;并努力为成为师傅做好准备。

    熟练工的责任比学徒更广。同样,他的失败也会带来更多的损失。我们将要讨论的模式中有一些并不适于熟练工,这完全是因为对那些视之为指导者的人来说,他负有更大的责任。

做师傅意味着什么

    精通意味着行使学徒或熟练工的所有职能,同时还要关注如何将行业向前推进。“达到技能和技术的炉火纯青”(《The Creative Habit 》(创造性的习惯),第167 页)只是一个开端。精通还包括掌握一种技能,然后把它变成一个能将其他人的技能提升几个数量级的放大镜。这会表现为创造直击软件开发本质的新工具,也可能是训练一代熟练工,使之青出于蓝而胜于蓝。或者,它会表现为我们还没想到的某种形式。总之,师傅将高级技能的获取、使用和分享看成是身为软件技师的重要方面。

    这里所讨论的学徒、熟练工和师傅的定义跟你在任何字典上能找到的都不太一样。这是一些新的解释。但我们相信,我们的软件技能愿景中存在固有的价值,它能够帮助你,使你希望自己有多成功便能有多成功,不管你最终采纳了它们,提高了它们,拒绝了它们,还是遵循了一条完全不同的路。

1.2 学徒期是什么 Top

    最基本的学习情形是这样:一个人帮助一个知道自己正在做什么的人,从而让他学到东西。
——Christopher Alexander 等,《A Pattern Language 》,第413 页

    许多书,包括1945 年版的《Fifteen Craftsmen On Their Crafts 》(十五工匠学艺,第69 页),都描绘了一种学徒训练的老套情景:一个十来岁的小男孩,脸上满是烟灰,在一个铁匠铺子里做工。铁匠,那个粗鲁的、有经验的工匠,在男孩的协助下打造着自己的项目。有时男孩积极地参与到这一过程中;也有时他只是在打扫店铺,但仍然密切注意着正在工作的师傅。最典型的情况是:男孩的学徒期将持续好几年,除了知识、经验和食宿,他很少能得到其他报酬。

    最终,男孩将学到足够的技艺来独立承担一个项目,甚至可能离开他的第一位师傅,到另一家店铺中充当责任更多的角色。学徒期结束时,他将获得一份铁匠的营生,靠自己的手艺来为自己遮风雨、充饥肠,并购置工具。在现今世界上,包含一名熟练的软件开发者和一名新手的学徒训练跟这种旧式的学徒训练已经少有相似之处了。那么,我们现在对学徒期的理解是怎样的呢?它又如何超越那种老套的情景呢?

    明确一点,在本书中我们并不是要向软件开发新手建议理想的做学徒的方法。如果我们是为团队负责人和项目经理写这本书,那么对于构建理想的学徒期提供一些指导是有意义的,因为这些人确实有力量推动这类训练过程。但本书是为软件开发的新人而写的,这些人处在阵地上,想努力搞清楚怎样才能学到他们需要的东西,从而实现一些目标,比如找一份(更好的)工作、完成项目,或者成为一名卓越的开发者。由于大多数新人的经历并不与一种“理想的”学徒期相似,现代学徒期的概念主要是一种心境:你认识到自己处于起始阶段,哪怕你已编程多年;而且你想采取措施从你所处的环境中建立自己的学徒过程。

    大多数人都没有机会参与一次由软件熟练工指导的正式学徒训练。现实中,多数人都只能在不太理想的环境中磨砺他们的学徒过程。他们可能面对傲慢专横或能力不足的经理,精神涣散的同事,无法达成的最终期限,以及条件低劣的工作环境:把新手当苦力,安置在狭窄的长方形隔间里,有一台PC 跟一条很卡的网络连接。本书中所有的经验都来自于那些为达到新的技能水平而不得不克服这类低劣环境的人(就像我们)。在这个行业注意到后面所讲的Pete McBreen 的建议之前,新手仍将需要像本书的这样书籍来帮他们创造自己的学习机会。

    我们可以从容不迫地培养学徒开发者,因为我们面对的是过剩的问题,而不是短缺的问题……如今的开发者数量比我们需要的多,而我们缺少
的是好的开发者。
——Pete McBreen ,《Software Craftsmanship 》,第93 页

    学徒过程是学习如何成为专业软件开发者的途径。特别地,它是学习如何成为你所找到的技能最高超的软件开发者的途径。它包括寻找好的老师并利用在他们身边工作的机会来学习。它是成为一种不同的软件职业者的道路上迈出的第一步,这种职业者想要的绝不只是“称职”。

1.3 学徒模式是什么 Top

    学徒模式(Apprenticeship Pattern )尝试给那些走在职业进步的道路上按工艺模式来工作的人提供指导。所有的模式都是从我们自己和那些我们访谈过的人的经验中提取而来。跟任何好的模式一样,它们会引起你的共鸣,让你觉得这并非玄门独创,因为你周围的人已经在使用它们。这些模式的另一共性是它们的生成性(generativity )。每次你运用它们都会得到不同的结果,如果用在合适的上下文中,它们会改善你的工作环境。它们并不是每次运行都保证得出同样结果的算法。相反,它们是解决一组问题并造出新问题的工具。诀窍在于:你要用自己的判断来选择自己更想解决的问题。

    本书是以模式语言的形式来组织的。模式语言是针对特定领域中常见问题的一组相互关联的解决方法。最初的模式语言是Christopher Alexander 在《A Pattern Language 》一书中所写的,在那本书中,他描述了250 多种用于设计各类建筑的模式,从厨房到房屋到城市甚至社会。Ward Cunningham 译注8和Kent Beck 在1990 年把模式语言引入软件行业,结果引来了大量的文献、书籍甚至聚焦设计模式的学术会议。软件设计模式著作中最有名的例子是“四人帮”写的《Design Patterns 》译注9,而Martin Fowler 的《Refactoring: Improving the Design of Existing Code 》,(重构:改善既有代码的设计)是模式语言方面更好的例子。明确地说,你正在读的这本书并非一本关于如何设计软件的书,而是一本关于如何设计软件开发职业生涯的开端并为你在该领域成就卓越打下基础的书。

译注8:
Ward Cunningham ,美国程序员,世界上第一个wiki 的开发者,设计模式和极限编程方面的先锋。

译注9:
全称《Design Patterns:Elements of Reusable Object-Oriented Software 》,中译本《设计模式:可复用面向对象软件的基础》,机械工业出版社出版,机工出版社还出版了该书的同名影印版和双语版。该书的作者一共有四位:Erich Gamma 、Richard Helm 、Ralph Johnson 、John Vlissides ,常被称为“四人帮”。

1.4 模式来自哪里 Top

    好的软件框架设计考虑的原则之一就是从能够运行的实际系统中提取框架元素。同样,软件设计模式就是从许多运行系统中提取出来的,那些系统中使用同样的方法来解决类似的问题。本书的内容最初提取自Dave 在学徒期中经历的故事,之后基于Ade 的故事做了检验和增补,最后用大约30 位从业者的经验做了检验,这些人的开发经验从两三年到几十年不等。我们与这些人做访谈,目的是检验这些模式是否真是针对常见问题的一般解决方法,顺便也挖掘我们没有认识到的其他模式。我们还参加了多种研讨会(2005 年的PLoP )、亚特兰大敏捷会议,以及ThoughtWorks 的内部会议,以此来帮我们改善这些学徒模式的结构和精确性。最后,我们把这些材料的大部分都在网上免费发布,从社区中寻求反馈。

1.5 下一步做什么 Top

    随着你开始学习模式本身,要记住:你可以基于任意的方式选择、合并或调整它们来适应你的独特情形。要理解:这些模式是针对特定上下文中的特定受众而写的。今后,有些模式会突然变得适合于你,而后,同样又突然间让你觉得不再合适。在你的职业生涯中,学徒期是你关注自身成长超过所有其他东西的一段时间。这是你暂缓直接最大化收入潜力的野心,从而最大化学习机会的一段时间。正因为此,它是一段你可以适当自私自利的时间。一旦这段时间结束,你的优先级将需要调整。你将不再是一名学徒,尽管你仍有很多东西需要学习;而你的优先级需要转向其他人:你的客户,你的同事,还有你所在的社区。

第2章 空杯心态 Top

本章内容
·  入门语言
·  白色腰带
·  释放激情
·  具体技能
·  暴露无知
·  正视无知
·  深水区域
·  以退为进
·  总结

    你没看到杯子已满茶水正往外溢吗?
——年轻的哲学家

    一位年轻的哲学家经过长途跋涉去访问一位禅宗大师。大师同意与他见面,因为哲学家随身带来老师们写着高度评价的推荐函。两人坐在一棵树下交谈,话题很快转到大师可以向年轻人传授什么这个问题上来。大师感受到了年轻人的激情,他温和地微笑着,开始讲述自己的禅定术(meditation technique )。哲学家打断了他,说:“嗯,我明白你在说什么!我们在寺院中使用过与之类似的技巧,不同的是我们使用塑像来定神。”

    当哲学家向大师解释完自己是如何学习并实践禅定的,大师接着往下说了。这一次他试着向年轻人解释人应怎样与大自然和宇宙保持和谐。还没等他说完两句话,年轻人又一次打断了他,并开始谈论自己如何学习禅定术,以及很多很多其他的事情。

    大师再一次耐心地等待年轻的哲学家结束他动情的解说。当哲学家再一次安静下来之后,大师开始讲述如何通过各种情形看出几分诙谐。年轻人见缝插针,又开始讲述他最喜欢的笑话,还有他认为那些笑话可以怎样联系到自己所经历过的场景。

    哲学家说完之后,禅宗大师邀他到室内做一次茶道。哲学家听说过这位大师的茶道技艺与众不同,于是高兴地接受了。跟这样一个人品茶论道,这永远都是特别的礼遇。一直到进入室内,大师都做得完美无瑕,直到他开始往茶杯里倒茶。这时候,哲学家注意到茶倒得比平常满。大师继续往茶杯里倒,茶很快满到杯的边沿了。年轻人不知道该说什么,开始诧异地看着大师。大师仍然继续倒,就像什么也没发生一样,茶开始溢出了,热茶溅到地毯和大师的衣服上。哲学家不敢相信他的眼睛,终于忍不住大叫:“不要倒了!你没看到杯子已满,茶水正往外溢吗?”

    听到这句话,大师轻轻把茶壶放回火炉上,用他那恒久温和的微笑看着年轻的哲学家,说:“如果你带着一只已满的杯子来找我,如何能指望我再给你一些东西喝呢?”

    这个故事是从Michel Grandmont 的“品尝一杯新茶”(Tasting a New Cup of Tea)注1改编而来的。我们在这里重提这个故事是为了阐明成功的学徒所需的一种态度。已有的经验越多,你就越需要更多的努力进入到“空杯”状态,清除思想中的坏习惯,放下对技能水平的自鸣得意,敞开自己,从更有经验的同行那里学习不同的而且常常是违反直觉的新方法。

    本章的模式将提供一些方法,使你能顺利开启学徒期的旅程,并保持开放的思想。系上“白色腰带”表示不管你原来有多少专长,都要维持一种初学者的思想。“释放激情”将推动你跨越诸如灰心、迷茫和沮丧之类的新手障碍,使你敢于深入探究自己的“入门语言”。特定技术领域的“具体技能”会向你敞开大门,为你提供探索后续章节中更高级模式的机会。但不要让自己变得过于舒适!将最后四种模式合在一起使用,从而系统地获取知识,不断拓宽自己的技能领域。让自己在特定技术领域“暴露无知”,从而使注意力集中到下一步要学习的东西上面。然后“正视无知”,让团队和客户看着你雄心勃勃地获取知识。最终你将有机会承担一项冒险的任务,一次跳入“深水区域”的机会,要么学会游泳,要么沉入水底。这听起来挺吓人,但在你的职业生涯中没有比这更好的时机来尝试这类冒险了。当所有这些新知识和新思想的拓展快要把你淹没的时候,“以退为进”很重要,回想一下自己走了多远,开发了多少技能,然后打起精神去占领下一个高地。

注1:
http://www.ironmag.com/archive/ironmag/2000_mg_reality_of_learning.htm.

2.1 入门语言 Top

让大脑放下所有不重要的东西,一种好的记号(notation)
能使大脑关注于高级问题,效果上就相当于提高了
人类的智能水平……任何专业和行业的技术名词,
在那些没经过专门训练的人们看来都是难以理解的。
但这并不是因为它们本身很难。相反,
它们无一例外地是为了让事情更简单才被引入的。
——Alfred North Whitehead ,《An Introduction to Mathematics 》(数学引论)

情景分析

    你刚刚起步,只对一两门编程语言有肤浅的认识。

问题描述

    你感觉自己的职位取决于你是否能交付一套用特定语言编写的解决方案,而且质量上达到队友同样的水准。或者,你想获得一份工作,而这首先取决于你对某一门编程语言的精通程度。

解决方法

    选择一门语言。熟练地使用它。接下来的几年里,这将成为你解决问题的主要语言,而且只要你还在实践,这都是你要磨炼的默认技能。做这个决定是一次挑战。将各种选项仔细权衡一下非常重要,因为这是你构建早期职业生涯的基础。

    如果别人要你去解决一个问题,而这项任务指定要用某种编程语言,那就让解决问题的动力来指导自己的学习。如果你想获得一份工作,而这份工作要求你使用某种特定的编程语言,那就使用那种语言来构建一个玩具应用,最好是个开源项目,这样你所期望的雇主就很容易看到你写的代码示例。不论哪一种,去找一名你知道的、接触得到的而且是最有经验的程序员,以后需要帮助时就找他。解决一个问题是花费几分钟还是几天,就看有没有一个可以随时帮助你的人。但还要记住,不能依赖那个更有经验的朋友来解决你所有的问题。

    在学习第一门语言的过程中,一种改善学习体验的基本方法就是找一个实际问题来解决。这可以使你的学习根植于现实世界,从而为你提供第一个较大的反馈回路(feedback loop )。基于书本或者文章中那些短小的、人为设计的例子来学习是有局限性的,你将失去学以致用带来的好处,毕竟,你在工作中要做的是解决问题。改善这一体验的基本方法是寻求反馈回路。特别地,创建较短的反馈回路能协助测量你的进步。有些语言相比其他语言拥有更好的反馈工具,但不论哪种语言,你都能采取一些措施来搭建一个学习沙箱(sandbox ),然后在里面实验。

    Ruby 中有一个交互式的命令行工具:irb 。Rails 中有script/console 。类似地,Erlang 有erb 。Firebug 提供了很多好用的方法,可以在Firefox 网页浏览器中研究运行时的JavaScript 。许多语言都提供了与此对等的工具。

    有时,这些工具还不够,你需要更大的沙箱。Dave 喜欢在他的IDE 中始终放置一个空的Java 类,当需要研究一个不熟悉的API(Application Programming Interface ,应用编程接口)或者一项新的语言特性时,就可以直接拿来用。

public class Main
{
public static void main(String[] args) throws Exception
{
System.out.println(/* 这里要将要把玩的东西*/)
;
}
}


    当学到足以编写实际代码的时候,测试驱动开发(test-driven development )技术能让你基于小步骤前进,并确保自己的假设被检验。测试驱动开发是如此普及,当发现一门语言没有测试框架时,你甚至会有手足无措的感觉。不要犹豫是否写一些简单的测试来检查你对语言的理解,要么就直接让自己熟悉测试框架。

    从采取近乎愚蠢的小步骤开始;等到你学会更多的东西,步子可以相应地放大一些。例如,Ruby 语言有一项特性,可以把一个代码块应用到一个列表(list )中的每个元素上,并将结果收集到新的列表中。你可以编写如下的代码来明确你对这项特性的理解:

require "test/unit"

class LearningTest < Test::Unit::TestCase

def test_my_understanding_of_blocks_and_procs

original = [1, 2, 3]

expected = [2, 3, 4]

p = Proc.new { |n| n + 1 }

assert_equal expected, original.map(&p)

end

end

    学习测试不一定只为了学习语言;也可以把这一过程用于学习其他人的库如何工作。久而久之,这些开发商的测试(Ade 在伦敦测试自动化会议[London Test Automation Conference] 的一次闪电演讲中使用了这个名字),注2可用来检验当一个库升级到新版本时会不会弄坏你的系统。如果弄环了,这些测试便可指明新库就是问题的源头,因为这些测试使用的功能恰恰是那个库提供的。在一个构造良好的系统中,可以用它们来验证一套库的不同实现是否拥有了你所需要的所有功能。最后,你将不再编写用于学习的测试,而是编写用于检查实际代码的测试,这些测试不再检查你对语言结构和API 是否理解。时间长了,你会发现除了简单的单元测试(unit test )外,还有很多其他技术可用于验证你的工作,以及你跟其他团队成员的交流。

    下面的讨论是关于如何通过学习一门新语言来学习不同的思考方式,但Ralph Johnson (《Design Patterns 》,中译本《设计模式:可复用面向对象软件的基础》[机械工业出版社]的合著者之一)的建议也适用于第一门语言的学习。

问:那假如某个人确实想学习怎样以不同的方式来思考,他该学习什么语言?Ruby 、Python 或者Smalltalk?

答:我倾向于Smalltalk 。但我倾向于什么并不重要。你应该根据周围的人来选择一门语言。你知道周围有谁爱好这些语言中的某一种吗?你可以常与此人交谈吗?或者更好一点,你能跟此人一起做个项目吗?

    就我所知,学习语言的最好方法就是和一位该语言的专家一起工作。你应该根据自己认识的人来挑选一门语言。一位专家就够了,但一定要有一位。

    最佳的情形是:基于一个项目,使用那种语言的项目,你可以经常性地与专家一起工作,哪怕只是每周四晚上一次也行。另一种情形也一样好:你独立完成一个项目,但每隔两周你都在午饭时把代码样本带给专家看。

注2:
Ade Oshineye,“Testing Heresies ”(测试邪说),参见:http://www.
youtube.com/watch?v=47nuBTRB51c#t=23m34s 。


    靠自己也可以学习一门语言,但除非与专家交流,否则你需要更长的时
间来领悟语言的精神。
——Ralph Johnson 谈语言学习注3

    Ralph 的建议与“找人指导”模式紧密相关,而且直接阐明了指导者对你的学习所能产生的影响。因此,在选择第一门语言时,是否能从就近的语言专家那里得到反馈就成了一个首要的考量。还有一点:选择了一门语言,就意味着选择了一个虚拟的实践社区,这个社区里有成型的惯用思想、社交集会方式和沟通机制。你应该利用这种支持网络,这样你就不只是在学习一门语言,而且实际加入了你的第一个“同道中人”社区。开始时,你所拥有的一切就是这个社区所倾向的工作类型,社区的边界,还有社区中的偏见和信仰。当选择学习一门语言时,你应该参加本地的语言狂热者集会(或者访问一个他们经常去的网上论坛),看看自己是否愿意属于这个社区。

    如果能加入一个肯共享代码的社区,带来好处之一就是可以超越对简单语言结构的学习,并开始用惯用的语言思想来表达自己。但这只是开始,每一种语言都有其精妙之处,仅通过阅读别人的代码很难领悟到。

    比如,XSLT 中有“Muenchian 方法”,Perl 中有“Schwartzian 转换”,而C中有“Duff 设备”。这些技术都可以通过阅读代码学到。但是要领悟到它们为何重要,以及何时使用它们,则需要社区分享的经验。有时这种共享池仅存在于口头的传统中,你必须单独去跟一个人交谈才能获得这种知识。有时这种知识仅存在于邮件列表的归档中,或者一本在线的入门手册中,若没有上下文,很难理解它的重要性。在这类情形中,学习语言的新手不得不多年沉浸在社区中,才能把知识的管子接入到这个共享池。但现在这些语言的精妙之处常常被总结在一些书中,像《Effective Perl Programming 》(Addison-Wesley 出版)、《Effective Java 》(Addison-Wesley 出版)(中译本由机械工业出版社出版)、《Effective C++ 》(Addison-Wesley 出版)。在掌握基本语法之后马上阅读这类书籍能大大加速你的学习过程,并帮你避免常见错误。

注3:
http://groups.yahoo.com/group/domaindrivendesign/message/2145.

    所有这些都能帮你深入挖掘第一门语言。几年之内,第一门语言将是你学习其他语言的框架。第一门语言学得越好,下一门语言学起来就越容易。尽管你将主要使用这门语言来解决日常问题并交付软件功能,你还是应该经常花一点时间来延伸自己在正常工作中对它的使用。在非常规的方向上延伸一下语言的使用能帮你发现语言的强项和弱点。

    Eric Merritt 的网志“The Shape of Your Mind ”(你思想的形态)深入讨论了编程语言会对你解决问题的能力产生多么深远的影响。

    从很多方面来说,编程语言都像一种塑形工具,像那些给帕拉卡斯译注1 婴儿塑头盖骨、给汉族女人缠足或者给克伦邦译注2长颈族女人塑颈的东西。在编程语言的情形中,被塑的不是头盖骨,而是我们思考问题、形成想法并把这些想法运用于特定问题的方式。比如说,如果你写只用早期版本的Fortran(Fortran 77 或更早)写过代码,很可能你不知道递归的存在。同样,如果你只用过Haskell ,你对命令式(imperative )风格的循环也会知之甚少。
——Eric Merritt,“The Shape of Your Mind”注4

    深入挖掘入门语言也有危险,那就是深陷其中而止步不前。这门语言将在你整个职业生涯中成为你的“母语”而一直陪伴着你。不要让你对它的精通阻碍了自己对其他语言的学习和使用。健康的职业生涯会把你带入软件开发领域多姿多彩的语言洞天。每一种语言都为你提供了使用不同模式来解决问题的机会。在逐渐超越第一门语言的过程中,你应该寻找机会去学习一些采用迥然不同的方法来解决问题的语言。惬意于面向对象语言的学徒应该探究一下函数式(functional )编程语言。畅然于动态类型的学徒应该钻研一下静态类型。安逸于服务器端编程的学徒应该考查一下用户界面设计。一路走来,你肯定会对某些语言和解决问题的方法产生偏好,但要避免固执的、宗教式的亚文化把你推向一种“一刀切”(one-size-fits-all )的方法。这种语言技能的拓展是向着“师傅”般的博学多艺迈出的第一小步。

译注1:
Paracas ,南美洲秘鲁地名,隶属秘鲁西南伊卡地区皮斯科省。

译注2:
Karen ,缅甸邦名,位于缅甸东南部。

注4:
http://erlangish.blogspot.com/2007/05/shape-of-your-mind.html.

    你不应该“嫁”给任何特定技术,而应该有足够宽的技术背影和经验基础,使自己能针对特定的情景选择好的解决方案。
——Dave Thomas 和Andy Hunt ,《The Pragmatic Programmer 》(程序员修炼之道——从小工到专家),xviii 页

行动指南

    找一份语言规范(specification )来读一读。对某些语言来说,这很简单,去弄一本公开发售的书来看看就可以了。对另一些语言,可能只有一份语法规格给你读。甚至还有一些语言,其规范仅存在于语言的实现中。你可以考虑接受一项挑战:为它撰写规范。

    如果语言的标准库是开源的,你可以采用“使用源码”模式中描述的技巧把它通读一遍。其中代码的质量不见得能给你留下较好的印象,但你要想到,代码的作者那时还没有一个社区提供给他向别人学习的机会,他们不得不摸着石头过河。你可以考虑给他们发送一个补丁来修正你所发现的bug ,另外一种积累语言知识的方法是请教那些与你共事的人,问他们是如何选择自己所精通的首门语言的。然后把他们提供的准则添加到自己在选择入门语言时已经使用的准则当中。

    最后,除了我们前面提及的“Muenchian 方法”、“Schwartzian 转换”和“Duff 设备”,你还可以找到更多这样的惯用法(idiom )。它们都是以某个程序员的名字命名的,这些程序员都曾有一个具体的问题要解决,于是才发明了那种惯用法。试着去追查一下这些惯用法最开始试图解决的问题,然后考虑如何使用自己的入门语言来解决同样的问题。

参考模式

    “质脆玩具”(第5章),“深入挖掘”(第6章),“找人指导”(第4章),“漫漫长路”(第3章),“使用源码”(第5章)。

2.2 白色腰带 Top

    通常,每一步都该有进门的感觉。这是初学者的心——一种正在“成为”的状态。
——铃木俊隆,《Zen Mind, Beginner’s Mind 》(禅者的初心)

情景分析

   你已经深入理解了自己的第一门语言,舒适地享受着自信的状态。同事们发现了你的能力,请你帮忙解决属于你的专长领域内的问题。你为自己的技能感到自豪。

问题描述

    你在努力学习新的东西,但新技能的学习看起来比以前更难了。尽管你已经尽了最大努力,但自学的速度似乎却在降低。你担心自己的个人发展就要停顿了。

解决方法

    在对自己已有的技能保持自信的前提下,当接触到新情况时,你应该先放下已有的知识。正如Yoda 在电影《The Empire Strikes Back 》(星球大战2:帝国反击战)中所说的:“你必须忘记已经学到的东西。”(You must unlearn what you have learned)系上白色腰带译注3,是基于这样一种认识:系黑色腰带的选手知道该怎么做,而系白腰带的练习者别无选择只能去学习怎么做。

译注3:
在许多武术门派中,束白色腰带的代表初级练习者。

    作为一名家庭问题顾问,Dave 采用的方法之一就是保持一种不知道的姿态。遭遇困境的家庭都是在经历一种特殊的情况,尽管接受过相关训练,但Dave 知道自己不可能完全理解那种情况。虽然,在如何促进建设性的提问和交谈方面,他对自己的技能颇感自信,但他也曾学到:在那些家庭所经历的现实问题上,不要相信自己有任何专家知识。这听起来违反直觉,实际上却是在培养一种尊重和好奇的态度,这种态度能揭开意料之外的可能性和解决方案。Dave 不会把解决方案给这个家庭,相反,他的不知道的姿态使他能跟这个家庭形成一个团队,大家一起合作找出解决办法。

    采用这种方法来学习新技术会大大加速你的学习过程。训练自己暂停已经习惯的编程机制,这会使你发现新的可能性。然而,作为一名终将因自己获得高水平技能而感到自豪的程序员来说,向无知退一步并让自己看起来很傻会很痛苦。不过,你不妨考虑下George eonard 在《Mastery 》(精通)的最后几页上说的话:有多少次你担心被人觉得愚蠢而没有尝试新东西?有多少回你担心被人认为幼稚而压抑了主动性?……心理学家Abraham Maslow 发现,那些能把潜力发挥到显著水平的人身上都有一种孩童般的品质。Ashleigh Montagu 使用术语“婴儿化”(neotany )(来自词语“neonate ”,新生儿的意思)来描述像莫扎特和爱因斯坦那样的天才。发生在朋友或自己身上的一些事,我们认为愚蠢,紧锁双眉;但同样的事如果发生在世界著名的天才身上,我们只会觉得古怪,一笑置之;永远不要忘记:可以随便犯蠢的自由很可能是打开天才成功之门的钥匙。

    或者看看下面的例子,一位有10 年行业经验的老手一直保持虚心并不断学习新东西:

    我已经很专业很成功地编写软件长达十年之久,实践TDD 也有好多年,直到有一天,我偶然翻到那本Michael Feathers 编著、Prentice Hall 出版、不幸被命名为《Working Effectively with Legacy Code 》(修改代码的艺术)的书。这本书对我如何编写代码产生了直接而又深远的影响,我给我那个小公司的开发者每人买了一本,并要求他们阅读。从那之后,我的代码库被逐渐改良成一个测试更良好、耦合更松散、适应性更好的系统,对它的开发和维护也带来了更多的乐趣。
——Steve Smith ,电子邮件

    正如Steve 所学到的,我们必须能够放下过去的经验和先入为主,这样才能把新的知识放进来。在你尝试学习第二门编程语言时这尤其困难,因为它可能是你第一次为提高技能水平而牺牲生产率。先前你已经以“空杯心态”解决过一些问题,那时对于解决问题的“正确方法”你几乎没有任何先入之见。现在,在新知识有机会渗入到大脑之前,你必须设法避免将新旧知识混合在一起,并以初学者的心态着手解决新问题。这可能意味着短期内生产率会降低一些,以期在掌握新方法之后能获得技能水平的飞跃。

    为了攀登高峰,你必须离开原来那个稳当的落脚处,放下已经取得的成果,甚至可能需要下滑到一个峡谷中。如果你永远不肯放下已经取得的成果,你仍可能不断取得平稳的进步,却永远不能抵达高峰。
——Jerry Weinberg ,《Becoming a Technical Leader 》
(技术领导之路:全面解决问题的途径),第42 页

    在学习新的语言、工具或业务领域时,培养起这种心态有一种好处:你可以开放地学习如何用合乎惯例的方式表达自己,从而使自己和已有社区的沟通更加流畅。避免了“用各种语言写Fortran 程序”的老问题,对新知识就会有更深刻的理解。这样,最终新旧知识融会贯通之时,你已经处在了更好的位置上,可同时从两个领域获得富有成效的见解。
    以下面的Java 代码为例。这段代码为英国的国家彩票产生随机投注数,方式是打印六个1~49 之间的不同数字。

public class Lottery {

private static final int NUMBER_OF_RANDOM_NUMBERS = 6;

private static final int MAX_RANDOM_NUMBER = 49;

public static void main(String[] args) {
SortedSet randomNumbers = new TreeSet();
Random random = new Random();
while (randomNumbers.size() < NUMBER_OF_RANDOM_NUMBERS) {
Integer randomNumber = new Integer(random.nextInt(MAX_RANDOM_
NUMBER) + 1)
;
randomNumbers.add(randomNumber)
;


}
System.out.println(randomNumbers)
;
}
}


    如果别人要求你用一种稍微不同的语言,比如Io (这种语言被设计成拥有尽量少的语法元素,同时又能被主流程序员接受)来重新实现这一功能,你可能复用很多Java 知识并写下这样的代码:

list := List clone

while (list size < 6,
n := Random value(1 50) floor
list appendIfAbsent( n
)


)

list sort print

    但如果你被要求用一种完全不同的语言,比如J来重新实现它,你会发现这种方法不灵了。只有“系上白色腰带”,接受“在一种没有循环的语言中,肯定会有迥然不同但依然有效的方法来解决问题”这一事实,你才能取得进步。因此,按照J语言中的惯用法,答案是:

sort 1 + (6 ? 49)

    后面我们将给出一些模式,来帮你练习,帮你设计玩具程序,并让你有意识地反思手头的工作。对于你的知识来,这些模式能使你更深入地理解不同部分之间的共性,并构造一些情景,让你能研磨自己的技能,而不必承受维持正常生产率水平的压力。

行动指南

    寻找机会来忘掉一些东西。最好是迫使你放下以前经验的机会。

    比如,找出一个采用某种编程范式(如命令式、面向对象、函数式、面向数组/向量等)编写的程序,然后用一种基于不同范式的语言来实现它。确定新实现遵循了新语言的惯用法。如果你所了解的所有语言都采用相同的范式(如面向对象),那这就是一次学习新范式的机会。

    这种模式解决的不只是编程语言的问题,只不过在这方面编程语言是一个很容易产生误解的领域。你应该去请教一位使用你不所熟悉的编程语言或技术的人,让他帮你解释一下:有你这种特定知识背影的人,通常会对他们的社区产生怎样的误解。

参考模式

    “质脆玩具”(第5章),“不断实践”(第5章),“且行且思”(第5章)。

2.3 释放激情 Top

软件技师们只会雇佣对软件开发工艺
有强烈学习欲望的学徒。


学徒是软件工艺的重要组成部分,因为它带来了能感染所有人的学习激情和学习动力。
——Pete McBreen,《Software Craftsmanship 》(软件工艺)

情景分析

    对于软件开发工艺,你有着无尽的兴奋和好奇心。

问题描述

    你意识到自己对工作的热情远远高于你的同事,你发现自己正在抑制自己。

解决方法

    尽管你缺乏经验(而且恰恰因为你缺乏经验),你会为团队带来一些独特的品质,包括富有感染力的激情。不要让任何人压抑了你对软件工艺的兴奋——它是一种宝贵的财富,它将加速你的学习。

    作为软件开发者,你将不可避免地成为团队一部分,并在此基础上展开工作。在任何组织结构中,都会有一种遵循规范的趋向,对新人而言尤其如此。大多数团队都不会对技术有过热的激情。可以肯定,他们都专注于交付下一个项目,或者改善软件开发周期中的某些让他们头痛的方面。因此,充满激情的学徒常常会屈服于“做人要低调”的外界压力。他们要么完全压抑自己的热情,要么仅在日常工作之余才让它表现出来。

    在相对完善的团队中释放激情当然是有风险的。如果团队士气较低或者团队不欢迎新人,你可能在背后遭遇白眼。对那些认为竞争力比学习能力更重要的人来说,毫无疑问,你会给他们留下不好的印象,特别当你暴露出自己无知的时候。跟任何模式一样,这一模式也不应被盲目运用。团队动态(team dynamics )永远都是需要考虑的因素。如果你发现自己处在一个无法接受你激情的团队中,那么你将需要想些办法来养护自己的激情。

    然而,在一个对学徒的兴奋和贡献持开放态度的团队中,你将能为团队输入独特的品质,而且是有经验的开发者可以依赖的品质,比如自由的想象力和激情。在你的整个职业生涯中,只有这段时间冒冒风险,大声讲讲自己的想法是最靠谱的。你几乎不会因此失去什么。你的思想、热情将增加团队的智慧,并带来多样性。James Surowiecki 在他的《The Wisdom of Crowds 》(百万大决定:世界是如何运作的?)一书中多次指出:思想的多样性应看作集体智慧的关键因素。

    对航空母舰舰队集体心理的一次有趣的研究显示:要安全地操纵一艘战斗机不断从它上面起降的巨船,需要复杂的、相互配合的行动,而新人在这类行动中扮演重要角色。研究者发现,一个由不同经验水准的人组成的团队更加健康。

    如果把不同的经验水平关联到一起,比如当脑子里没有任何“想当然”的新手与认为自己已纵观全貌的老前辈们更加频繁地打交道时,大家对问题的理解都会加深。
——Karl Weick 和Karlene Roberts ,《Collective Mind in Organizations 》(组织中的集体思想),第366 页

    最后,释放激情是学徒们相对较少的责任之一。你可能不会为团队带来深奥的知识和极高的生产率,但是,为团队注入一些兴奋因素,并对所有的事情表示疑问是你的责任。你(临时)处在一个独特的位置上,拥有新鲜的视角,这使你能提供一些有用的建议,从而改善整个团队。

    学徒向技师学习,技师也向学徒们学习。激情洋溢的初学者不仅能恢复技师的活力,还能从外界带来新的思想来挑战更有经验的技师。精心挑选的学徒甚至能使师傅变得更有成效。
——Pete McBreen ,《Software Craftsmanship 》,第75 页

行动指南

    想想上一次你有一种想法却没有提出来是什么时候。找到那个你本想向她提出的人,向她描述一下自己的想法。如果她帮你指出一些缺点,试着说服她帮你改进。

参考模式

    “暴露无知”(第2章),“培养激情”(第3章)。

2.4 具体技能 Top

拥有知识,与拥有运用知识来创作软件应用的技能和动手能力不是一回事。这就是“工艺”发挥作用的地方。
——Pete McBreen ,《Software Craftsmanship 》

情景分析

    你正打算到一个技艺更高超的技师团队中谋求一个职位,希望他们能提供比现在更好的学习机会。

问题描述

    不幸的是,那个团队并不愿意冒险雇佣一名可能对团队没有直接贡献的人。而且还有另一种可能:你对团队甚至连间接的贡献都不会有。比如说,他们已经把简单的任务全部自动化了。

解决方法

    你应该学会并持有一些具体技能。虽然学徒能把快速学习的能力带给团队,但在技能水平达到一定高度之前,在特定的工具和技术领域拥有具体的、可展示的能力还是会增大团队信任你,相信你能对他们有间接贡献的可能性。

    在需要学会的具体技能中,有些无非就是一些能让你能通过HR 过滤的办法,或者应付一些靠术语游戏来构建团队的经理们。另外一些技能则可以让未来的团队成员们对你放心,相信你能被很好地利用,而且不需要“日常照料”(《Organizational Patterns of Agile Software Development 》(敏捷软件开发的组织模式),第88 页)。具体技能的例子包括使用各种流行的语言编写构建脚本,了解像Hibernate 和Struts 这样的开源框架,基本的网页设计技能,JavaScript ,以及你所用语言的标准库。

    要点在于:你会经常需要“雇佣”一些经理,让他们对选择你有信心的飞跃。具体技能(最理想的情况是你可以带一个玩具应用的实现来面试)使你可以“迁就”他们。你的具体技能就是用来回答这种问题的:“如果我们今天聘用了你,周一上午你能帮我们做点什么呢?”对“入门语言”的深入理解能帮你建立信任度,对团队而言也是很有用的。

    随着你慢慢过渡到熟练工的角色,你将变得越来越不依赖于这些技能,慢慢地别人开始基于你的名声、你以前参与过的项目,以及你能带给团队的更深层品质来雇佣你。在这一天到来之前,你的优点必须更明显一点。

Dave 填补空白

    跟许多很晚才开始学习编程的人一样,我带着一大堆生活经验进入了程序设计领域,远远多于你们这些拥有6个月经验的一般程序员。从以前的职业中,我已经学会了各种人际交流技巧,也有了一些心理方面的感悟。在我作为一名程序员不断前进的过程中,我还是能遇到非常激动地谈起我过去的人,这使我偶尔高估了这些软技能,或者过于关注非技术主题了。的确,我身上的软技能曾经让我过得很好,并在很多情况下对我产生了极大的帮助;但是,为了让自己把大部分精力关注在技术技能方面——那显然是我最欠缺的领域,我那时不得不让这些技能稍微退缩一下。我改换职业并不是因为想成为程序员问题专家;而是因为我热爱制作软件的活动。
——Dave Hoover

行动指南

    针对那些技能让你欣赏的人,收集一下他们的履历(Curriculum Vitae,CV )。你可以直接向他们要一份或者从他们的网站下载。对其中的每个人,找出履历上提到的五种具体技能,确定其中哪些是对你要加入的团队是直接有用的。总结出一份计划,设计一个可证明你掌握了这些技能的玩具项目。然后实施这份计划。

    要养成定期把自己的履历审查一遍的习惯。一边看一边把具体技能提取到一份单独的列表中。你知道吗?许多雇人的经理只会看这份列表中的项目,而不愿看你的经验总结。

参考模式

    “入门语言”(第2章)。

2.5 暴露无知 Top

    明天我要让自己看起来更傻一些,而对此的感觉要更好一些。那种保持沉默并猜测到底发生了什么的作法是行不通的。
——Jake Scruggs 在“My Apprenticeship at Object Mentor” (我在Object Mentor 的学徒经历)中讲到的注5

情景分析

    那些雇你做软件开发并为你支付薪酬的人,需要依靠你来了解你所做的事情。

问题描述

    经理和队友需要对你有信心,相信你能够交付结果,但你对某些需要用到的技术并不熟悉。这样的事情不只会发生在咨询顾问身上。它会发生在所有人身上。你被带进这个团队,或许只是因为你对业务领域有深入了解,或者只是了解团队技术栈的某些其他方面。亦或者你是唯一可用于这项工作的人力了。

解决方法

    向那些依靠你完成工作的人说明:学习过程是交付软件的一部分。让他们看到你在成长。

    根据社会心理学家Carol Dweck 的研究,在大多数工业化社会中,“让人觉得有能力”的思想深深地植入人们的意识中。随着软件日益渗透到日常生活的每个角落,作为开发者,社会越来越依赖于你具有这样的能力。然而,因为经验不足,你有许多无知的领域。你很盲目。你周围的人——你的经理、你的客户、你的同事,更不用说你自己了——都处在交付软件的巨大压力之下。当人们问你完成特性X需要花多长时间时,你能从他们的眼中看到他们多么需要信心。你有很大的压力,想使他们安心,想打消他们的顾虑,让他们知道你很清楚他们想要什么,你将怎样、何时把结果交给他们。

注5:
http://www.jikity.com/Blah/apprentice.htm.

    软件技师通过与客户和同事的紧密联系来打造自己的名声,向难以描述的压力屈服,并对别人说他们想听的话并不是构建紧密关系的好方法。把真相告诉人们。让他们知道你已经开始理解他们想要的是什么,而且正在学习怎样把这样的结果交给他们。如果你想让他们安心,那也应该通过你的学习能力,而不是通过假装知道自己并不知道的东西。这样,你的名声将建立在你的学习能力上,而不是你已经知道的事情上。

    暴露无知,最简单的方法就是问问题。但说起来容易做起来难,如果你要问的人以为你已经知道了答案,做起来就更难。别管那么多,坚持要问!当然,你可以保护自己的自尊,并通过不那么直接的途径来获得所需的知识,但不要忘了,如果采用最直接的可用途径,通往熟练工的道路就可以被缩短。经过时间和实践,直接去问团队里最明白的人会成为你的习性。在暴露无知的同时,你也向团队展现了自己的学习能力。而且,有时他们也能从回答问题的过程中对自己的知识获得新的认知。

一种“不知道”的姿态

    作为家庭问题顾问,我曾了解到:要舍弃自己对别人的生活拥有专家知识的想法,采用一种“不知道”的姿态来接近人们。这是一粒必须吞下的苦药丸,不管你是一名新的家庭问题顾问还是一名新程序员。你的本能告诉你要掩饰自己的无知,装作通晓各种专家知识,但这只会阻碍你的成长,并阻止你完成正在尝试的工作。我把这种经验从一种职业带到另一种职业,这对我很有帮助。实际上,在日常工作中,我已经依赖于这种无知的感觉;它使我知道我正处在正确的位置。我正在成长。
——Dave Hoover

    要习惯这种学习过程。这是一种技能。的确有一些对这种过程感到不舒服的人。这类人不会成为技师,而会变成专家(expert ),即那种专长于某种平台或某一领域,并坚守这一平台或领域的人。由于他们的关注面更窄,这样的专家能在特定上下文中交付功能,而且会做得比其他人都好。让我们这个行业拥有专家当然很重要,这也是必然的事情,但那不是学徒的目标。

    专家技能是我们走的这条漫漫长路的副产品,但不是目的地。在旅途中,技师的工作会接触到数不尽的技术和领域。如果,因为必须或者因为兴趣,他们“深入挖掘”,并在一种或多种这样的技术方面掌握了专家技能,那就再好不过了。这是可以期待的,正如马拉松长跑训练会锻炼出更强壮的腿部肌肉。她不是在锻炼腿部肌肉;她是在锻炼跑步。就像一个行动积极的开发者,在一个Python 项目上做了两年之后,会获得对Python 知识的深入掌握,马拉松运动员健壮的腿部肌肉也只是一种手段,而非目标。

    有些专家不遗余力地只与单一的上下文结合,收缩学习、实践和项目的范围。技师却恰恰相反,他们在拎起一门新技术或者学习一种新领域时,需要有勇气和谦逊来放下已有的专业技能并系上“白色腰带”。

    技师所拥有的重要品质之一就是学习的能力,他们能找出无知的领域并通过努力工作来减少这样的领域。无知就像草地里的秃块,不断散播知识的种子,它就会减少。通过实验、实践和阅读来浇灌你的种子吧。你也可以将这些秃块隐藏起来,因为它们的面积让你感到窘迫,你想把它们遮盖起来以保持自尊不受影响。或者,你也可以选择暴露它们,对自己和依靠你的人保持诚实,并寻求帮助。

    在学徒期结束时,你会深入掌握一些技术的丝线。凭借这些丝线,你可以在少数的平台和领域中编织出健壮的软件应用。师傅则可以用无数的丝线织出一幅锦绣。他无疑会拥有自己最喜欢的丝线和最喜欢的组合,但丝线的数目是巨大的,使得师傅能适应广阔的技术环境。这就是“漫漫长路”会把你带向的地方。相对于掩饰无知以显得自己有能力,暴露然后正视自己的无知能使你更快地纺起那根原本缺失的丝线。

行动指南

    写下跟工作有关,而且自己不甚了然的五件事。将这份列表放到其他人可以看到的地方。然后随工作内容的改变养成不断更新这一列表的习惯。

参考模式

    “正视无知”(第2章),“深入挖掘”(第6章),“漫漫长路”(第3章)。

2.6 正视无知 Top

    如果我们看重独立性,如果在当前体系所包含的知识、价值和态度方面,我们因为自己日益变得从众而感到不安,那说明我们希望创造面向独特性、面向自我导向(self-direction )、面向自发精神的学习环境。
——Carl Rogers ,《On Becoming a Person 》(个人形成论:我的心理治疗观)

情景分析

    你发现了自己的技能空白,跟自己的日常工作有关系的空白。

问题描述

    你需要掌握一些工具和技术,却不知从何开始。在这些工具和技术中,有一些是你周围的每个人看来都已经了解了的,而且别人认为你也了解。

解决方法

    选出一种技能、工具或技术,积极地填补跟它有关的知识空白。

    采用一种对你最有效的方法来做这件事。对于某些人,最好的方法可能是阅读能接触到的所有文献和FAQ ,来获得知识概览。其他人则可能觉得直接动手构造一个“质脆玩具”才是理解一样东西的最有效途径。不管哪种方法适合你,都不要忘了问问周围的“同道中人”和指导者,看是否有人已经掌握了这项技能并愿意分享所学。有时其他人也可能在学习这项技能,跟他们一起工作你会获得更快的进步。到某个时刻,你将在这个新领域达到令人满意的能力水准,这时你就可以做决定了,是继续深入挖掘下去更有成效呢,还是应将注意力转到其他的技能空白上。每天只有24 小时,你无法将每项技能都研磨到很高水平,因此你必须学会在它们中间做必要的权衡。

    这一模式与“暴露无知”紧密相关,但实施它的过程却不会对你的自尊形成那么多挑战,因为它可以私下完成,不会有人发现你不懂的东西。然而,作为一名有志于精通技能的学徒,你也要有“暴露无知”的意愿。单独运用这一模式(即正视自己的无知但不暴露它)是有风险的,那样会怂恿一种不接受失败和学习的文化,因为每个人都在秘密地学习。记住,公开地学习是学徒开始向熟练工跃进的途径之一。在人们能看到的地方学习,到可以向别人传授技能,其间只差一小步。

    即使你成功运用了这一模式,也会有不好的副作用。如果因为想学习如何构造复杂的并行系统,你就用Scala 语言译注4亲手写了一套消息系统,而没有使用现成的产品,维护你代码的程序员可能不会对此大加赞赏。如果他们无法向你提问,因为你正在参加一次学术会议,那他们就更不高兴了。最后,如果因为你的学习需要而妨碍了项目的成功发布,你的老板也不太可能谅解你。总之,你需要保持足够的警觉,不能让你的学徒期成为团队的问题。工艺方法的一个重要方面就是要有一种意愿:把更大的团队利益置于个体利益之上,而不是利用团队和客户来促进个人成长。

    另一方面,也有可能你正视了自己的无知却没有“暴露无知”。如此行事的人在面对自己的无知时只会无辜地耸耸肩,像是在说“就是这样。”这会导致一辈子的谦卑、无知,并过度依赖团队中的其他成员。最后,它会导致这样的团队:每个成员都维护着自己的一丁点知识储备,当问题延伸到另一个人的知识领域时就耸耸肩。

译注4:
一种多机制的编程语言,支持函数式和面向对象编程。

    因此,在该模式和“暴露无知”之间精心地维持平衡非常重要。仅仅正视无知会导致自负的食知动物(infovores ),最终一事无成;而仅仅暴露无知却不视之为需要解决的问题则会导致过度的谦卑和无能。

行动指南

    针对“暴露无知”模式中列出的项目,努力学习其中的每一项,每学会一种就把它从列表中划掉。这些新的知识又会揭示你以前没有注意到的新空白;别忘了把这些新发现的空白也加入列表中。

参考模式

    “质脆玩具”(第5章),“暴露无知”(第2章),“同道中人”(第4章)。

2.7 深水区域 Top

    如果你从来没有一败涂地,那很可能你也没尝试过有价值的东西。
——Christopher Hawkins,“So You Want To Be a Software Consultant?” (你想成为一名咨询顾问吗?)注6

注6:
http://www.christopherhawkins.com/08-30-2006.htm.

情景分析

    迈着安全的小步子前进已经无法让你满足。你开始担心这不是一片高原,只是一段泥沟(rut )。在高原上,你可以通过勤奋的实践来巩固自己的技能,从而达到更高的水准;在泥沟中,平淡无奇的能力终将衰落成碌碌无为。

问题描述

    你需要提高技能和自信,为自己增加成功项目的数量和多样性。你觉得有必要用更大的事情来挑战自己。包括更大的项目、更大的团队、更复杂的任务、新的业务领域,或者去新的地方。

解决方法

    跳进深水区域吧。“一直等待直到自己准备好”会变成一张啥也不做的处方。因此,当你被安排扮演更高姿态的角色或者解决更加困难的任务时,要用双手抓住机会。只有承担艰巨的任务并做一些让人紧张的事情,你才会成长。

    这样做也有风险。如果估算失误,水位高过了你的头顶,那你可能溺水。谢天谢地,在IT 行业,有许多领域你可以冒冒风险,即使失败了也不会损害你的职业生涯。本来是机会,从半闭着的畏惧的眼睛里望去就成了风险。但这并不是教你在简历中撒谎来骗取一份本来无法胜任的工作,也不是让你在没有充分准备的情况下迎接挑战。它意味着当提升或者外部的任务被安排到你头上时,即使面临着极高的失败率,也要勇敢地接受它。为失败做好准备并从失败中振作将为你打开怯懦者永远看不到的大门。

双脚跳入

    我来到这家做这类电信服务交付平台的西班牙公司。我加入的是核心团队,做一些常规工作,没什么挑战性。公司曾经换过一任CTO ,而我对整体的方向就根本不满意。

    我厌倦了,而且下定决心离开这家公司;正在这时,我听说公司要在尼日利亚安排一名咨询顾问。在一次厨房闲聊中,我向他们提及了自己愿意去的想法。

    CTO 和CEO 找我谈话,问我是否愿意接受这种改变。我的合同将会调整,我将不再是一名正式员工。

    他们想让我销售公司的产品,但我并不是一名销售员。然后我读到了一些吓人的报道,说拉各斯(Lagos :尼日利亚首都和最大城市,位于尼日利亚西南部的几内亚湾畔。)是世界上第三大危险城市。这真的让我感到恐惧。但我对自己说,如果真这么恐怖,我大不了当天再飞回来。

    两周后我飞到那里。离开之前,我跟一个在那里生活过的同事聊了聊,这对我很有帮助。或许是我比较冒失或者愚蠢吧,但那些担心确实消失了。或许不只是前面几天,而是连续好多周,我都是如鱼得水的感觉。

    本来计划的是三个月的短期合同,可我在那里呆了整整两年,一直帮助我们的客户。我意识到自己根本不可能在那里销售我们的平台。他们需要的是一些不同的东西。我们的平台对他们不会有帮助,于是,我投入精力来做这件事情,修正了他们的服务,并为他们构建了一套真正适合其需要的平台。

    自从去了尼日利亚,我后来几乎跑遍了西非的所有国家。现在我在伦敦工作。
——Enrique Comba Riepenhausen ,电子邮件

    虽然我们提倡你去尝试自己所能承担的最具挑战性的任务,但你仍要记住:如果水位高过了头顶,你将会溺水。即使在Enrique 的例子中,他让生活做如此重大的改变,但去的地方至少也有个熟人,而且那里还能说母语。你有责任对这种方法的风险做些调整,方法是参考“找人指导”和“同道中人”模式,找到在你需要时能提供帮助的人。

    你也有责任“建立馈路”,从而当挑战性的项目失去控制时,你还可以抓住它并马上获得帮助。运用这一模式的时候,应该让人觉得你很勇敢,而不是很冒失。

行动指南

    按代码行数或开发者的数量来算,你做成功过的最大项目是什么?你独立构建过的最大代码库又是什么?写下这些问题的答案,然后看看能否找出项目复杂性的其他尺度,以及度量项目的其他方法。用这些尺度度量一下自己参与过的每个项目。现在,当下一个项目到来时,你可以把所有的项目画一张图,并找出新项目在其中所处的位置。一段时间之后,你将通过这张图看到自己职业前进的方向,甚至基于这张图来做决策。

参考模式

    “建立馈路”(第5章),“找人指导”(第4章),“同道中人”(第4章)。

2.8 以退为进 Top

    “众里寻她千百度,蓦然回首,那人却在灯火阑珊处。”沿着你蓦然回首时发现的模式向前推进,有时你就能想出新的东西了。
——Robert Pirsig ,《Zen and the Art of Motorcycle Maintenance 》(万里任禅游)

情景分析

    你开始意识到自己的知识是多么匮乏,或者你已接受了新的挑战,但事情并不如意。也可能两者都有。

问题描述

    当你发现了自己的大片无知领域时,感觉自己要倒下了。

解决方法

    退一步,然后再向前冲,就像弹弓打出的石头那样。暂时退回自己的能力范围之内来获得一点镇定。花点时间构建一样你知道如何构建的东西。然后基于这种经验来认清自己已经走了多远,当前的能力有多高。

    学徒期的体验就像坐过山车。你会体验到学习新技术的刺激,还有借助自己的知识和创造力向客户交付价值的刺激。然而,比起一路上遇到的成熟技师和专家,你开始觉得自己的知识是多么匮乏,因此你也会体验到那种心脏跳到喉咙的紧张。这会把人压垮,特别当最终期限已经临近,或者当你在处理产品问题的时候。振作一点。这是“漫漫长路”上正常的、不可避免的现象。战胜能力不足的恐惧正是“暴露无知”和“正视无知”之间的桥梁。

    这一模式跟那些将自己过度拉伸到能力之外的人最有关系。如果你在学徒期基于合理的步伐、逐步增加的责任和技术复杂度前进,那么你不需要接受这一模式的庇护。但如果你真的在挣扎,或者说在深水区域你难以让自己的脑袋浮出水面,那你就应该寻找暂时回退的机会。有时你需要后退一步才能前进两步。这时,要尽可能快地将这种后退的动作转变成前进的冲力,这一点极其重要。这种前进的冲力将表现为你拥有了比昨天更丰富的知识和更高超的技能。

    然而,向后退步也使这一模式的使用带上风险。如果不能清醒地选择一个后退的距离,你会发现,自己不过是向失败的恐惧投降了。更深地投入到已经有能力做好的事情中,会让人非常宽慰。专长带来的回馈是直接而切实的,但这样做的风险不会立即浮现出来,直到有一天你采取任何措施都为时已晚。当你的专长最终变得过时,你将被迫再次面临一大片无知领域,而此时你可能已经失去学习新东西的习惯,重新开始会比原来痛苦得多。在这种情况下,克服那种被压垮的感觉比解决问题本身更困难。

    要避免这种情况,你必须接受这一事实:该模式只是你聚集力量东山再起过程中的一个短期修正。为自己设定一个时间限制(或者说一个“时间盒”[timebox] ),比如“在优化提供数据的SQL 查询之前,我将把接下来的10 分钟用于重构这个页面中的JavaScript 验证。”或者“在学习如何调用这个第三方的SOAP API 之前,我将把接下来的4小时用于实现这个工具的命令行界面。”或者“在开始优化那些Python ‘全局解释器锁’(Global Interpreter Lock )影响到的代码之前,我将把今天剩下的时间用于提高测试的覆盖率。”

    该方案的另一个重要方面是:利用短暂的休息向聚集在你周围的指导者和“同道中人”寻求支持。有了他们的支持,再加上最近一次展现能力的推动,你可以准备得更充分,从而能够应付再次尝试时前进道路上的碰撞。

行动指南

    选择一项你已经非常了解的自包含任务,重新实施它。比如,Ade 喜欢实现缓存算法,因为它可以非常简单,也可以超级复杂。这给他提供了机会,使他能强化自己在设计和算法复杂度方面的直觉。

参考模式

    “正视无知”(第2章),“暴露无知”(第2章),“同道中人”(第4章),“漫漫长路”(第3章)。

2.9 总结 Top

    本章讨论的“无知”、“深水”、“暴露”、“回退”,听起来都比较消极。但无知并不是一件坏事,只要你能意识到并正视它。最坏的情况是你根本不知道自己无知,如果你能意识到自己缺少的东西并补充它,你就向前迈进了一步。要获得扎实的学徒期锻炼,基础之一就是“准确的自我评估”,在评估中你试着确定自己已经走了多远,并记下知识中的空白。你需要对自己已有的能力、需要赶快胜任的技能以及有长期兴趣的知识都了然于胸。后续章节谈到的一些模式,比如“且行且思”,能够帮你维持这种“了然”。最重要的是,要拥抱“漫漫长路”中的这段时间。在职业生涯中,你很少有其他时间可以保持如此的内向关注,并致力于个人的成长。


  • 大小: 25 KB
  • 大小: 38.4 KB
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics