我也有一个梦想

许多年前,我第一次读到《第三次浪潮》,里面有一句话非常激励人:在第三次浪潮面前,知识已经取代了资本,变为生产力提升的最重要因素。我读到这个观点,总觉得平添了无穷的力量,它比从小就耳熟能详的“知识就是力量”更加有说服力,更令人向往。

而且,我逐渐发现,知识与资本相比,其实是一种更独特,也更坦诚更健康的力量:资本的力量往往是独属于个人,或某个小团体的,固守起来,价值并不会贬低,知识却不是如此,知识的价值和增值,更多体现在交流与分享之中,“保守秘密“的做法,反而得不偿失。

举个自己经历的例子吧:上中学的时候,有一些同学对自己使用的复习资料守口如瓶,似乎这样就可以保住自己的名次和优势,我当时觉得这类做法有点奇怪,但也有朴素的味道,可以理解。

到了大学才发现天外有天,更深刻觉得这种做法真是不太好。一来因为大学里能人太多了,在中学觉得很“了不起”的东西,在大学显得非常稀松平常,往日那些“绝学”立刻显得很苍白了;二来大家都住校,基本没什么秘密可言,你看什么书,花多少精力学习,旁人不可能完全不知道。“固守自己绝技”或许能建立一些的优势,但总的来看,还是不如心态开放、愿意交流和分享的同学,尤其是,不少愿意分享的同学本身也学的很不错。

毕业以后工作了,逐渐发现自己经常在某些方面浪费了很多时间:比如非常简单的技术问题,因为不熟悉,或者没有想明白,总是“不得其门而入”,若有人点拨,往往很快就能解决了。但许多时候,人家“就是不告诉你”,甚至自己就“觉得”人家不会告诉,因而都不好意思去问。

2007年,我翻译了《精通正则表达式》,此后常常遇到各路朋友关于正则表达式的问题。平心而论,我也只是用过一点正则表达式,多一点经验而已,而且正则表达式,实在不是什么高深的技术。但是,我却发现不少朋友乃至技术高手所问的,往往多是这类看来比较简单的问题,只是没有遇到过,或者不熟悉而已,所以他们也“不得其门而入”。换位思考,我逐渐体会到,简单的问题,解决起来未必简单,其实是因为“术业有专攻”而已。没有人能做到面面俱到,即便是某个领域的行家,在不熟悉的领域,也难免被简单问题困住——我问他人的问题是如此,他人问我的问题,也是如此。

或许,也正是因为有这样的情境,“固守自己绝技”的做法,才体现出价值?我不知道。

可是再后来,见的再多一点,读的书再多一点,我却越来越否定“固守自己绝技”的做法了,因为无论从个人,还是从社会来说,其实都是得不偿失的。

从个人来说,长期来看,我们的脑细胞一直在不断减少,但智力却没有明显的下降,甚至会上升。这是因为,通过不断的学习和思考,脑细胞的突触会增加,脑的结构也会不断变化,知识体系的索引结构也在不断优化。所以,质量的提升取代了数量的下降(可以参考Richar Restark博士的Think Smart)。而固守自己绝招,不愿与人交流的人,大都满足于守住自己的一亩三分地,却忽略了不断的学习和思考。这样的生活,或许过得确实“不错”,无可厚非;但我相信,在另一个平行宇宙中,很可能有一个同样的人,却更善于学习新知识、思考新问题,他的生活,或许“更不错”。我想做的,是那个“更不错”的人。

从社会来说,一个社会要想运转正常,让成员生活幸福,必须是一个足够有效率的社会。分属熟悉不同领域的人,通过交流知识,节省了彼此的时间,这就是为社会的效率做出了贡献。也就是说,作为社会的一分子,我们所能利用的他人的知识越多,这些知识的质量越高,利用的难度越低,我们自己工作生活的效率就越高,他人为我们提供服务的效率也就越高。伟大的经济哲学家哈耶克早就发现,社会中除了存在劳动的分工,还存在知识的分工,社会发展、达致均衡的过程,就是把分散在个人之间的知识顺利协调起来的过程。

就我对中文技术资料的了解,哈耶克的观点真是伟大的洞见——网上的中文技术资料,细心整理的很少,“无责任转载”居多,即便有交流,许多也局限于小圈子的彼此欣赏。其直接后果,就是大家时常为了一个简单的问题费尽周折,也导致论坛里总是出现重复的问题……中文开发世界的整体水准不尽如人意,缺乏高质量的知识协作,肯定是原因之一。

故而,我时常为自己没有能迅速发现和利用其它知识,浪费了时间而惋惜,同时也为被正则表达式困扰的朋友而惋惜;基于此,就更加感激坦诚贡献自己的知识,指点、帮助我解决不熟悉领域问题的朋友。所以,我要把自己关于正则表达式的经验悉数总结出来,整理好,写成一本书。它或许比不上《精通正则表达式》,但终归是自己的知识总结,除去讲解了功能,还点出了自己学习时犯过的错误,更提供了常见开发问题的解决方案:正则表达式问题的分类和解决步骤、URL转发的规则、中英文混排文本的处理、正则表达式中使用Unicode的细节……

其实,这也是我长久以来的梦想:我不希望看到更多的朋友同仁,为了这类已经有现成答案的问题,再浪费时间和精力,尤其是在大家生活压力都很大的今天。我可以尽力为大家写各种表达式;但我更希望这本书能成为“木牛流马”,跨越时空的距离,为更多的人送去便利。当然,其中也有一点私心——如果这本书真的能帮到大家,它也可以分担我亲自帮各位同仁解决正则表达式问题的压力;这样,我也有更多的时间,再学点新知识,再思考点新问题罢。

说说我理解的“自我管理”

在很长的时间里,我都认为真正要做一点事情,只能来自日复一日的钻研,如“水滴石穿”那样,心无旁骛地持续做下去,才可能成功。可是,这样的生活必然又很枯燥乏味,许多人看来甚至不可理喻——那么,那些既能把事情做成做好,生活又充满趣味的人,他们到底是怎样生活的?除去运气,他们还有怎样神秘的力量?这些问题我想了很久,也实践、反思了很长时间,后来逐渐得到的一个结论:仅仅日复一日的钻研,苦行僧的做法,其实是不够的,更重要的因素,恐怕是自我管理。

