Archive for the '技术' Category

各种编程语言的对比

别上火,这可不是各种BBS里面那种炒的脸红脖子粗的”Java与C++”哪个更好,”Ruby会不会取代Java”类似的帖子,而是偶尔看到的一篇用女人来比喻编程语言的文章,对与不对放在一边,挺逗的。
Java - Bulky with big boobs. Does everything you want but slowly. Hardly complains about how you want it in bed. The kind of woman who is not sexy, but gives you amazing satisfaction. You have tried several women, but this one doesn’t get off your mind so you always go back to her.
Ruby on […]

Popularity: 54%

微软著名的C++大师Herb Sutter在2005年初的时候曾经写过一篇重量级的文章:”The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software“,预言OO之后软件开发将要面临的又一次重大变革-并行计算。
摩尔定律统制下的软件开发时代有一个非常有意思的现象:”Andy giveth, and Bill taketh away.”。不管CPU的主频有多快,我们始终有办法来利用它,而我们也陶醉在机器升级带来的程序性能提高中。
我记着我大二的时候曾经做过一个五子棋的程序,当时的算法就是预先设计一些棋型(有优先级),然后扫描棋盘,对形势进行分析,看看当前走哪部对自己最重要。当然下棋还要堵别人,这就需要互换双方的棋型再计算。如果只算一步,很可能被狡猾的对手欺骗,所以为了多想几步,还需要递归和回朔。在当时的机器上,算3步就基本上需要3秒左右的时间了。后来大学毕业收拾东西的时候找到这个程序,试了一下,发现算10步需要的时间也基本上感觉不出来了。
不知道你是否有同样的经历,我们不知不觉的一直在享受着这样的免费午餐。可是,随着摩尔定律的提前终结,免费的午餐终究要还回去。虽然硬件设计师还在努力:Hyper Threading CPU(多出一套寄存器,相当于一个逻辑CPU)使得Pipeline尽可能满负荷,使多个Thread的操作有可能并行,使得多线程程序的性能有5%-15%的提升;增加Cache容量也使得包括Single-Thread和Multi-Thread程序都能受益。也许这些还能帮助你一段时间,但问题是,我们必须做出改变,面对这个即将到来的变革,你准备好了么?
Concurrency Programming != Multi-Thread Programming。很多人都会说MultiThreading谁不会,问题是,你是为什么使用/如何使用多线程的?我从前做过一个类似AcdSee一样的图像查看/处理程序,我通常用它来处理我的数码照片。我在里面用了大量的多线程,不过主要目的是在图像处理的时候不要Block住UI,所以将CPU Intensive的计算部分用后台线程进行处理。而并没有把对图像矩阵的运算并行分开。
我觉得Concurrency Programming真正的挑战在于Programming Model的改变,在程序员的脑子里面要对自己的程序怎样并行化有很清楚的认识,更重要的是,如何去实现(包括架构、容错、实时监控等等)这种并行化,如何去调试,如何去测试。
在Google,每天有海量的数据需要在有限的时间内进行处理(其实每个互联网公司都会碰到这样的问题),每个程序员都需要进行分布式的程序开发,这其中包括如何分布、调度、监控以及容错等等。Google的MapReduce正是把分布式的业务逻辑从这些复杂的细节中抽象出来,使得没有或者很少并行开发经验的程序员也能进行并行应用程序的开发。
MapReduce中最重要的两个词就是Map(映射)和Reduce(规约)。初看Map/Reduce这两个词,熟悉Function Language的人一定感觉很熟悉。FP把这样的函数称为”higher order function”(”High order function”被成为Function Programming的利器之一哦),也就是说,这些函数是编写来被与其它函数相结合(或者说被其它函数调用的)。如果说硬要比的化,可以把它想象成C里面的CallBack函数,或者STL里面的Functor。比如你要对一个STL的容器进行查找,需要制定每两个元素相比较的Functor(Comparator),这个Comparator在遍历容器的时候就会被调用。
拿前面说过图像处理程序来举例,其实大多数的图像处理操作都是对图像矩阵进行某种运算。这里的运算通常有两种,一种是映射,一种是规约。拿两种效果来说,”老照片”效果通常是强化照片的G/B值,然后对每个象素加一些随机的偏移,这些操作在二维矩阵上的每一个元素都是独立的,是Map操作。而”雕刻”效果需要提取图像边缘,就需要元素之间的运算了,是一种Reduce操作。再举个简单的例子,一个一维矩阵(数组)[0,1,2,3,4]可以映射为[0,2,3,6,8](乘2),也可以映射为[1,2,3,4,5](加1)。它可以规约为0(元素求积)也可以规约为10(元素求和)。
面对复杂问题,古人教导我们要“分而治之”,英文中对应的词是”Divide and Conquer“。Map/Reduce其实就是Divide/Conquer的过程,通过把问题Divide,使这些Divide后的Map运算高度并行,再将Map后的结果Reduce(根据某一个Key),得到最终的结果。
Googler发现这是问题的核心,其它都是共性问题。因此,他们把MapReduce抽象分离出来。这样,Google的程序员可以只关心应用逻辑,关心根据哪些Key把问题进行分解,哪些操作是Map操作,哪些操作是Reduce操作。其它并行计算中的复杂问题诸如分布、工作调度、容错、机器间通信都交给Map/Reduce Framework去做,很大程度上简化了整个编程模型。
MapReduce的另一个特点是,Map和Reduce的输入和输出都是中间临时文件(MapReduce利用Google文件系统来管理和访问这些文件),而不是不同进程间或者不同机器间的其它通信方式。我觉得,这是Google一贯的风格,化繁为简,返璞归真。
接下来就放下其它,研究一下Map/Reduce操作。(其它比如容错、备份任务也有很经典的经验和实现,论文里面都有详述)
Map的定义:
Map, written by the user, takes an input pair and produces a set of intermediate key/value pairs. The MapReduce library […]

