写点什么

Python 太慢、Golang 太差,那些关于软件工程的“宗教”辩论

  • 2019-08-12
  • 本文字数:4915 字

    阅读完需:约 16 分钟

Python太慢、Golang太差,那些关于软件工程的“宗教”辩论


开发者的世界里总是充斥着各种各样的争论,从编程语言、框架甚至到编辑器、Windows/iOS 系统,都可以成为争得面红耳赤的“宗教战争”。本文作者针对软件开发行业的辩论进行了深入研究,探讨了这些辩论背后的本质,解释了他认为好的技术辩论应该是怎样的。


Python 的速度不行。”

“都 9102 年了,还有人不用 Java 虚拟机ScalaClojure)构建 Web App 吗?”

Mongo 是最好的数据库;SQL 很差劲,SQL 数据库扩展性不行。任何现代工程师都必须熟悉 Mongo。”

Golang 糟透了(因为没有泛型);谁用谁白痴。”


在我刚刚成为软件工程师那会,最令我震惊的就是,同行们居然用“宗教战争”这样的字眼来形容工程层面的争议。有这么严重吗?干嘛那么大火气?带着好奇心,我希望弄清为什么工程技术辩论会成为“宗教战争”,而不像经验主义或者科学方法层面的其它问题那样可以安静平和地进行讨论。在亲身参与一些讨论之后,结果更是让我万分不解。


我发现,虽然也用到了不少术语,但多数工程辩论只是情绪性的或者简单化的产物,与工程效益几乎没有关系。通过研究这类辩论,我总结出以下几项要点,希望帮助大家在未来的对话以及交互当中提高效率。


我的观点包括:


  1. 有效识别出可能降低工程辩论质量的因素(例如讨论者与议题存在利益相关、使用炒作 / 营销内容作为工程论据、过多纠结于好或坏的争论,以及使用大量缺乏实际意义的虚荣性指标等)。

  2. 评估自己,特别是对所选工具的偏好。

  3. 评估用于制定工程决策的内容与人员,并思考其中可能存在的潜在问题。

  4. 通过讨论权衡并强调一切可能降低辩论质量的因素,鼓励经过深思熟虑的软件辩论。


下面,让我们首先看看可能降低软件工程辩论质量的因素。

“利益相关”

为什么只能宣泄情绪、却无法带来实效的工程辩论那么多?首要原因就是各方都在议题中都有“利益相关性”,这就意味着最终结论必须落在赢家和输家身上。以咨询企业为例,他们只了解单一语言 / 框架,而且与其他组织相比,他们当然会尽力宣扬自己所选择的解决方案。另一种情况则是工程师间的讨论,他们之所以会拿出不同的结论,是因为不同的技术选择会直接给他们造成对应影响甚至左右晋升前景。拿我之前了解的 Uber 内部对于 Node 与 Python 的争议来看,这种对抗只会令企业错失技术优势(例如最简单的 X 更快、Y 扩展性更强、Z 维护需求更少等等)。


“利益相关”有时候相关的 并不只是 工作内容或者收入前景。一类常见的例子是,我们不想花时间学习新东西,或者说只希望学自己想学的东西,这对团队来说当然是个负面因素。很多人可能在与熟悉技术的团队合作时,仍然强烈主张自己所熟知的工具,因为这对自己来讲更容易。或者,大家可能在考虑自己的职业前景,因此着力倡导一种能够帮助自己的技术,即使这可能与团队的利益相悖。这些技术选择可能广泛存在于我们的日常当中,其显然只会增加复杂性,而不会带来多大好处。

炒作与营销

炒作与营销内容对于那些“利益相关”者来说可算是极为强大的盟友,甚至可以说二者是互相成就了对方。新的操作系统、社交网络、开源前端框架或者语言需要吸引用户及开发人员,才能变得更具竞争力与价值。而其支持者也会努力进一步扩大用户 / 贡献者的规模,从而让自己的意义得到体现。在这样的思路之下,网络效应开始变得至关重要,并有可能引发与实际工程情况毫无关系的激烈争论。


这一点在工程层面显得尤为突出,因为工程讨论应当以专业知识为先决条件——即只允许具有基本理解的人参与讨论(没有真正理解,但却自信能够发表意见的作法其实相当危险)。如果“利益相关”一方达到较高的占比水平,那么正确一方的工程师们恐怕也别无选择,只能跑去学习前者“强烈推荐”的技术方案。


