2007年03月19日

上一篇文章里,我们提到了重构是现代开发的一项利器,因为它同时满足现代开发的核心思想:正交性(做一件事情不会影响到另外一件)、小步快跑(人的大脑在处理多头绪的事情时效率不高,多头绪的事情要分解成大脑最擅长处理的单头绪)、实用优于优雅(不过多考虑将来的事情,用最简单明了的方法解决当前的工作)。

在我的实践中,小步快跑式的快速叠代开发,效果很是令人满意。在2006年11月至2007年1月间,项目已经内部发布了24次,一直稳定地在生长,直到年关前,我决定进行一次大的重构为止。

让我简单回忆一下,当时为什么决定打破常规,做一次大型的重构。

最开始,我只是想进行一些优化工作,一方面项目的代码有些乱了,另一方面系统有一些运行瓶颈。我想在过年前做一些完善,发布一个让我自己舒服的版本,好带着好心情过年。谁知随着重构的深入,我竟如陷落泥潭一般,苦苦挣扎着过了一个相当沮丧的年,直到三月中旬才真正完成这次重构。这其中到底发生了什么呢?

首先,为了优化代码,我决定把手写的sql代码,尽量用rails的ActiveRecord的方式重写一下(手写的sql代码是过早优化的明显证据),这样可以令代码更好懂,更好改,为后续开发打好基础。看起来毫无疑问,我应该先把model association中的join table升级为join model,前者已经过时,而且我的确需要利用join model添加我需要的额外关系属性。

嗯,终于需要改动数据表的结构了,由于一直用migration来改变数据结构,项目的数据库一直在平滑改进,用户数据没有破化过。但是一些看起来杂乱的migration文件应该重构,应该把它们归置整理,将数据库从头到尾好好整理下–反正还没有正式发布,自己的数据也可以用导出导入功能安全的备份,就这么弄。

对了,要趁这整理数据库的机会,把所有数据表的主键改回系统缺省的整数,用uuid字符串做主键越看越是个错误。

动手。升级到join model看起来还顺利,只是很多测试通不过了。老方式虽然落后,但rails框架准备了较完善的支持代码,使得model间的associations方便易用。而join model虽好,却是个新事物,还在不断的发展中,不得不手工处理一些常见的功能。

经过调查,决定将rails升级到最新版,这样join model就好处理些。

有点中流换马的感觉,测试还没有完全通过,所以不应该签入代码库。但升级到新版rails前,不把已经做好的很多改动保存好,心里也是没底。不管了,签入代码库,反正开发人员就我一个。(后来这样不负责任的签入还有好几次)。

一大堆跟rails1.2.2相关的警告,我的代码中有些过时用法,更正。还有些错误,排查。运行测试,老错误很多还在那里,但升级是完成了,按理说也是要签入吧?唉。

研究剩下的错误,发现那是个大话题,并非我想象中的那么容易。扎到hasmanythrough.com,找答案。发现需要把rails的model好好研究下,可是,年关将至。。。

还有一点时间,把uuid改了吧。一改才发现,这后面藏着的也不是善碴儿,但已经上了贼船,硬着头皮弄吧。还好,过年前这个东西总算解决了。

过年,不爽。还是得过年,休息,远离电脑,不爽。。。年终于过完了!

来吧,我王老五重打旗鼓另开张。可是,大脑用各种理由推诿我的要求,我发现连做到电脑跟前都是件事情了。传说中的“节后综合症”静悄悄地登场了。

强制,没有状态,给自己放假。再强制,还是没状态,再放假。反正soho一族就这点好处了。

总算进入正轨了,咬牙骂娘诅咒,好歹解决了所有问题。可是这么长时间,写一个自己的宠物项目都可以完工了。这就是重构吗?

其实这次重构开始不久我就意识到问题所在了,可是已经走不了回头路,只能硬着头皮坚持下去。大型重构应该是极力避免的,如果不能,也必须将大型重构分解成小型重构,再分解成相互不影响的小块。互不影响的一个简单检验标准是:重构了这个小块,全部原有测试依然通过,毫无遗漏。每次一个重构小块通过了测试,签入代码库,签入是小里程碑的标志。当然了,小里程碑是“小步快跑”思想的捍卫者。

