Archive for July, 2005

IE7 Beta1 Installed on my laptop

今天在笔记本上装了IE7 Beta1,我的笔记本是中文XP,所以安装起来还需要修改注册表,过程见此(下载的链接也在这里,不过Pconline的Web Standard实在不敢恭维,所以如果要下载,还是用IE6吧,Firefox不行)。
离开IE已经有1年多的时间了,除了招行一卡通的网站和一些不标准的网站,我的浏览一直在用Firefox,感觉非常棒。可是最新的Firefox1.0.6在我的笔记本上出现了一些问题:

休眠起来后经常CPU占有率达到100%,不得不杀掉Firefox进程,这个是老问题了;
打开一个Load比较慢的页面(比如Sina新闻的Comments),会将其它的Tab也都阻塞,整个Firefox会Hang住,这个似乎是最新版的问题,很郁闷;
经常Crash,大米曾经跟我抱怨他的Firefox经常每天死一次,我还嘲笑他。现在,我的每天都死不止一次。而且我的阅读习惯是打开很多Tab,然后一起看,Crash经常搞得丢掉了所有的链接。

TestNG与JUnit的嘴仗似乎告一段落了,Gunjan Doshi今天发布了一个"JUnit 4.0 in 10 Minutes: A Quick Reference Guide",学习笔记如下。
注:所有代码和插图都来自于原文。
首先来看看JUnit4.0以前,我们怎样编写测试用例:

测试用例必须继承自"junit.framework.TestCase";
测试用例函数必须以"test"开头;
用assert的系列函数来验证结果。

如果用JUnit4.0重写,将是这个样子:

不用再继承自"junit.framework.TestCase",TestNG批评JUnit的一个方面就是在JUnit中,每一个测试用例都会实例化一份TestCase,带来效率的降低。JUnit4.0确实修改了这样的设计。
测试函数名称不用再以"test"开头,而用Annotation"@Test"来修饰;
assert系列函数没有大的改变;
如果希望用老的JUnit Runner来运行JUnit4.0的测试用例,需要用Junit4TestAdapter来Adapt一下。
或者可以用新的JUnit4的Runner来运行。

java org.junit.runner.JUnitCore LibraryTest

其中,用"@Test" Annotation来修饰测试用例是JUnit4.0的一个大Feature,这也正是这种Metadata应该发挥作用的地方。
"@Test"有两个非常有用的参数:
1) 预期会抛出的异常检测
"@Test"的"expected"参数用来说明希望抛出的异常,如果运行时没有抛出这个异常,测试用例就被标识为失败。

2) 预期运行时间
"@Test"有一个timeout的参数用来说明这个测试用例运行的时间最长应该为多少,如果时间超出,则标识为失败。
@Test (timeout=10)
TestNG批评JUnit的另一个方面是所有的测试用例函数都会在测试执行前执行setUp,在测试后执行tearDown,不仅效率很低,也会带来很多问题(比如一次性的数据库链接等等)。
JUnit4.0这样解决这个问题:
引入Annotation"Before", "After", "BeforeClass", "AfterClass"。
"Before"修饰的函数将会在每个测试运行前运行,"After"修饰的函数将在每个测试用例运行后运行。JUnit4.0支持任意数量的"Before"和"After" Annotation,并且支持继承。"Before"修饰函数的执行顺序为父类的在前,继承类在后,"After"则相反,继承类在前,父类在后。

"BeforeClass"修饰的函数将会在所有的测试用例运行前运行一次(只运行一次), "AfterClass"则会在所有的测试用例运行后运行一次(只运行一次)。

JUnit4.0还有一个有用的Annotation "@Ignore",它用来修饰将被忽略的函数,用"@Ignore"修饰的测试用例函数将不会执行。这个Annotation支持一个字符串参数,用来说明忽略的原因,比如:

@Ignore(“Database is down”)

TestNG则采用配置文件的办法解决这个问题,两种方法各有利弊。
Reference:
JUnit 4.0 in 10 Minutes: A Quick Reference Guide [PDF] – Gunjan Doshi
注:所有代码和插图都来自于原文。

Subscribe using XML

在SUN的一个同事的签名档是这样的:

Java == platform independence
XML == application independence
JXTA == network independence

Bill Joy也说过:

Unix first gave us modular applications, connected by pipes; Java gave us portable applications; XML gave us portable data; and peer-to-peer gives us simple distributed computing. Can we tie these benefits together?

XML(eXtensible Markup Language)的确是一个伟大的发明,而且几乎成了Internet数据交换的标准。从软件架构的角度来讲,XML使得HTML中的数据和表现分离,提供了一种数据传输和交换的标准。
现在有很多文件都利用XML文件来进行同步更新,比如PAD.xml,RSS(包括RSS, Atom),Sitemap.xml。
做过共享软件的朋友应该都知道PAD(Portable Application Description),3年前做Shareware(VVPhoto)的时候第一次接触到了PAD.xml。这其实是一个共享软件领域内的数据同步交换标准。如果你的软件的网站支持这个XML文件,软件下载站(比如Download.com、Tucows)的Robot就会自动来订阅你提交的XML文件,并定期同步来保持更新。
这样做的好处显而易见,每个软件下载站都要提供成千上万种软件,而对于每个共享软件得开发者而言,他也要面对少则几十,多则几百的软件下载站。在没有PAD之前,共享软件开发者需要自己写Email或者添一些表格来提交自己的软件(包括今后的每次更新),这个工作实在是冗长并且无聊。
PAD这种发布-订阅方式使得这个工作简化许多,软件开发者只需要更新发布自己软件的PAD文件,而把其它工作留给软件下载站的Robot去做。
Google前一段推出的Sitemap文件其实也是如此,如果Webmaster都能提供良好维护的Sitemap文件(就像Blogger提供自己的RSS),Google就可以订阅这些Sitemap文件,从而采用异步订阅更新的方式来更快、更全、更好收录网站内容,Google Robot也不用再那么辛苦的四处爬行了。
RSS更是如此,我坚持认为,CMS和RSS是Blog得以风行的两个非常重要的原因。

个人主页有一个缺点是跟踪其他人的主页困难。如果我有很多朋友,每天通过收藏夹打开他们的主页,将会打开非常多的页面,而且如果发现没有更新,不但沮丧可想而知,宝贵的时间更是费了不少。RSS这种基于“推”的技术可以让我们可以更方便、高效的关注我们感兴趣的内容,我们再也不用去收藏夹中寻找感兴趣的内容,更新会被自动推倒我们的面前。 [...]

Dissect WordPress Themes

还是想用Nat在OOS上的一段话来作为开头:

You have to give people work to do.
Create an “architecture of participation” as Tim O’Reilly says.

要想真正成功,必须能够提供一个可以供人参与的架构,Eclipse如此,Firefox亦如此。与Plugin一样,WordPress中的Theme机制也非常灵活和强大,社区贡献出的一个个漂亮的Theme都是这个良好架构下的杰作。
1)读取系统中所有可用Themes
<?php 
function get_themes()
?>
这个函数用来从文件系统得到所有的Themes。首先列出’wp-content/themes’的文件夹,然后跳过”.’、’..’、’CVS’(跳过CVS目录,这个在Xerdoc DSearch的Theme中也遇到过,因为都是采用CVS进行源码管理 ):
<?php 
if ($theme_dir{0} == ‘.’ || $theme_dir == ‘..’ || $theme_dir == ‘CVS’) {
    continue;
}
?>
然后会判断每个目录中是否有Stylesheet ’style.css’文件,如果有,列为Theme候选目录,否则加入到’$wp_broken_themes’中。
接下来,就利用函数
<?php 
function get_theme_data($theme_file);
?>
来从’style.css’中提取Theme的描述信息,包括’Theme Name’、’Version’、’Author’等等。同WordPress中的插件类似,这些描述信息是存在’style.css’中的。
<?php 
Theme Name: WordPress Default
Theme URI: http://wordpress.org/
Description: The default WordPress theme based on the famous Kubrick.
Version: 1.5
Author: Michael Heilemann
Author URI: http://binarybonsai.com/
?>
第三步,需要判断命名冲突。这种情况发生的原因是:将一个Theme拷贝,然后做修改,可是Theme的Descriptor并没有修改。可见,WordPress在人性化上真是做足了功夫,值得学习。
这样,合格的Theme就读取完毕了。不合格的Theme会被放到"Broken Theme"这个Section中,需要重新进行修改才能使用。
2)更换Theme
更换Theme很简单,先来看看当Active一个Theme的时候我们所Access的URL:
http://localhost/blog/wp-admin/themes.php?action=activate&template=sixties-datetitle&stylesheet=sixties-datetitle
同Plugin一样,Active Theme的信息(其实就是目录名称)也保存在数据库中。但是需要存两项,分别是"template"和"stylesheet"。这是为了处理Style的CSS文件与模板文件(比如index.php)放在不同目录的情况。
<?php 
if (isset($_GET['template'])) {
    update_option(‘template’, $_GET['template']);
}
 
