教导自己,作为物理学家,成为一名更好的程序员[关闭]


17

我一直很喜欢物理学,也一直喜欢编码,所以当我获得大学博士学位时提供数值物理学的职位(细节不相关,主要是集群的并行编程)时, -我的脑子

但是,像大多数物理学家一样,我是自学成才的。我没有关于如何以面向对象的方式进行编码的广泛背景知识,也没有在某些kD树中优化搜索的特定算法的名称。

由于到目前为止我的所有工作都更加关注物理学和科学成果,因此毫无疑问我有一些不良习惯- 尤其是因为我的编码是我自己的,而不是真正的团队合作。我主要使用C,因为它非常简单,而且“您写的就是您所得到的”-不需要花哨的抽象。但是,由于我想进一步了解抽象所具有的功能,因此我最近改用了C ++,它非常像C(至少在语法上)。

我该如何像计算机科学专业的毕业生那样以一种良好的抽象方式自学编程呢?

我知道我的代码是高效的,但我希望它也要优雅,可读。请记住,我没有时间阅读关于抽象编程的几本1000页的书。我需要花时间进行与物理相关的实际研究(如果我的主管知道我花时间考虑如何优雅地编程,我的主管会嘲笑我)。如何从程序员的角度评估我的工作是否还不错?


12
一个问题:您如何知道您的代码有效?
Matsemann,2012年

我见过很多人拒绝使用C ++作为第一类面向对象语言。我正在学习Java,并且在eclipsetutorial.sourceforge.net/totalbeginner.html找到了Mark Dexter的视频教程,它们非常好,并且会以TDD方式教您。还请查看Head First Java,它以OO方式掩盖Java相当不错。
加夫2012年

4
@DeveloperDon,即使在没有电子计算机之前,计算仍是物理学的中心部分。可以通过手动或机械计算器进行计算。自从第二次世界大战以来,物理学家一直深深地涉足软件。如果您正在计算彗星的返回,模拟核链反应中的中子产生,或分析千兆字节的数据以寻找希格斯玻色子的迹象,则必须进行大量的数字运算。早在1974年,我第一年物理实验室的上半年就致力于教授FORTRAN。
查尔斯·格兰特

1
@DeveloperDon例如,当CERN的物理学家获取数据时,他们从数百万次粒子碰撞中获取数据。您需要一台计算机来处理此信息量。还要考虑一个类似于固态物理学的领域,在这里您试图从原子的微观相互作用中了解材料的宏观特性。在这样的系统中,单个电子会受到数十亿个原子核和电子的排斥/吸引,要准确地描述这样的系统,您需要快速的计算机和高效的算法(以及基本方程式的良好近似)。
user787267 2012年

1
也许您应该将语言从C / C ++更改为Python,以便有更多时间?科学家经常使用 Python ,其中有类似NumPy的模块,可使用PythonSciPy 进行科学计算。如果您需要Python中C / C ++的速度,然后使用Cython,它允许您使用C / C ++类型和结构,从而获得与C / C ++类似的速度,并且还可以轻松地使用Cython与现有C / C ++库集成。
Czarek Tomczak 2012年

Answers:


20

请记住,我没有时间阅读一些有关抽象编程的1000页的主题。

那么,您是否要求某人给您提供五步检查清单,以使您成为熟练的程序员?那不会发生

与其他学科一样,如果您想擅长编程,则必须花费时间和精力进行练习和学习。您将通过编写大量代码并仔细阅读他人的代码来学习编写清晰,优美的代码。通过总结其他人所学到的艰辛的经验,这1000页书中的某些书实际上可以节省您的时间。认为您可以成为一名熟练的程序员,这是获得物理学博士学位的无痛副作用,这是一种幻想。这并不是说您不能脱离物理学博士学位。拥有疯狂的编程技能,这只会花费您的时间和麻烦。

Code Complete是对软件开发机制的很好的介绍,包括有关如何编写和构建清晰,可维护的代码的建议。是的,这是一个巨大的书,但是它肯定不像狄拉克的《量子力学原理》或MTW的《引力》那样稠密。代码完成与您将获得一份五步清单来编写更好的软件一样接近。

Matlab,VIM,C,MPI和Valgrind是了解的出色工具。您没有提到使用版本控制系统。如果偶然发现您尚未使用版本控制系统,则必须立即开始使用版本控制系统。版本控制也是撰写论文的绝佳选择。您应该知道的其他基本工具是调试器,执行分析器,日志记录框架和单元测试框架。您不必为每本书都读一千页的书。完成在线教程,以获取基础知识,然后开始使用它们。随着您的需求变得越来越复杂,请更深入地研究文档。

