百科问答小站 logo
百科问答小站 font logo



对于学习代码困难的人来说,应该如何学习代码比较合适? 第1页

  

user avatar   yongle-li-86 网友的相关建议: 
      

目录

  1. 段子
  2. 学习经验
  3. 一点忠告

我学Fortran的时候,学起来类似于:

老师:1+1=2。

我:哦。。。。。。。

老师:习题就是1+2啦!

我:虽然不明白咋回事,但是根据老师提供的模版,把1换成2就搞好了。。。。。。。

科研文献:使用SVD求解矩阵奇异值,然后就可以求矩阵广义逆。

我:啥是SVD?啥是广义逆?哦SVD啊,让我来看看Numerical Recipes。。。。。。。糟糕,这个部分还要看《矩阵计算》。。。。。。。不好,又要翻《高等代数》了。这个定理太专门,我的《矩阵论》放哪去了。。。。。。。指标对来对去整不明白,《具体数学》放哪了。。。。。。。好了,终于写出来一个O(N^3)的算法,但是太慢了,我要做一个500万 500万矩阵的问题,让我看看咋化成O(N log N)。。。。。。。。嗯,这里有个开源子程序,来自于地球上某角落的一个大学里一个课程大作业,估计能有用。。。。。。。糟糕!怎么Segmentation Fault了?(Debug一周后)我****!原来是我下载的子程序弄了一个全局变量跟我的变量名冲突了!赶紧把变量名改过来。。。。。。。咦怎么又死了?(又一周后)原来是字符串占用了浮点数的内存!唉还要改Module啊。。。。。。。咦这里有个现成的小程序?嗯?编译要用20年前的操作系统和18年前的Intel Fortran编译器,还要配合19年前的一个库函数,这个库函数在15年前已经停止更新,无法在现在的操作系统上用。。。。。。。谁来救救我。。。。。。。

本是为了整明白程序看点书,结果越看越迷糊。。。。。。。。


正好我课题组有两名新生加入。正在给他们培训。就在这里讲一点编程的学习方法。书是一定要读的,但是不可能“我先读一些书,学会了再编程”,永远是边学边用,滚动式学习。

先介绍一下我学习编程的历史。

我2004年底开始接触编程。之前都是小打小闹,比如用LOGO语言画个几何图形之类的。2003年大二,我们开了C语言,但是我竟然神奇的没有任何印象,可能是当年的SARS夺走了许多上课时间的原因。2004年有位老师从美国德州农机学院回国,负责讲授一门《计算化学》,实际上是半学期线性代数科普,

外加半学期Fortran编程小入门。当时书也不多,也没有上机的课时,这位老师在黑板上写伪代码和笔记本电脑操作相结合。当时还坐校车走遍了山东大学四个校区,寻找谭浩强写的一本Fortran参考书。我觉得学的还比较有兴趣,就自告奋勇去他课题组实习。正赶上寒假来临,老师提示了我学一些内容,就回安徽安庆老家过年去了。我寒假就没有回家,在泉城广场附近的书店逛了一下午,买了几本书,学习了一些理论知识。计有:

计算机操作系统

数据结构与算法

编译原理(龙书)

在电脑上练习了Linux一些基本操作和vi的用法。(当时我的笔记本电脑被盗,是在老师的办公室里用老师的电脑、他给我开的账号进行练习的)

开学一来,我跟老师说了我的假期收获,他问了我一些基本操作,发现我已经熟练,就告诉我要学习Intel编译器,并给我当年全国最先进的“联想深腾6800”账号(速度排全球第15名,我都觉得很了不起了。现在的无锡“太湖之光”曾经占据过全球第一宝座一年之久,祖国的科研实力真是今非昔比),叫我负责编制一些MPI程序。于是我又购买了若干本MPI的入门书籍(有一本深蓝色16开大本,和一本清华大学编写的),按照书中的例子开始编写程序。搞了几个月,这段科研经历随着我返回天津大学而结束。

这段时间我只关注算法的实现,由于书中有矩阵乘法、矩阵求逆的例子,我就照着书里的例子用Fortran编写出来,调试成功并测试速度即可。后来分布式存储和读写一直也没有完全搞明白,因为书中没有,网上的信息庞杂,进展有限。现在好像方便许多了。至少我一个同学已经学会,我有需要的时候咨询就好。

读研究生的时候,第一个小程序是利用一套基函数,求解一维束缚态本征值问题。这是一个纯粹计算的问题,虽然Morse势有解析解,但是我们假定不知道,用一组三角函数做为基,把求解薛定谔方程问题化为一个矩阵本征值问题。而求本征值这一步用MKL函数库进行,关键在于计算矩阵元、建立矩阵。(这就是计算物理的思路特点,跟教科书里什么级数解、解析解的思路是不一样的)这里暴露出来我的不足,往往公式推导不求甚解就开始编程,因为编程时反馈快,类似打游戏;而公式往往推一天,然后费去一大堆草稿纸,让我不想再抄一遍。这样导致编程的结果一直出错,对自信心打击很大。后来老实推导了程序,在师兄的建议下学了一些LaTeX,写出公式手册并打印出来,按手册编程,就一次通过。这时候我根本没有管子程序,所有的代码都在一个主程序里。

编程笔记类似上图这种。

秋季学期我选了四门大课:量子化学、高等量子力学、群论、谱学原理,累死。期末见到导师(导师半年中国半年美国),导师告诉我一个人的精力只能支撑一学期学明白两门课,我才反应过来是自己贪多嚼不烂了。转过年来学计算物理,在师兄的教导下开始培养子程序封装的意识,把某个特定的计算步骤写成子程序,一来是“一次干好一件事”(Q-Chem开发者之一邵逸汉教导我的名言),另外是可以反复调用,省力。

(邵逸汉博士现在已经从Q-Chem公司退休,加入了俄克拉荷马大学。欢迎同学们报考他的研究生)

再往后是痛感自己编程知识匮乏,正好组里有一本进口书,是师兄在香港买的,我就抱着啃了一段时间,了解了很多知识的同时,也感觉这时间花的不值,知识的增加并没有带来代码能力的增加。后来三年级的时候开始阅读一个大型程序AMBER的代码,把主要部分啃下来,这时候发现了许多业内人士的代码习惯,以及一些书里写了不少、但实际不怎么用的“白知识”(Neil Gaiman发明的词,跟White Noise类似,但属于信息)。这时候又花了两天时间过了一遍师兄买的那本书,觉得Fortran语言再没有什么神秘的了。后来自己又开发了子程序。当时还为方便的制作部分电荷(partial charge),制作了一些小程序,又获得了一些锻炼(这些小程序后来都没有继续开发,是因为自定义功能需求暴涨,我又没空)。

我在博士后阶段的编程能力又迎来了一次飞跃。这次是当时课题组需要使用一个Python的程序,只有我会一点Python,就硬着头皮上。成功使用这个程序发表了一两篇文章之后,导师又叫我读懂整个程序,然后读懂整个计算方法。一番折腾搞定之后,这三部曲就成了我现在学习新方法的三板斧:

  1. 速度弄一个现成的程序,做一个小例子,务求完整;
  2. 搞定整个程序的来龙去脉;
  3. 根据程序中的具体计算方法,进一步学会编制此程序用到的理论方法。

忠告:编程需要循序渐进,一开始不可能一口吃个胖子,也不能想读完一本程序的教科书,以后就再也不用看,就一直编程就好。

有益的思路是,

1.用一本最好是讲解用编程解决具体问题的书入门,最开始也不需要考虑子程序的问题,以实现想法为导向学习。此时解决了自己的问题就好,不必深究。

2. 随着经验的增加,已经不需要时时查询语法的时候,再尝试“重构”,把自己的程序拆成各个子程序的组合,每个子程序只做一件事情,搭积木一样解决手头的问题。

3. 然后再下载业内的程序进行阅读理解,体会常用的编程技巧。小技巧这东西每个研究方向都不一样,无法泛泛而谈,只有通过已有的程序来学习。比如AMBER里计算van der Waals势和力,是牺牲内存换取速度:

先算出因子 、 ,然后计算每一项势能的时候就算一个平方、一个减法和一个乘法:

4. 出错的地方永远不是最难的,而是你觉得不可能错的地方。因为难懂的部分你会觉得恐怕是个挑战,下意识里就会仔细的编程,往往不会出错;而简单的部分,往往会让你觉得“飞龙骑脸怎么输?”然后就死了。。。。。。。我一个师弟曾经被检查出来i和j指标写反了,我今年给学生检查出来把3-秩张量当成矩阵来用,一次性少了不少分量,导致程序出错几个月,自己还查不出来错误所在。

5.要坚持检查中间结果。一个好习惯是把中间结果打印出来,跟你自己用计算器手算的结果对比,看看程序是不是像你想象的那样运行了。这一点至关重要,往往你想象不到的地方程序出错,只有用看上去最笨的方法才能检查出来。当然了,有人好像能熟练运用GDB之类的debuger,这是极好的;但是如果你技术不熟练,还不用手算,就永远也无法改正你的错误了。

6.导师的作用,是告诉你什么能做什么不能做,什么需要搞定,什么不用太花精力。Debug这种体力活还是要自己搞。

这里我推荐一个学习Julia编程的课程,是我的朋友朱强老师开设的,100%免费共享。

朱老师也是工作做的非常棒的一位导师,欢迎有志青年去报考他的研究生。而且学校地点也非常有吸引力哦。

最后感谢题主回复。友情赠送一张我制作的“量子地毯”[1](Python实现),祝题主享受编程每一天!

参考

  1. ^ Frank Grossmann, Theoretical Femtosecond Physics, 3rd ed. 2018



  

相关话题

  本人物理系大一新生,对于学习方面有一些问题? 
  一块砖超高速垂直振动,视觉上看起来就是变大了,那么摸起来是什么感觉,能不能把它看成是另一种形式放大了? 
  《魔兽世界》里面310%的飞行速度相当于现实中的多少? 
  理论物理科普是否有意义? 
  在电子战中,全频段阻塞式电子干扰实战意义大不大? 
  在科学技术领域,中国还有哪些像芯片一样,与世界一流水平差距巨大的项目? 
  C语言中while(a=10);和while(a==10);有什么区别? 
  如何看待物质的新相态:「时间晶体」被实现?是否属实? 
  如何理解引力波,怎样具体探测? 
  高维度世界的生命是以什么形式存在的? 

前一个讨论
如何看待大多数科研工作者“不谙世事”?
下一个讨论
名校的博士学位,在高校找教职时,不重要到什么程度?





© 2024-12-22 - tinynew.org. All Rights Reserved.
© 2024-12-22 - tinynew.org. 保留所有权利