此外,极端的陈述与流行语更受媒体的青睐,也更能吸引支持者。但在进行辩论时,这种细微的差别几乎没有任何价值。我们并不是要彻底否定项目宣传,但开源项目或语言天然倾向于让贡献者反对其他开源项目,并为其描绘一幅光明的前景。这些企业 / 开源项目的内容营销(包括会谈、博文、媒体报道以及由利益相关者主理的大学课程)都将悄悄潜入工程辩论,并直接冲击冷静工程师们提出的全面且准确的观点。


炒作确实有可能获得成功,因为有些人愿意把自己的思想分享给那些特定的人群:没有技术专长、缺少时间或者实践经验的群体。他们通常也无法意识到很多布道者都有自己的利益主张。结果就是,他们会受到媒体缺乏论据的片面报道或者言辞激烈的帖子的直接影响。这就是所谓“无脑相信”,这种以布道内容为上,而不愿认真考虑各方实际利益的作法,可能给团队带来巨大的损失。

好坏之分

工程辩论中的另一个常见问题,就是争论的人们会考量不同的案例,并最终以这些案例作为判断相关技术到底是“好”还是“坏”的基础。我们不妨以 VimEmacs 这两款编辑器之间的永恒对抗为例:


你希望自己的文本编辑器能够开箱即用吗?如果你是一位不断开拓新环境的 DevOps 工程师,那么与只面对单一开发环境的全栈工程师相比,你对于最佳选项自然拥有不同的想法与理解。对 DevOps 工程师而言,能够开箱即用的方案也许更为理想;对只需要面对单一计算机的开发人员,IDE 的功能齐备水平(自动补全、插件、自定义按键)才是最重要的。这里的问题在于,很多人将辩论集中在“好”与“坏”之间,而非哪款工具最适合某个特定用例。

(在这方面,「利益相关」其实仍可分为两个层面:那些已经投入数年对编辑器进行微调的用户不愿改变使用习惯;而 Vim 或者 Emacs 的贡献者则希望搞垮对手以增加自身贡献者及 / 或用户规模,从而令竞争对手更难以与之抗衡。)


当团队在技术方案选择当中受到炒作观点的引导时,这种“好坏之分”的思维可能会带来大麻烦。例如,最近围绕微服务的热情(其在一定程度上重新定义了以往的使用实践)促使不少人重构自己的代码库。但即使是在初创企业当中,单体式架构仍然拥有着巨大的生产效益。在这样的背景下,一部分团队在起步阶段就专注于微服务,而忽略了产品 / 市场适应性,并最终导致工程安排成为容器化炒作浪潮下的牺牲品。


这里我单纯讨论好与坏的问题,但类似的过度简化倾向还有其它表现形式,例如旧与新之类,大家可以自行脑补。

偏爱虚荣性的指标

性能、可扩展性与页面加载大小都是工程辩论当中常见的所谓“重要指标”,但它们真那么重要吗?卓越工程师的一大标志,在于他们能够根据手头的实际问题做出权衡。因此,他们只会在必要时,牺牲开发速度、开发者生态系统规模或者可维护性等因素来换取语言的“高性能”或者页面最小化。有时候,我认为我们对这类指标的关注,有点像汽车爱好者们讨论中经常提到的百公里加速时间或者极速水平——这些指标确实非常有趣,但在不少重要决策当中却毫无意义。毕竟如果一家卡车制造商雇用了一位特别喜欢谈车辆性能的工程师,那么结果只能是一败涂地。


更进一步来讲,我们的辩论也可以专注于技术优化,而不考虑其它权衡性因素——即确保最佳决策能够实现全局最大收益,而非技术最大收益。举例来说,企业 / 项目对于编程语言的选择不应仅基于技术细节(性能、可扩展性、内存占用等等),还应考虑到库生态系统、可招聘开发人员规模、开发团队现有技能储备、未来前景以及维护挑战等众多其它权衡因素。很明显,目前大部分关于“正确语言”的争论只集中在技术层面。在设计自己的系统或者工具时,许多工程师都非常了解全局与本地优化问题,但在考虑其它问题时,却往往忽略了这一点。事实上,这些问题都会受到全局最大收益的影响。


