Monday, December 29, 2008

裘宗燕翻译的太不负责任了

我前些日子花大价钱买了一本<C++程序设计语言 特别版>,就是Bjarne Stroustrup的那本.译者是裘宗燕.

开始就看不下,总觉得词句别扭,我也没想这么多,心想可能这本书定位就是手册吧,看不下是正常的.

可是今天看了几处,发现可能不是我的问题.

这本书的翻译很有问题.比如第8章<名字空间和异常>的8.1节.最后一段是
"理想情况下,程序里的每个实体都属于某个可以独立识别的逻辑单元("模块").所以,在理想情况下,一个非平凡的程序里的每个声明都应该位于某个名字空 间里,以此指明它在程序中所扮演的逻辑角色.例外的是main(),它必须是特殊的,以便运行时环境能干特殊对待它(8.3.3节)"

原文是
Ideally,every entity in a program belongs to some recognizable logic unit("module"). Therefor, every declaration in a nontrivial program should ideally be in some namespace named to indicate its logic role in the program. the exception is main(), which must belong to global in order for the run-time environment to recognize it as special.

短短53个单词的小段落,这篇译文有好几处极具误导性的bug.
1)
nontrivial不是非平凡,trivial在这里作细小讲,trivial program指hello,world之类的小程序,nontrivial指软件行业普通的软件项目,由多个模块组成.
译者翻译成"非平凡",完全不通,金山词霸的智商才会这么翻译.

2)
be in some namespace named to indicate 的named to被译者故意忽略了.这句话的意思是每个声明都应该在某个namespace里,而该namespac的命名表明了它的逻辑角色.比如 namespace TaskHandler表明了这是处理任务的模块. Named to indicate这个从句修饰的是some namespace而不是前面一整句话.
译者直接忽略named to,把这句话的意思完全扭曲了.中文读者看上去,会理解成,"之所以每个声明都应该位于某个名字空间里,是因为这样可以指明它在程序中所扮演的逻辑角色",这种理解和原文的意思相差太远,会让读者很困惑.
真正的意思应该是"每个声明都应该放在一个命名空间里,这个命名空间的名字暗示了它在程序中的逻辑角色."
its logic role的it指的是namespace而不是前面的every declaration.

3)
which must belong to global 翻译成"它必须是特殊的",这真是莫名其妙,global翻译成"全局的"完全是金山快译也会的.难道译者故意把金山快译的作品改错了吧?

4)
其它不通的,拗口的,比如"例外的是main()"这个句子,就不再详细说了.

5)
结论,裘宗燕 sucks!

Sunday, December 21, 2008

中国人测试---不是中国人的,你就答不对

下面是一道测试题,来自于真实案例,
可以检测答题者是不是中国人,凡是答对的,可以100%确定是中国人,答错的,可能是外国人,也可能是80后(据说他们脑残).

问:
你丢了手机,被人拾了,那人问你要3500块钱赎回.跟你约好了在步行街交易,请问你现在最好的选择是怎么办?
1.带钱过去,一手交钱,一手交货.
2.请朋友过去,揍他们一顿,把手机拿回来.
3.这是敲诈勒索,报警.


上一题,你选择了3,请问警察会如何处理?
1.立案,跟你去抓贼,请上新闻记者随行.
2.立案,跟你去抓贼,不请新闻记者随行.
3.立案,跟你去抓贼,但是要你交车马费.
4.不立案.建议你跟贼讲价
5.不立案,让你去交易,有事打110.

好了,正确答案是
第一题:2
第二题:4,5

这个国家,你信警察你是SB

Thursday, December 18, 2008

Software Design不是简单的活

今天把我StatusD的代码重构了一下,开始还兴致勃勃,做到后来就发现一个严重的问题。

问题的大致是这样的。有1个下载任务,会分配给M个TailNode,每个TailNode都会给StatusD上报对每个任务的完成报告,报告分为"成功"或者"失败"。

需求1规定StatusD应该给Monitor One上报所有成功完成的任务。而"任务的成功"要求所有M个TailNode上报"成功"的完成报告。
需求2则规定,StatusD应该定期Monitor Two转发"失败"的完成报告,亦即每60m上报一次最近60m内失败的完成报告。

这两个需求看起来很简单。我是这么做的。

StatusD为该任务维护一个map<NodeIP, Status>的statusMap,每次从TailNode接收到一个完成报告,则往statusMap里增加一项。
需求1可以这样满足:
1。当statusMap的size增长到N的时候,且所有N个报告都是"成功",这个任务是成功的,上报给Monitor One
2。如果接收到一个"失败"的完成报告,则该任务算"失败"。

需求2可以这样满足:
每隔60m,遍历一下statusMap,找出所有的"失败"的status,上报给Monitor Two.

