如何提高编程能力(知乎)

作者:Jiecheng Zhao
链接:https://www.zhihu.com/question/28177315/answer/39739882
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    如何提高编程能力,这个问题几乎是媒体们采访大神们必问的问题。就我所敬仰的一些大神们(Linus,Yukihiro Matsumoto,TJ,多隆等)的回答都会提到多读源码,当然每个人还会列出其他的一些内容,但是我觉得读源码是十分核心的提升编程能力的方法。(debug其实也是编程能力的一部分,区别可能是需要熟悉一些debug的工具,不过我觉得就题主来说这都是浮云。编程能力本身是核心。等编程能力上去了,读代码的时候读到不对的地方就会感到硌牙,设计模块设计不好就会觉得难受,然后debug自然而然就顺当多了。。。)

    读高质量的源码有什么好处呢? 这和大量的阅读对于写作有什么好处是十分类似的,我想题主作为一个很高阅读量,文字功夫也非常好的人对此应该也是深有体会的。这种好处难以用条条框框来说清楚。套用文学上的说法那叫语感。写代码也有语感。
创作自己的东西之前首先就是阅读别人创作的东西。多看了高手们是怎么写代码的,试图去理解高手们写代码时在想什么,久而久之(其实也不用太久,两个礼拜细心的读代码就能让能力上升一大截。)自己就会模仿就会慢慢地学会如何像大神一样写代码。等阅读量和写作量积累到一定程度,很多业界所谓的设计规范,模块流程会自然而然的理解并遵照执行,因为这已成习惯。(其实没说的那么自然啦,据传TJ大神是纯看代码流。[TJ Holowaychuk's answer to How did TJ Holowaychuk learn to program?] 正常人会看些书同步补充些规范啊之类的相关知识来帮助看懂代码。)相反如果一开始强套规范,容易遇到瓶颈,那时就只好说,臣妾做不到啊。

----------------------------------------------------2/15更新-
我觉得适合(以学习目的)阅读的代码有一下几个特点。
1。高质量。比如千锤百炼的基础库。
2。上下文环境熟悉。在读一个函数或组件的代码之前应该用过它,最好是经常用它,对于它的用法十分熟悉。恩,这也是我首先推荐阅读基础组件库的原因,因为这些总是经常用到的。
3。不涉及过于专业的知识。基础库很多代码并不适合这一条,特别是为了性能考量,代码中会涉及一些比较难的算法和罕见的处理手段。所幸的是这种东西出来的时候一般都会带上大把注释。开始时候回避一下,后来还是很值得读一读的。是在看不懂的话多读一两篇paper也能搞定,一般注释中都给出线索的。(当然了,有些就变成迷了,比如这段非常有名的代码,就只是留了个很邪恶的注释。 Fast inverse square root。)

读了代码以后可以做的两件事。
1。 默写。读完代码以后等感觉基本把细节忘干净了,比如一周到一个月后。像我这种小短脑三天就够了。。。自己把阅读的代码实现一遍。如果实现不下去了,或者觉得自己实现得很丑,就看看原版代码。
我自己在实践过程中最常碰到的就是模块设计上的障碍,核心的算法往往记得,数据结构也大致记得,但是模块是怎么设计的就忘得一干二净了。写起东西来总是磕磕绊绊的,然后再回头去看“正确答案”,会对别人的设计理解更深一层,发现在美好的设计下那些磕磕绊绊都自然消失了。或者忘了其他什么部分,总之忘了什么就说明缺什么,回头看一下大师的代码就能赶快补上。
2。翻译。现在很多开源项目的项目介绍中都会写“inspired by balabala”,基本是说我看了某某项目的源码(语言A),然后依着他的框架结构功能在语言B里实现了一套。这件事情其实是十分好的锻炼编程能力的方法,算法、逻辑、设计别人都已经做好了,需要做的只是迁移。迁移的过程中需要对原项目的代码结构有清晰的认识,还需要在现项目中对应的实现,但是对于原算法的理解和一些其他业务性的考量要求却不高(毕竟只要抄就好了)。如此一来,几乎就是集中锻炼了纯纯地编码能力。

-------------------------------------------------------
关于debug,我觉得这其实是小事,还有那么多人还在用printf debug呢! 但是也是很烦恼的一件事,很多时候总是觉得debug很不顺手。这里也说一下我的看法。
debug首先是编程能力的一部分,如果都搞不太清楚程序再干什么又怎么debug呢?如果模块设计很差,算法实现混乱,出错的概率和debug的难度当然会增加。相反,设计的好,编程习惯好,想出错都不容易。
debug主要有三种工具,debugger(mike zhang 给出的 26.2. pdb — The Python Debugger 是一个很好的debugger工具。),log(print大法),assertion & testcase (可以视为一种工具化再抽象的print大法,其实本质和log没区别)。
可以从这样一个视角去看这三种工具:
工具: debugger——log————assertion
可操作度(对人灵活性): 高————中————低
表述能力(对机器灵活性):低————中————高
请按需取用,对于离机器端较远,逻辑抽象度较高的应用,一般会更看重debug时对内部状态的表述能力而不是具体的运行细节。相反离机器端比较近的,逻辑抽象度并不高的场景,一般更喜欢用debug一步一步跟,希望能了解程序具体的运行细节。

以上仅仅是我个人的理解,实践出真知。各种debug方法都用一下,然后再判断该怎么debug吧。况且实际使用时各类工具是可以混合使用的。

另外当程序规模渐渐超出一个程序员能力范围的时候,debug有时的确是十分苦恼的,大神也不例外,他们也会抱怨,然后说“我不想再写XXX了”。例如:
Why should I have written ZeroMQ in C, not C++ (part I)
Farewell Node.js
(记得linus也吐槽过linux kernel变得越来越大而越来越难以维护和调试,文章我找不到了。如果有线索的童鞋希望能告知一下。)
所以当觉得调试很难时请不要灰心。那些说着不干了的大神们后来还是都回到了自己原来的位置。困难总是一时的。

------------------------------------------------------
对于python来说有一步很重要的debug步骤静态类型检查不是python环境自带的。它可以在运行期之前就解析并探知python代码中的类型错误,十分有用。可以减少很多的麻烦。
现在比较好的工具如下。
Sourcegraph
github.com/yinwang0/pys

------------------------------------------------------

然后就如同教别人怎么读书一下,现在应该写推荐书目了:
先弱弱的问一句除了python还会什么?一般而言读源码我会先推荐别人当前语言的标准库,先从二分搜索和排序开始看起。这两个算法几乎每个语言的标准库中都有,它们是将逻辑本质从事物本身表象中解耦的典范,而且除了语言本身以外它们对其他知识和上下文语义的依赖很小,十分适合作为最早的读物。很可惜的是python的这部分标准库是C写的,所以并不能靠读这些立杆见影地提高python的编码能力。(当然那些C代码也很有价值,特别是python的排序实现,很精彩,后来被java啊,octave啊,gnome啊都抄了去。其实编程能力总是相通的,读了对python还是很有好处的。)入门"书籍"都不知道推荐什么,真让人团团转。(我猜其实题主既然是用python在做机器学习,应该底层实际接触的还是C。其实cpython的标准库也可以读~~)

恩,推荐"书目"之前我能问一下题主的编程水平吗?
比如写过多少代码。然后看看这里Problems | LeetCode OJ的题目,用python做一下感觉如何?(这里的题目也很好,做做也是很好的提升代码能力的途径。)描述一下,然后我帮你找找看合适的阅读材料。其实我觉得呐你只要双手一摊问你导师要他的代码或许就可以了,虽然程序写的最漂亮的还是那些大师级的程序员。

啊对了,光读不练是不行的,如果追求高强度,高效,那就请刷题吧。题主坐拥世界上最好的计算机教育资源,我这里就不献宝了。



就把码代码当做写作,我相信题主你可以的!
========================================
为表对cpython TimSort 的景仰还是贴点连接:
cpython: 99302634d756 Objects/listobject.c
bugs.python.org/file445
TJ 是node社区代码贡献第一的男人,代码质量高产量高。以下是他回答他是如何学习编程的。
TJ Holowaychuk's answer to How did TJ Holowaychuk learn to program?
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值