没想好放哪


按:今天在网上看到阮一峰推荐的《Hype Driven Development》,忍俊不禁,联想到工作中的很多经历又百感交集。趁春节假期翻译出来(练练手),与大家共享。


软件开发团队所做的软件架构或技术栈的决策,很多并没有经过踏实的研究和对目标成果的认真思考,而是不准确的意见、社交媒体的信息,或者就些是“热闹”的玩意。我称这种作派为“热闹驱动开发(Hype Driven Development,HDD)”,眼见它的危害,我赞成更专业的做法,就是“脚踏实地的软件工程”。下面我们一起看看HDD的来龙去脉,想想能如何改进。

(more…)

按:这段时间为了办理异地验车手续,费了不少力气折腾,而且发现网络上的许多答案都不准确,所以把我的流程贴在blog上,希望可以帮到大家。

北京车牌异地验车委托书开具流程

申请时间:在行使证有效期到期前的2个月(60天内)内。

申请资料:车辆行使证或者机动车登记证书的原件,最好带上一份复印件(在车管所复印需要排队、花钱)。

申请费用:无。

前提条件:车辆无违章信息(可在北京市交管局网站查询,目前已经全国联网,所以异地违章也可能有记录,不过支付宝可以办理一些异地违章)。

受理单位:北京市各车管所和车管分所(网上有说法必须到上牌注册的车管所,这是不对的)。

受理时间:早上9点到下午4点(周六日也可以办理)。

补充说明:超过行使证有效期(逾期)之后,仍然可以开具委托书并在异地验车,不收取任何额外费用,如果车辆在在逾期之后验车之前上路被抓拍,需要缴纳罚款。

拿到开具好的委托书后,加上行使证、登记证书、保险资料(有些地方还要求提供当年的车船税年票,请提前咨询),到所在地车辆检测场按照正常验车流程进行即可。

程序员有哪些职业素养?关于这个话题已经有很多资料,前段时间章显洲和我一起翻译了Uncle Bob的Clean Coder(中文名《程序员的职业素养》),通篇谈的都是程序员的职业素养,而且讲的很在理。不过今天,我想根据自己的经验和观察,谈“程序员的职业素养”的两个方面:克制和放纵。这里说的“克制”,指的是要克制自己敲代码的冲动;而“放纵”,指的是要放纵自己关于程序本身的思考。下面先从克制说起。

许多年前我刚开始学编程时,朋友曾说过一个笑话:差劲的程序员有两种,一种是开始就写main函数的;还有一种是上来就上网找各种类库源代码的。当时我并不能完全理解:编程序,不去找类库源代码,不从main函数开始,还要怎么做呢?后来才逐渐明白,上来就写main函数,或者上来就找类库找源代码,归根到底都是不能克制关于代码的冲动。直接写代码当然很“爽”,很有“成就感”。可是,这样做真的是好事吗?

在现实生活中,我确实看到相当多的程序员写代码的冲动相当强烈,难以克制。这可能是因为任何软件都需要落实为代码,拿到一个任务,直接写代码可以赋予程序员充足甚至全部的成就感。在心里想个明白,在纸上写写画画,反而成了一种难以克制的煎熬。但有经验的人都知道,程序不等于代码,程序的含义和复杂性远远超过代码;没有明晰的需求,没有清楚的头脑,没有良好的规划,写出来的代码就成了无源之水,无本之木,写的越爽,后果可能越严重。

我曾经见过一套系统,其中充满了各种状态码的条件判断,这种情况本来很正常,不幸所有的状态码都是硬编码的数字,整个系统就是一本天书:一会儿判断这里是否等于2,一会儿判断那里是否大于7……究其原因,是程序员觉得这些状态码无非就是“用数字代表状态”,所以随便选些数字就好了:2代表什么,7对应什么,自己记得就好;更重要的是,硬编码的状态码“用起来方便”,敲代码的速度大大提升——不需要查找变量,也不需要输入整个变量名。这种系统的问题相信大家都猜得到,维护和修改起来无比痛苦。所以,尽管写这些程序的程序员已经有了一两年甚至更多的工作经验,但他们身上很难说有“职业素养”。

