Tuesday, February 2, 2016

Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman - 软件开发者路线图:从学徒到高手



http://read.lingyu.wang/apprenticeship-patterns/1.html
什么是软件技能

仅仅告诉人们去做事情并不能带来长久和可持续的变化。按照你的要求去做事的人如果遇到你的规则没有囊括的新情况,他们马上就会迷失。相反,还是同样的人,如果理解了支撑规则的底层因素,他们就能想出新的规则来适应任何情况

对软件技能的愿景,一部分是价值的提取,针对我们为写作本书所访问的技艺精湛的个人;另一部分是希望的表达,表达我们希望出现的社区类型。

如果你愿意钻研一件事,你就能做得更好,一切也将得以改善

注重实效而非教条主义
分享知识胜过隐藏独享
敢于实验并被证明错误
掌控自己的命运并为之负责,而不是等待别人给我们答案。

对于个体而不是群体的关注。我们追寻的是自身的改变,而非世界的改变

不抵制企业级软件开发、计算机科学或软件工程。一种有用的系统应该能够从软件开发社区的所有元素中识别并吸收那些最好的思想

我们以技能为中心,而非以过程为中心。拥有高超的技能要比使用“正确”的过程更重要。

最好的学习方法,就是同那些使用你要学习的技能来达到某种目标的人处于同一个房间里。

做软件学徒意味着什么

对于已经做完或者正在做着的事情,永远都有一种更好、更聪明或更快的方法来完成它。不断演进并寻找更好的方法,找到能使自己学会那些更好、更聪明或更快方法的人、公司和情景

做学徒意味着什么?本质就是这种对自身的关注和提高自身技能的要求。

做熟练工意味着什么

熟练工关注如何构建一些能彰显其技艺进步的更大的应用程序。力求拓展其技艺组合的广度和深度;他力求提升自己在社区中的位置。

熟练工的责任比学徒更广。同样,他的失败也会带来更多的损失

做师傅意味着什么

精通意味着关注如何将行业向前推进

达到技能和技术的炉火纯青
创造直击软件开发本质的新工具
师傅将高级技能的获取、使用和分享看成是身为软件技师的重要方面。

学徒期是什么

多数人都只能在不太理想的环境中磨砺他们的学徒过程

寻找好的老师并利用在他们身边工作的机会来学习

下一步做什么

在你的职业生涯中,学徒期是你关注自身成长超过所有其他东西的一段时间。这是你暂缓直接最大化收入潜力的野心,从而最大化学习机会的一段时间
最新最早最热

第二章——空杯心态
成功的学徒所需的一种态度。已有的经验越多,你就越需要更多的努力进入到“空杯”状态,清除思想中的坏习惯,放下对技能水平的自鸣得意,敞开自己,从更有经验的同行那里学习不同的而且常常是违反直觉的新方法。

入门语言

基于书本或者文章中那些短小的、人为设计的例子来学习是有局限性的,你将失去学以致用带来的好处,毕竟,你在工作中要做的是解决问题

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

选择了一门语言,就意味着选择了一个虚拟的实践社区,这个社区里有成型的惯用思想、社交集会方式和沟通机制

如果能加入一个肯共享代码的社区,带来好处之一就是可以超越对简单语言结构的学习,并开始用惯用的语言思想来表达自己。

几年之内,第一门语言将是你学习其他语言的框架。第一门语言学得越好,下一门语言学起来就越容易

在非常规的方向上延伸一下语言的使用能帮你发现语言的强项和弱点。

在编程语言的情形中,被塑的不是头盖骨,而是我们思考问题、形成想法并把这些想法运用于特定问题的方式。第一门语言将在你整个职业生涯中成为你的“母语”而一直陪伴着你。不要让你对它的精通阻碍了自己对其他语言的学习和使用

你不应该“嫁”给任何特定技术,而应该有足够宽的技术背影和经验基础,使自己能针对特定的情景选择好的解决方案。 行动指南

找一份语言规范(specification)来读一读

白色腰带

在对自己已有的技能保持自信的前提下,当接触到新情况时,你应该先放下已有的知识

训练自己暂停已经习惯的编程机制,这会使你发现新的可能性

释放激情

不要让任何人压抑了你对软件工艺的兴奋——它是一种宝贵的财富,它将加速你的学习。

如果你发现自己处在一个无法接受你激情的团队中,那么你将需要想些办法来养护自己的激情。

思想的多样性应看作集体智慧的关键因素。

具体技能

你应该学会并持有一些具体技能。

