我开发了一个基于 Beancount 的账本托管服务 HostedBeans,欢迎大家来了解纯文本复式记账并试用我的服务。
归档 2015 年 2 月

读代码是好的学习方式么

自我开始编程以来,我一直觉得读别人的代码的难度,要几倍于自己写代码。一直以来我都很困惑,难道是我技艺不精,所以读别人的代码很困难么。

其实不是,我能看懂代码中的每一句话,并没有我不认识的语法,但连在一起就不懂为什么作者要这么安排代码了。

后来我渐渐有了一些想法,代码是程序员给计算机的命令,是作者思考过后的产物,但思考的过程却没有体现在代码上,这就好比一道数学题,只有一个最终答案,所有的计算过程都被省略掉了,自然难以理解作者的意图。一段代码一开始写出来,后来发现存在问题,陆陆续续地改过好几版是很常见的事情。最终版本中可能每个小的细节,都是作者花了很多时间试错的结果,但这个试错的过程并没有直接地体现在代码上。

另一方面,代码中往往存在一些「隐含前提」,例如假定函数的参数已经在传入之前被以某种方式处理过了,这个假定很可能与另一个文件的某行代码有关,这种联系很难引起阅读者的注意。当然,好的设计可以缓解这个问题,但很难被彻底地解决。

代码的历史会被保存在版本控制系统里,但说实话,按我的经验,很少真的有人去翻版本历史,因为正确地使用版本控制工具相比起写代码是一项比较不受重视的技能,在这种情况下翻历史是非常耗时的。当然,有些人会将一些细节以注释的形式添加到代码中,但注释也只能承载很小的一部分信息,因为维护注释也是一项很高的成本,我个人一向是反对添加注释来解释代码的。

所以阅读代码实际上并没有看上去那么轻松,为了彻底理解一段代码,很有可能你需要付出和编写这段代码差不多的努力,来了解这段代码的历史和前提。

前面提到的是阅读「好的代码」的情况,比如大多数活跃的开源项目,如果是面对质量较差的代码情况就更为糟糕了。

所以我的观点是,读代码绝对不是一种好的学习方式,我认为学习一项技术应当先阅读书籍,然后尝试自己实践,最后再参考代码质量较高开源项目。

对于大多数项目而言,可能从未把「供他人学习」当作目标,只有当你自己实践过,积累了一些经验并且也遇到过一些困难的时候,你才能读懂代码并且从中学到解决问题的技巧。而在开始实践之前,最好的知识来源是书籍,因为书籍的内容是经过精心的安排的,最高目标就是供他人阅读。

从初中开始编程

我是初中一年级从 VB6 开始学编程的,后来写过一点点 VB.Net. 但是我现在回想起 VB 的语法,其实什么都想不起来了,说起来当时其实更关心能做出什么样的软件,对代码该怎么写是完全不关心的,有很多是从百度上搜来的代码,经常一大片一大片地复制,也不知道版本控制。

后来大概初中毕业的时候,我发现如果要写一个规模稍微大一些的项目,以前那种到处复制的方式就行不通了,于是我开始关心什么是好的代码,如何使用编程语言提供的各种特征来组织代码。这个阶段我用的是 C++, C++ 的学习曲线实在陡峭,就算你花了一年学会了 const 的四种用法,你还是写不出什么实用的程序。但因为 C++ 是个相当复杂的语言,支持多种范式,所以 C++ 还算是一个比较不错的,用来学习如何组织复杂的代码的语言。

C 和 C++ 都算是竞赛党常用的语言之一,因此当时也认识了一些参加 NOIP 的人,也参加过两次百度之星的比赛。但后来我发现其实这和「写程序」其实是两个不同的圈子。NOIP 其实就是披着编程语言外衣的数学或者说是算法竞赛,因为我的数学并不好,所以我想我还是不要继续在 NOIP 的圈子混了。

之后高中的时候接触到了 Qt, 学了将近两年的 C++ 终于可以写出 GUI 程序了。我一直觉得 Qt 是 API 设计最精良的 C++ 库,我从 Qt 里学到里很多,理解了 C++ 中一些特征究竟要被使用在什么样的具体场景下。

不过 C++ 写程序实在还是有点慢,其实写桌面程序真的没啥好的选择(当时没在用 Windows, 不然 .Net 还是挺不错的),所以开始转向编写网站,说到网页,当时了解的编程语言也比较少,于是显而易见地就选择 PHP 了,说实话 PHP 是个设计得很糟糕的语言,中文社区也非常不活跃。虽然我的英语也不算太好,但毕竟在学校也学了快十年了,我开始去探索中文社区以外的更大的世界,更多地学习其他人如何写好代码。在比较空闲的时候,我每写一句代码,都会去翻官网的文档,去 Stack Overflow 搜索,以便确认我这一句的写法是不是业界认可的,是不是官方推荐的,是不是最优的写法。

这么多年我学习编程一直都是自学,基本上就是每经过一段时间,我就发现我掌握的知识又上了一个台阶,于是离开了之前的圈子,进入了一个新的圈子,周围都是和我差不多的朋友——一直没得到过水平远高于我的大牛的指导。