与此相反,重构的人员采取了完全不同的方法:虽然全部硬编码看起来不爽,用起来更不爽,人人都有立刻动手改掉它的冲动,但重构时首先要做的并不是直接修改代码,而是仔细阅读整个程序,编写了一份所有状态码的图表(并且打印出来供随时查阅),再根据状态码的意义和使用场景,重新设计状态码(因为各个状态之间还存在逻辑关系,所以需要以自定义类型表示状态),最后才动手编码完成重构。事实证明,这种策略是非常成功的:阅读代码、制定图表、重新设计需要三周的时间,真正的重构只用几天就顺利完成了,而且从此以后维护和修改的难度大大降低,真正达到了重构的目的。完成重构工作的程序员,工作经验并不比最初编写程序的人要多,他们没有一开始就写代码,甚至没有花太多时间在代码上,更没有用到高深莫测的技术,但他们身上恰恰体现出了程序员的职业素养。

身为程序员,大概人人都喜欢狂敲代码带来的快感;但身为职业程序员,必须要克制写代码的冲动,在写代码之前花更多时间理解需求,设计系统,制定规划,这样写出来的代码才会更加精炼,整个程序才更有价值。我们甚至可以说,拿到需求就动手敲代码的程序员,无论有多少年经验,仍然不过是楞头青。

说完了克制,下面说放纵。此处的“放纵”其实是一个比较夸张的说法,但依我所见,用“放纵”非常有必要,因为不少程序员写的程序实在太“保守”了,矫枉必须过正。

我刚刚工作时,项目经理分给我的任务是从网络上抓些特定的信息存到数据库。这个任务我花了不少工夫完成,本以为可以赢得项目经理的表扬,结果却是劈头盖脸的苛责:“你当这是学生写程序吗?什么异常情况都没考虑?网络断了怎么办?数据库连不通怎么办?……”虽然在学校写过不少程序,但这些问题我真是没处理过,甚至完全没考虑过。可以说,在那一刻,我才真正开始理解,为什么要有异常,为什么会有强制异常处理。

本来我以为这只是自己经验不足的教训,但后来我逐渐发现,不少程序员对异常处理都相当吝啬,更乐意让自己的程序呆在舒适安逸的温柔乡里,走在万事俱备的康庄大道上——用户的输入永远是符合预期的,程序的计算永远不会出任何误差,网络和数据库连接永远是稳定可靠的……这样做最明显的后果就是,对程序员意料之外的情况,程序做不了任何处理,只能交由它所依赖的类库或者运行平台来显示最原始的错误信息,而这些信息直接暴露给客户——比如明明是网络不通,却提示 “无法解析域名”(对普通人来说,“解析域名”简直就是天书);明明是客户输入有错误,却直接抛出最底层异常(即便大公司也会犯这种错误)。

亚马逊的报错界面

几年前我自己的抓屏

每次遇到这种情况,用户即便有能力解决问题,也不知所措,只能找程序员本人来处理。如果某人开发的程序发布之后经常需要在线调试、现场维护,开发效率和质量就会大打折扣,我们也很难说哪里体现了“职业素养”。相反,足够职业的程序员,哪怕开发一个非常简单的程序,必然不会局限于正常的逻辑,而会“放纵”自己的时间精力,去考虑各种异常情况,做出合适的处理,他开发的程序就像优秀作家的作品,可以简单,也可以复杂,可以平实,也可以高深,但一定不会轻易倒下。

武侠小说里常见一些顶尖高手,用平凡无奇的招式,轻松击败对手,那是因为比起招式,“功力”和“应对”是更重要的因素,其实程序开发也是这个道理。如果我们把看得见、摸得着的代码比作某种招式,那么程序员越能克制写代码的冲动,花越多的时间思考和设计,此招式的功力就越深厚;另一方面,程序员越能放纵自己对各种意外的考虑和处理,此招式的应对能力就更强。如果成为武林高手必然有深厚的功力,有丰富的应对经验,那么要成为职业程序员,也必然要花大量精力思考代码之外的问题,处理意料之外的情况。

经过各位读者和出版社的辛苦努力,《正则指引》终于上市了,以下是主要的购买链接:

亚马逊:http://www.amazon.cn/%E6%AD%A3%E5%88%99%E6%8C%87%E5%BC%95-%E4%BD%99%E6%99%9F/dp/B007X6O6J0/

当当:http://product.dangdang.com/product.aspx?product_id=22702127

京东:http://book.360buy.com/10972570.html