大型重构的问题也是中古年代开发的问题:所有的头绪纠缠在一起,它们互为牵制,为项目的顺利进行设置重重障碍。头绪增多时,大脑处理它们的能力并非是线形下降,而是成指数下降,如果这种情况发生了,项目死亡的风险急剧加大。因为在这种极低的效率下,开发人员的士气受到影响,心智受到摧残,表现为注意力下降,精力分散,拖延任务,推卸责任。

这正是为什么许多项目总是在百分之九十处停滞,并且永不能完成的原因。在前文提到的开发思想的帮助下,这个问题得到了相当程度的解决。我上面犯下的大错,就是对没有很好的遵守正交性和小步快跑原则的惩罚。

让我们来假想一下怎样按照正常的现代开发方法,更好的进行上述重构。如前所述,我的目地是进行一些优化工作。这应该是一系列子任务,将这些子任务写出来,力图使它们看起来相对独立。

考虑到rails是个正在成长的开发框架,应该首先把它升级到最新版,以避免无谓的重复劳动。测试,签入、庆祝。

一项项重构子任务,如主键uuid替换为整数的那个任务。测试,签入、庆祝。

一项项重构子任务,如发现正在处理的问题超出预期的麻烦,则要看情况决定处理方法。这个问题可能可以继续细分成更小的子任务;或者,纯粹是因为问题难解决,这时可以硬攻,也可以暂时绕过,等所有其他重构完成后再集中火力攻克。对大型重构来说,这么做值得鼓励,因为它没有打乱正常的重构步骤,没有破坏可预期性。测试、签入、庆祝。或者测试、恢复原版本、庆祝(看你怎么想了)。

重构过程中一定要避免加入新功能,有时候那是一种诱惑,但必须要抵制。有了好的想法,记下来,继续重构。等重构结束后再来研究那些新功能,新点子。

总之,大型重构是很危险的。如果不能很好的将其细分成正交性强的小块,它将面临老式开发带来的收尾难题。不要害怕琐碎的重构步骤会降低你的工作效率。一个花了一年时间才完成项目的开发者,是没有能够完成项目的开发者效率的 无穷倍

2007年03月16日

我从来都特别羡慕那些效率奇高的人。我总是搞不懂那些家伙是怎样在完成许多伟大事情的同时,还能到处参加社会活动、出书、沉迷于自己的特别喜好。这种人中做的极端的,会令我不自觉地妒火中烧,关于这点,我以后会专门写个帖子讨论。

在过去相当长一段时间内,我的工作效率是比较低的。作为一个开发者,我越来越对微软的那一整套东西心怀怨念。几年前为了改善我的开发效率,我下了很多功夫去研究当时比较流行的一些开发新概念,比如设计模式、面向对象编程的原则、范型编程、测试驱动、敏捷开发等。每一种技术都有其道理,但我后来发现,这些技术都是一些更高阶思想原则的派生物,如果不理解那些基本的思想,就不能很好的应用由它们派生的技术。

在我对此有了模糊的印象时,两本书和一个开发框架适时地出现了:The Pragmatic Programmer, Getting Real和Rails

这两本书的作者带给我了核弹式的冲击,特别是The Pragmatic Programmer,令我这个对unix没有太多概念,几乎完全成长在微软操作系统和开发环境下的程序员倍感惭愧。

软件开发是个很复杂的事情,如果你没有必要的而且正确的指导原则,不同程度的开发失败几乎是必然的事情。人们一直都在搜寻那些“正确”的指导原则,经过了这许多年的持续努力,一些当前最流行的技术思想看起来离“正确”越来越近了,她们中最核心的是:正交性和“小步快跑”。

敏捷开发主要源于“小步快跑”的思想,即快速迭代。敏捷开发和各种现代开发方法都严重依赖的单元测试,则主要源于正交性思想,即完善的隔离开发中的各个模块,确保随着时间的推移,各个模块始终互不影响。重构则源于这两个思想:重构特别重视正交性,她鼓励你在每一步后通过测试确保刚才的改动没有破坏原有的系统;同时重构也极端鼓励小步快跑的方式,以至于人们经常会感觉到她有点书生气,甚至迂腐。但本质上重构是利用每一步都可以掌握的微小重复,换取项目自始至终的可掌控性,而对于稍有规模的项目,可掌控性通常比其他任何东西都重要的多。结对编程鼓励人们小步快跑,同时使用单元测试保证项目不会跑到沟里。

