我们先来看一个比较:

项目代码

竞赛代码

  上图是我写的项目代码(左边是接口,右边是某个类的实现),下图是别人写的竞赛代码(因为我写的代码都有非常浓郁的项目风就直接CV别人的了)。

  可以很明显的感受到两者的区别,很明显第一段代码更易读。下面我们说一说为什么会这样。

缘由

  竞赛代码与项目代码区别如此之大是因为二者的追求(或者说目的)完全不同,竞赛代码简单地追求编写快、运行快,而项目代码则同时追求开发速度、性能、可读性、拓展性、复用性、容错性等等。

  造成这一区分的最根本的原因实际上是两者代码的“存活时间”不同,竞赛代码大部分使用一次之后就废弃了,而项目代码经常会存在很长时间甚至永远存在,所以项目代码必须考虑后期维护的问题。

  还有一个重要的原因是开发人数,竞赛代码是由一人开发,而项目代码经常会出现多人开发或者一人开发多人使用的情况,如何保证多个人合作且不出现或者尽量少地出现错误也是一个巨大的挑战。

可读性

  可以发现,项目开发中同时追求非常多方面,以至于经常需要程序员在多个追求之间进行取舍。最常见的就是性能与可读性,在很多时候,为了保证代码的可读性,或多或少地需要舍弃一些性能。在实际开发中,我们通常以可读性为第一要求(对性能要求极高的场景除外)。

  项目开发为何如此注重代码的可读性,因为代码的存活时间相当长。如果可读性不好的话,后期在维护代码时就会非常困难,因为你很难看懂甚至有时候根本看不懂你要维护的代码在干什么。一旦出现看不懂的情况要么就干脆放在那不管,要么干脆重写。为了避免重写导致意外,大部分时候都会选择前者,时间长了就有了我们常说的“屎山”。

  还有一个重要的原因是项目代码不仅要让自己看懂,也要能让别人看懂。因为你写的代码不是你一个人在用,如果别人看不懂你的代码,那么你们的代码将非常难以互通。(至少要保证你提供的接口别人可以看懂)

性能

  性能无论在项目开发和竞赛中都很重要。在竞赛中,性能过差会TLE,而在项目开发中,性能拉跨会使整个软件的评价降低。

  不过性能在项目开发中大多数情况下并不是首要追求,在很多时候会牺牲一部分性能来换取其它优势。

开发速度

  竞赛中,快速的解出题目、写出AC代码可以为其它题目腾出更多时间。在项目开发中,缩短开发时间可以节省成本。

复用性

  竞赛代码基本不追求复用性,因为代码实在太短,要复用也没有太多的机会。而项目代码就不一样了,一个项目动辄就有成千上万的代码。我写的现代工业只是一个小项目而已,还没写完就已经有两万行代码了,可以想象一下一个大型项目的代码会有多少。

  这种代码量还是因为尽可能地复用代码,如果不加以复用的话还会更多,代码越多后期维护成本(包括但不限于时间、人力成本)和难度就会越大。

  说到维护成本,复用代码还有一个降低维护成本的重要原因。如果有一段同样的代码多次出现在不同的地方,如果这段代码有问题或者因为某些原因需要修改,那么我们就需要手动修改这个代码出现的所有地方,这无疑是费时费力还容易出错的方法。但是如果我们复用了代码,把这段代码封装起来,那么修改的时候只修改一个地方即可。

拓展性

  竞赛代码可以说完全不追求拓展性了,反而是追求高订制、高耦合。正如“拓展性”三个字,它追求的是程序可以以尽可能低的成本在原有的基础上添加新的功能。

  为什么说竞赛代码追去高订制、高耦合呢?我们要知道,“可拓展”这三个字不是没有成本的,为了支持拓展,我们需要给代码预留更多的接口,性能就会比订制出来的代码差。

  这方面和“复用性”有些许重复,思想也是复用已有代码,就不再多说。

容错性

  同样,竞赛代码完全不追求容错性,反而追求绝不检查参数。所谓的容错性是什么?简单说就是外界输入错误的数据时程序能够保证自身运行不受影响。

  我们举一个最简单的例子:(注:这个参数不仅仅指的是控制台用户的输入,这里只是拿控制台程序举个栗子)

1
2
3
4
5
6
int main() {
int n;
scanf("%d", &n);
printf("你输入的数字为:%d", n);
return 0;
}

  这段代码看似没有问题,实际上隐患很大,因为用户一旦输入非数字数据程序运行就会出问题。

  在竞赛中是不需要检查输入数据的,因为测试样例会严格按照题干给出的格式传入数据。但是在项目开发中就不一样了,用户可能会传入各种各样奇怪的东西。最经典的案例就是现在很多3A都取消了空格跳跃这个功能,因为有了跳跃玩家就能做出千奇百怪的操作(比如在BOSS头上跳舞),非常容易出BUG而且有时候还会影响设计师辛辛苦苦渲染出来的氛围。

模块化

  模块化和高订制不完全对立,但是大部分时候并不能共存。模块化的目的就是将不同的功能彻底分割,降低耦合度(某种意义上也是为了提高复用率),同时提高可读性。

总结

  可以说,项目代码和竞赛代码绝大多数地方都是不同的,少有的相同之处就在于对性能和开发速度的追求了(不过项目开发没有竞赛对这两个追求那么极限)。

  综上所述,如果有一天玩竞赛地同学去开发项目了,虽然习惯很难改,但是切记一定一定不能按照自己写题地习惯写代码,不然你会被骂的很惨的。

  综上所述,如果有一天玩竞赛地同学去开发项目了,虽然习惯很难改,但是切记一定一定不能按照自己写题地习惯写代码,不然你会被骂的很惨的。

  综上所述,如果有一天玩竞赛地同学去开发项目了,虽然习惯很难改,但是切记一定一定不能按照自己写题地习惯写代码,不然你会被骂的很惨的。

重要的话说三遍(雾)