18 October 2016
版权声明:本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名elloop(包含链接)

解ACM题的能力真的代表编程能力吗?

这是我早期的一篇讲ACM能力和编程能力的文章, 希望能给你提供一些启发.

一、能

  1. OI 和 ICPC 竞赛需要的知识和思维方式,是一个有效的智商、问题分析等逻辑能力筛选器,也是成本最低的一种选拔方式。具备非常强的解题能力,但是实际工作中交付能力差,解决问题差的概率非常低,在我有限的工作经验中,还没有碰到过。OIer或者 ACMer 背景的小伙伴理解和逻辑能力一流,交流非常愉快,你几乎不用担心你的问题太复杂对方听不懂。

  2. 竞赛中分析问题的能力也是非常有价值的。比如如何把一个问题归约到另外一个问题来简化设计,比如一个分支非常多的业务流可以设计为一个DFA(有限状态机)。另外竞赛者往往对问题的边界、特例更加敏感,因为这也是竞赛需要的一项基本能力,而这些边界特例处理不当,可能导致系统崩溃。还有 debug 能力,比如如何排除影响验证定位问题,这些也是竞赛中需要的基本能力。

  3. 优秀的竞赛者数据结构和算法基础更扎实,coding 实现能力更强。关于数据结构和算法是否有用,我这里不讨论了,知乎有太多相关的帖子了。我只说一句,「不是数据结构和算法无用,而是你没用」。这里讲 coding 能力,我碰到过不少大学生,给一个算法描述,他能用笔模拟出运转的过程,但是一用代码(包括伪代码)描述,就漏洞百出。而对于 ACMer 来说,如果有清晰的解决方案,实现往往都不是问题。许多人认为,大多数人通过训练,就能获得这种能力,我对此持否定意见。一次性写出bug-free的代码,除了熟能生巧,还和人的思维、习惯等等有非常紧密的关系。

  4. 其实这点和1相似,就是快速学习的能力。多数情况下,由于优秀的竞赛者具备更扎实的知识储备,更强的逻辑和分析能力,学习新知识的能力更强。归纳或者归约分析的能力更强,他们更容易从新旧技术(知识)中找到共同点把知识体系统一起来。

二、不能

  1. 仅仅ACM/ICPC涉及的知识体系,还不够完善,和实际工作需要的知识栈还有差距。现在分工非常细,实际工作中设计的知识栈也差异巨大。以后台开发为例,操作系统、TCP/IP 网络、数据库也是非常重要的知识。实际工作可能更关注的是系统的设计,多线程多进程还是单线程的模型,如何处理高并发、如何应对由此带来的数据一致性挑战,如何提高系统的可用性,如何优化 cache 命中率等等。应用开发中,除了围观层面的写好每一个函数每一行代码以外,设计是非常重要的,抽象逻辑并选择好的设计,这些都和实战经验关系非常大,而不是 uva/spoj 多刷200道题能解决的。

另外这里扯一下,经验也分很多种,有很多纯粹是量的积累,并没有太多价值。我们在学校随便开发的 app 或者网站,你根本不用去考虑设计和优化,一则是你没有足够的数据反馈来优化产品,二则是用户规模达不到需要改进设计和优化的层次,怎么写都行。

经常有些小公司的朋友问我,他们应该选 mongodb 还是 mysql, 或者是选择 PHP 还是 GO,哪个性能会更好, 我就觉得奇怪他为什么有这样的困惑,因为以他们的产品的水平,选哪个都能解决问题,肯定是哪个简单哪个好招人用哪个,而且等这个成为瓶颈时,你们已经不是一家小公司了。

没有成长和迭代的开发,这种经验也没有多少价值。否则那些在校在猪八戒和淘宝上借外包的人就是最牛的了,他们一个月能做8个网站外加2个看起来和 微信一样的 app。

  1. 同时存在其它选拔方式,也可以选拔出在竞赛中不突出或者没参加过竞赛的优秀学生,所以 ACM 竞赛不能代表编程能力。有很多学生在学生时代,就是开源社区的佼佼者,或参与过一流的开源项目,或自己有较好的开源作品。还有些优秀的学生,在校写过很不错的 app,可能技术并不复杂,但是设计非常精美或者体验非常棒。这些都能代表编程能力,有这样的人群加入,丰富一个技术团队,团队发展会更好。

  2. 竞赛涉及的算法只是算法世界里最基本的逻辑和方法论,而比如机器学习、密码学、分布式计算等分支涉及的算法能力或者编程能力又有所不同(但是优秀的竞赛者在这些领域深造成为优秀工程师的概率还是更高)。我认识一些机器学习领域的工程师,编程一流,Tensorflow 等框架出来前各种复杂的模型能自己人肉用 C++写,各种机器学习竞赛排名刷的飞起,但是好多数据结构和算法设计的基本方法论都不懂。

三、说下其它的

  1. 竞赛者也分很多个层次,刷题者亦然。大多数人的能力也就是掌握基本算法设计的基本定式,而无法理解其背后的本质问题,他们并没有比没参加过竞赛没刷过题的优秀学生高明。比如有不少人能解典型的动态规划问题,滚动数组用得非常溜,但是问题一变化,需要从一个看起来毫不相关的问题规约到另外一个经典问题,就完全不只从何做起。有些人刷了几百道动态规划的题目,对贪心和动态规划的理解,依旧模棱两可。有些人你让他写 KMP,他能几分钟给你背出来,但是却不知道这个算法和 自动机之间的关联,不知道next 函数的本质是什么,甚至无法把他和 ac 自动机关联起来。

  2. 在大学能坚持做好一件事情的人很少。大多人,不止平庸而且非常懒,他们可能毕业设计都得花一个月生活费买,能拿网上的改改调通的都不能算特别差。ACMer起码需要坚持经过几百上千道题的训练(虽然也有不少如我,喜欢刷水题凑数……),这种精神力量就代表了一种能力,在工作中就是一种交付能力。当然,能坚持学习写好一个app或好好写一个网站的学生或把一门课程学到极致的学霸也有这种特质。

欢迎关注靖难,一个程序员,一个长期不单身的青年,热爱和年轻人围炉谈话,分享一点人生经验,喜欢在世界地图前思考历史的行程,关注亚非拉局势,也想在这个世界保持独立清醒。


在这里也能看到这篇文章:github博客, CSDN博客, 欢迎访问



分享到