由于这是个很大的话题,一遍小文章不可能涵盖清楚,必要的后续展开是少不了的。下一篇文章将讲述我的一段滴血的重构教训

如果你想更深入的了解正交性的思想,看The Pragmatic Programmer;如果你想更深入的了解小步快跑,看Getting Real;研究rails框架和她的开发哲学,你将加深对这两个原则的理解,并了解到其他一些核心思想,如隐藏在“习惯优于配置”之后的“实用优于优雅”。

2006年10月17日

在王建硕的博客上看到这样一封读者来信,感到莫名的难过,如果我们自己是外来者,和这位可敬的老外的感受会有什么不同吗?

你好建硕,

我读你的博客已经有几年了,我是在2004计划去中国旅行的时候发现你的博客的,你的那篇北京到上海的列车时刻表帮了我的大忙。继续努力。

我总是想问问你对一件事情的看法,这件事情困扰了我很久–关于在上海这样的大城市中,人们对乞丐和无家可归者的态度。

我不能在餐馆中吃完我的食物,我总是想把它们打包,然后送给那些我碰到的无家可归者。偶尔我碰到上了年纪的人,比如一位老妇人,我会给他们一点钱。在旅行中我这样做了,但我的中国朋友告诉我不要这样,因为这些人都是假装行乞的。

有一件我印象极其深刻的例子发生在我旅行到安徽省的时候。我看到一位老年妇女在收集塑料饮料瓶,我猜她是要到回收站换一点钱。她被几个年轻人耍弄,老妇人看起来乞求那些年轻人把刚喝完的瓶子给她,但是他们不但没有体面的那样做,而且将瓶子踢到湖里老妇人无法够到的地方。在老妇人试图从湖中捞那个瓶子的时候,我不得不把她拉到一旁以免她不慎落水。这件事令我愤怒了很久。。。

在我看来,这位妇人做了一件对每个人都有益的事情,她把这些空瓶子搜集起来送到回收站,它使得环境保持清洁,并解决了塑料不能降解的问题。我对这些人持尊敬态度,这些他们一生下来就为了生存而不得不做那些不足挂齿的但他们力所能及的小事情。与那些富有的但被宠坏的一天没工作过只知道花父母血汗钱的孩子相比,这真是另一个完全的极端。人们戏耍没有自己幸运的人的态度令人作呕。

我不知道你能不能告诉我,在中国,这是不是个普遍的问题。你会,或者你曾经为这些乞丐和无家可归者做过什么吗?

我想到这些是因为我看到你今天的帖子,讨论为什么星巴克是欣赏外滩风景最便宜的地方,因为一杯咖啡只需要25块人民币。我确信这些钱可以为那些无家可归者买些肉了。这件事提醒我,会不会有一天中国与日俱增的贫富差距,会成为一个不可救药的问题?

不管怎么说,这是个长期的挑战,我希望你能告诉我你对这件事的想法,先这样吧。

Beggers in China and People’s Attitude

2006年09月14日

Joel是很多人很尊敬的软件大师,他的个人网站Joel on software在Bloglines的订户数已经达到32235个。可能你对他没印象,但你很可能看过他的文章,比如行进中开火看起来简单,实际上复杂。

Joel最近遇到了大麻烦,他撰文批判了Ruby的性能,遭到了来自四面八方的猛烈而一致的批驳。

Joel认为,Rails并没有性能问题,他只是质疑Rails的实现语言Ruby。由于绑定和duck typing的原因,Ruby不可能向下编译成CPU能够用一个Call指令直接支持的程度,这就在语言底层造成了性能上的短板,从而导致了Ruby在理论上的“慢”。导致的结果就是,本来你的应用要用10个服务器,现在可能要用100个。这样的话,你很难说“程序员的时间”真的比“CPU时间”更宝贵。

平心而论,Joel的观点在我看来还算是正常的质疑,只要是动态语言,就会面临这些矛盾。Joel也很小心的一再暗示,“我是尊重程序员时间的,请不要误解我。”

