关于编程学习的一些思考 | 欢迎投稿
▼生物信息学习的正确姿势(第三版)
NGS系列文章包括NGS基础、转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这)、ChIP-seq分析 (ChIP-seq基本分析流程)、单细胞测序分析 (重磅综述:三万字长文读懂单细胞RNA测序分析的最佳实践教程 (原理、代码和评述))、DNA甲基化分析、重测序分析、GEO数据挖掘(典型医学设计实验GEO数据分析 (step-by-step) - Limma差异分析、火山图、功能富集)等内容。
较早时发表的生物信息之程序学习阐述了我自己学习程序的历程,这次学习下厦大统计系Dwzb同学关于编程的一些思考,关键两点:输入和输出;即是程序的输入和输出,也是知识的输入和输出,更是脑力的输入和输出。读进来的知识是别人的,能写出的东西才是自己的。有出有进,才能细水长流,汇成江河。
厦门大学统计专业学生
知乎专栏:https://zhuanlan.zhihu.com/Data-Analysis
很久以来,我一直都有这样两个困惑:
统计专业学习编程应该系统学习还是遇到问题再找答案?
要不要写博客?写博客对自己的编程水平有多大提升?把自己的技术全部分享出去是不是会被超越?
最近我才把这两个问题彻底想清楚,而且这两个问题的根源在同一个地方,写在这里和大家分享一下。
首先我来回答一下这两个问题:
第一,其实系统学习和现查都是可以的,两条路径都可以成为大神,并没有哪条路径是捷径的说法,just do it! (PS:我个人倾向于系统学习)
第二,要写博客,提升非常大,也不会被超越
为什么是这个答案呢?因为编程语言掌握的好不好,完全在于你付出的时间多不多,会不会思考总结,而不在于你学习的途径。只有解决了足够多的报错,并进行总结归纳,你对这个编程语言才会有基本的直觉,这个直觉比任何显式的知识都重要,但却常常为人所忽略。
下面是我的理由。
系统学习还是遇到问题再找答案
我相信这个困惑是比较普遍的
对于主张系统学习的人来说,他们没有掌握这个用法是不敢直接去做项目的,总会觉得心里没底,遇到什么bug解决不了怎么办,所以他们总会在做之前先对这个东西有一个比较系统的认识,我就是这样。但是这又会带来一个问题,那就是系统了解要花费大量的时间,而且学过的东西很容易忘记;最重要的是,即使系统学习过,做项目的时候还是会遇到之前没想过的问题。
对于主张遇到问题再找答案的人来说,他们会遇到找不到答案的情况,当你在毫无了解的情况下,在搜索时有时连该输入什么关键词都不知道。还有一种情况是,明明有现成的方法,你却不知道,自己造轮子还造不出来,陷入绝望中。
两种人都羡慕对方的优势,同时又畏惧按照对方那么做而产生的弊端,于是陷入迷茫。我在学习生信的系列书籍中一提到过我自己的一点理解。
这时,我们如果能意识到下面这点,就不会有迷茫的感觉了。
要想成为其他人眼中的编程高手,无论走哪一条路,都是行得通的,但是都有两个前提:要花费大量时间精力、要思考总结。
相信更多的人会主张边做边查,所以先说这一点。我见过这样做成为大神的人,也见过因为这样而被一个小bug卡住半天的人,他们的区别在哪里?在编程上花的时间精力不一样,对编程的兴趣不一样。
大神遇到bug会搞清楚它产生的原因,保证以后不会再犯,每遇到一个bug都积累一次经验。甚至他们会通过这个问题思考出一些新的问题,完善这方面的知识体系,积土成山。长此以往,他们的知识体系也会非常完整,对待bug有自己的一套解决方案。
而小白则只要能跑出结果不报错就满足了,他们甚至不知道结果是不是自己想要的,更不会去深究、扩展这方面的技术细节。编程对他们来说是噩梦,没有bug就谢天谢地,无论做了多少项目,他们依然是小白(而且他们可能会逃避这种项目,做的也没有大神多)。
我们可以看到,大神良性循环,小白恶性循环,逐渐走到两个极端。生活中的编程大神几乎不会问编程问题,而小白问的问题你只要百度一下就能帮他找到答案了。这是肯不肯思考总结的差别、肯不肯花时间精力的差距。所以只要肯思考总结花精力,边做边查的弊端是可以完美解决的。
接下来,我们来讨论系统学习的情况。系统学习中也会出现上面提到的大神和小白。这点拿我自己的经历来说就可以了。
我在学习python的时候,廖雪峰老师的教程我看过不下5遍,每一次我都不怎么敲代码就觉得自己已经会了,之后也没去用,一段时间之后就全都忘记了,之后我又会去看一遍,然后又忘记,如此循环往复。直到后来我真的去敲代码了,用的比较多了,才逐渐熟悉python的语法的。
后来我有指导过女朋友入门python,也是看的廖雪峰老师的网站。她之前没怎么接触过编程,但是学python的时候每一行代码都会自己敲一遍,现在已经掌握的不错了。不过从当时她问我的问题上来看,我深刻地认识到,正确的代码就摆在那里,你还是会敲错,新手总是会犯在我看来非常低级的错误,但是每个人都会经历那个阶段。不去敲代码,一个低级错误在你眼中可能就是不可逾越的高山。
我举这个例子是想说,系统学习的一个弊端在于你学的东西可能在短时间内用不到,于是非常容易忘记。这种情况无法避免,但是这并不一定说明你的时间是浪费掉了的。如果你学习的时候只是看别人的代码就以为自己懂了,那么你的时间确实是浪费掉了。但是如果你是边敲着代码,有时还会思考出一些新的问题,并去寻找解决方法的话,这个时间完全没有浪费掉。下面我来解释一下二者的区别。
在我们敲代码的时候,掌握的并不只是当前代码的知识,而且还有一些潜移默化的、你自己可能都没有意识到的收获。可以这么说,我们看教程、看帮助文档学习一个个函数、语法、数据类型的时候,收获最大的不是了解了这些东西,而是你写代码调试的过程。所以如果你只是在看,或者复制粘贴运行,冲着那些具体的“知识”去的,那就完全失去了这段时间学习的意义。
我还是拿自己的亲身经历来举例。当初我学习R语言时,几乎看遍了dplyr data.table ggplot2等包的帮助文档中的所有函数,不仅运行了他们的示例代码,而且不断思考实际中会需要怎么用,实际中需要什么功能。读者可以从下面3点中看出这样做的好处
我思考函数在实际中应用的时候,经历了自己编写、报错、查找答案的过程。这个过程其实和其他人做项目时的过程没有什么区别,只不过一个是项目中遇到问题,一个是自己给自己提问题,都可以起到锻炼编程能力的效果。如果说做项目可以遇到自己想不到的问题,从而更大丰富自己的经验;那么我要说帮助文档中的例子、函数中形形色色的参数经常非常富有启示性,可以达到开拓视野的作用。
自己写代码、解决问题的过程可以让这块知识更难忘记,即使忘记也能留下比较清晰的痕迹,随便查一下就可以马上熟悉。
第三个非常重要的点我称之为信仰。你相信自己的代码一定能正常运行,相信一个bug可以顺利解决,相信看这个资源可以学到你想要的东西,这些是我所说的信仰,这些信仰是从编程中潜移默化获得的,也是最有价值的部分。举几个例子
对代码的信仰。假设你刚学会使用爬虫抓取10个页面的信息,现在让你抓取1万个页面的信息,你心里虚不虚。你想可以把原来循环中的10改成10000,但是又不敢确定它能正常运行。运行一会儿发现果然报错,然后你找到了解决问题的办法,设置了代理ip,再启动爬虫,你心里还是虚的。果然,又报错了,可能页面增多解析时需要处理特例,修改后再运行.....心里虚就是没有信仰的表现,因为没有成功实现过,就怕解决了一个问题又来一个,问题多了心态就崩了,尤其是在这个任务是很急迫的时候。
遇到bug时的信仰。在刚刚接触编程的时候,我就听说过stackoverflow这个网站是非常好的,几乎你遇到的所有编程问题都可以再这个网站上找到答案。当时我也去看了一下,看到那些寥寥几个赞的回答,心中大不以为然。直到后来编程越来越多,我才逐渐认识到,真的是几乎所有问题都有人实现碰到过并在这个网站上讨论。我认为这是一种信仰的建立,长期查找才能建立起这些途径信仰,这可以让你遇到新问题时知道应该怎么找答案,甚至相信什么样的问题到哪里一定能找到答案,这样你在遇到bug或者需要了解新问题时几乎不会有焦虑感,对编程不会有挫败感,反而有解决问题的快感。
资源的信仰。我们经常看到,一篇文章列出了各种书籍、pdf、视频资源,人们往往趋之若鹜,最后绝大多数都只是收藏下来再也不会翻看。其中的根本原因在于他们对这些推荐的资源没有信仰,就算别人吹的天花烂坠,自己没有亲自看一下依然不会完全相信这是非常好的资源,没有这种信仰自然就没有驱动,不说当前没有学这个的需求,即使之后有这个需求也想不起来这个时间收藏过这个东西了。
博客的信仰。学习编程很多时候是看网上的博客学习的,长期接触一些博客也会对一些博客产生信仰,比如愿意无条件接受某个公众号的文章一定是精品。对于我来说,遇到一个bug我喜欢去stackoverflow这样的问答社区,当需要系统掌握一块知识(比如字符编码)的时候,我就会去寻求博客。当搜索引擎不能帮我挑选出优质文章的时候,我一般会搜“字符编码伯乐在线”,因为在我的印象中伯乐在线的文章没有一篇水文。看,当你看到我这么说的时候,你肯定对伯乐在线有点好奇,但是你肯定只是想去确认一下是不是真如我所说,甚至会认为我在打广告,而不会建立和我一样的信仰。而当你亲自看过才有可能建立这个信仰。
系统学习对于建立信仰非常有帮助,因为这个时候不像做项目有个截止时间催着你,你可以尽情享受各种报错和找答案的过程,逐渐培养自己的信仰。信仰也是一种直觉,是潜移默化的收获,也是我们在讨论竞争力时常常忽略的一点。但是获得信仰的前提也是要主动去查、主动去试,花费时间精力思考总结。
总结
看完上面的论述后,再回过头来看边做边查和系统学习的困惑,应该豁然开朗了。无论哪种方式,要想在编程方面达到很高的水平,都需要付出大量的精力,没有捷径可以走,只有一直在写代码,一直总结,才可以成为大神。区别只在于这个人是不是想成为大神了。
而边做边查和系统学习这两种学习方法则是因人而异,首先看你习惯哪一种,其次看你能不能接触到项目。
这一点扩展到是否要写博客的问题上也很清楚了。
以我自己写博客的经历来看,写博客能极大促进自己思考,解决以往会回避的问题。因为我以前学习可能会糊弄自己,但是现在我不能糊弄读者,这应该算是一种责任。
以前我看别人博客学习的方式是,跟着博客的思路学习那些函数、用法等;而且学了一篇我就觉得掌握了80%的东西,就认为自己已经掌握了。
而现在我看别人的博客从来不跟着他的思路,我会按照自己要写的文章的思路进行学习。一个知识点我要写成一篇文章,需要进行下面这些步骤
首先模棱两可的概念我需要查清楚了才能写下来
然后我会思考关于这个知识点我曾经遇到过的所有有关的问题,全部列出来
对于我列出来的点,可能有一些东西只是处于知道的层次我要查资料搞清楚
然后关于这个知识点,我要看网上的文章都写了哪些东西,是否有一些我之前没有接触到的点
整理好所有的点之后,我要排列先后顺序、组织哪些点放在一起讲、用什么样的示例等,还要用通俗易懂的语言讲出来
最后我写出来的文章必须是网上能找到的教程中最全面,还要是能看懂的
可以看到,我通过写博客来掌握知识,就会力求掌握该领域100%的知识。这样做我很明显发现,我学过的东西真的没有那么容易忘记,而且复习起来很快,这应该也是跑那些困难的程序带来的信仰。
所以说写博客对自己编程水平的提升是非常显著的。当然,写那种复制粘贴官网代码,毫不重新组织思路的博客是没有什么帮助的。
最后只剩下一个问题:写的这么辛苦的博客,被别人看了会被超越吗?
我相信这个问题的根源在于,觉得别人会比自己更快地学会这些知识,自己的努力完全就是在给他人做嫁衣。
那么我们不谈别人能不能看全你所有文章的问题,也不谈他是不是走马观花不自己写代码运行,就看那些知道该怎么学的人非常精致地扒着你的博客来学的人。
就算有人能做到这一点,他也不会轻易超过你,因为他这么精致地学习,即使有你的博客做辅助,也是要花费大量的时间的,这个时间不亚于你当初学习的时间。我们举一个例子,你在博客中说如果这个参数换成某某,结果就大不相同,读者自己尝试。你这么写肯定是尝试过了,他如果不自己再尝试一下,只是知道了,并不会产生和你一样的对这个参数的信仰。这一点的外在表现是,他在跟别人说这个参数的时候,不会有自信说一定会得到这个结果,只敢说应该会,因为他自己没有试过,有时候相同的代码在不同机子上结果就是不一样(有时用的不同IDE就会不一样)。
更何况他没有自己组织逻辑的过程,思考也不会比你更深入。你什么都在博客里解决了,也丧失了自己去查资料的机会,在信仰这方面的收获就缺失了。
最后还是那句话,显式知识的学习不如潜移默化的提升更有价值,当你的信仰建立起来,学什么知识都是手到擒来。编程能力是要靠大量时间堆积起来的。开始写博客吧!(欢迎投稿)
如果觉得本文有帮助希望点个赞支持一下!
授权转载自:Python爱好者社区。
Python
往期精品(点击图片直达文字对应教程)
后台回复“生信宝典福利第一波”或点击阅读原文获取教程合集