China-Pub:http://product.china-pub.com/199266

有趣的是,预售阶段就登上了京东的24小时分类畅销榜,感谢大家的厚爱。

 

 

 

去年不少媒体热炒“逃离北上广”,今年又热炒“再回北上广”。逃离也好,再回也好,都与我无干,算起我的经历:北京五年半,上海一年半,下面要去广州,更贴切的说法,可算是“北走南驰”。

这种生活,虽然我之前不曾想象过,但实际经历了,却觉得不过如此——你可能觉得自己生活多年,搬家已经是巨大的工程了,但真正要搬走,才发现不过48小时就可以把全部家当打包完毕。我不知道还有多少人愿意,或者可能愿意接受这样的生活,如果你在其中,或许下面这些经验会对你有用。

心态

无论在哪里,我们生活的内容不太可能有大的变化,都是工作、休闲、交流等等,但是城市不同,形式也有不同。举个例子,同样是聚会,聚会的频度、地点、时机、谈论的话题,都有不同;我自己感觉,北京的聚会比较随意,更加“形而上”一些,上海则比较讲究,也更洋气一些。对这些差异,如果都用“好-坏”、“先进-落后”的标准来衡量,就极容易产生形成鲜明的好恶,而产生排斥感。更合适的做法,是能以开放包容的心态去对待这些差异。拥有这种心态,你可以积极体验各种细节,不但生活的体验大大丰富,回过头去看原来的生活会发现,许多“理所当然”的事情,其实没有那么理所当然,而是错落分布的——到过上海之后,我发现“去别人家玩”虽然感觉亲切,其实是比较奢侈的待遇,而政府机关和公共服务部门,竟然也可以周六办公,不需要请假去办各种手续。接触了这些,就会更深刻地了解,哪些方面值得坚持和赞赏,哪些方面需要人忍让和改进,因而在内心构建出更辽阔的图谱。

坐标感

在城市间游走,并不意味着每到一地,从头开始。所以,我们需要培养清晰的坐标感,它既包括外界的方面,也包括内心的方面。从外界来说,这是一个怎样的城市,它坐落在哪里,气候如何,它的特点是什么,它的有哪些有力的资源,它的现状是如何演变而来的……要了解这些,不但要有开放的心态,还必须有深入的思考能力,才能把所观察到的一切统摄起来。从内心来说,自己处在什么样的年龄阶段,社会角色是如何,自己成长所需要的因素,周围的环境里是否具备,如果具备,要如何去获得,如果不具备,要如何去发掘和弥补,或者下一步为了接近这样的环境,应该按照怎样的计划,需要花费多少时间……要了解这些,必须有不断的思考和反省,才能真正认识自己,也才能真正找到与环境之间的契合点,让每一段经历,成为一级台阶。如果缺失了坐标感,即便一直呆在北京这样的城市,呆下去的理由也只有空泛的“机会多”而已。

情趣

我经常遇到的一个问题是:换了城市,熟悉的环境没有了,熟悉的朋友不在了,怎么办?确实,陌生的环境,遥远的朋友,都是不可忽略的问题,但是我想,人总是要做生活的主人,不要依附外界而生活。要做到自主,情趣是很重要的方面。面对陌生的环境,有情趣的人也不会觉得枯燥乏味,总可以营造出属于自己的生活方式。比如我喜欢读书,在北京便是去国家图书馆,在上海便是去上海图书馆,不管天南地北,阅读的趣味总是保留下来的。对朋友来说,就更是如此,努力成为有情趣的人,即便不在身边,远方的朋友也难以忘记你,而且在陌生的环境里,也更容易被散发出不一样的气息,从而被识别,迅速交往到比较投合的朋友。

刚到上海的时候,我的朋友霍炬跟我说:换一个城市,就好像多活了十年,你看上海的云彩都跟北京的不一样,这是在北京根本想象不到的。这句话我印象特别深,觉得他说的特别对,也特别准——是多活了十年,多体验了十年,而不是多享受了十年。人的生活,也应该是自己规划自己做主,而不是非要依附于某个环境才可以展开;胸中有丘壑,再加上这一程程的经历,就可以收获凝练的人生。

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

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

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

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

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

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

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

http://songshuhui.net/job/