但Joel明显低估了RoR粉丝们的狂热。他发贴后的数个小时,几篇声讨文章就出炉了:

Avi Bryant从技术角度向Joel的观点发难,他认为,Ruby是慢,而且的确是受mathod dispatch方式的拖累。但他不同意“Ruby不可能向下编译,以便代码能够用一个CPU Call指令直接调用”的论断:在95%的情况下,一个很好的实现可以做到向下编译成一个跳转加一个比较指令,不需要“虚函数表”,这实际上从理论上比C++还要快。Avi解释了他的实现方法,并推介了应用了类似技术的Sun公司的新产品Strongtalk,他认为Ruby迟早会实现这个技术,并从Sun雇用了JRuby的人推测,Ruby很可能已经在做这个事儿了。

Chris Hanson提出不同观点,他认为,Ruby慢的原因不是message-based dynamic dispatch(dock typing),而仅仅是因为Ruby是一个单历的解释语言,Ruby需要在运行时扫描、解释然后执行代码。Chris提到Ruby2.0会会加入预编译环节,从而在性能方面获得重大提升。“这没什么难的,”他说,“这些技术难题60年代的Lisp语言和70年代的Smalltalk语言早就攻克了。”

Obie Fernandez用时态表达了他的遗憾,“他曾经是我心目中的英雄。。。”,Obie的这种感觉,我有一些,Jeff Atwood也有,他认为:

尽管Joel的Blog几乎是个金矿,他也会犯错误,比如他讨厌异常(Exceptions)(2)Java不适合做教学语言。但是,和最近Joel的新帖子相比,这都是小巫见大巫了。

Jeff更是翻出了旧账,有点不厚道的猜测Joel对Ruby的批判或多或少和他想推介自己的语言Wasabi有关,Joel当初推介基于VBScript的wasabi的时候,大家都以为他在开玩笑,以至于Joel要专门写个帖子辟谣:wasabi是真的!,挺好玩的。Jeff看不出wasabi比ruby高明在哪里,他认为,如果按照Joel的逻辑,我们就应该拒绝所有的动态语言,即便这个世界上已经充斥着双头的3G主频的只值两百美金的CPU。

最强烈的RoR粉丝Matt M甚至使用了不礼貌的字眼,他称Joel是一个“滑稽的老家伙”,曾经干下不少打压Ruby和Java的勾当,最近的那个帖子更是白痴论调,他讥讽到:“Joel说Ruby做计算不够快,请问他的Bug管理软件需要做什么样的大计算?是自动修复你的bug吗?” Matt进而讥讽了Joel的wasabi:“Joel实际上是用基于VBScript的定制语言来开发他的小程序。”--老美骂人都是这么杀人不见血的,害怕。

Matt M最后叹了口气,说出了我想说的:“近年来我比以往更仔细的在Joel的东西里淘金子,但我想再也淘不到了。”

从技术角度看,这件事情挺正常的。Joel敢去触动编程语言优劣这个话题禁区,遭到批判就不奇怪。他不像Robert C. Martin那样在语言的优劣问题上显得老奸巨滑。我感慨的是发布观点的风险竟然可以这么大,一着不慎,多年经营的口碑就会大打折扣。但是对于需要和喜爱发布观点的人来说,几乎不可能提前判断出一个话题会带来什么后果。这个事件令我联想起keso曾遭遇过的baidu专利事件。keso和Joel化解这件事的方式如出一辙:

keso说Update: 在有关朋友的提示之下,重新以“Li Yanhong”这个名字搜索,找到了相关专利,美国专利号:5,920,859。专利提交日期为1997年2月5日,批准日期为1999年7月6日。这项专利是关于超文本文档检索系统和方法(Hypertext document retrieval system and method)。相关专家可以来分析两个专利的相似性。

Joel说: Avi Bryant describes a method for making method calls really fast, even if they do happen to be duck-typed. Cool! (Ruby’s still slow. Film at 11.)

其实对有影响力的团体和个人来说,危机攻关的需求随时都会到来。提前准备好一个危机处理原则,恐怕是一件非常有价值的事情。

2006年09月10日

摘自360安全卫士

由于网络实名与雅虎助手的恶意破坏,导致部分用户的360安全卫士无法正常运行。

