身无所拘,心无疆

Standing on the Shoulder of Giants

2020-01-07

牛顿曾说

如果说我能看的更远,
那是因为,
我站在了巨人的肩膀上。

0x0

我不知道是从什么时候开始,大学的学术圈开始瞧不起软件工程,有些人整天就把“算法才是灵魂,做软件没有技术含量,编程语言只是工具”之类的话挂在嘴边,仿佛他们自己就是用算法代码拯救世界的英雄一般,瞧不起任何系统软件开发者。他们闲暇之余混迹在大大小小的闲聊群里,张口闭口向过路的小白普及着各种诸如贪心,回溯,生成树的名词的解释,忙的不亦乐乎。

有一天,我就心血来潮翻了翻他们的 GitHub,这下给我人都看傻了:
原来他们所谓的高效率算法是这样写的:

1
2
3
int A[10001];
int B[10001];
/* ... */

哈,哈哈,哈哈哈

编程语言工具论

一个朋友曾经跟我说“编程语言只是验证算法是否正确的工具”。

然而,编程语言真的只是验证算法的工具吗?

显然不是。无论描述算法的论文再厉害,最终实际运用到工业环境中时,一样要取决于编程语言。同样的算法,同样的编程语言,不同的编码实现往往都会带来大小不一的性能差距。

在工业环境下,评定算法好不好的标准绝不仅仅只是一个“是否正确”,更多情况下我们要考虑算法的“健壮性”,“拓展性”,以及最重要的,“可维护性”。我是一个对“美”有自己的见解的人,如果是我做 Code Review 的代码,我往往还会要求代码实现的“优雅大方”。

健壮性,指的是一个算法在面对所有可能的输入情况时都能给出正确的结果或者友好的报错。我说的所有可能的输入情况绝对不是那些 OI 平台上所谓的“数据约定”,而是一个测试工程师走进了一家酒吧…

拓展性和可维护性,指的是一个算法在日后面对更多复杂情况时,能否不加改动就支持新的变化。举个例子,如果让我实现一个 List,我在一开始就会去考虑:这个 List 内部存放的数据具有什么特性的时候,我的 List 应该怎么实现去配合这些特性来写出性能更高的实现。而反观上面那些“唯算法灵魂论”的人,他们之中往往都是写了一个这样的代码就觉得自己真的实现了一个 List

1
2
3
4
struct List {
List *next;
int data;
};

甚至还有一个国内顶尖高校的研究生写出了类似这样的代码:

1
2
3
void doit() {
int a[10000];
}

我还有什么话好说呢?

你们管这种垃圾叫算法?对不起,没进过生产环境的代码,都配不上叫算法。

至于代码的“优雅”,我想,肯定不会有人觉得上面那些代码都是优雅代码吧。

哈,哈哈,哈哈哈

真的如此不堪吗?

真的如此不堪吗?当然不。

你也能想到,有“唯算法灵魂论”这种想法的人,在算法上又能走多远呢?

真正的大佬眼中从来就不会认可什么“编程语言工具论”或者“唯算法灵魂论”之类的说法,我读过的有关 GC 算法的论文中,几乎每种实现都会考虑到 Java 语言的特性,甚至 JVM 的实现方式。

编程语言工具论,可休矣。
唯算法灵魂论,可休矣。

巨人?

1
let A = "算法才是灵魂,做软件没有技术含量,编程语言只是工具";

持有 A 想法的人往往觉得自己是在做创造性的工作,设计各种算法,把“刷题”看作“解决实际问题”。

然而事实上,这些人所谓的“设计算法”,也只不过是把脑中一些因为写过无数遍而肌肉记忆的代码背诵出来,再套上题目中的数据。

这跟他们嘲讽软件工作者的时候所用的说辞:“做软件不久只是复制粘贴” 有什么本质上的区别呢?

大家都是站在巨人的肩膀上,那些站在了更高的巨人的肩膀上的上的人,又有什么资格瞧不起我们这些站在了更低的巨人的肩膀上的人呢?

领域不同,请不要自以为很懂。你懂个🔨

你们也许站在了更高的巨人上,但你还是个矮子,甚至,傻子。

对矮子们的话

我想对那些仍然持有 A 想法的人说:

请开阔自己的眼界。不要做井底之蛙

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章