Noah Gibbs是一名长期的专业软件开发人员,到2024年,他的程序员生涯就要满40年了。近日,他发表了一篇长文来分享自己的编程之路,无关编码技巧,无关如何赚钱(尽管他赚到了很多),那么他会分享些什么呢?笔者以第一人称的视角,对原文进行了编译整理,以飨读者。
到2024年,我就将成为一名有40年经验的程序员。这与开发软件赚最多的钱,或者创办一家软件公司不同。我确实赚了很多钱,但这并不是这一切的意义所在。
我认为你可能想长期做一个软件开发人员,就像有些人长期做音乐家、艺术家或者屋顶工人一样。如果不是,你可以在你的浏览器中点击 “返回”。这很酷,无伤大雅。但如果你想成为一个二十年、四十年或者更长时间的程序员,那就听我继续讲下去吧!
我不会告诉你要学什么语言或框架。如果你擅长基础知识,你可以学习任何你想要的东西。在那之前,你可以什么都做不好,反正我就是这么做的。
相反,我想讨论刚开始时对我没有意义,而现在成为我天空中启明星的那些事,这意味着它不是关于具体的技术。因为技术日新月异,语言来来往往,它们不可能成为你的天空。下面,让我们开始第一个话题:
软件开发很年轻
计算机语言Fortran的历史可以追溯到1957年。还有其他一些语言也差不多是在同一时期出现的(LISP和Algol:1958年,COBOL语言:1959年)和一些奇怪的年老竞争者(Konrad Zuse的Plankalkül,1942年左右。)
假设从1957年开始就有程序员了,那一共有65年历史。我从1998年(24年经验)开始成为一名全职程序员,从1984年(38年经验)开始做一名程序员,可以说非常有经验了。此外,Smalltalk编程语言的发明者Alan Kay,从1963年左右开始成为程序员(59年经验),他是我发现的活跃时间最长的人之一。
相比之下,天才大提琴家马友友今年66岁,他从4岁半开始就一直在拉大提琴,但他远不是世界上演奏时间最长的音乐大师。《吉尼斯世界纪录大全》记载,Kasper “Stranger”Malone连续80年都有专业的音乐作品发布。因此,一个真正有经验的音乐家的工作时间,甚至比我们整个学科存在的时间还要长15年。所以,我们的领域还很年轻。
年龄不是问题
所以,如果我从8岁开始,马友友从4岁半开始,对你来说太晚了吗?并不。
大约一年前,45岁的我开始认真弹钢琴。我认为自己真的在进步,如果我能够坚持下去,当我60岁的时候,我就会变得非常出色。现在,我已经可以像样地演奏一些歌曲了,所以,当你已经有一些背景和观点时,你会更快地变好。更何况,你已经练习掌握了几十年或者更长时间的技能。
假设你50岁了,你可能还有30年左右的大好时光成为一名软件开发人员。如果你从50岁开始,你在10年后的60岁可能会比我在10年后的18岁要好得多。
我遇到过的优秀程序员很多都是从20岁、30岁甚至40岁开始工作,你没有什么理由不能从50或60岁开始。虽然这需要时间和努力,但并不意味着你要从小开始。
不过,这也意味着你的编程可能不会那么厉害。就像我弹钢琴不会像马友友拉大提琴那样好,我在编程方面不会像Alan Kay那样出色,尽管我很小就开始编程。实际上,几乎所有其他拉大提琴的人都比不上马友友,但这并没有阻止他们投入到大提琴事业中。就像我喜欢弹钢琴,即使我从来没有进入到世界前十名。
我仍然喜欢编写软件,但我成为下一个Alan Kay的几率基本为零,因为他在我这个年龄已经写出了Smalltalk。如果你从事软件工作,“不做Alan Kay也没关系 ”的想法是必要的。
顺序不是决定性的
如果你刚刚开始编程生涯并且想长期做下去,我经常说“只要写一些软件,任何软件都可以”。你需要学习很多不同的东西,以什么顺序学习它们并不是什么大问题。
40年来,很多趋势来来去去。桌面应用、移动应用、操作系统和系统、网络编程,我都学习过。当然,你所学的列表会有所不同,但它将涵盖多种编程。只要你尝试不同的东西,你做它们的顺序并不重要。
当然,“尝试不同的东西”是关键。你在四个不同的领域各花十年的时间,会比你花40年的时间写网络套接字服务器要好得多。并不是说40年的深度没有价值。深度绝对有价值,所以你也不应该在四十个不同的领域各做一年。
但你要注意别太刻板。事实证明,几乎任何学科都可以教给你一些东西。如果你不知变通学不来,那你就失去了机会。
尝试不同类型的编程,用任何顺序都可以,但同时你应该在某些方面下功夫并变得更好。
现在还为时过早
很多人会觉得自己学的东西没用,但我认为,没用是相对的。
我把多年的业余时间投入到一种叫做DGD的旧MUD编程语言中,几乎所有关于它的东西都是奇怪的和不标准的,而且很少有真正实用的东西。然而,正是因为它很奇怪,所以它教会了我很多东西。
它教会了我Ruby on Rails后来使用的东西,它还教会了我有关数据库编程的知识,尽管它没有使用数据库!我从中学到的这些东西,在我后来学习的五六种编程语言中都起了很大的作用。
有趣的是,许多年后我得到了一份DGD的咨询工作。要知道,世界上没有多少DGD工作,但我有一个!这比我学过的很多 "实用 "语言更实用。
我经常对自己说 "现在还早"。虽然我已经46岁了,但我还没到96岁,我至少还有20年甚至50年的时间。所以,如果我做一些奇怪的事,但它教给我有趣的东西,那真的很好。如果我做一些实际的事,让我在短期内度过难关,那也是好事。
但重要的是:一定要继续工作。作为一个程序员,要想做到二十年、四十年或者七十年,需要大量的工作。如果两件工作难以取舍,可能它们都很好,任何一件都会是一个好的选择。否则只能说明它们都很糟糕,你应该找一些有价值的东西来代替。
现在还早,学习一些有趣或有用的东西,给予它时间来收获好处。但你需要期待的是十年、二十年或三十年后的回报,不要总是选择十八个月后最好的东西,因为你真的看不到未来会发生什么。
确保工作是好的
你开始编写软件一定是因为它吸引到了你。它的某些部分是好的,否则你也不会费心费力了。
试着弄清楚那是什么。你喜欢什么?是什么吸引了你?它有什么好的地方?这对每个人来说都是不一样的。
我喜欢有成就感和聪明的感觉。这不是我工作中最好的做法,但我在家里经常这样做。我不需要每个人都看到它,我可以只靠自己的聪明才智做好工作。我也喜欢做一些和自己工作不同的事情,即使我在两个地方都写代码。我还喜欢写一些其他程序员可以使用和欣赏的东西。
你的理由也许和我不一样,但我想说的是,工作很好,如果它不好你也做不下去。如果它不再好,那就是紧急情况:你需要休假,或重新找到你喜欢的东西等。因为如果你的工作不再让你感觉良好,你会很快精疲力竭。
工作是好的,如果不是,那就改变工作。这些都不一定意味着这份工作是好的,或者换工作,但是你需要在你的工作中获得足够的好处让自己继续下去。不管怎样,坚持下去是一种要求,所以这可能也会影响你的工作。
别把计划看得太重
你很容易下定决心“成为一名计算机程序员”,甚至为此制定一个包含56个要点的八部分计划来说明自己将如何去做。我不会告诉你不要激动,因为如果你不能兴奋起来,那又何必费力呢?但我想说:不要把计划看得太重。
当我在卡内基梅隆大学读书时,我经常在计算机实验室闲逛。因为计算机很棒,而我没有任何社交技能,所以我早早就开始编写软件并且一直在工作。
但我渐渐发现,自己的生活中不能只有工作,最终我联系朋友,娶妻生子。我领悟到,即使有一份好工作,情感上的僵化和压抑也不会让你走得太远。在某些时候,你会停止打算,因为你不可能通过打算和计划来做所有事情。在某些时候,你并没有“脱离任务”,你只是在“生活”。
学习编写软件不是计划好的任务,因为你不是在短跑或跑马拉松。相反,你正在写日记。也许十年后,你会翻开它说,“哇,我做了一些很酷的事情?”或者“我对Java语法很在行。”
不要混淆工作和职业
虽然我也期待着能够退休,但我不会停止工作,我也不会为了钱去做我不喜欢的工作,特别是如果它不能教给我什么了不起的东西。
我目前在YJIT(用于Ruby的JIT编译器)上的工作充满了我愿意免费写的代码,但如果我没有得到报酬,我就永远不会碰费用报告,也很少写状态更新。他们会少做很多系统管理员的工作或Git历史修剪。
所以,不要把工作和你的事业混为一谈。它们不是一回事。编写软件是一项了不起的工作,它也是一个不错的职业。就像我经常谈论的音乐家,有些人通过写作和演奏音乐获得报酬,但很多音乐家从来没得到报酬还一直在坚持。如果你能得到报酬,那你可能会在工作上花更多时间。但工作就是工作,而职业则是为你的工作扫清道路。对我来说,编写软件就是我的职业。
不过,最重要的是,要分辨出你在任何时间得到的是哪种建议。你会得到关于工作的建议、你也会得到关于职业的建议。如果你把两者混淆,那么这些建议就没有什么意义了。
没有明确的级别
如果你学习的顺序并不重要,那么就没有所谓的“第一级”或“第二级”等级别,你会得到关于先学什么语言或技术不同的不同建议。但是,如果你开辟了自己的道路,这并不意味着你没有做好基础工作,你就很糟糕。最终,如果有些东西是重要的,你会发现你需要它,还会重新回到它身上。
可怕的是,有人会年复一年地忽略一些基本的东西,那就会变得很糟糕。比如,你可以写15年可怕的意大利面条代码,其中每个模块都可以进入其他模块并直接设置对方的变量。如果你继续尝试,你要么会弄清楚为什么这样不好,要么会发明一种新的方法来解决问题,并在一些奇怪的事情上表现出色。通常,一个程序员的“新范例”,在其他程序员眼里总是“奇怪的东西”。
问题是当你不再努力变得更好时。如果你不断地犯新的错误,你就会学到有用的、美丽的或奇异的东西。如果你继续做同样的事情而不尝试改进,那么当然,你会一直很糟糕。即使你按部就班地通过某人预设的关卡,结果也是如此。
李小龙说:“我不害怕练过一万种脚法的人,但那个将一种脚法练了一万次的人,我怕他。”由此可见,诀窍在于关心和改进。如果你坚持足够长的时间,你可以专注于一件事、十件事,甚至一百件事。如果你真的足够努力,你甚至可以管理一万件事。
你变得越好,你就越与众不同
职业生涯早期的培训(代码学校、博客文章、大学课程、书籍)往往感觉有点像一条流水线。有一堆真正的基本技能,例如写函数、调试、估算、与团队交谈,他们试图确保你在每一个方面都具备基本的能力。这让人们很容易以为,比如对于一个首席工程师来说,有一个你需要的技能清单,但清单上有更多的技能而且水平必须更高。但事实并非如此。这不仅仅是工作水平,它也是开源中的“水平”,尊重的水平。
你可以通过把一段相当简单的代码,写出(用英语,给人类)大量的细节而备受尊重,就像Patrick McKenzie写的Bingo Card Creator一样;你可以通过写一些真正有利可图的东西来获得尊重,就像一个公司的创始人;或者写一些深奥复杂的东西,比如一种晦涩的语言(Haskell)。除了基本能力之外,这些途径几乎没有任何共同之处。
你需要真正擅长某件事,而这件事需要受欢迎或有利可图,或者以其他方式“成功”。这听起来应该很模糊,因为事实就是如此,这也是主观的。如果你打算赚比尔·盖茨级别的软件钱,结果你写了Haskell(复杂、深刻、广受好评,但没那么赚钱),那你就太失败了,反之亦然。
这就是为什么问“我是一个有15年经验的软件工程师,通常工资是多少?” 这样的问题很愚蠢。15年的经验太多,所以你应该完全不同于其他同样有15年经验的工程师。你写书了吗?有做一个赚钱的大项目吗?还是创建了一个有趣的开源项目?你用这15年做了什么?这就像说“我是一个有二十年经验的音乐家,我每小时应该收费多少?” 这个问题没有简单的答案,也不应该有。
这也不仅仅是薪水的问题。你可以问:“我是一个有15年经验的软件工程师,这意味着我有能力领导这个项目,对吗?”答案当然是“也许”,接下来的问题是“在那十五年里你做了什么?”
通过基础工作来学习深层原理
我不建议大家一开始就去学习软件设计的深层原理。因为如果你试图把它们作为理论来学习而没有实践经验,你肯定会做错。我建议首先要学会用某种实际的语言构建一个可用的软件,哪种都可以。只有经历过一些真正的错误,然后我们才能讨论有什么理论可以解决你个人遇到的问题。
如果事实证明你在模块化方面很出色,那就太好了!我们可以讨论你其他方面的问题。如果你没有关心的问题,那就意味着你可以暂时构建相同级别的软件。这一切都由你决定,当你开始觉得工作变得乏味时,那么你确实遇到了问题,所以你可以寻找一个解决方案。在那之前,做对你有用的事。
接着,在20多年的时间里做同样的循环:构建、犯错、学习理论,修正错误。我并不在意你做这一切的顺序。而这是否意味着如果你先学习理论,你就会一直做不好?这倒不至于,但在你能正确使用你所学的东西之前,那还需要一段时间。所以,这不是构建好软件的最快方法。
了解相关技术很重要
我已经说过很多遍,以什么顺序学习什么技术并不重要。重要的是,你要学习一些不同的东西。如果你总是做一件事,你不知道自己会养成什么坏习惯。
如果你总是在一台机器上编码,你就不知道自己有多少网络知识没有学到,而最终网络可能是重要的。如果你只在web服务器上工作,而从不在手机或应用程序代码上工作,你永远不会知道为什么“在我的机器上工作”是如此糟糕。你可以做一件事很长一段时间,五年?十年?但如果你想做到40年,你就需要了解自己软件所涉及的许多其他技术,要有一点洞察力。
洞察力就像其他深层原理一样,你通过工作和看到现实世界的问题来获得它。而你通过各种工作来获得它,这样你就能看到不止一个观点。当你说 “好吧,我的部分起作用了”,但整个系统因为其他人的部分不起作用而失败时,你会意识到自己的观点有问题。你学会关心比自己的代码更重要的事情,这就变成了软件架构,但也变成了观点和同理心。一个真正有用的软件系统有很多软件,同样也有很多人参与,你不能忽视这些人。
这意味着你要学习各种技术,以及各种非技术技能。你使用什么技术很重要的另一个原因是,一些语言或库会让你在特定的技能方面做得更好。如果你想在编程领域工作40年,你将需要扎实的基础技能。
关注其他领域,向其他领域学习
如果我们的行业很年轻,这意味着我们仍在摸索基本的东西。
当我在大学的时候,从1993年到1998年,测试优先和测试驱动开发还不是真正的东西。敏捷也不是一个真正的东西。这些方法是存在的,但并不流行,也不为人所知,更没有很好的发展。源码控制存在,但不是很好,没有被广泛使用。开放源码是存在的,但人们普遍认为开放源码意味着粗糙的软件。认为Linux是或可能是最好的服务器操作系统的想法是一件奇怪的事情,但一些狂热者可能会相信。对于速度密集型应用来说,C语言是否足够快以取代汇编语言还没有定论。最终,“GOTO”被认为是不好的,我们应该避免它。网络刚刚起步,在我上学期间它开始支持网页上的图片。
我们这个行业的变化相当快。换句话说,我们在基础方面仍然无能为力。你可以从其他领域学到很多东西,比如我写了一本关于如何窃取艺术家实践方法的书。所以我在这里一直在谈论音乐家。艺术和音乐是古老的学科,他们有几千年的领先优势。
所以,如果你遇到一个问题,不要局限于学习计算机程序员处理它的最佳方式,最好想想其他任何人会如何处理这个问题。这也意味着,如果你有一些其他的兴趣爱好,你或许应该考虑一下它们会给你带来哪些实用技能。
程序员是逆反的
如果你从其他领域学习,它会让你变得很奇怪。虽然大多数情况下这是好事,但有时也会引起摩擦。
例如,艺术家、音乐家和作家都知道,如果你一遍又一遍地重复同样的活动,你会变得很擅长。我们在软件中也为它取了一个名字:“重新发明轮子”。这被视为一件坏事,我们羞于启齿,私下行事。我们想办法让计算机做所有的重复工作,这样我们就可以只做新的工作。
事实上,在公共场合说你一遍又一遍地做同样的事情非常尴尬,甚至还会损害你的名誉。这就是为什么我们大多数人都不擅长开始新项目、不能谈论何时使用一种或另一种句法结构,以及为什么我们表现得好像机器应该强制执行关于缩进的一目了然的规则,好像有一个简单、正确的方式来做到这一点。因为你建立这些技能的方式是重复,随着时间的推移变得更好,相信表达能力,并与其他人交流。作为一个行业,这些都是我们鄙视的东西。
这是否意味着你个人需要在这些事情上做的不好?答案是否定的。你没法让所有人都变得更好,但你个人可以做一些“不好的做法”,但实际上会让自己变得更好的事。你可以重新发明轮子,可以重复写同样的东西,也可以用“不好”的方式编写代码,看看会发生什么。
要注意的是,小心最佳实践。它们意味着别人做了工作来思考它,并变得更聪明,而你只是在使用他们想出的最简单的东西。这在开始时很好,但作为一种改进的方式,这很糟糕。
你要明白,如果你向艺术家、图书馆员和厨师学习,你就不能轻易地把软件世界的其他人也拉进来。仅仅因为你是对的,并不意味着你能说服他们。你的正确方法甚至可能需要他们不具备的技能。
但是如果你不在乎周围人的想法,你会变得更好,你不必告诉别人自己是怎么做到的。出于同样的原因,要小心使用工具和执行。它们的设计是为了保持最低水平的能力,而不是为了让你真正擅长一些不寻常的事情而设计的,而你想在一些不寻常的事情上变得真正优秀。
谨慎对待生产力技巧
人们会告诉你,变得更好的诀窍是不断地工作。他们会说,诀窍是每天进步一点,然后成倍增长。
但我认为,这个建议的陷阱就在这里:大多数时候,练习并不会让你变得更好。每隔一段时间,它就会使你的成绩有一个巨大的飞跃。但一些巨大的跳跃会使你在其他几件事上变得更糟。如果你期望每年都有20%的持续改善,每月复利,这会让人感觉很糟糕。
效率只会让你走到这一步,许多这样的过程效率极低,而且完全不可靠。虽然有时它们会带来巨大的收益,但往往是什么都没有,甚至它们偶尔对你造成的伤害比帮助更大。
漂亮整洁的生产力和效率建议,通常是针对你很了解,结构良好的任务,40年的编程生涯并不是那种任务。再次强调:想想日记,而不是马拉松或短跑。试图为自己保留一个进度条会很糟糕。随着时间的推移,你会学会小心任何过于整洁的东西。
效率总是某种特定类型的效率,省时的方法可能不省钱,效率是指你如何完善一个已经到位并运作良好的策略。
我很少谈论效率技巧,也并不是在告诉你做这些事情的最快方法,因为基本上最精心优化的方法也是最脆弱的。效率没问题,优化是好的。一旦你有了基本的工作,它可以提供额外的一点帮助。
最困难的部分是让基础发挥作用,这也是我要告诉你的大部分内容,事后保持高效就不那么重要,也更容易。
坚持才是最重要的
以上这些都是对我来说都是非常好的事情,大部分是为了让你消除疑虑,而不是改变你的方法。
如果你编写程序,你就是程序员,或者编码员,或者软件工程师,或者任何你喜欢的称呼。如果你坚持写程序,你可以成为一名多年的程序员。无论如何,只要你坚持不懈,管理自己的期望;当你犯错误时,你会注意到并纠正它们;你要注意别太刻板,试着享受这份工作。
剩下的就是时间,也许还有一点保持成熟。在你意识到之前,40年不知不觉就过去了。
参考链接:
《新程序员001-004》已全面上市,欢迎扫描下方二维码或点击进入立即订阅,即可畅享电子书及精美纸质书!