2008年3月29日星期六

用例浅谈

用例(use case)是现代软件工程中用来采集需求和软件设计的一个常用工具。那么用例到底是什么东西?什么时候用这个工具?如何使用这个工具呢?本文就结合本人在日常工作中的实践经验来做一个简单的介绍。

用例的定义有很多,几乎每一本书的作者都有自己的理解。但是用例的本质不变,系统的使用者对系统发出的一次请求,用例描述系统完成这个目标的过程的一种方法。因此我们可以用4个词来概括用例;他们是:角色,请求,步骤和目标。 有的书上说是三个要素。一个是参与者,也就是我这里的角色。一个是用例只描述单独的任务,也就是我这里的请求和步骤;最后一个是用例必须产生一个对用户有意义的结果,也就是我这里的目标。

系统的主要角色(可能是最终用户,也可能是其他系统)启动了一个交互,他有一个用户目标(user goal)。由于用户请求的上下文不同,前提条件不同,因此这个交互可能产生多个场景。一个UC会把目标相同的场景集合起来。


用例的格式

一般来说,用例可以以多种形式编写,但是大多数情况下都是用于和非专业人员交流,因此,用纯文本方式比较好。同时可以节约时间。

对于用例的格式,很多书上面都有不同的定义,但是我个人认为,用例没有特别的格式。只要意思清晰明了即可。每个人编写的用例都是不同的。UC写作有简化版本和完全格式版本,可以根据项目规模大小选用。

使用用例来发现需求

当编写一个新系统的用例时,一般先写黑盒,然后设计人员细化时变成白盒。黑盒UC的作用主要用来引发讨论,一般由PD或者RE来写,写好之后和Dev和Test以及客户进行讨论。因此UC常常被用作是头脑风暴的工具。UC本身的功能就是捕捉已知的功能性需求并为之建模,这样可以完成高质量的需求报告,相对来说比一般方法要可靠,完全的多。

但是用UC来找出需求时需要注意两点:
1. 它是真正的需求,不是行为或者过程,应该要正确的写出系统必须做的事情,而不是如何做事情。
2. 它不是所有的需求,它们不包括外部接口,数据格式、业务逻辑以及复杂的公式等。他们组成了所有需求中的一部分。不过虽然只有一部分,但是是最重要的一部分。


用例的价值

UC很流行大抵上是因为他们一致、连贵的说明了这个系统是如何使用的。在早期提出完备的UC,系统的使用者就知道该系统可以做什么了。他们可以及早的做反馈、进行调整或者拒绝该UC。不管采用何种设计方法,需求分析阶段的用例建模工作都能发挥极其重要的作用。

有一些公司是不是用用例方法的。他们使用的是Feature。首先获取用户需求,然后由PM大致写出该系统的Feature,当然要包括所有的用户需求,然后通过头脑风暴完善Feature List。最后为每个Feature添加Function List。

事实上,系统级的黑盒UC就可以看作是Feature。每一个步骤就是这个Feature下面的功能。

UC的价值最早产生于当这个用户目标(user goal)创建,并把它们放入到系统的特性列表中去时。这个列表说明了系统可以做的事情,规定了系统的范围。

这个List会由用户代表,PM,公司专家,行业专家代表等人检查。他们会用这个Feature List估算成本和系统实现复杂度,由此确定系统的起始点。这个列表可以联系到复杂性、风险管理、成本、时间和状态检查。

第2个价值体现在UC的作者用头脑风暴的方式把主成功路线上一切可能的错误列举出来的时候。这时候,他可能会发现一些令人惊讶的事情,或者是客户没有想到的事情。这些事情可能导致新的使用者,新的UC的出现。

第三,用例可以帮助我们划分软件的开发周期,评估研发工作量。对于优先级较高的用例会在早期的迭代周期中实现,优先级较低的用例则安排在后续的迭代中完成。

用例模型在整个开发过程中都扮演着非常重要的角色。它用来驱动软件的分析和设计逐步细化。

最后,软件项目中的功能性测试用例,基本上都是根据用例模型来确定的。

用例建模

用例建模是通过分析用户的功能性需求,得到用例模型的工作过程。一般包括下面几个步骤:

  1. 确定系统边界
  2. 确定参与者
  3. 找出所有用例
  4. 确定每个用例的级别
  5. 用例描述
  6. 画出以整个系统为对象的顺序图
编写用例

不要一开始就写出所有的细节,这是违反事物发展规律的,就像荒谬地要求把需求全部搞清才能做设计一样。用例的细化一般有4个阶段。
1. Actor & Goals
列出所有参与者以及他们的用户

2. Use case brief or main success scenario
选出主要的一些UC,写出触发条件和一个大致的轮廓,也就是主成功场景。保证该系统的功能真的是Stakeholder们感兴趣的。

3. Failure conditions
完成主成功场景后,用头脑风暴的方式找出所有可能的失败,首先把它们全部列出,而不是直接就讨论系统的应对之策。

4. Failure handling
写下系统是如何处理每一个错误的。这时候,常常会有一些原本不明显的问题被渐渐暴露出来或者错误处理会突然引入新的用户或者新的用户目标。

大多数项目时间紧张,人员精力有限,在项目前该确定要工作到何种细致程度,因此我强烈建议按照上面4个顺序来。

2008年3月20日星期四

到底什么是需求?

《HFOOAD》给了一个我觉得很简单,又很好的答案。单独拿出来做个笔记。
首先我借用一下里面的图片来说明问题。


那些黑色高亮的词是需求的几个特点。

specific thing
一个需求往往是一件单独的可测的事情。因为只有可测,才能保证你完成了客户的需求。

system
系统指一个完整的应用,或者是项目程序。因为客户只能看到这个。

do
系统做的事情,或者说是行为。

