怎样才算好代码

        至此,你也许明白了,许多公司都想找出能写出“优美、整洁”代码的人才。但这到底意味着什么,怎样才能在面试中展现出这方面的能力呢?

        一般来说,好代码具备如下特性。

  • 正确:代码应当正确处理所有预期输入和非法输入。
  • 高效:不管是从空间上还是从时间上来衡量,代码都要尽可能地高效运行。所谓的“高效”不仅是指在极限情况下的渐进效率,同时也包括实际运行的效率。也就是说,在计算O时间时,你可以忽略某个常量因子,但在实际环境中,该常量因子可能有很大影响。
  • 简洁:代码能写成10行就不要写成100行。这样开发人员才能尽快写好代码。
  • 易读:要确保其它开发人员能读懂你 的代码,并弄清来龙去脉。易读的代码会有适当注释,实现思路也简单易懂。这就意味着,那些包含位操作的花俏的代码不见得就是“好”代码。
  • 可维护:在产品生命周期内,代码经过适当修改就能应对需求的变化。此外,无论对于原开发人员还是其他开发人员,代码都应该易于维护。

        力求实现上述特性必须找到一个平衡点。比如,有些情况下,我们往往要牺牲一定的效率好让代码更已维护,有时则要反其道行之。

         在面试中,写代码时应该好好考虑这些要素。下文就前面的清单给出更具体的描述。

         1.多用数据结构

         假设面试官要求你编写一个函数,对两个简单的多项式求和,其形式为(其中系数和指数为任意正实数或负实数),即多项式的每一项都是一个常量乘以某个数的n次幂。面试官还补充说,不必对这些多项式做字符串解析,可以使用任意数据结构来表示它们。

         这个函数有多种实现方式。

  • 最差的实现方式

         最差的实现方式就是将多项式储存为一个double型数组,其中第k个元素对应的是多项式中的系数。采用这种结构有一定问题,如此一来,多项式就不能含有负的或非负整数指数。要想用这种方法来表示多项式的话,这个数组就得包含1000个元素。

        

  • 较差的实现方式

         一种不算最差的实现方式的将多项式存为一对数组coefficients和exponents。采用这种方法,多项式的所有项可以按任意顺序存放,只要系统和指数配对,多项式的第i项表示为 。

         采用这种实现方式,如果coefficients[p]=k和exponents[p]=m,则第p项为。尽管这么做没有上面那张解法的限制,但还是很凌乱。一个多项式就要用两个数组记录。如果两个数组长度不同,多项式就会出现“未定义”的值。而要返回多项式更是麻烦,因为一下子得返回两个数组。

        

  • 较好的实现方式

         对于这个问题,较好的实现方式是专为多项式设计一种数据结构。

         


         有些人可能或真的认为这么做“优化过了头”。也许是,也许不是。不管你是不是这么认为,上面的代码都表明你应该用心思考如何设计代码,而不要匆忙地胡乱堆砌一桶。

         2.适当重用代码

          假设面试官要求你编写一个函数检查某个二进制(以字符串形式传入)是否等于以字符串表示的十六进制数。

          我们可以善用代码重用巧妙解决该问题。

         

          

         我们本可以实现两套代码,实现二进制和十六进制的转换,但这么做只会加大代码的编写难度,而且维护起来也更难。相反,我们还是通过编写convertToBase和digitToValue的方法来重用代码。

            

        3.模块化

        编写模块化代码是指将孤立的代码块划分为相应的方法(函数)。这有助于让代码更易读,可读性和可测试性更强。

        假设你在编写交换整数数组中的最大和最小元素的代码,不妨将全部代码写在一个函数里,如下所示:

        

        或者,你还可以采取更模块化的方式,将相对独立的代码块隔离到对应的方法中。

       

       

         虽然前面的非模块化代码看起来也不怎么糟,但模块化代码的一大好处在于它易于测试,因为每一部分都可以单独验证。随着代码越来越复杂,编写模块化代码就变得越发重要。模块化的代码也更易阅读和维护。面试官希望看到你在面试中展现这些技能。

        4.灵活、健壮

        不要因为面试官要求编写代码检查谁是三连棋游戏的赢家,就非得假定它是一个3×3的棋盘。何不放手针对N×N棋盘编写代码呢?

        编写灵活、通用的代码,也可能意味着使用变量,而不是在代码里直接把值写死,或者使用模板/泛型来解决问题。要是有办法编写代码解决更普遍的问题,那我们就应该这么做。

        当然,它也有限制条件。如果通用解决方案更为复杂,并且在面试中几乎没有必要使用,那就按照要求解决相应的问题,效果可能会更好。

         5.错误检查

         写代码很细心的人有一个明显的特征,那就是她不会想当然地处理输入信息。相反,她会用ASSERT语句或if语句仔细验证输入数据是否合理。

         比如,回到前面那段将基数为i的进制数(比如基数为2或16)转换成整数的代码。

        

        

         在第2行,我们检查基数是否有效(假定除16外,大于10的基数都是无效的,没有标准的字符串表示形式)。在第6行,我们另外加了一处错误检查:确保每个数字都落在允许范围内。

         诸如此类的错误检查在实际的产品代码中至关重要,因此,面试中也不能掉以轻心。

         当然,这些错误检查有时很繁琐,可能会浪费宝贵的面试时间。关键在于指出你会加上错误检查。如果错误检查远非一条if语句就能搞定,写代码时最好先为错误检查预留一些空间,并告诉面试官,完成其余代码之后你会补上错误检查代码。


                                                               ——摘自《程序员面试金典(第5版)》   





        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值