天外孤鹰

develop

开发之道:无中生有

by nuffin on Sep.17, 2007, under develop

最初学习“无中生有”这个成语时,是当作贬义词汇学的,说捏造事实,无端生是非的意思。但目前就我的个人体会来看,无中生有其实是个很高深的境界。

老子讲无为,我个人理解,无为并不是真的什么都不干,而是用最小的动作达到目标,不做无用功;或者说,不为而有为的效果,不做而有做的功效。不是说道法自然吗?给它一个轨道,让它自然而然发展到达目标就行了。或者再用太极拳来说,轻飘飘的看似不用力,四两拨千斤。用力很猛,总要有个施力点,或支点,找到这个支点就可以有效地破解这个力;而轻、慢,于是没有自主的力,对方也就不能用己之道还施己身了。

在开发上而言,个人觉得,无为,可以理解为少犯错误。通常我们说,代码写得越多,错误就越多,而不断的修改 bug,总会产生新的 bug。这是不争的事实,无可否认。然而动动脑子而不是直接下手的话,可以减少错误,减少因修改 bug 而生的 bug,这样 bug 产生的速度,大概应该是平方级减少的吧。

小规模代码是这样,大的系统也是这样。一个由多个组建组成的系统,总有某个方面最强,某个方面最弱。借用一下木桶理论,系统的弱点就取决于最弱的那个组件了,而且很重要的一点是,桶箍也是木桶的一部分。一个组件也总是由多个环节构成的,所以评判这个组件最弱,并不能一概否定其中的各个环节都很弱,因为最弱的那个环节决定了整个组建的优劣,可以想象一下一个从小只读诗书的八岁小孩手持倚天剑,随便找个大人也就把他打败了;也有可能每个环节都很强,但他们直接结合得不好,比如使惯了鱼肠剑的无功高手,给他屠龙刀,这二者在一起也只是个二三流的战斗组合。

后面这种情况也很好理解,程序员总是强调创造力和个性的,如果没有足够好的管理,即使开始的时候设计很好的系统接口,他们会按照自己的想法修改一下,或者为了美观,或者觉得应该有某个特色,或者恰好刚刚学了某个新东西要尝试一下,也有可能是设计太复杂以至于理解不了,于是按照自己的理解给简化了,这种情况属于上段描述中的前一种情况。可能他们负责的部分都很好,非常牛,但组合在一起就是不配合,错误多多或者效率低下。这种情况也是最容易被忽视和最难找出原因的。

刚开始写程序的人,新东西很多,学得也很快,总想找机会就给用上去。于是系统里会充满各种所谓设计模式,各种所谓的思想等等(我写的程序里也有,但应该是逐渐减少了吧。所以这段其实是经验)。我想深谙编程之道的大师级人物,应该是不说这模式那思想的。因为手上有招说明还在拘泥于招式,无招才是真的溶入血液了。《倚天屠龙记》里张三丰教给张无忌太极剑的时候,让张无忌把招式忘了个干干净净才算学成。

在程序没有的时候总是最难的,因为从无到有,会有一段很长的时间内看不到任何有意义的成果。而修改程序是最容易出效果的,除非程序本身已经确实很完美了。只要能够找到缺陷,或者结合得不好的地方,修改相对来说是容易的事情。设计阶段就是一个“无”产出的阶段,看不到任何代码,其重要性并不在于每个组件具体怎么做,而是根据各种条件(时间、人力、物力)对各部分进行取舍,同时决定协作方式,再按照这个步骤逐步细化。

对于工作情况不令人满意的现有的系统进行改造也可以按照这个思路进行。先什么都不做,而是调查清楚问题出在哪里,如果这个木桶上刚好有块木头腐烂了,那就换块木头就好了;如果是桶箍松了,那就对桶箍进行改造。重点在于,调查阶段需要做很多深入细致的工作,而不能流于表面。换一个桶可能相对容易,但如果是个已经和系统其他的各个部分建立耦合的组件,更换起来总是会产生更多的工作量(也可以看作是 bug 产生的 bug 的一种)。

写到这里,想起来看过的 Unix 无名师的故事。太多了,每一篇都可以咀嚼多次品出不同的味道。程序开发很简单,学学语法就可以开始写了;程序开发也很深奥,深层的东西有很多值得我们去思考。想到的这些那些,有的对,也有的错,但不思考就什么都没有。子曰:学而不思则罔。当然思考的太发散也没什么好处,大道至简,万法归宗,思考的最终是形成无名的体系。

Leave a Comment :, , , more...

研发的成本