work correctly
一个系统是否正确是由客户说了算的。为了使最后系统能够正确运行,我们不能漏了任何一个需求,即使客户当时忘了,我们也不能忘。要从客户那里找出潜在的,忘记了的需求。才能使系统正确工作。


给出一个比较正规的定义
需求就是一个单一的要求,该要求详细规定了指定的系统或者服务的特征和行为。

论文写作正式开始

今天终于开始论文写作了!

自从我提交开题报告到现在都有4个多月了,如果按照开题报告里面的进度计划,我应该已经在收尾阶段了。可是当中遇到了很多事情,一开始准备复习高口,想在三月份把高口考出来,论文放到高口考完之后再写,可是接下来遇到母亲生病,很多计划都打乱了,最后到三月份高口也没有考,论文也没有写,这几个月几乎什么事都没有完成。真是人算不如天算啊。

现在我就开始觉得时间有些紧了,一般来说工程硕士要在4月中旬提交论文初稿,然后在5月份修改和审批,5月底答辩。但是我现在除了一个idea,还什么都没有,心里有点不安啊。

前两天每天下班回家都会考虑两三个小时,昨天晚上基本上把写论文的过程整个想了一遍。然后做了一个简单的计划,于是今天正式启动!接下去的两个月里面,基本上就是苦难的生活了,白天上班,晚上做论文。朋友老段曾说过,做事情要一鼓作气,“一而再,再而衰,三而力竭”,我很同意这句话,这次的论文不能拖,一定要一鼓作气完成。

像我们工程硕士,写的大多是工程应用论文,我也不例外。但是我不想写些什么“XX系统的实现与改进”,这个太没有技术含量了。我写的论文跟我的工作有密切关系。我的工作是AFC系统,我的论文就是AFC系统中一个关键模块--数据采集的改进。里面涉及到一些有意思的技术,比如词法分析器,处理分发器等等,因此总的来说还是有点技术含量的。

我把这个程序看作一个小项目,完全按照一个项目来安排需求分析,设计与开发,测试与部署。希望在写论文的过程中把我这两年里面学到的各种技术总结一下,运用一下。这样,我两年的研究生也就没有白读,对得起那40000块大洋了。

2008年3月19日星期三

好书推荐《HFOOAD》

为了不把标题弄得过长,我用了缩写,本书全称为《HEAD FIRST OBJECT-ORIENTED ANALYSIS & DESIGN》中文译名《深入浅出面向对象分析和设计》。



这本书是O'Reilly的Head First系列丛书中的一本。本书为什么好,我觉得有这几个方面。

一、本书对OOAD的讲解由浅入深
OOAD发展到现在也有10几个年头了,现在大多数人都在名义上采用OOAD在开发。但是有多少人真正懂OOAD呢?很少!国外少,国内更少!OOAD不是UML,OOAD 不是需求分析,OOAD不是Design Pattern。OOAD是一整套分析与设计的架构,它包含很多东西。市面上不乏好书,比如《Applying UML and Patterns An Introduction to Object-Oriented Analysis and Design and Iterative Development, 3rd Ed - Craig Larman》,或者《AGILE SOFTWARE DEVELOPMENT: PRINCIPLES, PATTERNS, AND PRACTICES》。但是在看这两本书的时候,我总是有摸不着边的感觉。看书的时候以为自己懂了,可是真正写UC或者做领域模型设计的时候又发现自己无从下手。后来我发现这是我自己水平未到。而且我喜欢的是简单的,真正能让我模仿的例子。《HFOOAD》做到了,它写的很浅,由浅入深。从一开始的分析客户需求到后面的健壮、可重用的设计,重构和设计模式,以及在设计时候遇到问题时功能和效率,成本与维护的平衡的选择,这么多OOAD的步骤和技术被作者抽丝剥茧,一步一步放在我面前。

我相信,一个希望自己变得更专业的软件从业人员都会喜欢这本书的。对我自己来说,我觉得虽然我进入这个行业有4,5个年头了,而且还有着计算机科学与技术的教育背景,但是我还是要很羞愧的说一句:我还不是专业的。

专业的人员是怎么样的?一句话,人家用正规的方式做软件,人家有方法学的支持。现阶段,主流的方法学就是OOAD。需求分析用什么?用例、场景、故事板,原型等等。怎么过渡到设计?领域模型、E-R关系模型、接口设计,类图等等。详细设计怎么做?UML主打,敏捷和迭代随行,设计模式长伴左右,测试驱动护驾。人家知道在什么时候用什么方法来解决问题。

所以要成为专业的人员,我以为有三个阶段:
第一阶段:学习理论基础,知道有哪些方法,有哪些阶段;
第二阶段:知道在什么阶段该用什么方法;
第三阶段:知道如何有效率地使用方法以及该得到什么样的结果。并且保持知识更新。
我认为《HFOOAD》这本书可以让我进入第二个阶段。而第三个阶段需要自己不断实践和摸索。

二、Head First系列独特的学习风格
我不知道这种学习风格是不是适合所有人,但是我觉得很合我胃口。
首先它不像其他的书,首先扔出一大堆定义把人砸晕,然后给出零零碎碎的例子,没有连贯性,实用性。它的教学方法是通过给出真实的场景,图片,对话等各种刺激大脑的方法来促进学习的效果。让人身临其境肯定要比单纯的文字要让人感兴趣的多,不是么?但是这需要看书的人主动参与,用自己的想像力带自己进入文中的场景,和里面的人一起动脑筋,一起动手做。面对如此好书,还用以前囫囵吞枣的方式看书,那还不如不看。

我还没有看完本书,有谁原意和我交流学习心得,欢迎来信。

