Profilo di 剑锋Jianfeng行行摄摄FotoBlogElenchiAltro Strumenti Guida

Blog


02 marzo

软件重构思考实录

所有大型系统的经验都说明,第一个版本不能令人满意,用户体验通常会抱怨资源消耗大、执行效率慢、用户界面不友好。比如Windows软件从1.0发布到较为成功的3.0推出,花了5年时间,3代升级。俺们的一个重要业务系统,也花了3年时间,多次重构才可以让用户能基本接受。看起来,重构是软件生命周期的必经之路,我们需要为了“将来被丢弃”而“现在建设”。
 
由于设计和开发过程需要持续相当一段时间,其间变化是必然的,不变才是偶然的。设计者面对变化时,不能抗拒和讨厌之,必须对变化进行有效的管理。也就是说,在设计时,需要事先为变化做好准备,而不是假设变化可能不会出现。同时,业务需求变化由业务方面根据项目实施期间外界的变化来驱动,而且越是成功的设计,业务需求变更的压力越大,原因是用户在不断使用的过程中,会探索出新的用法,扩展应用范围。与业务需求变更不同,设计策略和技巧上的变化,则完全由项目内部技术方面来驱动。
 
大型项目通常采用自顶向下,逐步精化的模式来进行架构设计。Bell实验室V.Vyssotsky曾经指出,“关键的工作是产品定义。许许多多的失败完全源于那些产品未精确定义的地方。”细致的功能定义、详细的规格说明、规范化的功能描述说明是一个项目能否成功实施的基础。在软件的重构过程中,这些基础性的文档必须能够预先地进行重构,否则等待重构的将是灾难。这种方式中,清晰的结构和表达方式更容易对需求和模块功能进行精确的描述。且松耦合的模块分割和模块独立性避免了系统级的问题,遇到问题可以分而治之(不会有人认为项目过程中不会遇到问题吧?呵呵)。另外,细节的隐藏使总体结构上的缺陷更加容易识别。最后,设计在每个精化步骤的层次上是可以分析和测试的,使得具有负反馈效果的Review工作可以尽早开始,并且每个步骤的重点可以放在合适的级别上。
 
在这种自顶向下的设计模式中,重构有点类似于递归算法中的回溯过程,按部就班的把步骤反过来,直到修订顶层设计,重新自顶向下开始整个过程。这种过程可以使得设计师们清楚在什么时候和为什么抛弃了某个臃肿的设计,并重新开始。如果不采用这种回溯模式,可能重构局限于添加了很多表面装饰般的补丁,最后导致系统内的无序不可控制,“熵”大幅增加,退化到不可救药。
 
重构中通常需要解决的问题概括如下:
1. 两个层次:去除无用的设计,且重新对热点部分进行优化性的再设计;去除“死”的源代码。在不断的设计变化、故障修复中,会遗留下不再使用且不再需要的设计和代码。对代码来说,存在比较简单的方法,就是通过一些工具,定位出定义后未被引用的变量,定义后未被调用的函数。
2. 整理“Copy Paste”的代码。在项目时间压力巨大,不得不引入新人力的情况下,往往会利用已经工作的代码,做些许修改,让某些新功能先运转起来,或者修复掉一个紧急的故障,这种时候,最容易导致的现象就是Copy & Paste。这会给未来的持续发展与维护带来很不利的影响,比如发现一个Bug,可能意味着很多处的修改和测试。
3. 提炼出一些原则,保持整个系统的一致性,比如函数调用中参数的顺序。增加一些必要的抽象层次,降低实现与接口的耦合程度。将这些公共福利部分写成文档,供后续开发人员和维护人员参考。
 
洗澡去了,先这么多,以后有空再总结。再见!
 
01 marzo

关于用户界面设计与用户思维的一点思考

思考了用户界面设计与用户思维的一些关系,设计者需要调整用户界面,以适应用户的思维方式。工业产品设计如是,软件产品设计没有两样。
 
根据自己观察和实际体验,概括如下:
1. 设计师容易把控制能力看得比易用性更重要;但实际用户更看重易用性。概括起来,参数化、开关配置等要适可而止,并进行一定的封装。即好的系统架构是设计师方便修改,而不是用户方便修改。用户要的只是方便使用。
 
2. 设计师容易把系统的工作原理展现给用户;但实际用户更关注结果。典型的就是,错误提示要明确是用户那里错了,要如何调整用户行为,而不是系统那里不对劲了。
 