这个设计的陷阱在于,需求2要求的增量转发,但是实际上,转发的是全量的。亦即下一60m的转发包含了上一个60m转发的内容。

这个陷阱的来源是因为,最初TailNode给StatusD的"失败"的上报不仅包含了状态信息,还有事件信息,而存储到statusMap后,只维护了状态信息,丢失了事件信息。

解决办法有
1。修改statusMap为map<NodeIP, Status,Redelivered>(请勿告诉我,map只有key和alue,没有第三者,这不是问题的重点)。转发则把 Redelivered为false的element,并且把该element的redelivered改成true。
2。另外维护一个list<failed report>的列表,每次StatusD从TailNode接收到"失败"的完成报告,则不仅修改statusMap,也往这个列表写入。每隔 60秒,则把当前的list全部转发给Monitor Two,并且将其清空。

实际代码比这个复杂,任务不是一个,而是多个,每个任务对应的Node的集合也不一样。但是问题的核心没变。

第一个解决办法,会搞得代码很难看,而且遍历的效率也不高。
第二个解决办法,造成状态信息的冗余。当增加超时功能(StatusD定期检查,在规定的时间statusMap没有达到N的size,则认为尚未上报的 TailNode该任务失败)的功能的时候,扩展变得很复杂。
真是有点头疼!

Tuesday, December 09, 2008

软件工程和足球

看slashdot上,Bjarne Stroustrup对程序员说"Serious programming is a team sport, brush up on your social skills.The sloppy fat geek computer genius semi-buried in a pile of pizza boxes and cola cans is a mythical creature, best buried deep, never to be seen again."

我就想到,可以把编程看作足球.

去小区足球场踢球,你可以随便玩花式,扮演足球黑洞(足球只传进不传出).

但是如果是正式比赛,一个人只想耍花样肯定会被教练换下来.因为足球是一个team sport.

那么,跟美式足球比起来,项目经理相当于教练, 程序员相当于前锋,测试人员相当于后卫

可是足球分工更细,有正前锋,边锋,中场,左后卫右后卫.守门员.场下有替补,有二级球队,有队医,营养师,按摩师等等等等.

还有各种433,253阵形.

可是几乎所有的程序员都只叫程序员,顶多分个前台后台,以我们项目组为例,甚至前后台分工也不明确.

这么比起来,据说是高科技行业的IT,其运作成熟度甚至不如体育界!

Friday, December 05, 2008

云脑白金

这个行业,充斥了太多sales和记者.这帮人背景各异,也许是技术出身,曾经为Linux内核贡献过代码,也可能文科出身,听不懂"世界上的人分10种,懂二进制的和不懂二进制的"这个笑话.

但是他们现在共享一个特点:喜欢谈论那些飘在天上的空洞概念,并且装作很懂,以便趁机赚钱.

云计算的泡沫就是他们这样吹出来的.

就像前些年的Web 2.0一样,谁也不知道web 2.0是什么,但是到处都是sales声称自己的产品将领导web 2.0的潮流,到处都是web 2.0的创业计划书想拐一大笔风投,到处都是网站声称自己已经部署了web 2.0的升级.

新鲜劲过后,大家都觉得这个概念腻味了.现在谁也不提web 2.0了.

在这空档期,Sales和记者们心里憋得真难受.他们是不会去谈论C++和并行计算的,那些东西太明确,他们一开口,会很容易的让别人知道他们其实一无所知.

这样憋了一阵子,Sales和记者里面也是有聪明人的.有人灵机一动,把网格计算(Grid computing)这个词翻出来,改个漂亮名字云计算(cloud computing).

哗啦啦,记者和sales们又有了新把戏可以玩了.

于是我们天天看到云计算,云存储,云计算操作系统. 汉语词汇有限,我猜三个月后会有人提出云QQ,云相亲,云网游,云打酱油,云俯卧撑......

我还预计,半年之后,记者和sales们会退出一个全新概念---云脑白金.因为那是他们天天吃的东西!

Thursday, December 04, 2008

近期学习目标

这一个礼拜狂写代码,累得半死.写的时候,有些感悟.

1.UML确实是个必需品,我做设计的时候,心里大概有想法,就会画下来,但是画得是如此的丑,以至于自己都不想再看第二眼.

2.STL的容器和算法,还是要系统的学习一遍,其实也不会太久,拿出一天时间足够了.这样可以避免在需要的时候把手册翻得哗哗响,影响效率

3.代码注释风格还是个问题.很多地方觉得需要注释,但是写了注释之后又觉得这注释很白痴,简直跟代码就是同义反复.

4.automake和autoconf这两工具,需要花时间学习.这个礼拜被他们妨碍了我不少时间.

5.做设计是一件比Coding远远有趣的活动!

--
Best Regards