小不点猪居然抠了一个晚上的手指头

    躲在后面桌子上,抠了一个晚上手指头,7:00我看她看到206页,刚才一看,居然看到204页了,真拿她没办法,^_^
    这几天都没让她吃肉,晚上买了个油饼给她吃,后来抢了她1/3吃了,俺要让她体会劳动之辛苦,革命之不易。

[转]小说《输赢》之序

人生本是过程,结果并不重要。

一位老人带着爱犬行走在乡间小路,看着沿路的风景,突然间老人意识到自己已经离开了人世。他不知道这条路通往何方,只是茫然地向前走着。走了一段路程,只见前面高耸着大理石的围墙,围墙的中间是流光谥彩的拱门,上面装饰着各种珠宝,门前的道路由金砖铺就。老人兴奋不已,他想自己终于到了天堂,带着狗走到门前,遇到了看门人。

“请问,这里是天堂吗?”老人问道。
“是的,先生。”看门人回答。
“太好了,里面一定有水喝吧?我们已经赶了很远的路。”
“当然有,进来吧,我马上给你水。”看门人缓慢地推开大门。
“我的朋友可以一起进来吗?”老人指着狗问。
“对不起,我们这里不允许宠物进入。”

老人沉默了一会儿,想到狗多年来对自己的忠诚,自己不可能这样扔下它。他谢过看门人,带着狗继续前进。长途跋涉之后,老人看到路边破烂的木门,通向木门的是坑坑洼洼的土路。老人带着狗过去,看见一个人在树下看书。“打扰一下,”老人对看书的人说:“请问,你这里有水喝吗?我们很渴。”

“当然,那边有水龙头,你可以喝个痛快。”看书人指着门内说。
“我的朋友可以进去吗?”老人指着自己的狗问。
“欢迎。”看书人说。

老人带着狗进了大门,老式的水龙头旁边有一个碗。老人先用碗盛了满满一碗水,让狗喝个痛快,然后自己又重新加满,也喝了个够。他们满足地离开水龙头,回到看书人的旁边。 
“这是什么地方?”老人问。
“这里是天堂。”看书人回答。
“呃,这可奇怪了,这一点也不像啊,而且我们刚路过天堂。”
“你说的是那个黄金铺地、有漂亮的拱门的地方吗?”
“对,那里非常漂亮。”
“告诉你吧,那是地狱。”
“原来这样,你为什么不介意他们盗用天堂的名义呢?”

“当然不,他们为我们省了很多时间,替我们把那些为了自己利益而舍弃自己良心和原则的人都挑走了。”

签约趋势

       上午面完回去,12:20就收到趋势hr电话,叫我下午2:00带三方协议书去五月花签约,当时我跟小不点猪在百味小吃城吃饭,以前我答应她去北京,后来说服她去上海,结果却要去南京,她一听到这个消息,就非常生气。
       的确,我当初没有想过去趋势,原因有二,一是之前面过nsfocus,感觉去趋势,还不如干脆去nsfocus算了,另外,是因为我趋势笔试的确考得太烂了,当时根本就没有考虑趋势会给面试。所以一直没有把趋势列入计划中,一直在准备autodesk。
       这两天一想,其实趋势更适合我,趋势正处于发展期,技术范围包括windows、linux平台,c/c++多个方向,而autodesk的产品已经很成熟,技术范围仅限于windows平台,c++方向。我当然更倾向于更宽泛一点的技术路线,^_^。
       趋势是计算机+通信,而autodesk就是计算机,我当然想尽量留在通信行业咯,^_^,更何况,autodesk要2个礼拜以后才能出结果,我等不起。
       要签趋势,当然首先要说服小不点猪,我的话她向来不听的,我只好求助于她妈妈。小不点猪把我的就业协议书藏起来了,后来被她妈妈说动,才把协议交出来,这个时候已经快1:00了,我匆忙忙的赶上公交,去了五月花。小不点猪真可爱,^_^。

       上去1018之前,刚好碰到alias张,他说我今天面试表现非常不错,看来我的判断没有错,趋势需要的,不是中庸的人。签约的过程看似神圣(毕竟是我有生以来第一次签聘任协议书),其实平淡;找工作的过程看似漫长,其实也不过2个星期。我要做的,就是看着前方,相信自己的判断!

       这次趋势招聘在武汉录了5个人,华工3个,都是电信系的,其他2人估计会去做qa,我应该会去做r&d;武大2个,都是计算机的;还有2个华工计算机的,是上次趋势百万程序设计大赛的,他们被提前录取了,所以总共在武汉录了7个人。

       晚上趋势hr请我们在巴山夜雨吃饭,celebrate我们的相聚,我们喝了47瓶酒。趋势有个传统,就是在同事聚会的时候,都要带上自己的另一半,他们认为家属的认同,其实也是趋势能够留住人才的一部分,我深深的认同这一点!在他们的强烈要求下,我们把自己的男/女朋友叫过去了,小不点猪晚上9:00多才打车过去,看到我喝得通红的脸,甚是心疼,但同时看到趋势员工真诚的态度和优雅的风度,她也对趋势变得满意起来了。
       三位趋势员工中,一位alias张,台湾人;一位是r&d的老大,也可能是我以后的上司,他是我第一面的面试官,他说第一次面我,就知道我肯定可以过关斩将,拿到趋势offer,为了他的赏识,我喝了好几杯;还有一位是老大的老大,john李,经历非常丰富的一位,他提到两点,其中一点是,everything is philosophy,什么事情都是哲学,他叫我们要学会取舍,得到什么,必定会失去其他东西,这也可以成为我放弃nsfocus和autodesk,放弃北京和上海的很好的注脚。
       明年的7月,我就会成为趋势一员,期待着与趋势共同成长,也希望我能在最后一段时间内,为团队贡献我的所有才智和精力!