为您提供有关学习计算机科学基础知识(相对于软件构建基础知识)的建议更加困难。无论是开发新算法还是应用现有算法,都无需指定正在解决的问题。根据您的研究问题,对基本数据结构和标准算法进行调查可能会有所帮助。其他问题将从数值分析的扎实背景中受益更多。如果您确实想学习算法分析的基础知识,则可以找到几本不错的文章。想到了《算法设计手册》《算法简介》。现在,在线上还有两本很好的入门课程:算法的设计和分析,以及算法


感谢您提供的链接,我将对其进行调查。我知道我不会在周末成为一名编码专家,但是我希望随着时间的推移会逐渐提高-尤其是如果我从物理学之外寻求启发(因为我认识的许多物理学家都不会在乎良好的编码习惯)。
user787267

1
我会在工具中添加python作为可读计数
Xavier Combelle 2012年

2
+1表示代码完成。操作人员阅读并解决有关问题确实是最好的选择。
2012年

9

我的背景和您的背景有些相似-我是一名物理专业的毕业生,自学编程。毕业后,我从事一些IT工作,最终成为一名软件工程师。包括在OpenGDA(用于在各个Synchrontron站点上运行实验的软件)上工作的时间。

我在来到这里时所遇到的问题的主要知识是,从他人那里获得这些技能比尝试自己掌握这些技能要容易得多。经验丰富的导师可以轻松地帮助您确定代码的弱点或常见的模式和实践可以帮助您的地方。当我学会了如何自己编写C和Objective-C时,直到与其他人一起使用同一代码之前,我才不知道到底是什么(如果您明白我的意思)。您在这里寻求建议的事实意味着您的表现比我已经做的更好:-)。

现在,您在哪里找到驯服的专业软件工程师?我最近加入了MentorNet,该系统与经验丰富的程序员和protégés合作。

但是您不必使用这样的正式系统。找到一个本地程序员聚会小组(或周五大学的软件工程系去哪里工作)是一个很好的起点。


MentorNet看起来非常有趣-我将对其进行研究。从物理学家到软件工程师的过渡很困难吗?
user787267 2012年

@ user787267因为我对编程感兴趣(并且已经是一名业余程序员),所以我很愿意进行过渡,因为听起来像是您一样,所以我并不觉得技术方面很困难。我花了更长的时间才开始接触湿件:了解我在一个更大的项目团队中的位置,并且是谁对我以前所做的“孤狼”编码有何重大变化的专家。

5

没有通往软件的皇家之路

在远古时代,他的学生托勒密国王(King Ptolemy)向欧几里得提出了类似您的问题。他的回答是:“没有通往几何学的皇家之路。”

您提到如果您的主管知道您花多少时间像专业开发人员一样编写代码,您就会大笑。其他人则通过从源代码控制到算法的设计和分析等一系列可供学习的东西回答了您的问题。

它们达不到您的目标:

“我需要花时间在实际物理学上”

音乐会钢琴家还是一个乐队?

世界发展太快,人们无法涉足。如果您想成为音乐会钢琴家,请不要将学习仪器的时间花在成为一个男人乐队上。

我对中型到大型项目物理学博士学位的概念是作为系统定义的思想领导者,理论专家,用例创建过程中的主题专家以及最终用户/软件工件所产生结果的判断者。与最好的软件工程师紧密合作。

如何从程序员的角度评估我的工作是否还不错?

如果您想将标准设置为高,请从此处开始:

实践中的软件架构,Len Bass,Paul Clements,Rick Kazman

查找“了解质量属性”一章。除了代码之外,它还考虑可用性,可修改性,性能,安全性,可用性,可靠性,可测试性,可维护性和可移植性(不能携带它,但是可以将设计从一个平台移植到另一个平台)。所有人都需要特定的可衡量目标。类似的参考文献包括:

http://msdn.microsoft.com/en-us/library/ee658094.aspx

http://www.sei.cmu.edu/reports/95tr021.pdf

您的目标与C和C ++

像FORTRAN一样,它们都是古老的硬语言。C / C ++的积极指标包括:

  • 具有硬件,嵌入式系统的应用程序。
  • 您想要作为起点的现有项目。

有很多人在做Web开发,数据可视化和大数据。许多人被激励去寻找或制作其他语言。例如,物理学家Tim Berners-Lee爵士在HTML方面取得了成功(但对物理学知之甚少)。评估您的目标与编程语言。

考虑使用Matlab