如果您的360安全卫士由于雅虎助手或者3721中文上网恶意干扰而无法正常使用,请点击下面的连接,下载360安全卫士的专杀工具来对此两款软件进行彻底清除

多有意思啊,我们何时缺少过漂亮而义正词严的话语:国共战争期间,我军称国军溃败为狼狈逃窜,称自己溃败为战略转移,当真是天凉好个秋。

本无意赶此等浑水,但今天我的IE不幸中招,逼着我跟这些所谓的流氓和流氓前辈小打了一下交道,想必是作为回报,老天让我看到了上面那精彩的一幕。

今天无聊,下载了些个“小电影”,正看得美滋滋呢,IE弹了出来。做为一代有经验的看小电影的前辈,我丝毫不以为然,随手把IE关闭了事,反正我的IE安全级别总是设为最高,基本上IE身上可能发生的那些烂事儿,在我这儿都碰不上。

突然发现不大对头,怎么还弹出了几个DOS窗口?仔细一看,果然像是蟊贼程序正在篡改我的系统呢,赶紧通通关掉,再一试,果不其然,IE的缺省主页被改成了xxxx.com,而且每隔十几分钟系统会自动弹出另一个成人站点。妈的常在河边走,哪能不湿鞋,我心想着,当即调出SpyBot查杀系统,果不然,发现了几个流氓软件。没想到的是杀掉它们重起系统,xxxx.com硬硬的还在。马上祭出Google大法,照着找到的前辈秘籍,将注册表、安全模式、组策略的虾折腾一气,xxxx.com还是稳如泰山。

要照我以前的脾气,恐怕又要跟这个困难忸上劲了,此番转念一想,黑皮的口头禅冒上心田:你费那事干吗?直接一锤子不就得了吗?对,就是这个主意。还没等脑筋还没转过来呢,谢小盟的台词又浮了上来,流氓与流氓斗,其乐无穷喔!

问题是找哪个流氓,挨着个的打量他们一番,看上了周前辈的360Safe,前辈两句话深深地打动了我:* 强劲查杀更多顽固恶意软件* 仅906KB,下载只需数秒。嗯,就是它了。

下载,安装,第一件事就是去控制面板看有没有卸载项,眼睛一亮,啊,她在那儿呢。心放下了一大半。接着看看效果:检测,查杀,重起,搞定。前辈出手,那果然就是不同啊。

好了,正经些,360Safe相当令我满意,从各个方面,当然除了开头那个小插曲。我站在菜鸟、程序员、美工、道德观察家和闲杂人等各个立场,挨个审视了360Safe一番,都送出了不错的分数。

如果非要站队的话,我选择周前辈的360Safe,中国人连日本人都原谅过,还有啥原谅不了的呢?但是,我保留看戏的权利,请洗过澡的和没洗过澡的流氓叔叔及流氓哥哥们原谅则个。

p.s. 中招原因分析:在调试程序的时候,我把IE安全级别调低了,忘了调回去,给了IE劫持者机会。播小电影的时候,小电影制作者有些会在电影中安插机关,打开某个自己的网页。如果这个页面上有不法的ActiveX,而且你的IE设置又允许ActiveX执行的话,那打开那个页面,就等于放贼进门。为避免这类事情发生,可以:

  • 使用Opera, Firefox等不支持ActiveX的浏览器,将IE打入冷宫。
  • 将打入冷宫的IE安全级别设为最高。
  • 更改缺省浏览器到Opera或Firefox。我就是忽略了这一点,从而失去一道屏障。

p.s.2 此类事情,别人的看法:

2006年09月04日

这是大徐在世锦赛中国队惨败给希腊后说的一句话。大徐认为,一场CBA比赛经常可以打出13x比12x的高分,你是不能说中国的队员没有技术的,你只能说,中国队没有高强度对抗下的技术。没有“功”- 身体素质和对抗能力,以及对抗下的技术动作稳定性,“拳”就只能是花拳,不能有效的打击对手。