3. 设计师容易制造很酷的,但是令用户讨厌的“蛇足”。著名的微软公司在著名的Office软件中,有两个特征就是典型的蛇足,一个是可以浮动的菜单,会导致用户不小心拖动菜单变成一个浮动在文本上阻碍视线的有边框的菜单;另外一个就是长着眉毛的扭来扭去的不断说着废话的称为Clipper曲别针的功能,这个特征从1997年发明,到2005年后被微软取消。
07 febbraio

软件开发中纠错与创新的辩证统一


软件开发与测试工作中,“纠错”的优先级要高于“创新”。此处的“创新”指开发新特征:可以是一个新的功能,也可能是一个技术架构上的优化。
 
原因如下:
1. 在纠正错误的过程中,可以找到更好的方法,或者有更多的经验来实现新特征。
2. 纠正错误的工作如果放到开发周期的最后阶段,所花费的时间要长。原因两点:同样的错误可能已经在多个地方出现;修改一年前写的代码比修改几天前的代码难度大。
3. 想一次性地修改完毕所有的错误是不可能的,同时改正多个旧错误的同时,必然会引入新错误。为了避免这个怪圈,最好的方法就是一个一个地修改,测试,关闭。
4. 规定只有把错误改正之后,才能增加新特征。只有把错误数保持在近乎于0的数量上,项目的进度才是真实的。而且,这样状态下,项目总是处于可随时交出已开发完毕特征的有利地位。如果管理层允许错误向后迁延,进度失控的可能性非常之大。
04 gennaio

军备竞赛之二

近三年来,大部分工作时间和业余时间都花在了某一个大型计算机系统的设计开发与组织管理上。虽然说心无旁骛,乐在其中,但是明显视野变窄,思考问题常常会被“经验”主导,人文和艺术方面也有明显退步,在向搞财金出身的领导汇报工作的时候,经常不能言简意赅地切中要点。是该充充电,换换脑筋了~~~
 
元旦假期中,抽空放“狗”搜索了一些在美苏两国冷战期间,极端刺激下军事工业中的典型案例,剪刀加浆糊拼凑出来,与大家分享另外一种系统设计的思路与灵感。
 
上回书说的是关于战略核武器当量指标方面,赫鲁晓夫在美国人创造的世界纪录基础上,拉了一个300%的涨幅,使美国人在这个问题上永远没有了想象空间,改而宣布核武器小型化,制造战术核武器。今天我们则讲一讲另外一个著名的设计案例:超越时代的设计:米格25。
 
50年代末,美国洛克希德公司放出风来,开始研制升限30000米、3倍音速的YF-12高空高速截击机。为对抗具有上述划时代性能的YF-12截击机,同期苏联米高扬设计局开始研制米格-25机。
 
与米格-25同时进行研制的还有米格-23,米格-23的设计思路是稳妥为主,在米格-21的基础上进行小幅改进,由总设计师米高杨负责具体研制。而米格-25的“冒险”设计则由米格设计局的二号人物格列维奇具体负责。米格-25的研制具有非常大的风险,从它的外形上,看不出半点上一代米格飞机的踪迹,其性能比起从前的米格飞机也是不可同日而语,也远超同代的西方截击机。
 
尽管米格-25有着无与伦比的高空性能,但中低空性能相对较差,发动机耗油量巨大,航程短,并不是一个“完美”的设计。可由于其进行了量产,并装备实战,而同期美国具有相同设计目标的YF-12则没有正式服役,演变成为没有截击功能的SR-71侦察机,美国的三倍音速轰炸机XB-70也没有正式服役,这使得米格-25当之无愧地拥有了“超越时代设计”的称号。总之,一个系统必须要从试验环境中走出来,投入生产,才能够获得升华。
 
在1971年第四次中东战争爆发前夕,1架埃及装备的米格-25R侦察机在与以色列装备的美国最好的战斗机F-4遭遇后,以跨越时代的差距,轻松甩掉F-4以及F-4发射的AIM-9“响尾蛇”近距空对空导弹,这架米格-25的速度超过了马赫3.2!其高速优势将所有的美国战机比了下去,“一俊遮百丑”,不明就里的美国人则把米格-25看成一种较为全面的先进战斗机,推测其使用了当时很新潮的涡轮风扇发动机,苏联人掌握了钛合金材料的技术。直到1976年9月6日,苏军飞行员维克托·别连科叛逃到日本,美国才算搞清楚个中奥妙。
 
米格25的研制并不是一帆风顺的,据解密后的资料表明,米格-25在试飞中,出现的问题很多很严重,其直到1968年试飞才在多次修改设计后结束,才宣告基本成功。
 
米格25到底用什么样的设计思路解决了同时代其他设计师没有解决的问题?
 