补充:
2008-3-19
1.有人认为学习OOAD需要学习UP,RUP等开发过程。我觉得这个不是必须的。UP只是一个被定义了的开发过程,是个成品,大家可以直接使用。但是作为产品,就肯定有用户群。有用户群也就有非用户群。很不幸,大多数企业都有自己的一套做法,这时候生搬硬套某一种开发过程反而会起反作用。 因此我们学习OOAD就是学习OOAD的各个组成部分,既将他们独立开来,又让它们保持一定的联系,然后选择合适的应用到我们自己的企业中。慢慢的形成以OOAD为基础的自己的一套流程。

2.最近被人关注的比较多的是《Head First Design Pattern》。我自己个人认为,Design Pattern是具体技术,做软件应该由大及小,自上而下,先把握整体,再考虑细节。同时DP是需要有大量的经验支持的,掌握DP需要顿悟,我自认没有10年功底,我即使学了DP,也无法灵活应用。就像一个小孩拿着一把倚天剑,却无法发挥其作用一样。而OOAD则相反,这是基础,能早学一定要早学,打好基础。

善解人意的google

我一直使用google作为我首要的搜索引擎,是因为我一方面对google有一种盲目的好感,另外在心里面也觉得其他的搜索引擎不如google好。但是到底google好在哪里,我也说不大出,只是曾经用google和baidu,yahoo比较过,发现还是google找出来的东西又快又正确。

今天又让我见识了一下google的人性化。我在搜索Head First这个词组,因为最近一直在看Head First系列的书,对国内翻译的深入浅出有点不太理解,所以像看看它原来的解释。金山词霸上面的解释是“冒失地,头向前地”,这显然不是我要地答案。

