All Stories

穿越东西涌

  这次是从西涌到东涌这样的路线。以前听很多人说过,就是自己没去过,这次可是切身体会了一把。  本来自己的负重差不多,不会让自己太累到,结果出发前有2个mm把一些水和水果放到我包里了,结果真的重了好多。  今天才知道,原来东涌和西涌也就是两处海滩游泳场,穿越就是沿着海岸线从一端走到另一端。  沿着海岸线很不好走,大半的是礁石,剩下小半的路程是在山上爬,真的是爬哦,我还带了跟登山杖去,没用上,太难走了。中途一mm要虚脱了,于是我发扬不怕苦不怕累乐于肋于舍已为人的国际共产主义绅士风度骑士精神,帮忙背上她的包,果然又重了很多!  非常不幸的是,在从一高处跳到低处时,左脚踩到一块不平的石头上,于是扭伤了。不幸中的大幸是,已经离终点并不远了,咬咬牙总算也坚持下来了。  拍了一些照片,总的说来,海景很不错,怪不得总会有拍婚纱照的要去海边,今天就碰到两对,呵呵。

软件工程大会

  今天上午去听了软件工程大会的几个议题,发现挺没意思的,没有多少收获。大部分都是炒冷饭,没有激情,没有让人耳目一新的感觉。全是敏捷来敏捷去,持续集成来持续集成去,TDD来TDD去的。  于是下午就没去了,写了几行代码,把log4cxx加到工程中了,用xml格式的配置文件,看起来比较统一,所有的配置文件都是用xml的,哈哈,不过我的配置文件也太多了点。发现还是不能直接在代码中用unicode,编译时没问题,但是链接不通过,不知道什么原因,难道是哪里设置的问题。不过中文倒是可以了,在家里编译的不行,输出全是乱码,而且同事也一直说是乱码,不知道是编译的时候用的操作系统影响的,还是编译器影响的。

感觉像是一种耻辱

  不分还好,一分就郁闷了,感觉像是一种耻辱。

软件可测试性设计

  可测试性设计,即所谓的DFT,今天又一次重重地感觉了一次它的重要性。  系统中有一个权限管理模块,同一个物理用户可以不同的逻辑角色登录系统,系统中以各个逻辑角色为最小管理单元进行权限管理。一般情况下,用户可选择的逻辑角色范围是极有限的,绝大多数用户应该有只一个逻辑角色,当然在测试情况下,情况刚好反过了,基本上每个物理用户会有几个逻辑角色,容易暴露出问题。主要集中在,角色拥有的权限不正常,比如看到了不该看的,看不到该看的,可以做不该做的,做不到该做的。  一直以来,对这块的调试/测试都是很困扰我的问题,主要就是DFT没做好。最开始,把所有业务逻辑和界面绑定在一起,差不多每一条规则都要在界面上点来点去,构造很多与真实环境类似的数据去测试,非常麻烦,不容易遍历到各种情况。  后来将这模块重构了,把业务逻辑和界面分离,用单元测试来保障逻辑的正确性。从DFT的角度讲,这种代码架构方式,就是一种改进,对DFT的改进。  有了单元测试,还不能保证程序能完全正确地运作,因为除了逻辑正确,还有可能其他地方出错,比如输入数据就有问题。在前些天他们测试的一个版本中,依然发现了一些权限相关的问题,让我觉得比较郁闷,因为我一直以为应该是万无一失了的。不过事实摆在眼前,也逃不掉,今天老老实实地在那里定位,不过开始的时候还是异常困难,因为测试场景的千奇百怪,我的开发环境下,有些场景很难模拟。  后来突然灵光一闪,我应该为了方便测试,多写一点代码,多加点功能,比如当前这个问题,我可以加一个特性,能在某种特定条件下,使我可以以任意角色登录系统。说干就干,果然很容易地定位到了测试发现的几个问题的原因。  今天的经历告诉我,在软件可测试性设计方面,有很多值得研究的东西的,天呐!

