Kenny's profile白菜地BlogLists Tools Help

Blog


    10/29/2007

    都是美金惹的祸——最无耻的FireFox推广用语

    以下是在诸多网站上见过的最无耻的FireFox推广用语:

    1、发现您正在使用老掉牙的IE浏览器,强烈推荐您在 Windows 操作系统中使用最安全(杜绝木马、病毒)的浏览器:FireFox火狐浏览器2.0,点击下载 !

    2、广大的男人性福了,最近我发现了一个好的浏览器,能够自动代理访问国外网站。它的名字叫火狐浏览器,下载地址为http://8.ycro.cn 在正常使用的时候,与普通的没有什么区别。如果你想看色情网站时,只需要通过“工具”->“网站”下拉菜单就可以选择内置的一些色情网站了,包括99BBS、情色六月天、色狼网等,并且会自动使用代理访问,这样就不怕被封了。看来,这是国外的色情网站为对付国内封站而专门开发的产品,我用了效果确实不错,给大家一个下载地址。http://8.ycro.cn 这款浏览器由著名搜索引擎google推出,性能十分优秀

    3、系统提示:发现您正在使用IE浏览器,强烈推荐您在 Windows 操作系统中使用最安全的浏览器: FireFox火狐浏览器2.0,点击下载[上网速度提升2倍] !

    4、系统检测发现您正在使用极低版本IE浏览器,可能存在各种安全隐患,强烈推荐:更加快速、更加安全、完全免费的浏览器:FireFox火狐浏览器2.0,点击下载

    5、如果您发现页面常常失去响应,建议使用FireFox

    10/23/2007

    破解网页不能复制的最简单的方法

    常见许多网站上登一些关于“破解网页不能复制的方法”的文章,内容很长,涉及许多javascript知识或Internet选项设置操作。

    其实,对于禁止复制文字的网页,最简单的方法就是,“文件”->“另存为”,然后选择类型为纯文本文件,然后双击打开(比如“记事本”程序),随便你怎样复制和粘贴了。

    以上方法教过几个人,几个使用电脑水平很低的人,反应都还不错。

    简单的方法有群众基础嘛,呵呵

    10/19/2007

    opera的面试

    opera的面试很有意思,先把一套题发给你,让你去做,然后根据你完成的情况来决定是否再参加面试。据说面试不是很重要,这个题比较重要,至少我是被这样告知的。

    opera的试题似乎很久都没有更改过了,从05年就是这样的一道,大致是关于LogicFunction(一个计算't'或'f'结果的东东)。
    原题里的代码写得很乱,完全是C里那一套用指针故弄玄虚的做法。虽然这东西就是用来让人挑错和改写的,但是也不要写得这么烂吧?

    发给我试题的那位女士叮嘱我说,不要在网上搜索,更别去抄。因为好奇,我去搜了一下,发现网上的确有相关的内容,但是看不到,只能看google的快照。不过我也懒得去看——看一份不好的代码已经很受煎熬了,难道要我看二份?

    做这题的时候速度很慢,对于这种烂代码我基本上看不下去,但还要硬着头皮去做。从晚上10点多开始弄这东西,但中间大部分的时间在上网,吃了一个苹果,两块奶糖,五个桔子,N把瓜子,还看了一集heroes,后来实再是烦了,准备去睡觉,但是睡不着,又起来写了点东西,后来又去睡,折腾了一夜也没真正睡上多少。今天早上终于忍着一种强烈厌恶的感觉把这东西勉强写完了。

    在最后写doxygen文档的时候,我在头脑中生出了一种邪恶的念头:如果opera的人真的在写这种代码(或者类似感觉的代码),那就不难理解为什么opera总是要频繁发布新版本了……

    但愿opera里面工作的人不是用这种方式来工作吧!要不然我就白浪费时间去和他们谈职位的事儿了。

    最后再说一句,I hate this piece of shit.

    补充1:opera后来给的回笔是:做得太好了(perfect),但他们“不敢相信”是我做的,要我给他们一个解释。我觉得很好笑,后来想想也合理吧,毕竟他们可能会对中国有偏见,而且之前有去应聘的人从网上抄袭被抓到过,唉!我的中国同胞们啊,何苦这么不争气呢!

    补充2:从百度搜到这里的各位要应聘opera职位的兄弟们,不知能否听我一言:不要作弊哦!中国人的形象已经不太好了,大家还是尽量维护一下吧!

    补充3:过去很长时间了,也没什么消息,人力资源公司的那位女士也感觉很奇怪,她也不明白为什么最终没有一个明确的说法。后来她给我推荐了一个别的职位,呵呵。Opera的这种种做法,实在是让人无法恭维。

    10/14/2007

    另一个面试中的问题,关于嵌套类

    还是上次说的那次面试,面试官提了一个明显违反ISO-14882国际标准的问题:嵌套类和宿主类的访问权限如何?

    是的,有些编译器自动把嵌套类型做为宿主类型的友元,虽然这种行为严重违反了现行标准。

    class H
    {
        class E
        {
        };
        firend class E; // 在现行标准中禁止,但有些编译器默认添加
    };

    不过,有个修正案,准备将现在标准中禁止的这一行为修改为允许,并同时允许友元说明向嵌套类型的传递。毕竟,这样子看起来更合理一些。

    附带说一句:关于“有些编译器自动把嵌套类型做为宿主类型的友元”我是刚刚知道,知道这个之后我才明白这道题想问什么,也猜出来了他们的“正确答案”是什么。所以,这道题对于考官来说应该也是划了大大的叉,因为我按C++标准答的。

    10/13/2007

    转一个文章:中国很多IT企业根本就不知道资深的含义!

    国内一个很著名企业老板曾经说过:在IT行业超过35岁的技术人员将被淘汰,所以不要35岁后的技术人员。导致整个业界尤其是在软件开发行业都在排斥年龄超过35岁的人员,也导致很多工程师为自己35岁以后的前途发愁而转行。因为很多人都认为IT行业是年轻人的行业,而软件开发就是吃青春饭,过了35岁就没用了。

    很多企业也在自己的企业宣传中吹嘘:我们企业 XX学历以上的占百分比的多少,平均年龄在25岁等。认为自己企业员工年轻了那才叫高科技企业,那才叫有创造性。其实我认为这一种很幼稚的想法。听了这些人的观念,我才明白为什么我们的IT企业很少有能成为IBM、MICROSOFT等国际大企业的原因了。

    因为很多中国IT企业根本不理解资深的含义!

    我曾经接受过INTEL公司的培训,他们来的工程师都40多岁了,一个行业搞了20多年,那是什么样的一个理解程度呢?有些人头发都白了,你根本问不倒他们。我曾经问他,你最喜欢的是什么呢,他回答说是技术,我问他长期做技术难道你不厌烦吗?他笑着说NO。我才理解什么叫资深的含义,我也才理解为什么他们能把技术做得那样好。

    我们中国的公司为什么很难在短期内超越他们呢?因为他们的公司是依靠大量的这样资深的工程师的支撑才持续发展到今天。

    我也曾经在日本公司工作过,才理解什么叫工作狂。很多日本人30多岁就白发斑斑了。如果你见了那些穿着整洁的西服,扎着鲜艳的领带,胡子刮得很干净,走路笔直,看起来年龄不大,但是头发却花白的人,多数是日本人。日本企业一般不轻易辞退员工,员工流动率也很低。一个人在一个行业或者专业一干就是几十年,甚至一辈子服务一个企业。在日本公司,就是写一个WORD文档甚至要写7、8遍。要求一个标点也不能错,格式要完全达到要求。你甚至都认为后面的修改都是在浪费时间,因为我们中国人认为能表达清楚,差不多就可以了,但是在日本人那里根本就不能过关。经过多次这样的训练,你就会理解什么叫日本的精工操作。我们的工业和日本差距大的原因,尤其在精工行业,我认为很重要的原因就是他们每件事上都做得很精细,一个行业内研究很深。而我们却很浮躁,长期已往就形成了差距。正是胡适先生所说的中国人差不多先生太多了,这就是差距。

    从IT行业人才使用看,我们国家普遍存在年轻化和短期化。做技术开发的多数是年轻人,并且很多人今天学这个,明天学哪个,哪个上手快就学哪个,哪个行业工资高就学哪个。并且频繁跳槽,到了另外的企业后就可能做新的工作了,学新的技术了。这种不断的切换其实是一种资源浪费,就很难把一个技术钻研地很透彻,对于整个IT行业来说也是一种损失。许多企业也觉得现在的员工对企业的忠诚度不高,跳槽频繁。一方面因为个人的价值导向的问题,但是我认为最大的原因是企业追求短期效益、短视造成的。哪个人不希望稳定发展呢,但是很多企业就是用员工的青春,年龄稍微大了(仅仅超过35岁就认为大了)就认为不能干活了,员工就面临随时被辞退。开发哪个项目就招聘那方面的人,产品做完了就解聘很多人。好听些是战略裁员,不好听了就是卸磨杀驴。企业不养老,而社会养老前景不清晰,这样大家能不跳吗?所以整个社会都是处于浮躁阶段。浮躁的原因就是长久落后惯了,突然进入了快速发展期,看到了很多美国的财富神话,所以都普遍犯红眼病,浮躁病。这种行业的浮躁和短视能造就成大批的资深的专业人士吗?

    从利益分配上看,我们国家很多IT企业也存在很大问题。有几个做技术的工程师最后能成为富翁呢?李彦宏那样很少,并且因为他做了老板才得到了价值体现。我们很多老板就很难和自己的员工尤其工程师共享企业发展的成果。在发展阶段,急需要人才的时候就很尊重你,等年龄大的时候就嫌弃,没有分配给长期利益。所以很多工程师年轻的时候就是牛马,就是工具,吃的就是青春饭。而在美国的很多企业,优秀的工程师们可以无后顾之忧,可以不为自己将来发愁,因为他们很多人都持有公司的股票,就是将来不工作了也是百万富翁。只要技术很强,一个工程师可以在他的专业领域一直钻研下去,不必为了养老而朝三暮四。这样不出成果都很难。

    从价值取向看,我们官本位思想导致很多人都追求做管理,不去做技术。在很多美国企业,他们是分职能和技术两条线。一个高级技术人员职位可能不高,可以不是经理,但是可能收入比经理还要高,因为他是某个行业行业的专家。经理主要是协调资源,落实制度和计划的执行。而高级技术人员则负责技术实现,规避技术风险,并创新,开发出具有竞争力的产品。而在中国呢,如果你是一个技术人员,即使你很优秀,有几个人能在收入方面超过自己的上司经理呢,一个新来的年轻的MBA或者能讲几口英语的海归就能当上你的上司,收入就可比你高,支配资源的权利就可比你大。

    如果在中国,30多岁了手下还不能领导一帮人,还在做技术,别人就觉得你很窝囊,就瞧不起你。如果你是经理了,则别人马上很尊重你,这样导致很分心,所以你不得不向上爬,做经理,高级经理,技术总监,CTO,才能收入高,地位高。但是等高升了,就不能做技术研究了。所以很多人做技术时间长了就去做管理了,有的去做销售了,总之转行的人很多。留下的如果没有一个头衔别人就认为是没出息。所以中国就缺少资深的技术人员。

    在美国考高学历是为了做研究,在中国则是为了当官,为了能在职场上获得更高的职位。其实很多人也喜欢钻研技术,但是整个环境如此,价值观和个人喜好发生矛盾,最后价值观被扭曲,只能放弃自己喜欢的专业追求,去做管理了。管理的成就感就是地位高,技术的成就感就是对做出了对社会有用的产品。所以在中国能有几个官员被历史记住呢,但是袁隆平却将永远被后人和历史记住。

    并且在我们企业,有些时候在上级看来,如果认为一个工程师技术很牛,就要提升你,但是被提升了,就离开了具体的技术岗位,管人了,不钻研技术了。所以这也是很大的人才浪费。并且很多人就不善于和人沟通交往,不擅长做管理。被提上去了却发现管理一团糟,就只得又下放,多数情况下这个优秀的技术人员最终选择了离开公司。所以我们很多公司为了表示对一个人的肯定,只能提升到管理岗位,而脱离了具体技术。所以都是受几千年来官本位思想影响很严重。这样导致我们的职业专业队伍被大大削弱。

    从一个人的成长来说,想在两三年内出成绩,基本不可能的,是违背自然规律的。毕业后基本头2年是在混混沌沌中度过,头3年时间是学习阶段,5年时间是基本成熟阶段,8年时间后才是出成绩阶段。除非天才,多数的人都是按照这个阶段发展。假设按照大学毕业23 岁计算,8年后就是31岁了。还没创造几年就35岁了。35岁就没人要了。 这样能出资深的人员吗?当然超过35岁也有人要,但是你必须要么是名人,或者高级职称的,或者高学历的。但是现在有几人考职称呢?有几个默默做技术的工程师能成为名人呢?在传统行业35岁正是壮年和创造时期,正是担当技术骨干的时期,我就是奇怪了为什么在IT行业35岁就不能接受了?是那个著名企业家的误导,还是世人的偏见呢?

    为什么有这样的观点呢,那是因为在前几年,IT刚兴盛,并且我们中国IT发展起步晚,年代短,所以基本上都是年轻人在技术开发,大学培养出了一批批的大学生加入了IT行业。好象很多年龄大一些的人跟不上时代了,所以那位企业家发出了那样的感慨。但是随着时代的发展,这种现象将发生改变。

    从行业发展趋势来看,IT行业现在看来是高科技行业,不断有年轻人涌入,是一个不断创造财富神话的行业。但是IT行业其实也是一个大的服务行业,当IT硬件技术成熟起来后,将成为一个制造业。所以将来IT行业也将成为一个传统行业。一个新兴行业最后都必然成为传统行业,这是历史规律。现在很多人已经感觉到IT行业没有前几年那样好做了,钱难挣了。这其实是一种回归传统的自然现象。随着这种回归,则IT行业要长久发展,则也将出现传统行业的那种需求,需要资深的工程师们的支撑。

    而我们要真正赶上发达国家,例如美国,日本,则需要改变观念。可喜的是,这种观点已经发生了改变。在华为那样的一些大公司,就很重视很有经验的工程师,里面拥有大量的超过30岁的比较资深的工程师。但是和美国那样的IT大国比较起来,我们的资深工程师就是他们的学生了。

    我原来认为象自己这样做技术近乎十年的人,也算资深了。但是当为了解决难题,到一些美国的技术论坛上去,才发现那里才存在真正的牛人。很多都是美国人,他们很多人现在几乎40 岁,还是在做技术,我到那里去就是请教问题的,是学生。在他们的个人介绍中,很多人在很小的时候,70,80年代就开始接触电脑了。我接触电脑比他们整整晚了20年,能相提并论吗?这就是差距。就如同游泳,一个人在一个行业沉浸了十年,甚至几十年,那种持续的用力,深厚的功底导致的解决问题的能力和熟练程度、创造性能和一个仅仅毕业才三年的人相比吗?

    当然了IT技术发展日新月异,新技术不断推陈出新,令人眼花缭乱。今天JAVA ,明天点net,J2EE,JSP;确实需要强的学习能力,年龄大了自然学习能力下降。年轻人当然脑子活,富有创意。但是聪明不能代替经验,并且多数情况下人的智商相差不大。所以不能仅仅依据此就认为否定了经验和思维能力。

    当然了互联网行业有些例外,所以也就是有些人所说的,互联网行业是我们国家最有可能赶超美国的行业。以在美国纳市上市的中国企业的分布比例来看,也证明了这个观点。但是在软件开发和硬件设计行业,我们还有很多路要走。这些行业经验还是很重要的,还是需要资深工程师们的支撑的。而软件开发和硬件设计行业正是 IT行业真正的核心和基础所在,是我们的软肋。所以将来必然需要大量的资深工程师。

    所以大家千万别被别人误导了,要看清历史的发展规律。注重持久和执着地发展。

    9/27/2007

    关于C++标准中的export关键字的故事(文摘)

    Herb Sutter在《Exceptional C++ Style》一书中这样写到:
    全世界唯一实现了export特性的是EDG,他们反映说,就他们的经验来看,export是至今最难实现的C++特性,与他们实现过的其它三大主要特性(例如名字空间或成员模板)耗费的工作量不相上下。仅是export本身就耗费了不止三个人年来编码和测试,而且这还没算上设计工作的开销,而同样这三个人实现整个java语言也只不过耗费了两个人年。

    Bjarne Stroustrup在他的论文《Evolving a language in and for the real world: C++ 1991-2006》中这样写到:
    这个(关于export的)伤感传奇的真正主角是EDG编译器的实现者:Steve Adamczyk,John Spicer和David Vandevoorde。他们强烈反对分离模板编译,最后为达到最佳妥协投赞成票,然后花了超过一年的时候完成了他们所反对的东西。这就是专业!编译器的实现正如他的竞争对手所预测的那样困难。但它成功了并带来了一些好处,正如它的支持者所承诺的那样。不幸的是,由于一些对分离模板编译的必要的约束,因此承诺以因没能提供它们预期的利益并且让编译器变得更加复杂而告终。一如往常,在技术问题上的政客般的承诺导致了“滑铁卢之败”。

    9/26/2007

    C++0x简单指引

    以下按随意顺序,列出C++0x中的特性,即不全面,也不是挑重点。无责任摘编,呵呵

    ●写烦了begin()和end()么?来吧,看看这个


    sort(vec.begin(), vec.end());
    进化为
    sort(vec);

    ●写烦了std::vector<int>::const_iterator这样的东西了么?来吧,看看这个


    for ( std::vector<int>::const_iterator it = vec.begin() ; it != vec.end() ; ++ it ) {...}
    进化为
    for ( auto it = vec.begin() ; it != vec.end() ; ++ it ) {...} // 这东西从83年就开发出来了,一直没加入到标准中

    ●怎么,上面的写法还不满意?试试这个含有for each语义的东东

    进化为
    for ( int& a : vec )
        cout << a << endl;

    ●在嵌套模板书写的时候,对> >中间的空格感到无法忍受么?来来来,这里有一颗语法糖。

    typedef std::vector<std::vector<int>> int_2d_array;

    ●难道C++0x里都是这些小打小闹的玩意么?那么,来个大家伙看看:GC(废料收集),怎么样,够大吧?而且还是多种模式可选的语言特性,可以选择使用、不使用、部分使用……

    ●多核时代,晶体管的集成度增加,运行时脉不涨,如何适应这个并发的时代?

    C++0x在语言级提供多线程内存模型(规范编译器的行为)。这回,不会再出现使用了同步对象,但还是被优化给害了的情况了(比如寄存器优化和同步信号的加锁、解锁顺序,就有可能被编译器优化而破坏)

    据称,这东西基本上是从java那里借用来的成熟模型。反正C++标准委员会里面的人跟java的关系很亲近,用C++实现过java虚拟机的人就不下10个……

    ●STL里有了pair,可以装任意的2个元素,那么3个、4个怎么办?试试tuple,可以接受任意多个元素,任意类型。真是物美价廉,行销全国,远销海内外231个城市……

    ●从圆括号()的书写给人的暗示出发,将所有看上去能调用的东西都做成“函数”,于是出现了function。只要是能调用的东西,函数,函数对象,成员函数,这个function什么都可以装进去。

    ●写烦了各种函数对象?尤其是不能把局部类作为模板类型的讨厌限制?试试无名函数的这个“装嫩的老家伙”吧!

    lambda x;
    auto p = find_if(vec.begin(), vec.end(), x < 7);

    ●concept是什么?对这个东西没有概念?没关系,你只要会使用经过concept重写过的、更好用的库就行了。比如这样写:

    list<int> lst;
    sort(lst.begin(), lst.end());

    你再也不会看到一大堆不知所云的出错信息了(在gcc下长达2k),而是看到类似于“std::list::iterator is not a ramdom iterator”这样的报错信息。(list的iterator不是随机iterator,所以不能用下标访问,也就不能经过通用算法排序)

    当然,concept这东西能做的不仅仅是这些。如果你编过模板,就会明白,想要能够在语言中做到“对模板的参数类型提一个明确的要求”这件事有多么迫切了。通过concet,这件事就可以完美解释了,唯一不能做的是限制参数类型的成员变量(因为违反封装原则)

    有了concept后,tmp(模板的meta编程)也变简单了。

    ●写过模板,想要模板参数可变?对不起,你还是去编写大量的迭代宏吧(往往还要经过perl或python来生成)!在证明了C++模板是图灵完全的之后,宏又被证明是图灵完全的,为什么?被不完善的模板机制给逼的!

    还好,现在有了潘婷……哦,不,是有了variadic template。模板参数真正可变了。tuple/function之类的源代码这回可以减少到原来的1/10不到了——因为原来的多数代码仅仅是在为语言不支持的特性而代劳

    ●模板现在终于有了别名了,可以为模板起一个自己喜欢的名字——记得Java原来也有过别名:C++杀手,嘿嘿

    ●表达式可以萃取类型了,看看下面的这行代码

    typedef decltype(1 + 5.5) result_type;

    (嗯,我承认,上面这一小坨看起来比较SB……)

    ●对于表达式右面的东西,现在也可以引用了……相信我,这东西的价值远比这句话看上去要大得多(比如move语义的实现)。如果不信相我,可以去试着相信Bjarne Stroustrup(不熟悉C++的人念到这里都会卡壳,嘿嘿,一个著名的FAQ就是“Bjarne Stroustrup这个词怎么念啊”)

    ●大部头的东西看多了,来个实际点的,看看下面的代码:

    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(4);

    写着很烦,是不是?这东西现在演变成(或者即将演变成):

    std::vector<int> vec = { 1, 2, 3, 4 };

    实现的手段是“序列构造函数”

    ●说到大部头和小部头,module也算是一个相关的特性……

    ●unordered_map提供了哈希表的无序map。hash_map这个名字被非标准实现所占用的太多了,只好让路。

    ●C++0x中的“x”,到底会是数字几?

    原来一般认为是09,但是根据目前的情况来看可能会是08,甚至有小道消息说07年10月有可能出一个关键投票。C++标准委员会的人太少,都有正式工作,而且开会都是自掏腰包,资源太有限了。据说boost库明年能够拿到fund了……但愿那些受益于C++的N多个大型项目能够回报一点金钱给这个标准委员会。

    ●一句话概括C++?

    这问题,问得有点像娱乐节目。如果让我来总结,那我会说:有一种计算机语言,他的发明者,虽然站在了语言设计的最前沿,但是,他经常被迫向其他人学习如何使用这门语言,换言之,他不知道他的语言究竟能够做多少事情……这种语言,也是唯一的一种,就是C++

    ●再用一句话概括C++ 0x的特点?

    bingo,你猜对了,不是真的有人要问,是我还有话要说……

    C++的成长过程就像是一种民主的进化过程,效率虽然低下,但是各方各面照顾的相当周到。

    C++是很多东西(包括软件产品、工具和其它语言)的基础工具链,一定要考虑兼容和稳定,如果标准的制定者脱离实际并一意孤行,其结果,就像那谁谁谁说的:工业界会简单地对不合实际的标准置之不理……

    这次的修订,其实是在减少实际应用中的“包袱”,这些“包袱”是在过去的某个时间内,由大牛和牛魔王们,为了解决某些迫切的需要而发明出来的。从这层意义上来说,0x标准算是还了一些拖欠已久的债务。

    碰到了一个水平有点低的面试官

    最近正在找工作,接受了一些电话面试。

    其中,有一个人问我:inline函数可以是虚函数么?

    我一听就知道他想要什么样的答案。他需要的是否定的答案,大约想要的解释如下:“inline函数表明在编译期优化掉了,没有真正的函数地址,这样就不能出现在对象的vtable中”。

    但是,如果对C++语言了解得更多的话,就会明白,这个问题不是这么简单。因为虚函数也可以是静态绑定的,而inline关键字仅仅是“向编译器的一种建议”,不是硬性规定要内联化处理。所以这个问题就变得似是而非。

    于是我告诉面试官,inline函数只不过是一种指示,并不一定会被编译器采纳,如果你非要问我“带有inline关键字声明的函数能否是虚函数”,那么,我会告诉你,答案是肯定的,即“带有inline关键字的函数可以是虚函数”

    但是,从他的语气中,我能感觉得到,他并没有搞明白“带有inline关键字的函数”和“inline函数”这二者的区别。估计这个问题被他打了一个大大的红叉叉吧。

    模仿一下伊索寓言,结尾处写上一个“教训”:面试时不单单要讲技术,还要多多地揣测面试官的水平,否则肯定会自讨没趣。

     

    6/19/2007

    5-1+1竟然等于6

    VC编译器的BUG,(5-1)+1竟然等于6,嘿嘿
    extern int argc;
    extern std::auto_ptr<unsigned char> buf;
        buf.get()[1] = (argc - 1) + 1;
    0168429B  mov         ebx,dword ptr [argc]
    0168429E  add         ebx,1
    016842A1  lea         ecx,[buf]
    016842A4  call        std::auto_ptr<unsigned char>::get (1681451h)
    016842A9  mov         byte ptr [eax+1],bl
     
    5/27/2007

    我为什么学习了编程

    大约是小学3年级到4年级的时候,我从家里的大书架上翻出一本书,书名大概是《逻辑代数及其应用》,浅灰色的书皮,上面有很多类似电路的纹路,还印着好多算式,类似下面这样子:
     
    0+1=1
    1+0=0
    0+0=0
    0*1=0
    1*1=1
    0*0=0
    ……
     
    一看到这本书,我立刻就开始喜欢了——这本书里的知识真是太简单了!都是0和1,连2都没有哇!太好了,我就学它了!
     
    于是,就开始慢慢陷入了“英国人说谎话”和“法国人买机票”的一类的问题中……
    2/15/2007

    真的是搞错了……

    在一个QT的程序里,写了一个函数
    void foo(const wxPoint& testPoint) const;
    编译不通过,看报告,是编译器不认识wxPoint类型。

    好半天才反应过来……

    解决Visual Studio 2005 SP1编译QT代码的BUG

    产品:QT 4.1.4 & QT 4.2.2
    平台:Visual Studio 2005 Service Pack 1 (SP1)
    错误:error C2244: unable to match function definition to an existing declaration

    现象:
    在qmap.h头文件中出现:error C2244: 'QMultiMap<Key,T>::insert' : unable to match function definition to an existing declaration
    (据说在qhash.h中也会出现)

    参考URL:
    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100

    原因:编译器升级后,分不清嵌套类型的名字是指哪一个,哪怕它们很明显地是同一个类型。例如,如下代码就会引发此错误:

    template <class T>
    class Foo
    {
    public:
        typedef int NestedType;
    };

    template <class T>
    class Bar : public Foo<T>
    {
    public:
        typename Foo<T>::NestedType test();
    };

    template <class T>
    typename Foo<T>::NestedType Bar<T>::test() // this is where the error lies
    {
        return 0;
    }

    微软的解释:
    The problem is due to the use of Foo<T> and Bar<T> on the line above; the compiler cannot figure out the relationship between the two template parameters even though they are clearly the same. The workaround is to add a typedef for the NestedType of Bar and use that in the implementation of test

    解决方法:
    在子类型中再次定义嵌套类型的名字

    例如,对于QMultiMap,就是这样子

    template <class Key, class T>
    class QMultiMap : public QMap<Key, T>
    {
    public:
        /////////////////////////////////////////////////////////////////////////
        //Modified by Kenny
        //Purpose: fixed the compiling-time error of Visual Studio 2005 SP1
        //Ref:
    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100
        typedef typename QMap<Key, T>::iterator QMapIteratorType;
        //End of modification
        /////////////////////////////////////////////////////////////////////////
        QMultiMap() {}
        QMultiMap(const QMap<Key, T> &other) : QMap<Key, T>(other) {}

        inline QMapIteratorType replace(const Key &key, const T &value);
        inline QMapIteratorType insert(const Key &key, const T &value);

        inline QMultiMap &operator+=(const QMultiMap &other)
        { unite(other); return *this; }
        inline QMultiMap operator+(const QMultiMap &other) const
        { QMultiMap result = *this; result += other; return result; }

    private:
        T &operator[](const Key &key);
        const T operator[](const Key &key) const;
    };

    /////////////////////////////////////////////////////////////////////////////
    //Modified by Kenny
    //Purpose: fixed the compiling-time error of Visual Studio 2005 SP1
    //Ref:
    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=214100
    template <class Key, class T>
    Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap<Key, T>::QMapIteratorType QMultiMap<Key, T>::replace(const Key &akey, const T &avalue)
    { return QMap<Key, T>::insert(akey, avalue); }

    template <class Key, class T>
    Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap<Key, T>::QMapIteratorType QMultiMap<Key, T>::insert(const Key &akey, const T &avalue)
    { return QMap<Key, T>::insertMulti(akey, avalue); }

    //The old code is commented out as the following lines

    //template <class Key, class T>
    //Q_INLINE_TEMPLATE Q_TYPENAME QMap<Key, T>::iterator QMultiMap<Key, T>::replace(const Key &akey, const T &avalue)
    //{ return QMap<Key, T>::insert(akey, avalue); }
    //
    //template <class Key, class T>
    //Q_INLINE_TEMPLATE Q_TYPENAME QMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey, const T &avalue)
    //{ return QMap<Key, T>::insertMulti(akey, avalue); }

    //End of modification
    /////////////////////////////////////////////////////////////////////////////

     

    12/10/2006

    疑似为未来的网络流行语

    偶发明了一个词:
     
    mouse=貌似
     
    读音也很像,缩写也是MS。
     
    用法举例:
     
    mouse今天的天气很好啊!
     
    mouse你今天不高兴啊?
     
    不知道别人是不是也同样“发明”过,偶先写在这里,立此存照,嘿嘿
     
    发明这个词的时间大约是2006年11月20日左右。
     
    在2006年12月曾给大饼同志发短信时使用。
     
    在给朋友讲解此词的用法时,想到了写个BLOG存照的问题,呵呵,万一哪天这个词也发达了,mouse可以满足俺的虚荣心呢
    11/10/2006

    关于光盘粉碎机

    说到读取光盘碎片,你有多厉害?问问专家吧。美国能源部CIAC(计算机紧急事故顾问办公室)安全专家Bill Orvis说他可以读取0.16×1.25吋碎片上的数据。

    Bill用数学方式来解释:「光盘片上的数据都是以塑料(以塑料制成的)内的凹洞,或是不同颜色,或反光(可写入的光盘)点的方式储存。用高级显微镜或SEM(扫描电子显微图)就能够看见并读取这些点。光盘片轨道间的距离为1.6微米,因此,0.16吋碎片的宽度相当于4046微米,可换算成2540条1.25吋长的轨道。这里面就储存了许多数据。」
    这代表什么呢?没有人会想办法取得这些小碎片中的大量资料,只为了得到你的信用卡号码,因此这种机器很适合家庭用户和小型企业。不过,对大型企业就不太适合了,因为花工夫读取这些小碎片以取得价值数百万的项目资料是很值得的。所以这款装置不适用于储存机密数据的光盘片。

    Orvis说他看过的NSA级光盘销毁机会将光盘表面(存放数据的地方)磨成粉末,不过,其余部分完好如初,包括印有光盘序号的地方。Orivs说:「你可以确定数据确实销毁了。」
    11/7/2006

    Intel PXA系列CPU的视频播放能力(AVI)

    测试平台

    型号          HP iPAQ hx2490
    CPU速度        518 Mhz
    视频输出方式      DirectDraw 240x320 16bits
    使用软件        TCPMP 0.72RC1 Beta


    1)[星河战队高清].Starship.Troopers.1997.HDRip.XviD-TLF-CD1.avi
    视频大小        736x416 缩放至 178x316
    原始文件数据比特率   1.7 Mbit/s
    测量到的数据比特率   1.8 Mbit/s
    平均速度        104.20%

    2)[X战警3.最后之战].X-Men.The.Last.Stand.TC.XviD-ASTEROiDS.avi
    视频大小        640x272 缩放至 136x320
    原始文件数据比特率   1.4 Mbit/s
    测量到的数据比特率   2.3 Mbit/s
    平均速度        168.49%

    3)[PRIDE-FC美国首战].Pride.FC.The.Real.Deal.2006.PPV.DSRip.XviD-KYR.cd1.avi
    视频大小        512x384 缩放至 236x312
    原始文件数据比特率   1.1 Mbit/s
    测量到的数据比特率   1.3 Mbit/s
    平均速度        123.81%

    10/19/2006

    找到Windows(R) XP的一个BUG

    虽然叫得响,说Windows(R) XP有多少多少个BUG,但我等普通人,一般是很少能碰到的
     
    今天我找到了一个明显的
     
    单击“开始”按钮,在“开始菜单”弹出的时候,点击屏幕右下角的系统通知区。这时你的单击操作会变为双击操作。而且,除“日期/时间”那个区别之外,点击所有的图标都只会被当成点击同一个图标,这个图标就是你上次使用过的图标。比如你上次使用了MSN Messenger的图标,那么这时候你点击任何一个图标,就相当于双击了MSN Messenger的图标。
    1/1/2006

    如何从光盘镜像中查看Visual Studio 2005版本

    以英文版为例:
    1)打开以下文件:<CD Drive>:\vs\_267_RTL_x86_enu_Core_IDE_VS7.cab
    2)解压此文件中的文件FL_devenv_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8,然后重命名为devenv.exe
    3)查看其版本,比如:8.0.50727.42 built by: RTM
    12/28/2005

    IT业界五大失误

    毫无疑问,当今的IT行业拥有世界上最多的天才,微软的比尔、苹果的乔布斯、Google的拉里佩奇等等都是其中的佼佼者。但天才有时也会犯错误,通常来说,绝顶聪明的人的失误和他的成功一样,都比普通人“伟大”得多。 
    下面就让我们一起来倒数由美国的权威商务网站RED HERRING新近评出的IT业界五大失误:
    第五位-施乐:与个人电脑时代擦身而过
    世界上第一台拥有图形界面、鼠标的电脑是由哪家公司研发的?相信大多数人的答案是苹果公司。正确的答案应该是打印巨头施乐,事实上当施乐的Palo Alto研究中心在1973年开发出一台具有图形界面、以太网功能、所见即所得的文本编辑器和鼠标的名为"Alto"电脑时,苹果公司还没有诞生。
    不幸的是,这个成果并没有引起施乐高层的重视,直到六年后乔布斯第一次见到"Alto",于是,有了苹果公司后来风靡全球"Lisa"和"Macintosh"......
    第四位-AT&T :早起的鸟儿找不到虫子
    我们先来回顾一下在九十年代初期AT&T所拥有的一些网站:ImagiNation网络,一个多人在线的游戏网站;PersonaLink,为无线设备提供在线信息的网络服务供应商; WorldNet,AT&T的ISP网站。可见那时的AT&T已经有了目前最流行的三种网络服务,可惜的是并没能坚持到网络浪潮的来临。
    第三位-Gary Kildall:错失IBM的世纪定单
    1980 年,当蓝色巨人为它的个人电脑寻找操作系统的时候,刚刚成立微软的比尔推荐了Gary Kildall开发的CP/M系统,可是Kildall先生当时正驾驶着私人飞机在天上飞翔,他的妻子接到了电话并自作主张地拒绝了IBM的定单。被拒绝的IBM最终选择了微软的DOS系统,也由始开始了微软的传奇故事......
    不知道可怜的Kildall先生是否知道中国有个成语-红颜祸水!
    第二位-Lotus:搭错车
    在八十年代中期,Lotus是办公软件市场无可质疑的领头羊。当时Lotus面临着二个选择,一是为IBM的OS/2操作系统开发应用程序,另一个就是微软的Windows系统。
    Lotus选择了如日中天的IBM并按照合约停止为微软开发软件,于是微软只好只行开发基于Windows的办公软件,聪明的读者一定猜到了,是的,这个就是后来的Office办公系统......
    第一位-雅虎:对Google说“不”
    1998年,当时还没有创建Google的Page和Brin致电雅虎的二位创始人之一的David Filo表示想把他们开发的搜索引擎技术转让给雅虎。Filo回应说:“这个技术还不成熟。”
    于是,Google出现了并在短短几年内成为了全球最大的网络搜索引擎提供商……
    12/26/2005

    使CVS忽略文件和目录

    使CVS忽略文件和目录
    使用目的:在使用cvs up命令时不对文件和目录显示问号
    测试环境:CVSNT 2.5.01 (Travis) Build 1976 (client/server), Windows XP Prof En SP2
    命令格式:#<file or foler name>[<.ext>]
    使用方法:在文件命名中加入#cvsignore字串。
    基本原则:
    1、文件名以井字符号(#)开头,其它部分任意
    2、扩展名任意
    3、对文件和目录均有效
    使用范例:
    1、#debug_record.txt(文件)
    2、#bin(目录)
    3、#doxygen.output(目录)
    4、#log.txt(文件)
    5、#lib.DEBUG(目录)
    应用案例:
    1、将Bin目录(下设Debug和Release目录)重命名为#bin.cvsignore以避免cvs up时的问号
    2、将doxygen的输入目录命名为#doxyhtml.cvsignore以避免cvs up时的问号
    (加入cvsignore是为了使文件夹的意义清晰易读)
    12/23/2005

    C++震撼系列——实现纯虚函数

    也许为一个纯虚函数编写函数体并调用它的做法会给你带来冲击,但是,请相信我,C++标准中是允许这么做的。
    不要报怨C++标准,我的经验是:如果你认为标准有问题,那么就先找找自己的问题(总有一天你会意识到是自己的问题)

    声明一个函数为纯虚并不是说它不能有实现,它的意义为
    1、带有这个纯虚函数的类是抽象类(不能生成对象)
    2、任何从此类派生的类,如果不将此函数声明为一个“普通”的虚函数(不带=0),那它将仍然是一个抽象类
    3、所有规则到此为止,再没有其它的含义了
    下面是一个例子:


    /// 抽象基类
    class Abstract
    {
    public:
        Abstract()
            : buffer_(new char[256])
        {
        }

        virtual ~Abstract() = 0
        {
            delete [] buffer_;
        }

    public:
        virtual void Foo() = 0
        {
            std::cout << "Abstract's pure virtual func called" << std::endl;
        }

    private:
        char * buffer_;
    };

    /// 实现类Final
    class Final
        : public Abstract
    {
    public:
        Final()
        {
        }

        virtual ~Final()
        {
        }

    public:
        virtual void Foo()
        {
            Abstract::Foo();
            std::cout << "Final's virtual func called" << std::endl;
        }
    };

    /// 客户代码
    int main(int argc, char* argv[], char* enpv[])
    {
        Final* f = new Final();
        f->Foo();

        return 0;
    }

    输出结果是:
    Abstract's pure virtual func called
    Final's virtual func called