试译:开源项目成功的十条准则

Ten Rules for Open Source Success

《开源项目成功的十条准则》

Everyone wants it, lots of people try it, yet doing it is mostly painful and irritating. I’m speaking about free software aka open source. Today I’m going to summarize 30 years of coding experience in ten management-proof bullet points.

每个人都想去做,也有很多人跃跃欲试,但是真做起来却常常会令人痛苦和愤怒——我说的是自由软件,或者更宽泛一些的开源软件。今天我要将自己30年来的开发经验,总结为开源软件的十条成功法则。

庄表伟:每个人都需要它,很多人跃跃欲试,但是干起来却往往会令人痛苦或者愤怒。我在谈论的是自由软件(开源软件)。今天,以我30年来的开发经验,我想要总结以下10条经营要点:

余晟:
每个人都想去做开源,也有很多人尝试了,但是真正去做却常常收获痛苦和恼怒。我所说的这回事是自由软件,或者叫开源软件。今天我要总结自己30年来的开发经验,归纳为十条经得起实践检验的准则。

魏永明:
所有人需要它,很多人尝试它,但做起来却常常是痛苦的甚至会令人不快——我说的是自由软件,或者更宽泛一些的开源软件。今天,我将把本人三十年的编码经验总结为开源软件的十条成功法则。

八刀:今天我将把我三十年的开发经验囊括在以下十点。

1、People Before Code
1、人比代码重要

This is the Golden Rule, taught to me by Isabel Drost-Fromm. Build community, not software. Without community your code will solve the wrong problems. It will be abandoned, ignored, and will die. Collect people and give them space to work together. Give them good challenges. Stop writing code yourself.
这是一条黄金法则,是Isabel Drost-Fromm【注1】教给我的。我们要建立的是社区而不是软件。没有社区,你的代码就会用来解决错误的问题。然后这些代码会被抛弃、忽略,最后死去。正确的做法是把人集结起来,给他们协同工作的空间,给他们充分的挑战。切记不要亲手来写代码!

注1:Isabel Drost-Fromm是Apache软件基金会的成员,Apache Mahout的创立者之一。

庄表伟:这是一条黄金法则,是Isabel Drost-Fromm教给我的。建立社区而非软件,没有社区,你的代码将会去解决错误的问题。然后它将会被抛弃、忽略,最后死去。将人汇集起来,给他协同工作的空间,给他们足够好的挑战,停止自己写代码!

余晟:这是金科玉律,是Isabel Drost-Fromm教给我。我们要建立的是社区而不是软件。没有社区,你的代码就会用来解决错误的问题。然后这些代码会被抛弃、忽略,最后死去。正确的做法是把人集结起来,给他们协同工作的空间,给他们充分的挑战。切记不要亲手来写代码!

Holm:..他们足够好的挑战,停止自己写代码!断句有问题,读起来想“让他们停写”

2、Use a Share-Alike License
2、使用“以相同方式共享”的许可证

庄表伟:2、使用‘以相同方式共享’型许可证

余晟:2、使用‘以相同方式共享’的许可证

Share-alike is the seat belt of open source. You can boast about how you don’t need it, until you have a bad accident. Then you will either find your face smeared on the wall, or have light bruising. Don’t become a smear. Use share-alike. If GPL/LGPL is too political for you, use MPLv2.
“以相同方式共享”是开源的安全带。在遇到严重的事故之前,你大可吹嘘自己完全不需要它。一旦出现事故,你就会发现自己满脸污垢,或者‘轻微擦伤’,不要成为一个“伤员”。使用“以相同方式共享”的许可证吧,如果你觉得GPL/LGPL太过于政治化,那就用MPLv2。

庄表伟:‘以相同方式共享’是开源的安全带,你可以吹嘘自己是如何的不需要它,直到你碰到糟糕的‘意外’。然后你会发现自己头撞南墙,或者‘轻微擦伤’,不要成为一个‘伤员’。用‘以相同方式共享’型许可证吧,如果你觉得GPL/LGPL太过于政治化,那就用MPLv2。

余晟:‘以相同方式共享’是开源的安全带。在遇到严重的事故之前,你大可吹嘘自己完全不需要它。一旦出现事故,你就会发现自己满脸污垢,或者还有轻微擦伤。你应当避免把自己搞砸,你应该使用‘以相同方式共享’的许可证吧。如果觉得GPL/LGPL太过于政治化,那就用MPLv2。

3、Use an Zero-Consensus Process
3、使用一个无需达成共识的协作流程

八刀:零共识

Seeking upfront consensus is like waiting for the ideal life partner. It is kind of crazy. Github killed upfront consensus with their fork/pull-request flow, so you’ve no excuse in 2015. Accept patches like Wikipedia accepts edits. Merge first, fix later, and discuss out of band. Do all work on master. Don’t make people wait. You’ll get consensus, after the fact.
寻求事前的共识就像是在等待理想的人生伴侣,这简直就是疯狂。借助fork/pull-request这种模式,Github已经干掉了事前共识,所以在2015年的今天你没有任何借口坚持事前共识。你应当像维基百科那样接受修改。先合并,再修复,同时单独讨论。所有工作应当在master分支上进行,不应当让大家等待。有了既成事实,共识会随之而来。

庄表伟:寻求前期的共识就像是在等待理想的人生伴侣,这简直就是疯狂。借助fork/pull-request这种模式,Github已经干掉了前期共识,所以在2015年的今天,你没有任何借口。例如像维基百科那样接受修改。先合并,再修复,然后附带进行讨论。在master分支上做所有的工作,不要让人等待。事实上,你会逐渐得到共识的。

八刀:这听起来有点疯狂

余晟:寻求事前共识就像是在等待理想的人生伴侣,这很疯狂。借助fork/pull-request这种模式,Github已经干掉了事前共识,所以在2015年的今天你没有任何借口坚持事前共识。你应当像维基百科那样接受修改。先合并,再修复,同时单独讨论。所有工作应当在master分支上进行,不应当让大家等待。有了既成事实,共识会随之而来。

刘天栋:然后扩大进行体制外讨论。先上车,后补票,你会逐渐得到共识的。

Holm:寻求前期的共识:预先达成的共识;事实上,你会逐渐得到共识的:最终,你能获得事实的共识。

4、Problem, then Solution
4、首先是问题,然后才是解决方案

庄表伟:4、首先是问题,然后才是解决方案

余晟:4、问题优先,然后才是解决方案