Popularity: 100%

CPPUnit Lite

CPPUnit Lite是一个非常简单的C++ UnitTest库,比较适合做一些小型的UT。基本概念来说,也是”期待与实际相比较“的经典JUnit模式,不过如何在C++上实现还是比较有意思的。
1) Sample
int main(int argc, char **argv)
{
    if(argc == 0)
        printf("%s", argv[0]);
    TestResult tr;
    TestRegistry::runAllTests(tr);
    return 0;
}
 
TEST(AddTest, Caculator)
{
    int iResult = 1+1;
    CHECK(iResult==2);
}
TestRegistry::runAllTests是一个静态函数,它会执行注册的所有测试用例。问题是,下面的测试用例(AddTest)是怎么加进TestRegistry的呢?
2) How it works?
class Test
{
public:
    Test (const SimpleString& testName);
 
    virtual void    run (TestResult& result) = 0;
 
 
    void            setNext(Test *test);
    Test            *getNext () const;
 
protected:
 
    bool check (long expected, […]

Popularity: 35%

前一段,Blogsphere里面关于WebOS的大讨论甚是激烈,如果说Web2.0的时代,整个Web将会是一个大大的WebOS的话,将各个应用和服务联系在一起的就是两个东西:

RSS
Web Service

以前RSS说的太多了,今天就来说说Web Service。Mac OS最新的Tiger里面的Dashboard,里面的每个小Widget都是由简单的HTML、CSS以及Web Service组成的,你可以用这些Widget来查询股票,天气,以及其它很多事情。这些Widget的核心组件,就是调用外部的Web Service。我以前曾经说过的Google IG、Live.com中的Gadget,也都是这个道理。
说到Web Service,就不能不说到RPC(远程系统调用)。所谓的远程,包括进程外,甚至本机外,经典的RPC协议包括DCOM、CORBA以及ICE等等。我觉得,对于RPC来说,最重要的就是两点:

将过程调用的参数和返回值序列化(Serizialize)成一系列的数据 - marshalling,中文翻译成“列集”这个怪怪的名字;
用某种方式来传递这种数据。对于进程外RPC来说,可以采用共享内存、管道等等。而不同机器之间,则多是用专署协议了,比如DCOM和CORBA,现在有更轻量级的ICE。

Web Service解决以上两个问题的办法是:

采用XML来进行数据的Marshalling;
采用HTTP来进行数据的传递(SOAP的新标准中也支持了其它协议,比如SMTP);

记着2000年我刚刚接触Web Service的时候,对采用HTTP来进行数据传输这点很是不以为然,觉得穿透防火墙这些Feature绝对是宣传上的噱头。那时的自己还醉心于对桌面平台的COM、DCOM以及CORBA的研究。现在我慢慢认识到,采用XML(明文、可读)、HTTP(最常用的网络协议),绝对是Web Service得以成功的两个重要的因素。
现在比较流行流行的Web Service主要有三种,分别来说说:
1)SOAP
SOAP,全名是Simple Object Access Protocol,是Microsoft提交给W3C的Web Service协议。我觉得SOAP的两个最大的好处是:

协议的可扩展性(Extension Mechanism)
良好的工具支持

SOAP的消息称为一个SOAP Envelope,包括SOAP Header和SOAP BODY。其中,SOAP Header可以方便的插入各种其它消息来扩充Web Service的功能,比如Security(采用证书访问Web Service),SOAP BODY则是具体的消息正文,也就是Marshall后的信息。
SOAP调用的时候,也就是向一个URL(比如http://ws.invesbot.com/stockquotes.asmx?WSDL)发送HTTP Post报文,调用方法的名字在HTTP Request Header SOAP-Action中给出,接下来就是SOAP Envelope了。
服务端接到请求,执行计算,将返回结果Marshall成XML,用HTTP返回给客户端。
SOAP的工具支持非常好,比如在.NET里,可以用WSDL.exe非常方便的为一个Web Service生成本地Proxy(Proxy模式),这样,你的程序就像调用本地API一样了,而由Framework为你完成Marshall和传送的工作。
2)XMLRPC
XMLRPC ,我记着看过一段Don Box的采访,他说当时Microsoft费了7年的时间(大概,记不清楚了)才成功的把SOAP提交给W3C,而Dave Winer(眼熟吧,RSS’s Father)借鉴SOAP实现了一个更轻量级的协议,那就是XMLRPC。以前曾经大概看过XMLRPC,XMLRPC就是SOAP的简化和改进,比如说:

Marshall类型的支持有限
取消HTTP Header中的SOAP Action,而将Method Name也放到XMLRPC的Body中
传送的XML信息中没有Header,只有Body。

XMLRPC相比于SOAP最大的优势就是它的简单,弱点就是扩展性弱,另外,工具支持也不如SOAP那般正规,感觉起来,一个像正规军,一个像游击队。不过,游击队才有作战灵活的特点 :P。
XMLRPC在社区中非常流行,我这篇Blog是在Writely写的,通过WordPress的XMLRPC接口发布到我的Blog上。
3)REST
REST - Representational State Transfer, 是Roy Fielding的博士论文中提出的概念,其实,与其说REST是一种Web Service协议,不如说REST是一种Web based软件架构,一种基于Resource State的服务访问架构。
通俗的将,可以用你访问我的Blog的过程来描述REST的工作流程。当你访问我的Blog首页,其实就是对我的Blog的一个资源访问,那么Web Server会将这个资源的Representation返回给你,也就是我的Blog的首页的HTML。当你点击了这个HTML中的一个link,比如某篇Blog,你实际上就又对另一个资源发生了请求,Web Server会将新的资源Representation以HTML的形式发送给你。
REST的参数传递是采用URL […]

