在课堂上,我们学习了停机问题、图灵机、约化等概念。很多同学说这些都是抽象无用的概念,知道它们没有实际意义(即,课程结束后可以忘记它们而不会失去任何东西)。
理论为什么有用?你是否在日常编码中使用它?
在课堂上,我们学习了停机问题、图灵机、约化等概念。很多同学说这些都是抽象无用的概念,知道它们没有实际意义(即,课程结束后可以忘记它们而不会失去任何东西)。
理论为什么有用?你是否在日常编码中使用它?
真实故事:
当我从研究生院毕业后得到我的第一份编程工作时,我所工作公司的老板是飞行员。在我入职几周后,其中一个老板问了我这个问题:
阿肯色州有106个机场。 你能写一个程序,找出降落在每个机场所需的最短路径吗?
我当时认为他在考验我对于旅行推销员问题和NP完全性知识的掌握。但结果表明他并不知道这些。他真正想要的是一个能够找到最短路径的程序。当我解释说有106的阶乘种可能性,并且找到最佳解决方案是一个已知的计算难题时,他感到惊讶。
这就是一个例子。
当然,它很有用。
想象一个开发者正在开发一个模板引擎。你知道那种东西……
Blah blah blah ${MyTemplateString} blah blah blah.
它最开始很简单,只是用一个调皮的正则表达式来执行替换。
但渐渐地,模板变得更加复杂,开发者添加了对字符串列表和映射的模板化特性。为此,他编写了一个简单的语法,并生成了一个解析器。
非常巧妙的是,模板引擎最终可能包括一种条件逻辑语法,根据参数的值显示不同的文本块。
具有计算机科学理论背景的人会意识到,模板语言正在逐渐变得图灵完备,也许解释器模式是实现它的一种好方法。
构建模板的解释器后,计算机科学家可能会注意到,大部分模板请求都是重复的,一遍又一遍地生成相同的结果。因此,开发了一个缓存,所有请求在执行昂贵的转换之前都会路由到缓存中。
此外,有些模板比其他模板复杂得多,渲染需要更长时间。也许有人会想到,在渲染之前估计每个模板的执行时间。
但等等!!!团队中的某个人指出,如果模板语言真的是图灵完备的,那么估计每个渲染操作的执行时间的任务就是停机问题的一个实例!!糟糕,不要那样做!!!
关于理论,实践上所有的实践都是基于理论的。从理论上说。
当我大学毕业时,我认为自己和其他人处于同一水平:“我有计算机科学学士学位,许多其他人也是如此,我们基本上都可以做同样的事情。” 然而,我最终发现我的假设是错误的。我脱颖而出,而我的背景与此有很大关系——特别是我的学位。
我知道有一个“轻微”的区别,那就是我有一个计算机科学“学士学位”,因为我的大学是全国第二所获得计算机科学专业认证的学校之一(据说是在1987年),我是第二个获得该认证的班级的毕业生。当时,我认为这并不重要。
在高中和大学期间,我还注意到,在计算机科学课程方面,我表现特别好——比我的同龄人甚至比许多老师都要好。我经常被人请教,做过一些辅导工作,被要求协助研究项目,并被允许在没有其他人参与的情况下进行自主研究。我很高兴能够帮助别人,但我并没有想太多这种差异。
大学毕业后(美国空军学院),我在空军服役了四年,其中两年应用了我的计算机科学学位。在那里,我注意到很少有同僚拥有与计算机相关的学位或培训经历。空军将我派去接受为期五个月的认证培训,在那里我再次发现缺乏学位或培训。但是在这里,我开始注意到不同之处——显然,我遇到的许多人并不真正知道他们在做什么,这包括那些接受过培训或拥有学位的人。请允许我举个例子。
在我参加的空军认证培训中,共有十三个人(包括我)。作为空军军官或相当职务的人,我们都拥有学士学位。根据年龄和军衔,我排名中等(我是六个O-1和六个O-3以上的人中间的一个O-2)。在此培训结束时,空军将我们所有人一视同仁地认为能够获取、构建、设计、维护和操作国防部任何部门的任何计算机或通信系统。
然而,在我们中的十三个人中,只有六个人拥有任何形式的与计算机相关的学位;其余七个人拥有从航空学到化学/生物学再到心理学的不同学位。在我们六个拥有计算机科学学位的人中,我了解到有两个人从未编写过任何类型的程序,也从未像使用电脑那样频繁地使用过电脑(写论文、玩游戏等)。我了解到另外两个人只在他们的计算机科学专业课程期间编写了一个程序。只有我和另外一个人编写了多个程序并使用多种计算机——事实上,我们发现我们俩都编写了很多程序并使用了多种计算机。
在我们为期五个月的培训即将结束时,班里被分成四组,各自承担一个编程项目。为了公平分配“编程天才”,我们的导师们将班级划分,并分配团队领袖、技术领袖和开发人员的角色。每个小组被要求在一周内使用Ada实现(这是1990年)一个全屏幕、基于文本的用户界面,用于一个由导师提供的飞行力学库的模拟器。我被分配为我的四人团队的技术领袖。我最常使用的技术:
至于图灵机等方面的内容,我认为这很重要,因为它定义了我们所有人所操作的约束条件。这很重要需要被认识到。
这就像学习代数和学会使用计算器的区别。
如果你懂代数,你会意识到同一个问题可能以不同的形式呈现,而且你也了解如何把问题转化为更简洁的形式的规则。
如果你只知道如何使用计算器,你可能会在一个已经被解决的问题上浪费很多时间,或者是对于一个无法解决的问题一直按键,还有可能是遇到一个与其他问题相似(已解决或未解决)但你因为问题形式不同而无法识别的问题。
如果假装计算机科学是物理学……那这个问题是不是看起来很傻?
虽然我在日常工作中没有直接应用它们,但我知道我的正式计算机科学教育影响了我的思维过程。因为我受到正式方法的教导,我能够从一开始就避免某些错误。
他们在学习时可能觉得这些知识毫无用处;但我敢打赌,你的同学最终会遇到一个问题,他们会运用所学的知识,或者至少是背后的思维模式...
上蜡...下蜡...上蜡...下蜡...这跟空手道有什么关系呢?
我从计算机科学专业毕业后也曾认为,我们所学的理论在实践中完全没用。然而,在处理复杂任务时,理论却比实践更有价值。几年编程经验后,每个人都可以写出一些“可行”的程序,但并不是每个人都能理解其中原理。不管怎样,我们大多数人在某个时间点都会遇到性能问题、网络延迟、精度、可扩展性等等。此时,理论显得尤为关键。为了设计一个好的解决方案,就必须了解内存管理的工作方式,进程和线程的概念,以及如何将内存分配给它们,或者高效数据结构以提高性能。
例如,有一次我正在开发一个包含大量数学计算的项目,但软件失败了。调试时,我发现某些数学运算会返回一个值为 1.000000000002 的 double 类型数字,但从数学角度来看,它不可能>1。这个问题在程序的后续阶段引发了传说中的NaN异常。我花费了一些时间才找到问题所在,但如果我更加注意「Double 和 Float 的近似」这节课,那么就不会浪费那么多时间了。