Educate yourself and others to focus on problems not features. Every patch must be a minimal solution to a solid problem. Embrace experiments and wild ideas. Help people to not blow up the lab. Collect good solutions and throw away the bad ones. Embrace failure, at all levels. It is a necessary part of the learning process.
教育自己和其他人,聚焦于问题而非功能特性。每一个补丁都必须是解决某个实际问题的最小化的解决方案。勇于尝试,勇于接受疯狂的想法。你还需要帮助他人,确保他们干的事情不会导致实验室的爆炸。收集好的解决方案,抛弃那些糟糕的方案。在各个层面上都应当宽容失败。这是学习过程中不可缺少的一部分。

庄表伟:教育自己和其他人,聚焦于问题而非功能特性。每一个补丁都必须是解决某个实际问题的最小化的解决方案。勇于尝试,勇于接受疯狂的想法,确保实验室不会被炸掉。收集好的解决方案,抛弃那些坏的。在所有的层面上,拥抱失败。这是学习过程中不可缺少的一部分。

余晟:你必须教育自己和他人,集中关注问题,而不是功能特性。所有补丁都应当是解决某个实际问题的最小化解决方案。你应当勇于尝试,勇于接受疯狂的想法。你还需要帮助他人,确保他们干的事情不会导致实验室的爆炸。请收集好的解决方案,抛弃那些糟糕的方案。在各个层面上都应当宽容失败。这是学习过程中不可缺少的一部分。

Holm:…疯狂的想法,确保实验室不会被炸掉…:断句有问题。

5、Contracts Before Internals
5、首先约定,然后再完成内部实现

庄表伟:5、首先约定,然后再完成内部实现

余晟:5、约定优先,然后完成内部实现

Be aggressive about documenting contracts (APIs and protocols) and testing them. Use CI testing on all public contracts. Code coverage is irrelevant. Code documentation is irrelevant. All that matters is what contracts the code implements, and how well it does that.
要积极地记录约定(API与协议)并加以测试。要使用持续集成工具测试所有的公开约定。代码覆盖率是无关紧要的,代码文档也是无关紧要的。真正重要的是代码实现了哪些约定,以及它们是如何实现的。

庄表伟:要积极的记录约定(API与协议)并测试它们。使用CI工具测试所有的公开约定。代码覆盖率是无关紧要的,代码文档是无关紧要的。一切的关键都在与约定的代码实现,以及他们是如何实现的。

刘天栋:…一切的关键都在于代码如何实现约定,以及他们是如何良好地实现的。

余晟:要积极地记录约定(API与协议)并加以测试。要使用持续集成工具测试所有的公开约定。代码覆盖率是无关紧要的,代码文档也是无关紧要的。真正重要的是代码实现了哪些约定,以及它们是如何实现的。

6、Promote From Within
6、从内部提拔

Promote contributors to maintainers, and maintainers to owners. Do this smoothly, easily, and without fear. Keep final authority to ban bad actors. Encourage people to start their own projects, especially to build on, or compete, with existing projects. Remove power from people who are not earning it on a daily basis.
将贡献者提拔为维护者,将维护者提拔为负责人。以流畅、轻松且无畏地方式来做。保留干掉‘害群之马’的最终权力。鼓励大家开始自己的项目,尤其是基于已有项目,或者与已有项目竞争的项目。每天持之以恒地检视并剥夺那些不再贡献者的权力。

庄表伟:将贡献者提拔为维护者,将维护者提拔为负责人。这样做起来,将会顺利、轻松并且免于恐惧。保留干掉‘老鼠屎’的最终权力。鼓励人们开始自己的项目,尤其是基于已有项目,或者与之竞争的项目。剥夺那些不再每日贡献者的权力。

刘天栋:…以流畅、轻松而无畏地方式来做。…每天持之以恒地检视并剥夺那些不再贡献者的权力。

余晟:维护者应当从贡献者中提拔出来,负责人应当从维护者中提拔出来。整个过程应当会平稳、轻松,而不应当有任何担忧。你需要保留干掉‘害群之马’的最终权威。还需要鼓励大家开始自己的项目,尤其是基于已有项目的项目,或者与已有项目竞争的项目。对于那些不能每日做出贡献的人,应当剥夺他们的权力。

7、Write Down the Rules
7、将规则写下来

余晟:7、明文记录规则

As you develop your rules, write them down so people can learn them. Actually, don’t even bother. Just use the C4.1 rules we already designed for ZeroMQ, and simplify them if you want to.
当你制定规则时,请将他们写下来,以便人们可以了解他们。事实上,你甚至都不需要亲自动手——如果你愿意,可以直接套用我们为ZeroMQ制定的规则C4.1,再按需简化。

庄表伟:当你制定规则时,将他们写下来,以便人们可以了解他们。这样一点都不麻烦。如果你愿意的话,可以直接使用我们为ZeroMQ制定的规则,再加以简化。

刘天栋:更简单的办法是,如果你愿意的话,可以直接使用我们为ZeroMQ制定的规则C4.1…

余晟:当你制定规则时,请将它们写下来,以便人们可以了解他们。事实上,你甚至都不需要亲自动手——如果你愿意,可以直接套用我们为ZeroMQ制定的规则C4.1,再按需简化。

8、Enforce the Rules Fairly
8、公平地执行规则

Use your power to enforce rules, not bully others into your “vision” of the project’s direction. Above all, obey the rules yourself. Nothing is worse than a clique of maintainers who act special while blocking patches because “they don’t like them.” OK, that’s exaggeration. Many things are much worse. Still, the clique thing will harm a project.
用你的权力去执行规则,但不要强迫别人认同你对于项目发展方向的“愿景”。最要紧的是,你自己必须遵守规则。最糟糕的事情莫过于维护者自己形成了小圈子,仅仅因为“不喜欢”就拒绝其他人的补丁。好吧,这样说有点夸张了。不过,很多情况其实更加糟糕。还是那句话,小圈子对项目是有害的。

庄表伟:用你的权力去执行规则,但不要强迫别人遵循你对于项目发展方向的“愿景”。首先,自己就要遵守规则。没有什么比一个维护者的小圈子,仅仅因为“他们不喜欢”就拒绝补丁,更加糟糕的事情了。好吧,这样有些夸张了。不过,有些事情会更糟糕。总之,小圈子会伤害一个项目。

余晟:用你的权力去执行规则,而不要强迫别人认同你对于项目发展方向的“愿景”。最要紧的是,你自己必须遵守规则。最糟糕的事情莫过于维护者自己形成了小圈子,仅仅因为“不喜欢”就拒绝其他人的补丁。好吧,这样说有点夸张了。不过,很多情况其实更加糟糕。还是那句话,小圈子对项目是有害的。

9、Aim For the Cloud
9、以“云”为目标

庄表伟:以云为目标

刘天栋:以集思广益为目标