Popularity: 54%

Feedsky新版

欣欣上周MSG我让我看看Feedsky的新版,初一看,吓了一大跳,ASP.NET竟然变成了PHP,这个变化实在不小。且不说这两种技术孰优孰略,看来Feedsky是下了功夫要重新架构一番。
首先,界面比以前清爽整洁了许多,也规范了很多。其实我在Feedsky刚出来的时候就注册了一个,不过一直没有公布,其中的一个原因就是用户名和密码的输入框大小不一样(还是没对齐?忘了),虽说是小问题,但是这样的小问题往往能反映一个团队的实力和态度。细节决定成败!
再说功能上的减法,确实,烧制和统计是RSS Burner的两个最基本也是最重要的功能,Feedsky删除了不少用处不大的噱头,这样挺好,减少了系统的复杂性。问题是,现在没有原因让我放弃Feedburner而转而使用Feedsky,因为没有特殊的地方。差异化生存,作为一个后来者,更要有超越前者的优势才行。加入本地Service(比如豆瓣,土豆)合烧是最容易想到的一个可以改进的地方。
Crawler的问题解决了,访问的时候已经带上了ETag,没有仔细分析Log,不知道对于其它Feed Platform应该遵循的规范考虑了没有。URL的重新设计也更加合理,feed.feedsky.com/user明显比www.feedsky.com/user更好。
团队Blog,终于加上了,这可以Web2.0服务的标志啊:P。我订阅了Feedburner的Blog,可以感觉那是一个充满激情,而且技术非常优秀的团队,希望欣欣和他的同事也能Build up一个这样的团队。
最后说说一些问题:

还是一些细节方面,比如Login.php Load出来后,焦点应该放在Username输入框;
Feed预览,显示英文是"an RSS feed powered by Feedsky";
比较严重的问题,登陆页面没有采用HTTPS。对于WEB应用,如果不能很好的保护PII(Personal Identity Information),一切都明文的传来传去,非常危险;
安全设计考虑的还不够,比如,举两个简单的例子。第一,Login的时候,输入不存在的用户名,会显示"对不起,用户不存在",输入存在的用户名和密码,会显示"登陆失败!",有时候,给用户的信息不是越Detail越好,登陆系统就是这样的例子。因为给用户信息的同时,你也把这些信息暴露给了Hacker,通常的设计要求,这时候的信息要尽量简单一致(Generic Error Messages),尽量少暴露系统信息;第二,连续N次Login错误后,没有任何方法加以限制。通常常用的方法是增加图形验证界面,或者甚至禁止继续试探。
功能上,Burn后还不能完全按照时间排序。

总的来说,还是不错的,希望Skyer们越做越好,也正好公布一下我的Feedsky的Feed:http://feed.feedsky.com/dreamwords。
Popularity: 72%

Popularity: 72%

近日思考四则

最近忙的晕头转向,直接的后果是ToRead List已经堆积如山,在这个信息过载的时代,我唯一的办法就是,放弃。
把在思考的一些东西,留在这里,本来都想仔细研究然后消化的,看来还是放在以后吧。
1) Live Clipboard
Ray Ozzie的最新大作,其实不能算新,都已经快2个月了。下面是一些Demo:

Simple Web page-based Demo
ScreenCast of Live Clipboard Demo

一定要亲自试试第一个Demo,你会被震撼的。再看看用来实现的技术,JavaScript + XML,不由得让我又想起了AJAX。相同的是,简单的、已存在多时的技术,却能带来非凡的体验。不同的是,只要你运用AJAX,用户就能感觉到,而Live Clipboard,只有大家都认可并且运用,才能更大发挥出它的价值。这也给它的前景蒙上了一层阴影。
Ray Ozzie的一句话让我印象很深:

I believe RSS has the potential to be the “UNIX pipe of the internet”, and that one of the simplest and most pervasive “mesh” needs that many of us have is to provide connections for things such as contacts, […]

Popularity: 76%

Windows RSS Platform Preview

曾经翻译过Longhorn中的RSS,那是Microsoft正式在Longhorn中加入RSS支持的白皮书。大概2个星期前吧,看到了Microsoft RSS Team Blog上面提到的Screen Saver的例子,才发现随着IE7 Beta2的发布,已经可以看到这个RSS Platform了。
大概看了一下整个文档,然后用C#编了个简单的小程序试了试,还不错,API还算合理好用,这下Desktop平台的对RSS支持变得非常容易了。
Windows RSS Platform的Online Reference在这里。

Subscribe to new feeds, and enumerate existing subscriptions.
Easily access properties of feeds (channels), feed items, and enclosures.
Manage and organize feeds into folders.
Listen for and respond to feed and feed folder events.
Check the status of the background Feed Download Engine, or modify settings.
Normalize the […]

Popularity: 58%

也说 Adapter Pattern

