2008年8月29日星期五
浅谈developer friendly
.NET和Ruby On Rails均是最先进的软件开发模式的代表,虽然它们并非一个级别的东西,但思想上有很多共同之处,这些“共通“的地方,大概就是他们”先进“之所在。我觉得它们最大的一点共通之处在于二者都花了很大的功夫在developer friendly上。另一点在于二者都力图在应用开发的不同领域(domain)内提供相同或类似的用户体验,更准确讲叫开发者体验。
先以.NET为例,.NET的出现对developer有两个重要意义:
* 一是对多语言的支持,使得developer能最大限度的利用已有的知识和经验,同时还能从统一的clr中得到同样丰富的类库与run-time支持,vb到vb.NET,java/c++到c#(还有那个被废掉的java版本的.NET实现),javascript到jscript.NET,以及现在的DLR支持下的多种动态语言的实现(ironpython, ironruby, javascript等等),而CLI(和DLR)的标准化,使得在.NET平台上扩展任何编程语言的做法在理论上是可能的。虽然我也总是认为,这只是把同样的东西(.NET framework)用不同的方式(各种基于.NET的语言)来表达,很多时间与精力花在这上面有点浪费,但是从微软的角度看,不论你从哪里来,.NET总是欢迎你,对developer来说,没有什么比直接使用已有的知识在新平台开发更友好的方式了。
* 另一个方面是在不同domain内开发方式上的趋同。原本针对微软平台的产品做开发和二次开发都需要相应的语言和方法,这种”domain"很多,传统的开发方式更多,比如桌面应用(vb, vc++等),web(asp/COM/vbscript/jscript/html/css,iis...),database(T- SQL),office(vba),mobile(embedded vb/vc)等等,一个domain内的熟手要想转到另一domain,是很困难的事情,不仅在于不同domain所需知识的差异,还包括开发方式,编程习惯等很多方面,在跨domain开发时,developer很难应用现有的经验和知识,基本上跨domain的技能都需要从头学起。而.NET从发布至今,微软的几乎所有产品都在悄悄的(或突然的)支持.NET开发,至少在编程习惯和开发方式上是这样的。
- 桌面应用自不必说,从1.0开始,Windows Forms便屏蔽了不同开发工具和语言的差异(几乎只剩下不同语言语法上的差异了),到.NET framework 3.0(3.5/SP1)对WPF的支持,从前使用的SDK和API几乎可以完全忽略。
- web应用方面,对客户端的要求只是浏览器,当大多数编程工作集中在server上时,更可以完全放弃以往ASP+COM粗糙的编程模型,而随心所欲地发挥.NET平台/语言的功效。 asp.NET提供了基于server control的web form编程模型,这种方式几乎屏蔽了web应用本身固有种种复杂因素(stateless, client/server roundtrip, debug, security, validation等等),使得web开发变得如同传统的桌面程序开发那样方便与直观(拖拽,数据绑定,属性设置,双击,编写事件代码,F5运行...),继而在ajax走到前台的时候,ajax也作为server control的extension被加入到toolbox里,在2.0的时候,masterpage,membership等原本需要大量编程才能实现的工作被抽象成了一个个out-of-box的feature,只需配置和简单编程即可使用,等等。当然webform屏蔽了太多细节,为了事件驱动的编程模型增加了太多原本不必要的东西,以黑盒子方式出现的server control给developer带来了很多不安和麻烦。为了顺应developer之意,随后asp.NET mvc作为另一种可选的开发模型被一个preview一个preview地加入进来,借鉴了ROR, django和monorails等成熟的mvc框架后,在强大的.NET framework和visual studio支持下,asp.NET mvc应该会是web开发领域的best practice,虽然其中几乎没有什么微软的创新。随着基于DLR的动态语言的成熟,rails式的DSL也不在话下,JRuby+Glassfish已经做了一个很好的榜样。
- 在database开发方面,无论DDL, DML还是DCL,原本都是SQL(T-SQL)的天下,从SQL Server 2005开始,数据库引擎开始支持.NET assembly,developer再也不必感叹stored procedure和function在实现复杂编程时的限制和不便了,除了部署时有些许麻烦,用vb.NET操作数据库实在是爽(如果有过在stored procedure里实现复杂逻辑的经历会深刻体会到这一点,虽然这不是一个好习惯)。更牛的是针对sql server所提供的报表服务,分析服务和集成服务,SQL Server安装时可以选择安装一个visual studio环境,可以用来在数据库上直接开发和部署这些服务,所以,甚至在生产环境里,developer都可以使用自己最熟悉的开发环境(visual studio)进行编译和部署,微软为developer想的真是周到。
- 基于office产品的二次开发由来已久,没记错的话,office2000以前只能使用VBA开发,2003里office里各产品开始支持.NET开发特性,visual studio里开始安装vsto扩展,到如今,vs2008里默认的项目模板包含了对2003/2007里各种产品的全面支持。office开发和部署原本是一个限制很多而且有些别扭的模式,而现在,把word/excel/infopath作为一种客户端形式,使用熟悉的编程语言,熟悉的事件驱动模型,基于完整的.NET framework,针对office的编程模型几乎与winform和webform完全统一起来,熟练的掌握winform编程的经验几乎可以没有任何障碍的转移到office应用开发上来,加上SharePoint的扩展,这种转移意味着现有的技能可能被放大到一个更宽广的领域。自身技能的可重用意味着经验知识增值和平缓的学习曲线,对任何developer来讲这都是个好消息。
- 还有一点可以说明,微软有一些很重要的努力几乎完全是为了developer friendly而做的。两个domain可以体现这一点,一是基于compact .NET framework的mobile的开发,另一是RIA方面的开发。mobile开发只了解大概,不过有一点比较明确,以前的windows CE上的应用开发一般是使用embedded c++/vb,简言之就是基于Windows CE这个小型的Windows(应该是小型而不是子集)采用非托管代码开发应用,优缺点与在windows上用c++和vb开发应用雷同,mobile开发毕竟不如desktop和web开发更广泛,所以按理说这已经足够了,在资源受限的mobile设备上,应该能简则简。之所以裁剪出个 compact .NET framework,除了移动设备硬件水平大幅度提升,j2me等移动设备上的虚拟机已有先例等原因外,给developer提供便捷一致的开发环境是一个重要原因,曾经做过简单尝试,虽然对mobile开发没有概念,但是按照开发winform的经验建立一个winCE程序(现在叫smart device了吧),拖拽、双击、事件编码,运行,直到一个手机样式的模拟器打开,程序运行起来,几乎没什么障碍,虽然实际的应用开发一定比这复杂得多,但对于一个developer来讲,这种体验必定能让人感觉到友好与自信。
- 更有说服力的是微软在RIA应用与开发上下的功夫,即Silverlight。从Silverlight的产生和发展过程即可见一斑。.NET framework 3.0发布以后,WPF是其中最酷最直观的一个新特性,不过曲高和寡,推广是个大问题,虽然微软想尽办法简化安装.NET framework的过程,也不遗余力的推vista,时至今日,仍然看不到wpf得以普及的希望。于是wpf/e出现了,'e'大概指 everywhere,能称得上everywhere的平台,大概只有浏览器,而基于浏览器的web客户端的局限性不可能从根本上解决,所以只有通过RIA。WPF的“样子 ”(和编程模型)看起来天生就与另一个早已遍地开花的RIA类似,也就是flash(flex)。在RIA上,Adobe与微软殊途同归,一个是从浏览器开始,flash到flex再到AIR,表明Adobe从网络扩展到桌面的野望。微软倒着走,既然暂时看不到wpf得以普及的希望,那就利用wpf给用户带来的印象深刻的使用体验,把wpf推广到浏览器上去。如今,真正基于wpf的应用并不多,对于普通用户来讲也无所谓有无,而所谓印象深刻的“用户”,很大程度上指的是developer,而“使用体验”也更多意味着开发体验。wpf的编程模型很优秀,有时候我甚至会想,桌面编程原本就应该是这种直觉的模型,比如以 tree结构组织的窗体和控件,本来就应该直接映射到xaml这种hierarchy结构上,用来描述UI component外观的属性,本来就该像css那样用resource和template来抽象和重用,等等等等... 从微软的角度看,他们也并没有“发明”这种新的编程模型,只是在向flex和xul等已经存在并经过实践检验的成熟的编程模型趋同而已。不过对于 developer而言,这种趋同绝对是一件好事,一个有经验的flex developer转而开发wpf或Silverlight是一件相对容易的事情,我们可以把wpf和silverlight看成是微软在向所有潜在的 developer示好的重要努力。再回头看Silverlight的发展过程,先前的wpf/e很快更名为现在的Silverlight,从名字到开发方式,都很有规划,很有章法,之前的wpf/e实际上只是一个过度,也许是因为当初有这个想法的时候很着急推出点什么,所以Silverlight 1.x 实际上只是wpf/e的别名,作为过度,它最大的问题并不在于它本身是否具有足够丰富的功能(事实上silverlight从一开始就支持各种媒体播放和很酷的交互方式,下载的run-time也很小),而是对于developer而言,它没有提供一个很好的编程模型,为了host一个silverlight组件(实际上是一个浏览器的plug-in在host),并控制silverlight与html的交互,只能通过javascript来完成。时至今日,vs2008(或其他任何一种IDE)都不能提供绝对完善的javascript编辑环境,而且javascript这种看似平常的动态语言,在充分发挥其动态特性并且代码越来越复杂的时候,会展示出其非常诡异的一面,所以如果silverlight要完全依赖于javascript的话,显然不容易被developer所广泛接受。于是微软推出了一种比较奇怪的版本策略,一方面这个从wpf/e改名而来的silverlight从beta演变成了1.0版,其后的1.x版本也都都基于同样的编程模型(javascript);另一方面Silverlight 2.0的alpha被推出,形式上与1.x同,但几乎整个run-time都被重写。实际上并不是重写,据说silverlight与wpf是从同一个代码树派生下来的,可以说silverlight的run-time是.NET framework的一个子集。第一次看到2.0的这个思路让我觉得非常惊讶,因为这意味着整个.NET framework要被挪到浏览器中,只依赖于浏览器里的run-time,而不论本地OS是否安装(或支持).NET framework。这需要多大的一个run-time啊?!当确认我的想法基本没错后,就马上开始浮想联翩了。因为这意味着.NET developer可以使用最熟悉的语言和环境来开发一个RIA程序,几乎不需要太多的额外知识,意味着一条平滑的学习曲线(当然前提是对wpf、 linq等有足够的了解)。而微软对silverlight运行环境的承诺是只需下载一个2-4M的run-time,难以置信。随后我们看到的是 silverlight的不断改进,包括加入越来越丰富的控件和对动态语言的支持等,同时runtime的尺寸一直控制在可以接受的范围内,直到2.0的 beta版本推出,北京奥运会期间NBC采用silverlight播放网络视频,使其知名度一举飙升。Silverlight 2.0实现到目前的状态,微软花了极大的努力,Scott Gu在一个专访中提到了这些努力,包括如何裁剪和如何尽可能的优化以控制尺寸。回头再看,Silverlight2.0所做的这些努力,几乎只是为了一个目标:developer friendly。(btw:采用同样策略的还有IronPython,1.x版本基于CLR实现,并行的2.x版本基于跟适合动态语言开发的DLR实现)
再看看Ruby On Rails。ROR是一个优秀的web开发框架,虽说与.NET framework并不是一个级别的东西,不过ROR的很多优秀之处体现了和.NET framework同样的理念,重要一点就是对developer而言十分友好。
与.NET开发相比,ROR并不十分强调IDE的先进性,textmate据说是DHH们的最爱,咱没有mac,不过体验过号称为textmate移植版的e-texteditor,老实讲,用惯了visual studio的developer不会觉得他们有何不同凡响之处,不过是一个对ROR开发而言便捷得恰到好处的编辑器。即便更高级的ROR IDE如NetBeans 6.1和3rdrails,也与visual studio有很大差距。而ROR的主要特点是一个框架、一种语言、一套惯例与思路。对developer而言,ROR最大特色是它的全部东西对开发而言都是实用的,也是易用的,换言之,developer friendly。
作为框架,ROR提供了shell command来生成代码,固定的目录/文件结构直接映射到MVC模式,无需配置文件(需要的话也只是几行简单yaml),大量helper方法几乎囊括了web开发中所有常用的功能,扩展很简单,写helper,放在相应的helper文件,写类库,放在lib目录,第三方扩展,放在vender目录,执行任务,运行rake即可,运行和调试很便捷,script中内置方便使用的web server,等等...就像常说的那样“框架为你规定了一切,你只需把精力放在真正重要的事情上”。
对developer而言,过多的选择有时候会让人不知所措(比如在使用php时,单单MVC框架,就有十种以上选择,再加上不胜枚举的模板引擎和数据访问方法,以及他们的组合),在纷纭复杂的选择中,花费了时间,最终却未必得到一个适合自己方案。rails则恰到好处地把所有必要的东西包装(比如ActiveRecord、 ActionPack和ActiveResource)并组织在一起,近乎于best practice,其不同版本对框架结构的调整也体现其与时俱进的生命力。“恰到好处”非常重要,这意味着框架能够在一方面能够满足大部分常规需要(不必开发大量底层重复性的代码),另一方面提供足够灵活的机制让developer有充分的扩展余地。这个“恰到好处”正是针对developer而言,“恰到好处”也是rails从众多类似框架中脱颖而出并被纷纷效仿的关键所在。
作为一种动态语言,ruby几乎是最简洁优雅的(个人认为要强于python)。ruby本身是一种通用语言,但它的动态特性使其经常与另一个词联系在一起,即DSL(Domain Specific Language),这里所说的domain可大可小,可以用来描述某种业务领域,也可以用来代表软件开发的某个方面,比如,html或css都是各自 domain内的DSL,分别用来描述web页面内容/布局和定义style。而Rails本身就是一个典型的用ruby定义的在web开发领域内适用的 DSL。也就是说用ruby语言定义一组在web开发中实用/常用的语法,这套语法接近自然语言,专门适用于web开发。打个比方,"3.years_ago"这样一个语句,实际上是rails为int类型扩展了一个years_ago方法,以简洁易懂的方式代替了通常至少需要几行代码才能实现的功能,即显示3年以前的时间。之所以定义了这样一个方法,是因为在web开发中经常会有计算和显示特定时间的需求,rails里包含了大量此类扩展,但绝不是随意为之,比如不存在一个"3.yeas_ago_plus_two_months"方法,因为就一般意义上的web开发而言,这种方法没有代表性,且不可枚举。而ruby的好处在于其开放性,如果在你的应用中确实会经常用到“n年以前加两个月”这种方法,你可以在helper或lib甚至 rails本身中扩展这样的方法。所以DHH采用ruby来实现rails并非偶然,这样一种灵活、易读的动态语言,对developer而言,是最舒服的选择。这里有个体会:即使使用cakephp或django这些与rails类似的web框架,因为编程语言上的差异(php和python),都没有使用ruby on rails时那种惬意的感受,这只是个人看法。对developer而言,大概这便是friendly的体验。
说到DSL,再补充一点。由前例可以体会,对DSL而言最重要的一点就是对domain恰到好处的抽象。 “恰到好处”可以理解,也就是前面提到的为什么扩展了years_ago方法而没有years_ago_plus_two_months方法。而“抽象” 这个词本身比较抽象,什么样的工作算是抽象?抽象到那种级别合适?没有标准答案。不过在rails里一些重要的方面体现了如何抽象和抽象到什么地步。有三个典型的方面:
* Model: 这个词就是MVC里的M,本身就有点抽象,通常理解为数据模型,在rails里,数据存储介质一般指database(当然也可以是xml,csv或一个 pojo样式的不与任何存储介质关联的实体类),对数据的抽象就是model, ActiveRecord就是model的具体体现。ActiveRecord就是一个ORM,与其他ORM工具的不同之处在于,在rails里,不需要描述实体与db映射的复杂配置文件,多数时候这种映射的依据就是convention,也就是按一些约定俗成的规则做映射,比如一个叫posts的表对应一个叫 post的model类,posts表中一个叫user_id的字段表明users表与posts之间存在一个多对一的外键关联。这种规约看起来没什么大不了,不过对于一个通用web框架而言,“以规约代替配置”这种设计理念是很大胆的,某些时候,这意味着rails里的ActiveRecord可能无法满足一些特殊需求(当然rails提供了足够灵活的机制在需要时可以用代码配置这种规约),而这种代价换来的好处是在很大程度上简化了配置,简化的代码结构,减少了依赖,目的无他,程序对developer而言更清晰简洁而已。ActiveRecord的好处当然不止于此,一旦在实体中定义了 association,就可以便捷的在关联对象之间导航,这种关联可以是1:1, 1:n, n:n, join tables, conditional joins和polymorphic associations,尤其是polymorphic associations,几乎可以实现传说中的OODB了。此外,在ActiveRecord中定义grouping,定义validation,都是非常简洁惬意的事情。在第一次看到LINQ to SQL时觉得这是非常棒的一种数据访问方式,不过随着对rails中ActiveRecord的深入了解,我简直怀疑LINQ是在照抄它的思路了。再加上migration和针对db的rake任务,以及自动生成的test框架,rails中的数据访问相关功能就完整了。
* HTML Template: rails中使用ERB作为默认的模板引擎,ERB本身功能很完善,不过与其他知名的模板引擎相比,似乎并无特别之处,有时反而觉得django的模板引擎更规范一些。rails2.0中也可以使用haml作为模板引擎,如果习惯perl的模板方式,haml也是一种很好的选择,更为清晰简洁。在这里谈起模板引擎,是因为考虑到模板的概念是对传统html的一种抽象。更准确的说,rails提供了一套比较完整的view templates,除了ERB之外,rails还提供一整套helper,比如“form_for",”text_field“等等。我们得理解web应用是由一系列元素构成的,比如客户端的html和javascript,以及服务器端用来控制逻辑和做render的代码,而html中翻来覆去使用的就是 button, div, textbox等等html控件,加之css控制外观,javascript控制行为,才组合成千变万化的web page。如果手工编写一个form,很多工作是重复或大同小异的,rails里的helper们正是对这些重复却又不尽相同的工作的抽象。比如一个 text_field方法,只提供name和value参数,他就是一个textbox,加上其他option作为参数,可以为其定义css,或响应一个 onclick事件,如果再对其扩展,它还可以成为一个带有suggestion功能的textbox。采用常规的方法实现这样的一个控件,我们需要多样技能,比如html,css,javascript,服务器端的ruby代码,甚至ajax(XmlHttpRequest)等。helper的作用就是把这些重复性的工作抽象,包装在一个个望名而知其意的方法里。虽然常用的helper并不多,但rails还是提供了大量的helper,它们可以应用在web开发的方方面面,有些功能甚至是我们想不到的,他们唯一的共同点就是都是在实践中总结出来的,有实用价值的东西,而不是像一个通用类库那样包含了方方面面,但实际上很多东西是用不到的。这种使用简洁的抽象,唯一的受益者就是developer。
* Javascript: 这种东西需要抽象吗?能抽象吗?rails给出了肯定的答案。这里说的是RJS。可以把RJS理解为一种针对ajax特性的DSL。据说高级的 developer是不用这种javascript的抽象的,我的理解是对复杂的ajax操作,RJS有一些局限性,而且RJS以Prototype和Script.aculo.us作为基础库,也妨碍的根据个人喜好使用其他javascript库,比如jQuery。不过这不妨碍我们理解和使用RJS。RJS是一种模板形式,被成为javascript generator template,与通常提交一个动作结果的模板不同,这些模板会生成如何修改一个现有的被提交页面的指令。这可以很容易地修改声明有Ajax 应答的页面内的多个元素。这些模板的动作在Ajax背景下被调用,并可更新页内容。一个简单的例子如”page.insert_html :bottom, 'list',“,它的作用是在当前页面底部插入一个'list'元素。这是一个javascript在客户端操纵html元素的例子,然而作为developer,实现这个功能(以及其他复杂得多的客户端功能),几乎不需要javascript相关知识,因为这里没有javascript代码,只有对javascript的抽象。我想asp.NET的ajax控件扩展,实际上也是类似的道理:即封装javascript以及与服务器交互的功能,屏蔽复杂细节,展现高级特性。 如果不考虑RJS的限制,对developer而言,只要会用ruby,并且了解RJS能完成哪些功能,就足够了。
上述几方面有一个共同的特点:虽然它们针对的是web开发中的不同方面(db访问,html template,javascript),但抽象的结果是不要求developer精通每一方面的知识(比如 SQL,html,css,javascript,ajax等),熟练掌握ruby和rails框架的原理基本上就够了,我想对developer而言,这意味这平滑的学习曲线和快速开发的能力。
最后,说说为什么需要developer friendly。DHH在谈论为什么要使用ruby来开发rails时的一段话很有代表性:
Ruby is a language for writing beautiful code. Beautiful code is code that makes the developer happy, and when a developer is happy, they are more productive. Ruby is unique in the way it lets you express something briefly, succinctly, and beautifully.
没错,软件开发的主体是developer,用户会选择产品,但不会去选择开发工具与框架,只有developer(广义上的)才会在意这些,developer的取向直接引导了用户的使用习惯,Windows 的成功说明了这一点。让developer感到舒服,不仅会提高生产力和产品质量,也意味着你的框架,你的平台将被广泛接受,直接影响的就是你的市场占有率。
我想,当鲍尔默在微软开发者大会上歇斯底里的高呼”developer!developer!!developer!!!“的时候,大概想到的也是这些。
2008年8月26日星期二
奥运后杂感
中国人向来很在意别人对自己的看法,北京奥运的成功,让我经常忍不住想知道老外们作何想法。不出所料,一向自大的美国人用奖牌榜代替了金牌榜,并且吹毛求疵别有用心的讲了很多无中生有也无可奈何的蠢话;一向无耻的韩国人虽然还没来得及证明菲尔普斯和博尔特是韩国人,但他们的奖牌榜是把韩日朝放在前面比较,其他所有国家靠后,他大韩民国自然又是雄霸天下;法国人讲了很多酸话,可以理解,不必计较;英国人利用复杂的数学模型计算出不同项目金牌的含金量,结果自然是他不列颠的金牌一块顶三块,也可一笑置之。这些言论和行为艺术也恰恰佐证了北京奥运的成功。
欣慰之余,也会去想,中国社会真的是如同北京奥运所展示出来的这么成功么?体育赛场上争金夺银的同时,我们在其他领域也有同样的竞争力么?当看到中国股市上与奥运金牌榜形成鲜明对比的曲线,当看到那些关于掌握了中国经济命脉的特殊家庭的文章,当看到那些在现有法制陋规下无辜蒙冤的案例,当看到灾区那些因为资金问题偷工减料而在顷刻间化为砖泥的校舍,当看到国有垄断企业按种种“国际惯例”从数以亿记的中国消费者身上赚取暴利......我们很难得出肯定的结论。
所以,有时候会觉得很困惑:我们的社会究竟是怎样一种状况和发展趋势?我们看到、听到和经历的东西,有太多的矛盾之处。是虚假繁荣么?GDP和其他统计数据即使水分再大,连续二十几年两位数的增长也是不争的事实。是穷兵黩武、好大喜功、不计民生么?十几亿老百姓解决了温饱和基本的教育医疗住房等问题也是世界上其他任何一个国家所难以企及的,反例见朝鲜和伊朗。是思想僵化不思进取么?"中国特色的社会主义"这一思想本身及其贯彻过程,都证明了全中国自上而下的创造力和锐意进取的精神。可是伴随这些成就的,却往往都是一些负面消极的东西:贪污腐败、权钱交易、弄虚作假、司法黑洞,一方面一些有权有势的党贵们欲壑难填,竭尽敛财之能事,一方面国际金融炒家们在中国这只肥羊身上插满了吸管,中国人民积累几十年的血汗钱被轻而易举的吸干榨净。而就社会制度,更确切的说是政治体制而言,似乎完全不像我们从小受到的教育那样,有着非此即彼的区别,我们这个号称为社会主义的国家已经不再是按马克思对生产资料所有制形式的区分所定义的那种了,而这似乎又没什么不好......这么多大是大非的问题看起来都很矛盾。
生活在这个种种矛盾并存、价值观混乱的时代,很多时候我们弄不明白什么才是主流和趋势,甚至也不清楚哪些事情是被鼓励的哪些是法律、道德甚至常识所不允许的。
带着困惑,阅读了一些关于中国社会现状、由来和反思的东西,希望能收获一些判断是非的依据和能力。最终却明白为什么要推崇“摸着石头过河”,因为各种原因(历史的、文化的、政治的、经济的、国际环境的、生产力水平和科技进步的)所造成的现状,对现代中国似乎没有一种现成可借鉴的康庄大道可走,想要发展,“与时具进”就绝不是一句空洞的口号。
有一本书很值得阅读,《十亿消费者》,最初在和菜头的博客里看到介绍,后来三口气读完。这并不是一本教中国人如何奋发自强的书,相反,这是一个在中国生活工作多年,对中国社会和各种现象有着深刻认识的华尔街记者所撰写的用来告诉美国商人如何在中国经商与中国人打交道的书。正如作者和译者(乱翻书)所言,这样一本书是不可能在中国出版的,并非因为书中有何“夸张”或“反动”的言论,而是由于书中所记之事大多发生在并不久远的过去,其中一些 人物依然活跃在领导层。作为一名记者,作者基本客观的记述了这些人和事,非常专业,每每从历史到现状,阐述和分析得非常透彻,从中我们可以了解很多虽然发生在我们身边,但却很少知晓来龙去脉的事情。同时很多对现代中国人和中国文化中的弊病的看法一针见血,很多观点是作为一个中国人很不愿意看到但却完全无法否认的,有一些部分我想我是红着脸读下来的。在这一点上,和鲁迅的阿Q正传有着类似的功效。
感谢译者乱翻书,是他的高质量的翻译工作,给我们呈现了这样一本指出我们问题所在并且能够帮助我们自省的书。
从古至今,中国从不缺少思考者和实干家。我们陷入低谷时,他们努力给我们自信和向前的动力;我们爬上高峰时,他们给我们提供警示和方向。这样的人可能包括鲁迅这样冷静深刻的学者,或是袁隆平这样热情睿智的实干家,但更多的时候是那些我们并不了解但却通过不同方式从不同角度默默奉献的普通人。我相信《十亿消费者》的译者和那些关注此书并有所思考的中国读者,同样都是怀揣着一颗拳拳爱国的热心,希望客观的了解我们自身的问题,希望通过自身的努力为社会和国家作出些许贡献的人们。
再看北京奥运会,对现代中国社会,可以把它看成一场盛大的仪式,既是一场对过去成就做总结的庆功会,也是一杯为全民族壮行的上路酒,任重而道远,我们的振兴之路也许才刚刚开始。
愚人杂感,杂记之。
2008年8月9日星期六
2008年8月8日星期五
开幕式观感
1. 最后这个火点得太拽,主角连个正脸都没给,更主要的,看了半天也没弄明白那是个夸父追日还是嫦娥奔月。
2. 作为世界上人口最多的国家,发挥自己的优势,利用人海战术,开场的击缶和活字表演确实震撼!一些场景很有想象力,给人留下深刻印象,比如远远走来的烟火大脚,人与科技共同完成的巨幅画卷,平地升起的巨大星球(居然还是演唱主题曲的舞台)等等。
3. 某些方面,导演水平有待商榷。比如镜头的切换,总是感觉很别扭,该有宏大场景的地方弄得小里小气,该由长镜头表现的烟火弄得很突兀,该表现细节的地方没有 重点(居然还有一个将近10秒钟不知道是谁的脚的镜头)。总之,和煞费苦心的策划与表演相比,摄像导演得太一般了。
4. 最失败的就是那个假象的借助全场观众手势放飞白鸽的环节,领导也好,观众也好,中国人也好,老外也好,都在闷热中坐了五七八个小时了,没有强制的要求,有几个愿意劳什子连续不断的做那么拽的手势,用脚趾头想也该意料到。
5. 运动员入场时,观众的欢呼声很能听出些趣味,印象比较深刻的有中华台北(欢呼声仅次于东道主),韩国(也许是我听错了,但分明有嘘声在内),伊拉克(同情弱者?),美国(为啥没见到戴口罩的^_^)和中华人民共和国(东道主)。
6. 不记得从前的奥运会是否有人墙把运动员隔离开了,篱笆墙们从运动员入场蹦跶到结束,这大热天的,谁家姑娘谁不心疼啊。
7. 大腕云集,胡总带领下的中央领导们自不必提,布什普京盖茨一干人等也都扎在人堆里冒着白毛汗,让在家喝着啤酒吹着凉风的我们看起来很爽。江伯伯出镜率蛮高的,可怜了身旁那位年事已高的前任国母了。
8. 之前看过一些评论,说开幕式表演很张很艺谋,整体来看,确有此感。不过个人认为这不是什么坏事,原本想象开幕式表演中会有很多迎合世界各国口味的元素,实 际上并没有。感觉上,基本上体现了具有张艺谋特色的中国风格,张艺谋的未必是最好的,但只有民族的才是世界的,在这样一个向全世界展示的舞台上,只有把那 些我们自己看起来老生常谈甚至土的掉渣的东西拿出来,才有价值。
9. 不能完全否定东道主的服装设计,至少全场一眼就能分辨出身着红黄服装的中国运动员来。“西红柿炒鸡蛋”,之前听过很多人这样评论,总觉得是鸡蛋里挑骨头, 太夸张。看了以后才明白,没有比这更准确的形容了:)。我们有一个很大的问题,就是总是想方设法给事物赋予太多的象征意义,队服为什么一定要和国旗的颜色 一致?表演为什么一定要2008个人?开幕式为什么一定要安排在2008-08-08 08:08?为什么要选“五个”福娃做吉祥物?有谁能清楚的说出每个福娃头上那堆奇形怪状的东西都象征着什么来着?
天公也算作美,热是热点,至少没有出现传说中的中到大雨;这么大型的仪式,或多或少有点不尽如人意的地方也都可以理解。无论如何,北京奥运会的开幕式算是圆满结束了,跟着操了好几年心的全国人们也都可以松口气了。接下来,回到正题上,看比赛吧。
2008年7月30日星期三
给自频道找找茬
keso 很生气,因为“自频道版权问题”,北城更关注对“博客热情”的影响,还有讨论自频道成为“超级网络媒体代理商”可能性的,还有加问号的“新媒体自掘坟墓的 又一力作”,讨论的角度很多,我看多数是因为魏武挥介绍自频道的blog写的挺张扬。咱草根没资格也没兴趣参糊大佬们的口水仗,不过既然惹得咱花时间去体 验了,不挑挑毛病找找茬心里难受。
1. 不管定位多玄乎,说到天,自频道不过就是一个带编辑功能的rss聚合而已。
2. 既然首先是个rss阅读器,就得经得起比较和推敲,不要以为加个编辑功能再放上广告就是“新媒体商业”了,还是先别太看得起自己,至少基本功能和用户体验 上先和流行的rss reader看齐吧。反正我的使用体验是,不论从哪一点来看(内容输出、feed的组织和管理、阅读体验、收藏、标识、推荐等等)都比不上任何一个主流的 rss阅读器(google reader, 鲜果,抓虾)。
3. 列举几点感觉不好的体验:
* 所谓内容就是item的正文摘要,基本上没有能全文阅读的(除了那些原本就是输出几十字摘要的feed),就这样还放个“展开阅读”和“缩进文章”的开关,挺搞笑。
* 对item的编辑,居然也是“所见即所得”的,也就是只能编辑刚刚看到的摘要(还带着省略号的),我试来试去,最后发现真要编辑就只能回到原文处copy全文再paste过来,貌似很高级的操作哦。
* 看得出来为了显示摘要,程序做过一些处理,因为“摘要”居然不只是正文的开始的百八十字,不过显然处理得不到位,凡是经过处理的原文的格式信息全丢了,乱糟糟一大片,没人会有耐心去分辨。
* 像feedburner这种被墙封了的源,通通都是验证失败。拜托,你是做数据采集的,稍微有点专业手段好不好。鲜果抓虾从来没有这样的问题。
* 还是源的抓取,太慢了,慢也不要紧,我等你去抓的时候至少给我个提示吧,害得我傻了吧唧的以为输入有误,折腾了半天,不知道自己做错了什么,这种用户体验也太业余了。还是先向别人学习一下再说吧。
* 所谓“版权问题”根本是没法保证的,原始feed里一些重要信息很多没有显示出来,我可不是瞎说,专门拿rss文件对照的,比如digg的rss,作者、 分类、评论计数等信息都有,显示出来都没了,可能是因为digg的rss输出有自定义标签吧,不过这不是不显示原文作者的理由。
* 几乎每个原始feed都有pubDate的,不过在自频道里,所有的输出都是按"分享时间"来排序的,还大喇喇的在每个feed上方标识出时间和日期,我今天导入的feed,所有item的时间都是今天,而且没有地方能修改排序,看着真难受啊。
* 基本上这是我用过的最差的rss阅读器之一。如果算上编辑和分享功能,就是我用过的最差的带编辑功能的rss阅读器了。
* 我看到“自频道”旁边的“beta”字样了,可gmail也一直是beta。这种beta做个startup不会有人说什么,不过blogbus好歹也算 有点口碑的BSP了,何况“自频道”还炒得这么凶,这种水平的产品拿出来宣传实在有点脸红。你让我来做我可能做得还不如你好,可我是草根,我也没吹牛。
4. blogbus是BSP,作为provider,它应该是内容的生产者,优势在于已有的blog平台、用户和口碑。而“自频道”基于rss聚合,本质上,它是rss的消费者。虽然都是针对rss,但并不是一码事。就好像你是一个汽车生产商,但并不意味着你一定就是一个好的车手。
5. 如果真的要做一个自媒体,现有的主流的在线rss reader更有优势,比如鲜果和抓虾,几乎用不着大动干戈,给每个item提供一个edit功能就完全可以了,可以借shared items功能输出经过用户编辑过的rss,阅读就在现有的reader或任何其他地方(只要不是现在的自频道)。或者,假想一下,给热文之类提供 wiki功能,用户共同编辑热文(如果有必要的话)再输出,这样既避免内容重复,又保证原文质量,如果再加上一些人工分类编辑的功能,那才叫真正的新媒体 自频道。
6. rss(包括众多衍生者)被发明出来的本意是提供一种开放的数据结构,将信息结构化的,便于在internent上传递,便于信息“忠实”地在生产者(如 blog)和消费者(如rss reader)之间传递。我觉得“忠实”很重要,就像正规的电子文档都用pdf,因为pdf的内容一般来说是不容易被修改的。当然这是一种防君子不妨小人 的约定俗成的办法,如果有人改动了原始pdf公文的内容并再次分发,就叫“篡改”。我理解rss也是同样的意思,原样传播是正常的,你当然可以去编辑和修 改然后重新发布,不过在我看来,这就是篡改,是没有公信力的。别人没这么做并不是别人不能,大概是不屑吧。
7. 假设如其所愿,“自频道”各方面都就绪了,结果可能就像很多人预料的那样,“突破了自动抄袭的技术壁垒”,“成为垃圾站的温床”,可以预料到的是:大量重复的、雷同的内容层出不穷,有价值的信息被埋没在更多的垃圾里,这是对用户耐心的考验,而且几乎注定要失败的。
8. 按“自频道”宣传的本意,不过是要给人们提供一种批量的自动导入和编辑内容的方法,如果人们愿意花点时间(比如去适应“自频道”糟糕的用户体验的时间),利用现有的互联网工具,谁都可以创造出更方便的“自频道”。比如:
* 使用yahoo pipes(或ms的popfly或google mashup等mashup工具)去处理rss源,都是很cool的东西,不必被流程图模样的block吓到,它做成那样就是为了给不懂编程的人来用的, 只要习惯了他们的用法,获取rss源的途径几乎是没有限制的,处理rss源的方法也几乎是无限制的,有限制的只是想象力。
* 使用任何一个online rss reader订阅自己制作的rss源,或者在igoogle,netvibes上展示你的源。定制的源可随时根据需要去修改,或者根据不同需要制作任意数量的源。
* 如果真的需要编辑rss内容(为什么?),如果恰好懂一点编程,去google app engine上申请一个app,做个导入rss的接口,做个list和form,或发挥想象力做更多的事情。
* 这些都是随便提提,可选择的方法远比这些多。对于自频道的假想用户,上述都是可以自己做到的,不需要花一分钱,需要的可能只是花点时间去了解和学习一下,DIY的感觉比被人忽悠好得多。
2008年7月17日星期四
Deploy Ruby On Rails App on Heroku - A Simple Guide for Windows User
Ruby on rails is popular due to its practical methodology, framework and tools, rather than an extensive acceptance by web hostings(like php). If you've tried to deploy a ror application on one of most of popular web hostings (those promised to provide 1500+G space, 3000+G/mo file transfer), you may agree with me, because they always limit you so much. Of course you can buy a dedicated server, but how about just publish a toy project before pay anything? Heroku is a good choice.
As an online service, heroku did some wonderful things, for example, an irb, an ror editor, an rails console, a gem manager, and so on. The point is, they are all run in browser, even without any rich client support (I believe it will be practically used if is implemented in a rich client). You can check these features at http://heroku.com/features.
An important feature is about "work locally". For linux user, all the necessary tools are native. For Windows user, a few additional resource are required. Here's a simple guide for Windows user.
Heroku supports two ways to transfer source code between local and server,
* A simple way is "import/export", "import" means upload a compressed source code package in .tar.gz, it's easy on linux. For Windows user, a convenient approach is to use 7z. For example, your app folder is "myapp", compress it into "myapp.tar" using 7z, then compress "myapp.tar" into "myapp.tar.gz" using 7z. Upload "myapp.tar.7z" to an existed app on heroku, done! "export" means download a .tar.gz package from heroku, uncompress it, work locally.
* The other approach is more practical. using Git and a "heroku" gem for source control.
** Git is yet another source control tool, a substitute for SVN in ror world.
** GitHub is a Git repository, Rails itself and many other ror source are currently hosted there.
** "heroku" gem is a tool which helps to manage source code hosted in github, including source control and publish source code on heroku.
** Git is native in linux, for Windows user, there are two options: Cygwin and msysGit, the former is a comphensive linux simulator on Windows. The latter is an unofficial Git implementation on Windows.
** Download either of them (they are similar if you just need Git), and install. For Cygwin, remember to select git manually.
** msysGit provide a GUI interface for Windows user, Actually, I don't think it is better than its bash shell interface. So, even as a Windows user, you'd better to know a little about bash shell.
** Open msysGit bash shell from start menu, like this:

** Register an account at github.com, the "Free" one is ok, remember the email you used (e.g. name@example.com).
** Generate a ssh-key. In the opened msysGit bash shell, input following command:
ssh-keygen -C name@example.com -t rsa
In the following steps, it will ask to provide path and passphrase, use default by pressing enter (or change them if you know what you are doing).
** Get your SSH Public Key. Input following command in shell:
cat .ssh/id_rsa.pub
The SSH Public Key (lines of strange charactors) will display in the shell, copy them (how? just like what you did in a Windows cmd shell), and paste into Github account (go to https://github.com/account, login if necessary, there's a textbox titled with "SSH Public Key"), then click "Update Keys".
** The last thing is to get "heroku" gem: "gem install heroku"
** Everything is prepared, go to see heroku's demo, or follow the next simple steps to start to develop and deploy a ror app on heroku:
- Open msysGit shell, input "heroku list". which lists all your existed rails apps on heroku;
- Input "heroku create myapp", it helps to create skeleton of a ror app named "myapp" (I guess it run "rails myapp" for you on heroku server), you can access http://myapp.heroku.com directly (of course you should make sure "myapp" is not an existed app name on heroku), a ror welcome page is waiting for you.
- input "heroku clone myapp", make a clone of "myapp" for local development. First time, it will ask your email and password which you've used to register in Github. (BTW, in msysGit shell, change directory to the location you want to put your local app. It looks like "cd /d/apps/", which equals to "cd d:/apps" in windows cmd shell. Interesting to both linux or windows user:) )
- if everything ok, you could edit your rails app with your favorite editor or IDE. (I tried Netbeans and e-texteditor, both ok.)
- Make some changes to your local app, (for example, generate a scoffold, or modify routes mapping in config/routes.rb, these will take effect after you push them to heroku), run server and test it locally. If everything ok, check in (and publish) your local source code to heroku (Github) by following commands:
- 'git add .', adds the current content of new or modified files to the index, note you should in your rails app folder;
- 'git commit -m "comments about this checkin" ' , stores the current contents of the index in a new commit along with a log message from the user describing the changes;
- 'git push', updates remote refs using local refs, while sending objects necessary to complete the given refs;
- ok, now try to access your rails app on heroku by accessing http://myapp.heroku.com,all the local changes work. 'git push' does some great things: check in source code, publish updated source code on heroku, rake db:migrate (if there's migration), restart rails server (let the changes to routes.rb takes effect), maybe include other necessary work. Great!
- Git is similar to SVN,except above options, you can do checkout, diff, merge, mv, rm and so on. Check helps as you need.
- In fact, all the above command can be used in Windows cmd shell if you setup msysGit as need. And all these commands can be used in Cygwin either.
As a ruby on rails fan, you really should take a tour through heroku, there are so many interesting features except "work locally". After deployment environment getting done as above, you are ready to publish your toy project to the world.
2008年7月13日星期日
How many things to learn?
I was/am a MS tech fan due to my job and intrerest. For a long time, I was eager to learn everything about .net. For examples:
* There are more than 200 tech books on my bookshelf, Wrox, O’Reilly and others. My wife named Wrox area as “red-light district”, and O’Reilly area as “Zoo”;
* I collected webcasts and ebooks as possible as I can find. and burn them into DVD;
* There are hundreds of feeds in my rss reader, I subscribed all the popular blogs about .net, from MSDN to Scottgu, from Codeplex to Rob Conery;
* I browse Codeplex “tag by tag”, download all the pop projects;
Unfortunately, my interest was not just about this. I was interesting in OO/P/AD, design pattern, TDD, refectoring, UML/RUP, project management, agile project, enterprise framework, networking, web design, database,java, c++, python, javascript, even ERP for a while. Recently, the terrible interest spreads to ruby, ruby on rails, then linux server when I decide to deploy my toy project, then virtualization when I decide to setup my own vps of linux…
Sounds great, right? The truth is…
* half of books on my bookshelf were not touched,
* webcasts were reviewed when they were just downloaded, but never be opened after burned,
* there are always 5000+ unread feeds in my rss reader, sometime I will mark them as “read”, but the number came back soon;
* reading source code is good, but the projects which were really carefully researched are not much.
As everyone can guess, I may be an expert on “how many things do you know?”, but not an expert of each of the listed parts, although my interest has taken most of my free time :( . Sound despressed.
Write this because I read a blog “Do you have the time to learn everything“. I agree with some of its points. It’s definitely impossible to learn everything, people should has a limited learning list with prioritization, people should learn to make choice first. I know this from beginning, but when I start to be interesting in something, I feel this is the most important. what a fool!
Life is limited, knowledge is not. But if learning is as fun as playing game or watching TV, just do it.
That’s the words to comfort myself.