Aim for a cloud of small, independent, self-organizing, competing projects. Be intolerant of large projects. By “large” I mean a project that has more than 2-3 core minds working on it. Don’t use fancy dependencies like submodules. Let people pick and choose the projects they want to put together. It’s economics 101.
以小型的、独立的、自组织的、竞争性的(一群可以自由协作的)项目为目标,(市场)不能容忍大项目。所谓“大”,我的意思是一个项目包含了2~3个核心想法。要拒绝子模组那样花哨的依赖关系。让大家去挑选,并将他们选择的项目放到一起(工作)。这是经济学的常识。

庄表伟:以小型的、独立的、自组织的、竞争性的(可以在云中部署的)项目为目标,(市场)不能容忍大项目。所谓“大”,我的意思是一个项目包含了2~3个核心想法。不要用那些花哨的类似于子模组那样的依赖。让人们去挑选,并将他们选择的项目放到一起(工作)。这是经济学的基本常识。

刘天栋:以一群小型的、独立的、自组织的、竞争性的项目为目标,不要容忍大项目。所谓“大”,我的意思是一个项目包含了2~3个核心大拿,让人们自己去挑选并揉和他们选择的项目。

余晟:开源项目应当以小型的、独立的、自组织的、竞争性的(可以在云中部署的)项目为目标。对于大项目,应当坚决避免姑息。所谓“大”,我的意思是包含了2~3个核心想法的项目。要拒绝子模块那样花哨的依赖关系。让大家去挑选,去把自己选择的项目放到一起。这是经济学的常识。

10、Be Happy and Pleasant
10、开心愉快最重要

Maybe you noticed that “be innovative” isn’t anywhere on my list. It’s probably point 11 or 12. Anyhow, cultivate a positive and pleasant mood in your community. There are no stupid questions. There are no stupid people. There are a few bad actors, who mostly stay away when the rules are clear. And everyone else is valuable and welcome like a guest who has traveled far to see us.
也许你注意到了,“创新”并不在我的建议列表中。它很可能排在第11或12点。总之,你需要在你的社区里培养一种积极的、愉快的氛围。愚蠢的问题,愚蠢的人都应当被踢出去。就算有“老鼠屎”,也会在清楚的规范下自动消失。剩下的人是则有价值的,我们欢迎有朋自远方来。

庄表伟:也许你注意到了,“创新”并不在我的建议列表中。他很可能在第11或12点。总之,在你的社区里培养一种积极的、愉快的氛围,没有愚蠢的问题,也没有愚蠢的人。就算有‘老鼠屎’,也会在违反规则时被清理掉。其余的人是有价值的,我们欢迎他们像游客一样,远远的看着我们。

刘天栋:就算有“老鼠屎”,也会在清楚的规范下自动消失…我们欢迎有朋自远方来。

余晟:也许你注意到了,“创新”并不在我的建议列表中。它很可能排在第11或12点。总之,你需要在你的社区里培养一种积极的、愉快的氛围。愚蠢的问题,愚蠢的人都应当被踢出去。就算有‘捣蛋鬼’,也会在因为违规被清理掉。剩下的人是则有价值的,应当像对待远到的客人那样欢迎他们。

ps.  第一次试着翻译,求各位朋友帮忙指正,多谢了!

pps. 在诸多朋友的帮助下,再修订了一遍,有了不少自己的思考,仅仅是反映在了译文之中,没有一一说明,见谅。

ppps. 徐定翔给了我一个非常好的建议:“我通常是译完隔天不看英文读一遍译文。把不符合中文表达习惯的部分润色一下。” 谢谢!

从28万个开源项目中,我们能够学到一些什么?

引子:开源项目那么多,哪些是值得我们学习的?

这里声明一下,仅仅是学习一下:他们是用哪些工具,来管理自己的项目的?

开源项目多如牛毛,值得分析的项目也很多很多。从哪里入手呢?幸运的是,在开源社区,有一个著名的网站,过去叫oloho,现在改名叫openhub。在他的网站首页,有这么四行字,以表明他们的数据库是多么的全面、丰富:

Indexing 669,008 open source projects
Connecting 3,742,793 open source contributors
Tracking 679,761 source control repositories
Counting 31,158,335,454 lines of code

这么说来,事情就变得比较“简单”了,我需要把openhub的数据,都抓回来。


数据的筛选过程

具体的数据抓取过程,简直不忍详述(我的内心,几乎是崩溃的)。总而言之,我只抓到了289,631个项目。openhub虽然号称自己索引了66万的开源项目,其实这仅仅是他的数据库里的最大ID号!当我顺着这个ID一个一个的去抓的时候,有很多ID,都已经被删除了。

在抓取到的项目数据中,有两个数值,特别值得参考:contributors(参与开发者的数量);users(该软件的用户数量)。相对而言,users的数据,可以认为是一个样本,即该开源项目的所有用户中,愿意并且知道该如何来openhub点击I use this的人。因此,即使是排名第一的Firefox,在openhub也只有13158个用户。考虑到Firefox的用户数,已经超过5亿(来源于维基百科英文版),因此,我们相信这个数据仅仅是一个4万分之一的采样结果。

随后,我观察了这28万多个项目的users数据与contributors数据,顿时惊讶的发现,绝大多数项目,都小的可怜,用户也少得可怜。

当我以“select count(*) from projects where contributors>30”查询时,只搜到了  1662个项目...
当我以“select count(*) from projects where users>30”查询时,只搜到了1260个项目...
当我合并以上两个条件查询时,只搜到了335个项目。
再从这335个项目中,排除掉最近一年已经不再有活动的项目,于是只剩下了331个了。

三个感想

  1. 成功的开源项目,真是凤毛麟角
  2. 绝大多数开源项目都是少数人开发的小项目
  3. 这331个项目,也许可以作为我们的重要参考

第一个问题:他们用什么配置库?

这是331个项目,使用配置库的情况(有些项目,同时使用多种配置库),有两个现象值得注意:

  1. 接近92%的项目,已经在使用git——git的统治地位,已经无可动摇
  2. 只有53%的项目,在使用Github——那些用git却不用Github的项目,是什么原因?

通过数据来分析:是否使用Github与项目创建时间的关系

通过这个图,可以看出两个现象:

  1. 越是新创建的开源项目,hosting在Github上比例越高
  2. 越是新创建的开源项目,事实上成功的也越多(当然,2010年以后的数量锐减,我们怀疑是好酒也要陈酿的原因)

通过数据来分析:是否使用Github与项目代码规模的关系

由于不同的开源项目,代码行数差异巨大,因此我们只能以log(col)对数结果,来做区间划分。可以看到一个非常明显的趋势,当然代码行数超过10万行以后,代码部署在Github上的项目,就开始明显下降,直到为0。

总结:是否使用Github,越是新的项目越愿意用;越是大的项目越没法用。


第二个问题:他们用什么来管理issue?

排名前五的工具中,Github:91个项目;Bugzilla:81个项目;JIRA:43个项目;Trac:20个项目;另外还有9个项目,完全是在maillist里“管理”issue的。

