软件质量的思考

最近跟一个业内人士K聊天,讲到下面的故事:某国内软件公司人士J跟K抱怨说,你看,我们公司跟你们一样的写文档,一样的code review,甚至可能做的比你们还多,为什么我们做出来的东西总是感觉差那么一截呢? 是啊,为什么呢?是不是说,我们有了合适的软件的过程,比如严格定义的waterfall model或者scrum,甚至CMM这样的东西,外加严格的Policy,比如unit test coverage比如85%以上,kill all bugs with priority 1-3,就能保证软件的质量?好像不行。这些如果放在传统意义的生产型企业,也许可以,因为大多数生产是由机器来完成的,只要按照手册做事情就好了。但是软件业,是由一群mind worker来完成的,所以process只是一些辅助工具,最重要的,还要看执行这些process的人。这是我对这个问题的答案。 好像说了一段废话,谁不知道“二十一世纪人才最重要”?不过,还有别的么? 接下来的问题,如何找到合适的人呢?

一月 20, 2009 · Shawn Ma

How to get promoted as a developer

在网上看到一个人写他做一个developer被promote的感想,觉得写的很好。记下来与能看到这个文章的developer们共享。 First, NAIL the fundamentals. I’m a developer, so a large part of my time in the product cycle is spent fixing bugs. I made sure I was the fastest, most efficient, and best bug fixer. I made sure I was the guy you wanted to call when the server crashed in the lab with a crazy callstack and no reproducer. Second, OWN the features. I got involved in features up front, by spending time getting to know the PM team. I influenced the features, I lended my expertise on them, and I learned about the customer – all this way before the spec’ing phase. Every spec coming to this team had my feedback in it. The PM team loved having my technical expertise freely available, and I actually really like designing features too. ...

一月 17, 2009 · Shawn Ma

DKIM技术

前段时间看gmail的时候,发现邮件头上都有一个mailed by的字段,比如mailed by: yahoo.com,不知道这个东西是怎么来的,于是查看了一下整个header,发现有一个DKIM-Signature的字段,于是又去google了一下,了解到这个原来是一个新的标准,叫DKIM,定义在RFC4871里。它的功能是:让企业可通过密码对进出站的电子邮件进行签名,证实所发送邮件的真实性。 DKIM的全称是Domain Key Identified Mail(域名密钥识别邮件)。简单的说,就是发送邮件的服务器对邮件做签名,表示这个邮件的确是该服务器发送出去的。如果一个接收端能够验证这个签名,一定程度上表明这个邮件可能不是垃圾或者钓鱼邮件——原因是现在大多数的垃圾和钓鱼邮件都使用伪造的email地址。当然,这个技术不能单独解决问题,因为一个垃圾邮件发送者也可以自己做一个服务器来对发出的所有垃圾邮件签名。但是,由于邮件是签名的,我们就可以通过黑名单和白名单来进一步了解某个域名发出的邮件是否为垃圾邮件,甚至可以在网上维护一个域名的积分系统。 签名另外一个好处就是,DKIM提供一定的完整性(integrity)的保护,保证这个邮件在发送过程中没有收到篡改。 那么这个签名是怎么做的呢?基于公私钥的签名系统。发送者在服务器上生成一对RSA的key,私钥自己保存好,公钥放在DNS的TXT记录中,比如一个站点叫example.org,那么其DKIM的公钥通过_domainkey.example.org的TXT记录就可以查询到,这样接收方就很容易知道发送方的公钥了,也就可以验证这个签名。这个方案好的一点是,不需要一个第三方认证的CA——毕竟,每年通过CA签名一个证书也要好多钱。这也是DKIM跟以前的签名技术如S/MIME, PGP等不同的一个地方。当然,通过DNS的TXT记录也有其安全性问题,完全有人可以hack掉DNS,或者通过类似GFW的方法改变DNS查询的结果,但是DKIM只是一个辅助技术,是用来防范垃圾邮件的,并不是一个strong authentication system,如果真的对安全性要求那么高,就应该使用PGP之类的其他安全系统。 接下来的问题是,签名是如何加入邮件的呢?通过DKIM-Signature邮件头。这是符合邮件协议(RFC2822)规定的。这是跟其他签名方法又一个大不同之处,避免了任何不理解S/MIME的客户端把签名当成一个附件(比如gmail),或者把签名显示为一段跟内容没有关系的base64编码。接收方则根据DKIM-Signature头的内容来验证该签名。 一些签名的具体细节: 算法,必须支持rsa-sha256,可选支持rsa-sha1。key size建议1024。王小云老师在这里贡献不小。 标准化(Canonicalization). 有的邮件服务器可能会少量修改文件内容,比如换行或者移除一些空格等等。因此DKIM定义了两种标准化方法,simple和relaxed。simple最简单,就是一个字节也不能改,改了就错。relaxed就是可以少量的修改一些空格等等。邮件头和内容这两部分的标准化可以选择不同的方法,表示起来用/隔开,比如simple/relaxed表示头部用simple方式,内容用relaxed方式来标准化。 过程。签名是先对内容(body)部分hash,然后把这个body hash放在header里面,再对头部做签名。头部也不是所有字段都签名的,只有一些常用的字段,或者比较有意义的,会被签名。像Received和Return-Path这样的字段一般不被签名。而From则必须被签名。 差不多啦,来看个真实的DKIM头吧: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type; bh=LKY45ARqaaOMfM6XOs6BBkYA44a4+H26qQdm9oC55X0=; b=QhTXCrvIhk......XQbXhFl4Xk575ACw= 可以看到一个DKIM-Signature由一系列name=value的tag组成。其中: v=1表示版本1,将来要有新的版本,就扩展之。 a=rsa-sha256,表示算法(algorithm)。这里用了rsa-sha256的算法。 c=relaxed/relaxed,表示标准化方法(Canonicalization),头部和内容都用的relaxed方法。 d=gmail.com,发送者的域名。 s=gamma,表示域名的selector,通过这个selector,可以允许一个域名有多个public key,这样不同的server可以有不同的key。 h=…,表示后面这些header是签名的一部分。 bh=…,是body hash。也就是内容的hash。 b=…,是header的签名。也就是把h=那个里面所有的字段及其值都取出来,外加DKIM-signature这个头(除了b=这个值,因为还不存在),一起hash一下,然后用rsa加密。 最后看一下如何获得上面这个例子的public key。对于s=gamma, 这个gmail服务器的public key存在gamma._domainkey.gmail.com的TXT字段里。在Linux上dig一下: $ dig gamma._domainkey.gmail.com TXT ;; QUESTION SECTION: ;gamma._domainkey.gmail.com. IN TXT ;; ANSWER SECTION: gamma._domainkey.gmail.com. 300 IN TXT "k=rsa\; t=y\; p=MIGfMA0GCSqGSIb3...DAQAB" nslookup也是一样的: C:\>nslookup > set q=txt > gamma._domainkey.gmail.com Non-authoritative answer: gamma._domainkey.gmail.com text = "k=rsa; t=y; p=MIGfMA0GCSqGSIb3.....AB" 其中的p=那一段就是public key了。 ...

