Michael Chen's Blog World in my view is a word of my view http://michael.nona.name 邮件:新的堆积成山的纸 <p>2009年在新加坡工作的时候,我的单月电子邮件数量达到了最大:2000多封。以22个工作日大致算了一下,每天约100封,以8小时工作时间计算,每隔不到5分钟就有一封新的邮件收到。我知道这不算太坏。不是所有的邮件需要你处理,大多数情况下你只需要看一眼标题就够了。</p> <p>那么,这些种类繁多的邮件中包含什么呢?无所不含。新发起的对话,需要审批通过的议题,同意,顶,周末去哪里玩,新员工加入了大家欢迎等等。如果我们将这些电子邮件纸质化,每封邮件打印在一张A4纸上,那么每个月每个人都将得到一本2000页的当月邮件记录。2000页是个什么概念呢,红楼梦120回加起来也不过4公分厚,2000页加起来就是8公分,大概就是大多数人拳头的高度。</p> <p>这并非是想象。若干年前许多企业嚷嚷着要无纸化办公。于是这些信息开始转移到电子媒体上。堆积成山的纸片并没有神奇般的消失,经过人们几年的学习和适应,这东西有了新的名字,叫电子邮件。</p> <p>我一定不是最繁忙的人。作为稍具自动化观念的人,我还知道将邮件进行分类、过滤、归档。然而,既然某些邮件注定不会被读过,他们的存在又意义何在呢?</p> Fri Feb 03 00:00:00 -0800 2012 http://michael.nona.name/archives/emails-are-new-papers/ 向前的张力 <p>高中的时候,每个月都要从遥远的县城往返乡下的老家,都要经过一段常常的蜿蜒的小路。夏天的早晨走过这段路,来不及蒸发的露水总是把鞋子弄湿,于是踩着潮潮的鞋子去赶一天一班的班车。傍晚的时候,晚霞总是很漂亮,夕阳在露出半个脸的时候将云彩烤得灿红。走着走着,天经常就黑了,不远处的坟地偶尔冒出的鬼火已经不再像儿时那般吓到我,但仍然心里发毛着加快脚步往家跑。</p> <p>那时候想的东西如同每个步入高中的少年一般。望着天边还未散去或者刚刚出来的星星,吹着若有若无的晨风或者晚风,我在想着一个极其庸俗的目标:要考上大学。</p> <p>有时候也会怀疑。秋天的时候田地里一捆捆稻草就那样摆在哪里,连飘落的叶子、逐渐凋零的秋树也开始影响着自己的判断。仍然会偶尔开小差,课堂上看漫画。但似乎有一种纠正的力量不断的提醒,在偏离方向一点之后更加用功的学习。这时候那些课外读物(比如尼采的书,各种武侠小说,鲁迅)、胡思乱想的想法居然形成了某种神奇的力量,在不比最好的学生更用功的情况下,考试成绩居然还不错。</p> <p>最后果然上了大学,没考。</p> <p>后来见得多了,越发觉得这段经历的珍贵。在做Buffalo Ajax的那段时间里,每天晚上写到很晚,但精力充沛。那种做有意义事情的感觉充盈全身,吃得少,睡得也不多,产量却颇丰。这种感觉能分析吗?虽然读理科,虽然逻辑是吃饭的根本,但不得不说这种感觉很难分析。那种纯粹的、毫无任何功利目的的神秘力量,指引产生出的令人不可思议的结果,完全是任何过程所分析不出的。</p> <p>唯一具备共性的东西是,那种宁静状态下的反省。曾子说要日省吾身,乔布斯说每天要对着镜子问自己。那种向前的张力正由此而来吧。</p> Thu Feb 02 00:00:00 -0800 2012 http://michael.nona.name/archives/moving-forward/ 说成长 <p>从前,村子里有两个同龄的年轻人。他们的父母教导他们,要好好读书,成为栋梁之才,成为对家庭对社会有用的人。他们童年轨迹基本相同,小学,初中,高中。作为农村孩子,他们学习之余必然还要干一些农活,艰苦的生活并未对这两个年轻人厚此薄彼。两个年轻人学习都不错,然而家庭境遇不同。高中过后一个早早的步入社会,另一个则进入了令人羡慕的大学。若干年过后,如果将他们自己的个人收入作为成功比较的标准的话,读者会如何揣测他们的结局?</p> <p>一种比较时下的猜测是,现在的大学毫无意义。大多数大学生更多的是在学校这个环境里完成自己的成人礼。至于找工作?几百块到几万块,做什么都可能,也不可能。而社会这所大学更能够锻炼人,高中毕业很不错了,韩寒高中都还没毕业呢!社会上什么经历都有,成功的几率更大一些。</p> <p>另外一种猜测是,社会是一个大染缸。大学教育虽然扯淡,但好歹单纯,找个工作当敲门砖还是能砸出点痕迹的。极有可能的情况是社会上的那个小子经过若干年之后,变得世故油滑,要么爬不起来,要么庸碌一生。而大学生的未来显得更明朗一些。</p> <p>相对中庸、没有观点但也不错的一种说法是:一切皆有可能。生命的轨迹并非由他的学历、经历划定,人的成长依赖更多的外部因素,他生活的范围、交往的朋友、自己对待事物的反应等等会综合决定成长速度。老实说这个中庸的观点某种程度上否定了教育的作用:既然周围的环境决定了自己的态度,那么中国教育所营造出来的量产模式,为何没有产生出等质量、量产的人才?</p> <p>在《少有人走的路》中描述了这样一种现象:理论上被生活踩到泥泞中的人应当就此沉沦下去,结果却是,他们表现出的强大的生命力驱动了他们的成长。目前没有数据表明是继承财富的富二代还是白手起家的穷孩子成长更快,但从正常的、大众的眼光看来,那些没有任何基础能够获得瞩目成长的人显得更令人钦佩。</p> <p>那么,到底什么是成长?</p> <p>成长不是虚长一岁又一岁。成长不是老师拿着课本你也拿着课本照着念。成长不是生活让你怎么做你就怎么做。成长不是做出生活需要你做的事情。饿了知道盛饭,渴了知道喝水,学习好当班干部,累了要睡觉。这都不是成长,这只是生物本性。</p> <p>成长意味着建立对事物本质的看法。成长意味着挑战大多数的观点。成长意味着对自己的行为负责,意味着行为模式除了满足自然以及道德需求之外,更多的来自忠于自己的内心。要想达到这一点,光有可见的社交圈是不够的,切身体会下的深刻的反思,激烈的跨越边界的讨论,追求真知不惧规则的勇气,才是加速成长的过程。</p> <p>关于本文刚开始说到的那两个年轻人,他们获得了同样的成功。大学生并没有轻易的融入到“正常”的洪流中,混社会的也没有轻易的被污染。他们不断地拓展着生活圈,不断的思考,不断的成长,避免了大多数的诱惑和陷阱,如今,他们生活得都很好。</p> Sun Jan 29 00:00:00 -0800 2012 http://michael.nona.name/archives/the-grow-up/ Don't Hire B Player <p>按照贡献、能力、态度等维度的综合评价,如果将员工划分为ABC三等,毫无疑问,A Player是管理者无论如何都要留住的,他们理解公司的核心价值,对组织有着杰出的贡献;而C Player的存在显然只是为了公司的正常运营,他们很少追求职业上的发展,只是为了获得一份工作,很少做工作之外的事情。难以处理的是B Player. 他们表现各异,有些有着不那么出色的能力,却工作很卖力;有些能力出众却在职业态度上乏善可陈。从公司的主营业务上,B Player承担了事实上的大部分工作以及利润来源,从公司的日常活动上,随着在公司资历的提升,他们逐渐参与到公司日常的运作过程中,参与了招聘。</p> <p>抛开能力上的差异,B Player最大的隐患在于,他们其中很少有人能够真正全心理解所在组织的正确做事方式,以及组织对人的综合要求。因此在特别是招聘、coach、共同做事这些与人相关的关键环节上,表现出的价值取向会一脉相承下去,于是B Player hire C Player, C Player hire D Player, 最终你得到一群Z Player。</p> <p>有很多的资料谈到如何管理B Player。而大多关注于能力。对于越来越多的start up, 小团队,关注个体与协作效率逐渐成为主流,能力变得不那么重要。特别是对于计算机,有太多的开放免费的资源可供使用,只要投入足够的时间,在能力上完全可以胜任。组织开始花大量的时间关注B Player的时候,潜意识里将关注点从“挑战卓越”变成了“维护优秀”。这很难说不是一种妥协,这种妥协会让B Player更加安逸,C Player更为心安理得,而组织想留住的A Player更觉得失望。</p> <p>对于依赖机构能力的企业,这并不是一个大问题。通过部门、分工、职位以及精心规划的职业路线,每一个新进的员工只需要按照预定义好的路线前进,在给定的工作时间内输出能用的工作成果即可。这种情况下,任何一种工作成果都可以被评估,接受并且妥协。然而随着第二次互联网创业浪潮的到来,受到影响的不仅仅是startup, 互联网公司,大型企业也逐渐倾向于采用协作更为紧密的小团队来完成工作。这种情况下,共同愿景驱动下的个人创造力显得更为重要。具备事实影响力但在态度上摇摆的B Player为这个团队带来出了平庸产品之外的伟大创新。</p> <p>如前面所说,对B Player的妥协会影响A Player的表现。当组织花费大量的精力安抚B Player而不是鼓励A Player持续卓越表现的时候,A Player就得为B Player的不优秀买单。整个组织于是表现为平庸和死气沉沉。</p> <p>以前并没有思考如此的深入。在组织快速发展的过程中,很难不为利润来源进行人员质量上的妥协。而这些带来的影响深远并且重大。与其在后期花费大量的时间进行培训、沟通,尝试将B Player转换为A Player, 不如索性放弃B Player的招聘,直接想办法继续提升A Player的表现,并持续提升整个组织的服务品质,最终达到真正令人向往的团队。从某种意义上说,对人员质量的不妥协也意味着高的准入门槛,那些缺乏热情、缺乏事实证据投入的应聘者,也需要静下来仔细考虑这是否是自己的职业,而非另外一份获得收入的工作。</p> <a href='http://ycl0.com/topic/4e7a8c9c992bf642380054dd'>参与讨论,去ycl0 >></a> Thu Sep 22 00:00:00 -0700 2011 http://michael.nona.name/archives/388/ 评论的黄昏 <p>即便是排名数一数二的个人博客,有价值的评论却是越来越少了。这很难说是读者更加懒惰,或者作者内容本身不具备吸引力了。同时产生的现象是开始写作的人更多了。搭建博客这类的复杂技术工作,现在随便找个地方就能得到;微博、轻博客、社交网络之类的,将人们本身的写作诉求发泄的差不多了。人们可以趴在网上一动不动待上好几个小时,却很少能够在某个地方留下留言。即便有,也是只言片语,了了而过。</p> <p>读者更为珍惜他们的时间。我在别人博客上留言还是有的,也经常期待着其他人能够参与讨论。然而过上一阵就忘记了。太多的信息选择使得那个时候留下的信息并不重要。我也回复过自己博客的留言,想到只会有那么几个人看过,心中不免有些懈怠。不过,对于作者而言,比负面反馈更为糟糕的,是完全没有反馈。这就带来一个更为有意思的命题:人们愿意写其实是为了发起一场讨论,而不仅仅是单向将其表达出来。</p> <p>基于这种命题,个人博客是不具备这种基础的。每当回复的时候,交流似乎只限于博主与读者之间。太热门的个人博客,前几贴永远是抢到沙发,不那么热门的,则干脆回复寥寥。不是读者/作者不乐意去写,只是博客评论这种方式已经无法引起讨论,并且无法满足人们的社会需求。</p> <p>这种情况不仅仅发生在个人博客,即便是专业性强的门户网站,也无法获得读者们的青睐。上个月我在InfoQ上发表了《<a href='http://www.infoq.com/cn/articles/cjz-architecture-corruption'>架构腐化之谜</a>》,有32份评论,也还算有点讨论;这篇文章却在水木清华引起了更多的讨论,长达6页一百多份回复。虽然期间讨论已经脱离了主题,但起码引起了相关的思考。从我自己而言,这种一个话题引发一场讨论和辩证,却是我乐意看到的。</p> <a href='http://ycl0.com/topic/4e42a6018a36f4a912000103'>有想法?请到ycl0参与讨论。</a> Wed Aug 10 00:00:00 -0700 2011 http://michael.nona.name/archives/385/ 我为什么删除了在线简历 <p>大约一个多月前,我删除了所有的在线简历,包括中华英才网、智联招聘以及其他一些不知名的网站,还有被某电信公司直接收录到其内部系统的拷贝。</p> <p>如同大多数稍微有点沾沾自喜的IT从业人员一样,接到猎头打来的电话的时候总是心中一喜。从业多年之后居然有猎头主动联系了,起码说明这一行做的还不错。然而电话接得多了,开始感到郁闷,因为猎头所询问的,都是我在简历上、互联网上,我的博客上已经写得明确的不能再明确的东西:你工作几年了,擅长什么技术,有个某某公司你是否感兴趣,能否把详细的简历发来看看之类。我之前有更新简历的习惯,最多半年就会更新一下简历,每次更新完之后都会接到数个电话,我只能一而再的重复着“没有换工作的兴趣”。</p> <p>我最终意识到这是不对的。打开智联或者中华英才,对于IT从业者,我甚至找不到一个地方输入Ruby/Ruby On Rails经验,更不要说早已经成熟的nodejs/云计算之类的。作为面试者,我在ThoughtWorks看了无数简历,每次看到&#8221;Java - 36月 - 熟练&#8221; 类似的描述的时候都感到很迷惑——如何证明这一点呢?即便工作了这么久,又说明了什么?软件从业者当如同过去的手工业者一样,是依靠产品与声望而获得更好的机会。而这类通用的招聘网站,根本无法提供这类证明。删除前我的简历上密密麻麻的写了一堆,很多都是年少不经事时写下的,如C++ 2年 Oracle 2年,现在我却更乐于提及在架构、新一代web应用、团队建设方面的能力。这些,从我的twitter/blog/发表的文章中都能得到验证。</p> <p>从另外一方面,这类通用的网站似乎为那些传统的招聘者提供了方便。不难想象,智联或者英才的付费企业用户只需要在搜索中加入3年工作经验、Java之类的就能获得若干份简历。进入简历筛选之后开始cold call - 不管是雇主还是应聘人员,这一阶段显得如此的单调,双方只能获得一些简单的第一印象。这些印象本可以通过IT从业者的github/twitter/blog之类所有的渠道获得,而不得不通过更加低效、主观的方式来进行。</p> <p>因此,我删除了所有的在线简历。即便有一天我不得不再次找工作,我的<a href='http://github.com/mechiland/'>github</a>/<a href='http://sourceforge.net/users/mechiland'>sourceforge</a>/blog/<a href='http://www.infoq.com/cn/author/%E9%99%88%E9%87%91%E6%B4%B2'>InfoQ</a>等等都会帮助我证明过去的经历。来自招聘网站的电话显然并不了解,除了干扁的简历之外,IT从业者有更丰富的渠道来证明资历。</p> <p>PS. ThoughtWorks一直在招聘中。西安(我现在工作的分公司)、成都(明年春夏开张)、北京。如果你具备足以在网上证明自己的资历,也许你并不需要花太多时间准备简历。</p> Mon Aug 08 00:00:00 -0700 2011 http://michael.nona.name/archives/379/ 全面成功 <p>逐渐的,人们用越来越多的维度来衡量某一个人或者某一项活动的成功。例如,有很多的钱固然是人们对其保持羡慕的主要指标之一,能否行使对应的社会责任,维护公共道德也成为有力的判断准则。</p> <p>这与过去的,人类一向成王败寇的单一判断观念有些不同。过去的社会关系简单,战争这种纯粹的、一旦失败就意味着国家灭亡的沉重的责任也让个体在群体中泯灭。到了现代,这类竞争关系不再存在。特别是在软件开发领域,你永远有模拟环境实施,犯错误,获得反馈并改进的机会。</p> <p>奇怪的是,即便在这种情况下面,“交付成功”这一功利的目标,依然成为众多软件开发团队是否运转成功的唯一标准。在这种唯一判断标准之下,有一些行为显得可以理解:</p> <p>很少的日常质量活动。 最显著的特征就是没有进行持续的测试活动,包括细粒度的单元测试和为业务人员准备的展示。测试本质是一种浪费——如果确定你的代码能够很好的工作,测试的确是增加了工作量。以“交付成功”的唯一目的而言,这些浪费毫无价值。</p> <p>很少的知识共享和能力提升活动。 在“交付成功”的唯一目的之下,提升个体能力固然从长期看来对组织有利,但对于只有几个月的交付而言,没有项目经理希望这一行为发生在自己的项目之内。什么,需要花点时间学习新的技术?延误交付怎么办?沟通通常被工作环境、分配式的工作内容所隔离,团队中的个体往往只能在开会中聚集到一起,通常好几天、一两周才能偶尔发现一些讨论。</p> <p>加班。加班显然是所有领导者喜欢的,说不定也是员工喜欢的。在软件行业,大多数人将其与一般的,体力密集型的工作混为一谈,认为工作时间的长度决定了工作内容的产出。就像收割麦子,生产线上的工人,工作时间越长,产出越大。然而智力密集型工作的特点在于思维清楚。很难想象一个人在工作加班十几二十个小时,依然能够保持犀利的想法,对项目进行贡献。当成为一种常态的时候,加班更多的成为一种筹码——一旦交付无法准时,那么就可以说:我们已经加很多班了。</p> <p>让很多项目管理者感到迷惑的是,即便以“交付成功”或者“客户第一”之类的纯粹的,绝对的目标导向,最终许多项目依然不可避免的走向了无法按期交付、质量低劣、团队士气低落的噩梦。</p> <p>在这里我不想继续提那些单点的优化策略,例如持续集成、测试驱动开发等等等等。我发现这里面是一个认知的过程。绝大多数的项目领导者,没有意识到在软件开发行业,这种单一的、功利性的目标导向下,只能产生一时的生产力提升,或无法最终产生另所有人满意的交付。在此,作为对“交付成功”唯一目标的对立面,我提出“全面成功”的概念:</p> <p>全面成功,是指一个软件团队不再以交付成功作为唯一目标,而以团队沟通、个体能力提升、士气、客户沟通、持续的软件质量作为全面的衡量标准,最终获得一个全面成功的团队,交付成功只是必然结果之一。</p> <p>软件开发事关沟通。写下的每一行晦涩代码,如果存在另外一个人审视,那么也许将不会存在;如果团队以平等尊重为前提,那么所有的错误都被容忍并改进,那么团队将显得更加和谐充满生机。想办法将各种软件交付产物的受众加入到沟通圈来,及早获得反馈,获得信任。</p> <p>个体只有通过项目才能获得能力提升。这一点在软件行业尤其突出。给予团队成员一定的空间,通过各种活动提升员工的能力,最终这些能力会转化为惊人的生产力。</p> <p>持续的软件质量,而不是某一刹那的集成。数天的甚至更久的扫缺陷、稳定版本时间不是必然的。通过实时的集成,充分的测试以及良好的测试策略,让软件库任何时刻都处于稳定的状态。这样开发人员才能放心的实现新的功能而不比担心破坏已有的功能。</p> <p>全面成功并不是一个口号。事实上,我所经历过的成功的项目,都印证了这一论点。我的同事胡凯在InfoQ上分享的团队案例,也印证了全面成功对交付成功的必然性,并且获得了更多的好处。</p> <p>在此我呼吁,团队停止以“交付成功”作为唯一的目标,将“全面成功”作为追求,不断改进,最终获得令人羡慕的团队,以及理所当然的顺利交付。</p> Thu May 12 00:00:00 -0700 2011 http://michael.nona.name/archives/370/ 正版 <p>两周前,我家里的台式机硬盘坏了。2006年买的机器,AMD单核CPU, 1G内存,后来加了个23寸的显示器,发现集成显卡支持不了,于是又买了个显卡。自从在电脑城安装的盗版XP之后就再也没有重装过,兢兢业业居然挺了快五年。期间伴随我实验各种虚拟机的Linux, 玩魔兽世界台服,以及偶尔写写代码。后来沦为家用机之后,主要用来看照片,视频,QQ之类,成为全家的共享机。</p> <p>某一天开机无法启动之后,我研究了一下,发现机箱显示器显卡键盘鼠标还能用,于是跑到电脑城,买了AMD 4核CPU,4G内存,1T硬盘和技嘉的主板。花了2000块。抱着盒子的时候我琢磨:要不要买个正版的Windows 7呢?</p> <p>作为资深的IT人士,一份Windows拷贝从来不是难事。作为IT公司的员工,我甚至可以大模大样的把公司的正版拿来装到家里机器上,然后说我是正版。在电脑城四楼走来走去之后,老婆直接说:你就买了吧。于是350元,买回来正版的Windows 7.</p> <p>一边安装,一边回忆起这些经历来。</p> <p>99年的时候,去电子市场买软件只看光盘里面哪个装的东西多。光盘一张要好几块,太贵了,里面的软件越多越好。那时候最喜欢的杂志是《数码时代》,一期只要10块钱,一张光盘,还送一本100多页的杂志。里面有很多小软件。那时候最有意思的事情是和同学一起比,谁装的软件多,谁的版本新。那个时候似乎就知道了软件是要收费的。但没办法,电子市场太近了,西工大出门就是。里面的碟片跟太多了,一摞摞用纸片包着,整理在盒子里,随便一个小摊起码能摆出几千几万张,CD,MP3,电视剧,软件,游戏,什么都有。有些卖碟的小妹长得也很正。于是我们几乎每天都去。</p> <p>那一年的冬天我第一次挣到了10块钱,帮人写了个C程序。</p> <p>后来去公司帮忙打工。发现一个用VB4.0的人基于Excel写了一个酒店管理系统。界面非常复杂。一套卖好几万。后来我偶尔在电子市场似乎看见了XXX酒店管理系统,与其他YYY管理系统在一张碟上,五块钱。</p> <p>再后来去了另外一家公司。那家公司把光盘和32开说明书装到一摞A4纸那么大的盒子里面,哐当哐当响,也卖好几万。与CD一起卖的还有一个并口的软件狗。插上软件狗软件才能执行,否则软件无法执行。后来听说江民杀毒软件发现是盗版的时候会自动执行format C:的动作,听起来很是后怕。再后来玩盗版《轩辕剑天之痕》的时候要拔光驱,很是愤怒。现在想起来,这些软件的作者们为了保护自己的心血耗费了多少额外的心思啊。</p> <p>01年的时候我终于花血本买了Redhet红帽操作系统,4张光盘,包装精美,红色的盒子,好说歹说20块钱买下来——现在想起来这是我买的唯一的正版。学习Linux的日子是痛苦的,但终究体会了至少不蓝屏的自由。于是开始接触Open Source, Free Software。</p> <p>依然,几千块的操作系统、Office软件即便现在对我而言真的是太贵了。在没有选择的时候,有意无意间,用着盗版,心里偶尔会涌起惭愧。再后来Windows的某次更新加入了正版认证,自从那以后,我的windows就再也没有更新过⋯⋯我连运行那个正版认证程序的勇气都没有。</p> <p>再后来有了更多的选择。光盘还是5块一张,但原来觉得高高在上的游戏、软件觉得不再昂贵了,或者他们有了替代品。我买了正版的古剑奇谭,50块,高高兴兴的在玩,可惜没有Mac版;买了正版的波斯王子,70块,就印刷粗糙给客服抱怨(后来觉得不好玩了);花钱玩魔兽世界;AppStore上玩买的起的游戏。Office就不用了,OpenOffice、Google Doc、金山WPS免费版都能用。PhotoShop也不用了,于是我成为了周围人群中GIMP用的最好的。</p> <p>⋯⋯</p> <p>Windows 7安装完了。内存上显示可用内存3.5GB。我这才意识到我买的是Windows 7家庭普通32位版本。打电话问客户,32位的序列号能不能用在64位,毫不专业的客户扭捏的半天说不行,还说可以在京东上买64位的⋯⋯我勒个去,毫不客气的奚落了一番。作为合格的消费者,抱怨一下是完全合理的。</p> <p>后来发现硬盘没坏。无论如何,这将是我最后一台Windows电脑了。</p> Thu Mar 31 00:00:00 -0700 2011 http://michael.nona.name/archives/363/ 组件化:企业级大型项目必经之路 <p>超过一年以上、活跃开发的项目往往到后期陷入了一些共性的问题:</p> <p>* 构建速度慢,往往生成一次最终输出产物需要一小时以上;</p> <ul> <li>架构复杂:虽然说架构本身可以用类似于MVC/Service Bus之类的通用进行描述,但实际上使架构变得复杂的往往是业务本身;</li> <li>开发速度慢,构建速度是因素之一,它使得持续集成的反馈大大低于预期;然而这类大的项目往往被通过各种技术手段进行了分层、分project的切割,你要面对的可能不是一个project,而是一组项目群。我之前参与过、咨询过的项目里,开发人员打开IDE要面对的project少则几十个,多则上百个。即便以目前最强劲的开发机器,面对这动辄几十万上百万行的代码,依然显得力不从心。 * 以及由上面而引来的一系列问题:例如新人培养,知识传递等等</li> </ul> <p>在提出这些问题的解决方案之前,我们看看这些问题是如何产生的。通常需要很长时间这些问题才成为问题,而且往往在一开始出现的时候,总有一些快速而有效的解决方案去掩盖,进而加剧了问题的升级,最终成为一个旷日持久需要大量人力才能解决的问题。</p> <p><strong>项目的产生</strong></p> <p>新的项目来了。团队成员兴奋的引入了最新的MVC技术框架(比如SpringMVC/ASP.NET MVC)、持久框架、依赖注入框架等等。现在流行的迭代开发方法也被引入。于是前几个迭代过去了,Domain, Service, Web等,分层良好的应用产生了。需求也快速的实现了。代码非常健康。构建速度非常快。所有人都很高兴。</p> <p>2个月过去了。有心的团队成员不断的重构着代码,确保重复的逻辑、重复的代码被消除。新的人加入了团队。新的业务需求也来了。这些不断重构的代码进一步被不断重构着:终于引发了一些问题:由于只有一条主线:Domain -&gt; DAO -&gt; Service -&gt; Web, 在并行开发下(比如同时有5-8个并行工作)那么公共使用的那条线会不断的产生代码合并冲突/或者业务逻辑冲突。</p> <p>这不算一个多严重的问题。然而这个问题却制约了团队的规模扩张。比如需要更多的人加入这个项目的时候,耗费在沟通上的时间会大大增加,新加入的成员有效生产力也难以得到提升。</p> <p>并不算太难解决的的问题。现在团队还不大。团队的架构角色只需要花上一个周末的时间,将现有的代码按照业务逻辑进行纵向切分,划分为不同的小项目,问题算是基本解决。</p> <p><strong>问题来了</strong></p> <p>更多的代码被提交。构建速度从2分钟上升到6分钟的时候有人抱怨了一下,于是花点时间优化了构建脚本,时间减少到5分钟。代码继续增长——这是不可避免的趋势——构建时间继续加长,从5分钟上升到11分钟的时候,大家的工作习惯开始发生了一些变化:一旦开始构建,就开始跟旁边的伙伴聊聊天,或者趁这机会喝点咖啡。本地提交在这个时候与持续集成服务器有点不同——本地可能只运行少量的构建步骤、必要的测试,服务器则运行所有的。</p> <p>从11分钟上升到23分钟的时候,大家觉得要做点什么了。升级了所有开发人员的开发机器,最新的四核8G内存的机器,酷毙了。分布式构建集群也被引入。原来需要23分钟,现在通过分布式之后时间回落到10分钟以内了。</p> <p><strong>更多的问题</strong></p> <p>需求在不断的扩张着。代码的规模随之膨胀着。构建时间不引人注意的增长着。直到几年后的一天,突然发现:</p> <p>1. 即便已经使用分布式,构建需要一个小时</p> <ol> <li>打开IDE面对的是72个项目</li> </ol> <p>3. 虽然能忍,但干什么都有点慢</p> <p>4. 架构呢?架构呢?</p> <p><strong>解决思路</strong></p> <p>大多数解决这类问题的思路仍然停留在表象层面:加机器(改善构建速度)、增强结对编程(改善交流)、写更多的Wiki(增加对代码的共识)。然而却逐渐忽略了一个事实,那就是:</p> <p><strong>这么庞大的“业务需求”,根本不是__一个__项目能够承载的。</strong></p> <p>让我们从代码层面开始。</p> <p>一个大型项目需要在IDE里面打开数十个project. 这些project之间有着千丝万缕的联系——无论依赖被管理的多么好,没有人能够很清楚的知道他们之间如何被依赖的。更重要的是——大多数时间你都不会碰60%以上的project以及80%的代码。那么这些代码存在的意义何在?</p> <p>因为你处在一个团队中,别人会用。</p> <p>于是引用就成了依赖最强、最脆弱的代码引用。</p> <p>那么,如果我们将这些项目的引用变成二进制引用呢(如JAR, DLL)?由于依赖的这些项目已经经过构建,那么编译的时间可以减少。你也只需要关注自己的项目。</p> <p>听起来似乎太轻巧了。的确如此。如何获得这些二进制引用?对于JAR而言,假设一个Maven依赖仓库是必须的;对于DLL似乎没有太成熟的方案但总不是太难的问题。</p> <p>这个过程之中有非常多的实现细节,很可能大多数团队在第一步:分析project依赖就跘住了脚。这么多的project想要拆开是很有挑战的事情,在业务需求的并行压力下,缺乏勇气的团队很可能止步于此。</p> <p><strong>这些依赖是组件吗?</strong></p> <p>在进行二进制引用的进程中,你应该不断的问自己这个问题:这个依赖是组件吗?还是只是一个简单的压缩包?</p> <p>评估一个project是否为一个组件,在我看来有几个约束条件:</p> <ol> <li> <p>是否有超过2个project依赖于它?注意,这里的依赖,不是IDE里面你指定的依赖,而是真实的、API调用的依赖。对于组件化意识不好的团队,这类项目往往成为临时代码堆放地,需要通过识别、迁移,才能将真正有用的组件提取出来。</p> </li> <li> <p>是否稳定?所谓稳定是指,在过去一段时间内(比如一个月),这个模块没有经过大的调整,API基本稳定,未来的变化只在于增加API的数量而非调整API的架构。</p> </li> </ol> <p>3. 自己依赖于外面的足够少。</p> <p>通过这一步,往往你可以识别出项目中用到的公共组件、公共API等等。将他们组件化,通过Maven或者自己的依赖库管理起来,标记上版本,然后所有人使用二进制引用。通过这一步,构建时间应当大幅度减少。通过这一过程的梳理,哪些是核心业务逻辑、哪些是可以独立考虑的第三方辅助库,应当可以有一个更为清晰的理解。更重要的是,这些组件可以独立开发、升级、优化,丝毫不会影响到主线的开发过程。</p> <p><strong>组件是库(Library)还是服务(Service)?</strong></p> <p>经过上面一步,可能项目中仍然存在一些项目依赖,这些项目往往是公共的,通过API调用的。例如,在某一个银行业务中,支付模块被很多其他业务依赖。支付模块有很多代码,也需要在主进程中与其他模块一起被部署。但支付模块实在是太独立了,虽然与其他的domain之间存在一些类上的简单交互。</p> <p>采用上面步骤的方法不太合适,原因之一就是它是运行时才有效的依赖——它整体上是一个服务,而非一个静态的库。这个时候你可以考虑将其彻底独立,成为一个独立的service。它的形态可以是一个操作系统服务,或者独立部署的应用。然后写一组标准的轻量级API如REST/WebService来对其进行交互。这样这部分也独立出去了。</p> <p><strong>重要的考虑</strong></p> <p>上面看起来轻巧的过程实际上在操作过程中需要耗费很长很长很长的时间。原因之一是组件很难识别。然而难以识别的原因并非是这个过程很难,而在于我们在完成一个项目的过程中倾向于将所有的东西放到一起,顶多通过project区分但仍然缺乏真正物理意义上的隔离。这是一个认知上的障碍,特别是我们面对的是“项目”而不是“产品”。“项目”这个词本身就透露着短期的、目的性强的意义。识别出来的组件本身短期并不会给团队带来多大的好处,反而会增加工作量。就像所有的知识积累工作一样,它们的好处与他们的投入在因果关系上并不连续。</p> <p><strong>我们得到了什么?</strong></p> <p>这并非一个理想化的描述,最终我们得到的是:</p> <p>1. 真正物理隔绝的一组项目群:能够独立构建、开发部署和升级</p> <p>2. 依赖仓库</p> <p>3. 分工明确的组件和服务</p> <p>4. 针对产品的版本和部署策略</p> <p>(完)</p> <p>PS. 这里我所说的项目是指业务需求,project(英文)是指代码组织的一种形式例如eclipse/Visual Studio等IDE的“项目”。关于架构的术语之争从未停止过。这篇文章中大量用到了“框架”、“组件”、“库”、“服务”等词汇,也许跟你平时看到的不一样,如果有迷惑之处请谅解并指出。</p> Sun Jan 23 00:00:00 -0800 2011 http://michael.nona.name/archives/359/ 艺术馆 <img src='http://farm1.static.flickr.com/16/92531285_50546f968c.jpg' alt='图腾' /> <p>圣诞左右的时候到悉尼Art Gallery去转了半天,看到原汁原味的土著艺术品,草编制的eel trap, 树皮上的不断重复却又独具特色的纹理画,还有神秘的图腾。当然作为一个大型的艺术博物馆,当然也少不了欧洲中世纪的油画,雕塑和中国的瓷器、书法等。</p> <p>让我印象深刻的固然是那些美轮美奂充满神秘气息的艺术品,但井然有序的作品成列,精心挑选的作品,有意识用小字表明的作品介绍,以及与作品相应成趣的环境,让人欣赏的过程始终充满愉悦。欧洲油画的展厅有粗大的柱子,不时有雕塑;中国瓷器的展厅,白色的现代墙则被红木板细心的盖住,灯光也暗了下来;原住民艺术展厅则整个变得更加粗放,空荡荡的大厅没有任何额外的装饰,所有的艺术品都在四周的墙上。</p> <p>如果,同样是这些作品,放到一个大的空间中,胡乱的摆放上,参观者还会有如此好的体验吗?</p> <p>那将是杂物室,而不是艺术馆。</p> <p>新年夜里,我们一起Darling Harbor看新年焰火。如果你要问我具体烟火的情况,我只能很羞涩的说:比起中国的烟火,从壮观程度、时间长度、规模上,差得太远了。总共只有7分钟时间。期间真正精彩的烟火也就那么几出。</p> <p>然而这确实我见过最令人难以忘记的烟火表演。开场前节奏明快的黑人现场音乐演奏;临近新年的时候数万人一起倒计时;与烟火几乎同步的现场音乐节奏,让这原本平凡的烟火立刻充满了生命力。原来,人的需求是如此的全方位,那些极速上天的爆炸和光影,配合着音乐,以及周围游客的赞叹声,让这个烟花表演充满了生机。</p> <p>回到我的老本行,软件。很多软件都只是功能的堆砌。说得更具体一些,只是数据库表的一个直接的展现:增删改查某一项信息,以表的形式显示查询结果等等。粗制滥造的功能肆无忌惮的充斥着使用者的眼球,丝毫不顾及用户在使用的过程中的心理的引导和除功能之外的满足。一个好的产品,核心功能的完成也许很小部分的完成,但更多的,如何将产品成为一个艺术馆,引导用户一步步发现并获得满足,才应该是在满足功能之外需要更多考虑的方面。</p> Sun Jan 02 00:00:00 -0800 2011 http://michael.nona.name/archives/352/