忽然觉得自己也是“练拳不练功”。开发的时候,通常我在不断的重复着这样的步骤:1、构思 2、写代码,3、碰到技术问题,Google it。我似乎从来没有时间系统的学点什么,都是先上手,碰到问题了再去学,Python, Ruby, CSS和Javascript甚至Html都是这么学过来的,你可以说这种极端的实用主义没有什么不好,但我总觉得事情不应该是这样的,你见过一边学一边开刀的医生吗?你见过一边学一边盖楼的工程师吗?肯定有,但在那些行业里这是明白无误的乱来,可奇怪的是,软件开发就可以这么来,我的那个开发步骤,其实也是绝大多数开发者的步骤。Google助长了这种工作方式,它使得我连文档都懒得去翻了,碰到问题第一反应就是Google it. 我们都觉得这种方式最快最直接,可是,真的是这样吗?

大家都在说抽烟对身体不好,但没人注意到抽烟是非常浪费时间的事情。就像没人注意到频繁的搜索是多么的浪费时间。标准烟民一天抽一包烟,一包烟20根,平均抽一支烟5分钟,那一包烟就需要用掉你1小时40分钟,有点不可思议吧?即使很多时候烟民是一边抽烟一边做事的。

Google搜索中给出的搜索时间通常是几十毫秒,这给我们的潜意识施加了微妙影响,使得我们认为Google你要的东西是很快的,很多时候这是个错觉。Google给出它的搜索结果是非常快,但你从中找到你要找的东西需要花的时间,却远不止于此。按我在开发时搜索的经验,快的话需要十数秒,慢的话用掉半天时间也是可能的。Google只是从海量信息中帮你甄选了一个范围,你还是得在这个范围内继续甄选。

避免频繁搜索的一个办法就是系统的学习,另一个办法是弄些Cheat Sheets放在手头。本质上,凡事依赖Google而不进行系统的学习,就是练拳不练功,一定会受到某种程度的惩罚。

系统的学习包括看相关的书,文档,观点性的文章;看开发框架的代码,研究别人的代码,并尝试从中总结一些抽象的思想。系统的学习结合Google搜索,将会无往而不利。

跳出编程的小藩篱,这个思想同样可以用在别的地方,比如学英语。在求学期间,我的英语学习基本上是只有理论没有实践,到了工作期间成了只有实践没有理论,都很荒唐。只有理论结合实践,或者说即练拳又练功,恐怕才能真正的掌握要学的东西。

2006年09月01日

今年四月份造访了宁波,留下了非常美好的印象,在朋友的鼓动下,这次把家搬到了宁波。

宁波是我在国内可以找到的,最符合我心目中理想的城市了:中等规模,经济发达,文化底蕴深厚,人口密度小,自然环境优美,依江傍海,政府不作为指数低。这里并不缺少欣赏高雅艺术的机会(虽然此刻的我并没有心境玩儿高雅),能拥有一支CBA球队八一火箭就让我很开心啦。

随着年龄的增长,每一年都似乎在加速流逝,青春还有多少?借这个机会,我会慢慢的调整心态,多分配些时间来生活好好地向这哥们学习学习。。。作为起点,从现在开始,杜绝晚上工作,立此为证。晚上的时间多陪陪女朋友,向体育、影视、书籍、游戏以及系统的学习倾斜。

2006年08月08日

方军在Digg:无所依的产业链提到:

从整个产业链的角度看,Digg是无所依的。它所提供的内容,是传统媒体以及正大量涌现的blog生产的内容。由于这种模式并未触及内容生产,仅仅改变传播方式,内容的生产者无法从中获益,无法串起产业链条,因而是个小生意。