“自我管理”听起来是个大词,细说起来,却并不难。古话说,没有规矩,不成方圆。那意思是,无论形态如何,总是要有一定的规则和模式。任何一个组织:学校、公司、单位、社会,总需要这样或那样,硬性或柔性的规则来约束,才能维系,才不会散架;但是个人的生活,往往在这方面有所缺乏,所谓“自我管理”,可以理解为,认识、培养、建立、维护自己生活的规则和模式,然后才能让自己的生活变成某种样子(恐怕没有人希望自己的生活是一盘散沙,毫无章法可言)。

以我的经验来说,“自我管理”主要包括以下三个方面:

一,自我认识。认识自己,需要培养“旁观”能力,建立看待自己的全新视角。我们都有感觉,自己有时会“莫名其妙”做一些事情。许多人把这类行为归结为“感性”,但这并不正确。许多“莫名其妙”的行为,其实是自己的理性未能充分发挥的结果。我自己就有很多经历:明明可以准备周全再动手的事情,却“稀里糊涂”就开工了,结果多费许多时间精力;再比如,犯困了就认为自己休息太少,而没有认真想过提高休息质量,增加体育锻炼,其实也可以保证精力。这类事情发生在人家身上,我们可能很容易看出是“不够理性”,但发生在自己身上,就往往找出各种理由。可是,自己的情况到底是怎样,自己其实是最有可能认识清楚的,所以,学会旁观自己,加深对自己的认识,生活就可以少走许多弯路。

而且,即便是“感性”的行为,也可能是有章可循,可以认识的。仍然拿我自己做例子:生活中,情绪会起伏,有时开心,有时失落。以前我总觉得,这些是无可避免的,“坦然面对”就好。但后来我尝试去思考,遇到什么样的事情,我会开心;遇到什么样的事情,我会失落。这些事情,到底值不值得我开心或失落?为什么有时候听了其他人几句话,自己的情绪就会大不一样,我能不能自己想到这些话,这样就不用再借人家的口说出来?必须承认,思考这样的问题确实有些困难,可是一旦你认识了自己情绪的规律,许多问题就迎刃而解了,想放松的时候可以更尽兴(不用背着包袱去开心),生活的负担也减少了很多(大可以“清醒”地装糊涂,忽略许多事情)。

二,自我克制。认识自己到一定程度之后,我们就摸清了自己生活的特点和边界。与自己期望的生活对比,就容易看出有多少重复,哪些地方要扩展,哪些地方要收敛。一般来说,扩展的难度并不大——是你真正想做的事情,总会有动力去做的;收敛的难度却大得多,许多东西,我们已经“习惯成自然”了,改变习惯,不是容易的事情;更重要的是,社会上,诱惑总在不断地冒出来;生活中,惰性总在不断地渗透出来。这时候,自我克制的重要性就体现出来了:诱惑也好,惰性也好,往往并不是我们真正期望的,必须把它们拒之门外。

而且,自我认识更深刻,自我克制的力量也就更强。比如说,长假的前几天,往往是工作和学习最松懈的时候,大家都“无心”,更多地在消磨时间。但是我仔细想想,自己正处在怎样的阶段,还有哪些事情要做(即便近期手头的事情做完了,也可以提早开工长期的、以后的计划),如果发现“无心”地消磨这些时间,自己其实并没有太多收获,反而可能需要将来多花更多时间来弥补,就更能克制自己——不仅仅是意志的力量,还有理智的力量。

三,自我提醒/监督。必须承认,我们都是固执的,习惯的养成,生活的改变,都不是一蹴而就的。有些问题,即便我们能认识清楚,也足够克制,仍然不能迅速解决,这时候就需要对自己的提醒和监督了。它们可以提供持续不断的反馈,在反复的刺激下,习惯才能养成,生活才可能改变。

自我提醒/监督的有效办法是要不断地反思、总结。我刚开始开车的时候,“自然不自然”地喜欢急加速、路口抢红灯,虽然能想明白这样并不好,也有足够的克制力,但还是有时候“无意识”地做这类事情。为了戒除这不好的习惯,我每次熄火下车,都要想想自己这一路有没有急加速,有没有抢红灯,如果有的话,一定要再三提醒自己,以后不能这么干。这样过了一段时间,我确实能够“自然”地、心平气和地开车了。再比如,我时常会给自己制定一些专业书的阅读计划,预计是每天都要看,但往往因为各种原因中间有空隙、间隔。为了避免这种情况,如果昨天坚持阅读了,我会在当天的日记里给自己一些积极的反馈,否则就要说明理由,提醒自己今天绝不能空缺。这样持续地提醒/监督下来,即便计划中有错漏,有变故,也不会影响整个局面(要补充的是,写日记确实是非常好的提醒/监督手段,这是我的亲身体会)。

看到这里,有人可能会说,即使做到上面这三方面,能够自我管理,生活不是同样枯燥乏味吗?答案却是否定的。前面说过,没有规矩,不成方圆。大多数人都希望自己的生活能变成理想的样子(即便做不到,也要接近),这样内心才更舒服,更满足。身为成年人,你基本不能指望依赖他人来约束和管控自己——即便有人愿意这么做,你也未必会舒服。这时候,自我管理的重要性才体现出来。

而且,自我管理也不等于苦行僧式的生活。有个笑话说:程序员为什么要在床边放两个杯子,一个有水,一个没有水?因为他不知道自己夜里是要喝水,还是不要喝水。从另一个侧面来看,它也说明一个道理:不管要不要喝水,至少要有个杯子。同样,生活可以很随意很闲适,也可以很充实很匆忙,无论它是什么样子,你至少要能如愿管理自己的生活——该放松的时候要能放得开,该收拢的时候要能收得拢。而这,正是自我管理的意义所在。

【翻译】我为何爱读代码?你为何也应当爱?

我为何爱读代码?你为何也应当爱?

原文:Why I Love Reading Other People’s Code And You Should Too by Alan Skorkin

翻译:Yurii

我恨读代码