从某种意义上说,人的一生,就是不断突破个体经验的局限,解决未知问题、体验未知生活的过程——否则,我们只需要简单重复劳动,就足以应付了。也正因为如此,要避免在未知局面下的束手无策,借鉴前人/他人的经验,就是非常有效而且高效的做法。今天我要谈的这本书,正与他人的经验有关。

97 Things Every Software Architect Should Know,这是一本很“奇怪”的书,书名很“托大”内容很“平实”的书。我与这本书结缘也很奇特:去年博文视点的编辑徐定翔告诉我,正在翻译一本书,请我帮忙看看译稿,提提建议(后来才知道译者还有阿里B2B的章显洲)。我虽然没做过架构师,但恭敬不如从命,就答应了。

开始,我关注更多的只是文字和专业名词/术语方面,从技术本身的考虑比较少。因为一来自己不是架构师,也没有这方面的经验;二来,这种口气的标题,总觉得有点狂妄。不过,跟着译稿一篇篇看下来,我的看法逐渐改变了:虽然这本书更类似97篇随笔,但到底是经过选择和编辑的,即便“随笔”,也是围绕着“软件架构师”的“随笔”,它们大致勾勒了架构师这个职业的方方面面——职责、权力、问题等等,我之前以为架构师更多地偏向技术方面,也就是负责“规划”整个软件系统的结构,但本书各位作者,都认为架构师应当是甲方和乙方之间的桥梁,一方面,负责准确理解客户的意图,另一方面,拿出规划给技术部门实施。也正因为这种定位,软件架构师虽然大都是从技术人员成长而来,却不能继续埋头在技术(技术架构)的道路上走下去,而需要补充多方面的知识,培养多方面的能力——怎样与客户沟通,怎样选择合适的架构(不能仅仅从技术方面考虑),怎样说服(注意不是命令)技术部门采纳自己的方案。书中不仅点出了这些问题,也给出了一些解决的建议;譬如第85章就告诉读者,说服甲方,仅仅依靠技术的术语是远远不够的,必须把整个技术方案包装成有吸引力的商业模型,这样说服力才会大大增加。如果希望成为称职的软件架构师,此类知识还是尽早了解的好,毕竟,都依靠自己去摸索,在挫折中学习,实在很不划算。
另一方面,架构师也脱离不开技术,所以,技术人员阅读本书,又可以从另一个角度(也可以说是更高的层次)来审视自己的工作及其意义,我的感觉是,一些经验,自己之前只有模糊的认识和体会,但书中的文章它们挑出来,表述得更明确、更到位,于是自己心里也更加有数了。譬如第82章指出“你客户的客户才是真正的客户”,这是非常之对的,而许多技术人员因为自身角色和视角的关系,往往很少意识到这一点:假设你给客户开发了一个电子商务网站,该网站的信誉评价功能不够完善,对此,你的客户可能仅仅认为“这个功能需要改进”,而客户的客户,也就是真正使用这个网站的人,他们的反应很可能是“这个网站买不到真货”,选择离开。有句俗话说:聪明人就是能多为别人着想的那种人。如果能够明确且重视这一条经验,甲乙双方的合作很可能就会融洽得多,技术人员的价值也会随之上升许多。类似这样的经验,书中还有很多,作为技术人员,阅读的时候很可能会感觉“于我心有戚戚焉”,至少,我看到“要经常反思自己做过的项目”时,就是这种感觉。

鱼与熊掌不能兼得,随笔专辑性质的书,照顾了“广”,就难以照顾“深”,因此,在亚马逊网站上,指责的意见都是针对这方面的:lack of detail,random accumulation…。但是我想,书有很多种,定位当然也不一样,应当各司其职——满足了自身定位的书,就是“好书”。这本书也是如此,读者权当这是在旁听架构师的茶话会好了——资历尚浅的听一听,开阔开阔自己的眼界,资历深的听一听,整理整理自己的经验,都能收获愉快的阅读体验;况且,还有平时难得听见的“小道消息”——世界上最先进的F22战斗机,对飞行控制的要求极端严格,应当选择怎样的软件;M1A1艾布拉姆斯主战坦克,开炮的时候会产生极强烈的电磁脉冲干扰计算机工作,这情况下要采用什么数据库……

旧事难忘,一声惊午梦;新风振起,万里看朝霞。

我研究了一天的立体几何,终于把全部家当塞进了小切:)