非常好奇为什么方军先生认为“内容的生产者无法从中获益”,在我看来,“内容的生产者将从中疯狂获益”,特别是中小内容生产者。最直观的证据是:越来越多的Blogger将Digg,delicious,furl甚至blinklist的“添加”图标放在内容前后显眼的地方。无利不起早,这些Blogger这样做正说明一旦被Digg们“宠幸”了,将带来可观的利益:

  • 快速被世界注意到
  • 对于小的内容生产者来说,没有什么比被关注更重要的了。不管你在网络任何角落,只要你产生的是高质量的内容,你就会被那些精力旺盛的Digger们发掘出来。发展网站的传统方法中,可能只有打广告在速度上和被发掘的可能上比较接近。通过搜索引擎来发展小站点,越来越难了,没有一年半载,新站点上的内容很难保证会被Google搜索到。

  • 引爆流行
  • 通过Digg和Delicious的传播,很多新鲜事物似乎一夜之间人所共知,Ajax, GTD 和 Ruby on Rails都是例子。Digg是一个引爆流行的工具,你有了足够好的材料,就有可能通过Digg一举成名,因为Digg是一个天然的“口碑营销”集散地。

  • 高质量的外部链接
  • 首先Digg们就会给你带来一个不错的外部链接,其后喜欢你内容的人会通过各种方式链接到内容出处–你的网站。有了链接,搜索引擎就开始喜欢你的网站了,稳定而高质量的搜索引擎流量跟着也来了。

  • 长期的Blog订户
  • 作为Blogger,你永远会希望自己的订户越多越好,对Blog来说,这是最稳定的高质量流量来源。

  • 帮助建立自己的专家形象
  • 跟上一条有点一脉相承,但对于小企业主来说,如果你希望把写文章作为一种营销手段,那你很可能作对了,系列的高质量文章/内容,会逐步建立你的行业专家形象,这样你想卖给他们点儿什么就容易多了,:)

  • 满足心理需求
  • 前面提到“宠幸”一词,有点不雅,但我很难想到更神似的词儿。被Digg了,跟以前被Slashdot了一样,有一种强烈的满足感,有多强烈我是没体会过,但是想想看,你的文章被数万人看到,而这些人分布在全世界每一个角落中。。。

  • 其他一些好处,比如赚点小钱
  • 记得几个月前看过一篇趣闻,某人写了篇文章被slashdot收录了,收到数万访客,那篇文章旁有个adsense广告,结果这数万访客给他带来了数百美元的adsense收入。另一方面,你也可借助“slashdot/digg效应”检验一下你的主机皮实不,被slashdot或者digg收录,对小站点来说通常意味着一次宕机。

以上这些利益基本上都是从“流量”派生而来,考虑到这个流量的质量,你其实很难说“内容的生产者无法从中获益”。或许方军先生更多的是从媒体行业的角度看这个问题的,在文章开头引用的那段话中,他还提到:

刚才和林嘉澍讨论碰撞出一个观点:传统媒体它销售的是一个有形式的内容组合,即便它的单个内容被Digg用户强烈推荐,看似有利,但实际上依然是损伤了传统媒体公司。

这说明方军先生也很可能是清楚上面那些好处的,只是认为这种好处“看似有利”。对于Blogger和中小网站的内容生产者来说,我不认为这只是“看似有利”而已,对于媒体行业而言,我可以理解方军先生的担忧,但我觉得我们不能忽略一切内容生产者的动机,那就是被广泛传播。如果说谈到利益分配,那不妨站的稍微高一些看待这个问题,而不一定非要把思路限制在用真实货币交换上,比如,对于大型的媒体而言,企业形象的提升是不是一种获益呢?

所以,digg的产业链还是坚实的,这是个多赢的模式。google同样不产生原创内容,仅仅改变传播方式,但也是多赢的模式。对内容生产者来说,digg和google的作用类似,区别在于时效性的不同。

Update:

添加“引爆流行”一条

2006年08月01日

其实不应该意外,IE很多时候都表现的通用标准不兼容。

今天排查一个浏览器兼容错误,总是没有线索。按我以前的经验,这个时候应该用w3c提供的标准标记语言校验服务检测一下,很多时候会收到奇效。

由于我是在本地的web服务器上进行开发的,没有办法通过URL来检测,只能保存一个html文件,上传到w3c,然后进行校验。因为我排查的是IE6的不兼容错误,不假思索的就用IE6的“另存为”保存了问题页,然后上传检测。果不其然,w3c报告了8个错误!

挺高兴的,我以为这下有线索可以排查错误了,谁知仔细一看那些错误,全说的云山雾罩的事情,怎么看也不象是我犯的错误。同然猛醒,马上用Opera9保存了问题页,这次没有一个错误,顺利通过校验!

也就是说,没有错误的网页经过IE的手一保存,就会出现一堆错误。

因为习惯了的缘故,对这次IE的表现没什么惊奇的,只是写下来提醒一下web开发者。

2006年07月01日