我想到了Marriam Webster这个最详细的词典。我一般来说都会先进入Marriam Webster的网站(http://www.m-w.com/)然后查找单词。但是今天我却想试试google能不能一下子定位到Marriam Webster。

我在google里面输入"head first m-w",结果google就像我肚里的蛔虫一样,第一条记录就是Head First在Marriam Webster的解释。妙哉!搜索引擎能做到google这样“善解人意”,我还有什么好说的?

比较了国内的BAIDU,出来一大堆不知所云的结果,看也没看,直接关掉!

2008年3月17日星期一

Visual Studio 2008,我还没有准备好

昨天从MS网站下载了一个Webcast,是关于VS 2008的新特性介绍的。本来是为了写会议记要用来交作业的,所以也不打算仔细看。但是后来慢慢被吸引了,最后发现VS 2008竟然让我感到我离技术的浪尖越来越远了。

在VS 2008中,.Net Framework 已经升级到了3.5。

在VS 2008中推出了一种和编程语言整合的简单数据访问语言LINQ(Language INtegrated Query),用LINQ可以很简单的访问数据库,进行增加,删除和修改操作。它的思想和OR Mapping很相近。把Table映射成对象后,所有的操作都是对对象进行的,然后通过后台的序列化更新到数据库。

MS也终于把VSTO整合到了VS中去,这个开发Office所用的组件从通房大丫鬟变成小妾了。在VS2008中可以直接创建基于VISIO,WORD,EXCEL等的项目。

VS2008还增强了HTML/CSS编辑器,B/S项目现在已经成为主流,MS在这方面的支持实在很到位。HTML编辑器增加了和Dreamweaver一样的上下屏编辑窗口,上屏代码,下屏直接预览效果。CSS编辑器也非常强大,以前写CSS要靠开发人员的经验,手写CSS,还要进行调试也比较麻烦。在VS2008中,有一个傻瓜化的CSS编辑器,点击下鼠标一个漂亮的效果就出来了。不过在我看来,这个功能很鸡肋。假设我们在一个注重版权的公司里面。做HTML和CSS往往是UI设计师的工作。我很难想象公司会为这些人配置一套VS2008。要知道一套VS2008 Team Edition的价格可以抵得上N个UI设计师了。

WPF, WCF, WWF的完美支持。MS一直希望加强B/S系统的可操作性和表现力。但是要把瘦客户端程序做成和富客户端程序一样效果,光从HTML和CSS来说还是很困难的。于是MS就推出了WPF,一个基于XAML的图形库。不过老实说,我觉得还不如Adobe推出的基于Flex的解决方案好。WWF是基于Workflow的东东,我不懂,也没有兴趣。

VS2008的重定向功能,在VS2008中,用户可以随意的创建基于各种版本的.Net Framework的项目,其实也就是三个2.0,3.0和3.5。确定了.Net Framework的版本之后,支持的项目也会变化,乃至动态提示功能也会只对应的那个.Net Framework。我觉得MS在兼容性上做的的确很好。

不过说了这么多,这些都不是我需要的。我做的是系统编程,用的是C++,这个看起来快要落伍的东西。但是我相信C++有它自己的一片天地,我也有我的。只是发现VS离我越来越远,有些感慨罢了。

2008年3月13日星期四

妈妈已经可以起床了!

《Overload now, payoff later》中我提到了我妈开了一个大刀治疗椎管狭窄。今天是我妈手术之后第21天,按照医生的嘱咐,第14天拆线完毕之后就可以带着腰围下地了。但是我们都还有点担心,所以让我妈多躺了一个礼拜。同时她自己心里也不怎么敢下地。

今天早上我去为她付出诊费,回到家里一看她床上没人,吓了我一跳。后来发现她竟然一个人在洗手间!原来妈妈感到大便很急,而阿姨又出去买菜了,她实在没办法,只能自己起床去大便。没想到这样也让她去除了心理障碍,从今天开始她终于愿意起床做康复治疗了。

不过她说一开始起来头晕的很,恐怕是长期卧床导致的。我扶她上床的时候发现她的腿已经萎缩得不成样子了。穿着原来的棉毛裤空落落的。我妈原先的体重大概120多斤,现在估计100斤都没有了。以前听医生说长期卧床大腿会萎缩,但是毕竟没有亲眼见过,但是今天真是让我大吃一惊,仅仅3个礼拜卧床就能让大腿变得那么细。我不敢想象如果这次没有果断的做手术,导致我妈长期卧床做保守治疗会是个什么样子!

有时候,做人一定要果断。

接下来我要求阿姨帮助我妈一步一步做康复治疗,先坐起来,等头不晕之后,在下地活动。一开始时间少点,10分钟到15分钟,慢慢的增加时间。

今天真是一个值得庆贺的日子!

2008年3月12日星期三

开源和免费

今天上网的时候在PCHOME上看到一篇文章《够用就好 常用共享软件的免费替代品》。里面介绍了几个常用软件的开源或免费替代品。在我们这个不注重版权的国家里能有人提倡这个,看来人们也开始关注这方面了。事实上,在很多大公司里面都很注意这方面的问题,有些公司很严格的完全杜绝盗版,比如我一个朋友所在公司“中芯国际”。他们很早就已经强制把ultraedit,acdsee等软件请出了硬盘。一开始,人们不习惯,但是经过一段时间的适应,人们也慢慢有了版权意识,就算在家里也只用开源或者免费软件了。这方面,台湾人做的的确不错。

我自己用的大多数也是开源和免费软件。我这里也介绍一些我常用的软件。作为PCHOME那篇文章的补充。

Office软件:
SUN OPENOFFICE 2.3非常不错,完全兼容MS Office。不是我不支持国产软件,但是我一直不怎么喜欢WPS。

压缩解压缩:
7zip,绝对是7zip。其实winrar也可以不买一直用,只不过如果要浏览内容的话会出现一个提示窗口。7zip的速度完全没有问题,我解压缩一个1g的rar文件,用winrar是4分13秒,用7zip是4分16秒,效率上差不多。另外压缩比例7zip要比rar高一些。LZMA算法果然强悍!

图像浏览
IrfanView不错,界面稍微丑了点,Picasa也很不错。两个正好互补用来看单个图片和批量图片。

文本编辑
文本编辑对于我们程序员来说是很重要的。因此我有好几个编辑器,一个是基于SciTE的Notepad++,一个是vim7。一般情况下Notepad++已经可以胜任大多数情况,界面也非常友好。vim7可以提供一个很强大的编程环境,vim+ctags以后就能通过函数名找到函数声明,对读代码很有用处。vim的!%xxd命令可以用来查看二进制内容,这使得我最后一个留恋Ultraedit的理由也没有了。vim另外一点就是所有操作几乎都可以在主键盘上完成,对于使用笔记本的人来说很方便。emacs我也用过一段时间,但是emacs时间比较复杂,所以我放弃了。

图像处理
Paint.net需要.net支持,所以我不太感冒。我使用的是Unix下大名鼎鼎的Gimp。一开始可能用不管,但是时间长了就知道他的强大之处了。我个人认为比Photoshop有一段差距的,但是一般处理图片绝对能胜任。

PDF
阅读PDF当然是用Foxit Reader。这么快的pdf阅读器,谁不用谁是傻子!
生成PDF,有两个工具。一个是我常用的open office 2.3,直接保存成pdf。另外一个是Letex,这个我在linux下用,据说也有windows版,生成的PDF绝对漂亮!

听音乐
千千静听和foobar这两个我都用过,最后还是foobar占据了我的硬盘。无他,就是喜欢简单的工具。如果想听APE需要下载一个插件。

FTP
FileZilla,我用下来感觉很稳定,很方便,很强大。大概带Zilla的东西都不错。不知道以后会不会有Zilla Fan这一说!

源代码管理
公司用的是又贵又不好用的Clearcase,现在在Clearcase下面我连Debug都不行,只能靠打trace或者用Dump Stack来分析问题。因此我喜欢小巧的SVN,配上windows上最好的客户端TortoiseSVN,已经能完全满足一个大型公司的要求了,更别说我自己个人开发了。

播放器
还用说么?Windows Media Classic 6.4.9.1。稳定,CPU占用率小,启动快,自动加载字幕,对一般看看片子够了。另外国产的酷热影音也不错,速度很快,插件管够!

安全
安全涉及到杀毒软件和防火墙。我用的是Avast! Home版。这个捷克的软件我很喜欢。CPU占用率中等,每天自动更新。实在不放心再装个360安全卫士。Windows这东西防是防不住的,只能自己注意不要上乱七八糟的网站。浏览器用FF可以防止一些ActiveX控件。

基本上一般日常使用的软件都在这里了。详细以后会有越来越多的付费软件被开源或者免费软件所替代。

2008年3月11日星期二

搞定无线路由

昨天在淘宝上买的NETGEAR WGR614终于到了。拿到手一看,白色的,样子很漂亮,真是很庆幸没有买TP-LINK或D-LINK那些黑色的砖头。

不过在设置的时候遇到了些麻烦。这个机器真是奇怪,说是无线路由,但是无线一开始是禁用的。必须要用有线方式把无线功能开启才行。于是照着说明书连好网线。因为我是在公司里面试,所以用的是固定IP的局域网。然后就搞出一系列稀奇古怪的问题,我在这里总结一下,希望对以后自己和别人都有用。

  • 设置页面进不去
这是第一个问题,IE总是处于返回状态,但是界面上面就是一片白。我感觉可能是插了外网的网线所致,所以把外网的网线拔了。然后再试,一下子就进去了。结论是:进控制界面最好拔了外网网线,如果不行就把路由断电,再重新开启。

  • 配IP
如果在局域网内就直接配置局域网IP,网关和DNS。配好之后按“测试”按钮,如果成功就能连到NETGEAR中国网站。

  • 什么都设置好了但是还连不上INTERNET
我运气不好,遇到的就是这种情况,结果只能死马当活马医,不管三七二十一直接RESET。这个RESET键可以看机器背后的示意图,就在WAN插口附近。按5秒左右就能重置。然后再设置一边。


信号强度。NETGEAR不愧是排名第二的厂商。质量要比公司自己用的TP-LINK好的多。我站在60米外,隔了3堵墙还有1~2个信号。看看页面是绝对可以了。

少吃三、五斤

中午看到消息,食品价格上涨20%多。尽管近几个月各种物价持续上涨已经让我神经粗了很多,但是这个消息还是让我感觉一种无力感。看来我的减肥大计终于要在08年实现了。真好×_×~!。

其实从去年8,9月份物价上涨开始,我已经感到开销的增加了。比如脱脂牛奶,从6.7元变成现在的10.9。幅度之大令人乍舌。由于我妈身体不好,日常开销基本上就由我来把关了。“不当家不知柴米贵”这句话我现在有了深刻的体会。我也学会了买东西挑挑拣拣,和菜场里面小贩讨价还价,在抽水马桶的水箱里面放个瓶子节约用水。

对于这样的变化,同事们都在叫怎么还不加工资。前两天传出消息,这次工资涨幅将是10%~15%,不过是在基本工资的基础上。公司打的真是如意算盘啊。本来这10%应该是去年物价上涨的时候全国统一要求。公司那时候硬是不涨,一直到这个月才给涨。看似最后还是涨了,但是实际上公司却把两次加薪并作了一次。着实耍了我们一回儿。

更让我气愤的是,两个月前的报销单被退了回来,说现在加班吃饭已经不能报销了。Admin会在每个月底根据实际加班单把饭贴(12元)打到我们的饭卡里面。我真不知道公司什么时候变这样了,连通知我们一声也没有,我们还照着以前加班50元饭贴来吃饭,结果可想而知,两个月下来,我亏了好几百!!!要人干活,还不让人吃好,这班不加也罢!

这两个礼拜已经开始有人陆陆续续离开公司了,甚至4年多的老员工也离开了。为什么,因为做了4年还只是一个SE,两个Senior都没有捞到。可笑的是,公司随便招个根本不懂业务的,又不会C++的也能当Senior,因此他失望透顶,不想再留了。看来公司4月份将是一个大换血月。前年4月份,公司发好年终奖,一个人都没有走,大家都干劲十足。今年4月还没有到,公司里面就弥漫着一股子颓废的气氛。人心散了,公司也不远矣!

2008年3月7日星期五

PM with no IT background

这片文章我准备写双语,因为这是个真实的笑话。虽然还不是非常可笑。
It's a real joking, though it's not so funny.

昨天我正在写程序,突然听到旁边得一个PM在和他手下得一个程序员通电话。很快他说出了非常经典得一句话:
“……那个错误号是0乘以80004005……”
我还没有反应过来,但是80004005对我来说再熟悉不过,是COM的错误“Access Denied”。于是我很快反应过来,这个PM报的是一个COM错误。不过把0x报成0乘以,这个PM真是太有才了。从这一句话,我就能知道他没有多少编程经验或者it行业经验。
还好他没有报成0乘以8千万4千零5,否则我肯定喷饭!!

I was writing program when I heard a PM beside me calling his engineer. Soon I was attracted by him, : ".... the error number is 0 multiply 80004005....."
80004005 is very familiar to me because it is a COM error "Access Denied". Thus I knew he was saying a COM error, but he mistook the hexidecimal prefix 0x to be "0 multiply".... He is genius, my God!
It's not bad he didn't say "0 multiply by 80 million 4 thousand and 5" , otherwise he was killing me for sure!!


---------------------------------
PS. 我好像没有讲笑话的天赋,我自己看了都不觉得好笑。。。。。 原谅我把,就当冷笑话冷处理好了。。。。

2008年3月3日星期一

钱到用时方恨少

我有记帐的习惯。但是我平时用钱很少,所以基本上每个月都能控制在千把块。开头我把2月份的账单整理了一下,结果吓我一跳!我2月份竟然用掉了将近25000块。但是也的确是事情比较多。一开始买了个WII,然后过年,然后开学交了学费8K,最后是买了台笔记本,妈妈生病用掉8W多块钱,虽然都是父亲付得,但是平时零零碎碎加起来我也付了4,5千了。

真是钱到用时方恨少啊。平时觉得自己还有些积蓄,但是真正碰到事情了,这钱用起来就像流水一样哗哗哗地往外流。现在就这样,我不知道到结婚,买房会怎么样个惨烈的情形。

我准备这一年的目标就是努力赚钱了。再和去年一样混日子是不行的了。

2008年2月29日星期五

小黑入手-ThinkPad T61 AM6

自从几个月前我的PC开始间歇性抽风以来,我就知道我那台老机器该退役了。之后我一直在台式机的优秀性能和笔记本的轻便上犹豫着。后来我终于决定买笔记本,一方面是因为现在工作和读书的性质已经决定了台式机无法胜任我的要求了,另一方面是因为我要搬到张江去了,台式机搬起来不方便。经过一个多礼拜的调查和观望,今天我终于出手了。机器是从www.nbclub.net的上海分部买的。我下了班之后直奔普陀区中江路。到那里已经7点半左右,nbclub比我想的要大的多,有好几个员工,看来水货笔记本生意还是很好的。

机器我早已经定好,ThinkPad T61 AM6 + 1G内存。
机器配置很不错,
CPU: T7500 2.2G
Memory: 1G
Hard Drive: 160G 5400/8m
LCD: 14.1 SXGA+ 1400*1050
Display Adapter: Quadro NVS 140M 128M DDR
外加DVD-RW,蓝牙,1G迅盘,指纹识别、802.11agb
OS:Vista Home版
外加nbclub附送的原装红点包+IBM原装鼠标+IBMThinkPad清洁套装+转换叉头+IBM原装内胆包一个+微软专业游戏鼠标垫一块+一次成型网线一根+NBCLUB T61全自动恢复光盘一张。

价格: 机器9950+1G原装内存180=10130RMB。

在我看来这个价格配这台机器已经是相当超值了,更别说外带的这么多实用的附加产品。看照片永远没有实物来的震撼。当我看到小黑酷酷的外壳,IBM舒适的键盘,再加上IBM ThinkPad的标志,我开始激动起来了!我知道我买对了,没有买笨重的台式机真是明智的选择啊!!试机用了大概半个小时,运气很好,没有遇到坏点机器。虽说一两个坏点不影响使用,但是心里总归会有疙瘩。机器的分量2.3kg对我来说还是很轻的。本来想买宽屏的一款,可惜宽屏的都是4芯电池,待机时间太短了。换成6芯的就会突出来一块,极不雅观。而且我也不大看片子,所以还是这款标屏的算了。

现在我唯一担心的就是我只要买大件就出问题的超级霉运。希望这次老天爷能够抬抬手,睁一只眼,闭一只眼吧。





大多数机器都不在有IBM的标签了,据说这款是最后一款带有IBM ThinkPad标签的机器。


不过在屏幕下方还是打上了Lenovo的烙印。

Overload now, Payoff later

My mother was made a major operation last Thursday because her acantha hyperplasia oppresses her nerves nearby which deprived her mobility of her right leg. Unfortunately, it happened on the first day of Chinese Spring Festival. A unbearable pain stoke her and put her stay on bed. She wes sent to hospital on 12 Feb, and the doctor ask her to be in hospital immediately.

The operation was very successful according to doctor. 3 pair of nails were injected to her back bone to help enlarge the gap between acantha and fix it. It costed us more than 70,000 RMB. She was able to speak the next day. And I was surprised that she could even bend and unbend her right leg without any pain.

My mother is recovering very well, but this is not the point of this article.

From this event, I am asking myself. Why Mom got this painful thing just when she is just 54. After this operation, She has to live rest of her life with some steel stuff within her body. She can't bow too much. She can't do too much manual work. I can't image how her rest life will be.

Why? A simple reason is that she worked too much and avoided to protect her acantha. Of course no body likes to work and overwork. But in fact, most people are overloading there youth and energy when they are young no matter they are involuntary or have to.

I am one of them. Overwork to me is just like a habbit. I didn't remember when was last time I had gone back home on time. My working buddy is a computer, I sit almost all day long. I never go to gem. I go jogging every 2 or 3 weeks. I am getting fat. I always feel tired. I am just typical one of this generation. We have heavier stress more than any generations before both in mental and physical. Some of us try to change their life style. They manage to do it some a period. They turn a full circle back because the reality.Other people are overloading too. But they are just profligate of their lives. They play online game all night. They stay up in KTV, dance club and bar.

They maybe or maybe not realize that they are over using their life energe. Dead and alive are two ends of a seesaw. When we are living, the alive end is down relatively. We use energe of our lives and alive end goes up. When we run out of our energe, Dead end goes down and we die. When we overload our life energe, Alive end goes up quicker than usual. So do Death. The more we use our energe, the earlier payoff comes.

It is nature rule that Alive end goes up. But we can control its speed. But how do we know its speed? Easy, if you feel any uncomfortable, tired, pain etc, your body is warning you that its over speed. You should get to take care, avoid overworking, go to work out, take some centrum, go camping to have fun, change your mood. The sleep is low if you feel sharp, energic when you get up.

Remember, life is not credit card.

2008年2月13日星期三

Linux之父的人品令人质疑

最近一直在使用linux,因此对linux关注也比较多。随之看到Linux之父Linus Torvalds的新闻也多了。昨天就看到一篇Linus Torvalds抨击Leopard和Vista的文章。他在说Leopard完全是个废物,他说从编程开发讲,OSX的环境要比windows差很多,它的HFS文件系统简直是垃圾。

老实说,我自己很喜欢Leopard,我并不觉得它是个废物。同样,使用苹果的人也都很赞赏Leopard。Linus的言论给我感觉就像一个偏激的极端主义者。人们尊称其为lead of cult of Linux,说他是Linux世界的领袖。但是这种极端主义者能做领袖么?

Linus很喜欢做这样的事情,上次就抨击过C++,“C++是一种糟糕的(horrible)语言。而且因为有大量不够标准的程序员在使用而使情况更糟,以至于极容易产生彻头彻尾的垃圾(total and utter crap)”。我的C++水平还不到能和他辩论的水平,但是我相信就算我的水平到了他的级别,我也不会随便去贬低其他语言来彰显自己的地位。当年Andrew发明C#的时候,他没有说过一句Java的坏话。C++之父也只是实事求是的指出C在一些应用领域的不足才导致C++的产生。

作为自由世界公认的领袖人物,我认为Linus更应该注意自己的言行和修养,现在Linux是在夹缝中求生存,Linux在桌面领域只占有1%左右的市场份额,我不知道他从哪里获得那样的自信来抨击这两个桌面市场大颚。

前阵子看到另外的报道Con Kolivas放弃继续对Linux桌面性能提高的开发。Con Kolivas在Linux世界中是个异类,他很早就注意到Linux在桌面领域的性能远远不如windows和apple。但是Linux核心开发组的人们仍然陶醉于Linux在服务器市场上的发展,而对桌面领域视而不见。他只能自己操刀提高Linux桌面应用的性能。他的CK Patch在好几年来获得了大量的支持者。可惜,他还是没法改变Linux世界的那些人的观点,最终他心灰意冷放弃了。这其实也和Linus所指定的Linux发展方向有关。他的方向就是关注服务器市场,这样导致Linux内核越来越笨重,把应用于服务器的内核放在桌面应用中,当然导致的就是较差的用户体验。

Linus还有很多偏激的言论,基本上google这个人,出来的一半结果都是他发表自己的偏激的意见。Linux到了今天这个地步,已经不再是他个人的东西了,作为一个自由的OS核心,这么难能可贵的东西,他更应该考虑使用者们的感受,而不是自己的个人喜好。

2008年2月4日星期一

X11,FVWM,GNOME,KDE的区别

我用Linux也有一段时间了,但是在看一些老鸟们的文章时经常看到一些WM啊,桌面啊,X11啊之类的词,我模模糊糊的知道这些都是关于图形介面的名词,但是具体什么区别就不知道了。

今天抽空稍微查了一下,终于知道了他们的区别。

X Window System
X Window 系统版本 11,简称 X11,是一个运行于UNIX上的对网络透明的客户/服务器架构的图形显示系统。X并不是UNIX核心的一部分,而是在核心之上的一个应用程序。X提供一种协议,用来产生图形用户界面GUI。X不会负责很多事情,它只负责绘制(Drawing),移动窗口(Moving windows),和鼠标、键盘交互。X11 是 Unix 事实上的图形系统标准。Linux,各种 BSD 版本和多数的商用 Unix 都采用它,类似 CDE,KDE 和 GNOME 等桌面环境都运行在它之上。但是Linux使用的是一个叫XFree86的免费X11实现来提供相同的功能。不过由于一些License的问题,现在 X11的实现已经变成XOrg了。在Linux里面可以到/etc/X11/xorg.conf看到其配置文件。

Window Manager
在多数图形环境中,窗口边框的外观(标题栏,关闭按钮,等)如何显示是由系统定义的。 X11 则不是这样。在 X11 中,窗口的框架(也称为"装饰")是由一个称为窗口管理器的单独程序提供的。一般认为,窗口管理器只是另外一个客户程序;它用通常的办法启动,并与 X 服务器按同样的方法通信。有很多不同的窗口管理器供我们选择。 xwinman.org有一个详细的清单。多数常见的窗口管理器都允许用户定制称为主题的窗口外观。许多窗口管理器还提供额外的功能,象在根窗口上的弹出菜单让用户启动程序,docks,或程序启动按钮,提供一个或多个虚拟桌面。有一些WM还提供与桌面环境(A Desktop Environment)交互接口。

WM的功能可以用简单的一个词来概括--中转。比如一个程序要求X11绘制一个窗口,这个请求会首先被重定向到WM,WM来确定如何绘制窗口的标题栏(caption)和边框(Frame),在X系统中,这两个元素是由WM决定的。因此用户在窗口上拖拉和缩放也是由WM来做出反应。大多数WM还支持窗口最小化,也就是变成一个在窗口底部的图标。这项工作不属于X系统核心协议之列,因此是一些WM自己实现的。

大多数WM还处理一些其他的任务,比如显示根窗口(root window),这个就是Linux里面的桌面,和windows的桌面是topmost window同样的概念。WM还处理在根窗口上的键盘和鼠标操作,比如Alt-F4关闭窗口之类的功能。


GNOME,KDE,xFce等
这些都是桌面环境(Desktop Envrionment),他们运行于WM之上,提供更完善的桌面集成功能,更自由的定制操作系统使用方式。X上面的桌面环境与windows,Mac OS X等不同,它可以自由组合,自由更改。大多数的DE由窗口管理器(WM),文件管理器(FM),一组主题(Theme)与其他用来管理桌面的程序和库组成。所有这些组件都可以单独调换,随意组合成自己想要的桌面环境。不过现在很多Linux发行版都有一个预先固定的组合比如GNOME,KDE等(这两个已经成为最流行,最成熟的DE了)。这里有篇文章对大多数的DE做了比较。
http://en.wikipedia.org/wiki/Comparison_of_X_Window_System_desktop_environments

2008年2月2日星期六

2008年第二场大雪

前两天刚刚下了一场雪,没想到昨晚上又下了,而且更大。早上起来一看,地上的积雪足足有5公分厚。

看看我们家门口.....
家门口的雪


不幸的是我还要到公司加班。哦,忘了说了,我们和其他公司不同,这个双休日是照常休息的。中午吃饭仍旧去软件园,这里的人已经在打雪仗了,一路走过去,受到无数“友善”的问候。
软件园的人们兴奋啊


打起了雪仗


吃好饭,路过软件园的时候看到好多雪人,于是心血来潮把所有的雪人都拍下来,弄个“张将软件园雪人大赛”呵呵!
Snow Ogre


雪人1


猪头雪人
雪人2


呆瓜鼠
这个不错


这个有创意,还有耳环,不过总给我一种感觉好像是《Star War》里面的人物......
有创意,还有耳环!


这个比较一般
这个比较一般


招财猫
招财猫


这几个雪人酷
这几个雪人酷!

某人贡献了袜子和喜糖
某人贡献了袜子和喜糖


比基尼MM
泳装MM

我们浙江网新的作品友情参与,不过似乎比软件园的差些。
我们浙江网新的作品


软件园一角
软件园一角


路上全是雪
路上全是雪

和上次的比比,这次的雪厚多了
这次雪厚多了

我自己做的太极图
我自己做的太极图

2008年2月1日星期五

PHP5 can't connect to SQL Server 2005 Database

Yesterday, I started my small PHP tool for traffic chart embeded in my AFC project. Although using PHP with MySql and Apache is very common, I had to use Php adapting to my AFC project environment that is under windows 2003 server R2 and SQL server 2005 standard.

I built the environment in minutes and made php run quickly. Things seemed go easy. But a strange problem got in my way that my program could not connect to the SQL server 2005 database. I checked everything to ensure no grammer error and made the source file as simple as just one line -- calling "mssql_connect" function.

I knew the reason till I read a post in http://cn.php.net/function.mssql-connect, it said "The ntwdblib.dll should be version 2000.80.194.0, and not version 2000.2.8.0 that PHP 5 ships with"

But I can't download that file from the website the author provided and it is difficult for me to find it over the internet. So I upload and share it from my box. Anyone needs can download it from:
http://www.box.net/shared/qfmoo1ask4
and override the one in your php5 folder.

2008年1月28日星期一

2008年第一场大雪

上海昨天已经开始下大雪,今天早上起来,竟然积了挺厚的一层雪,虽然还没有银妆素裹的感觉,不过对于好几年没有下大雪的上海来说,已经够我兴奋一阵子了。我记得上次看到这么大的雪应该是在我初二的时候,也就是大概93,94年的样子。之后就没有过这么大的雪了。我今天特意带上了相机,一路上班,一路稍微拍些照片,留个纪念。谁知道下一次上海下这么大的雪是什么时候呢?随着全球气候变暖,上海这个南方城市能飘个雪花,下个雪子已经很不错了。

这是张江,我工作的地方。
First Snow of 2008



First Snow of 2008



路上的积雪其实不是很厚,但是走在上面滑溜溜的感觉真是久违了!路上看到有些女孩子很开心的滑着走路,看来年轻人的心情都差不多啊,呵呵。
Not so thick



走向张江软件园...路上的积雪已经被无数张江男,张江女踩化了。
Walking to Office



以前短短的5分钟路,今天却格外的长。
Still snowing



First Snow of 2008

2008年1月26日星期六

C++基础知识:函数指针

本文总结了C++中函数指针的使用方法和使用场合


声明
函数指针在C语言中已经存在,顾名思义,这是一个指向函数的指针。其声明方式如下:

int (*fp)(int); // a pointer to function that takes an int and return an int

这是一个“指向带有一个int参数,返回int值的函数的指针”。这时候可以把为该指针这样赋值。

int foo(int);
fp = foo;
fp = &foo;
fp = 0;

可以用函数名直接赋值,也可以用显式的方式用地址符取函数地址,函数指针还可以赋值为0。这和其他指针是一样的。不过直接取地址的方式是没有必要的。编译器会帮你取地址。

调用
函数指针的调用有两种方式,显式(简化)调用和隐式调用。

int k = (*fp)(100);
k = fp(100);

这两种方式是一样的。但是后面一种显然更符合使用习惯,不过请记住,这只是一种简化

使用
最常见的使用方式是回调函数。回调函数的意思是把函数指针告诉别的程序,由别的程序决定何时调用。比如windows编程常用的subclassing方式

LONG NewWindowProc(HWND,UINT,WPARAM,LPARAM); //申明了一个用来回调的函数。
SetWindowLongPtr(hWnd,DWLP_DLGPROC,NewWindowProc); // 设置了回调函数

// 当有信息过来的时候,windows 会调用NewWindowProc。
LONG NewWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// message processing logic.
}

