“如果有更多的高级工程师能够承认他们并没有把所有的事情都搞清楚,初级工程师就不会有那么多不切实际的期望。”
架构师是技术团队的枢纽,担负着成功交付可用的解决方案的任务。以前大家认为架构师可能是一个通才,有一定的深度,也有不同方案的广度,同时具备足够的经验,知道在哪些地方有可能出现问题。但软件开发发展到现在,涉及的领域越来越多:前端、后端、集成测试、云、物联网、运维(监控)等等,有无限的炒作和不断出现的“上百万”技术框架。
知识不断膨胀后的世界,已经不太可能像十年前那样打造“全才”、“通才”了。我们不知道的越来越多,从初级岗位晋升到资深开发的过程中,最有价值的技能是快速学习新事物的能力,以及能快速地了解框架/技术堆栈背后相同的基础原理。
软件开发和以前大不相同了
我最近一直在想一个问题:在二三十年前写代码应该是什么样子的?
那个时候,我最喜欢的技术作家之一 Ellen Ullman 是一名开发者和项目经理,她写了一本关于软件开发、生活、哲学以及它们之间关系的书,叫作“Close to the Machine”。
她在其中一章讲述了她与一家大银行负责全球交易处理支付重组的副总裁的一次会面。
由银行、自动柜员机、票据交换所、计算机、电话组成的庞大网络——所有这些组合在一起,可以在全球范围内发送一笔信用卡交易——这就是她负责的领域。
她说:“如果这一切都崩溃了,银行就无法平衡账目。”
……
一阵厌恶的感觉涌上心头:“我想象着在系统中留下一个 bug,最后却要为全球银行倒闭负责的感觉。”(Ullman 提到,那个副总裁说整个系统只有三个开发人员。)
副总裁笑了:“有他们在,我们感到很幸运。这个系统是用汇编语言开发的。”
“是用汇编语言开发的?”我的身体感到了一丝不适。汇编代码是低级代码,也就比机器语言高一级,不仅难写,也很难修改。随着时间的推移,注释的数量开始超过代码的数量,但这些注释也没有什么用处,反正也没人能看懂。
当副总裁看到我的忧虑,她放松了一下。接下来,她要和我说说他们有一个专门的编程小组正在尝试新的开发技术。分层的客户端/服务器、面向对象系统和消费者网络——所有这些很酷的东西与那些已经存在了 15 年的汇编代码形成了鲜明的对比。
在那么多年前写代码是一种什么感觉?我们知道可以被机器读取的字节码组成了我们的软件,并在互联网上传输信息。我们会因为各种各样的原因开发计算机程序,但最终,所有程序都是将人类可以理解的高级信息(如文本、推特、视频)转换为字节码,移动它们,然后再转换成字节码,直到变成人类可读的信息。
早期的编程主要关注如何取代这套物理编程基础设施(在打孔卡上编写逻辑,并在巨大的机器上运行),于是第一种编程语言出现了,就是汇编语言——让 Ullman 毛骨悚然的编程语言,因为汇编非常接近字节码。
随着机器变得更小,更容易访问,更多的编程语言出现了。到了 20 世纪 80 年代末或 90 年代初,一般的程序员除了知道汇编语言、COBOL、SQL、Fortran,可能还知道新晋的 C 语言。
从很多方面来看,当时的计算机世界要小得多,也没有那么复杂。我们甚至没有版本控制系统!但是,即使编程语言的数量少,要获取到相关的信息也并不容易。当时没有像 StackOverflow 这样的网站,只有参考书、手册和在线论坛。在早期,编程和找到有关编程的信息并不容易。
我没有从用户组那里得到编程方面的帮助,但他们确实存在。他们每个月见一次面,那里肯定有懂编程的人。我的意思是,如果你当时拥有自己的计算机,至少需要知道一点编程知识,即使只是用 DOS 写批处理文件。如果不懂技术知识,就不能那么频繁地使用计算机,因为有关 GUI 的想法在当时仍然是个新鲜事物。
互联网的迅速崛起为不同类型的编程语言的发展创造了机会:作为构建互联网平台的 JavaScript,作为主流 Web 服务开发语言的 Java,以及作为多用途 Web 和数据语言的 Python。
互联网的发展还意味着有关这些编程语言的信息可以得到更快的传播,获得更多的关注者,并通过博客和演讲的方式在各公司之间传播。现在,YouTube 等服务利用了带宽的增加,可以进行在线直播。
随着开发互联网应用程序变得越来越容易,收集用户的信息也变得越来越容易,这些数据开始涌入互联网后端的数据湖。随着联网机器的发展,工具、提供数千种服务的云环境、不同的编配基础设施、敏捷、看板、Scrumban 以及针对各种技术主题的开发者会议呈指数级增长。
以前,不管是在硬件还是软件环境方面,你都受到很大的限制。现在,对于每种编程语言,你都可以选出几种 IDE,将代码部署到不同的云平台,与其他代码、应用程序集成,使用成百上千种不同的方法来完成同样的事情。
你不可能精通所有的领域
我们现在的处境很有趣,这可以从人们对这条推文的回复中看出来。
推文译文:如果有更多的高级工程师能够承认他们并没有把所有的事情都搞清楚,初级工程师就不会有那么多不切实际的期望,那么这将是一件很酷的事情。
在推文的回复中,数十名资深人士表示,在他们的日常工作中,有很多东西是他们不知道的,有很多东西他们想要弄清楚是怎么回事。
类似这样的推文通常能够在人们职业生涯的早期给予他们探索的力量,但这也让我想起了一件我已经思考了很长一段时间的事情。因为我们有这么多不同的软件产品、服务、编程语言以及开发软件的流程,所以不再存在高级开发人员这种东西。或者更确切地说,不存在既具备早期开发环境所需的深度知识又具备现代软件技术栈所需的广度知识的高级开发人员。我们已经从邮寄软盘的时代发展到全方位涵盖软件开发周期的广泛领域:前端、后端、集成测试、云、物联网、运维(监控),以及其他可能被我们遗忘的 100 万个领域。
我们可以看一下软件开发生命周期中某个领域可用的工具数量,这甚至与编写代码无关,仅仅是为了 DevOps,也就是监控代码运行方式的“元控制”。
在早期,开发者可以进行深度探索,因为没有这么多需要了解的东西。你可以坐下来思考一些特别棘手的 C 语言代码,因为你不需要学习 React、Kubernetes、Tensorflow、GitHub、GitLab 以及任何来自 aws:Reinvent 的最新公告。
再以现在的机器学习领域为例。我发了一个推文,恶搞了 Matt Turk 每年发布的与机器学习相关的工具的现状。但是,每一个笑话总会反映出一些事实:
从事数据工作的人不可能了解所有这些工具,这些工具使用不同的编程语言开发,存在细微的差别。
最近,Chip 在推特上说,如果她要重新开始学习机器学习工程,她会专注这些领域:
我基本上同意她的观点,但不可能每个机器学习工程师都能够知道所有这些领域,或者擅长所有这些领域,或者在工作中需要用到所有这些领域的东西。
例如,我(至今)从未使用过 Dask 或 Kubernetes,只接触了数据结构,而且在工作中使用的 ML 算法比我希望的要少得多。但除了 Chip 所说的清单之外,版本控制、单元测试/集成测试、SQL、Python 和 REST API 却构成了我日常工作的大部分。
我无法想象这份清单对一个刚进入这个行业的人来说有多么难以承受。清单都还没有列出每个类别的子类别。例如,在机器学习算法下面,你可能会看到 20 或 30 种以上的算法。在我的整个职业生涯中,我大概只用过 4 到 5 种。
我敢说,大多数技术人员都只对其中核心的 7 到 8 个东西非常了解。除此之外,可以参考谷歌和 O'Reilly。
推文译文:好的开发者复制,优秀的开发者粘贴。
没有通才,只剩“顾问”
过去,用来区别资深人士和初级人士的是他们对编程语言和操作系统的了解深度,以及所花的时间。现在用来区别他们的是广度,还有辨别模式的能力,并将其用于一个技术栈的多个部分、多个技术栈以及多个行业的多份工作上。我们现在对软件技术栈的某些部分的了解都处在初级阶段,区别只是在于哪些部分上。
当然,这可能是我个人的偏见,但我真的认为高级开发人员现在的角色是一个内部顾问,根据之前发生的事件和产品提供建议,并猜测下一步该如何走,如果他们不知道,他们需要问什么样的问题来找到下一个方向。
如果你以前使用过 Kafka,对于如何使用 Kinesis 就不会有任何问题,而且你会发现它跟 Flink 非常相似。如果你使用过 Ruby,对于如何使用 Python 就不会有问题。如果你使用过 cron 和 YAML,你会喜欢 GitHub Actions。如果你使用过 Spark,那么使用 Dask 可能就不会有什么问题。
在其他方面,我认为现在对高级人员来说最重要的是扎实地掌握几种编程语言以及超越这些语言的基础知识。这里有一个例子:
推文译文:如果一定要我找出一个可以让你看起来非常牛逼的编程概念,那可能是哈希表(在 Python 里叫字典),因为它出现在几乎所有我做过的数据处理/程序当中。
当然,做软件工程除了写代码外,也与思考逻辑问题有关。但是,在一个拥有 500 万个数据处理框架的世界里,推理出为什么某些东西可能可行或不可行的能力变得更加重要。
换句话说,将系统和平台分解为核心原则、1 和 0,并能够在其他地方重新应用这些原则,这就是对命令行全新的了解。当然,你还是应该要知道什么是命令行。