trendmicro三面

        今天的面试是小组讨论,一共6个人:3个华工,3个武大;3个计算机专业,3个通信专业;1个女生。
        首先是英文的自我介绍——3次面试中唯一的一次——我说得有点紧张,中间居然还有几秒钟的停顿,不过他们似乎不在乎这个,这是最令我满意的地方,我一直觉得英语这东西只要有语境,肯定可以说好的,只有那些招熟练工的企业,才会那么追求英语。而且趋势也几乎不问技术,而仅考察是否适合他们公司的文化,这一点也是趋势的魅力所在。
        讨论题是设计一个technical solution,去抵御针对企业内部网络的target attack。我们都不是安全行业的,所以我们都不知道target attack到底是什么,只好认为是一个黑客攻击,然后就开始讨论。
        我们小组的人看上去都很谦虚的样子,所以,我一开始就觉得我肯定可以成为最终的核心(最后要有一个人上去讲解小组的讨论结果)。我们首先审题,大家都审不出个所以然,干脆就认为黑客攻击,大家开始提方案,有很多方案,有的说从远到近,有的说根据网络5层模型,逐层考虑……。我提的是根据企业内部网络的物理结构,在各个环节上进行部署(其实nsfocus和深信服做的就是这个),企业内部网无非就是一个网关,然后有很多主机躲在网关后面,我们分别在网关和主机上部署一些软件,防止黑客攻击。大家似乎对我这个思路有点感觉,然后大家就各自发言,丰富网关和主机端能够做的事情。比如在网关上可以进行:端口/IP过滤(我现在做的RCP项目就搞这个的,^_^);统计流量,对流量过大的源、目的主机进行限流;对通过网关的内容进行检查,防止敏感数据外流……主机端的措施包括:装杀毒软件,防止木马……
       时间到了,大家推举我上去讲解我们的方案,我基本上比较流利的表达了我们的思路,我不经意间举了个百度被黑的例子,以说明统计流量的重要性,评委们听到这个例子,都笑了起来(待会儿就知道为什么了)。在讲解过程中,我特别注意了一些词汇的运用,比如不要说“我的方案” ,而应该说“我们的方案”,讲解的过程中和讲解完以后,都尽量征求大家的意见,这些细节不是做作,而是团队精神的体现。另外,要特别注意讲解的思路,先讲什么后讲什么要打好底稿(我差一点在这方面犯了错误),这一点dian团队的同学们是不会有问题的。当然,个人自信非常重要,特别是面对趋势科技这种公司的时候。
       我们组队员后来补充了几点,但整个方案我应该都讲出来了,我想这就足够了。
       接下来是接受评委提问,john李对我们最终的结果不是很满意,他说其实我举的那个百度被黑的例子非常好,但为什么不事先跟组员说呢,我答:“我们在座没有一个计算机安全的,所以我也不敢确定百度被黑就是target attack”(够坦诚吧?我觉得真实的回答很重要,乱扯理由还不如说实话)。john李又问了一个问题:“你们的讨论是怎么分工的?”,我答:“由于我们对信息安全非常不熟悉,所以我们先是思维碰撞,然后大家选出一个大家都能够认同的方案,然后再分工细化……”。alias张问了我旁边一个同学一个问题,然后唯一的一位hr mm问了我一个问题:“yqh,我刚才看到你在跟大家说:‘大家还有什么问题’(这是我在我们小组例会上经常问的问题,^_^),我感觉你有点team leader的味道,请问你,如果你还有机会做一次这样的team的leader的话,你觉得你还有什么地方值得改进?”我答:“由于我们都不是信息安全专业的,所以我自己也不能甄别大家提出的方案哪一个更好,即使百度被黑是一个很好的例子,我也不能确定,这在一定程度上影响了我们今天讨论的效果,如果以后还有机会和大家一起合作,我希望自己能够先具备这方面的专业知识,这样我才能做到更好”。

       最后让我们互相评价,并且选出2个你最希望合作的人,我瞥见我对面的人的答案里面有我,窃喜,^_^

       回来的路上我想,要是趋势也像华为中兴那样“掐头去尾”,那我肯定挂了,因为我肯定算个头。但我想,今天的题目其实很简单,评委也根本不会关心最终结果,他们关心的是每个人所处的角色和讨论中所起的作用,趋势的企业文化是4C+T(creative、changable、communication、customer、trustworthy),所以,我相信他需要的是出头的人(所以,面试之前了解好企业文化,是必须的!),而不是中间和尾巴上的人,我被录的几率是70%。

trendmicro二面

    今天面我的是两个中年人,依然没有english,令我好诧异!
    我依然保持我的风格:点到为止,决不多说话。
    问:为什么不选择南方(因为我是湖南的),
    答:好男儿志在四方,趁着年轻到处闯一闯;
    问:为什么选择南京(长三角),而非京津唐工业区?
    答:这是鱼和熊掌的关系,我没有特别的要求;
    问:对CMM流程感触最深的一点是什么,要求非常简短的回答
    答:review
    问:第二点呢
    答:流程/文档
    问:平时都有什么爱好?
    答:篮球
    问:打什么位置
    答:组织后卫,point guard
    问:对组织后卫有什么感觉?
    答:组织后卫的主要责任不是得分,而是为队友创造得分机会
    ……
    问:面临一个新东西的时候,你一般如何搞定他,举个例子!
    答:……(我举的是我10天搞定linux下pci驱动的问题,强调团队合作,强调交流)
    问:作为team leader,如何分配任务?
    答:按功能分配,让一个人稍微固定的做同一个功能,并且通过review的方式,使他了解更多模块,互相学习。
    问:你觉得你笔试题做得怎么样?
    答:坦诚回答,做得很烂,尤其是IQ题和英语阅读理解,而且我做错了那道链表就地逆序题
    问:那你对链表就地逆序现在能做出来吗?
    答:可以!然后就跟他比划了一把,把算法写出来了(这是面试趋势过程中唯一一次涉及技术,^_^)。
    刚进去的时候,有个高个子(后来知道,他叫john,姓李,因此称为john li)对我好像还有点冷淡的样子,等到我出来的时候,他的态度已经转暖了,还特地提醒我他们的三面通知是在晚上8:30-9:00,看来有戏!

trendmicro一面

    今天去了趋势一面,就着简历泛泛的问,没有什么技术难点,问的问题也比较简单,我觉得自己答问方面时间把握还可以,每个问题都恰好答到他觉得可以了为止,没有那么多废话。
    但我觉得我似乎有点太强调自我了,即使当过项目组长,即使自己很牛,也不要老是以“我”来叙事,例如:“在我的小组……”,“我的技术基础很宽泛……”,这样容易造成人家反感,如果今天面挂了,那这肯定是罪魁祸首。以后要注意一下!

记录一下找工作的历程

    找工作到今天,也有一段时间了,从最开始与nsfocus互送秋波,到后来婉拒nsfocus,再到trendmicro笔试,后来zfan推荐我到MS-ATC做了一场笔试,再到笔试autodesk,随后收到MS-ATC的据信,再到今天,焦急的等待autodesk的二面通知……
    整个过程,我一直很平静。nsfocus是我不忍拒绝的一个公司,也许我应该给他发封据信了,告诉他我已经自断后路。虽然我现在还没有着落,但这样的据信真的能够给我一个心理安慰,就算是惩罚自己好了,因为nsfocus太真诚了,我不想伤害他,不想伤害marbai和wguangdi。
    明白说,我只是拿trendmicro练练手的,去trendmicro还不如去nsfocus,trendmicro笔试的细节已经记不得了,被他一堆iq题、英文阅读理解和网络安全方面的问答题(ex:vista的哪些新特性增强了它的安全性)搞晕了。
    MS-ATC是我本来就没有打算去的,不过既然有机会,还是要准备一下,临考前的晚上9:30收到笔试通知,第二天早上8:00就要笔试,当时我正在hyxxl那里调试DSP程序,当即丢下手中的事情,回到实验室把简历准备了一下,顺便再做了几道智力题——早就听说微软智力题超级变态了——准备只限于这些了。笔试题有三道,分别适于software development engineer、software development engineer in test、pm,一个小时时间,我只够做software development engineer那一道,题目很简单,就是要你在一个整数数组中找出所有重复的数字,并填到一个链表中,要求用三种不同的算法/数据结构,在算法方面我只能说黔驴技穷,虽然写了三种算法,但都是用遍历的方法,最多在元素排序、增加标记位方面做些手脚,出来以后,dingwei提到HASH,有种大彻大悟的感觉,但已经悔之晚矣!后来收到ATC的据信,也就完全可以理解了。
    算法是我软肋,我经常自嘲,我不适合那种算法题,我比较适合做题量很大的试卷,甚至能够既有硬件,又有软件那就更好了,因为我的优势在于我的全面,要是太拘泥于某一个算法,而且只有一道题,那我估计死定了,^_^,所以,当我看到autodesk的题目时,我真的有点开心了,^_^
    13日autodesk笔试,12日我在寝室做了一天笔试题,专门针对autodesk,虎哥当时已经拿到中兴offer,正在犹豫是否签,看到我这么投入的做题,冷不防迸出一句:“终于看到教头开始找工作了”,^_^。当时我有一道题目没有做出来,题目大意是要你定义一个模板min函数,要求对const char*也适用,我当时问虎哥,他也不知道,结果第二天刚好考了这个题,我只能望题兴叹了,当时好后悔(其实这就是c++中的一个简单的特化问题,c++ premier中有叙述的)。我还准备了很多平面几何中的证明题,比如求线段是否相交、点乘、叉乘之类的,总的来说,我真的打算对autodesk孤注一掷了。   
    autodesk笔试题量真的很大,而且几乎牵涉到c/c++的所有重要方面,不过我唯一觉得不够的就是时间,一个基于模板的队列,写了满满2页纸,还有一堆写copy assignment、copy constructor的东西,还考了一堆vptr、vtbl的问题,看来《C++面向对象模型》没有白看!幸亏时间控制得还可以,而且越做越流畅,到最后甚至把那道我甚至已经放弃的算法题搞定了,题目是:把一个二叉树中所有节点的左指针,指向他的父亲,右指针指向他的左孩子,树的根节点的左指针赋为NULL。
    我对autodesk抱有很大期望,我喜欢2d和3d,我喜欢建筑,回想小时候,我经常在家里的晒谷坪上打个小棚子,然后跑到下面去躲太阳,甚至会跑到山上去挖个洞,梦想着过野人生活,^_^,一个人的履历是最终会觉得他的生存路径的,也许瞑瞑中早就注定,我不会留在通信行业。我喜欢coding,我喜欢software engineering,即使以后不能在做嵌入式,我也会义无反顾的!
    PS:已经收到trendmicro的面试通知,下午就是面一把,全当练练嘴巴吧,^_^

组合问题的解决方案——回溯法

       回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一枚举和检验。当发现当前候选解不可能是解时,就选择下一个候选解;倘若当前候选解除了还不满足问题规模要求外,满足所有其他要求时,继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。扩大当前候选解的规模,以继续试探的过程称为向前试探。

       回溯法的一般流程和技术

       在用回溯法求解有关问题的过程中,一般是一边建树,一边遍历该树。在回溯法中我们一般采用非递归方法。下面,我们给出回溯法的非递归算法的一般流程:

       在用回溯法求解问题,也即在遍历状态空间树的过程中,如果采用非递归方法,则我们一般要用到栈的数据结构。这时,不仅可以用栈来表示正在遍历的树的结点,而且可以很方便地表示建立孩子结点和回溯过程。

      【问题】 组合问题

       问题描述:找出从自然数1,2,…,n中任取r个数的所有组合。

       采用回溯法找问题的解,将找到的组合以从小到大顺序存于a[0],a[1],…,a[r-1]中,组合的元素满足以下性质:

       (1) a[i+1]>a[i],后一个数字比前一个大;

       (2) a[i]-i<=n-r+1。

       按回溯法的思想,找解过程可以叙述如下:

       首先放弃组合数个数为r的条件,候选组合从只有一个数字1开始。因该候选解满足除问题规模之外的全部条件,扩大其规模,并使其满足上述条件(1),候选组合改为1,2。继续这一过程,得到候选组合1,2,3。该候选解满足包括问题规模在内的全部条件,因而是一个解。在该解的基础上,选下一个候选解,因a[2]上的3调整为4,以及以后调整为5都满足问题的全部要求,得到解1,2,4和1,2,5。由于对5不能再作调整,就要从a[2]回溯到a[1],这时,a[1]=2,可以调整为3,并向前试探,得到解1,3,4。重复上述向前试探和向后回溯,直至要从a[0]再回溯时,说明已经找完问题的全部解。按上述思想写成程序如下:
[color=Red]
/* m代表可选数字个数,从1开始[1…m],r代表组合数字的个数 */
void combine3(int m, int r)
{
    int *a = new int[r];
    memset(a, 0, r * sizeof(int));
 
   
a[0] = 1;
    int i = 0;
 
    while (1)
    {
        // 达到规模,输出结果
        if (a[i] – i <= m - r + 1)
        {
         if (i >= r – 1)
         {
             for (int t = 0; t < r; t++)
             {
                 cout << *(a + t) << ;
             }
             cout << endl;
    
             a[i]++;
    
             continue;
         }
     }
  
     // 满足条件,因而扩大规模
     if (a[i] < m && i < r)
     {
         i++;
     }    
     else
     {
         if (i == 0)  // 退出
         {
             break;
         }
         else if (i > 0)
         { 
             a[i] = a[i – 1] + 1;
             a[–i]++;    // 回溯
         }   
     }

     // 组合数字肯定有序
     if (a[i] <= a[i - 1] && i > 0)
     {
         a[i] = a[i – 1] + 1;
     }
    }

    delete a;
}

int main()
{
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int b[8] = {0};
 
   
combine3(10, 2);
 
    return 0;
}
[color]

autodesk一面面经

    这是我自nsfocus面试以来,第一次参见面试,感谢adk给我这个机会,为了保密,这里用adk代表我面试的这家公司。
    中午一觉睡醒,收到了adk工作人员的电话,让我晚上8:30到卓刀泉大厦面试。我很高兴他在我睡完午觉之后才给我电话,不然我这午觉估计要失眠了,^_^。
    adk是我等待已久的公司,所以准备也要充分点了。我找marilyn借了notepad,把标记机软件上层装上,因为这是与他们公司岗位最接近的一个项目,我还把cactus留在我这里的样标全部拿上,到时候给他们一点印象也是好的,^_^。
    7点多,我就到了酒店,足足早到了一个多小时,看了还是面试经验不够,卡时间没有经验。我跑上12楼,发现一个人都没有,以为走错地方了,打个电话叫cactus帮忙确认了一下,这才安心的跑到楼下大厅里面去等。到了7:50,匆匆跑进来一个女生,一看我就知道碰到同路人,轻松聊了几句,上去之前她居然先说了good luck,呵呵,看来我应该再绅士一点,^_^。
    8:20,我把marilyn手提打开,把软件准备好,想着马上要进去了,节省点开机时间。但很不幸,到了8:30,那房间还是一点反应都没有,这个时候有位在隔壁房间面试的仁兄,直接跑过去敲门了,里面出来一个面试官,我趁机上去询问一下我们那房间是不是有人面试(因为我从来没有看到里面有人出来过),那位面试官要我再等等,最好不要敲门,以免打扰人家,^_^,幸亏没有直接上去敲门。
    等到8:50,我先把手提关了,我怕电池撑不住。这时隔壁房间被面的一个男生出来了,小聊了几句,他是计算机的(adk是软件公司,估计来面试的大多数都会是计算机的),他很郁闷的样子,说那些面技术的都超级变态,c++把他问得一句话都没的说,我问他问哪些问题,他说简历上写了什么,就问什么,比如windows编程、c++等等,他说他对这两项写了精通,^_^,我知道问题的症结了。
    那人一走,我就过去敲门了,门开了,里面传来女生爽朗的笑声,晕啊,这些人难道海聊上了?害我等了这么久,出来的面试官叫我再等一会儿,还没完,虽然有点失望,但总归看到希望了,那就再等等吧……
    大概9:10,我进去了,面试官是两位男同胞,一个干瘦,一个微胖,一个颧骨突出(就像我这样),一个圆头圆脑。他们先看简历,看到项目经历,来了一句,你项目还蛮多的啊(我心中窃喜,^_^),我知道他们肯定会把落脚点放在“标记机软件上层”项目上,因为我已经把土土的“标记机软件上层”改名为“振镜标记机二维CAD软件系统”,而且把CAD狠狠的加粗了,adk不看这个还看啥呢?我还告诉他们我已经把这个软件带过来了,如果有时间,想请他们指点指点。
    他们先让我把CAD软件系统的类图绘制出来,我稀里哗啦把DocContainer、State、Command画上了,然后他们要我介绍这些类之间的协作关系。接着要我解释一下MFC中如何实现splitter窗口,我老实交代,对这块知之甚少,我只能说个大概,也许是先将一个framewnd分成两个子framewnd,然后再在子framewnd里面包容view什么的……不敢咬定一定正确,但我希望自己的回答能够体现自己对frame->view->doc的理解。他们对这个情况表示理解,紧接着他们问了一个文件依赖关系的问题,大概情况就是,有三个类:A、B和C,他们的定义大概如下:
    
    A.h:
    #include "C.h"

    class A
    {
         C *m_pC;
    }

    B.h:
    #include "A.h"

    class A
    {
         A m_A;
    }
    

    他问我如何减少上述代码中的文件依赖关系,并说明原因。我说可以把A.h中的#include "C.h"替换成class C;因为A.h只需知道C的定义即可,不需要知道C的实现,而B.h定义一个实例,编译的时候势必要去找到A的构造函数的入口,因此必须保留A的实现。他对这样的回答貌似比较认可。

    接下来要我写strcpy,这个好经典,一下子写完了,他们比较认可,但我稀里糊涂的把函数头写错了,应该是:
    
    char* strcpy(char *des, const char *src);
    {
        if(des == NULL || src == NULL) return NULL;
        while((*des++ = *src++) != �);
    }
    

    我把const写漏了,不过他们一提醒,我马上改过来了。其实犯错误不要紧,关键是要体现你对知识的掌握程度和你的思维能力,我改过来以后他们还是非常认可的,但我知道我写的里面还是有个漏洞,那就是没有判断des == src的情况,这种情况应该直接返回des,以免不必要的开销,不过这一点他们没有提。
    接下来要我写memcpy,我的答案是:
    
    void memcpy(void *des, void *src, size_t len);
    {
        if(des == NULL || src == NULL) return NULL;
        while(len– > 0)
        {
            *((char*)des) = *((char*)src); des++; src++;
        }
    }    
    

    他让我考虑异常情况,我想到了覆盖,一种情况是des + len > src && des < src的情况,这种情况上面代码应该是可以搞定的,但我当时有点蒙,想错了,觉得似乎有问题,他看我有点困难,就直接告诉我这种情况不存在问题,他让我考虑另一种情况,也就是src + len > des && src < des的情况,这样显然是存在问题的,我一看,迅速反应过来,这种情况应该反过来拷贝,他对我反应速度比较满意,然后就让我写代码了:
    
    void memcpy(void *des, void *src, size_t len);
    {
        if(des == NULL || src == NULL || des == src) return NULL;
 &nbsp
;      if(des + len > src && des < src)
        {
            des += len; src += len;
            while(len– > 0)
            {
                *((char*)des) = *((char*)src); des–; src–;
            }
        }
        else
        {
            while(len– > 0)
            {
                *((char*)des) = *((char*)src); des++; src++;
            }
        }
    }   
    

    我问他这代码怎么样,他说能回答到这一步已经很不错了。   
    再接下来,他又出了个问题,要我用排列的方式打印出1-9九位数,各个数字只能出现一次,不能重复。我问他,是不是要考虑时间复杂度,他说先按自己的思路写个程序再说,我第一反应就是一个9重for循环,这是初中老师交的,^_^,第1个数有9种可选方案,第2个数有8种可选方案……依次类推,就是9重循环。他就提问了,说这9重循环一点扩展性都没有,让我想想办法,他提到9重和8重有什么区别,我一下子就想到了递归,他很满意的说,那你写个递归看看,我写了一段伪码:
    
    void display(int a[], int size)
    {    
        if(size > 0)      
        {
            for(i = 1; i < N – m; i++)
            {
                在数字数组中找到一个没被用到的数字;
                display(a[], size – 1);
            }
        }
        else
        {
            printf 数字数组;
        }
    }
    

   
    调用者这样写:
    
    main
    {
        int a[N];

        for(i = 1; i < N; i++)
        {
            将a数组所有元素清为 N + 1
            a[0] = i;
            display(a, N – 1);
        }
    }
    

    他叫我分析这个算法的复杂度,我想了20秒,写了个O(m!),他说不对,按我这种算法,他觉得应该是O(m * m!),他问我m来自于哪里,我用了2秒钟时间告诉他,这个m应该花在“在数字数组中找到一个没被用到的数字”上。他然后就似乎比较满意了。其实面试官要搞死你很简单(我就还没碰到过搞不死的本科生,^_^),关键是体现自己对知识的掌握程度和思维能力(网上很多人都是这么说的,^_^)

    问完了算法,估计他们觉得再问也没什么意思了,就回到c++上面,就着我做的卷子问问题。他先问了一个sizeof的问题,大概就是:
    
    class A
    {
        A();
        virtual ~A();
    }
    class B : public A
    {
        char buf;
    }
    

    他问我sizeof(B) == ? 我画了个内存映像图,然后告诉他是8,他比较认可这答案,我刚刚在vc里面测试了一下,的确是对的。他注意到我画了个虚函数表,就问我虚函数表是一个类共用还是每个对象都有一个,我答是一个类共有。不过这里还是有个未果的问题,那就是c++如何实现dynamic_cast,利用的是什么信息,我答到用的是虚函数表,虚函数表中有一个指针指向基类的虚函数表,这个好像答错了,还得好好钻研一下。

    最后两个问题是设计模式的,问我strategy模式和template method模式的区别,我说了一堆,可惜最后没有坚持,因为我对template method不是很熟悉,其实我说的应该是对的,结果却自己把自己否定了,唉…..败笔!
    另一个设计模式问题,他让我画出我们系统用到的composition模式和command模式综合运用的例子,我画了一个cut = copy + delete的例子,总算挽回一点面子,^_^
    到这时,应该已经面了一个小时了,估计他们觉得时间不够了,最后叫我随便说几句英语,介绍一下我做过的项目和跟组员交流的体会,我大概说了5分钟,中间没有忘记把样标拿出来给他们展示,并且用english跟他们介绍,他们非常感兴趣的样子,^_^。

    最后让我问了2个问题,我表示很可惜没有把软件演示给他们看,他们说,不用看软件了,看我画出来的UML图和打出的样标,就已经很好了,最后一句话是:“我们对你做的东西很感兴趣”,希望这不是一句安慰我的话。