在技能水平达到一定高度之前,在特定的工具和技术领域拥有具体的、可展示的能力还是会增大团队信任你,相信你能对他们有间接贡献的可能性。 行动指南

确定其中哪些是对你要加入的团队是直接有用的。总结出一份计划,设计一个可证明你掌握了这些技能的玩具项目。然后实施这份计划。

要养成定期把自己的履历审查一遍的习惯。一边看一边把具体技能提取到一份单独的列表中

暴露无知

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

把真相告诉人们。让他们知道你已经开始理解他们想要的是什么,而且正在学习怎样把这样的结果交给他们

暴露无知,最简单的方法就是问问题

经过时间和实践,直接去问团队里最明白的人会成为你的习性。在暴露无知的同时,你也向团队展现了自己的学习能力。而且,有时他们也能从回答问题的过程中对自己的知识获得新的认知。

你的本能告诉你要掩饰自己的无知,装作通晓各种专家知识,但这只会阻碍你的成长,并阻止你完成正在尝试的工作

技师所拥有的重要品质之一就是学习的能力,他们能找出无知的领域并通过努力工作来减少这样的领域。

正视无知

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

对于某些人,最好的方法可能是阅读能接触到的所有文献和FAQ,来获得知识概览。其他人则可能觉得直接动手构造一个“质脆玩具”才是理解一样东西的最有效途径。不管哪种方法适合你,都不要忘了问问周围的“同道中人”和指导者,看是否有人已经掌握了这项技能并愿意分享所学。

公开地学习是学徒开始向熟练工跃进的途径之一

如果因为你的学习需要而妨碍了项目的成功发布,你的老板也不太可能谅解你。总之,你需要保持足够的警觉,不能让你的学徒期成为团队的问题。把更大的团队利益置于个体利益之上,而不是利用团队和客户来促进个人成长。

深水区域

只有承担艰巨的任务并做一些让人紧张的事情,你才会成长

意味着当提升或者外部的任务被安排到你头上时,即使面临着极高的失败率,也要勇敢地接受它。为失败做好准备并从失败中振作将为你打开怯懦者永远看不到的大门

以退为进

如果你真的在挣扎,或者说在深水区域你难以让自己的脑袋浮出水面,那你就应该寻找暂时回退的机会。有时你需要后退一步才能前进两步。

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

总结

最坏的情况是你根本不知道自己无知,如果你能意识到自己缺少的东西并补充它,你就向前迈进了一步
最新最早最热

第三章——走过漫漫长路
漫漫长路

要在编程方面真正擅长需要一生的努力,还有不断学习实践的进取心

在学徒期,相比薪水和传统意义上的领导能力,你要更看重学习和长期成长的机会。

技重于艺

技能建立在牢固的关系之上。相对于增加个人利益,要更重视向客户交付价值。作为技师,你的首要工作是构建能满足他人需要的东西,而不是沉迷于艺术展现。沉溺于制造漂亮但无用的物件不是技术。

必须在两件事上取得平衡,一是客户期望提供针对问题的直接解决方案,二是你成为技师总要有个内在标准。功用和美好并不对立,而是相辅相成。一款软件越有用,软件拥有高质量就越重要。但质量需要时间来保证。你必须不断地在美好和功用之间折中,从而向着适当的质量级别前进。

持续动力

有一类软件可以赚钱,有一类软件写起来有趣,这两类之间却没有太多的重叠。如果想挣钱,往往就被迫去解决那些非常难处理、没有人能轻松解决的问题。

培养激情

要成为熟练工,你需要拥有对软件技艺的激情。

处在恶劣的环境中,你很难培养自己的激情,但你可以采取一些基本的行动来维持它。

做点自己喜欢的事情
加入一个关注你要深入学习的某样东西的本地用户组。
当你的激情陷入危险处境时,可以让自己沉浸到软件开发领域的杰出作品中,这可以帮你越过难关。
有时你的需要、目标和抱负会跟老板提供给你的职业道路相抵触。可以考虑换到一个新的、能提供适合自己的职业道路的组织。要培养自己的激情,需要设置一个清晰的界限,基于这个界限来定义你愿意身处其中的工作环境
要保持你在14岁时对编程所抱有的新奇感。如果你担心现在的工作正在让你的大脑腐烂,那它很可能确实是

自定路线

为自己的职业生涯确定一个合理但又须付出努力的下一步。到达自己的下一步,然后继续制定整个过程直到抵达理想的目标,这都是你自己的责任。

有一点至关重要,就是一定要走出第一步,即使它看起来意义没有那么大。第一步会产生一种冲力,协助你向着自己的目标前进。

