学妹问我: 如何提高编程能力

开局两张图,剩下全靠吹了。

上面这两张图便是写这篇文章的原由。

对话框的另一边,是一位大二计算机科班在读的小姐姐,看似平静的文字背后透露着迷茫与困惑,还对未来的焦虑。

透过屏幕,似乎看到了大一时的自己,不会装环境、不知道怎么编译, 错也不会解决,更不知道除了计算水仙花数、打印乘法口诀表…还能写些什么。

感同身受让我觉得有必要认真的好好回答一下(其实是因为这是小姐姐问的算是对大一时的自己一个隔空对话。

怕自己不能够站在他们的境地去思考问题,搞成了「B」乎似的回答,也担心自己的回答不能帮到他们,甚至在某些方面对他们产生误导。

所以一般我都是选择回答比较政治正确的那种,比如:

“加油,你要多去实践,xxx”

“嗯嗯,你要多去看书,balabala”

“刚开始都是这样的,你多坚持一下呢,xxx”

怎么说呢,这都是正确的废话,谁都知道要多看书,要实践,要去动手写代码。

有时候想回答得更细致一些,但是迫于各种原因,也没时间去挨个的回复。

但这次学妹特地打了很长一段字,我看到了她想要快速适应计算机学习却又不得其法的迷茫,也许我的回答会对她有所帮助呢p>

因此我让她描述得更加细致一点,也很好针对性的提出一些建议。

可能有小伙伴没细看聊天截图的内容,我在这里再贴一次学妹的问题:

通过写这些项目,我像打通了任督二脉一样,不是学了什么厉害的算法、也不是高深的设计模式、更没有分布式这样高级的东西。

那是什么呢p>

我感觉到编程就好像搭积木一样,基本的函数、库、组件就是一个个的积木块,写的代码就是胶水。

只要我们心中有设计图纸,那就能通过胶水把这些积木搭建成想象的模样,缺少什么积木块,用到的时候再去搜索就行了。

在程序的世界,只要你想,你就能。

这段时间大概是我编程能力提升最快的一个阶段之一。

关于这个五子棋,还有个小插曲:

我写的不是联机五子棋嘛,然后启动的时候输入对方的 IP 和 Port 就能连上对战。

后来,我找了一个在其它城市上大学的高中同学,让他和我一起玩五子棋,但是呢,我傻乎乎的让他用 ifconfig 查看自己 IP 后告诉我,然后我在这边连接。

那个 ip 呢,大概长得像 ,熟悉的同学都知道,这个就是局域 内使用的 IP 了,并非公 上的 IP。

局域 内的 IP 只能在内 才能使用,所以我用这个 IP 是永远连不上的他的电脑的。

但是那时候我才大一,没学过计 ,根本不懂这里面的原理。

为啥我和室友能连上呢(因为在一个局域 )和其它学校的同学就不行p>

别看现在这个东西在我看来是常识,但我那时候是一点计 知识都没,就是硬着头皮学的 Socket 编程,去理解 IP 和 Port。

那是怎么解决的呢p>

当然是找谷歌呀!

在 上一番查询后,大概明白了,如果想让不同局域 内的主机进行 P2P 通信,需要一个公 中转服务器辅助进行 NAT 打洞。。。后来,我就又去尝试 NAT 打洞了,其中细节就不再描述了。

其实把我个人编程经历上写这么多,就是想展现我是如何一步步去实践的,遇到了什么问题,又是怎么解决的,把这个过程展现出来。

你看我没学任何计 知识,还不是通过边学边用,完成了 络相关的项目。

所以你离项目只差一个开始。

说到这里,不少同学又会说,我知道要多实践、多动手,道理我都懂。

可我还是不知道如何开始去写一个五子棋、贪吃蛇之类的东西。

好,那我就要问问你了

小北:为什么你学了 C 语言还是不会写贪吃蛇呢p>

学妹:老师没教我贪吃蛇如何在 C 语言中表示,也没教我如何让画面动起来,更没教我如何绘制 GUI ,所以我不知道怎么做。

这应该是大多数同学最典型的问题吧p>

那我们以贪吃蛇为例拆解一下,看看是如何从问题到代码的。

首先,贪吃蛇是一个个的节点组成的,节点肯定有横纵坐标吧个的节点组成了一条蛇,那自然应该想到链表吧p>

蛇还有什么属性移动的方向

还要食物位置吧些属性在 C 语言中用结构体表达出来就是这样:

接下要考虑的就是如何去绘制蛇,这个简单呀,就把整个链表从头开始把每个节点打印出来。

每个节点可以是一个圆点,也可以是方形。

那如何让蛇动起来的动,其实就是不断的将蛇打印出来,然后又清除。

并且不断的根据移动方向更新蛇的位置,只要这个过程够快,快过人眼能够分辨的帧率,那看起来蛇就像是在连续的动一样。

然后这个过程你还要去考虑如何检测碰撞,如何判断吃到了食物,还要随机产生食物。。。这些东西首先你得想清楚逻辑,代码实现其实if、else 、for 就足够了。

做项目的过程总会遇到不会的东西,也会遇到问题。

但是要相信,所有的问题在你之前基本上都已经有人遇到过了,只需要把问题准确的描述出来,然后去搜索引擎上搜就肯定能找到解决的线索。

如果你要等学会所有东西,才去开始做项目,那估计等到本科毕业也没机会。

本科上的就那几门课,Java/C/C++、操作系统、计 、编译原理、离散、数据结构……

可能没有学校会单独开一门课教你 Java Web、Python 写爬虫等等。

学完这些理论课,等到毕业,你会发现,依然好像什么都做不了,所以说,要动手,趁早。

并且理论上,学完一门语言,掌握了数组、链表、 if、for、函数这些编程最基本的概念,就有能力去实现一些诸如贪吃蛇、五子棋、扫雷这样的小玩意了。

这种通过项目去学习,以解决问题为导向的学习才是更加精准和高效的。

课堂上的学习大多数是老师灌输知识、学生记住,然后考试就能拿高分。

实际上有多少知识能转化为解决问题的能力呢p>

不好说。

还是那句话,编程就像搭积木,学完基础的,积木块都给你了。

你能搭出房子、车子、还是火箭这全靠自己。

二、善用工具、学会搜索

学会用工具,更要用好的工具。什么是好的工具p>

诸如 VSCode,Github、Stackoverflow、Google、知乎、Jetbrains 全家桶都是不错的编程工具,有的提高生产力,有的能解决问题。

都 2020 年了,就不要在机房装着 VC6 写练习题了。

不要等到大一结束了,还没上过 Github,更不知 issue、pull request 为何物。

计算机专业的学生,如果还在用百度搜索技术问题,送给你一段陈皓(左耳朵耗子)前辈的话:

学妹问我: 如何提高编程能力
coolshell截图

当然,在没法使用谷歌的情况下,百度还是可以用的,但是这对计算机专业的同学,不应该是一个问题。

很多时候,你把遇到的问题准确的复制到 Google/Stackoverflow 搜索框,大概就能找到答案。

而百度会将你带向培训班的课堂,嘿嘿,刺激不。

3. 看优质资料

现在处于信息大爆炸的时代,互联 上充斥着各种博客、学习资源,这是对学习者最好的时代。但是资源太多,就存在一个选择的问题,在这里我给你几个建议:

  1. 把 盘里屯的那 500G 视频/资源 删掉,你永远不会去下载来看的

正所谓,收藏从未停止,学习从未开始,当你不再习惯的收藏资源了,你就成长了。最好掌握获取/搜索资源的方式,自己需要什么资源再去搜就完了。而不是让资源白白的占据你的 盘。

  1. 当需要学习某个东西的时候先去知乎/Google 搜索 「xx学习路线」

然后根据高赞/优质回答,选取大 V 们都提到的资源,这大概是这个领域比较经典的,然后去搜集资料,开始学习。

B站、mooc、 易公开课、Coursera等视频 站上有很多优质免费的课程

答应我,不要再被那些关注送 500 G 学习资源的骗了好吗都在 上公开着,直接打开 B 站就能看,不香么p>

学应用框架,官方文档是最适合入门的,并且很多都提供了「快速入门」的指引

比如 Vue、Hadoop、Requests 这些官 的指引都非常的清晰易懂,真的不要再去看七零八碎的博客,博客的定位应该是补充。

少看博客,多看书

很多博客其实就是博主自己读完书,然后复述一遍的笔记,你再去看他的博客那就是等于学二手知识,他的高度就决定了你的高度。

当然有些优秀的博主能够概况性的总结,或者把某些原理讲得特别清楚,这是值得看的。

总的来说,系统性的看书是你成长最快的方式。

四、自学

大学的学习,学的绝非是仅仅的知识,最应该学会的能力是「自学」。

等走上工作岗位的时候,你便会发现这个能力有多么重要。

初入职场,在公司,没人会像学校里的老师那样,手把手的教你。

就算有安排导师,也是扔给你一堆的文档和资料,自己去学习,然后开始上手实际项目。

这个过程大多会比较痛苦,至少我这几个月是这么过来的。

说到这,我突然想说下我认为的「自学的能力」,因为在程序员这个群体中,不管是科班学生还是野生程序员,自学都是必不可少的。

那「自学的能力」又到底是什么呢p>

我个人体会有以下几点:

1. 明确你学习的目标,比如我要学 Java Web、IOS 开发、机器学习等等

2. 了解该领域包含了哪些子模块,比如 Java web 需要学 Java 语言基础、JVM、数据库、计算机基础等

3. 掌握这些子模块的学习顺序和依赖路径,也就是先学什么,再学什么

4. 搞清楚这个方向有哪些入门、进阶的学习资料

5. 按着学习路线,开始学习一个子模块

上面这个过程,不断的递归下去,直到拆分出一个比较小的学习目标。

比如我要学 「Java web」,那这里面可能包含了Java 基础、Netty、JVM、Spring、MySQL、Redis 等等。

那 Java 基础又可以进一步分为 基础语法、面向对象、异常、集合、IO、反射等。

分到这里,你就可以开始去找资料学习了啊。

比如先安装 JDK,然后写 Hello World,然后慢慢开始刷书或是刷视频……

五、看小而美的源码

这里我用了一个定语「小而美」,小是指代码量少,最好就几千行,这样我们能够充分把控,美则是指代码实现写得很优雅。

我们都知道提高审美能力很重要的一环就是多看美的东西,好的设计。

那写代码也是一样的,自己学完基本语法,写出来的代码大概停留跑起来的水平。

这时候去看看大佬写的代码,你绝对会惊呼 卧槽,还能这样p>

这样的代码有哪些呢p>

如果你是大一的同学,我推荐你去看看 Linux 内核中关于链表的实现,简直特么太妙了,平常我们定义链表不都是这样嘛

但是这个存在的问题就是,每个想用链表存储的结构体,我们都得去写一遍,遍历、插入、删除的逻辑,显然太low了。

那 Linux kernel 中就用宏,在对用户自定义数据结构侵入性很小的情况下,实现了其它语言中模板的功能。

相信我,看完,你会学到很多骚操作的,后面找机会写一下这块。

又比如学完 C 语言,你会不会觉得 C 中的字符串有点不灵活,那推荐你去看看 Redis 中关于动态字符串的设计–SDS。

这些代码都不长,也不难理解,但是看完对于提升我们的编码能力是有很大帮助的,这就是小而美。

提倡看源码,不是让你直接上手就啃什么 Nginx、Sqlite、Redis的源码,这些都是几万级别的代码量,一般初学者

即使要啃,我给你说个好办法,这些东西目前来看,代码量都是几万几十万的级别,有点不友好,你可以去 github fork 下来。

然后回退到第一个 commit,从第一个 commit 开始看起,看到第一个完整的版本。

这个过程也是能学到不少东西的,看看罗马都是怎么建造成的。

解答问题

好了,BB了一大段假大空的东西,最后再回到学妹具体的问题上,挑几个来具体问题具体分析:

一、只会像高中一样跟着课程学习

说到底,还是填鸭式,没有形成自己的目标和学习路径。

如何破局p>

最简单的方式,给自己定一个目标,或者我给你定几个,自己领一个:

  • 学习前端开发,目标 BAT

  • 学习 Java 后端开发,目标 BAT

  • 做 Linux CPP后台开发,目标 BAT

  • 保研/考研,目标 985 或 C9

  • 算法岗….不建议,太卷了

  • 大数据开发、数据分析等等

如果你做技术岗,上面这几个基本覆盖了应届生找工作的主要岗位,你选一个自己相对喜欢一点的。

至于如何去达到目标p>

当然是分解,然后去找 Google 呀,去看看 BAT 这些岗位需要点亮哪些技能,怎么学才能达到。

记住,目标、目标、目标!!!

没有目标,你的生活就会是得过且过,满足于上课、做作业、考试、绩点这样的循环。

到了毕业找工作,你会发现面试官好像都不怎么关注你的绩点有多高,他们更关注你的基础知识和解决问题的能力。

解决问题的能力怎么体现p>

可以是刷题或者是让你讲你参与的项目,以及在这个项目中你扮演的角色和遇到了什么题,又是怎么解决的。

我们会发现,那些优秀的人,无一不是有着清晰的目标,从现在开始给自己定一个目标吧!

二、怎么可以脱离课本和教学视频自己编写一个小项目h3>

初学者跟着视频做是很有帮助的。

先跟着课本或者视频完成一个项目,记住不是看视频里的老师完成,而是你自己要跟着完整的敲一遍!

第二步,不看视频,根据自己脑海中的流程、思路来逐渐编码,明确先做什么,再做什么。

第三步,改造,或者基于视频里的做一个类似但不同的项目,比如视频里写的商城,那你可以自己做个论坛,视频里是贪吃蛇,你可以自己做个坦克大战,诸如此类。

其实这就是学自行车嘛,先用借助辅助轮或者别人扶着练习,然后慢慢的下掉辅助轮,自己骑。

千万不要没学会走,就想跑了,这样会摔得很惨。

三、就算跟着教程安装软件,搭配环境几乎每一步都会有这样那样的错误

这个问题,百分之 99% 的同学肯定都遇到过,甚至现在,我安装一些新环境的时候也会有各种问题。

想起刚学 Java 的时候需要去配置 Path、ClassPath、环境变量这些,但是第一次接触根本不知道配置这些的作用,也不知道他们的原理。

就跟着博客教程一步步执行,但是经常就会发生,明明都照着来了,还是跑不通。

那这个时候怎么办呢p>

第一办法是重新搜索尝试不同的教程,这个其实是换汤不换药,能不能配通还是看运气

第二个办法就是去搜为什么要这样配p>

了解之后,你就明白 Path 就是指定了我们平时在终端使用命令的搜索路径,ClassPath 则是让 Java 执行环境找到指定的 Java 程序对应的 Class 文件以及程序中引用的其他 Class 文件。

当你去了解这些东西之后,再去看博客的配置步骤就不再是懵的了。

在不了解背景的情况下,我们只能根据别人的指令一步步走,害怕和被人有一丝的不一样,而导致最后配置失败。

但是当你了解了原理之后,这些博客就只是参考了,你甚至还可以考虑到你和博主的某些环境是不是有差异,这些差异会对应到步骤中哪里应该采用不同的配置。

这个其实我体会特别深,在我第一次用到 CMake 的时候,起初,我是去抄别人的 CMakeList.txt 文件。

但是当我需要增加编译依赖或者其它定制化的时候,我就懵逼了。

include_directories、include_directories、target_link_libraries 这些指令,不知道如何去组合达到自己想要的目的。

那我当时是去找来了 CMake 的教程,浏览一遍后,我便懂了 CMake 构建的原理,以及各个指令的作用。

这时候,我便有能力基于别人的 CMakeList.txt 去定制化。

这就是我个人认为「搭配环境几乎每一步都会有这样那样的错误」的内在原因和解决办法了。

一句话,你是否清楚你所看博客做的每一步操作是在干什么,如果不明白。

只是复制别人的命令,那出错了,肯定会懵逼的。

四、 知识遗忘得快,理论没有形成体系

不知道学妹这里说的遗忘得快的知识是指什么p>

我说一下我的看法吧,我在不同文章中都反复提到了,学习新知识要学会抓主线,把零碎的、非本质的东西浏览一遍就行,用到的时候知道去哪找,这就够了。

对不起,我也记不住,也完全没有必要去记。

计算机 络的主线是「两台主机之间的数据包是如何通过 络传输给对方的」,其它的,像 UDP 的包头的构成呀,SMTP 使用的端口 呀 之类的问题,看一遍,有个大体印象就行了。

但是你得知道 UDP 包头里有源端口和目的端口以及数据包长度,为什么呢p>

因为这个是靠理解,反推出来的,首先 UDP 是传输层协议,传输层的目的是区分同一主机上的不同进程,那么一定是需要一个标识的,这就是端口 。至于它们是怎么排列的,这丝毫不是关键。

上面这段话,抛砖引玉的聊了下我认为什么知识是可以遗忘,什么是不可以遗忘的。

那不能遗忘的知识也遗忘了怎么办呢p>

多看。多去思考这样设计背后的原理,多问自己「Why」。

至于理论没有形成体系,其实我也存在这个问题。

但是我想的是,量变引起质变,你先积累足够的各个领域的知识,总会有打通任督二脉的那一天。

才开始学,怎么可能有完整的知识体系呢,至少到了大三、大四再来考虑知识体系这个问题。

五、畏难情绪严重,担心找不到工作

畏难这个事,老实说,人人都会有,我也不例外。

不要想着去克服它,畏难其实和喜欢舒适区差不多,这大概是天性吧。

除了天性使然,还有一个原因是想得太多,做得太少,还没开始做呢,就去想各种后果了,进而产生一系列奇奇怪怪的想法,自己吓自己。

那克服畏难情绪最简单方法就是行动,立刻行动起来,去分析一下,要做成这件事,需要哪些资源、前置条件等等

行动是缓解焦虑的最好方式,这真的不是鸡汤。

至于担心找不到工作,这完全没啥好焦虑的呀,你按照上面说的去制定目标,学习,找工作就是一件水到渠成的事。

当然了,最重要的嘛,持续关注编程指北~

END

不知道这篇文章有没有解决学妹的问题,但是我已经算是把我能想到的,用我觉得最合适的方式表达出来了。

剩下的还要靠学弟学妹们自己去摸索了,毕竟,看别人的总结再多,不如自己亲身体会一次记忆深刻。

纸上得来终觉浅,至于学习资源的推荐,我考虑单独出一期~

写这篇文章的目的也不是传道授业,而是解惑,希望我的一点经历和心得的分享能够对后来的同学有一丝的启发,让他们少走弯路。

这便是这篇文章最大的价值所在。

絮叨

最近好像很久没写技术文了,全在写这种水文,大家是更喜欢看技术文章呢,还是这种类型的呢p>

投个票,让我了解下呗,不过无论如何,接下来几篇都是技术文章了。不能一直这样水下去了哈哈哈

另外,

最近 1024 程序员节,给大家申请了当当优惠码,160 买 400 的书,有购书需求的可以去看看:

聊聊小北大学最成功的投资:买书

对了,第一批优惠码用完了,新申请的,看上面这篇文章的置顶留言哦~

我是小北,咱们下周见!

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月22日
下一篇 2021年1月22日

相关推荐