2010年2月26日星期五

英语词典的选择

一般阅读文章使用网易有道词典就够用了,但要想学好英语,需要用到很专业的词典。从李笑来老师的这篇blog可以看出他所选择的词典:
Collins COBUILD Advanced Learner’s English Dictionary
Longman Dictionary of Contemporary English
Oxford Advanced Learner’s English-Chinese Dictionary
Oxford Collocation Dictionary for Students of English
The Merriam-Webster Collegiate Dictionary
WordNet English Dictionary

另外,李笑来老师非常推崇柯林斯(Collins)英语词典和《Collins COBUILD English Grammar》。为啥?Collins词典使用了“if...”的简单句型,最适合第二语言使用者的解释方式;而且它是市面上唯一一个自带可查询语料库的词典。

《Collins Cobuild Dictionary on CD-ROM ver 3.1》
http://www.lixiaolai.com/index.php/archives/7759.html

推荐另一本好语法书:《Collins COBUILD英语语法大全》
http://www.lixiaolai.com/index.php/archives/5610.html

笑来老师还将语法书提取了出来供大家下载
http://www.lixiaolai.com/index.php/archives/4668.html

柯林斯词典可以在verycd下载 http://www.verycd.com/topics/135421/

那到底用什么字典软件学习英语好呢?目前看Lingoes才是王道,搭配上笑来推荐的柯林斯加牛津,无敌了。同样的牛津词典,金山词霸牛津版要卖210。

2010年2月13日星期六

异步数据库driver试用

我们知道,目前的JDBC driver是同步工作方式,也就是发送请求后需要block等待响应。而且connection上的操作都是串行化的,在一个请求处理没有完成之前,后续的请求都必须等待。因此,在处理大并发量访问数据库时,都会应用到连接池技术,实现连接复用,避免连接频繁打开关闭这种不必要的开销,而且复用后不会创建太多的连接。但即便是用了连接池,在客户端越来越多的情况下,对于数据库来说,连接还是太多了。
实际上这种同步串行化的操作风格是对连接的浪费,每个物理连接并没有得到充分的利用,特别是在大并发访问数据库的情况下。面对这种场景很自然的想到,如果有异步的JDBC driver,所有的请求都可以并行发送处理,这样就可以充分利用单个物理连接,避免建立过多连接的情况。