一共有39种不同的工具,另外还有6个项目,我们无法了解他究竟是用什么来管理的。

简单的来看:

  1. Github已经占据统治地位
  2. Github的占有率仅仅27%。
  3. Bugzilla也算老而弥坚
  4. 有很多项目,在选择自己的工具

通过数据来分析:使用的issue tracking工具与项目创建时间的关系

1990年之前创建的项目,其中有一个已经开始使用Github了。但是,这仅仅算是个案。更加明显的趋势是:越是新的项目,越是倾向于采用Github管理自己的issue。

相对而言,其他各种Issue Tracking工具的比例,都在下降。

通过数据来分析:使用的issue tracking工具与项目规模的关系

随着用户数量的增加,我们猜想:issue的数量与复杂度,也会逐渐增加。可以看到这样的趋势:Github的使用率,也在不断下降。

总结:是否使用Github来管理项目的issue,越是新的项目越愿意用;越是大的项目越没法用。


尚未完成的分析:

  • 开源项目使用的CI工具的情况
  • 开源项目使用的Code Review工具的情况
  • 开源项目使用的文档类工具的情况
  • ……

主要还是工作量太大了。。。对这个分析有兴趣的同学,可以与我联系,咱们可以一块来干。

Free Software vs. Open Source

首先推荐一部电视剧

很早以前看过一部港剧《龙兄鼠弟》,是万梓良、郑则仕和张卫健演的。其中万梓良饰演的雷文凤,在最后写了一本书,叫做《黑白灰》。大意是:这个世界,虽然存在黑白两色,绝大多数人,却都是灰色的。而他,却一定要坚持做一个纯白色的人。甚至在他看来,灰色的人,较之黑色的人,更加罪恶。

最近刚刚读完了另外一本书《若为自由故》,则是一本Richard Stallman的传记。在这本书里,红帽公司总裁罗伯特·杨(Robert Young)总结理查德看似矛盾的政治行为时,说道:“我崇拜也尊敬理查德和他所做的一切。我对他唯一的批评就是,有些时候,他对待朋友甚至比对待敌人还要无情。”

在我看来,也许发起开源运动的那群人,大多数自认为是RMS的朋友,而对于RMS而言,他们只是一群放弃了原则而站在灰色地带的人罢了。

说实话,在自由软件与开源之间,我究竟应该持何种立场?这是一个,我一直以来,都不愿意深想的问题,实在是太难了。只是这回读了一遍RMS亲笔签名的个人传记,又了解到了很多当事人的实际言论,总觉得应该督促自己,思考出一个结论出来。

两者的分歧,首先是哲学上的:理想主义 vs. 实用主义

在RMS看来,自由是天赋人权,可以说:因为自由本身值得追求,而RMS恰好又是个软件天才,所以他才会致力于自由软件。

而在开源运动看来:吸引更多的人参与自由软件的开发,然后实实在在的拿出优秀的开源软件来,才是真正有价值的事情。

自由软件的目的,是更多的自由,而开源软件的目的,是更好的软件

GPL是一种神奇的创造

如果RMS只是一位致力于追求软件自由的斗士,也许不会有任何人理睬他。但是他写出了Emacs、GCC这样的神级软件。以至于由此建立起了几乎无人能及的社区影响力。

因为他写的软件实在太牛,所以无论他以什么样的License来发表自己的软件,都会引发全社区的关注。

然后,GPL这种诡异的授权模式,才会有人愿意遵循。甚至,应用作为自己的开源License。

或者换句话说:RMS挂了Emacs的羊头,卖了GPL的狗肉。但是,Emacs这个羊头实在太好,买了GPL这种狗肉的人,居然也就认可了。

《大教堂与集市》对于RMS是一个重大打击

因为《大教堂与集市》一书,对于Linux成功之道的总结与宣传,使得Linus被人们提升到了世界上最知名黑客的行列。

说到底,在黑客这个圈子里,大家还是更注重实力,而非理念。当有人以完全不同的方式,创造出完全不逊于Emacs、GCC这样的开源软件时,RMS/自由软件/大教堂所代表的「道路」,就不再是唯一的选择了。

尤其是当Linus站在了开源的大旗下,更多的公司则出现在了Linux的周围。集市的胜利,不仅仅是开源相对于闭源的胜利,也是Linus相对于RMS的胜利。

在之后的世界里,虽然开源的代码越来越多,但是自由却越来越少被人提及了。

不完美的系统会激怒黑客

公正——该如何做是好》一书中,有一个经典的伦理学命题:假设铁轨上有一辆失控的火车,在岔路的一边是一个人,而另一边则是五个人。你是一个扳道工,你会选择让火车开向一个人,还是五个人?

我曾经问过我儿子这个问题,他的回答非常有趣:「如果是五个大人,与一个大人」,那就撞一个大人。「如果是五个大人,与一个小孩」,那就撞五个大人。「如果是五个男人,与一个女人」,那就撞五个男人。「如果是五个男人,与一个胖女人」,那就撞那个胖女人。。。

这其实反应了一个事实:想要通过权衡利弊,来做出最有利的选择,可能会是非常没有原则的事情。即使是一个成年人,也未必能做得有多好。

对于一个像RMS这样的黑客来说:他们会被这种问题所激怒,进而会拒绝回答问题,并想尽一切办法,要hack掉这个该死的列车与轨道系统。

在本书的第十二章《开往黑客地狱的短暂旅途》,就讲了一个令RMS暴怒的故事,在书中,作者写到:「“不完美的系统会激怒黑客。”史蒂芬·李维说过 这样的话,这是我决定与斯托曼同坐一辆车前应该听取的另一个忠告,“这是黑客们通常不喜欢开车的原因之一:这是一个充满不确定性的程序,交通信号灯总是随 机的变化,还有横七竖八的单行道,导致交通经常堵塞。这实在是太不必要了,只要让黑客们重新安排一下信号灯,打开交通灯控制盒,重新设计整个系统。”」

是的,对于真正的黑客来说:适应这个不完美的世界——取舍、权衡、妥协,是别人的事情。而黑客,就一定想要改造它!

我的结论

RMS这样的人,就像是在遥远的天边,在夕阳即将落下之时,努力为我们撑起天际线上那最后一点光明的人。

我没有资格自称为黑客。哪怕是改变世界的念头,我也常常是一闪而过。但是,这并不妨碍我始终对RMS,报以最高的崇敬!

至于Open Source,那至少是个很不坏的东西吧!

如何评价一个新技术——以Docker为例

上次与霍炬聊天,霍炬提到他在跟陈皓抬杠,陈皓认为Docker与Java是一个级别的发明,第二年就吸引了所有热门公司的加入。而霍炬认为这太夸张了,毕竟就是个配置管理器嘛。