回调函数一般在“当你不知道何时调用函数,但是知道函数该执行什么样的任务,返回什么样的结果的时候用
再来一个例子,一个书店有两种方式付款,现金和信用卡,用户可以选择使用一种方式付款,为了让程序简便,可以使用函数指针:

extern bool PayByCash(double);
bool PayByCreditCard(double){...}

bool (*Pay)(double);

if( CustomerWantByCash )
Pay = PayByCash(amount); // amount is a double
else
Pay = PayByCreditCard(amount);

....// do some prepaid check and preparation
bool success = Pay();

如果想要把函数指针用在重载函数中,函数指针本身必须提供多个重载版本。解析规则和重载函数解析规则相同。比如:

bool PayByCash(double);
bool PayByCash();
bool (*Pay)(double);
Pay = PayByCash;
Pay(1000.0); // 调用的是第一个PayByCash; 因为类型一致
Pay(); // error!
还有一种常用的方式是把函数指针传递给另外一个函数,使得那个函数可以在它自己的函数体内调用我们传入的函数指针。比如设计一个sort函数,它接受三个参数,前面两个参数是两个相同类型的对象实例,最后一个参数需要一个函数来告诉它如何比较。我们这里不讨论具体实现,仅看看其声明方式:

void sort( T, T, fp);