六月 11, 2008 · Shawn Ma

加速windows xp的软件: eboostr

知道这个软件很久了,今天在CNBETA上看到,又搞了一个来玩玩,加速程序启动的效果还是不错的。 Vista的两个功能让我很感兴趣,一个是super prefetch,一个是ready boost。基本原理就是,1,把常用的文件缓存在内存里。2,使用U盘这种读取速度比硬盘快的设备来缓存常用文件。这样,启动一个程序的时候,如果能够从内存中或者速度比硬盘快的闪存中读取到需要的DLL,那么程序启动会快很多。 对于XP,有个公司做了一个程序eboostr,做类似的事情。他也可以把缓存放在内存,或者U盘(SD,MMC或者一切读速度比较快的设备)。搞了一个绿色版本,在这里。安装的要两步:第一,选择里面的inf文件,右键,选安装。第二,运行installservice.bat。然后重启就好了。运行eboostrCP.exe开始配置吧!不过这个软件正版只有39美元,条件合适的情况下还是应该买一下的。 我看,随着内存价格越来越大白菜化,将来我们应该可以直接把操作系统安装到内存,这样这些什么fetch都不需要了,再将来,我们要把OS装到CPU的L2 cache里面去……yeah… Linux似乎不需要这样的东西,因为linux内核会把不用的内存用来做文件的缓存,这样,当第二次启动某个程序的时候,速度也是很快的。

五月 28, 2008 · Shawn Ma

Scrum project management tool: Mingle