我发现,许多程序员都讨厌读代码——拜托别掩饰了,承认吧。差不多每个人都喜欢写代码——写代码乐在其中。可是,读代码真是不容易,而且还很烦人,又无可逃避,其他人写的代码总是很垃圾(即便不说,我们心里也这么想的)。即使自己写的代码,过几个小时再看也有点垃圾,过的时间再久点,就更垃圾了。那么,还有什么理由去看别人的蹩脚代码,而是不自己写几手漂亮的?能不能暂且忽略这个问题,花上几个小时看别人的代码,再回头来看自己的是不是还那么漂亮?即便有位大师坐在你面前,如果你不能从他身上学习,你永远也成不了大师。办法之一就是找到这么一位大师,让他手把手地教会你全部知识。有这可能吗?——当然有,只是很难遇到这顶好的运气。不过你也不必奢求那么幸运,做程序员这行就很幸运,因为大师们的所有思想和技艺都凝铸在他们的代码里,供我们学习。你要做的只是阅读代码——当然,如果有人给你一点点地讲肯定更节省时间,但这基本属于痴人说梦。换句话说,要相当个好木匠,得仔细研究大量的精美家具。

我热爱读代码,我总是直观地认为读代码的收获很大,没错,它可能有点讨厌甚至烦人,但你的收益绝对大过这点麻烦。举个例子,你要当大作家,是不是只关心自己写东西就够了?你可以试试看,但是估计不会折腾不出什么名堂。公认的事实是,多数大作家都是会如饥似渴大量阅读的。想写出好的作品,必须先阅读其他大作家的作品,吸收不同的风格,了解他人的尝试,然后才可以培养自己的创造力。这样,你的知识才能逐渐积累,最终你写的东西才有几分成熟,你也才会找到“感觉”。写代码也是这样,如果你不去阅读那些伟大的代码,怎么可能把程序写的漂亮?阅读伟大的代码之于程序员,就如同阅读伟大作品之于作家(我不敢掠美,这句话是Peter Norvig(译注:Peter Norvig是著名的Lisp程序员,现任Google研发总监)说的,他可不是个简单人物,所以好好记住这句话吧)。

即使上面说的你都不信,但有个事实无可否认。要想当个称职的开发人员,能熟练阅读代码是非常重要的。如今,只要不是闹着玩的项目,都是团队协作的成果,所以总会有这样的代码:它不是你写的,但你必须跟它打交道,去修改,或者去扩展。于是,阅读代码很可能就是你身上最重要最常用的能力了,咬紧牙关练好这门本事吧——而且,要快。

要像…会读代码的那些家伙一样…阅读代码

我都说不清有多少次见过这样的事情了:程序员把一段不熟悉的代码上下拖动,几分钟之后仍然一脸迷离。不久他们就宣布,这段代码根本没法看懂,更不必浪费时间了,可以想办法绕过这个问题。我不知道他们真正要做的是什么,一点点弄明白这段代码的意思,还是睁大眼睛等着开窍?阅读代码不靠成年累月死盯着看,你要做的是弄懂它,把它变成自己的。下面说的是我用的一些技巧,但不是全部,不过我觉得这些非常有用。

看代码看到目光迷离

1. 尝试亲自构建和运行程序。通常这一步很容易做到,比如你看的是真正运行的工作代码时(而不是不知来源的古怪代码)就是如此。不过也不是每次都很容易,如果不能很容易地构建和运行,你可以在完成构建和运行的过程中,认识到代码的高层结构。而且,阅读工作代码,你会非常熟悉如何构建项目。构建通常是复杂的,但是了解构建过程,知道代码是如何变为可执行程序的,会大大加深你的理解。

2. 别死盯细节。读代码要做的第一件事,是找到对代码的结构和风格的感觉。开始应当浏览,并且努力找出各部分代码都在干什么。这样你能熟悉整套代码的高层结构,也会明白你正在看的是什么样的代码(重构良好的,还是乱成一团的)。这时候你要做的就是找到入口(可能是main函数,也可能是servlet,controller之类),看看下面的分支是怎么展开的。这一步不要花太多时间,你对全部代码更熟悉之后,随时可以退回来。

3. 确保理解所有构造(construct)。除非你非常精通这门编程语言,否则多半还有些东西是你不知道的。在概略了解代码的阶段,要记下每一个不熟悉的构造。如果这样的构造有很多,下一步就不言自明了。如果搞不懂代码行为的意义,你什么也干不了。即便你不熟悉的只是少数构造,仔细观察推敲没准也是好事。你可能会找到一些以前不知道的关于这门编程语言的知识,我就很乐意为此花上几个小时。

4. 待熟悉了大多数构造之后,就可以搞几次随机的深入探查了。做法类似第2步,快速浏览代码库,但是这次要随机抽几个函数或者类,一行行地看下去。真正的考验现在才开始,但你的收益也是从这一步开始显现。主旨是:真正深入到你所阅读的整套代码的概念体系(组件结构)当中。这又是一个速度快不起来的步骤,但是在这一步,一定要尝试深入理解若干繁杂的细节。和第2步一样,在这一步,每次你多了解了一些上下文再回头看看,你的理解就更深入一些。

5. 前几步中肯定还有你不明白的地方,现在最合适的就是跑几个测试,看看已有的测试。测试很可能会大大打消你的疑惑,加深你对所测试代码的理解。我时常不能理解,为什么有些开发人员在阅读和理解代码时,忽略严密而精巧的测试套件。当然,也有时候是因为没有测试程序。

6. 如果没有测试程序,这时候就该写上几个。这样做有很多好处,它会加深自己的理解,它可以完善整个代码库,在阅读代码的时候也在写代码,这样对已有代码和你都有好处,你也可以真正动手参与进去。即便有现成的测试程序,为了加深自己的理解,你也可以再写一些。测试人家的代码,一般要求换个角度思考,之前你感到迷惑的概念也会变得更清楚。

7. 把弄不懂的部分拿到单独的程序中来。我发现,读代码时这样做,哪怕只是为了调节阅读的节奏,也是非常有乐趣的。即使你不理解代码的底层细节,也可能会对代码的功能有些高层面的想法。那为什么不把一些功能抽到单独的程序中测试呢?如果只运行一小段程序,debug就容易多了,而且这样的过程反过来又会加深你的理解。

8. 代码很乱(dirty)很糟糕(smelly)?那么重构吧。我可不是建议你把整个代码库推倒重来,但是重构一些部分确实可以让你的理解更上层楼。一开始要做的是把你明白了的功能变为独立的函数。在你真正理解之前,重构之前的函数只是看起来没问题,而重构可以把它们变成你想要的样子。依靠重构,你可以把代码变成自己的,而不要全部重写。好的测试程序可以帮上忙,不过如果你没有,就一边测试一边重构吧,而且只改动那些你确认弄懂了的功能。即便测试看起来太少太不完善,也要相信你自己的开发水平,有时候你只管大胆尝试就好(如果确实需要,总是可以回退(revert)的)。