下面这些文章详细介绍了CSS实战中,经常碰到的难题,以及这些难题的标准解决方案:

  • Box Model Hack 盒模型秘计

    盒模型是导致CSS难用,并招致不满声音的最大元凶。主流浏览器理解盒模型的方式不同,造成设计师只能利用Hack手段摆平这些区别。这篇文章详细的介绍了盒模型的概念,各个浏览器处理盒模型的区别,以及数种解法,很全面。延伸阅读 Alternate Box Model Hacks, Box Model Hack

  • Global White Space Reset 全局空白重置 (必读)

    我最喜欢的文章,因为它太实用了。使用这种技巧,CSS不再是那么痛苦的噩梦。这个技巧背后的思想是“默认优于配置”,你只需要很少量的细节微调工作,就可以得到很完美的效果,它不但简化了CSS代码,还有浏览器兼容性强的优点。

  • Efficient CSS with shorthand properties 高效CSS简写属性

    这篇文章汇总了常见的CSS简写技巧,使用简写技巧,不但减少了字节,也使CSS的代码可读性得到提高。比如:

    background-color:#f00;
    background-image:url(background.gif);
    background-repeat:no-repeat;
    background-attachment:fixed;
    background-position:0 0;
    

    可以简写为:

    background:#f00 url(background.gif) no-repeat fixed 0 0;
  • Sliding Doors of CSS CSS滑动门

    页签导航(tabbed navigation)技术现在应用很普遍,本文详细介绍了如何使用滑动门技术制作图片页签导航,图文并茂,非常详尽。

  • Avoiding Classitis 避免class爆炸 (必读)

    class爆炸可能是CSS使用过程中最容易犯的错误了。典型的代码类似于:

    〈div class="article"〉
     〈h3 class="article-title"〉我的自白〈/h3〉
     〈p class="article-brief"〉我坦白,我犯了一个错误...〈/p〉
    〈/div〉
    

    这段代码的作者似乎有兴趣给每一个元素都加上类,很多时候这是毫无必要的,并且还有浪费带宽,降低可维护性等诸多缺点,通过“全局空白重置”技术和属性继承技术,类爆炸现象可以得到明显的控制。延伸阅读 Div Mania

  • Turning a list into a navigation bar 用列表制作导航条

    一步步教你制作CSS导航条。 没啥说的,每个人都会用到。延伸阅读 Taming Lists

  • How To Clear Floats Without Structural Markup 怎样不用结构化标签就清除浮动

    传统技术中清除浮动一般用{clear: both;} ,这种技术有很多缺点,比如违背直觉、需要添加一个额外的元素、浏览器兼容性不好等。本文介绍了一种新型的技术,克服了这些缺点。图文并茂,非常详尽。

  • Faux Columns 自适应高度栏目

    几乎每个使用CSS的同学都会用div来为网页布局(排版),最终很多同学都会碰到这个问题:怎样使几个div栏目等高?这个看似易如反掌的问题却能把你弄疯,除非你知道这里介绍的技巧。

  • Making the Absolute, Relative 应用绝对和相对属性

    绝对属性和相对属性似乎比较难理解,不知道有什么用,这篇文章通过解释作者的一个实战:自动保持header中导航条和Logo的距离,详细的给我们介绍了绝对和相对属性的原理和应用,图文并茂。

  • Introducing the CSS3 Multi-Column Module 介绍CSS3标准中的多列模块

    在table的时代里,定位元素的手段主要是利用table和透明sizer图片。当前CSS的时代中,定位让位给了各种CSS属性。CSS很好的替代了sizer图片,却对布局支持不足。因为没有CSS语言内建的高级布局支持,同学们不得不使用div加float,clear属性来拼凑出所需的布局,又因为目前各种主流浏览器对盒模型和浮动的理解各有不同,使得CSS排版问题成了一个噩梦:不通过一定的hack手段,你很难实现想象中的设计。在这种背景下,一些同学(比如我自己),开始重新思考table的价值,并给予table在布局上的贡献以应有的尊重。然而这并不是终极解决方案,在未来的CSS标准中,排版应该在语言层级上得到支持,Multi-Column就是CSS3标准中推出的一种排版辅助模块,阅读本文有助于同学们更好的理解CSS版式问题,站在高一层的台阶上设计自己的作品。

[本文实时更新]