炒冷饭

  说话那天还在抱怨嵌入Python真辛苦,后来突然灵光一闪,马上解决了那个执行外部脚本文件的问题!既然现在已经能做到这一步了,接下来就应该考虑,能利用这个能力做些什么事呢?  总的说来,现在我已经有了嵌入4个不同风格各有千秋的脚本语言解释器的经验:Lua、TCL、Ruby、Python。以后如果有需求,我估计TCL是不会再使用了,总觉得它的语法太枯燥了点。剩下三者,对Lua和Ruby的了解稍微多一点点,但也还没达到能用来做独立应用的程度。相比之下,Ruby的那种怪异变态的语法,还是比较吸引人的,还有就是它带了那么多稀奇古怪的库,可以大大减少重复劳动,这比Lua来说,省事不少。但Lua的轻巧,却一直让我觉得是嵌入的最佳语言。实在让人难以取舍呀!  想了想,WIND就只用Lua嵌入了,因为这是一个相对比较追求性能的应用。而WallpaperHelper其实用什么似乎没多少影响,而且照现在的趋势,WallpaperHelper的体积已经不成为主要关心的问题了,功能才是最重要的。另外还想过要写打谱程序的,也要嵌入扩展。StoneBase的功能让人比较满意,但从写代码的角度看,它的架构不行,可扩展已经成了继续发展的必经之路了。但我还没想好,是用MFC,还是WTL,或者wxWidgets来写呢?

让SMTP支持中文

  项目里要有发送邮件的功能,想法非常简单,公司有个SMTP服务器,通过它直接就可以发送到notes中了。网上SMTP的源代码也是一堆一堆的,找了一个CodeProject上的,加上base64编解码也只有4个文件,接口非常简单,于是稍微改了一下,base64本来我就有,就只需要加入2个文件就可以了,附件也能正常发送,很是满意。不过上周五的时候突然发现,主题和内容中的所有中文都变成乱码了,有点气馁,随便又找了几个其他的代码,也是一样。  今天闲起无事,就想改一下。只知道在哪里看到过说要用base64,就能解决这个问题。尝试着先把主题编码了,发现收到后就是编码后的字符串了,这也是预料之中的。上公司的论坛发了个帖,没人回复。后来自己忍不住了,用Outlook Express写了个邮件,主题和内容都是中文,然后打开Wireshark,抓包,比较了一下CodeProject上那个代码发送的,看出区别了,原来也就是加上个charset="gb2312",再base64,就搞定啦!