引发这种状况的部分原因,在于我们沟通时往往抱有某些偏见。我们显然更了解自己的想法或技术,而不太了解对方的想法或技术。这时,我们往往会用最极端的观点或案例讽刺对方,同时只关注自己最好的一面(当然,这也适用于人类之间的其他辩论议题,例如政治倾向等)。而对我们工具的攻击,会被理解成对我们自身的攻击,接下来就是一场乱战。

如何进行更好的工程辩论

工程辩论非常重要。在初创企业当中,糟糕或者情绪化的技术辩论可能导致团队的实际目标愈发模糊,让人们无法弄清自己到底想打造怎样的成果。而在任何公司之内,这样的状况都可能令本有机会成功的项目陷入失败。

1. 自我评估

第一步是进行自我评估。我们之所以经常与其他人就工具的好坏进行辩论,很大程度上在于我们自己预设了偏好。真正有价值的作法,在于思考哪些框架、库或者语言有可能在你这里引发争吵性辩论,并反思如果再过几年,其中还有多少仍然受欢迎甚至能否继续存在。对于初级工程师来讲,回顾过去三、五年来的技术新闻网站头版,大家会发现很多此类辩论根本毫无意义。支持和倡导自己喜爱的工具可以理解,但我们也得真的花点时间了解另一方(正如经典的辩论格言:「让对手的论点变得更好」)。因此,不妨反思我们喜爱的工具在哪些用例中并非理想选择,同时结合对方提出的创新思路或见解。


另外,在宣扬自己的技术偏好时一定深思熟虑;因为你需要深入了解的不仅仅是自己的用例,还包括辩论对象的实际用例(这一原则不仅适用于辩论,也适用于你撰写的博文与评论内容)。另外,无论你是占据主动还是受到挑衅,都一定要保持谨慎的心态,千万不要驳斥那些令人信服的论据。我们知道自己知道什么,但更重要的是,我们得知道自己不知道什么。

2. 评估外部信息

接下来,要评估你在工程决策中使用的外部信息。首先评估与你进行辩论的工程师。在与另一方进行技术辩论时,需要确定是否存在某些可能左右其观点的个人或者狭隘的激励性因素(例如个人易用性、财务 / 职业动机、为产品建立开发者生态系统的意愿以及自我形象塑造等)。评估他们用于做出决策的证据,看看这些证据的来源是否存在问题。如果另一方正在利用我们的需求宣传他们的解决方案,请思考自己对具体用例是否了解、是否拥有深入的专业知识、是否充分考虑到权衡的意义。除非有充分的矛盾性证据说服对方,否则我们必须表现出必要的开放心态。


你还需要评估用于决策的工程内容。千万不要使用营销素材组织工程决策。想象一下,如果使用这些煽动性的信息,我们能够轻松让一大群初级工程师相信那些根本站不住脚的结论——这看似让我们在讨论中胜出,实际上对后续工作绝不是好事。请记住,最理想的内容宣传应当模糊作者的潜在意图。


如果大家对某一工程议题一无所知,请花点时间查看各类文章,并尝试通过亲自证明文章中的观点来完成知识学习。另外,请始终关注解决方案当中做出的具体权衡,包括那些往往被忽略的非技术性权衡。这项工作可能很难,但对于关键性决策却往往极为重要。或者,你也可以建立起一个值得尊重且思虑深远的工程师社区,并通过初级研究(不仅仅是阅读或者重复二手资料)进行论点测试。再有,请注意尽量避免使用新的术语描述旧有解决方案。虽然这种方法能够有效拉拢队友并激发人们的认同,但却未必能帮助你的团队找到正确选项。


在学习与个人成长方面,请支持那些愿意表达明确价值取向的团队,同时注意排除为了营销目的而创建的内容。如果你决定利用媒体素材作出关于工程技术的决策,那么必须确保自己能够处理好炒作以及好 / 坏二分观点之间的平衡。在利用某一社区中的素材(例如开源软件讨论)解决其它问题(例如起始工程决策)时,你可能需要有针对性地做出内容调整。

3. 鼓励全面的软件辩论

最后,你需要调整自己的沟通方式,包括面对面交流与虚拟方式(社交网络、博文帖子等)。在进行激烈的技术讨论时,请提出问题而非直接向某人叫板。这些问题能够帮助我们了解对方做出的全部假设,并据此引导他们找到更好的答案,且不至于引发情绪上的抵触。我们需要意识到,很多人除了字面上表达出的意思之外,在内心深处还有着另一股会引导其观点的潜在认知。如果你的目标是说服那些有思想的人,请用心揣摩如何通过细微差别提升沟通效果,同时引导他们将好坏之争转化为权衡之辩。关注团队或小组之间的共同目标,花点时间提升工程辩论本身的质量,而不仅仅是强调语言 / 框架 / 工具等内容。