不要仅仅写下上层的目标,尽量制定细小的、可达成的步骤。这些小步骤会提供一些反馈,你可以利用它们来修改自己的路线,这些小步骤还能使你能更容易地从“同道中人”那里获得帮助,从而达成自己的目标

成功的学徒们所走的道路都有很多相似之处。之所以有这种相似,是因为每一名学徒都会有意或无意地基于一组相互重叠的价值来选择生命的路线。

应该不断重新评估自己的路线。路线永远是自己的,你可以在任何时候重新描画它

评估是(短期)更响亮的头衔和更丰厚的薪水重要,还是一个更符合自己的目标,从长期来看能让自己飞得更高的公司重要。

太多的组织把人员分类,并采用一种目光短浅的方式对待组织的人力(或“资源”)

使用头衔
不要让头衔影响了你。它只是一种娱乐,你应该在意识中将它边缘化。你可以使用头衔来评估你的组织,但不能用来评估自己。

坚守阵地
一个人一旦停止了实践,她对技艺的精通就马上开始消退。”每一个不写程序的日子,你都是在不断远离熟练工的目标。

另辟蹊径
沿着自己定好的路线走,记住自己在学徒期学到的东西。
即使永远地离开原来的道路,在这一路上你所形成的价值和原则也将一直陪伴着你。
如果你离开了软件开发,你会发现不管自己去哪里,像严谨的思考以及将涉及大批量数据的任务自动化这样的习惯仍将对你有用。不管你选择什么样的未来,你过去做软件技师的经历都能使之更加丰富。

第四章——准确的自我评估
聪颖而且努力的学徒千万不要对自己的成功自鸣得意。在软件开发领域,超越平庸是很容易的,因为有太多的人只超出平均曲线一点点就开始满足了。你必须去追寻那些技艺精湛、学徒甚至无法想象其水平的其他团队、组织、熟练工和师傅,向他们学习,以此来抗争趋于平庸的倾向。

你必须愿意放下自己已经感知到的能力

只求最差
宁为狮尾,不为狐头!
让周围多些水平比你更高的开发者。找一个更强大的团队,在那里让自己成为最弱的成员并拥有成长的空间。
处在一个强大的团队中能使你“感觉”自己工作得更好。团队的其他成员经常阻止你犯错误,并帮你平稳地从错误中恢复正确的结果
作为团队中最弱的一员,你应该比其他人更用功。这是因为你的目标不是保持“最弱”,而是从最后面开始一路赶上去。没有这种集中精力向团队学习的意识,你会面临多种风险

你面临拖累团队速度的风险
由于好的团队不会(长期)容忍某个成员只是来做一回过客
为直接给项目增添价值,你特意去做些打下手的任务。开发“具体技能”会增加你对软件开发过程的贡献,而且这是学徒这一角色的根本。没有这类贡献,该模式会导致强大团队被严重削弱。你对团队快速增长的贡献会成为这些强大团队愿意冒险拉你入伙的理由。

找人指导
找那些走在你前头的人,努力向他们学习。
如果你最终发现找到的老师不适合自己,那首先应该想想自身的问题。可能你的期望值过高,没有哪个老师能达到

但困难来自两方面:
这些人可能没兴趣指导别人
跑出去做一件请求别人“指导学徒”这么奇怪的事情会让自己有说不出的胆怯。
要记住,被一位潜在的指导者拒绝或者认为你奇怪的概率并不高,而潜在的回报却是巨大的

同道中人
为保持前进的势头,特别是当找不到全职指导者的时候,你需要找到那些所走的道路与你相似的人,跟他们保持频繁联系。因此,你应该去找一些像你一样希望自己优秀的人。
社区的健康度可以通过它对新思想的反应来衡量。今天持不同意见的人可能是明天引领新思潮的人

密切交往
找机会跟另外一个软件开发者坐在一起,肩并肩完成一项实际动手的任务。有些东西,只有当你跟另外一名开发者坐在一起完成共同目标的时候,你才能学会它。
总会有一些细微的技艺,只有跟一个同事近距离合作才能学到。这些技艺通常被认为太琐碎,没人会在教别人的时候提到它,但它们的影响却可以累加起来。

打扫地面
主动去完成简单无趣却又必须完成的任务。这是一种可以尽早为团队的成功付出努力的方法,因为它表明你能完成高质量的工作,即使这种工作看起来无关紧要。在任何项目中敷衍这一部分的质量都会导致日后的麻烦。

