在React Conf上有几位朋友咨询我如何成为一名更优秀的程序员。由于某种原因,人们认为我是一个值得倾听的高级程序员。所以我想有必要把我这些年编程路上的『心路历程』写下来。
关于我的一些详细信息:我现年32岁,有10年以上扎实的工作经验。直到最近几年我才对自己所做的工作充满信心。即使是现在,我也在不断质疑自己。问题在于,这种质疑并不会消失,所以你要做的就是无视它,不断的解决问题,不断的积累经验。
首先我要说明的是以下提到的只是一些帮你提升技能的小贴士。最终你还是需要找到一条最适合你自己的路。这些只是我发现对我有帮助的点。
找到可以激励你的人,但不要崇拜他们。
在过去的几年中我曾经仰慕过很多人,并通过关注他们来获取新技术。通过单纯的相信他们以及深入研究他们的工作内容,我学到了很多东西。这些人往往成果丰富,才华横溢同时还能鼓舞他人。找到这种人,并让他们激励你,教导你。
然而,你要确保不会崇拜他们。他们的twitter feed往往看起来令人生畏,但是如果你去观察一下他们在现实生活中的是如何工作的,你就会发现他们并没有什么特殊的。使用各种奇技淫巧解决问题。我们都是在不断探索而已。最后,不要盲目的信任他们;如果你不这么认为,那你可以试着接触他们看看。我的一些最富有成果的对话就是这样发生的。
我的Emacs配置一团糟。我不知道为何我的OCaml自动补全失效了(已经失效一个多月了)。我不会把任务自动化,有时还需要在shell历史中搜寻我需要使用的某个命令。在最初阶段,我写的代码都非常丑陋。在我想明白怎么做之前,我会把变量放在全局对象上。最有经验的程序员都会使用各种hack写法,重点在于能解决问题。
不要贬低你的工作
因为是新人,新手程序员总是倾向于认为他们的工作没那么重要。又或者也许你是一个有经验的程序员,但是在一个让你感到不适应的新领域里工作。在我看来,一些最好的想法正是来自于新手程序员,他们能看到现有技术的可改进之处,而那些已经形成固有观念的人却看不到。
无论如何,你的工作都是有价值的。在最坏的情况下,如果你的方法失败了,社区至少可以更好的了解为何这种方法行不通。(对社区的一点说明:这条是我们要做的,要对新人友好一些。)
不用总是在压力下工作
新技术每天都会出现,这可能会让你觉得如果放慢脚步,就会与这个世界脱节。然而并不是这样的。事实上,如果你能很好的休息,你就能更好的工作。你的思路将保持清晰,我发现当我不工作时,我的潜意识里会出现很多新想法。
那些每天不断发布的内容大部分都是一些现有想法的翻版。真正革命性的东西只会每几年才发生一次。关于这个话题有一个不错的分享值得一看:吊床驱动开发(注1)
忽略没营养的东西
可以让你成长得更快,更好的最佳方法之一就是忽略掉那些实际上对提升技能没有帮助的没营养的东西。换种说法就是『聪明的使用你的时间』。你的时间有限,如果能把时间花在更深入的问题上,随着时间的推移你就会看到很大的不同。
到底什么是『没营养的东西』呢?这取决于你自己,但我可以给你举几个我认为没营养的东西:编程语言的语法,各种库的API以及如何配置构建工具。例如,学习一个ES7的新语法并不能像学习编译器的工作原理那样让你成为一名更优秀的程序员。采用一个使用新API实现了相同想法的库也没有什么意思。所有这些事情当然是有意义的,但我建议你花更多的时间用在学习那些可以是你长久受益的深层概念上。
这里我想问一个问题:你是否花很多时间用在把代码改得更『漂亮』上?如果是这样的话,我建议你不要把大把精力放在这上面。你的代码将会随着时间不断变化。最好把精力集中在你试图解决的核心问题上, 并认真思考你对问题的抽象层次。当你解决了所有这些问题之后,你就可以花些时间打磨代码了。(这也适用于DRP原则。不要太过担心它。尽管重复。)
挖掘过去的研究成果
如果一个想法让你感到很兴奋,你可能很想立刻就展开工作。但是在那之前,你应该先粗略研究一下前人是如何解决这个问题的。花上几天时间研究要解决的问题*总能*彻底改变我的思路。
学习如何阅读学术论文是很有意义的。我对指称语义、操作语义等毫无了解,因此有很多论文我不能读。但是很多论文中使用了代码而不是数学公式,这部分就没有那么难理解了。在过去30年中发布的论文中有数量巨大的知识。如果你能善于发掘它们,那么你很快就能成为思想领袖。
Prettier(注2) 就是一个绝佳的例子。我知道我想要什么但是却无从下手。在短暂的调研之后,我发现了这篇论文(注3) 。经过几天的学习之后,我已经非常清楚自己要怎样做了。在一周之内我就有了初步成果。如果我跳过最开始的调研阶段,那我就要花费多得多的时间了。
如果你在找一些论文来读,那么你可以从我们喜欢的论文(注4) 这个GitHub仓库开始
承担一些大项目,走出自己的舒适区
没有比经验更宝贵的东西了。不是每个人都有机会去尝试,但如果你有时间的话,试着去参与一些大型项目。你甚至都不需要完成它。只是试图解决像开发一个编译器这样的问题,就能在最开始的几周里教会你很多东西。
坦白来说,我讨厌那种面对复杂问题时毫无头绪的感觉。它让我很不舒服。我知道在我能接近答案之前要做很多的调查,学习。但在那之后,我总能成为一名更优秀的程序员。
你可以从学习一门新语言开始。这是使你摆脱现有习惯并以全新视角看待问题最有效的方式。对我而言,在我还是个新手程序员时做过的最棒的事情就是学习Scheme(注5) 语言。这是一门非常简单的语言,强制你使用函数式的风格做任何事,并真正了解代码工作的基本原理。直到今天我还在受益于当年花在Scheme上的时间,我考虑代码的方式发生了根本上的改变。(我甚至以Scheme中的shift/reset操作符命名了我的公司Shift Reset LLC。)
以下是一些我推荐尝试的事物清单。它们都曾对我的程序员生涯产生过巨大的影响。直到今天,它们中的大多数还在以某种微妙的形式回报我,帮助我从思想上解构新想法。你不需要做这些来成为一名优秀的程序员,还有很多其它帮助你提升自己的方式,但这些却是曾经帮助过我的。
学习C 只是基础知识,如果你还没学过的话。我认为了解一下为什么每个人都在抱怨它是有意义的。
写一个编译器 可能是走出舒适区并学习新知识的最佳方法了。看看这个超简编译器(注6)
学习宏指令 看看Scheme,Lisp或是Clojure(脚本)。宏指令会改变你看待代码的方式。
SICP SICP(注7) 是一本我认为直至今天仍有价值(有些人不这么认为)的旧书。它不需要你有太多编程知识,并将引导你逐步实现一个自循环直译器和编译器。另一本我非常喜欢并深入学习的关于编译器的书是Lisp In Small Pieces(注8) 。
理解延续性 延续性(注9) 是一个偏底层的流程控制机制。Scheme是唯一实现了延续性的语言,虽然你永远都不会生产环境中使用到它,但它却可以改变你思考流程控制的方式。我曾写过一篇解释延续性的博客(注10) 。
如果还有什么的话,尝试一门新语言 不论你做什么,你都应该去探索一下其他语言。我会推荐给你以下这些:Clojure,Rust,Elm,OCaml/Reason,Go或是Scheme。它们中的每一种都有很多独一无二的特性并强迫你学习新的思维方式。