再来聊点宏观的:我们需要有能力确定哪些情况适合使用工程术语辩论,而哪些情况与团队的权衡考量无关。相信大家都面对过不少艰难的工程技术决策,其中的差别你一定能够体会得到。

原文链接:

https://www.nemil.com/musings/betterdebates.html


看完这篇文章,或许你能更冷静地回答下面这个问题 ↓


#哪种编程语言注定会走向衰败? | 话题#


2019-08-12 16:4524793

评论 1 条评论

发布
用户头像
个人看法:PHP在国内的应用前景不是很好,微软系的技术栈在国内的发展势头同样堪忧。
2019-08-12 17:01
回复
没有更多了
发现更多内容

【插画】一文看懂容器k8s

恒生LIGHT云社区

Docker 容器 k8s

零代码上线小布对话技能:技能平台的实践与思考

OPPO小布助手

人工智能 自然语言处理 算法 零代码 语义理解

为构建大型复杂系统而生的微服务框架 Erda Infra

尔达Erda

开源 程序员 微服务 云原生 运维开发

云小课 | 到底什么是区块链?

华为云开发者联盟

区块链 华为云 区块链的定义 区块链的解决方案 区块链的发展

数据中台为什么要建标签体系,分类它不香吗?

用友BIP

数据中台 标签体系

1年半经验,2本学历,Curd背景,竟给30K,我的美团Offer终于来了

Java~~~

Java 架构 面试 微服务 多线程

手撸二叉树之数据流中的第 K 大元素

HelloWorld杰少

数据结构与算法 8月日更

小手哆嗦一下,就能用 Python Django 实现一个微型博客系统

梦想橡皮擦

8月日更

Vue进阶(二十六):详解 router.push()

No Silver Bullet

Vue router 8月日更

测试开发之系统篇-Docker容器安装

禅道项目管理

Docker 测试开发

数据中台——数据汇聚存储技术解析

用友BIP

数据中台 数据存储

【Vue2.x 源码学习】第三十二篇 - diff算法-乱序比对

Brave

源码 vue2 8月日更

uni-app技术分享| 怎么用uni-app实现呼叫邀请

anyRTC开发者

uni-app 音视频 呼叫邀请 点对点呼叫

某离散制造行业龙头客户“主数据管理平台”建设分享

用友BIP

主数据管理

云计算运维与传统运维工作有啥不同?需要什么资质?

行云管家

云计算 服务器 IT运维 云计算运维

拒绝内卷!Github连夜封杀的阿里全套Spring Security高级笔记

Java 编程 架构 面试 程序人生

【LeetCode】第一个只出现一次的字符Java题解

Albert

算法 LeetCode 8月日更

高防服务器,企业成长安全控制有效性的关键工具

九河云安全

阿里(钉钉部门)远程面,三面坐上“直通车”,拿下offer没问题

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Compose 可组合项的生命周期

Changing Lin

8月日更

Vue进阶(二十五):<component>实现动态组件

No Silver Bullet

Vue 动态组件 8月日更

Go 学习笔记之 Channels

架构精进之路

Go 语言 8月日更

跨链治理之入门三问 :WHO WHAT HOW

趣链科技

区块链 治理机制

当容器应用越发广泛,我们又该如何监测容器?

阿里巴巴云原生

云计算 容器 云原生 监控 中间件

prometheus 语法

Rubble

Prometheus 8月日更

AIMA:如何通过质量指标提高QA的绩效(译)

BY林子

软件测试 绩效 QA

差点跳起来了!全靠这份999页Java面试宝典,我刚拿到美团offer

Java~~~

Java 架构 面试 微服务 多线程

netty系列之:使用POJO替代buf

程序那些事

Java Netty nio 程序那些事

信创产业已成现象级新风口,快来加入争做“弄潮儿”

华为云开发者联盟

开源 信创 opengauss openEuler 鲲鹏

c++ 构造函数详解

若尘

c++ 构造函数 8月日更

VSCode July 2021 (version 1.59) 更新

IT蜗壳-Tango

8月日更

Python太慢、Golang太差,那些关于软件工程的“宗教”辩论_语言 & 开发_nemil_InfoQ精选文章