上大学的两年里,在专业学习上我走过很多弯路。我将结合自身经验和前辈的思考针对自己存在的问题分享一些想法。

沉迷工具,日渐消瘦

我的长远目标是要成为一个厉害的程序员。在大学的两年中,我试过各种的“厉害的”的东西。比如,Linux系统,我不选有图形化的安装方式的Ubuntu,而选择需要手动分区,手动输入各种命令才能安装的Arch Linux。安装完毕之后,还需要手动搭建桌面环境,调整UI组件、电源管理、开机启动服务……再比如,路由器。在校园网下不能开启笔记本的WIFI热点,所以我买了一个比较高级的路由器。我需要将开源的校园网认证程序部署到路由器中,但是这是一件不容易的事情,因为这项工作涉及了三个部分:认证程序、本地的Linux系统和路由器的系统,彼此之间配合得不好都有可能失败,解决办法是只能是自己试错。根据错误信息,我搜索解决办法,瞎折腾一段时间后放弃了,最后发现是本地的新版编译器与作者原来的旧版编译器的某个函数库不兼容而带来的问题。除了那个工具,还有其它的软件需要部署,干脆就编译完整的固件吧,我还因为好奇,试了文档中各种编译路由器固件的方法。是的,最终我可以使用WIFI了,但我知道我付出的代价很大,“骄傲自豪”的我写了篇博客分享折腾的成果,但我心里知道这一点也不值得骄傲。我不打算深入学习嵌入式和Linux运维的知识,所以这些经验只是让我使用工具熟练而已,或者什么都不是。可以说想要装逼的心与“好奇心”驱使我折腾、使用那些工具,但很大程度上是只是为了折腾工具,而不是为了解决问题。瞎折腾占据了我使用电脑的大部分时间,然而我只是重新学习怎样使用工具而已,为了折腾而折腾,做着繁琐、机械的劳动。那时的我不知道程序员的职责在于直接或间接地创造或改善“人”使用的东西,而不是在于使用工具的熟练程度。当然我不否定工具的作用,工具会在我们真正需要它的时候发挥巨大的作用,协助我们又好又快地工作。

一位博主介绍,技术知识是枣核型稳定结构。这种结构可以大致分为高层、中层、底层。

枣核型稳定结构是指越靠近底层(语言、算法、数据结构、HTTP、TCP……)和越靠近高层(分层、组件、概念、理论、模式、经验、思想、平衡)的知识和经验越少且稳定,而越靠近中间(框架、工具)越多且不稳定。 – 摘自王健的没有了老师,你该如何学习?

这句话引起了我的思考。枣核型稳定结构的中间是脆弱的。随着时间的推移,工具和框架往往被废弃,执着于工具的使用吃力不讨好的,学习基础知识才是最重要的。到目前为止,在大学学完的专业课主要有C语言、Java、数据结构、数字逻辑与EDA,目前正在学习的有计算机网络、计算机组成原理、软件工程导论。根据我自己的理解,C、Java属于编程语言,通过学习这两门语言,可以学到一些编程语言的套路,而这些套路属于编程语言理论,编程语言理论属于底层知识,具体的编程语言更靠近中层。数据结构、数字逻辑与EDA、计算机网络、计算机组成原理都是底层知识,而软件工程、设计模式等经验类的属于高层知识。这些底层和高层的知识应该如何掌握学习?看书和实践。学校给我们提供了各种实验设备、练习系统、教程,这些都是实践的资源。有时候我也困惑为什么要学习这些理论。学习底层知识时,我困惑,这些不是有接口或者现成的库给我们用的吗?后来,我想明白了,一方面,如果我们只想成为码农,只会使用框架和工具是没有问题的,但想在技术圈里混久一点的人不会造轮子是不行的;另一方面,框架和工具并不能屏蔽所有的技术细节,对框架的理解程度也影响我们使用框架的方式,继而影响使用框架的效果。学习高层知识时,我困惑:编程不是想到什么写什么吗?用得着专门花时间调研、精心设计软件的各种特性吗?我不用各种套路也能写出程序,为什么要有那些条条框框限制我们的代码?后来,我想明白了,我们很少孤身一人工作的,写出来的代码要给人看,代码是要被维护的,这是关乎团队效率的问题。总之,理论知识一定要好好学。

时间去哪里了

我接触前端开发已经一年了,最近在开发一个批量生成网页的工具。开发过程难免会与课内的学习冲突。开发过程中我急于在短期内实现功能,经常2点才躺床上,最终导致我第二天什么事都不想做。老师在讲课,我没有预习功课,老师讲课讲得很快,我听课时就简直像在听天书。这种情况下,我如果精力充沛,会看看课本,不然就直接开启手机,干其他的事情了,这样上课的作用就只是签到了。如果我是真夜猫就好了。我凭借当前的水平,在半夜没精神的状态下,写出的那些代码的可维护性是值得怀疑的。所以,我有调整作息时间的必要,我要早睡早起。