米嘉刚发了一篇Extension Object/Interface模式,周五很忙,但还是抽空看完了。不错,把Eclipse里面究竟为什么用Extension Object以及为什么用讲的很清楚。我自己非常喜欢看各种关于设计模式的书和文章,每一次读都会有不同的认识。终于今晚有时间,就也来说说Adapter。
按照GoF的说法,Adapter的意图是将一个类的接口转化为我们需要的其它的接口。这通常发生在这种情况下,比如我们拿到某个软件包甚至源码,但是我们不能修改她的接口,或者修改存在着潜在的风险。
其实,我觉得这不是最关键的问题,关键的问题是我们为什么不能改变自己的接口?为什么不干脆就直接使用软件包的接口算了?
仔细分析一下,其实Adapter算是我们平常用的最多的一种设计模式,可能甚至多到连你自己都没有意识到你是在用Adapter。我来举个例子,也是Adpater运用的一种最典型的情况:多态编程。

在XerdocDS中,对硬盘所有文件的扫描都是通过IParser的多态调用来进行解析的,这个接口是我们不能改变的。而事实上,很多具体的Parser,都有现成类可用,只不过接口和我们的不一样,比如上面的HTMLParser。这就需要用Adapter来适配一下。
在这种多态调用的结构下,我们都是针对接口来进行访问的,你不可能更改整个体系的接口,所以,必须要采用Adapter来进行适配。
再深究一下,可以发现,这种Adapter是针对对象的适配,也就是在对象的层面上来扩展功能。如果我希望给类扩展接口呢?很简单,多重继承(C++)就派上用场了。
小到这样的类结构设计,大到整个软件架构,Adapter的运用也非常广。我现在在做的一个Web Service,存在两个版本,由于中间一些比较大的变化,新版本已经几乎是一个完全新的Service,从接口到内部算法,都做了很大的改变。这样,新的Service中的接口已经和老版本完全不同,但是,我们还是有很多老的用户在使用老的Web Service接口,这就需要一个Adapter,在内部起一个适配的作用,以便来达到和老版本的兼容性。
可以说,上面举的例子都是Adapter比较经典的用法,本质上说,就是让由于接口的不一致而不能在一起工作的类,在一起工作的一种模式。
Eclipse把这种模式更加发扬广大。Eclipse的一大目标就是要无限扩展。除了插件的部分,扩展现有类的接口也是很重要的一个部分。很显然,我们不能修改现有类的接口,那么,如何给一个现有的类动态的增加新的功能呢?Decorator可以在相同接口下添加其它功能,而Adapter就可以添加其它的接口来添加需要的功能。这样,即可以无限扩充了系统的功能,又保证了系统现有类的纯洁性,也就是单一指责原则。不会造成各种正交功能的对类的污染。
在Eclipse中,所有希望在将来被扩展的类,都需要实现这个接口。
public interface IAdaptable { 
    public Object getAdapter(class adapter);
}
这和上面的需求正好相反,这里不是为了满足现有不匹配或者兼容的需求,而是为了满足未来可能的需求,而使用Adapter。叫Adapter似乎不太合适,叫Extension比较合适,呵呵。好像Eclipse早期的版本里面也确实不叫IAdaptable而叫做IExtensiable吧。
这样带来的问题就是未来的需求会很多,可能会有各种各样的Adapter,如何更好的管理、调用这些Adapter?Eric Gamma的AdapterManager和IAdapterFactory就派上了用场。
IAdapterFactory用来生产某些种类的适配器,而这些Factory和具体需要适配的类的关系由AdapterManager来维护,非常清楚。只需要在系统启动的时候把AdapterFactory都注册到AdapterManager中,然后在需要的时候来进行查询相应的查询即可,具体实现可以看看米嘉的文章。
之所以做出这样的设计,也是和OO设计的一些基本原则密不可分的,比如"针对接口编程"原则,比如"单一职责原则"。其实,这些原则也都是和现实世界密不可分的,比如针对接口编程对应到现实生活中,也就是针对标准进行设计。这样,各家的各种产品才能在一起工作。Adapter的经典例子便是不同制式的电源插销,去香港出差的时候,如果你不带一个大转小的Adapter,肯定无法进行工作:P。
最后举个简单的例子,比如Eclipse的SWT有一些UI元素,Button、List等等,你现在需要做一个Save All功能,就是把这些UI对象的状态序列化到硬盘上,并且能够下次再读取出来。
我可以定义一个接口,叫做:IPersistenable,然后让这些UI元素(Button、List等等)都实现这个接口,然后我就可以这样了:
public interface IPersistensable {
    public void save();
}
public void saveAll() {
    for(IPersistenable p : uiList) {
        p.save();
    }
}
现在的问题是,我无法或者不想改变Button、List等的代码。这时候,就可以采用下面这种方式了:
public void saveAll() {
    for(PlatformObject o : uiList) {
        IPersistensable p = o.getAdapter(IPersistensable.class);
        if(p != null) {
            p.save();
        }
    }
}
也就是说,我们需要实现一个Button->IPersistentable的Adapter,然后将它注册到AdapterManager中,就可以动态的为Button、List等类添加了新的IPersistensable接口。
Popularity: 45%