而我的评价,可能会比陈皓的更高,我认为Docker比Java的级别还要高。而且,这与有多少公司参与无关。甚至可以反过来说:因为Docker极为重要,才会有那么多的公司,在第一时间加入进来。

因此,我也答应霍炬,要写一篇文章,仔细的阐述一下自己的观点。

新技术的三大功效

新技术的三大功效

新技术的三大功效:

  • 提升效率:某种更快的算法

或者更快、或者更省,都是好技术。可以是一个算法,也可以是一种更方便快速开发的框架。可以是更高速的网络带宽,也可以是更省电的低功耗技术。

这些,当然都是极好的。但是,也都不过是某种层面的量变而已。除非提升的幅度,达到百倍、甚至千倍、万倍。

  • 增加选择:一种新的语言

有时候,我们会把这类行为称之为重新造轮子。然而,我们也可以认为,哪怕是做同一件事情,现在也多了一种新的选择。

当然,这并非其价值所在。更重要的益处在于:新的选择,意味着新的思路,新的模式,新的「解法」。

虽然,在做这件事情本身,也许并无太多帮助。但是,却可能启发新的创造。

  • 降低门槛:更加简单的工具

有一类技术,并非直接的贡献,而是间接的。原本在这个领域,非要苦学十年以上,才能出师。现在,21天,就能从入门到精通了。以前只有国际巨头才能开发的移动电话,现在一个英语教师,就敢开整了。

但是,降低门槛的技术,往往具有颠覆性的价值。一个行业,只有100人能参与,和有100万人能参与,将会带来绝对意义上的不同。很多时候,虽然降低门槛,并不能真正化解深层次的复杂性。但是,却会吸引更多的聪明人,来一起思考和解决问题。

繁荣之后,一切皆有可能。

如何给docker定位?

  • docker所封装的容器技术,带来了更高的效率
  • 以docker容器为代表的虚拟化模式,是一种新的选择,将为架构设计带来新的启发
  • docker-registry、dockerfile、docker-compose等相关技术,大大降低了参与到这一容器化浪潮的门槛

综上所述:我认为docker是一种极具潜力的新技术。正因为其潜力巨大,才吸引了众多巨头、众多企业、众多散户以及众多一线研发者的共同热捧。

题外话

事实上,我上面画的那个模型,是自己生造的。甚至可以算是为Docker度身定制的。在以上三个要素之外,还有其他一些评价新技术的标准。

从量变到质变

这是我上面刻意模糊的部分。一个技术,能够快2倍、20倍、还是20万倍。将会得到完全不同的评价。

飞行速度是否能超过7.9公里/秒,是完全不同的两重境界。

创造一个新行业,甚至更多行业

在电视机出现之前,不会有电视演员,不会有现场直播,不会有主持人,不会有…沙发土豆。

能够令整个世界因此而不同的新技术。岂是小小的docker可比?

危害性

似乎,IT行业最牛的技术,也不太会有啥危害性。前一阵热炒的人工智能,也不过是某种夸张100倍之后的危言耸听而已。

毕竟,一种新技术,都无法威胁世界和平,能有多了不起?比起物理学家、化学家,咱们这些搞IT的人,简直弱爆了。

三代开源社区的协作模式

一、研发工具与研发模式

据说,人之区别于禽兽,最大的特征在于利用,甚至发明工具。在没有任何其他工具时,我们只能借助于自己的肢体,一旦有了工具之后,我们的能力将会大大的增加。

但是,从另一个角度来看,工具也同时在限制我们的能力,甚至限制了我们的行为模式与思维模式。有一句俗话说得好:「手里拿着锤子,看见什么都像钉子。」

而在研发工具的领域,我们观察到另外一些有趣的现象:因为软件研发工具的开发者,同时也是工具的使用者。因此,他们不仅仅会受制于工具,也往往会由 此被激发,开发出对自己而言更加趁手的工具。开发者与使用者身份合二为一的现象,使得研发工具的发展,简直可以用「日新月异」、「层出不穷」甚至「争奇斗 艳」来形容。

随着软件复杂性的不断增加,以及软件开发的参与者不断增多,团队协作的辅助软件,也开始不断增加,随后我们发现:工具不仅仅限制了个人的行为模式,更进一步限制了团队的协作模式。

软件研发企业的管理者,往往会有某种错觉,他们会认为:管理就是定下制度、流程与规范,然后「下面的人」就会照此执行。因为有人「听话」,有人「不听话」,所以才需要奖励与惩罚的制度,来帮助管理者推行他的「规则」。所以,他们一般都很喜欢看《执行力》这样的书。

在开源社区,事情变得有些不一样。虽说开源社区也有「领导者」,甚至往往会有「精神领袖」,但他们并没有暴力手段,也没有经济手段,甚至行政手段。因此,要协调一帮自由散漫的黑客,共同开发高质量的开源软件,必须有更加高明的手段。

由于一切都是Open的,所以:不仅代码人人可见,开源社区的协作模式,也暴露在众目睽睽之下。从某种意义上来说:这促进了开源社区的协作工具的开发、进而使得开源的研发协作模式,以远远超过企业内部的演化速度飞速演化。

二、第一代开源协作模式

第一代开源协作模式,在早期几乎没有符合自身特殊需要的工具,有什么用什么,因此最为常用的email,被发展为Maillist,成为整个开发团 队的协作核心工具,大多数操作系统内置的diff/patch工具,使得代码的交流以email patch为主。这些老牌的开源项目,从使用RCS、CVS,到了后来也开始逐步引入svn/git,bugzilla这样的工具,但是围绕 mailing list开展协作的特征,则持久不变。

作为协作核心的Maillist

一个开源社区,往往就是一个邮件列表,随着软件的日益复杂,社区的不断扩大,邮件列表也会不断分化,通常会划分为:核心组、开发组、用户组。开发组与用户组的邮件列表,随着软件的架构分化为多个模块,还会进一步分解。

在邮件列表里,所有的用户都是平等的,在无法用工具保障流程的情况下,社区逐渐发展出了一套严格的邮件礼仪和格式规范。不规范的邮件,不会被理睬;不礼貌的家伙,甚至会被赶走。

邮件越来越多,即使分成多个邮件列表,依然太多。Archive这样的邮件归档、查阅的工具,就必须得有了。一封邮件,大家都来回复,严格re:的标题,组成了一个可供追溯的线索。

在邮件列表里,通常出现个人的名称,加上Reported-By、Tested-By、Acked-By的标记,即是一种代表个人名义的认可,也是流程规范的一部分,更是计算各人贡献的依据。

Bugzilla应运而生