Matlab具有强大的安装基础,专门用于数学和科学。它具有用于数据可视化的工具。它允许科学家和数学家在问题领域而不是解决方案领域表达问题。Matlab生产并行计算工具箱和分布式计算服务器产品。

我希望Matlab的成功归功于与物理,数学,电子和仪器,操作系统,编程语言,软件开发,软件测试,软件体系结构和设计领域的专家一起使用的多学科团队。打个比方可能有点麻烦,但是当您有3D打印机可用时,为什么您会独自一人摆在那里,从锤子,凿子和粗锉开始做点什么呢?就像牛顿可能会问的那样,为什么不站在某人的肩膀上呢?


4

您将能够在物理学上走很长一段路,而无需了解任何有关“专业”风格的知识(从经验上来讲)。但是我已经看到很多人浪费了无休止的时间,因为他们失去了对自己所从事的工作的了解,或者在代码增长了几年之后就迷失了它的复杂性(即使在学术界也没有“扔掉”的代码,但是停留的时间比您最初想象的要长得多)。

我建议您先学习算法和数据结构,例如本课程。之后,您应该能够在更高的生产力水平上考虑性能,并且能够跟进Wikipedia上的文章。

之后,请习惯于您语言的核心内容,例如C ++ cppreference.com。我也强烈建议您阅读Scott Meyers撰写的Effective C ++系列和Koenig&Moe撰写的Accelerated C ++。至少对于C ++,这将为您提供坚实的语言基础。

同时,您应该尝试很好地了解您的工具。您不太可能在Linux下开发代码,因此请尝试学习如何从编译器(至少是gcc和clang)获得更多诊断(警告)。还可以了解有关静态分析工具,例如cppcheckclang的scan-build。了解如何使这些工具成为开发过程中不可或缺的一部分,例如将它们集成到构建设置中(是的,您至少应使用GNU make,甚至最好使用GNU autotools / cmake / ...之类的东西)。您还应该将概要分析工具添加到工具集中。对于C ++,我强烈建议您学习有关valgrind的所有知识,这些知识可以在很低的层次上进行分析(它也可以帮助您查找资源泄漏)。

所有这些将帮助您专注于您最关心的(您的研究),而不是浪费时间查找错误或进行无用的优化。当然,这几乎不可能卖给顾问,但是他们(和您)会印象深刻,但是您获得可靠结果的速度。

您提到了C和C ++,但是对于数值计算,我不能推荐numpy和scipy的 Python 。它使您能够以极高的干净度使用干净的语言编写代码(甚至可以进行交互式工作),同时仍然可以利用在C,C ++和FORTRAN中实现的极其优化的例程。而且,将自己的C或C ++代码与Python交互几乎是微不足道的。


感谢您的链接!我一定会研究它的(但是我认为我没有时间阅读几本书-尽管我在高中的某个时候读过加速的C ++)。我在Unix环境中工作(我使用Vim作为编辑器并喜欢它),并且我广泛使用make和Valgrind。我还触发了gcc和-Wall中的-pedantic选项,因为它很有帮助。也许我应该提到我在大学的超级计算机上进行高性能计算(使用MPI库进行并行编程)。
user787267 2012年

我还应该提到Python并不是一个真正的选择,因为我的代码需要非常快-尽管我确实喜欢使用它进行绘图。我也经常使用Matlab。
user787267 2012年

我经常使用Python作为前端,与我自己的C ++中实现的例程进行对话。借助Boost,这确实非常容易,并且您可以获得Python的全部灵活性(例如,用于处理绘图数据)。而且,Python的原型非常整洁。一旦我知道某些事情变得至关重要,就可以随时将其移至C ++。既然您提到了MPI,我建议您在IPython上度过一个晚上,它为分布式计算提供了一个不错的界面。
本杰明·班尼尔

@ user787267 Python的执行速度不再不再是事实- 例如,请访问youtube.com/watch?v=Iw9-GckD-gQ。关键是您可以使用Python更快地编写工作代码,然后可以提高速度:1)使用numpy / scipy 2)使用Cython或shedskin,以及3)仅将核心算法放入C / C ++或FORTRAN模块中您真的需要最后5%的改善。还请记住,您花在编码上的时间是代码尚未运行的时间,因此有时将一半时间编写80%性能的代码可能更有效
Tobias Kienzler 2012年

我通常在Matlab中制作原型来测试简单的东西,但是我想一段时间改用Python。我来看一下。由于我的代码大部分已经用C ++编写,因此我不想在半途中更改语言。确实,您还必须考虑实际编程时间(相信我,我愿意),但我认为这不应成为不(逐步)提高编程技能的借口。
user787267 2012年