通常,你会关注风险更低的系统边缘部分,而不是常常带有大量依赖性和极高复杂度的核心。
不幸的是,在工作岗位上,你受到的教育并不如你认为的那么有价值。那些教育背景只能抬高人们对你的期望,期望你第一天就能交付更好的结果
会面对另一种风险:无法将前期的成功转变成请求更有挑战性任务的理由。另一种负面结果是:你发现自己害怕去做除“打扫地面”之外的任何事情。还有一种风险,如果只做琐碎的任务而没有更高的前后一致性,你会无法理解更大的图景。寻找各种机会证明自己能做更高级的工作

总结
谦虚是成功学徒过程的基础之一
与自己的志向结合,谦虚能让你集中精力,并保持沿正确的方向前进。没有谦虚,你很容易过早地宣告自己学徒期结束,并遗漏一些重要的课程。

第五章——恒久学习
软件开发由两种主要的行为构成:学习和交流
学徒期的主题就是学习,成功学徒的显著特点就是能证明自己的学习能力。学徒总是渴望有机会用技能替换自己的无知

提高带宽
学会那些本来不会做的事情,常常比去做已经会做的事情更加重要。
你一直像使用吸管喝水那样慢慢地汲取知识。但在学徒时期,有时候你必须快速地吸收那些就像从消防水管喷涌而出的、大多数软件发者都能获取到的知识。
提高获取新知识的能力是关键一步,尽管有时知识会多得让人崩溃。你必须开发一些必要的方法和技巧来高效地获取、理解、维持并应用新知识

注册成为博客聚合器的用户并开始订阅软件开发方面的博客(blog)。
从Twitter上跟(follow)一些软件大师,留意他们正在做什么。
订阅流量较高的在线邮件列表,重现别人遇到的问题并尝试回答他们的提问。
加入一个新成立的对某种新技术比较兴奋的本地用户组。
说服老板送你去参加技术大会。
在读完一本书之后,写封简短的邮件与作者联系一下,表达一下谢意,问一点问题
不要忘了网上有成百上千的在线教程、播客(podcast)和视频(如Tech Talks的广泛系列),可以从iTunes和YouTube免费下载。
理解何时“提高带宽”。

不断实践
在一个可以很轻松犯错误的环境中,花点时间不受干扰地实践你的技艺。
在软件开发中,我们是在工作中实践,这也是我们会在工作中犯错误的原因。我们需要找到把实践与职业分离开来的方法。我们需要实践期。
实践过程需要结合较短的反馈回路。虽然理论上实践是有益的,可如果你得不到周期性的反馈,你很可能养成坏习惯。
每天选择正确的事情来实践是一种技能,这几乎跟反复实践这一行为本身同样重要。

质脆玩具
设计并构建一套玩具系统,此系统从使用的工具集上(而不是功能范围上)与你在工作中构建的系统类似。通过这种方式为失败做出预算。
如果来自失败的经验可以与来自成功的经验一样多,那么你需要一个相对私有的空间来寻求失败
构建玩具包含了对新事物的学习,而且提供机会让你在特殊的环境中加深对手中工具的理解,这个环境不仅安全,而且你仍有余地来更好地服务自己作为一名用户的需求

使用源码
找别人的代码来读一读。从你日常使用的应用和工具开始。作为学徒,有一种想法会支持你阅读代码的信念:那些构建了你所用工具的人多少会有点与众不同,或有些特别,或比你更厉害。阅读他们的代码,你可以学会像他们那样写程序,而更重要的是,你将开始理解创造了你所用工具基础架构的那些思考过程。
除了阅读他人的代码(并在别人需要时提供反馈),也试着找找周围有没有人有兴趣阅读你写的源码。若能拥抱他们的反馈,并从中滤除纯个人的偏好,你将成为更好的程序员
通过阅读其他人编写的各种好的、坏的以及无关紧要的代码,你会慢慢学会特定语言社区中的各种惯用法和精妙细节

且行且思
自我反省是困难的,但我相信我们能从失败中学到的东西比从成功中学到的更多。
在软件开发领域做一名会思考的从业者。这包括经常反思自己的工作状况。考虑一下自己的实践是新颖的,创新的,还是过时的
这种观察、反思并改变的过程并不只限于你自己的行为。你还可以悄悄地观察团队中的熟练工和师傅。思考他们使用的实践、过程和技术,看看这些东西能否跟自己经验中的其他部分关联起来。

