2007年4月20日星期五

人生若只如初见

木兰花 拟古绝决词

纳兰性德(清)

人生若只如初见,何事西风悲画扇?
等闲变却故人心,却道故人心易变。
骊山语罢清宵半,夜雨霖铃终不怨。
何如薄幸锦衣儿,比翼连枝当日愿。

水源上看到这首诗,才知道 人生若只如初见 的出处。
此前也常读到这句诗,或是同学签名中引用,均未细想,此刻品味之余,方觉有味。
大概人生便是如此,初见惊鸿,时间一长,便觉平淡,亦或生厌。

以下为别人的注解:

人生若只如初见,这一句实在令人哑然
悲剧往往都是这样没有征兆的开始,
而种子已深埋在初见的那一刻。
漆黑一片的世界里,有喑哑的胡琴声响起;

隆中初见,羽扇纶巾,笑谈中三分天下,
再见时已是白帝托孤,六出祁山,壮志未酬身先死;
西厢初见,风流不用千金买,月影花移玉人来,
再见时却是弃掷今何在,悔教夫婿觅封侯;
梁山初见,天罡地煞席卷天下,
那一派豪侠风光令人血脉愤张,
乃至再见,听潮而圆,遇信而寂,
寥儿洼招魂幡动,依稀鬼哭;
金屋初见,千娇百媚,永世相守,
而色衰爱驰之日,终晓千金难买长门赋;
华清池中温泉水滑,生长殿里夜半私语,
谁会料到结局是马隗坡前数丈白绫,一捏黄土;
原来所有的名字,所有的故事,都是写在水上的,
那些波澜和涟漪,在当时看来惊心动魄,
而长江滚滚,只是一朵小小的浪花而已,
流过,终于迹;
年少的意气风发,最初的感动和梦想,
在时间的浸润下渐渐磨灭;
一见如故的亲切,山盟海誓的诺言,
只剩下一个依稀的背影;
金甲的战神披着天边的彩霞,
在故事中定格成永恒的记忆;
即便是猜得中绚丽的开头,
又有谁见到了那早已注定的结尾?

初见,惊艳,蓦然回首,
曾经沧海,早已是换了人间。

2007年4月19日星期四

线性方程组求解库

求解线性方程组 Ax=b,常用的方法包括 直接解法(一般是对 A 进行矩阵分解)和 迭代法。常用的数值计算平台,如 Matlab,Octave,numpy 中都支持对线性方程组的求解,以 Matlab 的性能最优,支持的方法也最多,直接求解时用 x=b\A 会根据 A 的性质(如对称、稀疏)选择最优的算法,在用迭代求解时还可以先进行不完全分解来加速收敛速度。

下面总结一下我所知道的开源的求解线性方程组的相关的数值计算库,一般都是 Fortran 或 C/C++开发。

  • BLAS(Basic Linear Algebra Subprograms)

    blas 是许多数值计算软件库的核心, 一般是用 Fortran77 实现, 支持矩阵、向量基本操作。也有 C/C++的封装。
    据说性能最优的 BLAS 实现是 gotoBLAS

  • Sparse BLAS

    BLAS的 Sparse matrix 版本。见到的都是 NIST 版本,C++的,netlib 上的 是一个 Fortran 版本。

  • LAPACK(Linear Algebra PACKage)

    专用于线性运算的,如求解 AX=b, 矩阵分解、求逆,求矩阵特征值、奇异值等,在 www.netlib.org/lapack/ 是 Fortran 版本的,应用很广,但还未见到针对 Sparse matrix 的版本。

  • ScaLapck

    可以在分布内存的计算机上并行求解线性问题,即并行版的 LAPACK。

  • SuiteSparse

    SuiteSparse 是 Prof. Tim Davis的 Sparse matrix solver 的程序包,涉及希疏矩阵分解,大多用 C 开发,提供 Matlab 接口。Matlab 中的很多数希疏矩阵函数的原型都可以在其中找到。性能非常出色。强烈推荐看看他的主页!

  • TNT(Template Numerical Toolkit)

    C++的数值计算库,目标很大,据说还要集成 LAPACK++,Sparselib++,IML++,MV++。但目前还很薄弱,也就是定义了一些数据结构,求解线性方程组的能力基本没有,Sparse matrix 的操作功能也没有。

  • Sparselib++

    C++的 Sparse matrix 库,与 sparse BLAS 差不多,多了对矩阵的 preconditioner功能,可以配合 IML++ 做线性方程组的迭代求解。

  • IML++(Iterative Methods Library)

    C++的。支持对 dense or sparse 的线性方程组的迭代求解,包括
    * Richardson Iteration
    * Chebyshev Iteration
    * Conjugate Gradient (CG)
    * Conjugate Gradient Squared (CGS)
    * BiConjugate Gradient (BiCG)
    * BiConjugate Gradient Stabilized (BiCGSTAB)
    * Generalized Minimum Residual (GMRES)
    * Quasi-Minimal Residual Without Lookahead (QMR)
    等方法,可配合使用 sparselib++。

  • ITL (The Iterative Template Library)
    The ITL currently includes the following methods:

    • Conjugate Gradient (cg)
    • Conjugate Gradient Squared (cgs)
    • BiConjugate Gradient (bicg)
    • BiConjugate Gradient Stabilized (bicgstab)
    • Chebyshev Iteration (cheby)
    • Richardson Iteration (richardson)
    • Generalized Conjugate Residual (gcr)
    • Generalized Minimal Residual (gmres)
    • Quasi-Minimal Residual Without Lookahead (qmr)
    • Transpose Free Quasi-Minimal Residual Without Lookahead (tfqmr)

    The ITL currently includes the following preconditioners:

    • Incomplete Cholesky (cholesky)
    • Incomplete LU without fill-in (ILU)
    • Incomplete LU with n fill-in and with threshold (ILUT)
    • SSO
  • SuperLU

    对大型、稀疏、非对称的线性系统的直接求解,用 Gauss 消去法做 LU 分解。用 C 开发。

  • SPOOLES

    C。可求解对称和非对称的线性问题。

  • MTL

    基于 C++ template 的 matrix class lib,技术比较眩,性能据说也不错,但支持的操作太少,线性方程组的只有 LU 分解,和几种迭代方法,不支持 sparse matrix。

  • blitz++

    技术上更眩,但对线性方程组的支持很少。

  • GSL

    GNU scientific library,很正统,但对 sparse matrix 的支持为0,性能也不突出。

  • 其它

    MKL(intel math kernel library)非常强大,包括了优化过的 blas,LAPACK,又支持 sparse direct solver,可惜不开源,使用起来不方便。
    这儿
    对 sparse linear system direct solve software 有非常全面的总结。

I've tested some of the libraries, with following results :
testing data : sparse symmetric positive matrix
dimension : 3000x3000
density : 0.3
non-zeros : 1284213
condition : 2.7015e+04
opencv : CV_LU 45.7s(linux)
mkl : pardiso 3.17s(win)
matlab : \ 2.57s(win)
CHOLMOD : cholmod 2.48s(linux)

and I've found that linux(ubuntu-6.10 in my workstation) is far more flexible than windows in programming and scientific research!

2007年4月11日星期三

Recipes of Books

Having just finished reading two of the exceptional c++ serials today, and it worth the two weeks time, really !
I'll focus on algorithm on the next stage, and will be my next book.
Reading, thinking, and then practising, are of great interest !

2007年4月5日星期四

SIFT-Based Object Recognition