9. 如果上面说的都不管用,就找个同伴跟你一起读代码。能从读代码中受益的可能并不只有你一个人,所以不妨抓住其他人,一起阅读。不过别找专家,他们给你的解释都是高层面的,这样看代码时注意的那些细节就都被忽略了。如果找不到人一起阅读,你又实在看不懂,有时最好的办法就是问别人。可以问你的同事,如果你在读的代码是开源的,也可以在网上问问其他人。记住,这只是最后的办法,不要一开始就这么做。

如果时间很紧张,短时间内必须弄懂某些代码,上面的步骤中只能选一步,我会选择重构(第8步)。你可能没法明白太多东西,但你肯定可以理解真正动过的部分。无论时间是不是紧张,你要记住的是:如果你第一次接触重要的代码库,肯定不能一下子就看懂,甚至不可能很快看懂。你可能需要耐心读上几天,几周甚至几个月——坦然面对就好。即便有专家坐在你身边,也省不了太多时间(我写的关于教和学的系列文章最后一篇就会谈这个问题)。如果你读(或者写)代码的耐心足够,方法得当,你肯定能成为对项目所有方面都非常熟悉的人,也是大家对代码库有问题时出面解答问题的人。你也可以不阅读代码,选择成为那个总想找人来解释的家伙。我想要做哪样的人,我自己很清楚。

抓住阅读代码的机会,别错过

我们都喜欢新写代码,它的诱惑力在于,我们能搞定问题。起码,这次搞不定,下次可以搞定。真相是:你在实践中不断提高,永远不可能一下就彻底搞定。这就是新写代码的价值所在,你在练习,你的水平在提高,但是阅读和改动其他人写的代码也很有价值(至少不亚于自己重新写),从中你学习到的不光是有价值的技术知识,还有关于整个工作领域的知识(毕竟,代码才是文档的最终形式),这种知识通常更有价值。

每一段不遵循传统的,莫测难懂的代码,都是有价值的。你知道我说的是什么,虽然它看起来一团糟,但本意并非如此(也可能因为它是Perl代码:))。每次我看到这样的代码,我都这么想。不妨把阅读它当作猜谜游戏,想想你能学到什么。是的,这很折磨人,但必须承认,你也希望能动手就能写出这么糟糕的代码。如果你花时间阅读这样的代码,你肯定更可能写出这样的代码——这倒不是说,你一定会写这样的代码,但你肯定希望自己能够。最后要说的是,态度总是非常重要的。如果你把阅读代码看作闲杂事,那它就是闲杂事,而你肯定会逃避,但是如果你把它看成机会,事情就不一样了。

朝三暮四,还是朝四暮三?

朝三暮四是个老典故:古时候宋国有个人养了一群猴子,早上喂它们三颗果子,晚上四颗,猴子就恼怒;如果改成早上四颗,晚上三颗,猴子就高兴了。小时候听了这个故事,总觉得猴子太傻:反正每天都是七颗果子,何必在乎早晚呢?长大了做许多事情也是如此,反正总量不变,朝三暮四还是朝四暮三,只有时间的差别而已,想找出什么分别都是徒劳,还不如索性从容点。而且,许多人的潜意识里似乎也这样认为的,至少争辩起来,许多人都会这样反驳,典型的句式就是“反正……,何必呢?” 可是,我又逐渐发现,有些事情似乎不是这样的。

就从生活的小事说起吧:现在物价飞涨,当过家的人都知道,有些菜简直是一天一个价,许多事情就不再是“早晚一样”了,能赶早的就得尽量赶早,否则,拿同样的钱,就买不到同样多的菜,要买同样多的菜,花的钱就不一样。换句话说,在迅速变化的形势面前,朝三暮四还是朝四暮三,就不再只有时间的差别,而是有了实实在在的不同。

而且,即便不是在迅速变化的形势下,朝三暮四和朝四暮三,也可能存在真正的分别。还是拿我自己当例子,我生活还算规律,晚上一般十二点左右睡觉,早上六点半起床,之后要锻炼、读读书、收拾收拾,八点多出门上班,时间充裕,动作从容,自己也比较满意。可是有一天,周老师跟我说,晚上早点睡觉,早上早点起床,这样可以做的事情多得多。开始我并不相信,抱着怀疑的态度尝试了几天之后,发现果然如此。可是,这是为什么呢?我仔细思考之后,终于找到了原因:我自己习惯每天要认真读点书学习点资料,大概是每天2小时左右,以前因为早上六点半起床,留给看书的时间大概是二十到三十分钟,刚刚进入状态,想清楚几个题,就得去忙别的了。提早到五点半起床之后,留出来看书思考的时间就多了很多,夸张点说,可以很从容地安排两节自习课。相应的,晚上不必看那么长时间的书,也更容易保持清醒的头脑,效率也高了不少。看来,“朝三暮四还是朝四暮三”的道理,也可以用在学习上:相比之下,“每天学习xx小时”这样的目标,还是显得太粗了,更细致更妥善的安排,完全可以收获更好的效果。

前些年我读冯仑先生写的《野蛮生长》,也见到了道理:年轻的时候,到底是多玩乐一些好,还是多积累一些好?对这个问题,他似乎并没有给出明确的答案,如果一生中用来积累的总量和玩乐的总量差不多,年轻的时候多积累一些,虽然看起来玩的少了点,但年纪大的时候收益更多一些,玩起来的后顾之忧也少一些;如果年轻的时候玩得多一些,老了就得花更多的精力补上积累的课。我想这说法确实有道理,此类问题也确实不宜从“总量一定”的角度来看:积累和玩乐之间,到底是选择朝三暮四,还是朝四暮三,它们之间,远远不只是时间的差别。

从QQ大战360想到的

按:QQ与360的大战已经持续一段时间了,而且显然成了最近的热点。网上网下,大家都在讨论,我也有些看法。不过,各方动态和大战进程已经有很多详细的报道,这里不赘述,只说说我的想法。

公关的新形势

公关(PR,Public Relation)是现代企业不可忽略的一面,无论是推广品牌价值、营造良好形象、应对负面信息,都离不开公关。传统的公关往往更侧重也更善于与媒体打交道,因为媒体几乎“决定”了公众的情绪——至少是垄断了情绪的表达。但是,随着博客尤其是微博的兴起,越来越多的个人成为了“自媒体”(we the media),即便在传统媒体的擂台上打了胜仗,也往往无法堵住所有用户的嘴,不一样的声音仍然会发出来,传播开来。“公关”丢了“公(公众)”,只剩下“关(关窍)”,自然成了无本之木,效果也大打折扣。

