打算给本科生教授一门名为“计算机编程概论”的课程。我有点困惑。在计算物理学中,科学家们使用 C/C++ 或 Python 或 Fortran、CUDA 等......这是建立他们的基础的时候了。我应该使用什么?我知道您可以在生活中的任何时候学习新的编程语言,但对我来说,稍后详细阐述所有基本的编程概念和 OOP 概念对我来说是更明智的选择。
在教授计算机编程本科课程时应该使用什么语言?
首先,如果你的本科生和我们一样,并且没有事先了解计算机,希望花一些时间教他们如何使用基本的东西,比如使用适当的编辑器(即,不是 MS Word)、命令行等。
我认为答案在某种程度上取决于您将课程重点放在哪里(或您需要教什么)。例如:计算机内部工作的相关性如何?您需要类和其他高级 OOP 结构吗?你想教他们如何制作高效的程序,或者如果他们制作了工作程序,你会感到高兴吗?另外,不要忘记您很可能需要有能力的导师。
但现在有些语言的优缺点,我很熟悉。请注意,这主要来自我作为计算物理学家的经验,其中一些可能取决于特定领域、工作组、大学等。
Python
我通常建议从一开始就使用 Numpy,并且我假设它会在下面使用。
好处:
- 它很容易学习,阅读其他人的代码也很容易(例如,您的示例代码,还有学生为导师编写的代码)。
- 输入和输出(这不应该是你课程的重点)可以完全被
print
Numpy 的savetxt
和loadtxt
,也许sys.argv
. 它可以即时引入,并且不会占用太多编程时间。 - 您不需要处理或只需要处理很少的细节,例如数字表示、内存管理、数据类型。因此,它的编程速度很快,您可以专注于实际的算法。
- 它不是一种编译语言。这有两个好处:学生不需要处理编译器,学生可以直接在控制台中测试东西,而无需编译、重新启动和重新运行程序。相关地,调试更容易。
- 几乎所有东西都有易于使用的库。
- 你不需要学习额外的脚本语言,比如 shell 脚本、Make、Gnuplot 等等——所有这些都可以在 Python 中完成。
- 有很多很好的教程(免费)。
缺点:
- 它没有编译。因此,在某些与计算物理相关的情况下,Python 程序可能比编译程序慢得多。然而,在其他情况下,库(尤其是 Numpy)可以产生相当的性能。另一种使用 Python 获得良好性能的方法是用另一种语言(如 C¹)编写相关的代码片段。显然你需要为此学习这门语言,但这可以在以后完成,你学习 Python 的时间不会浪费。
- 教授数字表示、内存管理、数据类型及其陷阱等细节更加困难,因为它们有些模糊。
C/C++
好处:
- 它是经过编译的,因此更容易生成高效的代码。
- 您正在直接处理数字表示、内存管理、数据类型,因此教授这些内容更直观——您的学生将更接近他们计算机中真正发生的事情。
- 基本上所有东西都有图书馆,但理解和使用图书馆需要一些工作。
- C/C++ 中存在相关数量的现有代码,因此如果学生想要使用此代码,则需要学习该语言。
- 如果您已经了解 C/C++,您可以非常快速地学习 Python(例如)。
缺点:
- 它是经过编译的,您的学生必须处理编译器、预处理器、头文件等。即使在学期结束时,您也会惊讶于有多少学生在这一步失败。
- 学习速度也较慢,生成工作代码需要更长的时间。
- 处理诸如输入和输出之类的边际内容在教学和编程中都需要一些时间。在 C++ 中,输入和输出有一个额外的语法。
- 编译器和操作系统依赖项。
- 你必须处理 C/C++ 的混乱。
- 由于大量的语法特性,阅读其他人的代码,尤其是 C++ 中的代码可能非常困难。
C++ 相对于 C(类、模板)的主要优势不应该与您的课程相关,而只会与较大的项目相关。因此我会选择两者中的C,因为它更简洁。
其他
对其他语言的一些评论:
- Fortran:许多团体仍在使用它,并且有很多遗留代码,但是您无法避免处理旧标准及其巨大的局限性和陷阱(很多人仍在使用 Fortran 77)。此外,在 Internet 上查找教程、帮助等将变得更加困难。
- Matlab/Mathematica:专有软件的所有问题。特别要考虑到您的学生可能会与无法访问此软件的人合作以及随之而来的问题。
- Cuda:这仅与某些问题有关,如果性能很重要的话。另外,据我所知,您不想以这种方式学习编程。
¹ 至少在我们的团队中,这是标准的工作流程。
在 2014 年,我会说 Python。2017年,我坚信教本科生的语言是Julia。
教学总是要权衡取舍。一方面,你想选择简单易懂的东西。但其次,你想教一些有持久力的东西,即可以和你一起成长的东西。常见的动态语言(Python/MATLAB/R)由于它们不存在样板代码以及易于打开解释器和吐出代码而很容易落入第一类,而 C/C++/Fortran 则属于第二类编写当今世界核心高性能软件的语言。
但是使用不能完全捕捉其他类别的语言存在问题。当使用像 Python 这样的语言时,它可以很好地抽象出类型和整数溢出之类的东西。这对于教授第一学期的计算很有好处,但是当你想越来越深入地了解事物的实际工作方式时,Python 的语言与底层金属太抽象,无法成为一个好的教学工具。但是 C/C++/Fortran(或 Java……我先学 Java……)都有如此高的启动成本,以至于最难学习的就是如何设置和main
编译标头,这会分散实际学习编程的注意力.
进入朱莉娅。当您第一次使用 Julia 时,您可以抽象出类型的整个概念,并像使用 MATLAB 或 Python 一样使用它。但是当你想了解更多时,语言有一个深度的“兔子洞”。由于它实际上是一个基于类型系统 + LLVM 上的多次分派的抽象层,因此它本质上是“一种编写静态编译代码的简单方法”(并且类型稳定的函数实际上可以静态编译)。这意味着 C/C++ 的详细信息也可以访问。您可以学习如何在没有样板代码的情况下编写简单的循环和函数,然后深入研究函数指针。Julia 的元编程功能让您可以直接访问 AST,并且有显示编译链每个部分的宏。此外,作为 Lisp,它适用于函数式编程风格。并且它具有很多并行计算能力。像参数类型和类型稳定性这样的想法在 Julia 中是相当独特和深刻的。
如果你想自己学习编程语言,你可以通过使用@code_lowered
来了解编译工作的步骤,看看什么是降级,看看 typed-AST with @code_typed
,看看 LLVM IR with @code_llvm
,最后看看原生汇编代码 with @code_native
。这可以用来展示动态变量的成本是多少以及“变量装箱”的工作原理,这篇博文展示了如何使用这些自省工具来教授编译器优化如何发生/不能发生。
不仅有计算机科学和软件工程思想可供探索,还有丰富的数学思想。由于 Julia 的主要库在编写时考虑了泛型类型,因此创建无矩阵运算符并使用 IterativeSolvers.jl 使用它们执行 GMRES 是很简单的。您可以使用内省工具,例如@which
向您展示具体是如何实现的。例如,如何\
工作?
@which rand(10,10)\rand(10)
#\(A::AbstractArray{T,2} where T, B::Union{AbstractArray{T,1}, AbstractArray{T,2}} where T) in Base.LinAlg at linalg\generic.jl:805
这直接指向了 \ 的定义。它是在 Julia 中实现的,因此了解 Julia 的人可以通过识别矩阵子类型并在可能的情况下进行专门化(回退到高斯消元法)来学习算法及其工作原理。由于 Julia 的代码是 MIT 许可的(几乎所有的包都是 MIT 许可的),学生可以在他们自己的代码中自由使用这些想法(带有归属地)(当代码是 GPL 许可时,就像大多数 MATLAB 和 R 包的情况一样,他们需要小心许可问题!)。
由于语言核心是由一个非常活跃的开源社区构建的,因此也有关于语言发展历史的丰富资源:它的 Github 问题。理解语言问题,比如什么是矩阵转置?对于更详细地理解这些数学对象可能非常有启发性。
但最后,你想教你的学生如何创造。可悲的是,学习 Python 或 R 并不一定意味着您具备“开发 Python/R”所需的条件,因为大多数广泛使用且经过良好优化的软件包中都有大量的 C/C++/Fortran 代码按顺序排列获得性能。因此,为了让这些学生能够为这些语言的科学生态系统做出贡献,他们最终将不得不在某个时候学习另一种语言。虽然这并不完全糟糕,但现在 Julia 的存在并不是最理想的。由于类型稳定的 Julia 能够达到 C/Fortran 的速度,因此 Julia 生态系统中的大多数包都是纯 Julia 代码。学习 Julia 意味着一个人已经学会了开发 Julia。而且由于 Base Julia 也主要是 Julia 代码(只有几个原语,而解析器不是),
也就是说,选择 Julia 有一些缺点。一方面,它比这些其他语言更新得多,因此资源更加稀缺。你必须自己想出很多教学工具,或者从Julia 网站上列出的网络资源中提取。此外,虽然 1.0 即将发布(到 2017 年底),但语言细节还没有完全确定。而且,作为 Julia 课程的潜在教师,您也很可能对这门语言没有太多经验。然而,这些问题会随着时间的推移而消失,而我上面提到的 Julia 的好处对于语言本身来说更为核心。
作为一个离得不远的本科生,假设你不是在 CS 系教书,我认为向学生介绍使用 C、C++ 或 Fortran 之类的计算机编程(或上帝保佑)将是一场灾难CUDA),尽管其他人指出它们可能是科学计算的现状。
如果您希望教学生科学计算并在同一门课程中向他们介绍编程,我敢打赌,除非您坚持使用 matlab 或 python 之类的解释性语言,否则这在一个学期内无法涵盖。根据我的经验,大多数本科阶段的科学计算课程都是用这两种方法中的一种来教授的,而且 Python 作为一种生产级语言每天都变得越来越有用,所以它仍然具有一些实用性技能(我的意思是,不仅仅是教授编程基础知识)。
只是我的两分钱。
如果您想解决超级计算机上的大问题,C、C++ 和 Fortran(排名不分先后)是用于计算数学/物理的三种主要编程语言。我认为 CUDA 被认为是一个与其他语言一起用于加速 GPU 计算的库。Matlab 和 python 非常适合学习运行输出诊断和创建原型模型。它们也更容易学习,并且可能更适合您想要学习算法而不是学习如何编程的课程。
因此,如果你的课程纯粹是关于编程的,我会选择 C++,或者,如果这是学生第一次编程,我会选择 Python。这两种语言在科学计算领域之外都具有很高的实用性。如果课程的重点是学习算法来解决基于物理的问题,那么我认为 Matlab 无疑是赢家。