在邮件中,有一类话题是最活跃的,那就是bug。但是,通过翻找邮件查阅bug的最新的解决状况,是非常困难的。一个bug,从提出,到最终解决, 并被确认在哪一个版本中发布fix,是一种稳定的状态转化模式。一个专有的处理工具,势必应运而生。Bugzilla、trac等一批工具,就由此被创造 出来了。

代码提交流程的规范化

开源社区,表面上非常的崇尚民主自由,但实际上却盛行精英主义、甚至是个人独裁的。我们往往会给某个开源项目的创始人,冠以「仁慈的独裁者」的头衔。虽然,是否仁慈,大家不得而知,但独裁确实是显然的了。

最大的独裁,是代码的管理权。因为作为创始人与核心开发者,他们往往以一己之力,贡献了绝大多数的代码,确定了项目最初的架构与发展方向。他们不会容忍任何人随意地向代码库提交代码。

在邮件列表中,一个新来的家伙,从没人认识,到能够独立的向代码库提交代码,非得经历艰辛的历程不可。这样的历程,简单的说,就是一次一次的 Code Review。被审核通过、合入代码库的patch越多,一个人对于社区的贡献就越大,可信度也越高,身份地位也逐步提高,然后,他也就可以去 Review其他人的代码了。

总结:在简陋的工具条件下,发展出高效、严格的社区协作模式

三、第二代开源协作模式

第二代开源协作模式,有两大特征:Web化、集成化。随着Web技术的不断成熟,开源社区也开始创造一个又一个的Web开源项目,其中Web化的项 目管理工具,如雨后春笋般冒了出来。在wikipedia上,issue-tracking systems列出了55个,project management software列出了152个,其中开源的也有30+,open-source software hosting列出了22个,堪称蔚为壮观。

这类平台又可以分为两大类:基于开源的项目管理工具或issue tracking工具,自建平台,以JIRA、DotProject、Redmine为代表;基于免费开源托管平台,以SourceForge、Google、LaunchPad为代表;

第二代的开源项目管理工具,可以说,主要是在向企业内的开发管理学习。文档、流程、角色、权限、统计报表等等功能,都开始出现了。有些开源项目,也在用这些东西。

以SourceForge与Google Code为代表的开源托管平台免除了开源项目搭建自己的官方网站,管理工具,代码仓库之类的繁琐事务,大大促进了开源项目的发展。不过,由于平台的功能总是受限的,因此自建门户,自组工具的开源项目依然层出不穷。

issue & milestone

在第二代开源协作模式日渐成熟的过程中,另一股潮流也正方兴未艾:「敏捷软件开发」。其中,最为深入人心的概念之一,就是每个迭代,完成一批User Story

在开源社区,这个概念被进一步演绎:无论是bug和feature,都被统称为issue。这些issue,被分到不同的milestone(版本),即使最后有可能延期,milestone也会定义一个预期完成时间。

这是好事?还是坏事?其实很难评价,因为从开源的原始教义而言:所有的贡献,都是自愿、随机、不可预期的。为自然生长的软件,规定里程碑,本来就显 得荒谬。但是,从另一方面而言,我们可以引用另一个中国人过马路的例子:「不管红绿灯,凑够一堆人就过马路」,开源软件,往往也是「不管里程碑,稳定一堆 特性和bugfix,就发布一个版本」。

如果在开源软件很少,更别提形成开源生态圈的情况下,这种随意的做法还是可行的。但是在大量软件,相互依赖的情况下,一个开源项目要赢得其他协作项目的信赖与协作,必须给出稳定的规划,以便相互配合。

这种规范,也是被逼出来的。

服务平台化

虽然黑客们喜欢写程序,但是要写的程序实在太多了,能够不重复造轮子,有现成的好工具可以直接拿来用,也是件好事。如果可以打开一个网站,注册一个用户,创建一个新的项目,剩下的事情自有平台帮忙打理,那么大家都可以愉快、专心的写自己的代码了。

平台在逐步进化,因而能够帮助开源项目,打理越来越多的事务。通常主流的开源项目托管平台,都能够完成:

  • 在线代码浏览,并能够支持不同的配置库
  • 需求管理、Bug管理,通常合并为Issue tracking
  • 版本与里程碑管理
  • 文档编写与管理,以Wiki的形式为主

更进一步的,还有能够完成:简单的自定义工作流、文件夹与静态资源管理、输出各种统计报表、甚至提供论坛、搜索、邮件列表以及各种排行榜等等。

在此之前,一个开源项目,是一个社区。到了大平台的时代,整个平台,构成了一个更大的社区。

总结:以Web形式提供的集成化开源项目托管平台,标志着开源项目的协作模式,进入成熟期

四、第三代开源协作模式

到了MySpace、Facebook与Twitter这样的SNS网站的兴起,开源项目的协作模式,受到SNS的启发,也随之进入了第三代,以 Social Coding为核心的开发协作模式,这样的模式在以Github为代表的网站上,体现的最为充分,众多的模仿者也层出不穷。过去的开源项目与托管平台,都 是以项目为中心来打造,而Github则是围绕着参与开源的人来打造。首先满足的不是项目的需求,而是个人的需求,由于对人的黏性大大增加,也使得 Github成为近年来最具吸引力的开发社区。

围绕着Github,一大批周边扩展服务被建立起来,构成了一个更加有活力的生态圈。而程序员们,不仅在Github上参与开源项目,更在Github上结交朋友,分享经验,增进能力。甚至这样的协作模式,还拓展到了编程领域之外,成为开放式协作的流行模式。

激励机制

第三代开源协作模式,以Github为代表,以Social Coding为精髓,这一代模式想要解决的问题,是激励机制的问题。

第一代开源协作,虽然创造了一批大大有名的项目,但事实上却是一个非常小圈子的事业。即使是最为成功的Linux内核开发,也不过1000~2000人。一旦人多事杂,就会出现管理混乱的现象。

第二代开源协作,虽然借鉴了很多企业界的规范管理经验,但是在事实上,却是不适应开源软件的风格的,举一个例子:在Redmine中存在的角色、权限、工作流之类的东西,实际开源项目使用的,却非常少。

第三代开源协作,借鉴了社交网络中的各种数值化模型,关注者数量,Star数量,Fork数量,Issue数量,Pull Request数量,都在显要位置标示出来,对于开发者形成正向激励,还有很多的统计图表,形象的展示了项目的活跃程度。

开源社区,原本就有非常深厚的,统计补丁数计算贡献度的传统,这一点在Github被发扬光大,可以说是优秀的继承与创新。

基于fork/pull request的协作机制

在github,一键就能够fork自己的分支,然后可以跟原有的分支毫无关联,也可以非常方便的提交pull request,这就带来了更加频繁的分裂,使得分裂常态化了。