记录所学
在日志、个人wiki或博客中为自己的行程做个记录。将自己学到的经验按时间顺序记录,这会给你所指导的那些人提供一点启发,因为它使你的经历更加明朗,另外也为你自己提供了可以利用的重要资源
尽量避免落入写下经验之后就忘记它们的陷阱。定期读一读以前写的东西,你就能保证这一点。试着在每次重读这些资料时都找到新的关联。

分享所学
要在学徒期的早期就养成定期分享所学经验的习惯。

建立馈路
技艺不精的人常常不知道自己技艺不精。再者,越是技艺不精,你越不善于评估自己和他人的技能。
建立一些机制,定期收集关于自身绩效的相对客观的外部数据。通过尽早、经常而且高效地寻求反馈,至少你可以提高知道自己不行的概率。
批评本身不太会成为有用的反馈,因为它没有告诉你别人期待的究竟是什么
有用的反馈是这样一类数据:你可以基于它采取行动,而且它能针对某种特定行为给出多做或少做的选择。
加强型反馈鼓励你多做某事,平衡型反馈鼓励你少做某事。
一个学徒不应该过早地致力于不犯错误,而应该尽早找出如何确定错误的办法。一旦学徒能确定他们的错误,从错误中学习就容易得多了。

学会失败
天赋常常被误解。它并不是超常的智力,而是一种性格。它最需要的是一种承认失败、不遮掩缺点并努力改变的意愿。它来自于刻意的,甚至强迫性的对失败的反思,以及对新方案的持续探索。
设法确定你常常会在哪些情况下失败并试着解决那些需要改正的方面。真正的目标是让你对导致失败的模式、条件、习惯和行为有所自知
知道了那些使你失败的事情,你就可以在修正这些问题和减少损失之间做选择。

第六章——安排你的课程
阅读列表

维护一张“阅读列表”,用它来跟踪你打算阅读的书,并记下已经读过的书。
任何一本书,你能从中获得的最有价值的东西就是一列值得阅读的其他书目。
由于阅读列表实际上是个优先级队列(priority queue),最终你会发现有的书已经在队列中下沉得太深,你可能永远也不会再读它们了。
开始时挑一本宽泛的书,让自己对目标主题有大致的了解;然后选择一些内容具体的书,从而掌握该主题中自己感兴趣的方面。
比起乱读一通自己还没有相关经验的书,或者乱读一通自己尚不具备相关预备知识的书,在合适的时间读合适的书会有更好的效果

坚持阅读
重视你对学习的如饥似渴,消化掉尽可能多的文字。在你构建“阅读列表”的过程中,要更加重视书籍,而不是博客。
这一埋头阅读的过程也应该包含对学术界大量知识库的探索。读一些偶尔翻到的研究论文可以拓宽你的思路,与计算机科学发展的前沿保持联系,而且提供了富有挑战性的新思想的源泉

钻研名著
暴露无知”,向别人请教那些自己不知道的概念,以及它们出自何书。将这些书加入你的“阅读列表”。
在你的阅读列表中,要确保经典名著和现代的、更注重实效的图书和文章混合出现。

深入挖掘
学会深入挖掘一些工具、技术和技艺。对知识的学习要达到“知其所以然”的程度。深度意味着要理解导致一种设计的推动力,而不仅仅是设计的细节
对自己构建的系统,你可以真正解释其内部机制。

从第一手资料中获取信息
找出是谁第一次提出了那种思想,弄明白他们当初想要解决的问题。这样的上下文通常在思想四处传播的过程中由于各种转译而丢失了。
阅读教程的时候,不要去寻找可以复制的代码,而应该寻找可用于放置新知识的思想结构。你的目标应该是理解某个概念的历史上下文以及它是否是另一种思想的特例。
你的目标是:不影响自己对软件开发各方面相对重要性的基本观点,在这一前提下,让自己获得足以解决任何问题的专业化知识
如果只拥有表面知识,另一种可能的后果是:你会永远意识不到自己正尝试解决的问题要么已经有了众所周知的解决方案,要么根本是不可能的

常用工具
找出一组常用的工具并关注它们。最好这些工具都是你不再需要阅读文档的。有了这些知识,你就能对工作中的特定部分提供可靠的时间估算,从而将风险限制在新的、未探索过的领域上。
可用于完成工作的最佳工具并不是你最熟悉的工具。在学徒期使用的工具到你变成熟练工时肯定会变得过时。最终,你所钟爱的所有工具都将变成垃圾。为了职业生涯的成功,你必须学会从容地获取或放弃一些熟练工具
最优秀的那些人可以稀松平常地做出大多数人认为不可能的事情


Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts