可以毫无讳言的说:算法能力是进入名企和获得高薪的最重要的能力。有一个著名的等式就是:程序设计语言 + 算法 = 软件。因此程序员要想提高自己的编程能力,写出优秀的软件,必须具备扎实的编程语言应用能力,灵活的算法设计能力,此外还应具备丰富的某个专业领域技能和经验(这一点对于非应届的朋友来说,非常重要。如果你之前没有搜索引擎开发经验,那么很少有搜索公司对你的简历感兴趣;如果你没有过安全软件开发,系统内核开发经验,那么也很少有安全公司对你的简历感兴趣),但归根结底还是算法设计。算法设计是计算机软件设计与开发的核心。编程语言与开发领域可以变化,你可以今天用C,明天用Java,你也可以今天做Web开发,明天做底层安全开发,但是算法设计以及数据结构却是相通的。
实际上,从开发经验来讲,程序 = 算法(包括数据结构)+ API调用 + “Hello world” + 字符串处理 + 内存管理(部分语言如java,python等无内存管理)。其中算法是程序的核心和灵魂。API是程序调用开发库中的接口,用来实现特定的功能和任务。一个程序不可能不调用API来完成功能。无论学哪个方面的编程,我们都可以从最简单的“Hello world”开始,学习它的开发环境搭建,程序结构框架,调试以及编译执行。剩下就是可能的大量字符串的处理和内存的操作,其中字符串处理会占程序代码中至少10%以上,这也是为什么很多企业(包括微软)会特别喜欢考查与字符串相关的算法题。
算法说白了,就是指程序员的编程能力,它是IT新手最需要训练和提高的地方,算法问题也是IT面试中的最具挑战性的问题,这直接反应了程序员的基本素质,因此答不好算法问题(一般就是在纸上或者黑板上甚至上机写代码解决问题),一般很难通过面试,那么离名企和高薪就会很遥远。算法能力(也就是编程能力)
1,确定函数名字与原型
一旦拿到有关算法的问题,那么就应该分析问题,找到对应的输入输出,从而确定出算法的函数原型。我们写算法,其实就是写一个或者若干个普通的函数(而不是main函数)。因此,需要分析出,应该传什么参数给函数(作为输入参数),函数处理完后,应该把什么数据作为结果返回(作为输出参数)。最后还要给函数取一个符合算法意义的名字,名字最好用英语表示,如果用拼音,会显得特别山寨的感觉。函数的命名方式与变量的命名方式都有相关的约定,比如匈牙利命名法,Linux命名法或者驼峰命名法等。
比如,有这么一个典型的算法问题:将一个字符串逆置,比如:”hello world”-->”dlrow olleh”
对于这道题,我们分析之后,应该知道,输入是一个普通的字符串,输出是将这个字符串逆置之后的字符串,因此,可以确定函数的原型:
void reverse_str(char *str);//str既是输入,也是输出 { } 或者 void reverse_str(char *str, size_t len)//str既是输入又是输出,len是字符串的长度 { }
很多初学者在这里容易犯的错误包括:只对字符串“hello world”进行了逆置而忽视了算法解决的是通用的一般性问题,或者把相关的代码直接写在了main()函数里。
此外,就是需要有模块化的思想。一个函数只单独完成一个单一的功能,函数的代码行数一般很少超过100行,加上注释不会超过300行。
因此,要把那些频繁使用而功能又比较单一的代码放在一个独立的函数里。不要在一个函数里完成N个功能,这不利于调试和维护,也和模块化是相背离的。
2,严进宽出
确定好了函数的原型之后,紧接着在完成这个函数的功能一开始的地方,就需要严格判断函数输入参数的合法性,我们称之为:严进宽出。具体点说,就是要判断:
a,函数参数中的指针是否为NULL
b,函数参数中缓存的长度是否在合理范围
c,甚至还要利用C++中的RTTI对参数的类型进行检查。
以上a,b,c三点非常的重要。
比如同样对于第1点里的函数原型,那么我们就需要作出如下的判断:
void reverse_str(char *str, size_t len) { /*首先判断str指针是否为NULL或者len是否为0和1,这些都是特殊情况或者非法输入,因此要严格检查,严进宽出。*/ if(str== NULL || *str=='