4

如何从程序员的角度评估我的工作是否还不错?

  • 这是对的吗?在所有情况下都能产生正确的结果吗?

  • 其他人能够阅读并轻松理解您的代码吗?

  • 当您的主管说“太好了,现在也使它成为X ...”时,您是否需要重写很多代码?

  • 编写程序后,它会成为您可以反复使用的工具,还是只使用一次并扔掉它呢?

如果您可以回答“是”,“是”,“否”和“是,我尝试制作工具而不是一次性计算”,那么您已经做得很好。作为程序员,我们做的很多事情都是为了帮助上面列出的事情。


3

您的程序将与商业源代码完全不同,因此许多良好实践和方法将不适用于您日常的源代码开发。但是,有一种学习一些提示和技巧的好方法。

让一些优秀的软件开发人员检查您的代码并一起对其进行优化。它会给您更多的经验,并会教给您良好的做法。还要查看其他人编写的源代码。在sourceforge或github上搜索开源项目,并阅读其源代码。

但最重要的是,请考虑是否真的需要学习新知识才能实现目标。只是为了使代码看起来更漂亮而做不必要的事情不会为您的应用程序增加任何价值。


阅读和参与开源项目实际上是一个很好的主意-但我必须在业余时间做些事情(但由于我喜欢编程,所以这不会成为太大的问题)。我希望成为一名更好的程序员的一个原因是,我不确定我是否会留在学术界。当我的博士学位。完成后,我可能只会在该行业找到一份工作-在这里,对熟练的程序员的需求很高。另一个原因是创造出优雅/美丽的东西的知识满足感-例如解决一个非常困难的微分方程。
user787267 2012年

不幸的是,行业需要您通常在学术发展中没有获得的技能。您在学术研究期间将要编写的内容通常不到商业应用程序源代码的5%。
2012年

3

就成为一个更好的程序员而言,没有神奇的子弹。如果您是自学成才,那么关键就是自我意识,这听起来像您拥有的那样。但是,学习良好的编码主要取决于阅读和练习。

批评自己的代码是获得更好代码的最佳方法之一。总是问自己:

  • 这会容易改变吗?
  • 这容易测试吗?
  • 我可以简化一下吗?3个月后再次看到它,我能轻易理解吗?

我的其他建议是不要将自己锁定在C / C ++中。虽然这些是出于某种原因而使用的好语言,但它们要求您执行许多与主题无关的事情。查看Matlab,如果大学没有适合您的信息,我会感到惊讶。考虑像Python这样的脚本语言。强烈考虑使用像Haskell这样的功能语言-该范例本质上是非常数学的,很可能会像手套一样适合您的问题。简而言之,探索其他一些语言/范例。即使它们不会成为您的永久工具,它们也会使您成为更好的程序员。

您可能还需要研究一些算法设计。我怀疑已经做好了这项工作,您已经在这方面做得还不错,但是算法在进行数值分析时非常重要。实际上,我会怀疑,有专门用于数值分析算法的资源。

编写代码时,请不要忽略您的主要目的。您需要完成任务。成为更好的程序员是做到这一点的一种方法。为工作选择合适的工具是另一回事。


2

首先,“优雅”是一个相对术语。对您来说,抽象可能看起来很优雅,但是对另一个C狂热者来说,抽象似乎没有必要。无论如何,要回答您的问题,您应该尝试在http://codereview.stackexchange.com上发布代码以供审核。
从重点出发,我根据自己的经验提出了一些不请自来的建议。如果仅使用C就可以完成所有工作,那么为什么要以抽象的方式对其进行编码?这样,您是否想使其他人重新使用您的代码?如果确实有充分的理由要切换到C ++,请进行抽象并学习C ++和OO概念。否则,放弃这个想法。以我的拙见,难道您不应该将代码赋予OO抽象的目标是使代码更具可读性并且科学结果具有可再现性吗?我本人有这种痴迷于学习OOPS和“优雅”编码的想法。但是C ++需要花费一些时间来掌握。由于C ++中的垃圾回收不是自动的,因此您必须学习内存管理。自从我自己在研究实验室工作以来,就花了很多时间来学习C ++和OO,


1
但是C甚至比C ++更不受管理。在C ++中,至少有RAII。
本杰明·班尼尔

我喜欢编码,所以我想成为一个更好的程序员。我首先是物理学家,其次是程序员,但这并不意味着我不应该提高自己的编程技能-毕竟,如果我决定将自己的代码与科学成果一起发布,那么最好能表现得更好,可读的代码。
user787267

