不要做一个只会面向搜索编程的程序员

时间:2023-02-11 16:22:36

在当今前端开发人员的世界里,JavaScript 疲劳已非常普遍。似乎每天都会出现新的框架、架构、命令行工具或 SaaS 服务。新事物的持续涌动让开发人员倍感疲倦。

为了避免这种情况,树立一种可靠的本能很重要——即甄别那些值得花时间去研究的技术和产品的能力,有些技术和产品在历经昙花一现后就销声匿迹,关于它们的文章在科技博客上也被归档,最后连正反两面的评论也都被遗忘了。

不要做一个只会面向搜索编程的程序员
 

大约在 30 年前我拥有了第一台自己的计算机,从此便开始了编程生涯。那是一台二手的 Commodore 64 的电脑,进入“Basic V2”时闪烁的光标像是在欢迎我。

从那以后,开发的世界里唯一不变的就是变化,以及不断学习和发现的需要。关于如何在不断涌现的新事物中立于不败之地,我有下面一些看法。

一、 了解历史

在这样一篇讨论如何在变革中处于领先地位的文章中,谈及历史可能有点出乎意料,但是为了了解和评估当代科技,你必须先了解该领域的历史。

历史知识可以让你拥有扎实的基础,帮助你思考:“这次有什么不同?”该问题的答案常常会决定这项新技术的成败。新鲜事物很酷,新鲜事物很有趣。但是如果过快的发展速度和 JavaScript 带来的间歇性的爆发,让你感觉难以接受时,你可以放慢脚步,记住这是一个漫长的过程,并且顺应大趋势比不断急于用最新的框架重写应用更为重要。

Peter Norvig 就这个问题发表了一篇很好的文章《十年内自学编程》(Teach Yourself Programming in Ten Years)

该领域中变化繁多且频频发生,很容易让人觉得那些新东西真的是新的。但令人惊讶的是科技发展的是周期性非常明显;表面看似是新东西,其实往往有深刻的历史渊源。

2004 年,Ruby on Rails 问世,并迅速崛起,对整个行业产生了巨大影响。与此同时,它的基本思想还是基于模型视图控制器(Model View Controller,MVC)模式,以及 Ruby 面向对象模式的基础,这些技术可以追溯到 70 年代末的 Small Talk 编程环境。

作为当时熟悉主流网络平台(PHP、Java、ASP)的开发人员来说,Ruby on Rails 不仅推出了具有全新语法的新语言,还提出了新的概念和主要的元编程的新范例。然而,对于那些一直关注 SmallTalk 的兴衰以及受其启发而创建的语言和平台的开发人员来说,Ruby on Rails 是一个很熟悉的概念(新型的语法,并采用一些 SmallTalk 应用程序的方式来实现 Web 应用)。他们仅需掌握 Ruby 和 SmallTalk 之间的差异(很重要但是差异并不大),以及 MVC 在 Web 和 Small Talk 应用程序之间的差异。

与之类似,React 的出现把整整一代 JavaScript 框架都扫进了垃圾堆。其中大部分框架都受到了 Rails 的启发,试图将 MVC 模型转移到浏览器中。对于很多开发人员来说,它似乎与依赖双向数据绑定模板的单页面的应用程序框架有很大的不同,与 JQuery 等简化的代码库也不一样。但是 React 的核心其实是受到了函数式编程语言(尤其是 OCAML)的启发,这可以一直追溯到计算机的早期阶段。

React 的创始人 Jordan Walke 最近在叙述自己的经历时,回顾了创建 React 的历史背景:

在很长一段时间里,我以为“天啊,我觉得我只是个奇怪的程序员。”后来,我参加了一门关于编程语言基础的课程(课程的大部分使用了 ML(SML)),而我终于掌握了一些如何描述我想建立的应用程序的一些基本术语。我还学习了编程风格,吸引我的既不是古怪,也不是新颖的思想,实际上是一些最古老的编程语言的思想(那些从未成为主流的思想),这些思想在软件业界经历了 20 多年的风吹雨打(在我看来都在朝着坏的方向发展)。

https://www.reactiflux.com/transcripts/jordan-walke/

对于很多前端开发人员来说,React 中完全成熟的状态管理融合了 Redux 的形式(也许是结合了 Immutable.js)让人一时有点难以理解。但是对于了解其后的历史背景并关注函数式编程(其概念可以追溯到 1958 年出现的 LISP)再现的开发人员来说,React 反映了熟悉的概念和想法。

即使在积极尝试学习新技术时,历史也可以起到很大的帮助。当 Rails 首次发布时,除了一些在线文档、教程和源代码本身(稍后将详细介绍源代码)之外,很难找到相关的资料。然而,有很多关于 MVC 演变到 Small Talk,再到 Objective-C 的文章,以及很多基于 Small Talk 的消息传递机制的元编程和 OOP 的经验教训。

这可以成为学习新技术的一个好工具,提高学习速度;我们无需再阅读最新的教程和新出现的文档,而是要弄清楚它们的灵感来源,以及它们引用的之前的知识和创立的基础。很多关于旧技术、想法和方法论的资料更加成熟,你会发现很多经验教训也完全可以使用该领域的新成果。

扎实的历史知识可以为你提供一个非常好的工具包,在面临新技术时可以想想:这次有什么不同?该问题的答案通常会决定一个新技术的成败。

二: 人、文化和社区都很重要

感谢 GitHub、Stack Overflow 和 NPM 的迅速崛起,我们可以更加轻松地了解社区的发展,以及开发人员的雄心壮志。虽然贡献度和给星表明很多项目已经取得成功,但在初期从这两点并不能看出项目的成功与否。然而,你会用下列方法选择技术来创建自己的软件或选择自己想去的公司,你也可以用相同的逻辑来确定一个项目是否会被社区接受:

是否有明确定义的愿景?

是否有明确的用户需求?

是否有合适的人员、资源和文档可以扩展?

是否具有可扩展性?例如,是否可以扩展或采用新兴技术或用户类型?

背后的支持者是谁?

人们往往以为工具和科技可以自行发展。例如,面向对象编程演变成了函数式编程,文本编辑器发展成了完全成熟的集成开发环境(IDE),还有动态语言转变成了静态类型语言。然而,新技术和框架不仅仅沿着自身的道路发展。它们是由人、组织和社区发明、构建并传播的。

当一种新型的工具或技术涌现时,其背后的技术基础(它有什么不同?构建的基础模式是什么?)和动机(为什么有人选择现在创建这个?哪些人会对此感兴趣?这项技术可以为公司解决哪些问题?)非常重要。

我最喜欢的一篇关于为什么有些工具可以获胜而有些被淘汰的文章是 Richard P. Gabriel 于 1989 年写的《The Rise of Worse is Better》[1]。文章描述了为什么 Unix 和 C 战胜了基于 LISP 的技术(其原因与两种解决方案内在的品质无关)。

在文章中,Gabriel 描述了“糟糕的设计却有更好的发展”,他比较了新泽西学校和麻省理工与斯坦福大学的设计,表明实现的简单性比终端界面的简单性或正确性更重要。正是这一点使得 C 和 Unix 在市场上击败了 LISP。C 编译器比 LISP 编译器更加容易实现、移植和优化,这使得 Unix 的实现人员可以更快地向用户交付软件。这导致这项技术被迅速采纳,并最终意味着更多人(和公司)向 C 和 Unix 生态系统的发展和完善投资。

在学习新技术时,不仅要理解它们的目标,以及在技术上的实现方法,还要了解它们的传播方式,以及社区的发展。通常变成重要的主流编程社区的技术正是那些能投为后续问题提供最佳解决方法的技术,即使有时它们看似是在旧技术的基础上发展起来的。

但真正的秘密是:

有时候领先于技术的工具注定无法得到广泛的采用(我敢打赌很快我们就不会用 Idris 语言编写 Web 应用了)。LISP 从未成为主流,但是当今很多主流框架、语言、代码库和技术都源自 LISP 的发明和探索的创意,即使在今天学习 LISP 也可以让我们更好地了解未来的技术。

如果你发现有的工具正处在这样的交叉路口,那么掌握这些情况可能会让你成为下一个超级开发。

三:知其然,更要知其所以然

不要专注于表面,我们需要关注底下的暗潮涌动。学习不同框架的语法或语言可以让你做好工作,但是了解这些技术的决策过程可以从根本上让你成为更好的开发人员。

Michael Feathers 列出了“每个开发人员应该阅读的 10 篇论文”[2]。所有这些文章都是关于语言、架构和文化的基本思想,并可以让你初步了解诸多趋势背后的基本思路,而这些直到今时今日仍然活跃在编程业内。

大胆地拥抱新事物!但是要有条不紊。让自己建立正确而坚持的基础。最终可以让你更快地采用新技术,更深入地了解它们,并更彻底地评估它们的持久力。

在我做开发的时候,与 * 非常接近的是带有源代码的计算机杂志,你可以手动将这些代码输入到你的机器上并运行程序。

我是一个粗心大意的打字员,我从来做不到输入完整的程序而不会有任何错误。与复制和粘贴 Stack Overflow 的代码段相比,这实际上是印在纸上的计算机程序的一个好处(无可否认的仅有的几个!),因为为了跑通代码,你需要真正理解代码。

作为开发人员,我们常常面临最后期限迫在眉睫的情况,我们需要背负压力尽快将新功能和改好的 Bug 交付到客户手中。我见过那些急于求成的开发人员,他们只是将代码库和代码片段放在一起,根本没有时间去理解其中的工作原理。或者,他们发现有什么不对的地方,然后只是尝试不同的解决方案,而不是首先花时间了解为什么系统出了问题。

不要学他们。记住,永远不要无脑地借用 Stack Overflow 或其他地方的解决方案,你需要花时间掌握解决方案可行的原因。更进一步挑战自己,弄清楚为了找到你自己的解决方案,你需要花费多少时间,需要哪些资源等。

有时你会发现一个小的改动(也许只是使用了另一个库,调用了不同的函数等)就能改好一个 Bug,但是你并不明白其中的原因。不能就此打住,你需要深入研究,搞清楚为什么原来那个解决方案失败了,而现在这个可行。这种深入研究常常可以让你找到一些蛛丝马迹,并发现潜伏在系统其他地方的 bug。

学习新技术时的状况也一样。不要专注于表面的学习。学习不同框架的语法或语言对你没有太多好处,但是了解这些技术下面的决策过程可以从根本上让你成长为更好的开发人员。

当一项工作或学习结束以后,最重要的不是你学到了什么(哪个框架、哪个工具、哪种语言),而是通过学习的过程你学到的了什么。

四、付诸实践

即便是对资深程序员来说,选择合适的工具也并不简单。选择依赖众所周知的、值得信赖的和可靠的工具,还是采用新技术(用新的更好的方法来解决问题),我们需要在这两者之间权衡利弊。但是,作为开发工作的一部分,一些事前工作可以帮助你成功地选择新工具并利用新工具实现功能。这实际上是一项不断发展的实践。下面是本文建议的几种做法。

写在最后:欢迎留言讨论,加关注,持续更新!!!