其实往大了说,这个问题非常微妙。
一般地,所谓的编程能力,可以概括为使用现有可编程性的设施完成表达满足特定需求的程序的能力。
一般人可能同时具有其中的一部分能力,但不具有另一部分。我把这样的能力排除出工程能力——这样的能力本质上和工程专业性无关(虽然也许和经验有关)。其中有一部分确实是吃天赋的也不容易传授的,因此不是人人都容易会的技能。只不过,职业上习惯水平扩展能解决问题就不强调这类技能了,所以会被忽视,但这不意味这样的差距就不存在,哪怕是非常小的细节。
像 @
youxiachai 提到“打奥赛的”(我理解为信息学奥赛,NOI/IOI 这类,如果说的是 Peter Dimov 这样 IMO 拿牌的另说),从细节就可以看出其中大部分人在一些编程的技能上是很不长进的。
例如有的 OI 撸 C++ 的会知道糊 __gnu_cxx 之类的开洞来偷懒——因为 OI 限定了环境,使用这些东西的问题相对不是很明显。不过,如果反思自己用的是“什么样的 C++ ”,就会发现一些问题。——这个下面讨论。
一个类似的出现在专业工程人士上的例子是 FreeType2 这个主要用 C 实现并且保证 ISO C conformance 的项目在 2016 年才修复不当使用下划线起始接大写字母的标识符和使用双下划线标识符的问题。(应该不用质疑这些作者的工程上的专业性,从 API 维护质量和工程过程看这应该是个星球上最专业的几个 C 项目之一,至少比什么 stb 之流好多了。)
这个问题的技术原理是,不当使用带有 __ 这样的标识符,在 C 和 C++ 都会引起未定义行为(不清楚这意味着什么的,最好别说自己了解 C 和 C++ )。所以如果不是自己实现标准库或编译器之类的东西,这就是 [编程上] 错误的。——这是使用 C 和 C++ 编程的常识问题,而在不经他人提醒的前提下 [意识到] 这个问题的能力,属于编程能力的一种。因为,这个问题的一般形式是:“究竟依赖了什么样的编程设施才能给完成编程任务提供基本的保证?”这个问题中,语言提供的可移植性是语言的 spec 保证的。而找到具体的依据(翻 spec )以及改正现有错误的效率,才体现出一部分工程能力。
和一些标榜 C/C++ 却不说清楚具体依赖的项目代码中 __ 满天飞作者却仍然没意识到问题相比,FreeType2 维护者的编程水准显然也不算太差——他们好歹终于注意到了。
退回到一些 C++ OI 选手上的例子,不经提醒,他们很可能不会注意到为什么在 OI 环境中恰巧能用这样的不可移植东西——或者一知半解而去用导致脱离他们使用 OI C++ 方言而改用“真正”的 C++ 会被坑的理由。这就是缺失编程能力的一个方面的体现。
至于 OI 选手在给定时间和资源限制内准确确定可行算法解决问题之类的技能,这属于 OI 环境下的业务逻辑,和编程水平没有直接关系。使用代码实现这些算法虽然是编程能力的体现,但考虑到 OI 使用的语言都相当烂大街,这个能力其实相当大路货,一般人就算会遇到门槛,也主要是算法这种业务逻辑方面理解和经验上的问题,不大会是因为编程水平拙计的问题。
而在业务领域提升到提供可编程环境(例如,发明语言和提供语言实现)之前,要把这类业务上的东西和编程类比所谓哪个更强,是没啥意义的。