首先还是来说编程是什么?
无论你是不是程序员,每一天你都在编程,每一天你都被编程。编程,就是设计一些步骤,组织这些步骤,让这些步骤在当前环境中正确的运行,最终得出自己想要的结果。
你的每一天都是在起床、喝水、吃饭、工作、上厕所、娱乐、睡觉等步骤的有序组织下运转的,你活在这个程序中,同时你在这个程序中为改善自己的生活而制定各种计划并努力去实现。
机械设计,其实比编程还要编程。所谓的机械零件,就是数据结构。所谓的传动机制,就是应用程序接口(API)。所谓发动机,就是程序的内核。你将零件装配好,通过传动机制将它们接驳到发动机上,于是你就创造出来一部机器,通上电或者打着火,就可以让它运转起来。
编程比机械设计来的更为简单,你不需要经常给自己所编写的程序添加润滑油,也不需要去对每个数据结构进行复杂的力学分析,更不需要关注这些数据结构是否严丝合缝的相互配合,至少目前的计算机软件工程是这个样子的,它不像机械工程学科那样以坚实的物理定律为基础。机械的结构与运行规律总是可计算、可分析的,而软件的结构与运行过程却充满着太多不严格的环节。这种不严格,却给我们营造了一个可以发挥天赋或工科实践经验的空间。显然,即使软件工程存在着各种不严格,但是我们却能够通过编程模拟出机械工程的一切。事实上也是如此,现代的机械工程领域,软件已经无处不在。
机械设计有很多精妙的『算法』,像缝纫机、枪械、发动机之类的机构,设计它们其实要比计算机世界里的算法设计难得多,而且这些机构对人类文明的发展往往能够产生巨大的推动作用。希望你不要因此爱上机械设计……学会编程,你会对机械设计的理解更为深刻。因为编程是将『设计』本身作为一种智力活动而对待的。你可以将机械工程领域的那些智力活动应用于编程,也可以将编程中的智力活动应用到任何设计之中。
最近很多同学都留言说:自己不是科班出身而且零基础,能学好编程吗?
这个问题我的回答是:哪个人不是从零基础开始学的,你又不是第一个!
非科班出身的人总是会引发各种对抗力量,这个库怎么安不上?这段程序是怎么运行的?
写程序遇到 bug 的时候,
科班出身的人先想到的是怎么排查 bug。
非科班出身的人先想到的是怀疑人生,
怎么会有这种问题?
我是不是不适合学编程?
学新东西的时候,
科班出身的人是在一个稳固的地基上添砖加瓦,底子稳、塌不了。
非科班出身的人是在拿着拼图的一角寻找关联的碎片,只有拼的足够多,最后才能连接成完整的知识网络。
我以前也试图提升过自己的学习能力,但真不像鸡汤文里说的学习某种模式能改变你的思维、加入一个读书会能让你成为终生学习者,不是这样的。只有学一个自己不擅长的东西、把自己推出舒适区、反复碰壁,这个过程才让我学会了如何学习。
从循规蹈矩到自寻出路
几年前,当我决心从零开始学编程的时候,我制定了一个「每天编程1小时」的计划。
和大多数人一样,我想系统的、有体系的去学习,跟着教程从基础学起。那时候还在印象笔记建了一个笔记本叫《每天编程1小时》,收集一些好的教程,根据知识点试着去列一套成体系的学习路径。
开始跟着教程学的时候,问题来了。看了几章之后,突然就会出现看不懂的概念,知识就断层了,就跟上数学课捡了根笔之后发现后面的就听不懂了,但我也没错过什么啊。我又试着跟着示例代码敲,敲完也不知道这段代码是怎么运作的,自己只要一拓展就会出错,后来敲烦了就直接复制粘贴,感觉学的特别迷茫。
实在学不下去的时候,就换一本教程,基本都是从第一章开始觉得会了,但实际上又不知道学的这个要怎么去使,这种感觉就一直在我的脑子里嗡嗡的转。到后来那一个概念我都看了六遍了,谁讲都那样,但还是不会使。
这时候开始对系统学习的方法有点怀疑了,大家都说要从底层学起、看大量书单,但会不会这种系统学习的方式不适合我这个非科班出身的新手?毕竟,我已经没有4年时间来学编程了啊,我每天只有1小时能用来学习,再这样继续看各种琐碎的语法细节,我就要失去耐心了。
我想,不如先写点小项目练练手。于是我开始从一些简单的程序写起,写一个汇率转换的公式、写一个随机生成姓名的系统,写一个学生图书管理,可能这些程序在专业人士眼里都算不上是项目,几行代码和简单语法就能搞定了,但对于我来说,这些程序就是一个个使用情景,我从这些使用情景中理解了概念的真正意义。
其实很多概念都是基于无数个场景的抽象,抽象了之后就会少了很多细节,给人一种太笼统、太晦涩的感觉。而让人印象最深刻的是场景,就像提到「烫」的时候,第一时间想到的是被烫的场景和感觉,而不是烫的定义。
所以说,开始动手写练手项目,是我自学编程的一个重大转折点,让我开始把编程用起来了。
发现别人没办法帮自己走出困境是有点沮丧的,但是可能挣扎的过程也是我学习的一部分。发现无路可走了,就只能靠提升自己的解决问题能力来突破困境。
经历过这次求助之后,我发现,如果我不能清楚准确的描述问题,我就没办法解决这个问题。而问题一旦被清楚准确的描述了,也就变得很容易解决了。探索了一段时间之后,我甚至形成了一个自己的解决问题
方法论:
第一步:提出假设
假设阶段是最重要的,如果你对一个事情没有假设,说明你没有思考。有时候之所以会痛苦,就是因为发现事实和你认为最正确的假设是不一样的。在阿加莎的小说里,平庸的侦探会为自己的推断找各种牵强的证据,而波洛会勇于根据事实不断推翻自己的推断。
在假设阶段,我会从我的角度对这个问题做几个推断。报了一个错之后,我脑子里会有若干个假设,是环境错误导致的,还是语法错误导致的,还是网站的什么问题导致的
第二步:搜索与修正
在这个阶段,我把所有假设转换成不同的形式进行搜索。拆分假设,重组语言,领域分类,转换形态…用这些方法挨着个搜索一圈,会排除掉一些东西,但如果还是不行,我会往回退一步,搜一下我做的这个事情有没有人在做,或者找一个相关视频跟着敲。这样下来,几乎没有什么问题是解决不了的。
通过这样大量信息的检索与对比之后,往往我会认识到自己思路上的一些根本性错误,有一些假设是不成立的。就比如说我可能会费力去想如何用石膏去做一个音色好听的吉他,石膏就不应该拿来做吉他。在初学时会犯很多这种假设上的错误,我通过几轮会修正自己的常识,等到稳固了之后,再在常识上进行一些创新,当我知道了大家会找最好的桃花芯木做吉他的时候,我再去思考,是否存在比桃花芯木声学共振还好的材料。
第三步:回归问题
在经历了前两个阶段之后这时候问题本身就已经变得清晰了很多,这时候只需要做的就是,将你认为最有信心的解决方案大胆的实践。如果成功那么问题就迎刃而解,如果不幸失败,那就洗把脸振作一下,重新回到第一步。
在反复经历这些阶段之后,我发现在解决新问题的时候,可以进行一个准确的假设了,因为我已经积累了足够多的编程常识。后来读到《解决问题心理学》这本书,发现里面提出的方法和我自己总结的还挺像的,有一种欣慰的感觉,知道了自己解决问题的方法是经过科学理论验证的。
成长的唯一办法就是写更多代码
虽然能做的事情比以前多了,但有些时候总会有一种不安、甚至是自卑感。就像是拼好了几大块拼图,却没有把这些都连起来拼成一个完整的知识网络。于是就想,是不是还是应该系统学习、从底层老老实实的学起。
那段时间,我又有了一种迷茫的感觉,面对着这么浩大的任务不知道该怎么进行下去。那段时间感觉很无助、失去了方向,每天胡乱找些视频来看。
我觉得对于技术上的学习让我知道了技术的可能性并抱有警惕之心,在最关键的时刻派上用场。尤其是创业的时候,更需要在无路可走的情况下,找到解决方案。