在高二的时候,我发现其实写出一个实现特定功能的程序或网站,也没有什么了不起的,大多数掌握了 Google 和 Stack Overflow 的人都可以做到。于是我发现了机械工业出版社出版的那套「计算机科学丛书」。在高二一年和高三的上半年,每天躲在教室后面看「深入理解计算机系统」、「计算机网络」和「计算机程序的构造和解释」之类的书。读了一些之后发现,其实这些理论知识是非常重要的,这些知识是前辈们花费大量时间探索和总结出来的,有时候一个概念你觉得似懂非懂,但前辈们可以用非常一本正经的语言点出其中的关键之处。但说起来如果我没有之前几年的编程的经历,是很难理解这些知识的,所以理论和实践还是要掺着来。

在高三的时候,我看到 V2EX 上的一个招聘远程兼职开发的帖子,觉得可以试一试,于是跟着这么一个小团队一直工作到现在(主要产品是番茄土豆 https://pomotodo.com)。后来觉得继续在学校上课也挺浪费时间的,就在高考之前果断地离开了学校。

作为兴趣而编程和作为工作而编程还是有很大区别的。比如程序写出来都是要解决具体的问题的,为了写出合格的程序,不得不去了解「程序所要解决的问题」,即所谓的需求。再比如工作中通常设计到多个人或者多个系统之间的合作,这时写出易读的代码,做出清晰的设计的重要性就体现了出来,再比如在作设计的时候要适当地预测今后的变化,留出一些所谓的「可拓展性」,为了能愉快地重构,还要具有所谓的「可测试性」。

虽然我之前一个人写程序的时候也比较注意这些问题,但直到工作时这些好的习惯才真正地派上用场。网络上很多黑程序员的段子,最常见的就是「自己写的代码别人看不懂」和「自己写的代码自己看不懂」这两个桥段。作为一个有追求的程序员,我可以比较自豪地说目前我还没出现看不懂自己以前的代码的情况(初中时的代码不算),目前也没有一同工作的同事表示阅读我的代码很困难。

最新的时间追踪成果

在一年前,我曾写过一篇 这个假期我都干了什么 的日志,从那以后我就开始热衷于追踪时间数据,以及其他的一些结构化数据,所以下面是最近一段时间的一些统计结果,取样范围是 2015 年的整个 1 月。

这次的统计追踪到了 79% 的时间,应该说已经非常完整了。

写代码(99 小时)

我用 番茄土豆 来记录我写代码的时间。

  • Mabolo —— 27 小时

    因为往在写 RootPanel 的时候实在忍不了了 mongoose, 于是自己造了一个 MongoDB ORM 的轮子,就我自己的使用体验来讲,目前 Mabolo 已经比 mongoose 好用了。

  • RootPanel —— 25 小时

    这一个月进度不是很理想,一直都在进行暗无天日的重构,不过在前端方面引入了 Backbone, 很好地控制了前端代码的复杂度。

  • express-explorer —— 7 小时

    这是一个全自动为 express 生成 API 文档的工具,我相信到时候一定能火,只是目前完成度很低。

  • 其他非开源项目 —— 40 小时

睡觉(266 小时)

平均每天八个小时十五分钟,中规中矩。

目前我是每天起床的时候手动记录到日历,然后通过 fetch-sleeping-data.coffee 这个脚本从日历抓取并上传到 Github.

阅读(16 小时)

这部分,以及下面的「维护粉丝团」、「看视频」、「打游戏」、「户外」都是使用 Toggl 追踪的,这是一款比较好用的,跨平台的时间追踪工具。

维护粉丝团(16 小时)

花了 3 个小时维护我的粉丝团网站;13 个小时来维护我的博客,主要是将博客从 WordPress 迁移到 Hexo

看视频(46 小时)

  • AKBINGO! —— 16 小时
  • 空中浩劫 —— 11 小时
  • 铁甲小宝 —— 10 小时
  • 哆啦 A 梦 —— 9 小时

似乎看视频的时候有点长,不过主要是吃饭的时候在看。

打游戏(70 小时)

  • 风暴英雄 —— 33 小时
  • LOL —— 18 小时
  • SimCity —— 13 小时
  • SC2 —— 5 小时

一开始觉得没 LOL 有意思,不过后来大概是因为天天晚上四黑,就感觉比 LOL 好玩了。这个月打游戏的时间略长,之前几个月都没怎么打游戏。

户外(13 小时)

  • 去饭馆吃饭 —— 6 小时
  • 举办粉丝聚会 —— 3 小时

应用

  • Atom —— 37 小时
  • WebStrom —— 34 小时
  • QQ —— 26 小时
  • 终端 —— 12 小时
  • Slack —— 5 小时
  • SourceTree —— 3 小时

这个月开始换用 Atom 作为编辑器,毕竟作为一个 Node.js 程序员,如果不用基于 Node.js 的编辑器,写出来的代码显然是会有 Bug 的。

这个部分以及下面的「网站」是用 RescueTime 追踪的。

网站

  • 知乎 —— 17 小时
  • Github —— 13 小时
  • Bilibili —— 8 小时
  • SegmentFault —— 6 小时
  • jysperm.me —— 6 小时
  • V2EX —— 6 小时
  • Google —— 3 小时
  • cnodejs —— 3 小时
  • Gmail —— 3 小时

我现在觉得刷知乎还是挺浪费时间的,然后 V2EX 的内容质量越来越低,以后要少去这两个网站。

精子生于 1995 年,英文 ID jysperm.

订阅推送

通过 Telegram Channel 订阅我的博客日志、产品和项目的动态:

王子亭的博客 @ Telegram


通过邮件订阅订阅我的博客日志、产品和项目的动态(历史邮件):

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-ND  授权发布。最后生成于 2024-04-08.