原来的开源社区,开发者修改了代码,希望能够贡献给社区,需要穿越种种障碍,如果社区不接受,最后开发者只能逼不得已,自己开一个新的分支,变成一个新的项目。

在分裂是异常的状态下,分裂是罪恶的,是不应该的,是会带来阵痛的。当分裂变得常态化,pull request也变得常态化,分分合合,以每天N次的速度发生,恰恰因为如此,他不再是一种罪恶,而是一种健康的、向上的、以更快速度进步的模式。大家不 再是在一个版本下,各自贡献,而是在各自的版本下,独立发展,想分就分,想合就合。

Pull request,从一个代码合并的方式,变成了开发者之间主要的交流方式,他们发现,最好的交流,正是通过源代码来交流,一切的讲道理,都不如用源代码来讲道理。这恰恰是程序员们最习惯,也最喜欢的一种交流方式。

围绕Github出现的扩展服务

较之上一代的平台,Github提供了优秀的开放扩展机制:OAuth、API、SDK、WebHooks、ServiceHooks等等,使得围绕Github,扩展各种满足项目特定需要的服务,变得非常容易。

这就是从上一代平台的开源大社区,进化为「围绕Github的开源生态圈」。

到目前为止,Github一共支持超过170个不同的扩展服务,其中较为热门的服务有:

  • 与其他项目管理工具集成(Bugzilla,Asana, Basecamp,Redmine,JIRA,ZohoProject)
  • 与持续集成服务集成(Travis,Bamboo,CircleCI)
  • 与消息通知服务集成(Amazon SNS,Email,IRC,Jabber)
  • 与DevOps服务集成(AWS OpsWorks, DeployHQ)

Github 开放平台与API,基于Github OAuth API,其他网站可以支持开发者用自己Github账号登录,并使用一些有趣的服务。

  • Cloud IDE,用Github账号登录,直接在浏览器里打开一个IDE,编辑自己在Github上的开源代码
  • Resume Service,根据开发者在Github上的各种社交行为与开源项目贡献度,自动生成格式化的简历

这些扩展服务,极大的丰富了开源生态圈的内涵。

总结:社区天生就应该是社交化的,Social Coding与开源社区,简直就是天作之和。

五、开源协作模式的新探索

Git:作为标配

目前看来,git作为分布式配置库的王者地位,已经不可动摇了。能够初步总结的原因,至少有三个:

  • git与github互相促进,作为全球最大也最流行的开源社区,他的标配是git。这也导致越来越多的开源项目,选择git作为标配
  • 众人拾材火焰高,越是参与开发的人不断涌入,越是帮助git发展得更快。这是一个赢家通吃的世界
  • 开源生态圈的出现,使得围绕git、github发展出一大批相关的开源项目、开源工具以及次级社区。这一现象,在docker横空出世之后,再一次得到展现。

Code Review:必不可少

开源社区,一直有非常悠久的CodeReview的历史,哪怕在最早的mail & patch的时代,Review也是开源协作的头等大事。仅仅梳理Review的历程,也可以看到其中工具与流程的发展。

最初是邮件review,然后是在集成平台上内置review功能,或者提供更强大的review插件。到github创新的提出pull request,则是一种更加方便有效的review模式。

与此同时,独立于集成平台的专门的code review工具,也开始发展起来:Review Board、Google Gerrit、Facebook Phabricator是其中重要的几个代表。

Workflow:百花齐放

在git逐步流行之后,大家发现基于git可以选择的「玩法」实在是太多了。从最初写下一行代码,到最终出现在项目发布的版本之中,期间可以有无数的「路径」。

在git-scm.com官方教程《ProGit》里,提及了三种:集中式工作流、集成管理员工作流以及司令官与副官工作流。

在蒋鑫的《Git权威指南》里,又提及基于TopGit、基于submodule、基于subtree、基于repo、基于gerrit、以及git与svn配合使用的不同工作模型。

再后来:GitFlow、Github的Pull Request、以及基于Github的Github Flow等等工作模式,堪称百花齐放。

为什么会出来这么多workflow?因为团队与项目的差别,实在太大了。现在到我们简直无法想象:那些在各种情况下都坚持使用SVN都开发者,是怎么熬过来的?

当然,从另一方面来说:选择太多,也会带来另一种烦恼…

CI、CD、DevOps

从Everything as Code到Everything Automation,是另一个越来越明显的趋势。前两天,我从机场出来,正好看到两个并列的广告牌,一个广告的大意是:「UPS助您打通全球供应链」、 另一个则是「中国银行助您打通全球供应链」。这真的很有意思,看来在各行各业,大家都开始在关注整个生命周期的各个环节之间的打通。

只是,在软件领域,我们会感觉到这是一种回归。毕竟,最初的软件开发,都是很简单的。在一台计算机上,自己写程序,自己编译,自己调试、运行,最后发布。既不用依赖他人,更不用等待什么流程。

随着项目越来越复杂,参与的人越来越多,我们的软件,不能仅仅运行在自己的机器上,或者需要部署到服务器上,或者需要发布到某种平台上。在协作者众多的情况下,如何分工合作?
在开发者水平参差不齐的情况下,如何保证质量?在分工、协作、流程与质量保证的要求之下,如何提高效率?

这些都是DevOps致力于解决的问题,也是DevOps不断得以发展的原动力。

总结:开源社区,始终在进步,Github代表的也只是「一代」而已,新的一代协作模式,还会被创造出来的。

六、暗线:工具、习俗背后的逻辑

过去是如何?未来又会怎样?想要回答这类问题,其实需要更加深入的思考:「开源社区的协作模式,为何会变?变化背后的逻辑是什么?」

开源社区研发工具的两大目标:降低门槛,提高效率

开源社区,与普通的软件开发最大的不同,就是参与者多多益善。在《大教堂与集市》中,Eric Steven Raymond总结到:「如果开发者协调者有至少一个像Internet这样好的沟通媒介,并且知道如何不靠强制来领导,那么多人合作必然强于单兵作 战」,这简直就是绝妙的预言。虽然当年的ESR也许并未预测到,基于Internet会出现那么多辅助开源的相关工具(他们当时还只有邮件列表)。

所以,开源社区一直在致力于两个看上去相反的目标:「吸引尽可能多的人,以尽可能简单、便捷的方式,参与到开源中来」、「在人多得超乎想象的情况下,依然能够保持,甚至不断提高效率」。

如何计算参与者的贡献?

开源社区,不会给参与者发工资,因此激励是一个大问题。公平、公开、公正大计算所有参与者的贡献,以所有人都能够接受都形式,计算并公布各种排行 榜,可以说是开源社区特有都「刚性需求」,因此SNS与开源社区的结合,成为必然。以后,面向开源协作的大数据分析,也一定会出现。

如何激励、吸引、回报参与者?