最近打算练习一下scrum,就在网上找一些scrum的管理工具。找了很多免费的工具,比如xplanner, agile42什么的,都不是很好用。xplanner看起来就令人生厌。有一个Project Dune的,利用Google GWT做的一个应用,看起来还不错,但是安装了之后有好多问题,比如什么deadlock的问题,mysql无法访问的问题,而且我看他们对scrum的支持的screenshot也很简单,就放弃了。 收费的软件貌似很多,很容易搜索到,有versionone,mingle等等。mingle好像网上用的比较多,有一些中文网站推荐,去看了一下,5个人一下可以Evaluate一年,而且支持unix/linux,就试用了一把,感觉的确很不错。 Mingle的核心是卡片,所有的东西都是卡片,比如feature, story, task等等。卡片可以通过树状结构组织起来,就形成了需求分析阶段的features树,也可以是计划阶段的planning树。最后,树上的节点,对于mingle来说主要是story,会被投入到sprint当中去。team member可以自主的选择一个个的story去实现。我们用的时候觉得story有点大,把story又分了很多的task,这样一个人可以负责一个task。 它的强大在于,卡片是可以扩展的。它使用了一些类似BPM的概念。一个卡片本身不代表任何意思。然后我们通过给他添加property来指定他的属性。比如类型,开始日期,结束日期,工作量预计等等——可以理解为面向对象里面的属性。接下来还可以给卡片增加Transition,可以理解为方法。比如一个task在new状态的时候,加一个Take Task的transition,那么就可以把这个task的owner设为当前用户,把task的start date设为今天,把状态改为In Progress。 接下来mingle可以用不同的view来显示这些卡片,并且可以加上一些filter。只有满足某些条件的卡片才被显示。对于Product Backlog,其实就是一个针对Featurs树做的filter。Sprint Backlog则是针对planning树。 最后,他还支持一种MQL语言,一个简单的统计报表语言,用这个可以画出各种各样的breakdown图。另外,还内置了wiki的功能,每个卡片的描述都可以是一个wiki,可以详细的描述一个需求和实现细节等等。 总得来说,这是一个很不错的软件。当然,估计用ALBPM也可以实现,只是有点杀鸡用牛刀的感觉。我倒是觉得要是用GWT做这么一个东西,应该挺有意思的。 有一个简单的突破5个用户的方法,设定卡片的owner属性不是member list,而是指定的另外一个list,就可以了。这样所有人用一个用户登录,但是通过手动改动owner属性来做task的分配。

五月 21, 2008 · Shawn Ma

Java De-Obfuscation