by nuffin on Sep.13, 2007, under develop

对于自己研发自己维护的团队来说,研发的成本不是到测试完毕上线时就截止计算,恰恰有可能恶梦在这时才刚刚开始。

说到研发的成本,最近加深了一下印象。

按照我的体会,对于既研发又运维的我们来说,研发的成本不光只是项目考察、设计、编码、测试,很大的部分还在更长期的运营维护。设计和编码时多花一些时间,可以减少后期很多维护的成本,这其间包括运行期维护、错误处理、代码更新等。有过一两年,我的手机会隔三差五的在夜里响起,要么是报警的短信,更多的是报警的电话。以至于我现在对手机铃声非常敏感,一定要弄成渐强的那种,接电话时必然会急促地说:“喂?什么事?”,哪怕是三更半夜,特别是对某个负责系统维护的 jj,当真是美梦也成恶梦啊……

看上去,对互联网公司而言,时间非常宝贵,能早一天上线,可能就意味着成功。听上去很正常,但也不尽然,gmail 的突然崛起就是个很好的例子。真的很突然吗?面世之前不知道怀胎几年呢。催生出来的早产儿多半会营养不良而夭折,至少也是体弱多病。

其实还是小学时就懂得的道理,要打好基础。就像金字塔,底部非常宽阔,当然,对研发而言不太需要考虑把石头运到顶部的工作量(当然随着项目代码量的增大,学习成本也随之增大)。如果按照体积计算(实际上考虑每层的高度都相同,问题缩减为面积计算)的话,越靠近底部的层耗费的时间越多,所以时间/产出的曲线是条抛物线。在最初,可能在相当长的一段时间内看到的都只是地上画好的线,和几块石头。实际研发的过程中当然不允许这么干,但在项目的早期越是急于求成,基础就越不稳。

基础不稳定的后果当然不会是崩塌,首先是竞争不允许我们出现这样的失误,其次一般也不会坏到那种程度。但这将会导致建筑工人(研发人员)忙于东补西补。有时候甚至是上面还在垒,或者在修改些东西,下面要求支撑,工人就那么几个,只好疲于上下奔跑。这样的情况是我的真实经历,上下奔走就是在两种不同的工作之间切换脑袋里的思考场景。当然长期这样也起到了健身的效果,我习惯于把整个结构记在脑子里,而不是纹在身上。也造成了我对于不顾全局只为完成任务而做的代码的痛恨。

总的来说,我更倾向与多花一些时间在搭建系统上,而不是忙于找补。找补不是创造,相反会影响士气,但节省出来的时间可以用于创造。

Leave a Comment :, , more...

写在项目完结之前

by nuffin on Sep.10, 2007, under develop

手头做的一个项目,同时也是个完全从头开始的产品,最近终于快要结项了。能这么说,是因为绝大部分功能已经齐备,再有一两个星期完善打磨,就可以交付测试了。开发的过程中比较注重边写边测试,所以希望测试的同学们能找到一些我不知道的 bug 出来。

回头看看,从底层到页面,包括部分页面设计,一个人开发,还是花费了大约半年的时间(具体开始时间有待查证),其间走了很多弯路,设计改了很多次,特别是 javascript 部分。这当然得感谢领导对我的容忍,因为除了例行演示之外,我应该是最不主动汇报工作的,而且很多该找同事协助的,我也因为兴趣的原因自己做了。

这么多次改动,和我凡事喜欢自己解决有很大关系,比如页面设计的部分,第一次做有界面的程序,感觉做设计的 mm 比较难说服(是个借口吧,出于对面对面交流和冲突的回避),于是很多事情就自己动手了。另外,感觉像 c++ 写的程序,稍大一些,通常是仔细设计避免改动的,javascript 程序改动起来容易多了,且是第一次开发,所以想到更好的设计的时候,总会有种改掉现有的冲动。

在一个综合性互联网公司做一个产品,做这样一个产品,不知道会和那些专门做同类产品的网站有多大区别,但我很羡慕另外一家通常是综合性互联网公司做的同类产品,总是在不断更新。这应该不是项目型产品的产物,而是产品型的项目。二者区别在于,前者的产品在项目(通常从开始到结项时间较短)结束后就很少继续发展了,而后者则是只要产品存在,项目就不断在跟进。

越是通用的东西,越不容易过期。比如我们使用的 smtp, pop3, http, ftp 这些网络协议,虽然普通网民很少会知道(我指的是不光知道名字),但他们已经是网络侏罗纪动物了,目前还在爬得欢。所以越是底层,越是通用的项目,其生存期越长,需要不断维护。这时所说的底层并不仅仅指界面之下的那些,还包括用以构成界面的架构和基础性代码。