计算参与者的贡献,仅仅是公平激励的基础。让激励变得有趣,变得有价值,变得有意义,则是吸引与回报参与者的不二法门。因此:游戏化的思路,会被越来越多的引入到开源社区中来。

如何保障项目质量?

开源项目保障项目质量都最大利器,是引入数量众多都热心测试者。但是,仅仅有人愿意测试,主动、积极都帮助测试,已经越来越不够了。随着项目越来越复杂,开源项目必须逐步走出仅仅依赖肉眼、依赖人多+运气的质量保障模式。

自动化测试、以及更加规范的Review流程,则是必然出现,而且将越来越重要的环节之一。

如何协调一致的工作?

自由与规范,计划与变化,兴趣与责任。经常会在社区里,成为争论的热点话题。虽然在《大教堂与集市》中,ESR极力鼓吹「礼物文化远远胜过交换经济」,但是:「在一个庞大的社区,各种各样的事务都需要有人去完成,而且还不能漫无章法。」

因此:「某种调节手段、协调者与协调机制、甚至是看不见的手」之类的东西,会慢慢的回到社区

如何在社区里平等、高效的协商?

目前来说,依然只能是线上讨论+线下开会。虽然,很多开源社区,开始学习《罗伯特议事规则》这样的开会圣经。但是,开会依然是最令程序员感到苦恼的事情。在这方面,将来会不会出现更好的辅助工具,这方面很值得期待。

结束语

唯有变化,是不变的。开源协作模式,同样如此。惟愿我们,能够成为推起其前进的力量之一。

[知乎]知乎诱发你做了什么此前没想过的事情?

因为回答了一个问题,进而开始写一本“书”。

zhihu.com/question/1963

在这个问题“如何更有效地学习开源项目的代码?”中,我获得了不少的赞同和感谢。于是,我决定将这个回答,扩充为一个长达10多章的一本小书。目前的进度是50%左右。很难,但是我会坚持下去。

teamhost.org/projects/l

另外,经朋友的介绍,我将这个文档转成了一个PPT,并且开始在各个高校里做巡回的演讲,目前去了上海大学和上海交大,下一站,会去华东师范大学。希望能够将这个项目,推广到更多的高校。

[知乎]关于开发和编程工具,有哪些经验可以分享给初学者?

  • 过尤不及:所有的工具,都是为了提高我们的开发效率而存在的,但是,如果为了那些工具,投入了太多的精力,则可能舍本逐末,忘记了自己的根本目标。也许有人会说,磨刀不误砍材功,但是,千万不要只顾磨刀,忘记砍材啊。
  • 对 于初学者而言,GUI是更加自然的方式。虽然,计算机的发展过程,是先有命令行,后有图形界面。但是,键盘、鼠标的综合运用,会更加容易被人掌握。当然, 随着熟练程度的增加,纯用键盘操作,加上花样繁多的快捷键,会大大的提高操作的效率。再进一步,有一些优秀的GUI工具,极其丰富的支持各种快捷方式,同 时又兼顾图形界面的美观与方便,是最值得推荐的。但是,还是回到那句话:过尤不及。
  • 好的教程,会帮助我们的熟悉开发工具,我一直认为TextMate的迅速普及,是由于RailsCast的功劳。因此,花时间找一些靠谱的教程,尤其是视频教程,会很有效。
  • 开发人员,往往会有两个误区,或者频繁的挑选、比较多种开发工具,或者长时间埋头于自己最常用的那个工具,对于外面世界的发展毫无兴趣。我的个人建议是,定期抬起头来,看看新工具的进展与介绍。1~2年为一个周期就好,不用太频繁。
  • 知其然,更要知其所以然。千万不要变成被工具惯坏了的程序员。

[知乎]老是听说hard coded但是一直没弄明白,能给解释下么?

var a=1;
var b=2;
console.log(a+b);

当然,这样你就能够得到一个输出:3

console.log(1+2);

这样,其实也能得到一个输出:3

这两段代码,其实都能够得到同样的输出结果,为什么要多两个代码,定义两个变量呢?

第一个原因:如果你打算计算3+4,前一种代码,你可以仅仅修改变量的定义;第二种代码,就要修改console.log里的数字。

再者,如果我们想做一个加法的函数,就必须要用到变量:

function add(a,b){
  console.log(a+b);
}
add(1,2);

这就显示出了第二个原因:有些功能,不用变量,根本无法实现。

如果我们想要连接数据库,通常会写:

var config = load_config();
var db = DB.connect(config);

这就显示出了第三个原因,各种配置类的数据,根本就不是代码,也不该写在代码里。

如果我们的程序,有很多的逻辑判断,可以写成这样:

const CONDITION1 = 1;
const CONDITION2 = 2;

if(input_data==CONDITION1){
  do_something1();
} else if(input_data==CONDITION2){
  do_something2();
} else {
  do_something3();
}

如果我们将各种条件的具体值都写在if判断之中,那就太死板了,阅读起来也会难以理解1,2,3分别代表什么含义。这就显示了第四个原因,在显著位置,集中解释(或展示)代码逻辑,而不是在代码中混乱的分布。

基本上,以上的几个原因,告诉我们,不应该写hard code。

[知乎]什么程序设计语言机制是处理异步 IO 最恰当的抽象?

我打算说一个非主流的答案。

大家都是程序员,我们经常会瞧不起那些不理解“程序是如何执行”的人,我们经常会说:“这个世界分为10种人,一种懂二进制,一种不懂”。

那么,在程序员内部,这种瞧不起同样存在:Lisp程序员瞧不起所有不懂函数式编程的程序员。C/C++程序员嘲笑所有忽略性能细节的程序员。

至于那些被嘲笑的程序员,他们的反击方式很类似:“你们那种编程范式,是反人类的。”言下之意就是:“我根本懒得学你们那些反人类的东西。”

但事实上呢?人类的思维模式,可塑性惊人,那些所谓的反人类的思维模式,照样有大把的程序员能够熟练掌握。

总结观点:所谓最恰当的抽象模型并不存在,只不过是个人最习惯的抽象模型而已。

[知乎]是什么在影响我们的开发效率?

影响开发效率的罪行,从大到小排序如下:

  1. 无效冗长的会议,却拖着研发去开
  2. 含混不清的需求,需要反复澄清,甚至往返修改
  3. 多个任务前后脚的砸在开发人员面前,各种紧急,让人疲于奔命
  4. 错误的架构设计,加大开发工作量,甚至不得不推翻重构
  5. 糟糕的Coding实现,被测试发现bug,然后反复debug
  6. 嘈杂的环境,反复打扰、打断开发人员
  7. 因为各种限制,没法上网查资料
  8. 糟糕的工具环境,搞死人的配置
  9. 猪队友