以下是技术问题,对java没兴趣的可以跳过了…… 最近装了一个软件,用来画UML图,并且可以对Java代码做反向工程。但是,Java 1.5的代码免费版本不支持,非要什么Professional版本不可。搞得我很郁闷,研究了一晚上,搞定了它。 其中最重要的是代码的反编译。现在这些java软件一般都用混淆器做obfuscation,比如RetroGuard和Proguard等等。混淆了之后的代码反编译起来就很难看,有些变量被起名叫for, while之类的关键字,类名都叫a,aa,b,之类的,完全没有了意义。而且,有的文件名还是重复的(比如hh.class和HH.class在jar里面是两个class,但是解压到windows平台上就是重名的……)。有意思的是,我们可以用混淆器的这个特点,把被混淆过的jar再弄得稍微有意义一点,好读一点点。这也不是我的原创,网上有个人写了很好的说明。基本原理是,替换掉混淆器里面的NameMaker,这也他就可以产生有意义一点的名字。然后这个人写了一个Noun的NameMaker,把classname,变量的名字都换成名词。还有一个动词的name maker,把所有的方法都搞成动词。接下来就用jad反编译就好了。 反编译出来的java class很有意思,比如: public class koreanRedFox { public koreanRedFox(blueGrayGnatcatcher bluegraygnatcatcher) { ...

十二月 4, 2007 · Shawn Ma

我也来说说Android

最近Android很火,也就是传说中的Google Phone (GPhone)了。它其实是一个手机平台,Google的雄心大概是要跟Symbian和Windows Mobile争夺手机,或者说是未来的个人通讯平台的市场。其实Symbian基本上不算是竞争对手,因为这个技术实在有些落后,过几年应该就要淘汰了,所以NOKIA也说,他们也考虑加入Android的联盟。据说微软很愤怒…… 一个朋友要去Startup公司开发这个平台上的定制系统,以前在MOTO的Lead也去了;另外一个朋友在琢磨怎么利用Google的新API开发应用来赚钱;大家还都一起感叹,当年要是JUIX做好了,就是这个样子了,可惜moto执行力太差,太小气了,结果P都没搞出来。寂寞秋水也不甘寂寞,写了一片关于Android的blog。诧异的是,xfocus的tombkeeper,也写了一篇文章,从内核的角度探讨了Android的问题…… 我也不能免俗,下了一个Android的SDK,启动了模拟器,并大概看了一些例子。模拟器看起来很不错的,看起来做到iPhone的效果一点也不难。他的Theme和Skin,大概还实现我们在moto做的功能——伤心啊。应用的UI主要是靠XML来写,有点类似Mozilla/Firefox的XUL,或者微软的XAML。国际化和动画也是用XML来写的,程序本身之用写event处理,就基本上差不多了,用Android的说法,叫Activity. 浏览器看起来也很不错,不知道嵌入的是个什么浏览器,访问html肯定没问题,不知道能不能支持web 2.0 🙂 不知道这种手机啥时候能上市。应该是挺好玩的,虽然,我也没觉得他比blackberry强太多,很多功能,可能我不会用的着吧……

十一月 21, 2007 · Shawn Ma

Compiz and Beryl

这两个东西大概就是Linux的窗口管理器的扩展——我是这么理解的。装上之后,的确很炫,切换窗口之类的有Mac的感觉,窗口边缘也是那种半透明的,完全可以匹敌vista的效果。不过使用起来还是一样的麻烦,可能需要手动的改xorg.conf,而且配置所在的地方也比较混乱,后来在system/appearance里面有两个可以配置的地方。唉,被windows惯坏了啊。 点这里看compiz的screenshot。

十一月 21, 2007 · Shawn Ma

装了个Linux

好久不玩Linux了,最近心血来潮,给笔记本装了一个。上一次用这个还是三年前在moto的时候。 折腾了两天,感觉是,这么多年了,Linux还是那么难用,太geek oriented了。 我装的是Fedora core 8,刚刚发行不久。毕竟是Redhat那么多年的忠实粉丝了,也不喜欢什么非洲人的Linux,所以还是用Fedora了。 吭哧吭哧用bt当了一天,刻了一个DVD映像,结果上来就给我一个考验,loader安装过程中got sigsegv! 真是不能忍受,而且真的要是最终用户用了,肯定一点办法也没有。我去网上搜了,也没有很好的解决方案,后来,阅读了install guide之后,在GRUB启动的过程中append一个askmethod,然后把那个iso文件放在U盘上,用硬盘安装,还好我那个U盘是FAT32格式的。 后面安装还算顺利,一共装了1400多个组件,不过速度还行。因为同时我在用windows live installer装一个live messenger,乖乖,装一个messenger的速度跟装一个OS差不多,这点真是忍不了微软了。 装好之后遇到的第一个问题是,无线网络没法使用,根本不知道去哪里查找SSID,也不知道哪里设定密码之类的,一搜,发现即使是fedora core 8,也是不支持WPA这种模式的,必须要下载wpa supplicant这么一个程序,在无线网卡驱动上做点文章,才行。 然后我还喜欢设定一下字体,微软雅黑多好看阿,但是firefox就是不肯好好使用,又不记得字体怎么改,网上所谓的linux美化的文章都早过时了,还是自己去把/etc/fonts/conf.d/下面的东西读了一遍,才改过来…… 中文输入法也有问题,作为IT professional,使用中文界面多土阿,但是英文界面就没法使用输入法,琢磨了半天,发现把/etc/X11/xinit/xinputrc烤到~/.xinputrc就可以了,不知道非中文locale下为什么不被执行…… Linux terminal还总喜欢叫,也得去google,不知道有没有控制面板可以改?我得到的解决方案是,把pcspkr这个驱动放在/etc/modprobe.d/blacklist里,禁用掉这个驱动。当然也要rmmod一下。顺便说一下,window下也是一样,net stop beep就可以让windows不beep。永久不让它beep还得禁用掉beep驱动。 装了nvidia的X驱动,但是问题是,切换窗口的时候,窗口内容是黑的,不知道为什么…… 另外,媒体播放器不支持mp3…file roller也不支持rar,真讨厌……总之,linux还是相当难用的。。。

十一月 18, 2007 · Shawn Ma

OpenID Debates

Open ID 是个很有意思的东西。它号称是一个分布式的身份认证系统。任何一个网站都可以做一个Identity provider。也就是说,用户只要在一个Identity provider那里注册了,那么在任何一个service provider那里就都可以sso了。具体的说,好比我在openid.cn注册了一个id,再如果天下所有的网站、论坛、blog都支持openid登录,那么我再也不用在任何地方注册第二次了。其实跟windows live id差不多,不过WLID必须微软来管,open id谁都可以做用户认证管理的。比如我就注册了一个id是:http://shawnma.openid.cn 然后网上就有很多的debate,基本上来说,就是这个东西非常不安全。 Eugene and Vlad Tsyrklevitch发表了一个白皮书,论证了这个东西是如何的有缺陷。 Stefan Brands发表了一个巨长的blog,来批判Open ID。 David Recordon就声称Open ID 2.0会解决这些所有问题。 Bob Blakley就开始问,Open ID到底要解决什么问题?他看起来Open ID是先有解决方案,再来寻找problem -_- Mike Neuenschwander说,Open ID缺少一个Trust model。 嗯,看起来都挺有意思的。其实用的技术也都很老了……

九月 20, 2007 · Shawn Ma