在这次的大战中,QQ和360的公关策略就是两种思路的典型代表。QQ更“愿意”(姑且这么认为)使用接受专访等方式发布和传播信息,立足点也多是“对方这么做,会把我们(QQ)如何如何”的逻辑(这更适合教室,而不是广场),微博上发布的信息也以“通告”口气为主,说是“以用户为核心”,却没有体现和传达出这种理念,更多的是自顾自地论证“不以用户为核心就没有腾讯的成功,没有全球第三的互联网公司”。这样的战法,似乎更希望也更合适在媒体擂台上跟360“一对一”,由专家点评、裁判论断,与普通人的感受相差十万八千里;然而昔日台下默不作声的观众早已登上擂台,感同身受地近距离观战,他们可以影响甚至决定舆论形势。

相反,360更多通过微博、论坛进行互动,反馈迅速而精准,而且强调始终“用户(您)会受什么影响”,而不是“我们(360)会受什么损失”。在公众表达渠道日益丰富,表达意愿日益强烈的今天,两套武功的高下立现。据我观察,QQ酝酿出台每一招都很正式,义正辞言,但360都可以迅速以草根形式应对,以巧劲化解;几个回合下来,360在公关上已经确立了完全的优势。

QQ以IM为核心的弊端

QQ庞大的“帝国”,始终是以IM为核心的,其它业务也多是以IM为入口和推动力。这样的好处是,具备足够黏性的IM能为其它业务提供可靠的依托和支撑,弊端则在于,一俊遮百丑——其它业务相对羸弱甚至不够称职,平时却没有机会暴露出来,比如上面提到“不称职”的公关就是如此。

QQ的公关的不称职,不但表现在缺乏应对新媒体、新形势的能力,而且在一些基础方面都很差劲。比如在微博中说“这种“云查杀”模式的指令来自服务器后台,在远程遥控安装在2亿台电脑里的360安全软件。这甚至是连微软、谷歌等国际互联网巨头也没有的超级能力”,措辞失当,贬损变成了褒扬;又比如在新闻发布会中,其公关经理前一分钟还说“昨晚腾讯一万多名员工,彻夜不眠”,后一分钟又说“其实作为有6千多名员工的公司我们有很多的办法结束这场战斗的”,且事后既没有“公关”修改此错误(照道理说,公司员工数目是一个相对稳定的常量,也无须保密),也没有给出解释,实在让人大跌眼镜;很难想象QQ帝国的公关部是这样的素质,可能的解释是,因为IM太核心、太显眼,公关部门的羸弱被掩盖了。

IM巨大用户量给QQ带来的好处,有时也可能变成坏处。前几个月QQ先后推出了“植物精灵大战格格巫”和“葫芦娃大战蛇妖”两款游戏,上线就引起强烈负面反响,旋即下线。我听闻这两款“山寨”游戏并非公司战略,而是个别部门自作主张的结果,他们认为随便山寨一个热门游戏,傍上QQ用户这棵大树就可渔利,不料恶评如潮,公司紧急叫停。没错,QQ确实模仿过不少产品,但做的成功的模仿,都离不开周密策划与精心投入(这就是我反对把QQ的成功简单归因为纯粹“模仿”的理由)。此类“仓促退出又迅速召回”的草率举动,对小公司来说或许无甚影响,但由QQ推出,造成的印象就是QQ恣意山寨,借IM入侵他人地盘,即便迅速召回也是赔了夫人又折兵,恶劣的印象一经留下,就难以磨灭。此次大战中,其它许多力量都暗中观战、巴不得QQ落败的心理,或许也与此类印象有关。

我们应该怎么看

之所以提到这个问题,主要是因为昨天看了霍炬的这两篇文章(流氓的背后是什么金山的流氓事)后的留言。大多数留言可以这样概括:要么“支持360”,要么“支持QQ”,要么不分黑白地大骂,却根本没读懂,甚至也没看文章的内容。
这里又不得不重弹“独立思考”的老调,所谓“独立思考”,就是不要“抽象支持”360或者QQ来“保持立场”,也不要笼统地“各打五十大板”以示公平,而要根据具体事件来判断。很可能在这件事情上是360有道理,而在那件事情上是QQ有道理;也可能,在某件事情上,QQ和360都不是“完全有道理”或者”完全没道理“,而是“各有一部分道理”或者“各有一部分错误”。只有摆脱情感好恶的垄断,脱开抽象笼统的概念,细致到具体的问题,仔细听取、分析他人的看法,才算得上真正具有了“独立思考能力”。

正则表达式的与或非

今天我的同事老赵 @jeffz_cn 问我,有没有办法用正则表达式匹配“不包含某个字符串”的文本,正好,我在写作的《正则表达式傻瓜书》中也提到了这类问题,就把这一节放出来,给大家参考,也希望大家多提建议(尤其是配图方面)。

正则表达式的与或非

我们都知道,写正则表达式有点像搭积木,复杂的功能总可以拆分开来,由不同的元素(也就是子表达式)对应,再用合适的关系将它们组合起来,就可以完成。在这一节,我们讲解常见的与或非关系的表达。

“与”是最简单的关系,它表示若干个元素必须同时相继出现,比如匹配单词cat,其实就是要求字符c、字符a和字符t必须同时连续出现。

正则表达式表达“与”关系非常简单,直接连续写出相继出现的元素就可以,我们可以想象,在各个元素之间,存在看不见的连接操作符·,比如上面匹配单词cat的正则表达式,就是『cat』,我们可以将它想象为『c·a·t』。

“与”关系也不限于字符之间,任何子表达式都可以用它来连接,如果我们把上面单词中的a替换为字符组『[au]』,表达式就变为『c[au]t』,你可以想象为『c·[au]·t』。

“或”是正则表达式灵活性的重要体现,我们可以规定某个位置的文本的“多种可能”,比如要匹配cat或是cut,在正则表达式看来,就是“字符c,然后是a或u,然后是t”。

如果“或”的多种可能都是单个字符(一般要求ASCII字符,中文字符等多字节字符的情况,可以参考本书专门论述的章节,此处仅以ASCII字符为例),就可以用字符组来表达“或”的关系,比如上面的cat或者cut的情况,正则表达式写做『c[au]t』,其原理如下:

更复杂的情况是“或”的多种可能,并非都是单个字符,有些可能是多个字符。比如,我们可以看一个更复杂的例子,不仅要匹配cut,还要匹配c开头、t结尾的单词chart、conduct和court。也就是说,在开头的c,结尾的t之间“可能”出现的是:uharonducour。

遇到这种情况,就不应使用字符组,而应当使用多选分支『(…|…)』,将各个“可能选项”列在多选分支中。于是,正则表达式变为『c(u|har|onduc|our)t』,其原理如下:

关于多选分支,还有两点要补充:

多选分支也可用于“每个选择都是单个字符”的情况,比如『c[au]t』写成『c(a|u)t』是没错的,但字符组的效率要远高于多选分支,所以,在这种情况下,推荐使用字符组『c[au]t』;

默认的多选分支『(…|…)』使用的括号是会捕获文本的,也就是说,括号内的表达式真正匹配成功的文本会记录下来,匹配完成之后可以提取出来,具体到上面的例子,就是我们有办法在匹配完成后“提取”出u或har或onduc或our。但许多时候,我们需要的只是整个表达式的匹配,而不关心“匹配时到底选择的哪种可能情况”,在这种情况下,我们稍加修改,使用“不捕获文本的括号”,可以提高效率。不捕获文本的写法也很简单,只是在开扩号之后加上字符『?:』,也就是『(?:…|…)』,具体到上面的例子,就应该写成『c(?:u|har|onduc|our)t』。这样做虽然繁琐点,但效率有保障,阅读起来也不困难,我推荐养成这种习惯,只要用到了括号,就想想是否真的要捕获括号内表达式匹配的文本,如果不需要,就是用不捕获文本的括号。

“非”看起来简单,其实是最复杂的,以下分几种情况讨论。

首先讨论针对字符的“非”:不容许出现某个或某几个字符。这是最简单的情况,直接用排除型字符组就可以对付,仍然用上面的例子,如果要匹配的单词是c开头、t结尾,中间有一个字符,但不能是u(也就是说,整个单词不能是cut),直接用『c[^u]t』就可以了,若中间的字符不能是a或u(也就是说,整个单词不能是cat或cut),则表达式改为『c[^au]t』。

如果你认真读过关于排除型字符组的章节,肯定会知道,这个表达式能匹配的只是cot之类的单词,因为中间的排除型字符组『[^au]』必须匹配一个字符。可是,如果我们还想要匹配chart、conduct和court,怎么办?最简单的想法是去掉排除型字符组的长度限制,改成『c[^au]+t』——不幸的是,这样行不通,因为这个表达式的意思是:c和t之间,是由多于一个“除a或u之外的字符“构成的,而chart、conduct和court,都包含a或u。

我们回头仔细看看这个“非”的逻辑,我们发现,其实我们要否定的是“单个出现的a或u”,而不仅仅是“出现的a或u”,所以才出现这样的问题,要解决这个问题,就应当把意思准确表达出来,变成“在结尾的t之前,不容许只出现一个a或u”。想到这一步,我们就可以用否定顺序环视『(?!…)』来解决了,它表示“在这个位置向右,不容许出现子表达式能够匹配的文本,我们把子表达式规定为『[au]t\b』(最后的『\b』很重要,它出现在t之后,保证t是单词的结尾子母)。

有了这点限制,匹配a和t之间文本的表达式就随意很多了,我们可以用匹配单词字符的简记法『\w』表示,于是整个表达式就变成了『c(?![au]t\b)\w+t』。请注意,这里出现的并不是排除型字符组『[^au]』,而是普通的字符组『[au]』,因为否定顺序环视『(?!…)』本身已经表示了“否定”的功能。

如果我们再进一步,“整个匹配文本中都不能出现字符串cat”,要怎么办呢?许多人的思路就是借鉴处理“或”关系的思路:既然字符组对应单个字符的情况,多选分支对应多个字符的情况,那么在否定时也是这样。可惜,正则表达式并没有提供与多选分支对应的“否定”结构,那么,应该怎么办呢?

解决的办法还是得依靠否定顺序环视——“整个匹配文本中都不能出现字符串cat”,换句话说,就是“在文本中的任意位置,向右,都不能出现该字符串”。因此,我们用两个锚点『^』和『$』,分别匹配整个字符串的开头和结尾位置,再用否定顺序环视『(?!cat)』表达“不能出现字符串cat”。

即便知道了原理,也不见得能写对正则表达式,比如『^(?!cat).+$』就是不正确的,因为它只限定了在文本的开头(也就是『^』)右边不能出现cat,而我们真正要做的是,在文本的每一个位置右边,都不能出现cat,所以应该改成『^((?!cat).)+$』;但这还说不上完美,根据前面提到的关于括号捕获的知识,因为此处并不需要括号捕获的文本,所以最好使用非捕获型括号『(?:…)』,最终我们得到的表达式就是『^(?:(?!cat).)+$』。

我翻译的几个步骤

提高自己的效率,做到事半功倍,是我们都希望达到的目标。如何达到这个目标呢?根据我的经验,不断反思、总结自己做过的事情,是很有成效的办法。翻译,也是这样,下面是我自己总结提炼的翻译步骤,给有兴趣的朋友作参考。

第一步,通读

通读很重要,却被许多译者忽视,他们往往认为,自己已经了解原文的“意思”,可以直接下笔,遇到问题“见招拆招”即可,翻译前通读原文,完全是浪费时间。

但是,事实似乎并非如此。我们翻译文章,要做的并不是“代替作者写文章”,而是“解释/传达作者的文字”。而文字本身是内涵丰富的,除去“意思”本身,还有用词、结构和风格等诸多方面。比如用词,原作者往往可能用一些双关语、多义词,在不同场合表达不同的意思,译者则应当尽力找到“对应”的双关语、多义词,这是个苦差,因此就更需要译者有大局观,知道原文中该词出现在哪些场合,都表示什么意思,才好取舍;再比如结构,原文中很可能有前后关联的典故/故事,有时甚至横跨几个章节,如果没有通读原文,翻译时就容易遗失原文的逻辑结构;风格也是如此,好的翻译讲究贴合原文,这种“贴合”,当然也包括风格的贴合,原文是轻快的,就不能翻译成沉重的;原文是严肃的,就不能翻译成平淡的。