我觉得在一个致力于长期发展的互联网公司里,特别是成功的公司,需要有这种长期性项目。这些项目(Project)的负责人(maintainer),需要是相对稳定的人,充分深刻的理解项目,以维持项目的方向性(不能充满拍脑袋出来的点子);维护这些项目则作为项目负责人的日常工作之一,决定做什么不做什么,决定怎么做(主要是架构和设计方面),同时,决策的权力决定了项目负责人要有代码审核和最后的质量保证的责任,这非常重要。项目负责人的选定,水平很重要,大概占 60% 40%,还有 40% 60% 应该是责任心和自愿,否则很难长久,强扭的瓜不甜……

回头看看遇到的项目,可以有两种方式实施,一种是向一个长期项目提交需求,然后项目负责人决定怎么响应;另一种是人和项目之间没有长期关系,有需求要做,就临时安排人手进行。前者的结果应该是枝干分明的参天大树,负责人易人时交接也很清晰;后者的结果应该是像蟹爪槐,就算没有分枝,也会有骨节,有转折,甚至有连接,长期进行下去,需求越来越难实现了,虽然盘根错节看上去真的很艺术。但前者比较理想化,因为很难确定一个人会在一个公司呆多久,特别是互联网公司人员变动非常频繁,但长期价值大,潜力大;后者则很现实,特别是越是界面的东西,越容易是生存期短,变化快,可能很快就没有价值了。

特别羡慕那些开发网络游戏的团队,会长期以整个团队为单位迁徙,做一个游戏平台或引擎会有相对长期的开发时间,特别的,是他们允许有一个相对长的蛰伏期,但蛰伏期过后,加不同的界面就能快速推出新的产品。这也像现代汽车的开发,越来越像共用底盘的方向发展,这样降低了设计成本,制造成本(生产线等)。但对我们而言,能实现吗?

其实如果没有人员离开的风险的话,开发人员的时间可以按照 80/20 分配,80% 的时间做突击开发的项目,20% 的时间进行项目维护。当然,对于项目负责人而言,这 20% 的时间是做决策,做设计,分派任务,然后视改动多少,由项目其他参与人员花费 80% 或 20% 的时间实施。这其实是我在很长一段时间内思考的一个问题,怎么在部门内部仿照 sourceforge 的项目组织。

这个产品,这个项目,日后将会是如何呢?或许做这样一个理性极强的工作有些不应该,但我个人对写出来的代码是有感情的。写完了的代码就不再管了,就像让自己的孩子去流浪,养不教,父之过……

Leave a Comment :, , , more...

ie 的一个 css 问题

by nuffin on Aug.17, 2007, under web design

这两天在做一个 html 的菜单,别的都没问题,但是在设置它覆盖其他页面元素的时候浪费了两天时间。这问题在 firefox 下没有问题,估计是 ie 的一个 bug。

描述如下(P, A, B, menu, b 分别为不同的页面元素,其中 menu 是 A 的一个子元素)

page.jpg

如果 A 和 B 都是设置了 position:relative 或者 position:absolute 的(即有定位的),而且 menu 和 b 也是有定位的,那么不管 menu 怎么设置 z-index,都不能盖住 b。现象是里面的字混在一起。

最终发现是定位坐标系的问题。因为这里 A 和 B 都是有定位的,相当于创建了不同的定位坐标系;而 menu 和 b 分别以他们为参照物进行定位,就进入了不同的定位坐标系中。这时候他们的 z-index 有不同的原点,也就无法比较谁在上层,所以只好混在一起。

解决方案:把 A 的定位去掉,让 menu 以 P 为参照物绝对定位,那么 menu 和 b 就是在同一个定位坐标系中了。

看上去很简单……但早先没有发现。

Leave a Comment :, , more...

链接:javascript 面向对象程序设计

by nuffin on May.18, 2007, under develop

两篇 javascript 面向对象程序设计的教学文章。正好我对 js 中面向对象编程还有些迷惑,都在这里找到了解答。

p.s. 貌似山东的几个大学的老师中间藏龙卧虎,还都是不受招安的主。似我等分不清理想和现实而终日奔波的人,敬仰之心入滔滔江水连绵不绝,又如黄河……算了,他们都在黄河边上。

Leave a Comment :, , , , , more...

 

March 2010
S M T W T F S
« Jun    
 123456
78910111213
14151617181920
21222324252627
28293031  

Visit our friends!

A few highly recommended friends...