该文由Markdown语法编辑器编辑完成。
这本书的英文名称为《The Passionate Programmer》
副标题为:Creating A Remarkable Career In Software Development。
也被称为——程序员职业规划之道。
“如果你对软件开发这行有浓厚的兴趣,如果你想成为一名出色的软件开发者,如果你想每天充满激情地工作,想要把开发软件视为一项事业而不仅仅是一份工作,那就一定要读完这本书。”
每个人都有卓越之处,但需要找到自己真正喜欢的事情把它激发出来。如果你不喜欢周围的环境,不喜欢你使用的工具,不喜欢工作的领域,那你的卓越之处又怎么可能被激发出来呢?
如果你想变得卓越出众,就必须相信你所做的事情正在推动整个世界的发展。
前言:
虽然追求卓越的人生是理所当然的,但却又不是显而易见的,你必须要去发掘它。
如果生活的大部分时间都被工作占据着,那么热爱工作就是热爱生活。
我们最终的目标是追求快乐。一旦满足生存的基本需求,人们就会转而去追求快乐。然后,我们的行动往往与此目标相悖。这是因为人们往往纠缠于做某事的方法,而忘记了最终的目的。
不要害怕失败
My Job Went to India
我要告诉你,你要出色,你要赢。就像在赛跑中,你要总想着怎么不输,那肯定不会赢得比赛。同样,总想着怎么避免糟糕地活着,那你也不可能成为生活中的赢家。任何人都不应该时刻想着如何避免失败。
经常有人问我为什么很多优秀的乐手同时又是很棒的软件开发工程师。这绝对不是因为这两种工作调动的大脑功能一样,也不是因为它们都是追求细节和创造力的工作,而是因为一个渴望成功的人肯定要比那些只是单纯完成工作的人更有可能成功。确定高目标,至少可以让我们不再平凡。
制订自己的计划
为了有别于他人,你应该停下来仔细审视自己的职业。
长期雇佣一个人对公司来讲是一笔很大的开销。公司雇佣你,是在你身上投资,而你要做的就是让公司的投资得到回报。要评定自己的表现,就要看你能给你的老板创造多少商业价值。
职业发展道路:
(1)选择市场。谨慎地挑选你要关注的技术和商业领域。如何权衡风险和收益?供需关系
(2)投资。需要在哪些技术上进行投资。
(3)执行。员工必须要有产出。
(4)市场。
请相信自己一定会成功,这样就不会感到恐惧了。
第1章:选择市场
(P1~P37)
大多数人对待工作的态度往往都是顺其自然,走一步看一步。我们的职业道路就是由一连串没有方向的偶然构成的。
开了一家公司,生产明星产品。如果失败了,公司就会破产。我相信你肯定会仔细考虑其中的每个小细节,然后亲自做决定。
在职业道路上,面临选择的时候,我们为什么就缺少了这番心思?
1. 稳定成熟的技术还是未成熟的新技术?(风险收益平衡)
那些即将完成使命的技术呢?只需轻轻一推,这些技术就跌进了坟墓。
练习:
基于当今市场,按照从左往右的顺序,尽可能多地列举出处于早期、中期和晚期的技术。最左边为崭新的尚未稳定的技术,最右边为即将退出市场的技术。尽可能仔细地找到它们之间的细微关联。
2. 供应和需求(供求规律)
当选择专注于哪种技术的时候,你要仔细考虑供给增长和价格下降给你的职业前景带来的影响。
作为.NET程序员,你会发现自己每天都在和成千上万的人竞争;但如果你是Python程序员,那么竞争就小得多。这会造成.NET程序员的平均工资大幅降低,也就可能会引起市场需求的增长,即会产生更多的.NET工作机会。这样可以很快找到一份工作,但薪水不会令人满意。
在印度,主流的外包公司不会着手做新技术。他们从来都不做第一个吃螃蟹的人。他们等待技术服务市场平衡,然后再用极其廉价的编程成本打入这个市场。
既然外包公司的工作都是市场是需求较高的,那么你就应该关注那些特殊领域的技术。这样或许不能减轻竞争压力,但是竞争的重点会由价格转向能力——这正是你需要的。你无法在价格上与他们竞争,但是可以在能力上与之抗衡。
需求的增长会加剧价格的竞争。需要去发现市场上的不平衡。
练习:
研究当今技术市场的需求。利用招聘广告和招聘网站找出哪些工作是高需求,哪些是低需求。密切关注外包公司还没有涉足的上述两类技术。思考它们需要多长时间才能为相应的市场提供服务。这个时间差就是市场不平衡的阶段。
3. 只会编程是不够的
如果你想站稳脚跟,必须要深入了解你所处的领域。
事实上,软件工程师不能只会开发软件,应该要成为这个业务领域的专家。你的行业经历应该成为你的重要才能。或许你只是一个程序员,但是如果你能用客户所处行业的专业语言与他们交流,那这就是一项非常重要的技能。
在选择从事哪个行业的时候,你应该像选择掌握哪门技术时一样谨慎。
把自身的发展限制在一个静止不前的行业里,可不是什么好的投资选择。
Now is the time to think about business domains you invest your time in.
练习:
- 安排一次与业内人士的午餐,问问他们是如何工作的。从他们的角度出发,思考你的工作;定期安排此类活动,这极大地帮助你理解和融入你所服务的行业。
- 选择一本与你公司行业有关的杂志。列出你可以向客户询问的问题。不要担心你的问题很傻,客户会大为赞赏你的这种学习态度。
- 找一个随时登陆的行业网站。注意大事件和专题文章。你所处的行业正在为什么而努力?现在的热门是什么?不管是什么,把他们介绍给你的客户。
4. 做团队中最差的
我认识到人们会取得很大的进步或者退步,仅仅是因为与他们合作的人不同了。与一个团队合作的时间长了,会对自身的能力产生持久的影响。
比起你直接问起他们如何评价你,这种检验方法更能得到真实的反馈,因为好的乐手不愿意和差劲的乐手同台。
试图做一个团队里最差的人可以让你不再小看自己。清楚地知道自己不是最好的,就不会总担心被人发现你不是那么优秀。事实上,即使你在尝试做那个最差的,也并不意味着你就是最差的。
The people around you affect your own performance. Choose your crowd wisely.
练习:
- 找一个团队,让自己成为“最差”的。可以试着找一个志愿者项目,通过与这个项目中其他程序员合作,提高自身能力。程序员一般都会用业余时间做兼职,以此来练习新的技术,提高自身技能。
- 或找一个开源项目,项目的设计者是你下一阶段的目标。
5. 在思维上投资
比起那些经验单一的候选人,我们更倾向于那些具有丰富经验的候选人。我认为优秀的程序员之所以寻找变化和多样性的工作,是因为他们喜欢学习新东西,或者是因为他们很清楚要想成为更加成熟和全面的程序员,就必须去学习新的技术、在新的环境下工作,获取新的经验。
作为招聘经理,我认为判断你适合不适合一个职位的首要因素就是你是否对这行感兴趣。
当我问候选人有没有用过某种非主流的技术时,最不愿意听到的答案就是“没有人给我机会使用”。没有机会?机会是要自己争取的。
接触这些边缘技术和方法能让你更有深度、更加优秀、更具智慧,以及更具创造力。
练习:
学习一种新的编程语言。但不是从Java到C#,或者是从C到C++。这门新的语言应该可以让你的思维方式产生变化。如果你是Java或者是C#程序员,那就尝试学习类似Smalltalk或Ruby这不需要强类型的静态编程方式的语言。
6. 不要听从父母
比起其他人的建议,父母给的建议总是包含着种种担心。这种出于担心的建议目的就是不要让你经历失败。但想着如何避免失败绝对不是取得成功的方法!成功是要冒险的。
一个成熟的职业软件开发人员需要从各个角度了解这个行业:产品开发、IT支持、内部业务系统开发以及管理工作。作为软件开发人员,你看到的角度越多,攻克的技术难题越多,就意味着你越有足够的能力来面对艰难项目。
以前,这种进入某个公司并为其终身服务的行为被看作是一种奉献。但现在这是一种障碍。
比起那些只知道一种做事方法的人来说,我更愿意聘请在不同的环境中经历过成功与失败的人。
在职业道路上,需要一些有目的性的冒险。别让恐惧征服了你。如果在工作中没有感到乐趣,那你就不可能出色地工作。
7. 做一名通才
经理们都希望软件开发机械化,这并不是什么奇怪的事。他们了解怎么做好机械化工作。
但是,软件开发和机械化生产不同。软件至少应该适应软件需求。这个行业已经变了,商业人士知道软件很“温柔”,可以根据需求做出改变。但这也就意味着构建、设计、编码和测试环节也要相应地变得更加灵活,这些都是机械化生产过程无法满足的。
成为通才就是说让你不要专注于一种技术。在工作中,有很多方法可以让我们扮演多种角色。
现状是我们要成为某一项技术的专家,同时还应该再擅长几种别的技术。技术平台只是一种工具,你的技术必须要高于它。
练习:
列出你能将你的知识和能力融合在一起的工作内容。写下每个方面中你的专长。在你专长的右边,再列出你要学习的一种或几种技术。
8. 成为一名专家
应试者缺乏技术深度。
如成千上万的Java程序员申请了职位,但没有一个人知道Java类装载器是如何工作的,也没人能高度概括出Java虚拟机是如何处理内存管理的。
很多人都认为专于某种技术,就简单地意味着不知道其他的技术。
遗憾的是,软件开发界有很多这样肤浅的专业人士,这些人以“专业人士”为借口,只知道一门技术。
在医学界,专科医生是指对某一特定领域有深刻了解的人。医生建议他们的病人向专科医生寻求帮助,因为在某些特定情况下,相比于全科医生,专科医生可以让病人得到更加专业的治疗。
在软件界,什么样的人才能称得上是专业人士呢?我想要寻找的人是已经处理过我们工作中可能遇到的80%的问题,并且拥有足够的知识来应付另外还未出现的20%的问题。我需要的人是不仅可以处理高水平的抽象,同时应该了解那些实现高端抽象的低端细节。
练习:
- 你是否使用在虚拟机上编译并执行的编程语言?如果你使用,花点时间学习虚拟机内部是如何工作的。
花点时间学习编写源文件。你敲打出来的代码是如何从可阅读的文本转变成可被计算机执行的命令的?输入或使用外部函数库时,它们是从哪里来的?输入一个外部函数库到底意味着什么?你的编译程序、操作系统或者虚拟机是如何将多个代码段连接起来,形成一个连贯系统的?掌握这些知识,可以使你在技术选择上向”专业人士”跨近一步。 - 在工作中或者工作外,寻找一个教课的机会。你所传授的知识是自己想要深入学习的技术。讲课是最好的学习方法。
9. 切忌孤注一掷
尽管一心一意地投资在一项特定技术上不是明智的选择,但是如果你必须这么做,那么别选择商业性质的,考虑一下开源的。
比起那些特定厂商的技术,你会发现经过你大脑分类解析的概念和模式更易于扩展和广泛应用。
练习:
试着做一个小项目,做两次。第一次尝试使用在家里就能使用的技术;第二次,使用你最惯用的竞争性技术。
10. 热爱它,不然就离开它
当然,在工作能力上,天赋占了很大的比例。不是每个人都能成为莫扎特。但是,我们大可以通过找到自己热爱的工作来摆脱平庸。
一门技术或者一个商业领域可能会使你感到兴奋;相反,或许是某一特定技术或者商业领域拖累了你。
短时间内你可能可以伪装,但是缺少热情总会影响你自己和你的工作。
练习:
(1)找一份自己真正有激情去做的工作;
(2)记录工作日志,找到自己的兴奋点。
第2章:在产品上投资
(P47~P78)
我在自己的能力(或者说是兴趣)上的投资,彻底击败了那个认为一切都是因为天赋的我。
如果你想要拥有一份可以在职场上出售的产品,一份让你具有竞争力的与众不同的产品,你就必须要在这个产品上投资。在商业中,有想法,有天赋的人很多。只有向这件产品中投入心血、汗水、眼泪和资金,才能使它真正具有价值。
1. 学习钓鱼
老子曾说:“授人以鱼,不如授人以渔。”这句话说得非常好。但是老子没有提到如果这个人不想学习怎么钓鱼,第二天又向你要另一条鱼怎么办。有老师也要有学生才能构成教育,但是大部分人都不愿意成为学生。
那么在软件界,“鱼”是什么呢?
很明显,你的出发点应该是学习如何使用你所处行业的工具。
或许你会很容易就忽略掉这行的“鱼”。如果你真正了解你所工作的行业的详情,那会大大提高你的工作效率。你不需要懂得每个行业的每一细则,但你至少应该了解最基础的规则。与我合作过的出色的软件业人士,很多人都成了客户所处行业的专家,甚至比他们的客户更了解那个行业,这样他们的工作成果显然更好。忽视行业性质的人,往往会犯低级错误,只要懂得最基本的行业知识,这些错误是完全可以避免的。
请注意,不要要求别人来教你,要自己主动学习。
Don’t wait to be told. Ask!
练习:
(1)如何与为什么?——在你读书或者工作的时候,想一想工作中你不完全懂的问题。你可以问自己两个问题:它是如何工作的?为什么会发生这种情况?虽然对于这两个问题,你可能给不出答案,但是只要你问了,就会形成一种新的思维模式,也使你更加关注自己的工作环境。
当然,这些问题的答案很有可能会引发对这些问题的新一轮探索。当在这个“如何和为什么”的环节中你无法再深入了,那就证明你已经达到目的了。
(2)“提示”时间——在你的工具箱里挑选出一种非常重要却经常被忽视的工具。选定了工具后,每天花一点时间学习这项工具的新知识,帮助你提高工作效率,或者能让你更好地掌握开发环境。当你工作中思绪出现游离的时候,就去学习这些知识。然后,你就可以利用一系列的“如何和为什么”的问题来深入研究它的核心了。
2. 学习行业是如何运作的
有一种知识,既不属于技术范畴也不是特定于某一行业的,而且也不会很快就过时,它就是财务基本知识。不管你在哪一个行业工作——制造业、医疗部门、公益机构或者教育系统都是一个行业。行业本身就是一门你必须要学习的知识。
我们来这个公司工作,目的就是为它赚钱或者省钱,但我们根本就不懂这行是怎么赚钱的。更糟糕的是,我们根本就不认为这是我们应该知道的知识。作为程序员和系统管理员,我们认为自己正在做的工作就是我们应该做的。但是,如果连这行是怎么赚钱的都不知道,又怎么能创造性地帮助公司赚取利润呢?
有创造性地增加价值需要全面地了解你所工作的行业环境。
“账本底线”,到底有多少人真正理解“账本底线”是什么,以及什么能对它产生作用?更重要的是,又有多少人知道自己怎么做才能对这个“账本底线”起到有利的作用呢?
了解你公司的财务运作可以让你做出有意义的转变,而不是茫然无知地专注于某一件事情,却主观地认为这样就是对的。
You can’t creatively help a business until you know how it works.
练习:
(1)通读一本基础商业教程,一本MBA教程是不错的选择。
(2)了解财务的基础知识,弄明白什么是“财务底线”。
3. 寻找良师
在传统的职场世界里(特别是IT行业),我们很少能求助于他人。依赖别人被看作是脆弱的象征。我们害怕承认自己不够完美。竞争无处不在,只有强大的人才能在竞争中生存下来。遗憾的是,这种观念导致了“师徒机制”严重不发达。
一名良师最首要也是最重要的任务就是做一个榜样。直到亲眼见识到某人突破你所熟悉的极限时,你才知道什么才是一切皆有可能。榜样的作用就是定义何为“好”。没有榜样,就没有动力进步。
良师还可以将你的学习过程形成体系。良师可以帮助你削减技术选择时的困难,避免你白费精力。重要的是良师缩小了要掌握的技术范围,这样我们就可以学习技术,取得进步,而不是停滞不前。
良师还是值得信任的朋友,可以观察并判断你做出的决定和取得的进步。良师是值得你信赖的人,你甚至可以问他们:”作为职业程序员来说,我与其他人有什么不同?”他们不仅会帮你分析,还会帮助你取得进步。
我帮助某人时,就是在这个人的成功上投资。
通常,经验丰富的成功人士都会受到一些重要人物的尊重。这个良师就成了你与这个人际关系网之间的桥梁。这种桥梁作用是不能被小看的。
”有本事不如认对人“。
师徒关系的形式不重要。重要的是你要有可以信赖敬佩的人,他可以帮助你做出职业导向,帮助你磨练技术。
It’s OK to depend on someone. Just make sure it’s the right person.
练习:
指导自己——我们都希望有人主动来教我们,但事实是我们很难再自己周围找到这个人。所以要学会自己做自己的导师。
列出你最钦佩的榜样的10种特性;把这些特征按重要性的升序排列,1最不重要,10最重要,列出一个特征列表,这些特征都是你钦佩并认为重要的。这就是赶上你选择的榜样的方法。但是,要先专注于哪一项呢?
4. 做一名良师
要想真正学点东西,可以试试向别人传授这些知识。清楚知道自己是否对某一知识真正理解的最好的办法就是把你的理解讲给别人听,让他们明白。
这个简单的方法是公认的帮助你理清思绪的灵丹妙药。
我们通过传授知识学习。
当要阐明复杂问题的时候,我们会用简单一些的事例打比方。当你向别人讲授的时候,你就必须回答一些你可能从未想过的问题。通过讲授,我们的那些知识死角就会暴露出来。
寻找学生的方法不是你声称自己是权威,而是使自己具备真才实学并且有耐心愿意与别人分享你的知识。如果你不是某方面的绝对权威,也不要惊慌。有时候你只需要具备某方面的经验,然后去帮助那些比你经验少的人。
Mentors tend not to get laid off.
练习:
(1)找一个你可以帮助的人。可以找一名实习生,或者去计算机技术学院做志愿者。
(2)找一个网络论坛,并挑选一个主题。开始帮助别人。慢慢地,你就会因为愿意助人以及有能力帮助别人学习而在这个论坛里出名。
5. 练习,练习,再练习
当你在练习的时候,演奏出来音乐或许总是难听的。如果你在练习的时候,总能演奏出悦耳的音符,那就证明你一直无法突破自己的极限。这就是练习的意义所在。运动也是一个道理。运动员在训练的时候总是将自己推到极限处,这样他们才能在比赛中突破自己的极限。
他们让丑陋的东西都暴露在平时的练习中——而不是真正的比赛中。
你能想象一名专业的乐手,站在舞台上,演奏出来的却是大学训练室里那些难以入耳的声音吗?这肯定是让人难以忍受的。音乐家是通过公开表演而赚取报酬——是表演,而不是练习。
在计算机这行,我们习惯于在工作中练习。
我们应该寻找时间练习。
编程练习,第一条规则就是练习开发的东西绝对不能是我想要使用的。我开始编写我用不着的程序。好的联系应该让我接近自己的极限。
对于软件开发工程师的练习,
(1)基础练习是指,有没有你基本不怎么使用的?比如正则表达式。还有编程语言的API和类库。大多数现代编程语言都提供了丰富和强大的库,但是软件开发师们却只学习了其中的一小部分子集。
(2)开源社区是练习的最佳场所。有没有哪个开源软件是你最喜欢的,你可以给它加个功能。浏览它的待办事项,给自己规定时间来实现这个新的功能。
练习的真正目的是以最快的速度读懂你正在看的代码。但是一定要确保这个软件与你平时工作时使用的软件不同。要寻找不同风格、不同编程语言的软件进行练习。
(3)训练思维敏捷和提高即兴编码技术的好方法是通过自我限制的方式来练习。
最重要的是找到你所需要的来进行练习,并且确保你不是在工作中练习。你必须要找出时间来练习,这是你的责任。
练习:
(1)Topcoder——编程竞技网站;
(2)Code Kata.
6. 做事的方法
“软件开发”不是一个名词,而是一个动词词组,它是一个创作的过程。
幸运的是,人们在开发一些优质的软件的过程中投入了很多心思。这些现有的技术被编录成”方法论“。
要想让自己找到对这个步骤的归属感,最好的方法就是亲自来操作。如果你的机构中没有工作步骤,那研究方法论对你可能会有帮助。
即使有很多角度的方法论可供选择,一个公司也不可能完全照搬某个方法。没关系,一个能使你的团队工作更有效率,帮助你们生产出更好产品的步骤就是最好的选择。
练习:
选择一个软件开发方法论,并且挑选一本有关此方法论的书。
7. 站在巨人的肩膀上
软件设计和编程与音乐是相同的。我们可以从大量的现有程序中寻找模式和技巧。
《设计模式:可复用面向对象软件的基础》
设计模式,关注可重复使用解决软件开发问题的方法。设计模式使现存程序的研究正式化,使大量专业软件工程师得以进行这项工作。但设计模式也只是我们读程序编码的时候可供使用的知识中的一个小子集。
比找出某一特定问题的解决方法更重要的是,将现有的程序当做一面放大镜来检查你自己的编程风格和能力。
当你读这些程序的时候,你会发现某些你可能永远也不会去实践的工作,甚至是你想都没想过的。他为什么要这么做?他是怎么想的?他这样做的目的又是什么呢?
即使你读到的是不怎么样的程序,通过批判的角度来研究它,你也会有所收获。
当你以一种批判的视角去看这些程序的时候,你就会开始培养自己的品味,就像你对音乐、艺术和文学的品味一样。
阅读这些程序的另一个作用就是能让你知道哪些方法是已经存在的。
当你意识到在软件这个行业中,正因为我们一遍又一遍地重复发明轮子而浪费了多少金钱时,你会大吃一惊!
牛顿说过,”我看得更远,是因为我站在巨人的肩膀上。“像牛顿一样的智者都清楚地知道我们能从先人身上学到很多东西。做一个像牛顿一样的人。
练习:
(1)选择一个项目,像读书一样研读并且做笔记。归纳出好的方面和坏的方面,发表一篇评论。至少找到一个可以借鉴的技巧或模式;再找一个缺点,提醒自己不要犯。
8. 在工作中,将自己自动化
我强烈要求雇佣一些真正优秀的开发师而不是雇佣一大批成本低但技术水平也低的写代码的人。
自动化属于我们这行的DNA。
练习:
(1)挑选一个你经常重复做的工作,为它编写一个代码生成器。
(2)研究模型驱动架构(MDA)。尝试一些可以使用的工具。看看工作中哪里可以使用MDA概念。