当然,通读只是提供了观察鉴别这些“意思之外”的方面的机会,并不能保证译者能“准确把握”这些方面。但是不通读,却是绝不可能“把握”的。要想提高自己的通读效率,可以参考郝明义先生翻译的《如何阅读一本书》。

Continue reading 我翻译的几个步骤

怎样翻译更地道:尾大不掉的处理

常做翻译的人都知道,英文讲究结构严密、成分齐整,我们遇到再长的英文句子(哪怕是多个从句,或者有长长的插入语),只要能正确解析结构,都不难理解;中文则更追求“写意”,不太受形式规则的拘束,好的中文能营造出“行云流水”的感觉。单独看这两种语言的特点,各有理由,但是做起翻译来,就难免出现冲突,“尾大不掉”就是突出现象之一。

这里的“尾大不掉”,借用了余光中的说法,问题并不在并不是“尾大”,而在于“身躯臃肿”——“头”和“尾”是必须要同时出现的,但之间的内容太多,等看到“尾”,往往感觉突兀,但没有“尾”,结构又不完整。比如以下三个例子:

就是为什么他历经磨难也绝不放弃,一定要回来的原因

桌子边坐着一位漂亮的、大方的、温和的、优雅的女士

就像花儿到了季节会开放、小鸡到了时节要破壳一样,小孩子到了年纪,自然就学会走路了。

the reason why……、多形容词并列、as开头,也都是英语中自然的现象,并无不妥(as的另一个用法请参见《怎样翻译更地道:as somebody said的翻译》);但这些英文中本来可以紧密联系不必拆分的词语,翻译成中文,必须改成“为什么……的原因”、“就像……一样……”,而本来很常见的多形容词并列,也要插入到“坐着一位……女士”中间。于是乎,“尾大不掉”就露头了。这样的译文,并不妨碍理解,但读起来多少有些梗滞,在阅读长长的中间部分时,总得“惦记”最后的那个尾巴。

按照我的经验,要想让译文读起来更加舒服,小修小补是不够的,必须对“尾大不掉”动手,彻底打破“头……尾”的形式结构。比如,以上三句话可以分别改为:

因此(所以/故而),他历经磨难也决不放弃,一定要回来。
(可以这样译,是因为这句话一般出现在真正的原因之后)。

桌子边坐着的一位女士,漂亮大方,温婉可人
(关键做法是把形容词“自然”地挪到后面去,但是,这样处理也要求译者能灵活熟练锻造四字短语:有时需要将两、三个词合并到单个四字短语,比如“温婉可人”,也有时需要将单个词扩展为四字短语,比如“性情温和”)

花儿到了季节会开放,小鸡到了时节要破壳,小孩子到了年纪,自然也能学会走路。
(这类句子最好处理,直接去掉“就像……一样”,最后的主句酌情添加助词即可)

P.S. 我的另一点经验是,如果想译出好的文字,最好还是抽点时间读读古文,比如上面第二、三个例句,如果你熟悉介绍人物的通用句式,以及诗经中的比兴手法,多半不会译得生硬。

看得见的和看不见的

18世纪的法国,有位叫巴斯夏的经济学者写过一系列妙趣横生的短文,我印象最深的一篇叫做《看得见的与看不见的》:

詹姆斯•“好人”先生的儿子贪玩打破了一块玻璃,“好人”先生不得花6法郎去换玻璃,于是玻璃匠得到了6法郎。这时候有人说:快看哪,如果不是那个孩子贪玩,玻璃匠就得不到那6个法郎,资金就不会流转……由此引申开去,整个行业、整个经济体也会受益。
“且慢,让我跳出来大喊一声,”巴斯夏写道:你只看到了你看得到的,没看到你看不到的,即便贪玩的孩子没有打破这块玻璃,好人先生也不会把那6个法郎埋到地下,他可能用来修鞋,于是鞋匠拿到了那6法郎;他也可能用来理发,于是理发师拿到了那6个法郎……虽然这个鞋匠/理发师是藏在影子里的,但是你不能忽略它。

这个故事令我印象深刻,倒不是因为我们身边还有不少“地震/洪水/天灾有利经济发展”的言论,而是因为我深刻感觉到:许多东西我们可能看不见,但并非不存在,如果仅仅按照我们看得见的样子去直观理解,忽略了看不见的方面,很可能会产生错误的观念。

2003年夏天,我正在复习托福考试,每天的生活就是背单词,做一两套模拟题。当时正是暑假,许多人都回家了,留下的人也大多过得逍遥,想到这自己还能坚持每天复习,我颇有些自豪。当时托福的满分是667,我每次做模拟题都有630到640,自己也很满意——复习托福不过如此嘛。考前一两周,与朋友W通电话,我告诉他自己水平很稳定。于是他问我“很稳定是个什么概念?”。我说“就是每次都有630左右啊。”“这怎么能行呢?复习这种考试就应该只有一个目标啊。”我忙问“什么目标?” 他说,“就是满分啊,要不你总这么630就满意了,考试时全部发挥出来最多也只有630。再说我们大家复习都是以满分为目标的……”  许多年后,我依然清楚记得当时自己有多么震惊和羞愧,他的话好像晴空霹雳,而我猛然发现自己之前的想法是多么可笑。于是我强打起精神,努力分析总结自己每一个错误,努力抠每一点分数。可惜觉悟还是太晚了,考试的分数果然只有六百出头。这些年来,我时常想到,如果当年我能早点看到其他人认真投入复习的样子,而不是看看自己周围就满意了(好像看到玻璃匠得了6法郎,就认定打破玻璃有益于经济发展一样),会是一番多么不同的景象呀。不过,我也因此学会了在许多事情上“较真”,不要觉得还凑合,就糊弄自己,坚持下来还是很有收获的。

