引言:开发者的世界里总是充斥着各种各样的争论,从编程语言、框架甚至到编辑器、Windows/iOS系统,都可以成为争得面红耳赤的“宗教战争”。本文作者针对软件开发行业的辩论进行了深入研究,探讨了这些辩论背后的本质,解释了他认为好的技术辩论应该是怎样的。
“Python的速度不行。”
“都9102年了,还有人不用Java虚拟机(Scala、Clojure)构建Web App吗?”
“Mong是最好的数据库;SQL很差劲,SQL数据库扩展性不行。任何现代工程师都必须熟悉Mongo。”
“Golang糟透了(因为没有泛型);谁用谁白痴。”
在我刚刚成为软件工程师那会,最令我震惊的就是,同行们居然用“宗教战争”这样的字眼来形容工程层面的争议。有这么严重吗?干嘛那么大火气?带着好奇心,我希望弄清为什么工程技术辩论会成为“宗教战争”,而不像经验主义或者科学方法层面的其它问题那样可以安静平和地进行讨论。在亲身参与一些讨论之后,结果更是让我万分不解。
我发现,虽然也用到了不少术语,但多数工程辩论只是情绪性的或者简单化的产物,与工程效益几乎没有关系。通过研究这类辩论,我总结出以下几项要点,希望帮助大家在未来的对话以及交互当中提高效率。
我的观点包括:
有效识别出可能降低工程辩论质量的因素(例如讨论者与议题存在利益相关、使用炒作/营销内容作为工程论据、过多纠结于好或坏的争论,以及使用大量缺乏实际意义的虚荣性指标等)。评估自己,特别是对所选工具的偏好。评估用于制定工程决策的内容与人员,并思考其中可能存在的潜在问题。通过讨论权衡并强调一切可能降低辩论质量的因素,鼓励经过深思熟虑的软件辩论。下面,让我们首先看看可能降低软件工程辩论质量的因素。
利益相关
为什么只能宣泄情绪、却无法带来实效的工程辩论那么多?首要原因就是各方都在议题中都有“利益相关性”,这就意味着最终结论必须落在赢家和输家身上。以咨询企业为例,他们只了解单一语言/框架,而且与其他组织相比,他们当然会尽力宣扬自己所选择的解决方案。另一种情况则是工程师间的讨论,他们之所以会拿出不同的结论,是因为不同的技术选择会直接给他们造成对应影响甚至左右晋升前景。拿我之前了解的Uber内部对于Node与Python的争议来看,这种对抗只会令企业错失技术优势(例如最简单的X更快、Y扩展性更强、Z维护需求更少等等)。
“利益相关”有时候相关的并不只是工作内容或者收入前景。一类常见的例子是,我们不想花时间学习新东西,或者说只希望学自己想学的东西,这对团队来说当然是个负面因素。很多人可能在与熟悉技术的团队合作时,仍然强烈主张自己所熟知的工具,因为这对自己来讲更容易。或者,大家可能在考虑自己的职业前景,因此着力倡导一种能够帮助自己的技术,即使这可能与团队的利益相悖。这些技术选择可能广泛存在于我们的日常当中,其显然只会增加复杂性,而不会带来多大好处。
炒作与营销
炒作与营销内容对于那些“利益相关”者来说可算是极为强大的盟友,甚至可以说二者是互相成就了对方。新的操作系统、社交网络、开源前端框架或者语言需要吸引用户及开发人员,才能变得更具竞争力与价值。而其支持者也会努力进一步扩大用户/贡献者的规模,从而让自己的意义得到体现。在这样的思路之下,网络效应开始变得至关重要,并有可能引发与实际工程情况毫无关系的激烈争论。
这一点在工程层面显得尤为突出,因为工程讨论应当以专业知识为先决条件——即只允许具有基本理解的人参与讨论(没有真正理解,但却自信能够发表意见的作法其实相当危险)。如果“利益相关”一方达到较高的占比水平,那么正确一方的工程师们恐怕也别无选择,只能跑去学习前者“强烈推荐”的技术方案。
此外,极端的陈述与流行语更受媒体的青睐,也更能吸引支持者。但在进行辩论时,这种细微的差别几乎没有任何价值。我们并不是要彻底否定项目宣传,但开源项目或语言天然倾向于让贡献者反对其他开源项目,并为其描绘一幅光明的前景。这些企业/开源项目的内容营销(包括会谈、博文、媒体报道以及由利益相关者主理的大学课程)都将悄悄潜入工程辩论,并直接冲击冷静工程师们提出的全面且准确的观点。
炒作确实有可能获得成功,因为有些人愿意把自己的思想分享给那些特定的人群:没有技术专长、缺少时间或者实践经验的群体。他们通常也无法意识到很多布道者都有自己的利益主张。结果就是,他们会受到媒体缺乏论据的片面报道或者言辞激烈的帖子的直接影响。这就是所谓“无脑相信”,这种以布道内容为上,而不愿认真考虑各方实际利益的作法,可能给团队带来巨大的损失。
好坏之分
工程辩论中的另一个常见问题,就是争论的人们会考量不同的案例,并最终以这些案例作为判断相关技术到底是“好”还是“坏”的基础。我们不妨以Vim与Emacs这两款编辑器之间的永恒对抗为例:
你希望自己的文本编辑器能够开箱即用吗?如果你是一位不断开拓新环境的DevOps工程师,那么与只面对单一开发环境的全栈工程师相比,你对于最佳选项自然拥有不同的想法与理解。对DevOps工程师而言,能够开箱即用的方案也许更为理想;对只需要面对单一计算机的开发人员,IDE的功能齐备水平(自动补全、插件、自定义按键)才是最重要的。这里的问题在于,很多人将辩论集中在“好”与“坏”之间,而非哪款工具最适合某个特定用例。(在这方面,「利益相关」其实仍可分为两个层面:那些已经投入数年对编辑器进行微调的用户不愿改变使用习惯;而Vim或者Emacs的贡献者则希望搞垮对手以增加自身贡献者及/或用户规模,从而令竞争对手更难以与之抗衡。)
当团队在技术方案选择当中受到炒作观点的引导时,这种“好坏之分”的思维可能会带来大麻烦。例如,最近围绕微服务的热情(其在一定程度上重新定义了以往的使用实践)促使不少人重构自己的代码库。但即使是在初创企业当中,单体式架构仍然拥有着巨大的生产效益。在这样的背景下,一部分团队在起步阶段就专注于微服务,而忽略了产品/市场适应性,并最终导致工程安排成为容器化炒作浪潮下的牺牲品。
这里我单纯讨论好与坏的问题,但类似的过度简化倾向还有其它表现形式,例如旧与新之类,大家可以自行脑补。
偏爱虚荣性的指标
性能、可扩展性与页面加载大小都是工程辩论当中常见的所谓“重要指标”,但它们真那么重要吗?卓越工程师的一大标志,在于他们能够根据手头的实际问题做出权衡。因此,他们只会在必要时,牺牲开发速度、开发者生态系统规模或者可维护性等因素来换取语言的“高性能”或者页面最小化。有时候,我认为我们对这类指标的关注,有点像汽车爱好者们讨论中经常提到的百公里加速时间或者极速水平——这些指标确实非常有趣,但在不少重要决策当中却毫无意义。毕竟如果一家卡车制造商雇用了一位特别喜欢谈车辆性能的工程师,那么结果只能是一败涂地。
更进一步来讲,我们的辩论也可以专注于技术优化,而不考虑其它权衡性因素——即确保最佳决策能够实现全局最大收益,而非技术最大收益。举例来说,企业/项目对于编程语言的选择不应仅基于技术细节(性能、可扩展性、内存占用等等),还应考虑到库生态系统、可招聘开发人员规模、开发团队现有技能储备、未来前景以及维护挑战等众多其它权衡因素。很明显,目前大部分关于“正确语言”的争论只集中在技术层面。在设计自己的系统或者工具时,许多工程师都非常了解全局与本地优化问题,但在考虑其它问题时,却往往忽略了这一点。事实上,这些问题都会受到全局最大收益的影响。
引发这种状况的部分原因,在于我们沟通时往往抱有某些偏见。我们显然更了解自己的想法或技术,而不太了解对方的想法或技术。这时,我们往往会用最极端的观点或案例讽刺对方,同时只关注自己最好的一面(当然,这也适用于人类之间的其他辩论议题,例如政治倾向等)。而对我们工具的攻击,会被理解成对我们自身的攻击,接下来就是一场乱战。
如何进行更好的工程辩论
工程辩论非常重要。在初创企业当中,糟糕或者情绪化的技术辩论可能导致团队的实际目标愈发模糊,让人们无法弄清自己到底想打造怎样的成果。而在任何公司之内,这样的状况都可能令本有机会成功的项目陷入失败。
1.自我评估
第一步是进行自我评估。我们之所以经常与其他人就工具的好坏进行辩论,很大程度上在于我们自己预设了偏好。真正有价值的作法,在于思考哪些框架、库或者语言有可能在你这里引发争吵性辩论,并反思如果再过几年,其中还有多少仍然受欢迎甚至能否继续存在。对于初级工程师来讲,回顾过去三、五年来的技术新闻网站头版,大家会发现很多此类辩论根本毫无意义。支持和倡导自己喜爱的工具可以理解,但我们也得真的花点时间了解另一方(正如经典的辩论格言:「让对手的论点变得更好」)。因此,不妨反思我们喜爱的工具在哪些用例中并非理想选择,同时结合对方提出的创新思路或见解。
另外,在宣扬自己的技术偏好时一定深思熟虑;因为你需要深入了解的不仅仅是自己的用例,还包括辩论对象的实际用例(这一原则不仅适用于辩论,也适用于你撰写的博文与评论内容)。另外,无论你是占据主动还是受到挑衅,都一定要保持谨慎的心态,千万不要驳斥那些令人信服的论据。我们知道自己知道什么,但更重要的是,我们得知道自己不知道什么。
2. 评估外部信息
接下来,要评估你在工程决策中使用的外部信息。首先评估与你进行辩论的工程师。在与另一方进行技术辩论时,需要确定是否存在某些可能左右其观点的个人或者狭隘的激励性因素(例如个人易用性、财务/职业动机、为产品建立开发者生态系统的意愿以及自我形象塑造等)。评估他们用于做出决策的证据,看看这些证据的来源是否存在问题。如果另一方正在利用我们的需求宣传他们的解决方案,请思考自己对具体用例是否了解、是否拥有深入的专业知识、是否充分考虑到权衡的意义。除非有充分的矛盾性证据说服对方,否则我们必须表现出必要的开放心态。
你还需要评估用于决策的工程内容。千万不要使用营销素材组织工程决策。想象一下,如果使用这些煽动性的信息,我们能够轻松让一大群初级工程师相信那些根本站不住脚的结论——这看似让我们在讨论中胜出,实际上对后续工作绝不是好事。请记住,最理想的内容宣传应当模糊作者的潜在意图。
如果大家对某一工程议题一无所知,请花点时间查看各类文章,并尝试通过亲自证明文章中的观点来完成知识学习。另外,请始终关注解决方案当中做出的具体权衡,包括那些往往被忽略的非技术性权衡。这项工作可能很难,但对于关键性决策却往往极为重要。或者,你也可以建立起一个值得尊重且思虑深远的工程师社区,并通过初级研究(不仅仅是阅读或者重复二手资料)进行论点测试。再有,请注意尽量避免使用新的术语描述旧有解决方案。虽然这种方法能够有效拉拢队友并激发人们的认同,但却未必能帮助你的团队找到正确选项。
在学习与个人成长方面,请支持那些愿意表达明确价值取向的团队,同时注意排除为了营销目的而创建的内容。如果你决定利用媒体素材作出关于工程技术的决策,那么必须确保自己能够处理好炒作以及好/坏二分观点之间的平衡。在利用某一社区中的素材(例如开源软件讨论)解决其它问题(例如起始工程决策)时,你可能需要有针对性地做出内容调整。
3. 鼓励全面的软件辩论
最后,你需要调整自己的沟通方式,包括面对面交流与虚拟方式(社交网络、博文帖子等)。在进行激烈的技术讨论时,请提出问题而非直接向某人叫板。这些问题能够帮助我们了解对方做出的全部假设,并据此引导他们找到更好的答案,且不至于引发情绪上的抵触。我们需要意识到,很多人除了字面上表达出的意思之外,在内心深处还有着另一股会引导其观点的潜在认知。如果你的目标是说服那些有思想的人,请用心揣摩如何通过细微差别提升沟通效果,同时引导他们将好坏之争转化为权衡之辩。关注团队或小组之间的共同目标,花点时间提升工程辩论本身的质量,而不仅仅是强调语言/框架/工具等内容。
有疑问加站长微信联系(非本文作者)