Merge pull request #6654 from yunfengHe/master

The One in Which I call out Hacker News校对完毕
This commit is contained in:
Xingyu.Wang 2017-12-15 21:14:22 +08:00 committed by GitHub
commit 3bc4a3152f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,99 +1,89 @@
我号召黑客新闻的理由之一
实现高速缓存会花费 30 个小时,你有额外的 30 个小时吗?
不,你没有。
我实际上并不知道它会花多少时间,可能它会花五分钟,你有五分钟吗?不,你还是没有。为什么?因为我在撒谎。它会消耗远超五分钟的时间,这是程序员永远的
乐观主义。
- Owen Astrachan 教授于 2004 年 2 月 23 日在 CPS 108 上的讲座
# [因为这个我要点名批评 Hacker News ][14]
指责开源软件的使用存在着高昂的代价已经不是一个新论点了,它之前就被提过,而且说的比我更有信服力,即使一些人已经在高度赞扬开源软件的运作。
这种事为什么会重复发生?
在周一的黑客新闻上,我愉悦地看着某些人一边说写 Stack Overflow 简单的简直搞笑,一边通过允许七月第四个周末之后的克隆来开始备份他们的提问。
其他的声明中也指出现存的克隆是一个好的出发点。
> “实现高速缓存会花费 30 个小时,你有额外的 30 个小时吗?
不,你没有。我实际上并不知道它会花多少时间,可能它会花五分钟,你有五分钟吗?不,你还是没有。为什么?因为我在撒谎。它会消耗远超五分钟的时间。这一切把问题简单化的假设都只不过是程序员单方面的乐观主义。”
>
> — 出自 [Owen Astrachan][1] 教授于 2004 年 2 月 23 日在 [CPS 108][2] 上的讲座
让我们假设,为了争辩,你觉得将自己的 Stack Overflow 通过 ASP.NET 和 MVC 克隆是正确的,然后被一块廉价的手表和一个小型俱乐部头领忽悠之后,
决定去手动拷贝你 Stack Overflow 的源代码,一页又一页,所以你可以逐字逐句地重新输入,我们同样会假定你像我一样打字,很酷的有 100 WPM
差不多每秒8个字符不和我一样的话你不会犯错。
[指责开源软件总是离奇难用已经不是一个新论点了][5]; 这样的论点之前就被很多比我更为雄辩的人提及过, 甚至是出自一些人非常推崇开源软件的人士口中。那么为什么我要在这里老调重弹呢?
Stack Overflow 的 *.cs、*.sql、*.css、*.js 和 *.aspx 文件大约 2.3 MB因此如果你想将这些源代码输进电脑里去的话即使你不犯错也需要大约 80 个小时
在周一的 Hacker News 期刊上,一段文章把我逗乐了。文章谈到,一些人认为 [编写代码实现和一个跟 StackOverflow 一样的系统可以简单到爆][6],并自信的 [声称他们可以在7月4号的周末就写出一版和 StackOverflow 原版一摸一样的程序][7],以此来证明这一切是多么容易。另一些人则插话说,[现有的][8][那些仿制产品][9] 就已经是一个很好的例证了。
除非......当然,你是不会那样做的:你打算从头开始实现 Stack Overflow 。所以即使我们假设,你花了十倍的时间去设计、输出,然后调试你自己的实现而不是去拷
贝已有的那份,那已经让你已经编译了好几个星期。我不知道你,但是我可以承认我写的新代码大大小于我复制的现有代码的十分之一。
秉承着自由讨论的精神,我们来假设一个场景。你在思考了一阵之后认为你可以用 ASP.NET MVC 来编写一套你自己的 StackOverflow 。我呢,在被一块儿摇晃着的怀表催眠之后,脑袋又挨了别人一顿棒槌,然后像个二哈一样一页一页的把 StackOverflow 的源码递给你,让你照原样重新拿键盘逐字逐句的在你的环境下把那些代码再敲一遍,做成你的 StackOverflow。假设你可以向我一样打字飞快一分钟能敲100个词 ([也就是大约每秒敲八个字母][10]),但是却可以牛叉到我无法企及的打字零错误率。从 StackOverflow 的大小共计2.3MB的源码来估计(包括.CS, .SQL, .CSS, .JS 和 .aspx文件就单单是照着源代码这么飞速敲一遍而且一气呵成中间一个字母都不错你也要差不多用掉至少 80 个小时的时间。
ok我听见你松了口气。所以不是全部。但是我可以做大部分
或者你打算从零开始编码实现你自己的 StackOverflow虽然我知道你肯定是不会那样做的。我们假设你从设计程序到敲代码再到最终完成调试只需要区区十倍于抄袭 StackOverflow 源代码的时间。即使在这样的假设条件下,你也要耗费几周的时间昼夜不停得狂写代码。不知道你是否愿意,但是至少我可以欣然承认,如果只给我照抄源 StackOverflow 代码用时的十倍时间来让我自己写 StackOverflow, 我可是打死也做不到
行,所以什么是大部分?这只是询问和回答问题,这个部分很简单。那么,除了你必须实现对问题和答案投票、赞同还是反对,而且提问者应该能够去接收每一个问题的
单一答案。你不能让人们赞同或者反对他们自己的回答。所以你需要去阻止。你需要去确保用户在一定的时间内不会赞同或反对其他用户太多次。以预防垃圾邮件,
你可能也需要去实现一个垃圾邮件过滤器,即使在一个基本的设计里,也要考虑到这一点。而且还需要去支持用户图标。并且你将不得不寻找一个自己真正信任的并且
与 markdown 接合很好的 HTML 库(当然,你确实希望重新使用那个令人敬畏的编辑器 Stack Overflow ),你还需要为所有控件购买,设计或查找小部件,此外
你至少需要一个基本的管理界面,以便用户可以调节,并且你需要实现可扩展的业务量,以便能稳定地给用户越来越多的功能去实现他们想做的。
_好的_我知道你在听到这些假设的时候已经开始觉得泄气了。*你在想,如果不是全部实现,而只是实现 StackOverflow **大部分** 的功能呢?这总归会容易很多了吧。*
如果你这样做了,你可以完成它。
好的,问题是什么是 "大部分" 功能?如果只去实现提问和回答问题的功能?这个部分应该很简单吧。其实不然,因为实现问和答的功能还要求你必须做出一个对问题和其答案的投票系统,来显示大家对某个答案是赞同还是反对。因为只有这样你才能保证提问者可以得到这个问题的唯一的可信答案。当然,你还不能让人们赞同或者反对他们自己给出的答案,所以你还要去实现这种禁止自投自票的机制。除此之外,你需要去确保用户在一定的时间内不能赞同或反对其他用户太多次,以此来防止有人用机器人程序作弊乱投票。你很可能还需要去实现一个垃圾评论过滤器,即使这个过滤器很基础很简陋,你也要考虑如何去设计它。而且你恐怕还需要去支持用户图标(头像)的功能。并且你将不得不寻找一个自己真正信任的并且
与 Markdown 接合很好的干净的 HTML 库(当然,假设你确实想要复用 StackOverflow 的 [那个超棒的编辑器][11] )。你还需要为所有控件购买或者设计一些小图标小部件,此外你至少需要实现一个基本的管理界面,以便那些喜欢捣鼓的用户可以调整和改动他们的个性化设置。并且你需要实现类似于 Karma 的声望累积系统,以便用户可以随着不断地使用来稳步提升他们的话语权和解锁更多的功能以及可操作性。
除了...除了全文检索外,特别是它在“寻找问题”功能中的表现,这是必不可少的。然后用户的基本信息,和回答的意见,然后有一个主要展示你的重要问题,
但是它会稳定的冒泡式下降。另外你需要去实现奖励,并支持每个用户的多个 OpenID 登录,然后为相关的事件发送邮件通知,并添加一个标签系统,
接着允许管理员通过一个不错的图形界面配置徽章。你需要去显示用户的 karma 历史,点赞和差评。整个事情的规模都非常好,因为它随时都可以被
slashdotted、reddited 或是 Stack Overflow 。
但是如果你实现了以上_所有_功能可以说你_就已经_把要做的都做完了。
在这之后!你就已经完成了!
除非...除非你还要做全文检索功能。尤其是在“边问边搜”(动态检索)的特性中,支持全文检索是必不可少的。此外,录入和显示用户的基本信息,实现对问题答案的评论功能,以及实现一个显示热点提问的页面,以及热点问题和帖子随着时间推移沉下去的这些功能,都将是不可或缺的。另外你肯定还需要去实现回答奖励系统,并支持每个用户用多个不同的 OpenID 账户去登录然后将这些相关的登陆事件通过邮件发送出去来通知用户并添加一个标签或徽章系统接着允许管理员通过一个不错的图形界面来配置这些标签和徽章Badge。你需要去显示用户的 Karma 历史,以及他们的历史点赞和差评。而且整个页面还需要很流畅的展开和拉伸,因为这个系统的页面随时都可能被 SlashdotReddit 或是 StackOverflow 这些动作影响到。
...在正确地实现升级、国际化、业绩上限和一个 css 设计之后,使你的站点看起来不像是一个屁股,上面的大部分 AJAX 版本和 G-d 知道什么会同样潜伏
在你所信任的界面下,但是当你开始做一个真正的克隆的时候,就会遇到它。
在这之后!你会以为你基本已经大功告成了!
告诉我:这些功能中哪个是你感觉可以削减而让它仍然是一个引人注目的产品,哪些是大部分网站之下的呢?哪个你可以剔除呢?
...为了产品的完整性在上面所述的工作都完成之后你又奋不顾身的去实现了升级功能界面语言的国际化Karma 值上限,以及让网站更专业的 CSS 设计AJAX还有那些看起来理所当然做起来却让人吐血的功能和特性。如果你不是真的动手来尝试做一个和 StackOverflow 一摸一样的系统,你肯定不会意识到在整个程序设计实施的过程中,你会踩到无数的鬼才会知道的大坑。
开发者因为开源软件的使用是一个可怕的痛苦这样一个相同的理由认为克隆一个像 Stack Overflow 的站点很简单。当你把一个开发者放在 Stack Overflow 前面,
他们并不真的看到 Stack Overflow他们实际上看的是这些:
那么请你告诉我:如果你要做一个让人满意的类似产品出来,上述的哪一个功能是你可以省略掉的呢?哪些是“大部分”网站都具备的功能,哪些又不是呢?
正因为这些很容易被忽视的问题,开发者才会以为做一个 StackOverflow 的仿制版产品会很简单。也同样是因为这些被忽视了的因素,开源软件才一直让人用起来很痛苦。很多软件开发人员在看到 StackOverflow 的时候,他们并不能察觉到 StackOverflow 产品的全貌。他们会简单的把 Stackoverflow 的实现抽象成下面一段逻辑和代码:
```
create table QUESTION (ID identity primary key,
TITLE varchar(255), --- 为什么我知道你认为是 255
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
USER integer references USER(ID));
TITLE varchar(255), --- 为什么我知道你认为是 255
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
USER integer references USER(ID));
create table RESPONSE (ID identity primary key,
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
QUESTION integer references QUESTION(ID))
BODY text,
UPVOTES integer not null default 0,
DOWNVOTES integer not null default 0,
QUESTION integer references QUESTION(ID))
```
如果你告诉一个开发者去复制 Stack Overflow ,进入他脑海中的就是上面的两个 SQL 表和足够的 HTML 文件来显示它们,而不用格式化,这在一个周末里是完全
可以实现的,聪明的人会意识到他们需要实现登陆、注销和评论,点赞需要绑定到用户。但是这在一个周末内仍然是完全可行的。这仅仅是在 SQL 后端里加上两张
左右的表,而 HTML 则用来展示内容,使用像 Django 这样的框架,你甚至可以免费获得基本的用户和评论。
如果你让这些开发者去实现 StackOverflow进入他脑海中的就是上面的两个 SQL 表和一个用以呈现表格数据的 HTML 文件。他们甚至会忽略数据的格式问题,进而单纯的以为他们可以在一个周末的时间里就把 StackOverflow 做出来。一些稍微老练的开发者可能会意识到他们还要去实现登陆和注销功能,评论功能,投票系统,但是仍然会自信的认为这不过也就是利用一个周末就能完成了;因为这些功能也不过意味着在后端多了几张 SQL 表和 HTML 文件。如果借助于 Django 之类的构架和工具,他们甚至可以直接拿来主义地不花一分钱就实现用户登陆和评论的功能。
但是那不是和 Stack Overflow 相关的,无论你对 Stack Overflow 的感受如何,大多数访问者似乎都认为用户体验从头到尾都很流畅,他们感觉他们和一个
好产品相互影响。即使我没有更好的了解,我也会猜测 Stack Overflow 在数据库模式方面取得了持续的成功-并且有机会去阅读 Stack Overflow 的源代码,
我知道它实际上有多么的小,这些是一个极大的 spit 和 Polish 的集合,成为了一个具有高可用性的主要网站,一个开发者,问一个东西被克隆有多难,
仅仅不认为和 Polish 相关,因为 Polish 是实现结果附带的。
但这种简单的实现却_远远不能_体现出 StackOverflow 的精髓。无论你对 StackOverflow 的感觉如何,大多数使用者似乎都同意 StackOverflow 的用户体验从头到尾都很流畅。使用 StackOverflow 的过程就是在跟一个精心打磨过的产品在愉快地交互。即使我没有深入了解过 StackOverflow ,我也能猜测出这个产品的成功和它数据库的 Schema 没有多大关系 - 实际上在有幸研读过 StackOverflow 的源码之后我得以印证了自己的想法StackOverflow 的成功确实和它的数据库设计关系甚小。真正让它成为一个极其易用的网站的原因是它背后_大量的_精雕细琢的设计和实施。多数的开发人员在谈及仿制和克隆一款产品的难度时真的_很少会去考虑到产品背后的打磨和雕琢工作_因为他们认为_这些打磨和雕琢都是偶然的甚至是无足轻重的。_
这就是为什么 Stack Overflow 的开放源代码克隆会失败,即使一些人在设法实现大部分 Stack Overflow 的“规范”,也会有一些关键区域会将他们绊倒,
举个例子,如果你把目标市场定在了终端用户上,你要么需要一个图形界面去配置规则,要么聪明的开发者会决定哪些徽章具有足够的通用性,去继续所有的
安装,实际情况是,开发者发牢骚和抱怨你不能实现一个真实的综合性的像 badges 的图形用户界面,然后 bikeshed 任何的建议,为因为标准的 badges
在范围内太远,他们会迅速避开选择其他方向,他们最后会带着相同的有 bug 追踪器的解决方案赶上,就像他们工作流程的概要使用一样:
开发者通过任意一种方式实现一个通用的机制,任何一个人完全都能轻松地使用 Python、PHP 或任意一门语言中的系统 API 来工作,能简单为他们自己增加
自定义设置PHP 和 Python 是学起来很简单的,并且比起曾经的图形界面更加的灵活,为什么还要操心其他事呢?
这就是为什么用开源工具去克隆和山寨 StackOverflow 其实是很容易失败的。即使这些开源开发者只是想去实现 StackOverflow 的主要的“规范和标准特性”,而非全面的高级特性,他们也会在实现的过程中遭遇种种关键和核心的问题,让他们阴沟翻船,半途而废。拿 Badge (徽章功能)来说,如果你要针对普通终端用户来设计 Badge , 则要么需要实现一个用户可用来个性化设置 bagdge 的 GUI要么则取巧的设计出一个比较通用的 Badge 供所有的安装版本来使用。而开源设计的实际情况是,开发者会有很多的抱怨和牢骚,认为给 Badge 这种东西设计一个功能全面的 GUI 是根本不肯能的。而且他们会固执地把任何标准 badge 的提案踢回去,踢出第一宇宙速度,击穿地壳甩到地球的另一端。最终这些开发者还是会搞出一个类似于 Roundup 的 bug tracker 程序都在使用的流程和方案:即实现一个通用的机制, 提供以 Python 或 Php 为基础的一些系统API 以便那些可以自如使用 Python 或 Php 的人可以轻松的通过这些编程接口来定制化他们自己的 Badge。而且老实说PHP 和 Python 可是比任何可能的 GUI 接口都要好用和强大得多,为什么还要考虑 GUI 的方案呢?(出自开源开发者的想法)
同样的,节制和管理界面可以被削减。如果你是一个管理员,你可以进入 SQL 服务器,所以你可以做任何真正的管理-就像这样,管理员可以通过任何的 Django
管理和类似的系统给你提供支持,因为,毕竟只有少数用户是 modsmods 应该理解网站是怎么运作、停止的。当然,没有 Stack Overflow 的接口失败会被纠正
,即使 Stack Overflow 的愚蠢的要求,你必须知道如何去使用 openID (它是最糟糕的缺点)最后得到修复。我确信任何的开源的克隆都会狂热地跟随它-
即使 GNOME 和 KDE 多年来亦步亦趋地复制 windows ,而不是尝试去修复它自己最明显的缺陷。
同样的,开源开发者会认为那些系统设置和管理员界面也一样可以省略掉。在他们看来,假如你是一个管理员,有 SQL 服务器的权限,那么你就理所当然的具备那些系统管理员该有的知识和技能。那么你其实可以使用 Djang-admin 或者任何类似的工具来轻松的对 StackOverflow 做很多设置和改造工作。毕竟如果你是一个 mods 懂如何mod的人那么你肯定知道网站是怎么工作的懂得如何利用专业工具去设置和改造一个网站。对啊这不就得了 毋庸置疑,在开源开发者重做他们自己的 StackOverflow 的时候,他们也不会把任何 StackOverflow 在接口上面的失败设计纠正过来。即使是原版 StackOverflow 里面最愚蠢最失败的那个设计(即要求用户必须拥有一个 OpenID 并知道如何使用它)在某个将来最终被 StackOverflow 删除和修正掉了, 我相信正在复制 StackOverflow 模式的那些开源克隆产品也还是会不假思索的把这个 OpenID 的功能仿制出来。这就好比是 GNOME 和 KDE 多年以来一直在做的事情,他们并没有把精力放在如何在设计之初就避免 Windows 的那些显而易见的毛病和问题,相反的确是在亦步亦趋的重复着 Windows 的设计,想办法用开源的方式做出一个比拟 Windows 功能的系统。
开发者可能不会关心应用的这些部分,但是最终用户会,当他们尝试去决定使用哪个应用时会去考虑这些。就好像一家好的软件公司希望通过确保其产品在出货之前
是一流的来降低其支持成本一样,所以,同样的,懂行的消费者想在他们购买这些产品之前确保产品好用,以便他们不需要去寻求帮助,开源产品就失败在这种地方
,一般来说,专有解决方案会做得更好。
这不是说开源软件没有他们自己的立足之地,这个博客运行在 ApacheDjangoPostgreSQL 和 Linux 上。但是让我告诉你,配置这些堆栈不是为了让人心灰意懒
PostgreSQL 需要在老版本上移除设置。然后,在 Ubuntu 和 FreeBSD 最新的版本上仍然要求用户搭建第一个数据库集群MS SQL不需要这些东西Apache...
天啊甚至没有让我开始尝试去向一个初学者用户解释如何去得到虚拟机MovableType一对 Django 应用程序,而且所有的 WordPress 都可以在一个单一的安装下
顺利运行,像在地狱一样,只是试图解释 Apache 的分叉线程变换给技术上精明的非开发人员就是一个噩梦IIS 7 和操作系统的 Apache 服务器是非常闭源的,
图形界面管理程序配置这些这些相同的堆栈非常的简单Django 是一个伟大的产品,但是它只是基础架构而已,我认为开源软件做的很好,恰恰是因为推动开发者去
贡献的动机
开发者可能不会关心一个应用的上述设计细节,但是终端用户一定会。尤其是当他们在尝试去选择要使用哪个应用的时候,这些终端用户更会重视这些接口设计是否易用。就好像一家好的软件公司希望通过确保其产品在出货之前就有一流的质量,以降低售后维护支持的成本一样,懂行的消费者也会在他们购买这些产品之前就确保产品好用,以防在使用的时候不知所措,然后无奈的打电话给售后来解决问题。开源产品就失败在这里,而且相当之失败。一般来讲,付费软件则在这方面做得好很多。
下次你看见一个你喜欢的应用,认为所有面向用户的细节非常长和辛苦,就会去让它用起来更令人开心,在谴责你如何能普通的实现整个的可恶的事在一个周末,
十分之九之后,当你认为一个应用的实现简单地简直可笑,你就完全的错失了故事另一边的用户
这不是说开源软件没有自己的立足之地,这个博客就运行在 Apache[Django][12][PostgreSQL][13] 和 Linux 搭建的开源系统之上。但是让我来告诉你吧,配置这些堆栈可不是谁都可以做的。老版本的 PostgreSQL 需要手工配置 Vacuuming 来确保数据库的自动清理,而即使是最新版本的 ubuntu 和 FreeBSD 也仍然要求用户去手工配置他们的第一个数据库集群。
相比之下MS SQL (微软的 SQL) 则不需要你手工配置以上的任何一样东西。至于 Apache ... 我的天Apache 简直复杂到让我根本来不及去尝试给一个新用户讲解我们如何可以通过一个一次性的安装过程就能把虚拟机MovableType几个 Diango apps 和 WordPress 配置在一起并流畅地使用。单单是给那些技术背景还不错但并非软件开发者的用户解释清楚 Apache 的那些针对多进程和多线程的设置参数就已经够我喝一壶的了。相比之下,微软的 IIS 7 或者是使用了 OS X 服务器的那个几乎闭源的 GUI 管理器的 Apache 在配置的时候就要简单上不止一个数量级了。Django 确实是一个好的开源产品,但它也 _只是_ 一个基础构架,而并非是一个可以直接面向终端普通用户的商业产品。而开源真正的强项就 _恰恰在_ 这种基础构架的开发和创新上,这也正是驱使开发者为开源做贡献的最本真的动力。
所以我的结论是,如果下次你再看到一个你喜欢的应用程序,请好好细心地揣摩一下这款产品,揣摩一下所有的那些针对用户的体贴入微的设计细节。而不是武断的认为你可以轻轻松松的再一周之内就用开源工具做一个和这个应用一摸一样的产品出来。那些认为制作和实现一个应用程序如此简单的人,十之八九都是因为忽略了软件开发的最终产品是要交给用户去用的。
-------------------------------------------------------------------------------
via: https://bitquabit.com/post/one-which-i-call-out-hacker-news/
作者Benjamin Pollack 译者hopefully2333 校对校对者ID
作者:[Benjamin Pollack][a]
译者:[hopefully2333](https://github.com/hopefully2333)
校对:[yunfengHe](https://github.com/yunfengHe)
本文由 LCTT 原创编译Linux中国 荣誉推出
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://bitquabit.com/meta/about/
[1]:http://www.cs.duke.edu/~ola/
[2]:http://www.cs.duke.edu/courses/cps108/spring04/
[3]:https://bitquabit.com/categories/programming
[4]:https://bitquabit.com/categories/technology
[5]:http://blog.bitquabit.com/2009/06/30/one-which-i-say-open-source-software-sucks/
[6]:http://news.ycombinator.com/item?id=678501
[7]:http://news.ycombinator.com/item?id=678704
[8]:http://code.google.com/p/cnprog/
[9]:http://code.google.com/p/soclone/
[10]:http://en.wikipedia.org/wiki/Words_per_minute
[11]:http://github.com/derobins/wmd/tree/master
[12]:http://www.djangoproject.com/
[13]:http://www.postgresql.org/
[14]:https://bitquabit.com/post/one-which-i-call-out-hacker-news/