我国的历史教育有很多特点,其中之一就是按照马老圣人的“规律”削足适履,另一大特点就是把历史当成“大事记”——哪年、哪月、哪日,发生了什么事情,意义是什么,它是进步的,还是退步的……教科书上的所谓“历史”,便是这样的简单重复。其结果就是,接受完完整的所谓“义务教育”之后,某天我忽然发现自己对历史竟然一无所知:阳历乃是外来的立法,为什么阳历1月1日会有“元旦”这样本土的名称?“星期”乃是外来的历法,在它传入之前,我们生活的时间单位是什么?……这些活生生的历史问题,“历史书”毫不关心,似乎我们根本不需要知道,也不需要感兴趣。 所以,我们只能便带着这些好奇,自己去探寻: 假如我生活在辛亥革命之前,那么大家说的“元旦”乃是春节; 如果我生活在“星期”没有传入的年代,大家的生活乃是以“旬”为单位的; 如果我生活在晚清、民国,我和普通劳苦大众穿的,多半是单调的深蓝色衣服; …… 不过,了解归了解,内心却难以清除“大事记”的遗毒:如果当时我是xxx,我一定要运筹帷幄、明察秋毫、力挽狂澜…… 可是,某天我忽然再次猛醒:从生活现状看,我生活在任何年代都只能是一介凡人,即便在风起云涌的年代,注定连“治世能臣、乱世奸雄”都算不上,再加上厌倦了那些毫无逻辑、牛头不对马嘴的所谓历史“分析”和“研究”——与其迷恋帝王将相、生造出各种因果链条,不如多去了解了解跟自己类似的平凡人的生活。革命导师说:忘记历史就意味着背叛。忘记自己是凡人,忘记平凡人的历史,多半可以算作背叛自己身份的可怜虚妄吧。 假如我是民国时期的贫苦农民,我一定去寻求新教传教士,而不是天主教传教士的帮助; 假如我是民国时河南的农民,在开明进步的“基督将军”冯玉祥的治下,春节包起饺子,是一定会被当兵的把桌子灶台踢坏的; 假如我是参加长征的战士,在贵州落了单,一心想要回到大部队,我肯定念叨的是“我要找到朱总司令”,而不是“我要找到毛委员”; 假如我是红军的下级军官,遵义会议的“伟大转折”期间,我很可能在馆子里消受美味的辣子鸡,连吃一个礼拜,最后店家只能以猪肉冒充鸡肉; …… 这些年来,我着意收集凡人的生活历史,只觉得困难重重:详实绵密的生活记忆本身就很稀少,又因为审查制度的妖娆,大多只能口耳相传,绝少集中公布、发表的机会;第一手资料固然可靠性高些,又要竭力避免有意无意的吹捧或贬损,需得多种资料互相验证才敢取信。在这种环境下,龙应台女士新近出版的作品倒是显得尤其可贵了:她通过大量的第一手材料,再现了“天翻地覆慨而康”的那些岁月中有太多太多平凡人的故事,又因为故事的主人多半是平凡人等,即便对大形势的了解有所差池,但对切身经历回忆,因为无涉太多利益,反而真切可信。星星点点的故事,让我想起许多年前的一首歌:一个神话,就是浪花一朵,一个神话,就是泪珠一颗,聚散中有你,聚散中有我…… 假如我是在长春被围困的老百姓,可能饥肠辘辘地被国军放出城去,面对解放军封锁的枪口,上吊自尽; 假如我是四行仓库撤退的八百壮士之一,我可能被送往腊包尔的俘虏营,为日本人修筑机场,被日军虐待,被美军轰炸; 假如我是抗战中被俘的国军战士,我可能遇上与日军同样凶恶的台湾监视员,命丧异乡,也可能遇到心怀善念的监视员,蒙恩幸存; 假如我是那些年河南南阳中学的五千学生之一,我可能必须与老师同学一起,徒步走过几千里,在永州“产异蛇”的空地上,跟老师朗诵《古文观止》,辗转到达台湾员林; 假如我是北平解放时载歌载舞的大学生,我可能遇到难过得掉泪的国军青年军官:前方打仗的补给都没有,却一直给你们白面、肥肉,可你们一直要闹,闹到“解放”了,跟大家一起吃陈年小米; 假如我是河北崇礼的村民,历来信奉基督教,我可能在抗战结束后,跟五百乡亲一起,被无神论的军队杀死,尸体不及埋葬,就要被三民主义的军队用作宣传的证据,直到亲友突破封锁,泪流满面地冲上来认领;…
有个故事是这样说的:一群傻子,每人得了一笔钱,纷纷去开加油站,因为他们傻,所以加油站如天女散花一般开得到处都是,高山上有,峡谷里有,池塘边有,平地旁也有;也因为他们傻,所以咬定青山不放松,坚持不换地方;结果,过了几年,只有平地旁的加油站存活下来,其它地方的加油站都销声匿迹了。 故事的道理很简单,所以如果听到“傻子那么傻,他开的加油站怎么可能维持下来呢,肯定是冥冥之中有神灵帮助”的说法,许多人多半会笑出声来。是的,这故事很简单,其中的道理也不难明白。那么,换一种形式呢? 同一个物种的生活,因为变异(Variation)而出现不同的个体,这些差异又被后代继承(Inheritance)下来,经过自然环境的选择(Selection),最终有一些个体表现出适应环境(Adaption)的特性,生存下来。本来毫无方向的随机变异,与自然条件较量之后,最合适的个体存留下来,表面看来竟然是“被定向选择”的结果。达尔文的学说,大致就是这么回事,更简洁点说,就是Darwin's VISA。 尽管“傻子开加油站”的例子很容易想明白,达尔文的学说却没那么容易被所有人接受,姑且不说那些坚持神创论之类观点的人士(参考鄙人翻译的《对神创论呓语的15点回复》(一)、(二)、(三)、(四)、(五)),即便是“相信”进化论的人,也多半“都以为自己懂进化论,其实只是一知半解”。故而,把达尔文的理论梳理清楚、阐述明白,是一件非常有意义的事情,也正是本周日(11月15日)松鼠会组织的“达尔文与达尔文革命”讲座的目的。 本次的主讲人是王道还先生,王先生来自海峡对岸(现任台湾中央研究院历史语言研究所人类学组助理研究员),讲座的当然也不同于我们常见的风格,他能恰到好处地把每个“知识点”后面的故事娓娓道来,颇有令人耳目一新的感觉: 达尔文虽然身为科学家,却是不同于当代的职业科学家,而是一名绅士科学家,对职业科学家来说,科学是工作(job),而对绅士科学家来说,科学是召唤(vocation),当然,这也与19世纪的社会环境有关; 达尔文身世煊赫,外祖父是Royal Potter,祖父是Royal Doctor,仅凭此,他其实不需有所作为,也可以过上殷实的生活,也不会是默默无名的小辈; 达尔文先在爱丁堡大学念了两年医学,又在剑桥大学念了三年神学,真正有兴趣的,却是自然史,所谓自然史(Natural History),更确切的说法是“自然誌”,因为在古希腊语中,history的含义乃是inquiry。 达尔文能登上小猎犬号进行环球航行,是因为小猎犬号的船长费兹罗(Robert FitzRoy)需要一名随从,当时英国海军的船长不容许与船员有私交,所以费氏报告要求一名随从陪同航行,“可进行自然史研究”的招牌,通过费氏父亲所在的剑桥大学校友圈子,吸引到了达尔文; 达尔文登上小猎犬号,收到费兹罗的礼物——赖瑞的《地质学原理(第一卷)》,依靠这本书,他完成了关于自然史的训练;到了南美,尤其在智利,先后见识到火山爆发和地震,他由此开始想到,五花八门的自然奇景,可能并非上帝的创造,或许也是大自然伟力的结果; …… 仅仅讲述这样的小故事,也就难免沦为《你可能不知道的xx点》之类的轶事文章;可如果把这些小故事一一对应到达尔文的学说,再把来龙去脉梳理明白,就是需要兴趣和功力的事情了。而且,王先生更上升一个高度,说明演化乃是永恒的过程:生物要生存,就必然对环境有所影响,而受其影响的环境,又要重新“选择”生物,这种动态平衡的过程,就是“演化”。他纵横捭阖达尔文理论的劲头,让我想起 James W. Loewen讲美国历史…
青润发了一篇很有意思文章:专业词汇需要严谨的分析——Serializable到底应该是串行还是序列,较真的精神是让人非常佩服的,我也赞同Serialization应该翻译成“序列化”的观点,理由与清润的类似“串行是一个固定顺序过程的展示,这个固定顺序过程是公认的已知的,不应该是自行设计的”。不过,我更有兴趣的是,serialization为什么应该翻译成“序列化”?又为什么被错误翻译成“串行化”?在我看来,这个问题,凸现了翻译中的困境。 回到Serialization的问题,前不久我也翻译了一篇关于Serialization的文章:发掘Java Serialization API中的秘密,本来serialize想当然就是“序列化”,专有名词嘛,中间却遇到一个词非常难翻译:flatten。原文是这样的: 靠对象的序列化(serialization),你就能把对象flatten,用各种神奇的方式重用。 一直以来,我都觉得“序列化”是一个专用词,指把对象转换成二进制数据的过程。但是,flatten的意思分明是“打扁”嘛,难道把对象“打扁”到磁盘上?再看下面的句子就明了了: the object can be flattened into bytes and subsequently inflated in the future 原来,flatten的意思就是:不管之前的对象有多大,多神奇,它总可以“还原”成一个个的字节排列成的“普通”字节流——就好像一栋大楼,不论多高多漂亮,最后总是能“拆散”成基本最原始的建筑材料,整齐地码好。…
2009年3月的一天下午,我在某家饭馆静候各位已知未知朋友来相聚。七点多,进来一位文静白皙的理工男,虽然不认识,但听他打探的口气,我确认他是来这桌吃饭的。打过招呼,才知道是松鼠会的大掌柜姬十三(想起来真荣幸呀),我连忙说“我知道你们我知道你们,德国之声评选十佳中文博客的时候我就知道你们了……”。 一下子,陌生感就卸去了大半,我们就开始像熟人热切地攀谈起来:从我印象深刻的《第一推动》丛书,到科普先驱站点三思科学,再到妙趣横生的博闻网,都成了我们的共同话题;最后我还说起了自己幼年的奇思妙想:既然我们能看到几千万光年外的星球“几千万年前”的样子,那么,距离我们几千万光年外的外星人(如果有的话),是否可以看到地球上的恐龙是为什么灭绝的,用录像带记录下来,再发送回地球(如此一来,几千万年后我们就“可以”看到恐龙究竟是怎么灭绝的)?这个“异想天开”的想法,姬十三丝毫也没嫌弃,反而正经地跟我讨论了一番可能性——这样的“待遇”,对我这种“科学票友”来说,算非常非常难得咯。 从那个晚上开始,我知道,松鼠会的口号“让科学流行起来”不会仅仅是一个口号。所以,前些天知道松鼠会要举办“科学嘉年华”大型科普活动,我就非常有兴趣参加了。 (more…)
据说,如果被人问道“该怎么办”,一般有两种应对:一种是单纯的说理,把问题剖析解理,抓住“本质”找到出路,遇上与科学关系紧密的问题,此类解法最是合适;另一种则是“答非所问”,给你讲一个故事,相比“干巴巴”地探究法则,娓娓而来的叙事更“罗嗦”,但也更丰厚、更温暖、更亲切——“听完这个故事,你就会感觉好多了”,对于人生的困惑,此类问题或许更加合适。实际上自古也是如此:从上古的传说,从《荷马史诗》到《伊索寓言》,再到晚近流传的各种故事、小说,人类一直从重复的叙事中获得安全感,获得启示。下面要说的,也是一本与叙事有关的书。 近年来,迷惘和无助,似乎成了大学生活的主要色彩。“我该怎么办?”、“我的人生究竟何去何从?”这样的问题困扰着许多正处于人生最美好年华的同学。甚至拙译《精通正则表达式》出版之后,也有同学给我留下的勘误邮箱来信诉说这样的痛苦,问题的严重性由此可见一斑。这里暂不去追究现象的原因,更紧要的问题似乎是:面对这些迫切希望解脱的同学,我们到底能做点什么? 面对这样的问题,单纯的说理难免显得乏力,尤其在现代,它往往带有荒谬的色彩——电影《顽主》里的“德育专家”,就是最好的注解。这种时候,叙事的解答反而更加合适:通过讲述那些经历过这些困扰,但又成功挣脱的“普通人”的经历,给还身陷其中的孩子以力量和启示。这样的好处是双重的:一方面,它真切展现了“挣脱”的过程,仍然身陷其中的人,往往能够在这样的故事中复现自己,这是“设身处地地讲道理”也无法提供的;另一方面,它又不同于大众传媒所包装的“成功人士”,它不但给你看到蝴蝶的美丽,也给你看到化蝶的辛苦,让你相信明白成功者并非“天赋异禀”,于是能够重塑对自己的信心。 当然,要做到这一点非常困难:如今我们看到更多的是成功之后的“全面包装”,有几个人愿意把自己曾经的血泪和疮疤无保留地展现给大家呢?也正因为如此,这本《我是一只IT小小鸟》,才显得难能可贵。 (more…)
第一章:通配符 我们已经说过,这本《正则表达式傻瓜书》并非把读者当傻瓜,而是保证“傻瓜都能看懂”。如果你到现在还没听说过“通配符”或是“正则表达式”,那么,请看这一章。 要说明的另一点是,因为一般的Linux/Unix用户都熟悉通配符,所以,本章假设读者工作于Windows平台下,所举的例子也全部面向Windows平台。 从Windows的搜索谈起 正则表达式是进行文本处理的工具。那么,它到底进行哪些“处理”?简而言之,正则表达式的主要功能就是对文本进行查找(匹配)和替换(修改)。在这一章里,我们先从最简单的文本查找说起。 正则表达式所“搜索/查找”功能的对象,就是我们说的“文本”——它可以是Word文档、Excel表格、浏览器看到的网页等等,也可以是文件名(工作日报20090925.doc)、电话号码(400-82055555)、电子邮件地址(somebody@someone.net)等等。所以也有这样一种说法:正则表达式处理的是“字符串”——也就是一系列的字符。想想也是,Word文档的内容、Excel表格的内容、网页的内容、文件名、电话号码、电子邮件等等,无非都是“连接起来”的字符,也就是“字符串”了。 几乎每种文本处理工具(Word、Excel、记事本、写字板)都提供了查找(和替换)功能: 图1-1 Word中的查找 (more…)
按:《精通正则表达式》是一本好书,我翻译之后,一直都奢望写本关于正则表达式的书,为《精通正则表达式》接上地气,今年终于有机会把“奢望”变成“苦差”。下面是本书(暂定名《正则表达式傻瓜书》,大家对此有意见或建议也请直说)的前言,其中介绍了本书的结构、读者和价值,请大家多提建议,在这里先行谢过。 前言 正则表达式简介 “正则表达式”,这个名字看起来有点古怪。不过别着急,我们先看看它到底是有什么用,再解释这古怪名字的来历。 简而言之,正则表达式就是一套专门处理文本的强大工具。“学术”地说,它能够做的事情主要是: 复杂的文本查找/匹配/提取 复杂的文本替换 请注意,这里说的是“复杂”的操作,而不是“简单”的查找/匹配/提取/替换(几乎任何一种文本处理工具,例如Word和记事本,都提供了这种功能)。或者,通俗地说,正则表达式能够做的事情是这样的: 如果你是一般用户: 把多行的文本迅速拼成用逗号分隔的一行文本(群发邮件时这非常有用); 把一长篇文章里的手机号码都找出来(除了匹配13x、15x、18x开头的号码,还可以处理开头有‘0’和/或有‘+86’的情况); 把一篇文章里可能拼写错的某个单词。比如把separete、saparate、saperete之类“自动纠正”到separate,而且不受大小写限制(seParate, separaTe也可以纠正); 如果你是专业用户: 验证用户输入的手机号、邮件地址是否合法(还记得填写网页表单时常见的提示吗?); 提取网页源代码中的所有图片链接、超链接(搜索引擎就是这么干的); 提取文本中的邮件地址(现在你知道自己的邮件地址怎么被“抓”走了吧?); 进行复杂的格式检查(把各种小数“统一”成精度为0.01的格式,去掉重复的单词); 这样的任务可能并不是我们日常工作的主要内容,“不幸”遇上了却非常烦人——简单重复劳动往往要耗费我们大量的时间。所以,在《卓有成效的程序员》(Neal Ford著,机械工业出版社2009年版)中,作者写道:…
我们所使用的绝大多数语言都具有这样的特性:既有规则(譬如句子要有完整的结构,过去发生的动作要用过去式),又没有规则(譬如不规则动词,以及某些“妙手偶得”的奇妙搭配)。可以说,语言的创造性,就在于能够灵活游走于这种有/无规则的矛盾之间,“产生”出历史上未曾有过,但意义完整的通顺句子。这种“游走”,在我们使用母语时,往往是凭借本能完成的:“千锤百炼”可以调换成“百炼千锤”,但不能变成“千炼百锤”。 但是,译者在翻译时则不容易做到这一点,究其原因,一方面是译者受到原语言规则的影响,往往把原文的思维“照搬”过来;另一方面,词典提供的往往是僵化或者说“过度统一”的解释,结果造成译文生硬晦涩——或许能看懂,但是很别扭。这方面最典型的例子,就是er/or后缀的翻译。 er/or是英文中常见的后缀,其英文解释是the person/thing that(does the action indicated by verb),在英文中,这是方便、简单而且统一的用法:无论什么动作,加上er/or后缀,就可以表示执行的人/器物。翻查英汉词典,通常将这个翻译为“xx者/xx的人”,这个翻译,意思是对的,但译法却不一定合适。 我们不妨来想想,中文语境中各种er/or对应的各种说法,总结一下这个后缀的多种翻译: ~师:培训师(trainer),律师(lawyer) ~者:译者(translator),读者(reader),作者(author) ~员:演员(actor),官员(officer),接线员(operator) ~官:指挥官(commander),法官(judger),翻译官(translator) ~手:水手(sailor) ~士:战士(soldier),辩护士(defender) ~民:农民(farmer),选民(voter) ~人:工人(worker),诗人(songster) ~方:资方(employer)…
题记:“怎样翻译更地道”是我在翻译中的随想,没有固定的更新间隔,供有兴趣的读者参考。 我们学英语,都追求“地道”,也就是“洋味浓”,要做到这一点,就得突破“意思”的层面,把握英语在形式上的某些特点。譬如下面的句子:Please buy two tickets for me,I think to do this is my honor,虽然“意思正确”,但明显不够地道;Please buy me two tickets和I grant it…
beta技术沙龙越办越有意思了,上次错过了阙宏宇的mod_cache(还有关于线程进程的讨论)就很可惜,这次关于Lucene的演讲,是无论如何不应该错过了。 到目前为止,全文检索已经完全不算高技术门槛了,记得以前看过一本书里面写:“今天,任何程序员,都可以很容易地构造一个全文检索应用”。是的,全文检索的基本原理大家都知道差不多了,剩下的只是实践。我见过纯粹自己开发的,具有AS(Advanced Search)、BS(Basic Search)、DI(Digest)等结构,“像模像样”的全文检索架构,不过应用更多的,却是在开源项目上完善、定制而来的,Apache的Lucene就是众多开源全文检索项目中,名气最大、资格最老、应用也最广泛的一个。本期beta技术沙龙,讲的就是大型网站中lucene的应用,主讲人是手机之家团队的唐福林(“手机之家”总是有些东东来共享,比如上次的DAL,这真是不错)。 众所周知,用Lucene构造一个“索引-查询”的应用是非常简单的,搭好环境,参照(修改)示范代码,很容易就可以成功。但是,要构造一个真正大规模、稳定、可靠的应用,就不说这么简单。程序的编写、模块的分布、架构的设计,都有许多费心思的讲究。按照PPT提供的数据,手机之家目前的Lucene应用,采用的是Lucene 2.4.1 + JDK 1.6(64 bit)的组合,运行在8 CPU, 32G内存的机器上,数据量超过3300万条,原始数据文件超过14G,每天需要支持超过35万次的查询,高峰时期QPS超过20。单看这些数据可能并没有大的亮点,但它的重建和更新都是自动化完成,而且两项任务可以同时运行,另一方面,在不影响服务可靠性的前提下,尽可能快地更新数据(如果两者发生冲突,则优先保证可用性,延迟更新),其中的工作量还是非常大的。 演讲的主要内容都PPT里,非常丰富,我就不再赘述了。要补充的是,这份PPT做得非常清楚,需求-目标-进度-设计-上线-测试-上线,整个流程非常清楚,给出的数据同样非常精当,我想,这也反映了手机之家团队的开发规范。 因为对Lucene的使用稍微有些经验,我在这里补充几句,权当狗尾续貂: 在大规模的应用中,Lucene更适合用于狭义的“搜索”,而不应当负责数据的存储。我们看看Lucene的源代码也可以知道,Document和Field的存储效率是不够好看的。手机之家的团队也发现了这一点,他们的办法是,用Lucene存放索引,用Memcache + Berkeley DB(Java Edition)负责存储。这样有两个好处,一是减小了Lucene的数据规模,提高了程序的效率;另一方面,这套系统也可以提供某些类似SQL的查询功能。实际上,Lucene Project自己似乎也注意到了这个问题,在Store中新增了一个db选项,其实也是利用的Berkeley…