if (isset($_GET['stylesheet'])) {
    update_option(’stylesheet’, $_GET['stylesheet']);
}
?>
3)Theme的加载
首先看看我们访问WordPress的过程。当我们访问’http://yoursite/blog/’的时候,访问的是’index.php’文件:
<?php 
define(‘WP_USE_THEMES’, true);
require(‘./wp-blog-header.php’);
?>
在’wp-blog-header.php’文件中,可以看到下面的重定向过程:
<?php 
// Template redirection
if ( defined(‘WP_USE_THEMES’) && constant(‘WP_USE_THEMES’) ) {
    do_action(‘template_redirect’);
    if ( is_feed() && empty($doing_rss) ) {
      [...]

Tiger中的Annotation又被称作Metadata(关于数据的数据),就是关于源代码的数据,具体来说就是关于Java的类、方法、字段等关联的附加数据。这些数据可以被Java的编译器或者其它工具(比如Java IDE)来发现和使用。
BTW:其实从数据的数据的角度来说,JavaDoc算是最早的Metadata了。
JUnit4.0中,就改用Annotation来创建单元测试,而不再用"test"开头的函数了。这样更自然,而且更符合标准。
看看J2SE 5.0 in a Nutshell中给出的例子:
import java.lang.annotation.*;
import java.lang.reflect.*;
                                                                               
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @interface debug  {
    boolean  devbuild() default false;
    int counter();
}
  [...]

Dreamwords & VV

2002年7月23日,生日前夜,VV答应做Dreamwords的GF,一晃3年而过。

2003年10月,九寨沟

2004年9月,中国网球公开赛

2005年春节

Events Handling in Java and C#

Actually, this article is posted about one year before, at here. Today, I happened to see this article, interesting. So, I found my old entry and post here. Also, I post all the comments at the end, it’s really valuable I think.
Recently(2004.08.06), a friend of mine discussed the Event handle issues in C# and Java [...]

How to implement queue with stack?

Interesting topic, right? One of my friends encounter this problem when he’s applying software engineer position in a company.

Suppose we have only stack available
Stack* stack_init();
void push(Stack*, int);
int pop(Stack*);
void stack_free();
Please implement the following interface of queue
Queue* queue_init();
void inq(Queue*, int);
[...]

我心目中的理想打工仔

总是和朋友说起,做个总结:
如果还在打工,以下这些是我最看中的,如果都不满足…
1)能做自己感兴趣的事儿;
2)有个好老板,这样可以学习他的成功之路;
3)有一群好同事,一起玩儿的来,工作也开心。

Longhorn中的RSS

Longhorn将要从底层(the deep platform support for RSS)开始支持RSS,好消息。今天从特意到MSDN中找到这篇文章-《RSS Support in Longhorn》,摘记如下:
1)Browse, Search, Subscribe
浏览 -> 搜索 -> 订阅,这六个字很形象、也很有意思。MS在"Browse"上判断失误,不过奋起直追,还是搞掉了Netscape;接着,MS在"Search"上再次判断失误,至今仍在苦苦追赶Google;这次对RSS有如此大的动作,不知道是不是MS不能再允许自己犯错误,要先发制人了 。
Update:Blog Business Summit in IEBlog

We think that RSS is becoming a critical tool for businesses to communicate with customers and we want that to happen even faster.
Robert will talk about how businesses can use RSS to create strong, [...]