如何学习和练习生物信息学算法,并提高编程能力
目录
如何学习算法
就像学习现有软件的使用方法一样,去官网看英文文档是最准确的方式。 中文文档读起来更快,但往往不全面,或存在翻译问题。 学习算法,最好的方式也是去读文献。 不过,如果是比较基础和应用广泛的算法,看中英文介绍也可以。 其实我看文献和长篇介绍也头大,所以有时候直接看代码,反而能更快地理解算法。
如今,大家喜欢都看视频来学习,也是一种不错的方式。 但是千万不要局限于中文视频,英文的高质量视频也很多的,多搜总有收获。 比如油管上Ben Langmead (Bowtie2 作者)的系列视频, 如 Algorithms for DNA Sequencing (其实我也没看,不过我看其内容挺广的), Burrows-Wheeler Indexing (我看了,但没看完)。
最后就是,可以在Google Scholar上关注感兴趣的同行,获得特定领域的文献推送,长期关注自己感兴趣的方向,持续学习。
如何提高编程能力
首先,如果可以,请选择一门编译型语言,比如C/C++/Go/Rust。 当然Python也是可以的,只是性能稍差(如果不用其他语言写底层代码的话)。
接着,除了掌握基础的语法、标准库、常见数据结构之外,最好的方式是通过重写经典数据结构和算法来练手。 我重写过CountMinSketch、BWT和FM-index、Minimizer、FracMinHash、Kmers编辑码等, 后来根据兴趣或需求从文献复现的有StrobeMers、LexicHash、WFA等。 WFA是做LexicMap的中途,花了4周全身心投入实现的,后续断断续续做了一些优化。 上述的包都在Github开源了的,都能直接拿来用。
重新发明轮子其实是个很好的锻炼机会。 一是锻炼编程(算法、数据结构、性能优化)能力。甚至很多人看不上的、简单的FASTA/Q文件解析,我都迭代过很多版本,从中学到很多。 二是启发新的方向,比如LexicMap核心算法基于LexicHash,但是我们做了很多大的改进。 而其中很多细节和灵感又源自于先前多个项目的积累,包括SeqKit、kmers、unikmer、TaxonKit、KMCP等。
我为什么要发明那么多轮子? 因为Go语言缺少很多生物信息学的库;为了保证跨平台编译,又不想使用其他语言的库,所以只能自己写。 渐渐的,时间长了,自己也得到了锻炼。 如果大家使用的语言有现成的优秀的库,直接用就可以了。不过,原创的算法还是得自己写。
至于如何进一步提高编程能力呢,这里推荐一本书,《深入理解计算机系统》,我每读一次都能获得一些性能改进的灵感。 另外,可以结合一些性能分析软件,比如go的pprof工具,就能更快地优化软件性能。 不过有时候,还需要更复杂的技术,比如SIMD。 Go语言不支持SIMD指令,但支持Go汇编语言,我还为此花了几周时间从头学汇编语言,来优化一个函数。
最后,一切都要源于兴趣,喜欢并投入大量的精力学习和练习,一定有收获。念念不忘(甚至游戏、洗澡、跑步的时候),必有回响。