今天去参加了微软的一个外包的公司的招聘,当然,这个招聘的公司不在国内,不过好在出人意料的是这个公司竟然在武汉来招聘了,我的一个非常优秀的 c++的朋友被应聘了,然后他极力推荐我去参加应聘,我第一次去,那个boss(老外)非常赞赏我,因为我的简历的原因,原来做了Shangducms这个项目并且还出了一本书,所以那个老外非常赞赏我,并且直接安排我到最后的面试。 

话说回来,这个老外是一个hr,但是是微软的员工并且长达10年的工龄,这个老外对算法和素质要求的比较高(其实国外的公司都差不多是这样),然后这个老外出了两个题,一个题是编程题,另一个是设计题,这两个题在各位高手眼中肯定比较简单,这两个题是这样的。 

1.对字符串进行排序,用任意一种编程语言来实现,不能使用现有的类,在排序中,字符串“Bc”,“Ad”,“aC”,“Hello”,“X man”,“little”,“During”,“day”能够排序成 “Ad”,"aC",“Bc”,“During”,“day”,“Hello”,“little”,“Hello”,也就是说,在排序的过程并不是传统的按照字符串排序,在排序中还需要将小写字母一并排序,也就是说a字符串要在B或b之前。 

2.设计一个图书管理系统,无需实现,只需要写清思路就可以了。 

考试也很轻松,出了不能用QQ,MSN以外,其他的什么baidu啊google啊都可以查,本来拿到这两个题的时候觉得非常的简单(当时的感觉那是相当的简单),但是没想到做了2-3个小时还没有做出来,要不就是出现错误要不就是无法排序,结果只好被老外说“I'm sorry”了。 

后来回来了之后,感觉非常的郁闷,其实也不是特别郁闷,但是觉得自己水平不错嘛,这样的工作当然是唾手可得了,没想到马失前蹄,感觉不爽,就和朋友玩了几个小时游戏,后来坐回电脑前,改不了程序员的“劣根性”,非要搞出个所以然来,结果没出20分钟就搞定了,真是很郁闷!因为如果做不出来就算了,结果自己做20分钟就做出来了,在面试时却没有做出来,我想除了紧张以外,更多的还是基础知识不牢固的原因,下面分享一下自己的代码。 

其实第一题很简单,就是一个排序,随便用什么算法都可以,直接冒泡就可以,不过难点在于比较字符串中间的字符的ASCII的值,首先写其他代码,初始化一下,示例代码如下所示。 
        public string[] str = { "dad", "bood","bada","Admin","Good","aete","cc","Ko","Beta","Could"}; 
        public Form1() 
        { 
            InitializeComponent(); 
        } 

        ** void Form1_Load(object sender, EventArgs e) 
        { 
            textBox1.Text = ""; 
            for (int i = 0; i < str.Length; i++) 
            { 
                textBox1.Text += str.ToString()+" "; 
            } 
        } 
上面这串代码很简单,就是先声明一个数组咯,然后在窗体加载时进行数组的遍历(原题是从文件中读取一串字符串转化为数组,这个简单,固可以忽略),当用户单击排序按钮时,进行排序,这里也很简单,示例代码如下所示。 
Code 
        ** void button1_Click(object sender, EventArgs e) 
        { 
            Sort(str); 
            textBox1.Text = ""; 
            for (int i = 0; i < str.Length; i++) 
            { 
                textBox1.Text += str.ToString() + " "; 
            } 
        } 
当用户单击按钮时,使用排序Sort方法排序字符串然后清空现有的内容再呈现在控件中,这里关键的就是Sort方法的实现,Sort方法的实现很简单,直接冒泡就可以了,但是注意的是,这里是字符串,而不是数字,冒泡的话需要判断大小,如果使用C#函数,则可以很容易的实现Sort方法,示例代码如下所示。 
Code 
        ** void Sort(string[] s) 
        { 
            for (int i = 0; i < s.Length; i++) 
            { 
                for (int j = 0; j < s.Length - i-1; j++) 
                { 
                    if (String.CompareOrdinal(s[j], s[j + 1]) > 0) 
                    { 
                        string tem = s[j]; 
                        s[j] = s[j+1]; 
                        s[j + 1] = tem; 
                    } 
                } 
            } 
        } 
好了,如果使用String.CompareOrdinal方法当然能够快速的排序,但是这里有一个问题,先不说这里不能用自带的类,就说这个题目吧,CompareOrdinal方法还是无法实现需求,但是这里给了一个思路,使用冒泡排序进行排序,可以在函数中实现字符串的大小的对比,就好像数字的对比一样,这里就该一下,使用自己的方法,示例代码如下所示。 
Code 
        ** void Sort(string[] s) 
        { 
            for (int i = 0; i < s.Length; i++) 
            { 
                for (int j = 0; j < s.Length - i-1; j++) 
                { 
                    if (compare(s[j], s[j + 1]) > 0) 
                    { 
                        string tem = s[j]; 
                        s[j] = s[j+1]; 
                        s[j + 1] = tem; 
                    } 
                } 
            } 
        } 
上面的代码使用自己的compare方法进行判断,其实现思路基本同String.CompareOrdinal相同再加以改进就可以了,这是最重要的方法,因为这个方法直接关系到排序,示例代码如下所示。 
Code 
        ** int compare(string str1, string str2) 
        { 
            int x=0; 
            for (int i=0,j=0; (i < str1.Length)&&(j <str2.Length); i++,j++) 
            { 
                int s1 = (int)str1; 
                int s2 = (int)str2[j]; 

                //insert 
                if (s1 >= 97) 
                { 
                    s1 -= 32; 
                } 

                if (s2 >= 97) 
                { 
                    s2 -= 32; 
                } 
                //end 

                if (s1 > s2) 
                { 
                    x = 1; 
                    break; 
                } 
                else if (s1 < s2) 
                { 
                    x = 0; 
                    break; 
                } 
                else if (s1 == s2) 
                { 
                    if ((int)str1 > (int)str2[j]) 
                    { 
                        x = 1; 
                        break; 
                    } 
                    else 
                    { 
                        x = 0; 
                        break; 
                    } 
                } 
            } 
            return x; 
        } 
在进行compare方法的实现时,首先要确定思想,对字符串进行排序,首先要判断两个字符串的第一个字母的ASCII码,如果相等,就判断字符串的下一个字母的ASCII,以此类推,但是这里注意的是a的ASCII要比Z要大,所以在判断前还需要判断是否为小写字母(这里的方法比较蠢,呵呵),如果是小写,转换成大写进行判断,同样为了实现String.CompareOrdinal方法的效果,可以返回一个int类型的值进行判断. 

这样,整个排序就完成了,做完之后,我自己真的是感慨良深啊,自己做了多年的.NET开发,却真正意义上并不太懂How the Program Works,老外在最后也对我说了“虽然你懂很多ASP.NET,WCF,WPF等等知识,但是最基础的却掌握的不好,相比之下,我建议你在这几个月的时间里多学习一下基础,当你的基础牢固了之后,一切都变得简单了(Everything gonna to be easy)”,确实,当时做不出来最郁闷的并不是题目本身,而是忽然感觉到自己学习的过程有点像揠苗助长一样,应用做多了,反而基本的都忘记了。 

其实,这篇文章并不是最出彩的文章,也不是技术含量最深的文章,而且这个题目肯定有很多高手看一眼就能够做出来,但是我写这篇文章,只是想分享一下自己的经历,真的,其实越到后来越发现,基础往往是最重要的,这让我想起几个月前讨论的基础是不是最重要的话题时,很多人都说只要工作的时候翻翻书就可以了,当时我也是这么想,想着不会了翻书找一下就行了,没想到优秀是一种习惯,熟练的掌握基础才是编写高质量代码的基本要求。 

最后在这里分享一下一点总结: 

1.面试千万不要紧张,特别是face to face的时候,还特别是老外面试,千万不要紧张,否则水平还没有平时的十分之一。 

2.多多锻炼一下自己的基本功,无论是在校学生(像我还有几个月时间),还是上班的同学(我也工作了几年),都应该好好把握时间多练习基本功,在校生有很多的机会可以练,而参加工作的同学也需要“温故而知新”。 

3.优秀是一种习惯,无论是在解决问题上还是在编码风格上,都应该按照最好的标准要求自己(老外还说看代码主要是要看风格)。希望能够和各位高手一起分享Code的乐趣和经验。 

4.可以上一些论坛看看面试题,看看《编程之美》之类的图书也比较有帮助。

分享一句不相关的话,人本是人,不必刻意去做人,世本是世,无须精心处世。
[em6]