我们难免会遇到不想做又不得不做的事情,比如写文档。我们通常不直接表现出自己不想做,而是用一件事情推迟一件事情,哪怕做的事情可有可无。我也有这个毛病,爱拖延。我知道这个问题必须解决,因为有些事情必须做,必须做完,我解决拖延的方法是合理的计划,通过计划一定程度上可以缓解焦虑感。我喜欢用纯文本记录代办的事,排好事情的优先级,可以写上截止日期等,做完就放在文件的下半部分已完成的列表。最重要是知道事情迟早都要做,干脆就按计划一条条做完。总有事情是我们不想干的,但干了又大有好处的,这种事情我们硬着头皮也要做完。

读了一本假书

上了大学,我开始才看一些课外书(没错,我语文水平一般)。看完《技巧》之后我“知道”了学习的逐步渐进的,但其实我不是真的理解,不知道成为一个普通的(平均水平的)程序员所需要付出的努力,只因听到这句话而感到自己还有希望,甚至还有一点沾沾自喜。看完《JavaScript高级程序设计》的大部分章节,我还不知道整本书的架构,某些概念也忘得差不多了。

目前,我认为我的阅读(只对那些比较重要的书)存在以下几个问题,等我看多几遍《如何阅读一本书》再补充。

  1. 没有系统的笔记。
  2. 看书不够主动。
  3. 看书的模式单一,基本只看一遍,看不懂的多看几遍,如果还不懂就放弃。

搞不明白

学习过程中难免遇到难题,其中之一是“如何判断自己是否真的懂得某个知识”。我认为向他人解释知识,可以判断是不是真懂。看书时看到一段文字,心里默念“我知道了,就是这么回事”,但当我们向其它人解释这个知识时,我们却不知道怎么表达,说,只可意会不可言传;还有一种情况,我们在解释时,对方没能听懂。这两种情况都说明我们对知识理解得不够透彻。就是搞不明白嘛,我们得承认。如果知道这一点,我们才可能进一步了解知识的背景和产生的原因,采取措施以加深理解。

Writing is nature’s way of exposing how sloppy your thinking is. - Guindon 写作也是一个暴露问题的方法,作笔记、写总结都是这个道理。单单写作可以解决“会不会表达”的问题,但确定“对不对”还需要做更多的工作。如果你的写的东西没人看(包括自己),没人反馈,效果将打折扣。

我觉得教育更有效,关键是要表达出所学的知识,并且获得反馈。教育的优点是获得的反馈及时,如果你说了一些误人子弟的话,学生应该会有所反应。Guindon的名言被改编了,Teaching is nature’s way of exposing how sloppy your thinking is.

对于程序员这项工作,最好要进入一个团队。编程知识不是线性的,团队成员往往各有专长,彼此间可以相互教学,相互监督,共同进步。编程的一个难题是很难判断代码的质量,但如果有了团队的代码审核机制,这个问题可以在一定程度上有所缓解,同时,在审核代码时,也是对自己的提高,因为你在说服对方的时候,你在表达,你在教育提交代码的人。毋庸置疑,天赋非凡的程序员是存在的,他们孤军奋战就可以创造出伟大的东西,然而,我不是这种人,大部分人也不是。三个普通程序员在一起不一定就比一个天才程序员有创造力,但至少可以比一个普通程序员有创造力。

这个学期,我去参加一个团队的面试,但失败了,一个原因就是不会表达,而不会表达的主要原因是我对问题不是真的明白。面试官问的问题都和我的面试申请(简历)的内容有关。面试申请上写的技能点不能随便写,要写自己真的会的,而不是写上自己接触过的时尚的框架或工具

个人技能
写上熟悉什么工具、掌握什么技巧并没有什么太大的用处。要写就写上一些领域性的能力,以及是掌握了什么关键性的东西,使得你具备了这样的能力。 – 摘自朴灵的分享一点“关于应届生如何写简历”的人生经验

没有团队或者进不了团队怎么办?现实情况是,学校里面不时有团队招新,然而一种不信任感使我不敢迈出那一步。团队的负责人会不会丢一堆旧系统让成员修bug,让成员做很多重复而无意义的劳动?经过笔试面试答辩,大学的时光还有多少?有没有更理性的选择?我认为拉上一两个小伙伴共同开发是一个更好的选择。网络给了我们方便交流的平台,和另一个地方的小伙伴远程协作也是可行的。

回到正题,教育还有其它的方式。利用好社区,学习一些知识后,去知乎等论坛类平台,不要脸的回答相关的问题,哪怕觉得会误人子弟,利用好与人交流的机会,毕竟有大神在。当然,还可以写博客,写总结,关键要分享,要有人看你的东西,要获得反馈,找到错误。

推荐 funfunfunction 这个YouTube频道,我的以上很多想法借鉴于主播mpj。