翻译时经常遇到的一些词语和结构,译者往往会用固定的办法来翻译。后果之一就是,译文中“翻译体的特征”很明显,许多时候我们都可以透过译文,“看出”原文,这样的译文,难说地道。when的翻译,就是一个很好的例子。
when,在多数译文中,都“约定俗成”翻译为“当……的时候(时)”,这样做本身不算错,但某些时候,稍加处理会让译文更加地道,譬如这两个句子:

当规则不够清晰,或者不是每个人都清楚这一情境是什么,或者当人们不同意规则应该被应用在某一特定场景下时……
当我询问我性别课上的女性,为什么她们会做这样一件古怪的事情时,她们回答说……

看到“当”,一般人会条件反射地想起when,知道这是“当……的时候(时)”的结构,再接下去阅读。但是,中文里较少出现“当……”而没有“的时候(时)”的情况(“当我想你的时候”比“当我想你”更普通更流行)。所以,无论是翻译还是阅读“当……的时候(时)”结构,都会惦记着最后的小尾巴——“的时候(时)”,如果中间部分足够长(譬如上述第一个例句),就露出尾大不掉的毛病:当 + 一个近乎完整的长句 + 的时候(时)。
要改变这种情况,可以从两方面入手:

一,准确理解when的含义。
查询词典我们知道,when主要有两个意思:(1)at or during the time that;(2)in the event that, if。前者与时间的意义紧密相关,也就是“当……的时候(时)”的“原型”,后者则与情境相关,对应汉语中的“如果”、“假若”。如果when的意思是后者,则可以抛弃“当……的时候(时)”的译法,直接采用“如果”、“假若”来翻译。因此,第一个例句就可以改为:

如果规则不够清晰,或者不是每个人都清楚此情境,或如果人们不同意规则应该应用于某一特定场景……

这种说法足够地道,相信不少人都还记得中学数学的解题步骤:若 X>Y,则……若 X<Y,则……。

二,掐头去尾。
以“当……的时候(时)”来翻译的弊端之一就是尾大不掉,后面总有个“的时候(时)”。如果能斩断这个结构,不修改意思,却只留下头或尾,问题就解决了。来看这几个例子:

当我心情好一点的时候,就给你打电话 -> 等我心情好一点,就给你打电话
当要下雨的时候,我们出门了 -> 要下雨的时候,我们出门了

当然,有时候也可以更进一步,把头尾都去掉,来看这个例子:

当他忙的时候,他就顾不上其它的事情了 -> 他忙起来就顾不上其他事情了。

同样道理,开头的第二个例句,就可以修改为:

我询问自己性别课上的女学员为什么要做这件古怪的事情,她们回答说……(她们的回答,必然是针对你的提问,这是不言自明的)

老话说“业精于勤,而荒于嬉”,这是非常对的。许多朋友认为我写正则表达式很有经验,其实不然,我虽然翻译《精通正则表达式》,其实自己写正则表达式的机会并不多,充其量是帮朋友写写一些“够用就好”的表达式,在“精于勤”的朋友面前,是不值一提的。

相反,2010年1月11日晚我在上海龙阳路地铁站附近见到的两位朋友rexcnhacktnt,都是“精于勤”的榜样:因为工作的原因,他们几乎每天都需要用到正则表达式,所以他们几乎是“全方位地”精通正则表达式:对语法的精确把握,对未知情况的处理,对匹配效率的要求……或许平时我们不需要注意这么多的方面,但多了解一点经验以供借鉴,总不是坏事。
举例来说吧:撰写高效率的正则表达式,需要注意哪些方面?更极端一点:正则表达式怎样匹配“0…1…”但‘0’和‘1’出现次数相同的字符串?这样的问题,对正则表达式没有相当研究和经验的人,是无法回答的。而答案和讨论,也让我这种半瓶醋看得眼花缭乱,大呼过瘾。
目前,国内已经有大量专业的开发论坛和社区,但是正则表达式这种“关键时候要命”的匕首式应用,总没有专门的场合讨论,这不能不说是一大遗憾。有鉴于此,rex同学开设了专门的正则表达式论坛 http://www.regex.me,大家有任何关于正则表达式的疑惑,都可以提问讨论,对《精通正则表达式》有什么意见,也可以自由发问,我会尽力解答。

正则表达式论坛

Next Page »