前不久逛知乎的时候看到一个问题:自学编程和计算机科班出身的差别在哪里?
自己回答了一下,获得了比较多的点赞和评论,在这里也分享给大家。
985 通信专业学长,转行程序员,聊一聊我的看法:说一千道一万,就是差在计算机基础。
该问题下面有将近 400 个回答,我大概都看了一遍,很多回答都挺好的,不过大部分的答主要么是 CS 专业,要么是在大学时自学 CS,这两者在本质上都属于有时间去学习计算机基础内容,但大部分自学编程的人应该和我一样,刚刚工作不久或者工作一段时间不满意想转行,想自学编程当程序员,从而想知道自学编程和计算机科班出身的差别在哪里,好分析出自己差在哪,有没有办法追上。
先讲讲我的转行经历吧,整个过程是培训+自学。
具体转行经历:
2015 年,在转正的那天,由于对薪资不满意,在朋友的建议下我报了一个培训班,脱产培训 5 个月。
不得不说,培训班的人员真的是什么层次的都有,一个班里面有一百二十人,从高中辍学到研究生在读,从电脑开关机不会到计算机科班的学生,应有尽有。
那个时候身上就只有三千多,不好意思向家里要钱,在培训班的操作性,我贷款了一万多,等工作后再分期还。
为了能更方便的上课,我搬到了城中村租了一个单卧,300 元一个月,大概是知耻而后勇,也大概是生活所迫,在脱产培训的那 5 个月过程中,我每天都是两点一线,七点去培训教室,晚上十点回出租房,唯一的乐子就是一周放一天的假窝在家看琅琊榜。
培训班的课程直接对标工作,没有讲什么计算机基础、数据结构和算法等底层原理,一开头就从基础语法开始讲起,然后过渡到实际项目工作,毕竟宣传的口号就是培训完毕让你具备三年的工作经验,所以培训力度挺大的,每天教的东西都很多,下午 6 点下课后才属于自己的练习时间,教室里面有空调,所以在附近吃个晚饭后回到教室开始复习。
由于培训班的人员参差不齐,能坚持下去学习的,大概就是我们这些度过大学的,最终找到工作的也就是我们这些人。
那个时候培训班在最后几节课都会讲怎么优化简历,所难听点就是造假,那个时候胆子小,担心面试时被揭穿那丢脸大发了,所以后面几节课都没听,自己写了一个简历带着几个实操的项目就去找工作,找的都是一些创业小公司,要求会低一些。
面试了两家就拿到了 offer,9000 一个月,是我之前在移动时上班的两倍,我立马签了,在其它人还在培训的过程中,我已经开始工作了,成为班上第一个找到工作的人。
2015 年底,我以为自己成为了一名程序员。
真正开始工作后才发现,自己的底子有多差,计算机基础、数据结构等内容都不会,只能做一些简单的 CURD 的工作,并且很吃力,当时处理一个简单的 json 数据花费了我三天时间,后面自己偷偷去问大神才知道用线段树可以几行代码搞定。
线段树是什么?
一脸懵逼。
一查,原来是数据结构的一种,当时想着我不会数据结构也能工作呀,还不如多花时间去写写代码,熟能生巧。
直到 2016 年我打算试一下能不能进大厂才意识到数据结构、计算机基础知识有多重要,说现实点,不会这些,连一轮面试都过不去。
开始了自学之旅,每天挤在五号线上往返两个小时的时间里面,不停的看视频,回到家也开始学,光是在慕课网上花费的时间就超过了一千多个小时(很多视频是下载离线看的,所以没有被统计到)。
当我开始去学习计算机操作系统、数据结构和算法、计算机网络这些底层基础知识时,才觉悟到,想成为优秀的程序员,基础知识必须扎实,否则天花板会很低。
上面这句话就是自学编程和计算机科班出身的最大的差别,计算机科班的学生的学习更体系化,对计算机的认知更加全面,出现问题知道可以在哪个方向找到答案。
而无论是自学编程还是报培训班,目的都只有一个:找到一份工作。
所以学的内容都是很功利性的内容,很狭隘,计算机基础的内容一开始都不会去学,框架、项目这些工作中用的到的东西才会去学。
不会编译原理,照样能定位到 bug。
不会数据结构,照样能写出个能用的排序功能。
不会计算机组成原理,照样知道怎么使用 IDE。
不会计算机网络,照样能写出个网络请求 API。
所以,你看,不会计算机科班必学的那些内容,完全可以做一个 CURD 的初级程序员。
这个最大的差别导致了自学编程的天花板和计算机科班出身的天花板相差很大,我这里并不是说自学编程的同学就不如计算机科班的同学,只是想强调,如果想达到更高的层次,自学编程的同学一定要去打好计算机基础,利用好工作之外的业余时间,这个过程的确会很辛苦,但人家科班的同学已经在大学辛苦学了四年呀。
计算机基础知识对程序员来说到底有多重要?
一、数据结构与算法
正如 N.Wirth 教授所说的:数据结构+ 算法=程序。
遇到一个实际问题,充分利用所学的数据结构,将数据及其之间的关系有效地存储在计算机中,然后选择合适的算法策略,并用程序高效实现。
这句话可能有点抽象,我举个例子给你们解释一下。
在工作过程中,我们多多少少都接触过 OAuth2 ,在使用 OAuth2 授权的时候,通常应用会弹出一个类似这样的信息:
1) 获取用户基本信息接口
2) 获取用户列表接口
3) 用户分组管理接口
。。。
思考一下,如果让你设计数据库,应该怎么设计信息存储权限?
如何你熟练掌握了各种数据结构的特点的话,那自然而然想到使用 bitmap 来存储权限。
我们把权限划分成最小粒度之后,每一个 bit 都它的含义, 例如我们把权限划分为以下几种:
-
获取你的头像、性别、昵称等基本用户信息
-
以你的身份发布微博
-
获取你的好友列表
-
获取你的朋友圈信息
每勾选一个选项,就代表着这个权限被授权,为了保证可扩展性,我们使用一个 uint64
来保存这些 bit ,也就是说,我们一共可以划分 64 种细分权限,然后对这些权限进行组合。
例如,第一个 bit 如果设置了,那么就代表可以获取你的昵称、头像、地区、性别等基本用户信息, 第二个 bit 如果设置了,就可以用你的身份发状态。
数据结构的实际作用还有挺多,感兴趣的可以搜索以下知识点:
-
二叉树搜索用于中断处理、登记缓存查找等
-
哈希表,用于实现索引节点、文件系统完整性检查等
-
红黑树用于调度、虚拟内存管理、跟踪文件描述符和目录条目等
-
Radix树,用于内存管理、NFS相关查找和网络相关的功能
-
......
上面这些例子是关于数据结构的,我再举一个算法的例子,如果有帮助,不妨点个赞收藏一下,好的内容值得肯定。
同样的也来思考一个问题:计算机的缓存容量无论再大,缓存满了还是要删除一些内容,给新内容腾位置。
那么删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?
这个时候采取的策略就是 LRU 缓存淘汰算法。
LRU 的全称是 Least Recently Used,也就是说我们认为最近使用过的数据应该是是「有用的」,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。
二、操作系统
先来看一下操作系统都有哪些内容。
img
现代计算机系统由一个或多个处理器、主存、打印机、键盘、鼠标、显示器、网络接口以及各种输入/输出设备构成。
说实话,程序员不可能会掌握所有计算机系统的细节,所以在硬件的基础之上,计算机安装了一层软件,这层软件能够通过响应用户输入的指令达到控制硬件的效果,从而满足用户需求,这种软件称之为操作系统,它的任务就是为用户程序提供一个更好、更简单、更清晰的计算机模型。
我们依旧通过一个例子来解释操作系统在工作中的帮助。
比如说,做一个网络代理软件,不过是从 socket 上收一个包然后转发给另一个 socket 而已,这好像和操作系统没多大关系吧?
但真做了,你会发现,用一个线程处理网络IO,只要写对了,那么哪怕系统压力很大,只要CPU顶得住,就可以保证引入的延迟总是在几个毫秒之内;但如果用了多线程分别处理收/发,那么只要网络压力稍大,引入的延迟就会增加,很快额外延迟就可能突破几十个毫秒(这实际上已经完全不能用了)。
想搞明白这是为什么,对操作系统调度原理、时间片等概念没有足够深刻的理解,是不可能的。
尤其是,当你突然遇到类似“系统压力一大网络延迟急剧升高”的 bug 时,如果对操作系统没有深入理解,你连准确描述都做不到,连查资料、求帮助都不知道该往哪个方向努力,更不用说 debug了。
换句话说,你可以不造轮子,但是你要知道这轮子是怎么造的,否则你连问问题都不知道如何去描述。
再降维一点,你总要掌握如何安装 Windows 系统吧,否则妹子让你去她房间里修电脑你都只能拒绝掉!
三、编译原理
众所周知,编译技术是计算机科学史上的明珠之一。
对于编译原理,很多程序员的困惑就是:我也不会去设计一门新的编程语言,有必要学习编译原理吗?学了有什么用呢?
实际上,编译原理不是用于炫耀的屠龙技,程序员在工作中经常会碰到需要编译技术的场景,比如:
-
编写界面模板引擎;
-
为项目编写各种各样的 DSL;
-
深度理解甚至开发出 Spring、Hibernate、阿里巴巴 Druid 这样的工具。
除此之外,解析用户输入,防止代码注入,为前端工程师提供像 React 那样的 DSL,像 TypeScript 那样把一门语言翻译成另一门语言,像 CMake 和 Maven 那样通过配置文件来灵活工作,运维工程师分析日志文件等等高级别的需求,都会用到编译技术。
当然,说实话,编译原理并非随随便便就能入门的!
换言之,需要准备一些基础知识在学习。
编译原理的学习和实践通常基于对计算机编译过程、计算机基本工作原理、甚至一定的数学知识有一定积累,这些知识分别分布并应用在了编译原理的不同阶段。
没有这些基本知识的积累,很快就会在某个阶段由于功底不够而无法再继续后面的学习。
所以不要一开始就去啃编译原理。
四、计算机组成原理
来源于深入浅出计算机组成原理
从上面这张图可以看出来,整个计算机组成原理,就是围绕着计算机是如何组织运作展开的。
我们依旧来举例子:)
每个程序员应该都知道 Ascii码,GB2312,GBK,Utf8,Unicode 等编码格式,如果你没接触过,那总出现过文件压缩后解压乱码的情况吧?
了解了这些编码的存储格式,你才会明白为什么会有中文乱码问题,靠,我在写这个回答的时候,我的后端同事发给我的日志就出现了中文乱码。。。。
再来个例子。
我们上面举的关于 LRU 缓存算法 的例子,它的设计也是借鉴计算机组成原理的内容的,
在计算机的世界里,空间换时间,时间换空间这个概念在复杂的设计中时常出现。
如果你想更详细的了解 计算机组成原理 的知识,推荐一本书:《计算机组成:结构化方法》。
书的内容完全建立在“计算机是由层次结构组成的,每层完成规定的功能”这一概念之上
“1、数字逻辑层
2、微体系结构层
3、指令系统层
4、操作系统层
5、汇编语言层
6、并行体系结构
最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。
这份完整版的Python全套学习资料已经打包好,需要的小伙伴可以戳下方链接免费领取
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
这份完整版的Python全套学习资料已经打包好,需要的小伙伴可以戳下方链接免费领取
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)