嵌入Python真辛苦啊

  两年前,就嵌入过python,那时宿主程序是用C++Builder开发的,python还是2.4,没用第三方库,完全用python C API直接操作,而且当时要暴露的接口不多,才4个C函数,当然还是费了不少力气。嵌入python的目的是为了主程序可以实现外部脚本扩展,只有一个很简单的应用场景,点击一个菜单项,就执行一个py文件。首先是要让它能执行起来,python文档有很多C API,例程却极少,记得当时连接1个半月每天至少到后半夜2点才睡,最后累得上wc连掀马桶盖的力气都快没有了。而且很大的问题是,在家里自己的电脑上终于可以跑起来了,拿到公司的电脑上却不行,每天只能晚上回家调,白天再到公司测试,很郁闷,我已经忘了最后是怎么搞的,反正是最后发现在公司的电脑上缺少一个site.py文件,直到这一刻才发现,这是python官方发布包中的一个文件,当时是自己放了一个0字节的文件在那里搞定的。那次这么多精力的投入真是不值,做出东西来本来想得个满分的,结果只打了个C,而且当时指定了4名专家评审,结果只有2个专家发表了评论,另2个还没评论就走到下一环节,直接C了,唉!  今天又看到很久之前写的计算hash值用的小程序CryptTool,核心功能早已完成,就是计算字符串,或文件的hash值,包括多种算法,比如MD2、MD4、MD5、SHA1、SHA256等等等等。后来出于尝试的心理,想给程序加上外部脚本扩展的功能,准备支持Lua、Python、Ruby三种脚本,而且不自己写粘合代码了,而是采用SWIG自动生成。Lua和Ruby的支持很快就完成了,可是Python的却一直有问题,网上翻了不少代码,以前C++Builder中的那个代码也翻出来,都是有问题,那时就搁下来,今天又心血来潮地想弄一下。  最主要的困难还在于对Python缺少了解,但这并不能成为借口,Lua和Ruby不就好好地嘛!这里我用的方法是把外部脚本文件作为module,import进来,但是一直返回一个空指针。实在没办法,PyErr_Print打印的内容又是输出到控制台的,而我的是个标准的MFC写的GUI程序,所以只好另外建了个控制台的测试工程,幸好模块独立性较好,几个文件拷过去略作修改就可以了。通过控制台输出的出错信息才知道,原来是import时,还会连带着import一些python自己的库,于是把python的lib目录添加到sys.path里。另外,如果说import这外部脚本文件时,报找不到该名字的module,就把脚本文件所在的路径也添加到sys.path里。终于可以在import时,执行一遍该脚本了!不过还有另外一个问题解决不了,就是调用Py_Finalize崩溃!在网上找了一圈,也有一些老外遇到这个问题,不过要么就是没有下文,要么就是给出的解决方案不适合我这种情况。因为我是import来执行脚本的,当没有Py_Finalize,而同一进程内再import时,就不会再执行了,作为外部扩展,有一个办法是定义一个基本规范,脚本中一定要实现一个指定名字的方法,再由宿主程序来调用这个方法,但这太不友好了。其实如果能用PyRun_File之类的API来强制运行一个文件的话,也是可以达到目的的,但还是绕回原来的路上去了,我这里PyRun_File这类API死活不能正常执行一个脚本文件,天呐!  于是还剩下一个遗留问题,怎么能解决脚本每次都能执行的问题呢?嵌入Python真辛苦啊!

杨柳坑快乐游

  部门组织去杨梅坑游玩,之前只看别人去玩过,自己却没去过,所以在出游前,一直有点儿兴奋。  早上等车等错了地方,有点囧,有点恼。坐了一个多小时车,终于到了目的地。每人都去挑了自行车,好久不骑了,有点感怀。租好了车,却一直不出发,等几个自驾车过来的人,有点不耐烦。估计等了有十几二十分钟吧。  一路逆风,而且风很大,路上看到不少前面的人被风吹掉的旅游帽。大概骑了半个小时,到了目的地,一个别墅,再过去就是悬崖了,悬崖不高,下面是海!在这么偏僻的地方看到悬崖,不禁想起很多肥皂剧里的那些跳崖的剧情,有点无语,当时的人们想像力还真是不够丰富啊。  悬崖上也风很大,拍了几张合影,也没什么玩的,就回去了。回去是理所当然的顺风,大概15分钟就当了,然后就是吃中饭。中饭比较合我口胃,是海鲜,但称不上大餐。价格不便宜,但也算不上贵。海鲜也是最常见的虾、蟹、鱼、花甲、扇贝,其他的就没什么值得说了,不过我还是吃了3碗饭,哈哈。  吃过中饭,就去桔钓沙。上一次去桔钓沙应该是2006年9月9日吧,记得当时小丫头不在深圳,说得她很遗憾的样子,小丫头应该很喜欢去海边玩吧。这次时节不适合下水了,风也很大,于是我只是躺在席子上用手机上网看小说,就这么过了一下午,直到4点半,打道回府。

n多bug

  今天终于发版本发出去了,但是,用别人的话说,几乎不可用。  这个版本确实进行了大幅修改,不但增加了新功能,还进行了重构,对原来使用的那一套机制50%被翻修过了。  那些出现的问题,都落在没有经过单元测试的模块,但是那些模块都是我不知道如何进行方便有效的单元测试的。  其中主要的还在于两个模块,一个是界面交互,确实不好测,另一个是数据库操作。当时的接口设计可能过于复杂了,导致后来想做单元测试时,很是畏惧。实际上,数据库操作部分,也是可以进行单元测试的,而且我想着要把本地数据库从Access换成SQLite,更是应该趁这个机会补充单元测试用例了。