David Lowe提出的SIFT算法得到的SIFT特征具有很好的稳定性和不变性,已经被证实是目前最好的不变局部特征提取算法之一。去年大半年时间都在研究这个算法,以及Lowe在Distinctive image features from scale-invariant keypoints(IJCV.2004)中提出的目标识别框架。去年12月时已经有比较好的识别结果了,并提出了一些自己的想法和改进方案,效果也可以,最近又对算法作了些优化,已经能做到2~3fps的识别速度了。
SIFT算法复杂度比较高,多次卷积计算量比较大,并且由于产生的特征点很多,生成特征向量的时间也就比较长;至于后期的匹配和识别过程,也需要一定的时间,比如基于kd-tree的BBF算法,虽说搜索速度比逐一比较加快了几个数量级,但数据库一大,输入特征点比较多的话,还是挺耗时的。而hash hough即需要空间上资源(每个feature需要对应16个bin),也需要一定的计算量,如求解基于最小二乘的仿射变换。因此要做到实时真是太难了。目前看到的最快速度大概也就是10帧左右吧,那已是commercial product了,并且David Lowe本人亲自参与开发,自是不可比拟的了。
SIFT算法过程也比较复杂,目前网上有一些参考代码,质量参差不齐,倒是不错的参考,完全自己写,还是比较难的,目前还没这样的算法素养。kd-tree比较成熟了,拿来用就是了,倒是generalized hash hough有点费神,Lowe的paper写得挺含糊,也并没有找到可参考的代码,只能自己边想边写了。hough变换的原理很简单,只想不明白hash与hough是如何结合的,看了一大堆hough变换的应用资料,再结合hash原理,用了三天才将代码写出,其中用到了STL中的hashmap(STL还是挺方便的,后来自己用C写了个hashtable实现hash hough,效果就有点差,可能是hash函数不够hash,数据结构安排也不合理),效果还是挺好的,挺开心的,也挺佩服Lowe提出的算法和框架,确实很有效。
下面是一些截图,已经将SIFT-Based目标识别做成模块,集成到Demo中了:
第四张图为landmark,前三张为在线识别视频截图,左边主窗口为识别图像,左边小窗口为视频图像,中下数据窗口为识别结果,右边竖条为landmark image database。
















Panoramic Image Transform

也是去年十二月写的一个小程序,全景图像展开,很简单的算法,两天便完成了。不过刚开始想得比较复杂,比如考虑镜面方程(二次抛物面),成像模型等等。这样恢复的图像质量当然比较好,不过比较麻烦。后来使用了简易算法:project circle to clinder, 公式如下:
panoramic(w, h) omni-directional(R, r) // center of omni-directional image
p(x, y) --> p1(x1, y1) p0(x0, y0)
w = (R + r) / 2
h = R - r
theta = x / w
x1 = x0 + (r + x) * sin(theta)
y1 = y0 + (r + y) * cos(theta)

按上面公式展开得到的图像会有比例失调:上半部分拉伸了,下半部分压缩了,这是由于镜面的非线性映射造成的。于是我拟了一个简单的二次函数对下半部分图像进行非线性拉伸(注:与镜面方程无关,在此就不透露公式了:),下面是一些实验结果:




全景图















NN未拉伸的图



双线性插值并拉伸后的图




可以看到,拉伸处理后的图与实际环境的尺寸比例比较接近,效果还是挺好的。
此外也在linux下做了实时视频展开实验,将494x464的彩色图展成864x244的彩色图,使用双线性插值算法,也有很好的实时性,核心算法代码写得比较高效。

Digit Number Recognition

去年十二月写了一段针对仪表的数字识别代码,功能比较简单,现总结一下其中的过程。
分别用模板匹配和神经网络实现了识别过程,其中模板匹配算法借鉴了茅老师的idea。
template match :
image[in] => rgb2gray -> segment(ostu) -> find digits(flood) -> normalize -> NN or Correlation => recognized digits[out]

neuronetwork :
image[in] => rgb2gray -> segment(ostu) -> binary -> find digits(projection) -> normalize ROI -> skeletonize -> generate features(top, bottom, right, left, width, height) -> normalize feature -> BP network(3 layers) => recognized digits[out]

训练与识别过程类似。
template方法比较简单,而且在实际操作中发现识别准确率也比较高,事实上对于固定的摄像机位置和固定形状的数字,模板与实际提取出来的数字不会有太大的差别,因此效果好,速度快,比较适合仪表数字识别应用。
神经网络方法有些复杂,我参考的是一个手写数字识别算法,识别效果也可以,但ANN的参数比较难调,最终选择96-192-10的3层BP网络。在调BP时也遇到了一些问题,训练BP时很多次迭代后RMS老是不能收敛到比较小的值,仔细读了pattern classification中关于ANN的介绍,明白了一些数据处理要求,如训练数据归一化,S函数选择技巧等,实践一下后,效果确实好了些。利用十个样本(0~9)进行监督学习,然后在线识别,效果不如template方法,但也是不错的。猜想使用更多样本学习后,可能效果会更好(有待实验证实)。

这样的小工程还是挺有意思的,前后也就用了两个星期,练练手,不错的。c++代码也写得也还满意,factory模式,支持xml配置文件读写,cross platform(linux, windows),在windows上做了个Demo:一个数字仪表模拟器,一个USB摄像头视频捕捉和在线识别Demo(这些灵感也来自于茅老师,看过他们的电路实验:),下面是Demo截图:

一些说明:左图为数字发生器,模拟LED数字,可以定时随机生成,右图为视频采集与在线实时识别Demo,识别前先要手动选择数字区域,固定好位置后就能实时识别了。

2007年4月4日星期三

Testing Tesseract-1.0.3

有关tesseract的报道不再多述,google一下就会有很多结果。早在去年12月就因为要做数字识别而尝试过tesseract-1.0.2,2月底google在sourceforge上又发布了1.0.3,修正了一些内存泄露bug,并作了不少改进,至少编译起来很少了错误(vc2005对一些语法检查比较严,有一些类型转换的错误)。
1.0.3中运动WinMain,但还是通过间接调用main,完成识别工作,也就是在控制台下工作。觉得不太方便,今天花了点时间在已有的基础上增加了剪贴板功能,直接对文字识别,其中做了些彩色变换,因为目前tesseract只支持灰度图,只能识别英文和数字。下面是截图:

Our generalized Rough algorithm uses edge inlors
matron lu dehne a mapping [rot-n the orientation nfan edge paint to a reference point of the shape. Tht: reference point may be though! of as the origin of a loualeo-ordinate system for the shape Then there is an easy way ofcompuling a measure which rates how well points in the image are likely to be ortgins of the specified shape. Figure X shows a few graphic examples of the information used by the generalized Rough
transform. Lines indicate gradient directions A feature of the transform is that it will work even when the boundary is disconnected due to noise or occlusions.This is generally not true [or other strategia whichtrack edge segments
The original algonthrn by Houghm did not use

准确率还是挺高的。
目前还没有关于tesseract的官方文章,相信google不久会整理并发布的。现在也没有时间研究它,先好好把Duda的pattern classification看完再说.

further more, perhaps I've found an interesting application of tesseract, that is Visual Reader on our PC. more details, read web pages, papers, books, etc for us. This is obvious possible with tesseract and MS's Speech SDK, plus some additional image processing, for example, selecting the text region, finding out the time to perform OCR on current screen content. I've got a picture about this demo, just some programming work remained:)
life should be ease for us slothful man ~~

2007年4月3日星期二

Testing Davison's MonoSLAM

半个月前从Davison的主页上下载了monoSLAM的源码,在ubuntu 6.10(gcc 4.1.2)上编译通过,并运行正常,最近又将它移植到windows平台,主要是考虑以后的兼容使用。其中有一些心得和经验,记录于此。

1. support usb camera under linux
Davison的代码只支持1394 camera,在linux下我先为其添加了USB camera支持. 这个工作其实也挺简单,参考VW34/VWFirewire和VW34/VWGLOW/Interface/*代码,写了个VWUSBCam接口,其中调用v4l2(2.6 kernel支持)API,这里又参考了spcaview中的代码,再修改一下makefile就行了,也就用了一天时间,麻烦的事情在于makefile的修改,automake生成的东东总是显得过于繁杂,手动修改起来比较烦。
sequence的工程机理是这样的:底层有一个循环,进行IO操作,不断地读取文件或摄像机数据;一旦得到数据后,发送消息给上层,上层调用响应消息的回调函数,在其中进行数据处理。 这样的循环式操作有一个弊端:CPU占用率一直比较高。特别是读取视频时,没有数据时也会一直在"空转"。不像MS的DirectShow,底层的WDM检测到数据信号时,自动发送消息通知上层,即中断式的操作。不过对于linux下的v4l2编程,目前还没有看到过支持中断方式视频捕获。

2.port to windows
移植往往是比较麻烦的工作,linux与windows的平台差异比较大。不过Oxford的VW4是cross platform的,并提供了VC7的project,monoslamglow和scenelib也是完全platform independent,并全用c++实现。这样的工作还是挺好的,我比较喜欢这样的方式,以前写的一些程序也都是这么处理的。
不过在移植过程中还是有一些问题。我使用的是VC2005,可能是目前最好的编译器与IDE了,对C++标准支持得很好,毕竟是Lippman领导设计的。这使得monoslam中大量的模板编译能够顺利通过。
首先需要编译glut和glow,是opengl的一些扩展工具,我使用的分别是glut-3.7.6和glow_104,编译中没有问题。
其次需要编译wxWidgets,目前有2.8.3,第一次尝试搞错了一些设计,出了错,便选用了2.6.4,也是一样的问题。后来分析了一下错误,再结合readme,明白了原因:需要设置一些宏,打开或关闭一些选项。顺利通过后也懒得换高版本了,2.6.4够用了。
现在便可编译VW34了,直接用其中的VC7 solution,并设置好前面几个库的路径,编译也可以通过,但在后来编译MonoSLAMGlow时,却有unresolved link error,显然是找不到库的模块。回头再看VW34,发现了是因为有一些.cpp文件没有添加进solution,没有编译进lib,还有就是文件读取的几个template没实例化,手动加上就可以了(虽说简单,但找到错误却不容易,一开始没想到是这些问题~~)。在这里,gcc与vc2005似乎有比较大的差别,gcc似乎不合乎标准。
最后编译monoslamglow和scenelib。这两个没有现成的工程,monoslamglow其实就是scenelib中API的简单调用,负责一些界面处理,主要的vSLAM工作在scenelib中完成。直接将这两个模块放到了同一个project中,修改了一些头文件路径和gcc、vc2005的语言差别,最后也能编译完成,但冒出来很多multiple symbols error,都是来自于VW34,像是VW34中已经定义了一些标准C++的库函数,如basic_string, vector之类,细查一下又没有,比较奇怪。google了一下,从VXL(一个比较好的computer vision library,VW34中的VNL便是它的一个模块)的文档中找到了答案:C++编译器编译选项设置不一致。solution如下:

Project->Settings->C/C++ Tab->Category: Code Generation->Use run-time library: Multithreaded DLL

于是编译就通过了,porting就初步完成了。

3. fix bugs
前面完成了移植工作,这只是一部分工作而已。程序在windows上读取Davison提供的test sequence,一会便出错了,而且是比较莫名的错误:基于wxWidget的窗口一重绘便出错。wxWidget的问题?若如此,便很麻烦了,不确定是wxWidget还是opengl或是基于opengl的glut、glow有bug,没精力去研读几十M的代码的~~
仍然编译了个debug版本,初步调试了一下,发现只是在窗口重绘时出问题。像一般的界面程序一样,重绘是基于消息的,消息又与回调函数挂钩。在调试中发现调用回调函数的对象指针失效了,这是失败的原因!深入VW32的底层代码,跟踪程序的过程,了解了它的处理方式:从一个带虚函数的EventHandler类派生出窗口子类,再利于EventHandler保存子类的句柄,回调时,由该句柄调用多态调用子类的重绘函数。一切看起来很合理,充分利用了C++的多态性。但EventHandler却在重绘时失效了。不可理解。 好看月前仔细阅读了,了解了C++一些底层的对象模型处理过程,对于虚拟继承内部错综复杂的关系也比较清楚了。很快便想到:基类指针失效应该是由于指针在对象转型时offset调整出了问题。这部分是编译器的工作,我们无法干预。这便又是gcc与vc2005的一个显著不同!看了一下MonoSLAMGlow类的声明:多重继承!4个类的多重继承!令人生畏的多重继承!其中EventHandler被放在第二个!这些类都有虚函数,很显然,也就会有多个虚函数表,指针调整时也会比较复杂。从理论上来说,EventHandler应该设计成抽象类,并作为公有虚拟基类,这样便不会有上述问题。我采用了一个比较简单的修改方案:将EventHandler设为第一个继承类,因为不是虚拟基类,它的地址便是MonoSLAMGlow的地址(vc2005中是这么处理的),不再需要指针调整,快速、方便而又正确!就是这么一个问题,真是得感谢Lippman,难怪侯捷竭力推荐他的这本书,很有道理。
紧接着便是第二个错误:运行一会程序会崩溃了。使用debug版本观察了一下,是vector出错了,看似是指针无效。这个错误很难找,整个工程大量使用了vector,无法定位是哪里出了问题。前段时间发现这个问题时,觉得一时难以下手,也正好在忙别的事,就此搁下了。昨晚又拿起来分析了一下,初步判定是monoslamglow中的问题。今天花了一天时间调试,才找到这个问题所在。真是个非常隐晦而又阴暗的错误!当然,也怪我一时疏忽了,话说过来,这种bug若非亲历并尝过艰辛,是不可能想到并很快发现的,虽然我早就知道bug原因和解决方法~~建议使用STL的程序员都好好读读scott meyer的effective stl,唉,其实我已经读过两遍了~~
这个bug便是vector::erase便得基于vector的所有iterator都失效了!很简单的理由,在effective stl中反复说了好几遍。比如程序中有这样的一段代码:
for(vector::iterator feat = feature_init_info_vector.begin();
feat != feature_init_info_vector.end();feat ++)
{
if(feat->...){}
else{
delete_partially_initialised_feature(feat); // 调用vector::erase
}
}
看似没有问题,delete_partially_initialised_feature erase的是feat的一个副本,feat已经更新了。看过effective stl的人也都会这么说:这是meyer推荐的一个技巧啊,后置++返回旧值。其实不然,erase后,vector内存已经重新分配,以前的iterator都已经失效,因此更新后的feat实际是无效的,在下一次for比较中就会崩溃,错误提示为:incompatible iterator!一个我刚开始始终看不懂的错误。
修改方法就比较简单了,修改delete_partially_initialised_feature的原型,返回iterator,然后
feat = delete_partially_initialised_feature(feat)
即可。
注:程序中有三处这样的错误,需要一一修改。
gcc对于这个问题也没有出错。gcc使用的是sgi的stl,不知道底层是如何处理的,按理说不应如此。还可以说明一点的是:Davison(也有可能是其他人)的c++和stl水平不怎么样,不应该犯这样的错误的,嘿嘿!

update 1 : 2007-04-12
yet another bug of the same kind : incompatible iterator !
in Scene_single.cpp, line 301, delete_feature erases an item from feature vector and invalids all the iterators kept previously in the context, so in the next loop, the "incompatible iterator" error will jump out while comparing the iterators !
solution :
I subsitude the original prototype of delete_feature below

bool delete_feature()
with
std::vector::iterator delete_feature()

in fact, the latter conforms to the convention in STL, such as vector::erase, list::erase, etc.

update 2 : 2007-04-19
add usb camera support on both linux and windows !
It's quite interesting to run the demo with real environment.

4. conclusion
移植与修改这个程序还是很有意思的,有利于提高自己的程序水平。特别是使我们看到了大师提出的经典与意见是很有用的,经典著作不能不读!
另外,对于gcc,我也觉得比较有意思,上面发现的一些错误在gcc中完全正常,虽说有些地方不符合标准,但确实好用。还是比较喜欢gcc的。
写了这么多,觉得可以写封信给Davison了,report bugs to him and ask him to read some classic books on stl :)

5. forwards
以后再为monoslam加一个windows上的USB摄像头接口,那就可以做实验了。这倒是比较容易的,对于摄像头采集还是很熟的,今天就到此为止吧。
我还是比较喜欢在linux下写程序,工具比较丰富,也比较好玩,如emacs,eclipse之类的,只是不如windows中方便,因为vs2005的功能实在太强大了!不过支持开源、支持linux!

2007年4月2日星期一

some bugs on opencv 1.0

最近几天用opencv采集视频、读取AVI,发现了一个bug,源程序为cv中的sample,如下:
void ShowAVIVideo(char* filename, HWND hwnd, int width, int height)
{
cvcamAVIFILE f = cvcamAVIOpenFile(filename);
if( (int)f <> 1 )
{
cvNamedWindow("avi window", CV_WINDOW_AUTOSIZE);
ShowAVIVideo( argv[1], (HWND)cvGetWindowHandle("avi window"), 320, 240);
}
}

其中在cvcamAVISetWindow等操作中会有出错,追踪一下源代码,发现是库中的一个不一致造成的。在cvcamavi.cpp中定义了#define AVIS_START 1000,可能是为了今后的扩展之用.
cvcamAVIOpenFile中调用了cvcamAVIs::AddSource,其中返回的是i,此次应该返回i+AVIS_START, 因为cvcamAVIs::operator[]中有source -= AVIS_START操作。

另一个问题是opencv的cvSaveImage保存的pgm为ascii格式,有时这可能是不需要的,修改方法为:找到highgui\grfmt_pxm.cpp中的GrFmtPxMWriter::WriteImage函数,将
bool isBinary = false;
改为bool isBinary = true,重新编译即可

顺便看看一些相应的代码,发现opencv的代码结构写得还是很不错的,比如文件读写便使用了factory patten,毕竟intel有的是写程序的高人,opencv的几个维护人也是资深的程序员。

07.05.30
add white balance control to opencv

sometimes it's rather boring when there is not white balance control interface in opencv. so i modified highgui.h and cvcap_v4l.cpp and added balance control according to v4l2 api's document. Also, blue/red balance controls are available, but it didn't work for me, curisous !

2007年4月1日星期日

April's Fool

Damm casher!
套间的洗澡计费器有时会出问题,卡插入后不计费,显示为00:00,也没有热水,急死人啊。
刚才洗澡时,一开始还正常,洗头时,将卡拔了,省钱嘛。涂上洗发液,充分搅拌,就等热水冲洗一下,很爽的感觉。这时casher发难了,卡怎么插都没反应!急啊,感觉头发都快变僵硬了:(
卡坏了?小概率事件。casher罢工了,极有可能,但很不情愿承认。这时自然想到三毛在撒哈拉沙漠流记中的类似故事。相比之下,我还好一些,好歹出来后还是能洗头的,只是麻烦罢了。心有不甘,先将卡仔细擦干净,再将casher好好擦了一遍,算是对它的慰劳(大概我是第一人呢!),满怀期望地插入卡,只等它发善心了。不行!它倔强地回应。没得办法,横放、坚放、倒着放,都不见效,看着那00:00,我都觉得它在得意得看着我笑了。晕了,算了吧,等着换卡或是穿衣出去吧,不和你斗了~~
不过一会儿热水倒自个儿流出来了,发善心了?不会吧~~细想一下,可能是时间问题,需要一段时间"预热"一下。唉,就当是愚人节的玩笑吧。

浅淡C++

前面接连转了几个和C++相关的帖子,可见对C++还是挺有感觉和感情的。算起来从接触C++到现在,已经有五年了,前四年浑浑噩噩、游手好闲般地混过来,一技无成,白浪费了很多时间,倒是去年此时,受人指引,才恍然发现另有天地,奇珍异草,璀璨夺目,由是一头扎进,遍玩不疲。啃了很多前面提到的经典之作后,突然发现理论水平提高了很多,但实际运用的能力却还是有限,原因在于很少有需要发挥的余地,比如用到C++的各种高级技巧,如大片的GP,曲折的模式之类,退而言之,即使真的需要这些技巧,我也不能发现,这便是经验的问题了,所以实践也很重要,目前缺乏的便是这个。
当然,倒不是说这些经典或是书本没用,了解前人的智慧结晶,还是能指导我们写出优质高效的代码的,只是还远没能发挥它们的最大作用。近半年来一直和GP打交道,主要是阅读代码并修改,理论结合实践,这的确是一个享受的过程,倒仅限于此罢了。
目前各种程序语言也很多了,但仍有很多人一如即往地支持C++,其原因,一部分是因为C++语言本身确实魅力无穷,吸引了一大批聪明而勤奋的人,比如C++中的GP、STL、OO之类,另一方面,C++也比较难以学精学通,很多程序员以学精C++为目标,算是对自我的挑战,好比武功绝学,一旦学成,便可傲视群雄,唯我独尊(这么说有点偏激了,大多数人应该是本着对语言的执著追求而学习它的:)。但真正能到此境界的人并不多,武学奇才也是凤毛鳞角嘛。所以大家都执着地学习这些经典,真正有所成的却也不多,对有些人来说,这倒反而是个负担。比如有人说:连Mayer,Sutter的书都没写过,你就来写程序了?! 或是有人会纸上谈兵:根据Sutter或是Mayer的多少条,这应该这么处理。 做实际也没用,因为没有变通。经典便成了语录,或是教条了~~
因此,我的结论是,如何学用C++是个人的兴趣,喜欢它,并愿意研究它,那便自然会投入时间与精力,如果觉得一般用用即可,大可不必随波逐流,追捧所谓的经典。
当然,前面提到的很多书确实是经典,看了还想再看^_^

C++程序设计之四书五经zz

C++程序设计之四书五经(上篇)

C++是一门广泛用于工业软件研发的大型语言。它自身的复杂性和解决现实问题的能力,使其极具学术研究价值和工业价值。和C语言一样,C++已经在许多重要的领域大获成功。

然而,一个不可否认的现实是,在低阶程序设计领域,C++挤压着C同时也在承受着C的强烈反弹,而在高阶程序设计领域,Java和C#正在不断蚕食着C++的地盘。也许C++与C合为一体永远都是一个梦想,也许Java和C#的狂潮终将迫使C++回归本位 — 回到它有着根本性优势的开发领域:低级系统程序设计、高级大规模高性能应用设计、嵌入式程序设计以及数值科学计算等。果真如此,我认为这未尝不是一件好事。

C++吸引如此之多的智力投入,以至于这个领域的优秀作品,包括重量级的软件产品、程序库以及书籍等,数不胜数。文题“C++程序设计之四书五经”一个不太严格的含义是:C++程序设计之四书 ⅹ 五经。是的,在本文(及其下篇)中,我将分门别类推荐20多本C++好书,你可以根据自己的需要选读。

TCPL和D&E
TCPL和D&E分别是《The C++ Programming Language》和《The Design and Evolution of C++》的简称,均出自Bjarne Stroustrup之手。我将它们单列出来,首先是因为Bjarne是C++语言的创建者,然后是因为比“首先”那个原因更重要的原因:这两本书是C++领域毋庸置疑的杰作。说它们是C++语言圣经,并不为过。

Bjarne Stroustrup, The C++ Programming Language (Special 3rd Edition)
《C++程序设计语言(特别版)》,机械工业出版社
《C++程序设计语言(特别版)(英文影印版)》,高等教育出版社

迄今为止,TCPL是除了C++标准文献之外最权威的C++参考手册。和大多数人的看法不大一样,我认为Bjarne的文字语言并不逊色于他所创建的程序语言,至少我喜欢这种学院气息浓厚的作品。本书对C++语言的描述轮廓鲜明、直截了当。它从C++语言创建者的角度来观察C++,这是任何别的作者和书籍做不到的 — 没有任何人比Bjarne自己更清楚该怎么来使用C++。

这是一本严肃的著作,以中、高级C++开发人员为目标读者。如果你是一名有经验的C++程序员,需要了解更加本质的C++知识,本书正是为你而写。它不是那种让你看了会不断窃喜的小书,需要用心体会,反复咀嚼。在阅读过程中,请特别留心Bjarne先生强调了什么,又对什么一语带过。我个人比较喜欢这本书的第四部分“使用C++做设计”,这样的内容在类似的程序设计语言书籍中很难看到 — 我甚至认为Bjarne应该将这部分独立出来单独写一本书。

Bjarne Stroustrup, The Design and Evolution of C++
《C++语言的设计和演化》,机械工业出版社
《C++语言的设计和演化(英文版)》,机械工业出版社

D&E是一本关于C++语言设计原理、设计决策和设计哲学的专著。它清晰地回答了C++为什么会成为今天这个样子而没有变成另外一种语言。作为C++语言的创建者,Bjarne淋漓尽致地展示了他独到而深刻的见解。除了广受赞誉的语言特性外,Bjarne没有回避那些引起争议的甚至被拒绝的C++特性,他一一给出了逻辑严密、令人信服的解释。内容涵盖C++的史前时代、带类的C、C++的设计规则、标准化、库、内存管理、多重继承、模板等,对包括异常机制、运行时类型信息和名字空间在内的重要的新特性都分别进行了深入探讨。每一名C++程序员都应该可以从Bjarne的阐释中加深对手中这门语言的认识。

需要再次提醒的是,这两本书知识浓缩,信息量极大,请不要错过Bjarne每一句看似漫不经意的话。

入门教程
学习任何一门语言都需要一个从入门到精通、从新手到高手循序渐进的过程。不过,对于一个所谓的新手而言,究竟是一个完完全全的新手,还是一个熟悉某种别的语言的“新手”,甚至是在某种语言程序设计领域已经颇有建树的高手,很难一概而论?不同的C++新手需要不同的入门书籍。

Andrew Koenig, Barbara E. Moo, Accelerated C++: Practical Programming by Example
《Accelerated C++中文版》,中国电力出版社

和市面上大多数C++教程不同,本书不是从“C++中的C”开始讲解,而是始于地道的C++特性。从一开始就使用标准库来写程序,随着讲述的逐渐深入,又一一解释这些标准库组件所依赖的基础概念。另外,和其他C++教材不同的是,这本书以实例拉动语言和标准库的讲解,对后两者的讲解是为了给实例程序提供支持,而不是像绝大多数C++教材那样,例子只是用作演示语言特性和标准库用法的辅助工具。

作者在C++领域的编程实践、教育培训以及技术写作方面都是世界一流水准。我喜欢这种大量使用标准库和C++语言原生特性的清新的写作风格。在这本教材面前,几乎迄今为止的所有C++教材都黯然失色或显得过时。尽管这本教材也许对于国内的高校教育来说有些前卫,不过我仍然极力向我的同行们推荐。顺带一提,在Bjarne和我最近的一封通信里,他这样评价本书:对于有经验的程序员学习C++而言,这本书可能是世界上最好的一本。

Stanley B.Lippman, Josee Lajoie, C++ Primer (3rd Edition)
《C++ Primer (3RD)中文版》,中国电力出版社

这本书的名字多少有点让人误解。尽管作者声称这本书是为C++新手而写,但无论是它的厚度还是讲解的深度都暴露了似乎并非如此。也许说它是一本“从入门到精通”的C++教程会更合适一些。我个人认为它并不适合完全不懂C++的初学者 — 在阅读这本书之前,你至少应该先有那么一点C或C++的背景知识,或者至少要具有一些其他语言的编程经验。

尽管这本书省略了一些高级C++特性的讨论,但仍然可以称得上是迄今为止最全面的C++学习教程。事实上,如果一名C++初学者能够扎扎实实地读完本书并对照《C++ Primer Answer Book》完成全部习题的话,他的水平肯定可以进入职业C++程序员的行列。我个人认为,即使你已经拥有了TCPL,这本书依然有拥有的价值,因为在许多方面它比TCPL来得更详细、更易懂。

Stanley B. Lippman, Essential C++
《Essential C++中文版》,华中科技大学出版社
《Essential C++(影印版)》,中国电力出版社

可以不太严格地认为这本书是《C++ Primer》的精简版。本书一一讲述了C++中最具代表性的主题,包括过程式编程、泛型编程、基于对象编程、面向对象编程、模板编程以及异常处理等。Stanley将门槛调低到“具有其他语言程序设计经验”的C++新手所能接受的最基本的层次,使他们能够迅速开始使用C++编程而又免于阅读《C++ Primer》那样的大部头。它以实例引导学习,力图使读者在最短的时间内把握C++的精粹。

也许换一个人来概述C++编程范型(paradigm)的方方面面需要好几百页才能说清楚,但这本小书不可思议地做到了这一点。我个人非常喜欢这种满是技术、简明扼要并且“有话好好说”的书。这本书同样具有一个明显的风格:所有程序例子全部采用标准库组件,让人耳目一新。

以上三本书都不是为了完完全全的编程新手而写。完全的C++编程新手可以阅读Francis Glassborow的新书(尚未出版):《You Can Do It!: A Beginner's Introduction to Computer Programming》。这也是Bjarne的推荐。Francis Glassborow是ACCU主席,多年来他对几乎每一本C++经典名著评头论足,他自己的这一本自然会引起C++社群的极大兴趣。

高效、健壮编程

两年前我在负责一个省级电力调度系统项目时编写了一个网关程序,它从SCADA系统获取电力实时信息。通讯接口采用了不常用的数据库直连方式(这个网关程序一端连接SQL Server 6.5,另一端连接Oralce 8.1.6)。由于实时测点近万,每次将全部取样更新或插入一遍显然是低效的。我在网关程序里建了一个内存库,获取到的数据首先在其中进行比较,然后决定是否更新物理数据库(同时还做了别的更复杂的事情……),从而在效率和资源占用两方面达到了预期效果。

这个程序一直运行得很好,但在离开现场之后的某一天,系统管理员打来电话,说大概因为网络故障等原因,有时这个网关程序会崩溃掉 — 它自己崩掉也就罢了,问题是它还会把Windows 2000 Advanced Server搞成“蓝屏”!坦白地说,我还从来没看过哪个非蓄意的程序有这个“能耐”。由于当时正忙于另外一个大项目,无法去现场调试,最后只有凭经验对内存库代码小心翼翼地封装以异常处理代码(同时也做了一些别的修改……)。这样,虽然没有彻底解决问题,但程序终究不再死得那么难看了。

在这儿讲这么一段花絮有什么意思呢(当初为那个可怕的bug朝思暮想时我可不认为这是一个“花絮”)?我想说的是,对于任何软件而言,离开强健,效率也就无从谈起。而对于C++程序员来说,也许编写一个高效的程序并不难,但要编写一个需要7 ⅹ 24小时持续运行的服务端软件就不是那么容易了,需要考虑许多因素,有时这些因素甚至远远超出C++语言和开发工具的本身。作为一名开发实际项目软件的程序员,并非非得自己碰钉子才能积累经验,只要我们足够虚心,别人的经验往往都是我们很好的借鉴。鉴于此,我推荐以下几本书供你选读,它们可以让你从强健和效率两方面受益(当然了,它们涵盖的内容远不限于异常处理J)。

Scott Meyers, Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition)
Scott Meyers, More Effective C++: 35 New Ways to Improve Your Programs and Designs
《Effective C++中文版》,华中科技大学出版社
《More Effective C++中文版》,中国电力出版社
《Effective C++(影印版)》,中国电力出版社

如果说《Effective C++》主要讨论C++中一些相对基础的概念和技巧的话,那么《More Effective C++》则着重探讨了包括异常处理在内的一系列高级技术。与前者相比,后者具有两大主要区别:其一,它包含很多时新的标准C++的内容;第二,它讨论的主题倾向于“战略化”而非“战术化”,并且讨论得更深入、更彻底。尤其是对虚析构函数、智能指针、引用计数以及代理类(proxy classe)等技术和模式论述的深入程度,让人很难想象是出现于这样的一本小书之中。

游刃有余的技术,高超的写作技巧,Scott无疑是世界上最优秀的C++技术作家之一。在简洁、清晰、易读等方面,这两本书都卓尔不群。总之,Scott提供的这85个可以改善编程技术和设计思维的方法,都是中、高级C++程序员必备的技能。我强烈推荐这两本书(实际上还有一本,稍后就会看到)。

Herb Sutter, Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions
Herb Sutter, More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions
《Exceptional C++中文版》,中国电力出版社
《More Exceptional C++中文版》,华中科技大学出版社

你自认为是一名C++语言专家吗?读一读ISO C++标准委员会秘书长的这两本书再回答。在这两本书中,Herb采用了“问答”的方式指导你学习C++语言特性。对于每一个专题,Herb首先合理地设想出你的疑问和困惑,接着又猜测出你十有八九是错误的解答,然后给你以指点并提出最佳解决方案,最后还归纳出解决类似问题的普适性原则。

这两本书是典型的深究C++语言细节的著作,很薄,但内容密集,远远超过Scott的那两本书,读起来很费脑筋 — 我个人认为它们要比Scott的书难懂得多。若要研习这薄薄的两本书所包含的知识,至少需要花费数月的时间!(在Scott的荐序中,他坦陈不止一次陷入GotW问题的陷阱,你应该知道这意味着什么)对于语言细节的深究有什么好处呢?尽管在大多数情况下,我们不必关心C++代码幕后的动作,然而当我们不得不关心时,这两本书可以为我们提供很好的线索,因为它们揭示了C++语言中微妙而又至关重要的东西。

Stephen C. Dewhurst, C++ Gotchas: Avoiding Common Problems in Coding and Design
《C++程序设计陷阱》,中国青年出版社

Stephen的理论素养和实践经验注定这是一本值得一读的好书。Stephen曾经是贝尔实验室中第一批C++使用者。他已经使用C++成功解决了包括编译器、证券交易、电子商务以及嵌入式系统等领域中的问题。本书汇集了作者来自开发一线的99条编程真知灼见,洞悉它们,你可以避免几乎所有常见的C++设计和编程问题。

我甚至认为,对于C++编程菜鸟而言,阅读这本书会比阅读Scott和Herb的书更能轻松而立竿见影地获得更大的提高。我个人很喜欢这本书的写作风格 — Stephen的许多观点看似极端却无可辩驳。当然了,这种自信(以及冷幽默)来自于作者深厚的技术素养,而非自大的偏执。

除了上面推荐的书籍外,Dov Bulka和 David Mayhew合著的《Efficient C++: Performance Programming Techniques》(《提高C++性能的编程技术》,清华大学出版社)也值得一看。这本超薄小书聚焦于高性能C++应用程序开发。两位作者都是IBM软件专家,都工作于对性能要求极高的系统构建领域,本书是他们的经验之谈。也有人不喜欢这本书,因为它花了不少的篇幅讲述和C++无关的东西,我却恰恰因为这一点而对这本书产生好感,正是这些东西让我开阔了眼界。

模板和泛型编程

模板和基于模板的泛型编程无疑是当今发展最活跃的C++程序设计技术。模板的第一个革命性的应用是STL,它将模板技术在泛型容器和算法领域的运用展现得淋漓尽致,而Boost、Loki等现代程序库则将模板技术的潜能不断发挥到极致。在模板和泛型编程领域,我推荐以下两本重量级著作:

David Vandevoorde, Nicolai M. Josuttis, C++ Templates: The Complete Guide
《C++ Templates全览(繁体版)》,台湾碁峰资讯股份有限公司
《C++ Templates全览(简体版)》,人民邮电出版社

有一种老套的赞美一本书的手法,大致是“没有看过这本书,你就怎么怎么地”,这里面往往夸张的成分居多。不过,倘若说“没有看过《C++ Templates: The Complete Guide》,你就不可能精通C++模板编程”,那么这个论断对于世界上绝大多数C++程序员来说是成立的。

这本书填补了C++模板书籍领域由来已久的空白。此前,上有《Modern C++ Design》这样的专注于模板高级编程技术和泛型模式的著作,下有《The C++ Standard Library》这样的针对特定模板框架和组件的使用指南。然而,假如对模板机制缺乏深入的理解,你就很难“上下”自如。鉴于此,我向每一位渴望透彻理解C++模板技术的朋友推荐这本书。

这本书在内地、台湾各有一个译本,但出自不同的译者之手。当你看到这篇文章时,两个译本应该都已经上市,对于读者来说当然也就多了一种选择。侯捷先生个人网站上开放了繁体译本大部分章节,不妨先睹为快。

Andrei Alexandrescu, Modern C++ Design: Generic Programming and Design Patterns Applied
《C++设计新思维:泛型编程与设计模式之应用》,华中科技大学出版社
《C++设计新思维(影印版)》,中国电力出版社

你自认为是C++模板编程高手吗?请看过这本书再回答J 这是一本出自天才之手令人敬畏的杰作。泛型模式,无限延伸你的视野,足以挑战任何一名C++程序员的思维极限。

这本书共分为两大部分,第一部分讨论了 Loki程序库采用的基础技术以及一些高级语言特性,包括基于策略的类设计、模板局部特化、编译期断言、Typelist以及小型对象分配技术等。第二部分则着重介绍了Loki中的重要组件和泛型模式技术,包括泛化仿函数(Generalization Functor)、单件(Singleton)、智能指针、对象工厂(Object Factory)、抽象工厂(Abstract Factory)、访问者(Visitor)以及多方法(Multimethods)等。每一种技术都让人大开眼界,叹为观止。

在C++的学习方面,过犹不及往往成了不求甚解的借口。然而,面向对象并非C++的全部,模板和泛型编程亦占半壁江山。对于“严肃”的C++程序员而言,及时跟进这项早经例证的成功技术,不失为明智之举。

结语

这些著作是如此大名鼎鼎,也许根本不缺我一个推荐。然而,纵然C++程序员队伍的发展壮大速度不像其他更时髦的语言那样迅速,新人进总是多于旧人出。除了热忱地欢迎新人,我个人认为到了对C++书籍进行“盘点”的时候了,并且希望这样的“盘点”有益于感兴趣的读者。请保持耐心和宽厚。在下篇中,我将继续介绍标准库、网络编程以及其他方面的C++好书。有好书相伴,这个冬天不会冷。


C++程序设计之四书五经(下篇)

我在上篇中“盘点”了TCPL和D&E以及入门教程、高效和健壮编程、模板和泛型编程等方面共十几本C++好书。冬去春来,让我们继续C++书籍精彩之旅J

标准库

当 我还在研究院工作时,与同院另外两家研究所合作开发过一个大型水利枢纽调度集成项目。我们三家软件系统之间都要相互通信。在调试通讯模块时,细心的客户 (一名好学的系统管理员)发现对于同一通信规约的解释代码,我的不超过30行,而对方的则超过了150行且很难看懂。这位系统管理员很纳闷,我说大家编程 风格和习惯不一样,我使用了标准库,而他使用了传统C编程风格以及他所习惯的另外一些技术。

别误会!我绝无贬 低这位合作伙伴的意思。事实上,我对那些真正有着深厚的C编程功力的程序员常常怀有钦佩之心。毕竟,C++能有今天的成功在很大程度上缘于它深深地植根于 C。作为一名C++程序员,倘若不熟悉C++中的C,我往往会认为他的基本功是不扎实的,他的技术底气是不足的。

不 过话又说回来,C++是一种多范型(paradigm)编程语言,具体采用哪种编程风格,专业程序员应该知道视具体情况而定。作为一名经常需要在现场做即 兴开发的项目负责人,为了短平快地解决当务之急,我习惯尽量采用现有的库(和组件)。效率(以及强健性)久经验证的C++标准库已经摆在那儿了,何乐而不 用呢?

Nicolai M. Josuttis, The C++ Standard Library: A Tutorial and Reference
《C++标准程序库:自修教程与参考手册》,华中科技大学出版社

这 是一本百科全书式的C++标准库著作,是一本需要一再查阅的参考大全。它在完备性、细致性以及精确性方面都是无与伦比的。本书详细介绍了每一标准库组件的 规格和用法,内容涵盖包括流和本地化在内的整个标准库而不仅仅是STL。正如本书副标题所示,它首先适合作为教程阅读,尔后又可用作参考手册。

浅显易懂的写作风格使得这本书非常易读。如果你希望学习标准库的用法并尽可能地发挥其潜能,那你必须拥有这本书。正如网络上所言,这本书不仅仅应该摆在你的书橱中,更应该放到你的电脑桌上。我向每一位职业C++程序员强烈推荐。

Angelika Langer, Klaus Kreft, Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference
《标准C++输入输出流与本地化》,人民邮电出版社

C++标准库由STL、流和本地化三部分构成。关于STL的书市面上已经有不少,但罕见流和本地化方面的专著。本书是这两个领域中最优秀的一本,迄今为止没有任何一本书比这一本更全面详尽地讨论了流和本地化。如果你不满足于停留在“会用”流库的层面,千万不要错过它。

2001年夏天,我草草翻阅过这本书的中文版,从内容到包装都给我留下了比较深刻的印象 — 不过负面的居多一些。2003年秋天,无意中得知某网络书店正以超低价格甩卖这本书的中译本,情不自禁,一阵唏嘘。

Scott Meyers, Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
《Effective STL(影印版)》,中国电力出版社

读 完Scott 的《Effective C++》和《More Effective C++》的中译本之后,我一直期待这本书的中文版。我从潘爱民先生的个人主页上了解到,他和他的合作伙伴似乎早已完成了这本书的翻译工作,可惜至今市面上 仍不得见。幸运的是,我们可以看到它的原版。

本书是使用STL的程序员必读之作。在这本书中,Scott向我们 讲述STL容器和算法的工作机制以及如何以最佳方式使用它们。和Scott的其他作品一样,这本书的写作风格清晰、精确,具有极佳的可读性。看过这本书以 后,我想你也许会和我以及其他C++程序员一样产生这样的想法:Scott什么时候会写出一本“More Effective STL”?

关 于STL,我还提醒你留心Matthew H. Austern的《Generic Programming and the STL: Using and Extending the C++ Standard Template Library》(《泛型编程与STL》,中国电力出版社)。这本书散发着浓厚的学院气息。Andrew Koenig和Barbara Moo在《Accelerated C++: Practical Programming by Example》一书末尾郑重推荐另外两本进阶好书(除了他们自己的《Ruminations on C++》外),其中一本是TCPL,另外一本就是本书!

网络编程

在网络编程时代,C++应该扮演着怎样的角色,让ACE(Adaptive Communications Environment)来告诉你。

Douglas C. Schmidt, Stephen D. Huston, C++ Network Programming, Volume 1: Mastering Complexity with ACE and Patterns
Douglas C. Schmidt, Stephen D. Huston, C++ Network Programming, Volume 2: Systematic Reuse with ACE and Frameworks
《C++网络编程,卷1:运用ACE和模式消除复杂性》,华中科技大学出版社
《C++网络编程,卷2:基于 ACE 和框架的系统化复用》,电子工业出版社

采 用C++进行企业级网络编程,目前ACE(以及这两本书)是一个值得考虑的选择。ACE是一个面向对象、跨平台、开放源码的网络编程框架,目标在于构建高 性能网络应用和中间件。Douglas是ACE的创始人,Stephen则已为ACE提供了数年的技术支持和顾问服务,两位都是ACE社群(是的,ACE 的影响和实际应用的程度已经形成了一个社群)的专家。

ACE并不单单被大学和研究所追捧,它已经被成功地应用于世界上成千上万个商业应用中。在电信、宇航、医药和财经领域的网络系统中,ACE已经并继续发挥着重要的作用。如果你准备开发高性能通讯系统,你应该考虑考虑这一汇集世界顶尖专家智慧的成果。

除 了使用C++面向对象设计技术和模板等高级语言特性外,ACE还运用了大量的模式。《C++网络编程》卷1和卷2并不仅仅教你关于ACE的方方面面,它还 会教给你模式和通用框架设计等高级技术等。所以,作为一名中、高级C++程序员,即使你很少进行正儿八经的C++网络程序设计,阅读这两本书同样可以从中 受益。

是的,并非所有网络应用都要使用Web服务器(以及其他应用服务器)和重量级组件模型,换个思路,它们或许也可以从轻量级的ACE组件中获益。

杂项

以下这几本书之所以被列入“杂项”单元,只是因为我没有考虑出更合适的归类方法,它们和上面的书籍一样,值得一读。

Bruce Eckel, Thinking in C++, Volume 1: Introduction to Standard C++ (2nd Edition)
Bruce Eckel, Thinking in C++, Volume 2: Practical Programming (Second Edition)
《C++编程思想(第2版)第1卷:标准C++导引》,机械工业出版社
《C++编程思想(英文版 第2版)》,机械工业出版社

《Thinking in C++》的第1版于1996年荣获“软件研发”杂志评选的图书震撼大奖。最新推出的第2版对内容进行了大幅改写和调整,以反映C++标准化带来的影响以及 近几年面向对象领域最新研究和实践成果。“输入输入流”、“多重继承”、“异常处理”和“运行时类型识别”等高级主题连同C++标准化以后增加的一些内容 则被放入第二卷中。Bruce是一名经验丰富的C++讲师和顾问,其培训和写作经验都是世界一流水准,他的作品比那些“玩票”的技术人员写的东西更能吸引 读者。事实上,在同类图书中,对于大多数读者而言,这本书的可读性要超过TCPL《C++ Primer》顺带一提,访问作者的站点,你可以先睹第二卷的风采。

Andrew Koenig, Barbara E. Moo, Ruminations on C++: A Decade of Programming Insight and Experience
《C++沉思录》,人民邮电出版社

Andrew 是世界上屈指可数的C++专家。这是一本关于C++编程思想和程序设计技术而非语言细节的著作。如果你已经具有一定的基础,这本书将教你在进行C++编程 时应该怎样思考,应该如何表达解决方案。整本书技术表达透彻,文字通俗易懂。Bjarne这样评价这本书:本书遍布“C++是什么、C++能够做什么”的 真知灼见。

Stanley B. Lippman, Inside The C++ Object Model
《深度探索C++对象模型》,华中科技大学出版社
《深度探索C++对象模型(影印版)》,中国电力出版社

从 编译器的角度观察C++可以使你知其然并知其所以然。本书探讨了大量的C++面向对象程序设计的底层运作机制,包括构造函数、函数、临时对象、继承、虚 拟、模板的实例化、异常处理、运行期类型识别等,另外还介绍了一些在实现C++对象模型过程中做出的权衡折衷。喜欢刨根问底的C++程序员不要错过这本 书。

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Design Patterns: Elements of Reusable Object-Oriented software
《设计模式:可复用面向对象软件的基础》,机械工业出版社
《设计模式:可复用面向对象软件的基础(英文版)》,机械工业出版社

设 计可复用的面向对象的软件,你需要掌握设计模式。本书并非专为C++程序员而写,但它采用了C++(以及Smalltalk)作为主要示例语言,C++程 序员尤其易于从中受益。四位作者都是国际公认的面向对象软件领域专家,他们将面向对象软件的设计经验作为设计模式详细记录下来。这本书影响是如此深远,以 至于四位作者以及本书都被昵称为GoF(Gang of Four)。本书学院气息浓厚,行文风格严谨简洁,虽然它不如某些讲解模式的书籍易读,但真正要精准地理解设计模式,本书是终极权威。学习设计模式,这本书需要一而再、再而三的咀嚼。顺带一句:请将设计模式化作开拓思维的钥匙,切莫成为封闭思维的枷锁。

还有一些C++好书值得一读,恕此处无法一一列出。例如John Lakos的著作《Large-Scale C++ Software Design》(《大规模C++程序设计》,中国电力出版社)和侯捷先生的《STL 源码剖析》(华中科技大学出版社)等。

《STL 源码剖析》是一本很有特色的书,但我认为它还可以更好。我个人期待侯捷先生自第一版发行以来经过对模板技术的沉淀和再思考之后,再写一本剖析得更深入、更 透彻并且更全面的“第二版”。遗憾的是,侯捷先生在完成《C++ Templates: The Complete Guide》一书的翻译后似乎决定暂时告别模板、泛型编程和STL领域。

2004年3月31日补充:我目前最常查阅的两本参考书是《C++标准程序库》和《STL源码剖析》。当然了,这与我年内的写作计划有很大的关系。

使用C++成功开发大规模软件系统,不仅需要很好地理解大多数C++书籍中讲述的逻辑设计问题,更需要掌握《大规模C++程序设计》中讲述的物理设计技术。当然,这本书的确有点过时了,不过,如果你的精力和金钱都比较宽绰,买一本看看并无坏处。

至此,我想有必要声明一下,有一些(好)书没有得到推荐,主要原因如下:

  • 以上这些书已经足够多、足够好了。

  • 我不会推荐通过正常渠道很难购买到的书籍 — 不管是中文版还是英文版。

  • 作(译)者名气大小不影响我的推荐。我们是在看书,不是看人。

  • 我不会推荐我从来没有看过的书。我至少要看过其中的某个版本(包括电子档)。这个“看”,一般指“认真阅读”,不过有一些也只能算是“浏览”。

结语

作 为一名普通技术写译者,我深知技术创作和翻译的艰辛(和快乐),并多多少少了解一些有关技术书籍创作、翻译、制作、出版以及市场推介背后的细节。今天,我 不会再对一本看上去差强人意的图书信口开河。罗列同一本书的各种版本的用意只在于为你多提供一些信息,让你多一种选择。

在本文成文的后期, 我给Bjarne写了一封信,请教如果他来写这篇文章会怎么写。他给了我简明扼要的建议。在肯定以上列出的绝大部分图书都是世界顶尖水平的C++著作的同 时,Bjarne提醒我别忘了向专家级程序员推荐《The C++ Standard : Incorporating Technical Corrigendum No. 1》。这本书是 C++标准规范的“图书版”,Bjarne亲自为之作序。

Bjarne还友好地提醒我, 在我的推荐列表中没有哪一本有助于C++程序员进行Windows编程 — 这正是我的本意。在这篇文章中,我只推荐、点评平台中立的C++著作(网络编程除外) — 和操作系统无关,和集成开发环境无关,我甚至幻想它们和编译器也无关。你可以根据业务开发需要,选读自己喜爱的领域相关的C++书籍。

说到 “系统无关、平台中立”,我不由得想起了“抽象层”的概念。开发实际应用的C++程序员通常工作于特定操作系统、特定开发环境和特定业务领域之中,而对标 准C++和C++标准库扎实而深刻的把握,无疑是你得以在不同的操作系统、不同的开发环境以及不同的业务领域之间纵横驰骋的“抽象”本钱。

荣耀
2004年1月
南京师范大学

至少应该阅读的九本C++著作zz

C++语言吸引如此之多的智力投入,以至于这个领域的优秀作品,包括重量级的软件产品、程序库以及书籍著作等,数不胜数。对于读者来说,倘若限于经济等客观因素而必须做出折衷取舍,我推荐至少阅读以下几本书:

1. The C++ Programming Language (Special 3rd Edition) by Bjarne Stroustrup

2. The Design and Evolution of C++ by Bjarne Stroustrup

如果你只打算购买一本书,那就选择1,如果还想要第二本 — 那就是这两本了。它们的作者是 C++语言的创建者。Stroustrup的文字语言丝毫不逊色于他所创建的程序语言。它们可以使你免于误入歧途。

3. Effective C++: 50 Specific Ways to Improve Your Programs and Designs by Scott Meyers

4. More Effective C++: 35 New Ways to Improve Your Programs and Designs by Scott Meyers

5. Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers

我强烈推荐Meyers这个系列。它们是菜鸟进阶必读之作。游刃有余的技术,高超的写作技巧。Meyers可能是世界上最优秀的C++技术作家。

6. The C++ Standard Library : A Tutorial and Reference by Nicolai M. Josuttis

C++标准库字典式著作。内容全面,结构清晰。

7. C++ Templates: The Complete Guide by David Vandevoorde, Nicolai M. Josuttis

AlexandrescuModern C++ Design阅读门槛很高,这本书可以充当你的垫脚石。单单阅读The C++ Standard Library或许并不足以使你具备定制、扩充标准库组件的能力,这本书可以助你一臂之力。对于任何希望进入模板编程领域的C++程序员来说,这是一本必读之作。

8. Modern C++ Design: Generic Programming and Design Patterns Applied by Andrei Alexandrescu

一本天才的著作!泛型模式,无限延伸你的视野,足以挑战任何一名C++程序员的思维极限。这本书几乎可以满足你对C++模板的所有幻想。

9. Design Patterns by Erich Gamma , Richard Helm, Ralph Johnson, John Vlissides

设计可复用的面向对象的软件,你需要掌握设计模式。这并不是一本专门针对C++程序员的著作,但它采用了C++(和Smalltalk)作为主要示例语言,C++程序员尤其易于从中受益。学习设计模式,这本书需要一而再、再而三的咀嚼。

这是公正客观的推荐吗?可能不是。实际上,没有任何人能够做到绝对客观 — 至少The Design and Evolution of C++是否应该进入这个推荐列表就能惹起喋喋不休的争吵

还有许多优秀的著作值得推荐,但为了将推荐数目控制到个位数,它们没能入选。换一个人也可能会给出另外的“九本书”列表,但至少大半会和这个列表重叠。

巧合的是,这几本书均出自Addison-Wesley。它们绝大多数在市面上能找到相应的中文版,几乎每一中文版都有很好的质量。祝各位阅读快乐。


荣耀
20039
南京师范大学
www.royaloo.com

胡子决定编程语言运势zz

胡子决定编程语言运势(程序员2005年第一期文章)
http://blog.csdn.net/myan/archive/2005/11/23/535391.aspx


C#会前途黯淡,只因大胡子惹的祸?!有点耸人听闻吧。可是色列软件工程师 Tamir
Khason自有一套理论(也许他曾学过中国的面相术)得出这样的结论。不信,咱就瞧瞧
他发在自己Blog上的一篇文章,看看他有什么样的奇思妙想。

Round 1


http://bbs.sjtu.edu.cn/file/test/117542647972940.jpg
John Backus,Fortran之父


http://bbs.sjtu.edu.cn/file/test/117542648972670.jpg
Alain Colmerauer, Prolog之父


http://bbs.sjtu.edu.cn/file/test/117542710259292.jpg
Jean Ichbiah, Ada之父


以上三人分别发明了Fortran、 Prolog和 Ada语言。这些语言都有着过人的优点,每一种
在当时都可以称得上是创意不凡。很可惜,三个当中没有一个广泛流传。与之相对,下面
的Brain Kernighan、Dennis Ritchie和Ken Thompson所“炮制” 出的C和Unix,已经使用
了三十年了,也许再用100年也没问题!


http://bbs.sjtu.edu.cn/file/test/117542712478021.jpgC语言宗师Brain Kernighan


http://bbs.sjtu.edu.cn/file/test/117542714935394.jpg
UNIX/C创造者Ken Thompson 和 Denn



Round 2

以下两位分别是Alan Kay和Kristen Nygaard。是他们发明了第一批面向对象语言
Smalltalk和Simula 67。不过,这些语言都行之不远。


http://bbs.sjtu.edu.cn/file/test/117542716773320.gif
Smalltalk之父Alan Kay


http://bbs.sjtu.edu.cn/file/test/117542718072942.png
Simula 67之父Kristen Nygaard


Brad Cox,曾尝试把OO加入到C中,于是Objective-C诞生。然而,Objective-C 也是命运
不济,目前只有在Mac操作系统中还能看到它的踪影。 与之相对,另一位所做的相同尝试
却大红大紫,这就是Bjarne Stroustrup所写的C++。其实,看看 Stroustrup的脸就不难明
白为什么这两种语言的命运会如此不同。

http://bbs.sjtu.edu.cn/file/test/117542719874221.gif
Objective-C之父Brad Cox

http://bbs.sjtu.edu.cn/file/test/1175427235306382.jpg
C++之父Bjarne Stroustrup



到这里,你能猜出点规律来吗?

答案揭晓:有大胡子——有旺运;没胡子——只有干瞪眼!



由此,看看下面两位的胡子,C#和Java究竟鹿死谁手,不就是不言自明的吗?

http://bbs.sjtu.edu.cn/file/test/117542724573970.jpg
C#之父Anders Hejlsberg


http://bbs.sjtu.edu.cn/file/test/1175427256306383.jpg
Java之父James Gosling



Round 3

当然,你也可以不信。不过,还有一个例证可以很好地说明。下面两位分别是Basic的作者
Thomas Kurtz 与Perl的作者Larri Wall。两人虽然没有令人咋舌的大胡子,但两撇小胡子
倒也浓密有致。自然,这两种语言红得发紫。

http://bbs.sjtu.edu.cn/file/test/1175427267318501.gif
Thomas Kurtz, Basic之父


http://bbs.sjtu.edu.cn/file/test/117542727534513.jpg
Larry Wall, Perl之父


但是同为动态语言,Python和Ruby的作者Guido van Rossum和松本行弘都没有胡子,哪怕
是两撇小胡子,所以尽管它们都比Perl语言好,但都没有Perl使用广泛。不过,凡事都有
转机。Rossum看样子极有希望很快长出大胡子,而日本人松本,看样子够呛。

http://bbs.sjtu.edu.cn/file/test/117542806173972.jpg
Guido van Rossum, Python之父


http://bbs.sjtu.edu.cn/file/test/117542796773030.jpg

松本行弘, Ruby语言之父




————————————————————————————————
更有意思的事情还在后面,松本正巧看到了这个帖子,很不服气,于是便在自己的blog上
贴出这幅照片:

http://bbs.sjtu.edu.cn/file/test/117542802973300.jpg松本行弘:谁说俺长不出大胡子?



看来, Ruby还是大有希望的!

后记:从2005年发展的情况来看,Ruby的火爆再次证明的胡子定律的正确性。