软件开发: 12 2010存档

类型转换bug

| | Comments (4) | TrackBacks (0)
int a = -10;
unsigned int b = 5;

if (a > b) {
printf(“big\n”):
} else {
printf(“small\n”);
}

有经验的人一看上面的代码,就知道有问题,“>”会让int型降为unsigned int,结果会是打印出“big”,因为-10转成unsigned int肯定比5大多了。

虽然是个小bug,却是第一次撞上,因为我以前如果拿变量做计数,通常是给size_t类型,所以还真不容易遇到。查了一下gcc的文档,想要针对这种情况报warning,必须加一个编译选项:
-Wsign-compare
也可以用
-Wextra
但是-Wextra报错就会特别多,连main函数里的argc和argv没有被用到也会报出来,嗯,适合重口味的开发者。
第一个bug:

struct msg_header {
int a;
int b;
int c;
};

这个只是消息头,消息内容在内存里排放在 struct msg_header 的后面,现在我要把消息内容部分(不包括头部)拷贝到string里:

struct msg_header *msg;
….
//拿到msg
….
string res;
res.assign( (char*)(msg+sizeof(struct msg_header)), len);

这样写是错的,括号嵌括号而且“+”写得不规范,靠得太紧,让自己都看晕了,正确的写法应该是:

res.assign( (char*)msg + sizeof(struct msg_header), len);

第二个bug:

没什么代码可列举,就是c++类的成员变量(int型)未在构造函数时初始化,在有些情况下可能默认成员变量的值就是0,在另一些情况下可就不一定了。正因为时有时无,所以最难发现。


都是简单bug,没有什么技术含量,但是一旦犯了,排错又耗力又耗时,遂贴之以为警示。

前几天去参加了velocity大会。
大会邀请了google、yahoo、facebook、还有国内几个大公司的技术高手来演讲,参会的人也很多。大部分讲座是针对前端优化的,听得我一愣一愣,所以,我尽可能挑后端技术的讲座。
开场是由google的Steve Souders和淘宝的章文嵩博士做主题演讲。章博士详细介绍了淘宝网尤其是核心系统部门这两年的基础设施搭建和优化的经验,很实际很有启发,欲知详情请猛击这里。其中提到的作为通信中间件的夸父项目,是我这两年参与开发维护的,这是个很好用的工具,适合机器多但压力不是极高(万兆网卡就免了)的场合,已经在淘宝广告部门使用,装机量达到千台。



腾讯的谢明博士讲的是他们为了应对QQ图片存储而开发的“腾讯文件系统”,英文叫TFS,谢明刚说到这里,大家嘿然一笑,因为我们公司的Taobao File System也简称TFS,看来以后给自己的系统起名字不能太短,不然太容易重名了。
这个腾讯FS也有ChunkServer,ChunkServer也分主机备机,也是一个文件存多份,也是抛弃所有ext3等os级文件系统改为直接读写裸盘....我旁边的同事对我说:咱们的TFS做法也类似,其实大家的做法都差不多,都是从google的那篇GFS的论文学来的。我基本同意,但是说“学”倒也不完全,完成“海量文件存储,且成本低”这个目标一般来说也没有太多道路,大家很容易想到一块儿,当然,google首先总结了这些经验并公开给大家,还是值得称道的。



盛大的许式伟虽然是泛泛而谈互联网的应用架构,但是slide里有一篇特别有趣,就是告诉大家:不要看着腾讯、淘宝在做分布式文件系统做得很high就跟着去做,大公司有钱有人才做得起来,中小公司如果也瞎参合“自主研发”,会被搞死。
我严重同意许同学的观点,分布式文件系统虽然种类繁多,但是原理基本一样,功夫都在实现细节上,所以如果资源不足却冒然去做,收获不见得很多,花销却很大,因此,我更推荐中小公司使用开源的分布式FS和NOSQL。

人人网的邵君辉介绍了他们用c语言做CGI极大提升了服务性能的故事。听这个讲座的人不多,我之所以选择听这个,是因为当初我刚上班的时候份任务就是写php并测试性能,我对php的性能一直都不舒服,当时就萌生了拿c做网页的想法。所以,时隔多年,现在也想看看别人是怎么做的。他们是选用了google的开源字符库ctemplate来搭建的,用来替换原先的java实现,性能提升很明显,但是开发很累,两个c程序员用了一个月把java业务代码“翻译”成c,但是相比于省下的几十台服务器,这一开发还是相当划算的。
我知道很多教材也好、技术书籍也好,都在劝告我们“不要提前优化,随着硬件的提升,浪费的那一点性能会很快被弥补”,话是对的,但是,互联网公司需要节约钱、需要节约机器、需要提高性能,以前我们的软件只是一些windows上跑的单机程序,多耗点儿CPU无非就是客户多等个几秒,而现在我们的程序是在几百台甚至几千台的服务器上跑,一个程序只要快个1%,就能省下几十台服务器,就是几十台机器的托管费啊。想想吧,为了对得起我们的工资,优化程序的性能真的很必要,而且,不光是写完程序再优化,开始设计时就要考虑简洁性和性能了。
邵君辉同学根据多年经验,精挑细选了几个开源c库总结在了自己的slide上,非常感谢他。

最后听的一个讲座是土豆网的,他们是自己做CDN,之前用lighttpd做HTTP server,但是后来发现单机链接数超过600以后,lighttpd的性能大幅下降,原因是sendfile调用不高效,怀疑是sendfile没有文件预读,所以后来换成自己实现read和send....
这一段听着很诡异,我回来后专门又看了一下sendfile的实现,觉得跟单独read单独send的组合并没有什么太大的不同,也没有什么额外的锁造成性能问题。sendfile的原理实际就是调用generic_file_read(如果用户调用read,内核逻辑也会走到这里),然后针对该文件的cache里的每个page(4K的页面)调用tcp的sendpage,当然,sendpage里会判断滑动窗口是不是够大,如果不够了,会等一会儿,但是这个“等”即使是自己实现read/send也无法避免的。所以我初步怀疑不是sendfile本身的问题,可能是lighttpd对sendfile的使用问题,当然,后继再研究了。


演讲人的照片墙,照片下面的贴画是“投票”


讲座的间歇有免费饼干和水果提供,大家吃的真是毫不客气,我观察了一下,虽然吃的很猛,工程师们的体型都不太胖,这是个好现象,也验证了我以前的猜测

OReilly公司还在会场免费送书,只需要给一张名片,我借了同事的名片去软磨硬泡讨了一本ULK3,感觉很成功。嗯,我也要自己印点名片了。