过了几年,还是从W那里,我又接受了一次教训。因为打算出国留学,他开始精心准备自己的P.S.(Personal Statement,个人陈述),我见过其他朋友准备的P.S.,虽然大家都花了时间,但大多数人写完、投出去,自己其实并没有太多的把握;而W的P.S.,我见到的感觉就是“眼前一亮”,虽然一时说不上究竟哪里好,但可以感觉到低调的文字间散发出卓尔不群的张力。我自然要问他,这是如何做到的。他说,这份P.S.弄了三四个月,一开始觉得照网上模板写写就好,给在美国的同学看却被批得一塌糊涂,于是下来几个月里,每天都在琢磨这份文档(甚至是忍着恶心),反反复复修改,真正是“字斟句酌”,到最后才算是真正满意了,投出去后自己心里也很有底,当然,最后申请的结果也相当满意。相比之下,我也看到身边有些人,找工作的时候大言不惭地说“简历就是随便弄了弄,别介意”之类,投出去的结果自然也是“看运气”。我问过一些人,为什么不花点时间认真做做简历,至少不用说“随便弄了弄”;而回答大都是“没时间”、“不知道怎么做”、“懒得弄了”;而且,越是这样回答的人,似乎也越难找到满意的工作,于是他们大都认为“如今工作不好找”、“太难”或是“我命不好”,而别人找到了好工作就是因为“机会好”、“会钻营”…… 我见过W对P.S.的态度之后,时常觉得摆这些理由其实就是“打破玻璃有益于经济发展”——因为没有看过那些“藏在阴影里”的现象,没有看到有人可以突破“凑合就行”的局限,没有仔细观察思考过其他人是如何找到好工作的,所以认定“工作难找”、“运气不好”,这类理由固然能够自圆其说,却可能并不是真正的原因,而且,相信此类理由,最终受影响的还是自己。

我自己亲身经历的另一件事情也是如此:刚上班的时候,我总觉得每天劳累不堪,累了自然就要休息,越累就越觉得要多睡觉。可是有一天我忽然发现身边有人做的事情一点不少,也不用睡那么长时间,精力照样很好。于是我想,“累了就要靠睡觉来补,越累就越多睡”可能不见得是真正的逻辑,仔细观察那些精神很好(并非天生精力旺盛)的人,并读过一些书之后,我逐渐发现,如果能够合理安排作息时间、规律生活、坚持锻炼身体,即便每天睡觉的时间不变,甚至还要少些,精神却好得多。回头想想,正是因为我有幸看到一些人和现象,现在的精力才好了许多,否则,多半还在“太累-睡不够”的简单逻辑里循环。

这个道理还可以推开来说:多留心一些“看不见的”东西,有助于我们形成更加准确的认识。比如近来非常流行的“一万小时”的说法很流行,它的大意是,不管你天资如何、所处环境如何,认定某件事情坚持练习一万小时,总会出类拔萃。许多人听到这个说法非常激动,但真正行动起来却又推三阻四。或许对他们来说,看得见的是“出类拔萃的人其实并不稀奇,只是坚持练习了一万小时而已”,看不见的则是“身边或许就有人一直在默默练习,而在你的无聊和犹豫的时候,生命留给你练习一万小时的时间,已经越来越少了”。

争当科学的逃兵吧

我的父母都是大学生,但严格说起来,我家并不算“知识分子家庭”:我父亲是学无线电的,母亲是学分析化学的。充其量也只算是“双料理科”家庭,少点人文气息;小时候没读过什么人文经典,不过爸爸妈妈从来都不给我太多的限制,只是根据我的兴趣,讲讲各种有意思现象背后的原理。而且,托“理工科”的福,我很小就在母亲实验室用氢气充过气球,用水银温度计测过温度,用比自然教科书上精密得多的仪器制过蒸馏水;也在父亲实验室的示波器上见过各种无线电波的“样子”,在中秋节用天文望远镜看过月亮上的环形山…当然,为此也弄过不少笑话:小朋友们都喜欢互相吹嘘自己父母的工作,有的说自己爸爸是解放军,有人说自己爸爸是大干部,我说“我爸爸是研究电子枪(电子枪是阴极射线管显示器里的元件)的”,当即引来大家的不服气,而且老师也没听说过什么是“电子枪”,于是宣布我在吹牛……

读大学之后,曾有一段时间我总抱憾小时候缺了“人文经典”的课,但这些年陆陆续续看了些书,看法又有改变:虽然没动多少人文,但大言不惭地说,好歹受了点科学的熏陶。真正的科学,总是能“养住”人的好奇心,把精力引导到大千世界的奥妙中去;即便不从事尖端的科学研究,多了解一点点科学,也能大大丰富自己的认知,看到与之前大不一样的世界,生活也会因此多了不少妙趣。

但是,要保持对科学的兴趣,对我们来说并非易事。现在许多人说起“科学”,想到的要么是不苟言笑、木讷寡言的孤僻,要么是全知全能、四处指点的霸气,所以多少有些“敬而远之”的味道。我有幸从小就接受科学的“浸染”,能够以柔润自然的方式体会到科学的妙趣,欣赏知识之美,并保持至今;另一方面也时常有些惋惜,我们本身就缺乏科学的传统,当今的科普又缺乏“柔润”,所以科学或被奉为神明,或被斥为外夷,总之就是“科普不得法”,许多人抱怨生活无聊乏味,这或许也是原因之一。

不过,科学松鼠会算是科普中的异数。借用革命导师的话说,“让科学流行起来”的口号,给科普增加了中国作风和中国气派;虽然某些人觉得不够严谨,但事实是最有说服力的:以我的经验来说,活动总是妙趣横生,嘉宾也总是和蔼严谨,这正是我所欣赏的“柔润”的方式。尤其是创始人姬十三,我见他之后最高兴的是:如今终于可以正经讨论我看《恐龙特急克塞号》时的奇怪念头——“如果几千万光年外的外星人,看到了恐龙灭绝的情形,用录像机录下来,再传回地球,我们就可以知道恐龙灭绝的原因了”,这样的人作“大当家”,还有什么好说的?后来参加“科学嘉年华”的经历,更是肯定了这一点。

在北京的时候,我参加过松鼠会好几次活动,大感意外的是,有许多年轻的家长带着孩子来参加松鼠会的活动,看到他们,我总是想起自己的童年,继而心生羡慕:他们要更加幸福,因为他们遇到的科普更丰富,更好玩,也更深刻;这样的孩子,一定能从容面对科技更加发达的生活。

今天看到松鼠会“寻科学逃兵”的活动,我立刻答应帮忙吆喝两声:年轻的时候,能做点自己真正喜欢的而又有意思事情才好,哪怕累,也是有意思的累(借用韩寒的话说,等你老了回忆自己的年轻岁月,至少敢说真正做了点有意思的事情);真正对科学有兴趣的同学们,不妨大胆去争当“逃兵”,我相信,科学的逃兵,能在松鼠会“淘”出点意思。

——————————【北京 and 上海】招聘职位分割线—————————–
科学编辑
科普图书编辑
实习编辑
IT实习生
NGO合作官员
媒体品牌主管
会计
公益活动志愿者

http://songshuhui.net/job/