这一节还是挺有收获的,作者首先讲了代码的规范性和完整性。规范性即清晰地书写、清晰的布局、合理的命名,我想这也是对一个优秀的程序员的基本要求。代码的完整性里面提到了几个以前没听说过的概念。确保代码完整性的3个方面:功能测试、边界测试、负面测试。
功能测试即考虑普通功能的测试用例,写出的代码要能够满足面试官要求的基本功能,同时考虑问题要全面,不能遗漏。边界测试即程序中可能存在递归和循环。如果是循环,那么结束循环的边界条件是否正确。如果是递归,递归终止的边界值是否正确。最后还要考虑各种可能的错误输入,也就是通常所说的负面测试用例。
3种处理错误的方法:
1.返回值。函数用返回值来告知调用者是否出错,这种方式的缺陷是不能通过返回值直接调用函数的计算结果,因为返回值被占用。
2.全局变量。这种方式可以通过返回值直接调用函数的计算结果,但缺点是很容易忘记去检查全局变量。
3.异常。当函数运行出错的时候,我们就抛出一个异常,我们还可以根据不同的出错原因定义不同的异常类型。缺点就是有些语言不支持异常,抛出异常时对性能有负面影响。
下面以一个题目来作为实例:
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
解答:最忌讳的是只考虑到指数是正整数的情况,指数还可以是0,负数。如果是指数是负数,直接求正数次幂然后求倒数就可以了,但是需要注意0不能求倒数,这里需要返回一个异常。
bool InvalidInput = false; double PowerOfUnsignedExp(double base, int exponent) { if(exponent == 0) return 1; if(exponent == 1) return base; int HalfExp = exponent >> 1; double result = PowerOfUnsignedExp(base, HalfExp); result *= result; if(exponent & 1 == 1) result *= base; return result; } bool equal(double num1, double num2) { if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)) return true; else return false; } double Power(double base, int exponent) { if(equal(base, 0.0) && exponent < 0) { InvalidInput = true; return 0.0; } unsigned int UnsignedExp = (unsigned int)exponent; if(exponent < 0) UnsignedExp = (unsigned int)(-exponent); double result = PowerOfUnsignedExp(base, UnsignedExp); return (exponent < 0 ? 1.0/result : result); }代码里用到了两个技巧: 用右移运算符代替了除以2,用位与运算符代替了求余运算符来判断一个数是奇数还是偶数。位运算的效率比乘除法以及求余运算的效率高得多。