第三章:高质量的代码
3.1 面试官意见
- 两个double之间不能用=号判断相等,会因为精度差而无解。
- 忽略边界情况不可取。
- 代码容错能力,即考虑所有情况,考虑异常情况,考虑资源回收等。
- 函数、变量的命名;合适的数据结构的选取。
- 正确性和鲁棒性。
3.2 代码的规范性
- 因素:清晰的书写 + 清晰的布局 + 合理的命名
3.3 代码的完整性
- 测试被试者考虑问题是否全面,是否完成了基本功能,是否考虑到边界因素。
- 以3方面确保代码完整性:功能测试、边界测试、负面测试。
功能测试:即完成大多数情况下完成的功能,尽可能看到更多的功能需求。
边界测试:考虑输入的值的极端情况,考虑递归或循环的边界条件是否正确。
负面测试:考虑输入如果是错误,如何异常处理。 - 3种处理错误的方法
1) 返回值:一般返回值为0 为正确,不为0表示调用过程中出错。但如果是返回值有用的函数,这种方式就不可取了。
2) 全局变量:设置一个全局变量,在调用过后检查这个全局变量,得知原因,但有可能会忘记导致安全隐患。
3)异常:运行出错时就抛出一个异常,根据不同的错误原因抛出不同类型的异常,从而做相应的处理。并且try-catch的逻辑清晰,不过C语言不支持,C++、C#支持。缺点是会打乱程序正常执行的顺序,尤其在多层调用中好像比较复杂。
- 题11:数值的整数次方
double power(double base, int exponent);不得使用库函数,不考虑大数问题。
分析:
首先base是一个double型的值,正、负、零都要考虑;exponent是int型,是指数,也要考虑到正、负、零。exponent是0时,所以的base为正数次方都是1。exponent是正数时,base乘exponent次。exponent是负数时,则乘exponent次后再取倒数。
再者优化次方函数,常规方法即循环乘exponet次,而效率更高的方法可采用二分法。即:x32=x16*2=x2*2*2*2 - 题12:打印1到最大的n位数
输入3,打印1到最大的三位数,即1-999。但这里有大数问题,有可能超过int 或者long的范围。
所以,这道题要用用字符串或数组的方式表示大数。
常规方法:用字符串表示,每个字符表示一个位,每算法逻辑对字符串进行加1,然后打印一次。
高效方法:因为每一位都是从0-9打印,可以用递归的方式:for循环打印0-9,每次打印过后打印下一位。不要打印前面的0的话(如三位数098要打印成98)。就每次往字符串中0-9顺序加入,递归加入下一位,直到个位数时每次加则打印。 - 题12:以O(1)的时间复杂度删除一个单向链表的节点
分析:
若是常规删除单向链表中的一个节点,需要找到其上一个节点,但找到上一个节点肯定需要O(n)的顺序遍历的方式。所以不能以常规方式,可以删除一个好删除的,再把它的元素复制过来,其后一个节点好删除,所以复制再删除即可完成O(1)的删除节点操作。
还需要考虑到如果是尾部的节点,那就必须找到上一个节点才行。
再考虑如果只有一个节点,还需将root置为NULL。