Popularity: 45%

How NLB works

这两天试了一下 Microsoft NLB(Network Load Balance),顺手记些笔记。
1)Aim:higher availability, greater scalability, 使用一种分布算法将访问Clustern的负载均衡分布到多台Host Server上,并且可检测主机故障并自动将流量重新分配给其它Host Server。
2)配置起来非常简单,需要注意的就是单播和多播的方式,以及Port Rule的配置。
3)NLB的实现有单播和多播的方式,在单播模式下,所有的Host Server都被赋予一个虚拟的Mac地址(02-BF开头,其后跟随的内容则取决于配置的Cluster IP 地址, 这也正是Token Ring不支持NLB的原因,令牌环网络不允许多台主机共用一个 MAC 地址),并且所有的Host Server都会有相同的一个虚拟IP地址,访问这个虚拟地址的IP数据报将会被所有的Host Server接收到。说起来简单,其实为了应对各种Switch和Hub,NLB采用了几种方法来实现,比如HUB的Broadcast,比如对一些Switch的Disable Learning,等等。当所有的Host Server都接收到请求此NLB的包后,会由一个Distributed Mapping算法,根据客户端的IP,Port,预先配置的负载比重等其他信息,确定具体由哪一个Host具体执行这个请求,其它Host简单的丢弃这个Message。
如果是多播,就会分配一个二层多播MAC地址专用于NLB的通讯,但是需要在Router上添加静态的ARP映射,将Cluster IP映射到多播的MAC地址。其后是一样的。
对了,如果是单播,Host Server之间会无法访问,为什么?如果你熟悉ARP协议,这个问题应该不难想到。
4)Port Rule,也就是端口规则。其实不难理解,试想一个Web Application,如果Client对Server的每次访问被定向到不同的Host Server上,那么像Shopping Cart等这种基于Session的程序将无法工作。NLB提供了很多种Port规则,比如相同Client IP Mapping到同一个Host Server,相同IP和Port Mapping到同一个Host Server,或者相同IP C网段映射到同一个Host Server等等。
5)Host Server之间保持HeartBeat,来确定所有的Host Server都还活着,否则就要重新Converge。HeartBeat也是发送到Host Virtual IP的,具体的IP祯也需要修改其中的SRC MAC地址和DES MAC地址。
6)来张Architect图:

7)有篇介绍NLB技术具体实现的非常好的文章,读完就会明白它是怎么work的了。
www.microsoft.com/technet/prodtechnol/windows2000serv/deploy/confeat/nlbovw.mspx
Popularity: 42%

Popularity: 42%

Trackback, Pingback & Backlink

今天看到王建硕的文章《如果过得去那个临界点》