adbcj(http://code.google.com/p/adbcj/)定义了一套异步访问数据库的API,并用两种方式实现了这个API。
1. 使用threadpool包装现有的MySQL connector
2. 基于MINA实现的native driver
第一种方式使用的是现有的MySQL connector,虽然用threadpool包装后达到异步性,但底层的connection对操作还是串行化处理,性能并没有本质的改变,只是用来展示如何实现ADBCJ。
第二种实现方式不仅对调用者表现为异步性,底层的connection对请求也是并行发送,最大限度的利用了物理连接资源。
目前该项目还处在试验阶段,native driver只支持int和varchar类型。

作者的blog列出了他测试对比的结果 http://swamp.homelinux.net/blog/index.php/2009/11/25/performance-comparison-of-apache-mina-and-jboss-netty-revisited/,可以看出adbcj的性能优势。但作者只测试了query,ResultSet是通过callback通知。我比较关心的是insert,而且希望通过feature在调用线程直接得到操作的结果。

callback方式:
                final CountDownLatch latch = new CountDownLatch(count);
        final DbListener listener = new DbListener() {
            public void onCompletion(DbFuture resultSetDbFuture) throws Exception {
                latch.countDown();
                resultSetDbFuture.get();
            }
        };
        for (int i = 0; i < count; i++) {
            connection.executeQuery(query).addListener(listener);
        }

通过feature拿到结果:
            DbSessionFuture resultFuture = session.executeUpdate(sql);
            Result result = resultFuture.get();
            long affected = result.getAffectedRows();
            if (affected != 1) {
                System.out.println("插入数据库失败");
            }

我也做了一个简单的测试,对比adbcj和使用线程池的情况。首先创建一个表,只包含int和varchar:
CREATE TABLE `adbcjtest` (
`id` bigint(64) unsigned NOT NULL auto_increment,
 
`topic` varchar(32) NOT NULL,
 
`body` varchar(4000) NOT NULL,
  PRIMARY KEY  (`id`)
)

测试的场景有:
1. 10个线程,单个adbcj连接 VS. 10个线程,JDBC连接池大小为10。插入1000万条记录
2. 50个线程,单个adbcj连接 VS. 50个线程,JDBC连接池大小为10。插入1000万条记录
3. 100个线程,单个adbcj连接 VS. 100个线程,JDBC连接池大小为10。插入1000万条记录

客户端为Linux ,4核,4G内存,MySQL Server为Linux,8核,16G内存。
测试的对比结果,纵轴为TPS:






可以看出,在并发小的场景下,adbcj并没有优势。并发线程增加后,adbcj的性能就超过了使用JDBC连接池。同时注意到,所有的测试场景adbcj只使用了单个连接。

我们还可以对比测试过程中客户端的load情况:

第一种场景:








第二个测试场景:




第三个测试场景:








所有的测试场景,adbcj的load都低于JDBC连接池。


所以,异步的数据库访问方式值得关注,它能够很大程度上的提高连接的利用率。目前MySQL官方没有提供Java异步方式的驱动,而adbcj发展有些缓慢,也许有必要自己实现一个。

另外,我浏览了一下MySQL的通信协议:http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol,发现MySQL的请求命令都没有sequence number,因此请求并不是完全并行处理。从adbcj的代码也可以看出来,需要用一个activeRequest标识当前请求,请求并行处理程度并没有想象中那么高。

2010年2月10日星期三

《怪诞行为学》书评

传统经济学认为人都是理性的,会根据自己得到的所有信息,做出最合理的决定,以便最大化自己的利益。但本书阐述的是,在很多情况下,人们常常做出非理性的决策,而这种非理性的行为又不是随意做出的,而是有规律可循。正像这本书名的直译:可预期的非理性。这个理论是对传统经济学的补充,是当前很流行的行为经济学。作者因为他的特殊经历而具有非凡的洞察力:在他18岁时由于意外全身烧伤,在医院治疗了3年,在住院期间他因为孤独而常常以旁观者的视角去观察世界,各种人的行为,也包括他自己。这本书不是一本理论著作,读想起相当轻松,每章都描述了一个人们日常生活中常见的非理性行为,然后通过实验揭示这种行为背后的真实原因。因此,行为经济学也称作实验经济学。看着作者构思出一个个巧妙的实验场景,然后一步步得出结论,真的非常有趣。例如为了验证人们是否诚实,他在大学宿舍的公共冰箱中偷偷放了一箱可乐和一些零钱,几天以后去观察,可乐都被拿光了,而钱一分也没有被拿走。从这个现象得出的结论是:离现金一步之遥的作弊最容易发生,因为人们根本就没有意识到自己在作弊。对于非现金的事物作弊,我们擅长于把自己细微的不诚实想法和做法合理化。这大概就是孔乙己说的:窃书不算偷。

读完这本书,不只是了解了行为经济学的知识,更重要的是我们认真的审视了自己的非理性行为,并用理性的眼光看待他们,知道这些行为背后的真实规律。当你下次再在两个功能价钱相似的相机前选择很久而不能下决定的时候,你就会想起那头在两堆谷草之间饿死的驴。心里感叹,人就是这样,竭尽全力的想保持所有选择的可能性,而忘记了真正重要的事情。

2010年2月9日星期二

目标的重要性

一口吃不了个胖子,但很多人就此放弃了吃胖子。


目标对人非常重要,人有了目标,都会尽自己的所能,去完成它,在目标的指引下可以发挥出自己最大的能量。但没有明确目标的时候怎么办呢?需要自己给自己设定目标。
设定目标,然后把它分解,一步步的完成,最终达到目标,是多么一种难得的能力呀。

人很容易因为眼前的诱惑而放弃长远目标,这就是拖沓的原因。人们都希望自己的努力马上能看到成果,这是人的天性使然。所以有些人喜欢赌博,不管输还是赢,马上能看到结果。实际上,通往成功的道路是漫长和艰辛的,成功不可能一蹴而就,推迟满足感,耐得住寂寞,用无比的毅力和耐心去实现自己的目标。认识到人天性上的弱点,就要运用心智力量去改变它。一切的成果都是耐心的成果,而我们需要有一个远大的目标在前面指引,时刻提醒自己,不受眼前的诱惑影响,依靠信念的力量一路前行,最终达到目标。

现在,去设想你十年后成为怎样一个人,把它铭记在心,然后落实到每年、每个季度、每个月、每周和每天的行动中,持之以恒,还有什么做不到的事呢。


说了这么多仿佛都是大道理,但却是我真实的感受,那种经历过失败后沉思的顿悟,那种看着蹉跎岁月无情流逝的刻骨铭心的痛楚。就像别人没办法代替你自己思考,我说出来的感觉别人也体会不到。我们可以看到“过来人”的苦口婆心一般都是白费,只有自己经历了才能深切体会。但我也不想放弃这种“说教”,真的,成功者都是很早就明白这个道理的人。想想如果十年前你就设定了一个你目前都无法企及的目标并持之以恒的去努力,现在的你又是一个什么样子呢?现在也不晚,你能下决心耐得住下个十年的寂寞去完成你的目标吗?共勉吧。

2010年2月2日星期二

如何禁止CNNIC根证书

CNNIC根证书的危害性和如何在Firefox下禁止请参考AutoProxy作者所写的《CNNIC CA:最最最严重安全警告!》

下面说一下如何在Windows下IE/Chrome禁用CNNIC根证书:
运行certmgr.msc,第三方根证书颁发机构-CNNIC(及Entrust),详细信息-编辑属性-证书目的-禁用此证书的所有目的。
如果找不到对应的证书,先访问一下:https://tns-fsverify.cnnic.cn/ 和 https://www.enum.cn/cn/
设置完成后,请务必用这两个地址验证。