几种递归算法

1. 递归逆序打印字符串
void reverse(char *s)
{
     if(*s != �)
    {
        reverse(++s);
        putchar(*(s-1));  // 巧妙的利用栈的先进后出的特点!
    }
}

2. 递归方式将链表逆序
// p 为指向非空单链表中第一个结点的指针,本算法逆转链表并返回逆转后的头指针。基本思路是:如果链表中只有一个结点,则空操作,否则先逆转a2开始的链表,然后将 a1联接到逆转后的链表的表尾(即a2)之后。
LinkList reverse(LinkList p)
{
    if(p->next == NULL) return p;   // 链表中只有一个结点,逆转后的头指针不变
    else
    {
        q = p->next;          // q为链表(a2,…an)的头指针
        h = reverse(q);       // 逆转链表(a2,…an),并返回逆转后的头指针
        q->next = p;          // 将a1联接在a2之后
        p->next = NULL;

        return h;               // (a2,…,an)逆转表的头指针即为(a1,a2,…,an)
    }
}

3. 递归方式合并两个链表
Node * MergeRecursive(Node *head1 , Node *head2)
{
    if ( head1 == NULL )
        return head2 ;
    if ( head2 == NULL)
        return head1 ;

    Node *head = NULL ;
    if ( head1->data < head2->data )
    {
        head = head1 ;
        head->next = MergeRecursive(head1->next,head2);
    }
    else
    {
        head = head2 ;
        head->next = MergeRecursive(head1,head2->next);
    }

    return head ;
}