2

考虑到您提到缺乏学习理论的时间。

如果几个月后您回头看了旧的代码,并且想知道“那种白痴写了那个代码”,那么您正在取得进步。

你进展如何?通过查看其他人编写的更好的代码。一个人从来不知道“优雅”或“好”代码的价值,除非他们看到它为工作增添了价值。除了鼓励您阅读理论以外,我鼓励您对工作领域中其他人编写的代码保持警惕。请注意在stackoverflow(C ++标记)上讨论的概念。每天只花15分钟进行这样的搜索,就会使您无所适从。它可以向您显示比您的代码写得更好的代码。那是您在Wikipedia上进行进一步了解的更多信息。这种对好奇心的学习,比第二天醒来时会忘记的理论要持久得多,对您有用。

还可以考虑尝试使用MATLAB或Python之类的语言。


我确实在Stack Exchange上花费了大量时间-对于我的日常工作来说,这是宝贵的资源。我已经使用过Matlab了很多,但是很容易养成不良习惯,例如不预先分配数组,因为它非常宽容。
user787267 2012年

为python @ user787267 +1我真的不明白为什么不预先分配数组是一个坏习惯
Xavier Combelle 2012年

2

作为一名物理学家,我自己变成了程序员,我发现我的物理学背景对于形成正确的隐喻来理解软件概念最有帮助。这种观点也使学习编程对我来说更加有趣,并帮助我发展了软件中“优雅”的感觉,这似乎是您所追求的。

我在CUJ专栏“思维模式-名称,隐喻,更好的编程和语言的政治性”中描述了隐喻和类比在软件中的重要和未被重视的作用。例如,OO继承继承的概念通常与将特征从父母传给家庭的后代进行比较。这是一个错误的类比。类继承的正确类推是生物的生物分类(例如,类RedRose是花,而花是植物)。

或以分层状态机的软件概念为例。这里的一个很好的比喻是束缚量子系统的概念,例如氢原子。您还记得,一个原子的状态用三个量子数| n,l,m>编号,正是因为它们是“嵌套”的(分层的)。这个隐喻向您展示了如何理解状态嵌套在状态中(就像角动量状态(l)嵌套在能量状态(n)中一样),并且您立即看到状态嵌套始终反映了系统的某些对称性

物理学中另一个有趣的类比是“计算的参与者模型”,由于多核CPU和“云”中的分布式计算,最近又对其进行了重新发现。我发现将有状态的行为者(又称活动对象)交换的事件视为虚拟玻色子(如QED中的光子或QCD中的胶子)会很有帮助,也很有趣。这个隐喻解释了通信的基本异步特性,运行完成事件处理(量子跃迁)以及活动对象的严格封装,这些活动对象只能通过显式的中间工件相互交互。

无论如何,在XP(极限编程)中推荐开发系统隐喻,而作为物理学家,您将在提出良好隐喻方面具有优势。您还将对“优雅”有所了解,因为您的软件将从您应用的良好隐喻中继承概念的完整性。


虽然物理可能是丰富的隐喻来源,但是XP的目的是要找到一个隐喻,以促进与现场客户和其他团队成员的交流,因此通常倾向于选择更常见的隐喻。
皮特·柯坎

2

我可以告诉你,我在解决问题的方法上所取得的最大收获都是通过学习功能语言和解析器而实现的。这两个发现都是偶然发生的。因此,我现在要告诉您,如果您真的很认真地成为一名更好的程序员,那么您需要了解编写编译器所涉及的各种技术,例如解析器和解析器生成器,还需要学习如何以更高的阶数组合计算功能。

解析器和编译器的绝妙资源是PL101:创建自己的编程语言。我仍然没有找到函数式编程的良好入门,但是我听到了有关SICP的真正好消息


-5

计算机科学专业的毕业生毕业时并不知道如何编码。离开大学后,他们的需求就不那么多了。只有他们获得了经验。

您问题的答案是您需要学习设计模式。我使用Java,.NET进行编程,现在以PHP,Javascript和MySQL程序员的身份工作。顺便说一下,.NET具有非常大的抽象级别,例如ASP.NET。这意味着您可以跳过抽象学习。诸如Perl,PHP等语言的抽象水平较低。

阅读Head First设计模式,这是一本好书。这是一本非常全面的书。这就是您所需要的。


我有一个想法为什么这个答案被拒绝,但是如果拒绝者说为什么呢?也许会有用吗?
皮埃尔·阿洛德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.