这里的fp将是一个函数指针,指向一个函数接受sort的前面两个参数,然后返回一个int值,来表明两个T的逻辑上的大小。因此这样的函数可以声明为:

int compare( T , T )();

因此对应的函数指针为:

int (*fpc)(T,T)();

其类型为

int (*)(T,T)

因此sort函数的原型可以声明为:

void sort( T, T , int (*)(T,T) ) ;

使用typedef,提高可读性:

typedef int (*CH)(T,T);
void sort( T,T, CH );



提升难度
现在,我们来提升一下难度!假设我在首地址为0的地方有个子函数,我该如何去调用呢?让我们想一想!首先我们已经知道了函数指针的声明方式:

void (*fp)();

在C/C++中,知道了一个类型,那么它的类型转换符也就容易得到了。只要把声明中的变量和最后的分号去掉即可,再在外面用括号括起来,也就是:

(void (*)())

这就是一个指向没有返回值的函数的指针。
这时候,我们可以把0地址强制转换成函数指针了。也就是:

(void (*)())0 ---- (1)

这就是一个指针,把他看做void (*fp)()中的fp即可。想想我们如何调用fp指向的函数的?不就是fp()么?但是这里由于是强制转换的,因此不能用这种隐式方式,要使用显式调用方式,也就是(*fp)();
我们把上面的fp替换为开头的 (1)式,既得:

(*(void (*)())0)();

但是这种方式大家都会看着头痛,因此我们可以用typedef声明。

typedef void (*fp)()
(*(fp)0)();