来自更数学的背景,我从未真正学会过编码。我正在TCS攻读博士学位,许多人对我对编程(以及一般计算机)了解甚少感到惊讶。我可以用伪代码编写算法,但是我真的不知道任何编程语言。
我可以想象有一天我可能必须为我的工作实现一些算法,但是我可以等待这一刻吗?还是还有其他东西?
知道如何在TCS中编码(在不直接涉及编程的领域中)有多重要:是否有某些原因可能会使CC理论家(例如)知道如何编码?值得花费大量时间学习如何编码吗?如果有的话,是否有更适合的编程语言类别(函数式,命令式,面向对象..)?
来自更数学的背景,我从未真正学会过编码。我正在TCS攻读博士学位,许多人对我对编程(以及一般计算机)了解甚少感到惊讶。我可以用伪代码编写算法,但是我真的不知道任何编程语言。
我可以想象有一天我可能必须为我的工作实现一些算法,但是我可以等待这一刻吗?还是还有其他东西?
知道如何在TCS中编码(在不直接涉及编程的领域中)有多重要:是否有某些原因可能会使CC理论家(例如)知道如何编码?值得花费大量时间学习如何编码吗?如果有的话,是否有更适合的编程语言类别(函数式,命令式,面向对象..)?
Answers:
理论计算机科学是一个广阔的领域,编程的重要性取决于您在TCS中所做的工作。我将提到编程可以帮助您的两种方式,但并不意味着这是唯一的方式。
首先,如果您针对具有实际重要性的问题设计算法,那么实现您的算法并将代码提供给其他人可能是一大优势。例如,凸包问题出现在许多领域,人们用诸如软件包CDD通过公明福田和LRS由大卫·阿维斯来解决这个问题。如果他们只在论文中发表算法,那么使用该算法的人可能会更少。更多的用户意味着更多的反馈,可能还会有更多的合作机会,这是无价的。
其次,即使您不使用算法,编写一次代码也可以帮助您在适合于数值计算的情况下测试简单的猜想。例如,如果您想知道三个正定矩阵的乘积是否始终具有正迹线,那么很容易编写代码以对2×2或3×3个正定矩阵的一些随机选择进行测试,并找到一个反例。尽管您并没有宣传自己编写了任何程序来测试这种猜想,但编程可以节省那些徒劳无益地试图证明错误陈述的时间。
选择的编程语言取决于您要进行编程的工作,在我看来,这可能是整本书的主题。但是,如果您设计算法并想实现自己的算法,以便其他人可以使用该实现,那么一个重要因素就是可用性。尽管可以期望代码的大多数潜在用户可以访问C编译器,但是不能期望同一个人可以访问Haskell编译器。对于一次性程序,选择更多是基于可用的库,并且包括Matlab等环境。
顺便说一句,编程也很有趣。
我感到不得不在此引用Doron Zeilberger:
意见37:编程比证明更有趣,而且更重要的是,它提供了很多(如果不是更多的话)洞察力和理解力。
阅读该意见,其中充满了宝石(但他倾向于故意挑衅)。例如,“了解某物的最好方法是教它。但是比对人类教它更好的是将其教给计算机”。
我的个人经验是,即使仅做理论性的工作,也需要一些计算工具。我避免使用Mathematica进行许多繁琐的常规代数运算。我通过在Matlab或Python上强行强制小实例来测试半生不熟的猜想。我与他人合着了一篇纯粹的组合学论文,而这项工作受益于运行大量的计算机实验以了解正在发生的事情而受益最大。欧拉制作了大量冗长的计算表,以深入了解问题。我们应该归功于他在进行数学运算时使用我们的工具来自动化该过程。
除此之外,如果您要研究算法和数据结构,编程将在效率和可用性问题上提供无可替代的观点。我在这里的观点与其他人有所不同。我认为学习功能性语言以使您能够正确地写出类型正确的证明是浪费时间(我认为拥有强类型语言经验的人可能倾向于编写更仔细的结构化证明是很重要的一点;我只是不愿意认为您不值得花时间进行这项练习)。函数式编程模糊了算法设计和运行时间,并强调了逻辑和语义问题(当然,学习函数式编程可能是必须的,如果您对逻辑/ PL语义感兴趣的话,会自然而然地出现)。同样,我认为进入Java和C ++的OO详细信息也不是花费时间的最佳方式,因为OO的目的是编写模块化可重用代码。如果您要生成供他人使用的代码,这就是方法。但是如果您想深入了解效率和运行时间,如果您关心真正高效的算法和数据结构,我建议您考虑使用C。它可以使您在保持接近机器的同时仍提供合理的抽象水平。 。通过这种方式,您可以了解快速和慢速,什么是合理的数据结构等。但是如果您想深入了解效率和运行时间,如果您关心真正高效的算法和数据结构,我建议您考虑使用C。它可以使您在保持接近机器的同时仍提供合理的抽象水平。 。通过这种方式,您可以了解快速和慢速,什么是合理的数据结构等。但是如果您想深入了解效率和运行时间,如果您关心真正高效的算法和数据结构,我建议您考虑使用C。它可以使您在保持接近机器的同时仍提供合理的抽象水平。 。通过这种方式,您可以了解快速和慢速,什么是合理的数据结构等。
您无需编程即可成为非常成功的理论计算机科学家。对于少数人来说,编程是非常困难的,如果您是其中的一员,则不要绝望和切换字段。
但是,对于大多数数学和计算机科学专业的研究生来说,学习编程并不是特别困难,并且是一项非常有用的技能。您应该学习一种编程语言,并且如果喜欢的话,应该尝试进行足够的练习以变得相当熟练。然后,当谈到(并且将会)在您的研究中编写程序很有用时,您就可以做到。
如果您现在不学习编程,那么很有可能在您最终需要编写程序时,您将没有时间学习,因此您可能实际上没有编写程序,最终在您的工作中效率降低了。研究。虽然让一个研究生或一个本科生为您做这件事并不难,但在很多情况下,自己做而不是向他们解释问题要容易得多,耗时少。
您应该学习哪种语言?我建议使用一种面向对象的语言,因为这些是当前使用最多的语言,我怀疑将来这会更加正确。也许是Python或Java,它们都是面向对象的语言,尽管在实践中它们的使用量少于C ++,但我的印象是它们都非常容易学习。(注意:尽管我在Bell Labs工作过,但我并不了解C ++,所以也许我对此有误。)
还有一个答案,没有人真正提出过。编程实际上可以导致有趣的理论。散列(尤其是制表散列)方面的许多最新发展并不是出于理论上的考虑,而是由于理论上最优的算法在实践中并不那么出色。除非您可以编写代码,否则这当然是您不知道的。
即使在精确的指数时间算法领域,一种动机仍然是产生可以实际起作用的算法。SAT求解器就是一个典型的例子。
简而言之,编码能力使您可以了解最佳理论结果中的缺点和不足,从而为理论研究开辟了新的方向。
三点:
1)有一种称为“ 实验数学”的数学方法(另请参阅Wikipedia://计算机辅助证明),您可以在其中使用计算机程序来研究对象的模式和结构,以便得出有关这些对象的分析证明。对于这种方法,您最好知道如何编程。您可以确定您将需要这种方法来证明非常理论上的陈述。我相信,反对编程的势利往往不会对TCS研究产生真正的帮助。
3)当您说“至编程”时,是指“至线性程序 ”还是“至半定程序 ”?:)
谢谢Gopi这个问题。我想在一个尚未提及的维度上扩展许多有趣的答案。
研究不是我们在大学里唯一要做的事情:如果您想留在学术界,最终将不得不教书。如果幸运的话,您必须教授与专业领域相距甚远的课程。您很可能会被分配具有实质性编程内容的课程。在这里,即使是中等的编程能力也可以大大帮助您:如果您知道如何编程,您会成为更好的老师。首先,您将对材料更加熟悉,将能够更好地回答学生的问题,并且您将了解自己在学习编程过程中遇到的困难,因为您自己经历了这一学习过程。此外,您可以制作更好的教材。例如,您可以在将编程练习提供给学生之前自己进行测试,
还有一个实用的方面:教学涉及熟练的程序员经常可以自动化的各种重复性任务,例如快速建立一个网站供学生用来提交课程并对其进行自动评分(根据代码通过的自动测试的数量)。
编程是提高您对各种概念的理解的好方法,但是它也是一个危险的时间消耗。
反对编程的一个典型论点是,它使您花费大量时间花费不重要的细节。一个典型的说法进行编程是它让你意识到你认为细节是不重要的其实都是很重要的。擅长编程主要意味着能够迅速处理不重要的部分。成为好人需要很长时间。
至于要学习的编程语言:“所有人”都是我的回答(嘲笑)。
我来晚了,这些都是很好的答案,但是我还有另一个原因:
可视化。
是的,通常您将使用无法可视化的内容,但是通常您将使用可以可视化的内容。知道如何编程对于该任务是必不可少的,而可视化可以使您对问题有很多了解。
这里没有人解决过一些实际的问题,即为什么学习TCS的人应该学习编程。
如果您打算在计算机科学系的TCS攻读博士学位,那么您很有可能需要参加一些非理论课程,而且这些课程几乎肯定是编程密集型课程。根据您所修读的课程,您可能还需要非理论科目的知识才能通过资格考试。
完成博士学位后,TCS的大多数工作机会都来自学术界。如果您在学术界工作,就应该教书,并且可能要教入门级的本科CS课,这比理论编程要重要得多。即使您正在向本科生讲授理论课,例如“算法”,您也可以期望您的学生会比理论了解更多的编程知识,并且不了解学生的知识,就很难弥合他们在理解方面的差距。我对CS本科生被一个不懂编程的人所教的想法感到震惊!
如果您不关心这些实际问题,那么您可能无需真正了解编程就可以进行研究。当然,您在TCS社区中有很多公司,但是里程会根据您所从事的理论的确切领域而有所不同。例如,如果您在进行纯计算复杂性理论,则证明没有人拥有的类的下限听说过,那么编程可能对您毫无用处。但是,如果您正在做更多的算法工作,那么我认为能够编写出良好而干净的工作代码将增强您的直觉。
我建议学习C(不是C ++)。拿起K&R的副本并从头到尾阅读。C没有现代语言的许多奇特功能,但确实具有简单但优雅的语法和语义,您应该可以全面学习。但是,即使您完全理解该语言,仍然需要实践才能熟练地用C编写精美的无错误代码。但是,如果您可以熟练地使用C进行编码,则您将能够掌握所遇到的任何编程语言。此外,该学科将帮助您思考硬件的想法,这在设计算法时将是有益的。
指针之类的思想对于进行算法设计的任何人都非常重要,但是不幸的是,Java和Python之类的语言使您难以理解它们,因此,我不建议将其作为具有数学背景的人的第一语言。对于必须维护大型软件项目的人员,而不是设计算法的人员,OOP更为重要。
我建议您不要等待课程的开始,因为任何水平的计算机科学都涉及通过计算机实现算法,以便完成/验证/解决您在整个课程中必须面对的任何理论,尤其是在您的水平上。
我必须首先在10年级(高中)编程,而且我已经知道如何使用命令行,这确实有所帮助(这是向您展示如何在CS中考虑“基本”编程技能)。
同行的惊讶是有充分根据的,因为伪代码和算法是编程的第一要学的知识。
但是,您不会在即将开始的课程中完全迷失,因为您可以利用自己的广泛数学技能(自己)来跳过面向对象的编程,从而更快地学习函数式编程语言。
我认为您可以解决Haskell(通常不是第一语言),因为它纯粹是数学,函数式的,基本上可以完成您想要的任何事情。学习Haskell将使您处于一个无需学习更多知识即可掌握的水平,甚至会使您处于对课程的控制和控制之下。如果您喜欢统计学,那么学习R是一个加分,但没有Haskell多。我看到数学家的报告说,他们对它对数学的亲近感以及它如何接受他们的思维方式感到惊讶。
另外,一个值得解决的挑战(使您快速适应编程环境)将是安装和使用Linux(Ubuntu Linux会做到)。相信我,您会通过学习而学到很多东西...
对于计算机科学领域的数学家来说,这些建议是我所知道的快速,可靠地赶上的最佳方式。此外,开源社区非常友好且乐于助人,如果您受阻,IRC是通过专门渠道(在FreeNode上连接)谈论任何主题的最直接方法。请记住:提问是解决问题的唯一方法,无论是对自己,论坛,搜索引擎还是在聊天室中。
以下论文是交互式证明系统的C ++实现的一个示例:贾斯汀·泰勒(Justin Thaler)的用于电路评估的时间最优交互式证明。可从http://people.seas.harvard.edu/~jthaler/获得。这似乎是朝着开发通用交互式证明系统的实际实现这一目标迈出的一步。
类似的论文和相关的源代码出现在上述网站上。