做Ping,需要发的人要支持,收的人也要支持,这种分布的方式的唯一问题是,你需要很多人的协作。不是每个人都愿意协作的,圣经里的通天塔Babel就是一种努力。这就形成了网络外部性--就像一个对讲机没有用,多个才有用处。
网络外部性的东西(email, TCP/IP协议,MSN Messenger,电话)必然需要强大的外因(或者极好的运气),才可形成,但一旦形成,就会病毒性复制。
这个就像核反应堆。谁有能力击破第一个原子,以后的事情就不用你管了。这个点,有人叫做引爆点(tipping point),有人叫做临界点(Critical Mass)。
所以,搜索引擎不需要被爬的网站的配合,就可以工作,所以成功。如果依赖于别人的ping, 就像有了C2C的交易平台,却没有那足够市场经费(这是一种办法),或者经过几年的积累(这是另外一种做法)轰击原子核,很难达到Critical mass。这个和技术无关无关了。

不久前曾有过一场关于Trackback是否会死去的大讨论,我也恰巧想过这个问题。于是,昨天仔细看了Trackback,Pingback,以及Backlink。
从使用的难度来说,Trackback > Pingback > Backlink。Trackback的使用方法实在太过Geek,你需要到对方的Blog上找到Trackback
URI(虽然Trackback支持Auto-Discovery,但是真正用的似乎并不多),然后把它Paste到Blog软件的Trackback
Field里面去,我觉得,这个过程对于普通用户来说绝对不可忍受。即使你做到了这点,不同Blog程序间标准的不统一,对国际化支持不佳,使得Trackback的送出是如此之难。
相比之下,Pingback要好很多,如果你的Blog软件和对方的Blog都支持了的话,用户什么都不需要做。比如WordPress,会自动的向文章引用的每一个URL发送Pingback,当然,只有对方支持才会Ping成功。支持Pingback的Blog程序也很多,包括WordPress,Dupral,其它像是MSDN
Blog也都支持(用的是.Text?)。
这里废话一下Pingback的实现,其实很简单,每个客户端负责对指定的URL发送Pingback。而服务器端有两种办法来提供Pingback的地址:HTTP Header和Link Element。

HTTP/1.1 200 OK
Date: Sun, 08 Sep 2002 15:05:37 GMT
Server: Apache/1.3.26 (Unix)
Last-Modified: Thu, 28 Dec 2000 03:18:26 GMT
ETag: "65044-15b9c-3a4ab102"
Accept-Ranges: bytes
Content-Length: 88988
Connection: close
Content-Type: image/png
X-Pingback: Pingback Server URI

<link rel="pingback" href="Pingback Server URI">

可惜,标准总是好的,现实总是残酷的,并不是每个人都愿意遵循标准。显然,Trackback的提出者MT就不愿意支持Pingback。因此,我认可建硕说的,“当一件事情有赖于多于一个人的努力才能成功的话,他成功的可能性就小很多”。
这样看下来,Backlink就是最简单的了。如果你不知道什么是Backlink,就去看看Google的官方Blog。哦,对,这个。。。,那就拿Google中国黑板报来说吧,每篇文章后面会有一个“引用此贴的链接:”,就好比MT中Trackback到此篇文章的链接一样。下面列出的是一些链接到这篇文章的Blog。看看代码,你会发现,其实很简单:
<script
 type="text/javascript" src="http://www.blogger.com/dyn-js/backlink.js?blogID=20904277&postID=113976536783718339" defer="true">
  </script>
 
  <noscript>
  <a href="
http://search.blogger.com/blogsearch?q=link:http%3A%2F%2Fgooglechinablog.com%2F2006%2F02%2Fgoogle.html">See links to this post</a>
  </noscript>
正是Google Blog Search中的反向链接查询结果。
就像建硕所说的那样,搜索引擎不需要被爬的网站配合,就可以自己工作。有的时候,与其花费时间去推广一个标准,真的不如另辟蹊径,去找执行力更好的解决方案。
我觉得,无论从实现者的角度,还是从最终用户的角度,Backlink都是最简单的,事实上,他也确实成为我现在查看Backlink,进行Ego
Surfing的主要工具了。
还有,如果你希望Backlink成为文章的一部分,要展现给读者,那么就学习GoogleChinaBlog吧。Google Blog Search提供了Backlink的RSS,然后再用RSS -> […]

Popularity: 67%


Creative Commons License
This work is licensed under a Creative Commons License.

没有什么能够阻挡,你对未来的向往