首先要解决的是“热障”,在零摄氏度的空气中以马赫1.3飞行时,摩擦生热,温度可达到72摄氏度。而在以马赫2.05飞行时,温度上升到107摄氏度。当马赫3时,这一温度将达到300度!在机体材料方面,传统的飞机结构材料硬铝因为耐热能力只能到130度,而不能使用。钛金属耐热能力和重量方面都符合要求,但是昂贵,难以加工,且苏联缺少耐高温的铆钉等连结材料。苏联人选用的是美国在F-108 和B-70上同样的技术:主要结构(80%)采用不锈钢。即先解决热障的难点,钢虽然笨重,但在耐高温方面能符合要求,且焊接技术成熟,机体上的焊缝长达 4,000 米,焊点多达 140 万个,避开了高温铆钉这一问题。大量的钢结构解决了米格25突破热障的主要问题,同时高速飞行的机体强度也得到了保证,试飞中就顶住了11.5G的高过载。 除此之外,还有许多难关有待克服。例如象传统的座舱盖、橡皮轮胎及油封等等,都无法承受高温,甚至连液压系统的液压油也会因高温而变质,只有这些看似微不足道却可令米格25无法顺利升空的问题一一解决之后,米格25的雏形才渐渐显露出来。该设计中,不锈钢焊接结构曾招致很多人非议,原型机三度坠毁。但政府和军方对技术问题没有横加指责和干预,技术人员和试飞员则表现了高度的责任心和进取精神,面对困难不动摇,通过科学的态度予以克服,终于取得成功。总之,要制造新一代的米格飞机,那么就要突破原来的框框,大胆创新!

其次要解决的是“动力”,不得不采用了钢结构之后,那么就要制造出能把这个巨大的钢铁玩艺送上天的发动机。当时,第一代涡扇发动机的研制刚刚起步,在已有的加力式涡喷发动机中也选不出合适的型号,从头研制势必延迟飞机研制进度。于是决定以当时为高空无人驾驶飞机研制的低增压比试验型涡喷发动机15K 为基础,由米库林/图曼斯基设计局按米格-25 的设计要求进行改进。据负责发动机改型的型号总设计师费·乌-苏霍夫称,改型设计的工作量很大:为增大喘振裕度修改了压气机;为适应高空工作重新设计了燃烧室;涡轮前温度提高了 50℃;消除了加力燃烧室的燃烧振动;采用了三种工作状态的可调喷口。改型发动机实际上只保留了原来的机匣,编号为 R-15-300。总之,好东西是反复改出来的。
 
另外,电子化和自动化要求非常高。以雷达为例,米格25的雷达是同期中性能最好的,然而由于苏联电子技术的相对落后,其性能是靠加大功率来实现的,因此该雷达的功率大到了一种超乎想象的地步。据说该雷达在地面开启的话,会杀死300米外的兔子。米格-25的雷达装有高度锁定装置,不飞到一定高度是不能启动的,以防无线电辐射伤害地面人员。大功率的缺点是耗费大量的电能,容易暴露目标;优点是在电子技术落后的情况下实现了预定性能指标,且对干扰的穿透能力强。这些特点也为后来的苏联雷达所延续。总之,把强项发挥到极致,其弱项就不再成为弱项。
 
========================================
米格25系列机型(E-266M)有六项至今未被打破的世界纪录:
 
1975年5月17日:
自海平面爬升到25000米(82000英尺):2分34.3秒
自海平面爬升到30000米(98400英尺):3分9.85秒
自海平面爬升到35000米(114800英尺):4分11.7秒
 
1977年7月22日:
带2000千克(4400磅)有效负载飞上37090米(121622英尺)
带1000千克(2200磅)有效负载飞上37090米
 
1977年8月31日:
无负载飞上37650米(123492英尺) —— 这几乎是40000米,直到目前仍是绝对的世界纪录
 
01 gennaio

军备竞赛

1942年,美国在研制原子弹的过程中,推断原子弹爆炸提供的能量有可能点燃轻核,引起聚变反应,从理论上证明可以制造一种威力比原子弹更大的超级弹。1952 年11月1日,美国进行了世界上首次湿式氢弹试验。美国第一次试验的湿式氢弹,由于采用液态的氘氚材料,重65吨,体积十分庞大,并没有实战价值,但是规模相当大,为1500万吨TNT当量。美国到1954年,试验了2500万吨TNT当量的氢弹。
 
苏联人起步晚一些,但是有我们中国近代以来常称谓的“后发优势”,于1953年8月21日爆炸了第一颗干式氢弹装置。由于采用固态氘化锂,首次试爆的威力小很多,但是具有实战能力,可以用飞机投掷。到1961年,苏联在美国的“世界纪录的指标”上“翻了两番”,设计出通常称为“赫鲁晓夫弹”的超级氢弹,当量为1亿吨TNT!剩下的只是试验问题了,最后决定在新地岛试验场实施爆炸。试验场占据了整个新地岛,面积为8.26万平方公里。然而,当设计者们计算出爆炸威力的半径为1000公里时,感到为难了:离新地岛750公里即有城市和人口稠密居住区。由于威力太大,这颗炸弹在广阔的苏联国土,甚至地球上竟然找不到任何地方可以“试验”(自杀或者杀人不算)。苏联同志们在请示赫鲁晓夫后决定把装药量减少一半,为5000万吨当量,进行了一次空前绝后的试验。
 
回头看来,如果没有美苏军备竞赛的历史,也许人类没有机会制造这种永远不希望也没必要使用的“高科技”产品。美国的2500万吨也罢,苏联的1亿吨也罢,仅仅作为指标和试验存在,这些氢弹没有任何实际价值。
 
01 dicembre

历史思辨

观察有文字以来的国家历史,大多数情况下,并不是一个从美好的设想开始,一直正确地从开始走向完美结局的历史。而往往是从美好的设想开始,在前进中,受偶然性影响以及人类本身的局限不断犯错误,并在错误中反省,通过分辨、质证的方式,总结经验,积累智慧,不断进步的历史。
国家历史如是,具体到项目历史也如是。
02 giugno

Giga Scale Transacting

最近在忙处理具有海量业务规模的联机事务处理系统的性能优化,对照计算机系统架构学术界高端的研究方向:"Tera Scale Computing",“发明”了一个词 Giga Scale Transcating. 
 
抽空小结几点:
1. 只有CPU快还不够,内存访问也要快才能真正地提高事务处理性能。
2. 内存快还不够,要保证数据安全,必须写到磁盘,磁盘也要快才行。
3. 365*24*7运行的系统,它的耗电量不可小瞧。
4. 应用软件架构设计中一个事务由多个进程顺序完成与CPU微架构设计中的超流水线技术(Super-pipline)道理相同。
5. 一台机器支持多个事务能够分组多个进程并行处理,与CPU微架构设计中的超标量(Superscalar)道理相同。
 
 
11 settembre

AO处理Issue感想

以下几种情况:
1. 用户不知道问题是什么,需要给用户解释;  :-) 
2. 用户知道问题是什么,但是问题其实不在这里; 
3. 用户知道问题是什么,但是过去没有写下来,时间长了,失传了;
4. 用户知道问题是什么,AO没有精确记录,BuildTeam理解错了;
5. 用户之间不同意见,甚至敌对;为难;
6. 时过境迁,问题发生了变化,原来的SPEC要修订;
26 febbraio

白话项目工作

协调就是求人帮忙; 你帮人家,人家才会帮你.
计划就是预留变化; 要未雨绸缪,不能临渴掘井.
管理就是严以待人; 当然要更严的律己.
朋友就是会把你的事情当作他必须支持的人;当你做错的时候指出来并帮忙解决, 谁敢说自己永远正确?
学习就是有不懂的时候立即去弄懂;遇到高手的时候尝试去交流;发现错误的时候勇于改正; 提出另外思路的时候不抵触.
16 febbraio

对儒家经典的回顾

今天很高兴,一个困挠项目多时的问题在领导的大智慧和绝大多数相关者的支持下,有了重大的进展,大家在一次“对表”后,可以分头并进,等待下一次的“对表”时刻的到来。禁不住想起了小时候读的一篇《 孟子》:
 

天时不如地利,地利不如人和。三里之城,七里 之郭,环而攻之而不胜。夫环而攻之,必有得天时者矣;然而不胜者,是天时不如地利也。城非不高也,池非不深也,兵革非 不坚利也,米粟非不多也;委而去之,是地利不如人和也。故曰: 域民不以封疆之界,固国不以山溪之险,威天下不以兵革之利。 得道者多助,失道者寡助。寡助之至,亲戚畔之;多助之至,天下顺之。以天下之所顺,攻亲戚之所畔;故君子有不战,战必胜 矣。”

另外一个感想,那就是工作性质从单纯的开发转换角色到协调以后,常常思考的就是如何使得沟通有效,而不是单纯地“程序正义”;如何高效解决问题,而不是开游哉游哉的神仙会。要知道大项目动辄牵扯好多部门,每个参与者都非常忙碌,时间紧张,一个决策可能影响几十万甚至上百万的投入。为此要在一个重大会议之前,先逐个和各参与者商量解释,多次反复和讨论,使得到真正开会之前,各参与者都基本了解了背景,并且基本达成共识,那么到会议上大家讨论的话题只是最精彩的部分,大家思路也会开阔,创新和高水平的观点才会层出不群。