之前和家里长辈聊天,或者给一些准备高考选专业的学弟学妹介绍专业时,经常会被问到一个问题:你们计算机专业到底都在学些什么?
这个问题看起来很简单,但真要回答的清楚并不容易。
因为“计算机”这个词在生活里太宽泛了,而对于科技有些许了解的人来说,方向也特别多,如果没有亲身学习过这个专业,还是会有不少误解。
有人觉得学计算机就是写代码,有人觉得是修电脑、装系统,也有人觉得是做游戏、做网站、搞人工智能。它们都和计算机有关,但都是这个专业的一个方向,与我们本科教育里面的“计算机”关系并不大。
本科的“计算机科学与技术”主要是一套围绕“如何让机器可靠、高效、自动地处理信息”的完整体系。从数学开始奠定逻辑基础、将一切用代码表达清楚,最重要的还是背后的抽象、系统、工程和问题拆解能力。
所以我想写一个简单的说明书。以后如果有人问我“计算机都学些什么?”,我就可以直接把这篇文章发过去,好过每次都从头讲一遍,还讲的不够清晰全面。
当然,不同层次的学校的培养方案会有差异,我也没有亲身体会过顶尖学府的计算机课程,不过好在Berkeley、MIT都有很多公开课,我也通过这些公开课一窥顶尖学府的教育理念和思想。下面写的主要是以我的学校——一个普通一本大学,国内大部分“计算机科学与技术”本科培养方案里比较常见的内容,加上我通过公开课了解到的东西。
先说一个误区:计算机不是“学会某个软件”
很多人对计算机专业的第一印象,是会不会修电脑、会不会装系统、会不会做 PPT、会不会剪视频。
这些当然都是有用的技能,但并不是计算机专业的核心内容。不然学机械是为了会拧螺丝,学建筑是为了会搬砖,学食品是为了给趣多多点巧克力豆。
本科教育里的计算机专业,主要关心的是:
- 一个程序为什么能运行?
- 程序里面的数据是怎么被组织和处理的?
- 网络怎么把信息从一个地方送到另一个地方?
- 操作系统为什么能同时运行很多软件?
- 一个大型系统如何被设计、开发、测试和维护?
- 算法如何在时间和资源利用最小的情况下解决问题?
接下来我也会从人工智能、数据库、图形学、网络安全、嵌入式这些主流方向,探讨下我这几年对这些方向的理解,以及他们分别在解决什么问题?
现在让我们自底向上的一层一层解决计算机的思路来源、我们的学习目标、以及我在学习过程中遇到的问题和走过的弯路。
第一层:数学基础
刚进大学时,很多同学会惊讶:“为什么我报的是计算机,结果一上来要学这么多数学?”
大一时候我们也凑在一起吐槽这一件事,但学到后面才发现数学原来并不只是小中高的代数,那些叫做初等数学,本科学的是更广且更深的数学,且基础也确实十分重要。
高等数学、线性代数、概率论与数理统计、离散数学,这些基本都是绕不开的课程。甚至有的学校还会学数值分析、组合数学、运筹学之类的内容。
高等数学主要针对的是连续变化、微分积分的思想;线性代数在图形学、机器学习、数据处理里非常常见;概率统计是人工智能、数据分析、随机过程的基础;而离散数学则和计算机关系尤其紧密,集合、逻辑、图、树、关系、递归,这些东西听起来像数学概念,但后面会不断出现在数据结构、算法、数据库、编译原理、人工智能里。我就是当初的离散数学学的比较认真,后面会有一种触类旁通的感觉。
当然,也不用因此被吓到。对于普通学生来说,如果不想继续在技术前沿去苦苦探索,数学其实没有必要抓的特别狠,即使后续忘得差不多了,也不会影响找工作或者简单的前后端编程问题。大部分本科阶段的数学课,只是培养一个思维,在后面遇到复杂概念时,不至于完全没有抓手。
现在遇到的问题:
而我在大学四年里面,如果只是按部就班的上学校的课程的话,多半不会对数学有多么深的理解。
学校的课程为了方便量化考核,不会考你的数学理解和思维思想,而是主要抓你的做题能力。
这一点我认为是学校教育考核的问题。举一个最好体现的例子,我身边几乎每一个同学对线性代数的理解都是计算行列式,矩阵乘法,求特征向量... 而没有一个是从线性代数上几何的意义去考虑,给我的感觉是我们过于注重线性代数后面的“代数”部分,而忽略了“线性”的概念,导致大部分同学即使学了人工智能或者图形学的知识,也不理解里面为什么要有矩阵 (后面有机会我再单独整理一篇文章) 。
而通过自学了解了 Gilbert Strang教授的 18.06课程,以及3B1B的动画讲解,才从其基本上去了解了数学的概念和意义。

第二层:编程基础
学计算机的一定要会编程👋😭👋!
常见的入门语言可能是 C、C++、Python,不同学校选择不同。大部分学校一开始强调 C 语言,因为它更接近底层 (几乎可以说是万物起源),可以帮助理解内存、指针、数组、函数调用这些基础概念,在掌握后,对其他语言的学习会快很多(这里强烈推荐下CS 50)。有些学校会用 Python 或 Java 入门,因为更容易写出能运行的东西,降低初学门槛。
刚开始学编程时,内容通常包括变量、条件判断、循环、函数、数组、结构体、类和对象、文件读写这些内容。看起来就像是在学语言语法,但本质上是在训练如何把一个现实问题拆成机器可以执行的步骤。
很多人以为写代码难在记住语法,实际上语法只是最表层的东西。真正难的是理解问题、拆分问题、设计流程、处理边界情况。
简单举个例子:写一个程序用来统计一组成绩的平均分。
这看起来很简单;但如果数据为空怎么办?如果输入格式错误怎么办?如果成绩太多,内存放不下怎么办?如果要在网页上实时展示又该怎么办?一个问题,一层一层往下挖,找准需求并采用基本的变量、逻辑就会逐渐从“写几行代码的小功能”变成“设计一个完整系统”。
编程基础课的意义不是是教你某门语言,而是第一次习惯用程序的方式组织思路。
遇到的问题:
1.考核带来的问题:
现在计算机课程的老师大多数是在念ppt,然后布置作业,写作业报告的考核方式为主。现在AI技术起来后,大部分的思维训练都可以通过直接给ai发要求来解决,几乎不用动脑。我身边追求绩点的同学,也为了拿到老师的高分,选择更为稳妥的解决思路,避免犯错,也会直接使用AI完成主要工作,把更多的精力放在完善工作报告上。导致我身边有很多编程几乎不通,但是文档能力较强的同学。
2.课程的设置问题:
我在这些基础课程的拿到的作业要求质量与 Berkeley的作业要求在难度上有着明显区别。我们最后完成的内容在难度上达到 Berkeley 的课后作业的大概期中前的水平,很难深入的通过一个项目让学术把问题拆的清楚,拆的明白。
而且我有一个很明显且强烈的感觉:教我们课程的老师大多是受制于课时要求来上的,其并不真懂得这门语言。比如C++的老师对指针的运用仅停留在基础用法,python老师对python的基础库的知识仅局限于课程ppt里的那些,更不用说上课会有尝试写代码运行不通,解释说写的是伪代码的闹剧。
这几个问题导致同学们的编程基础从从根本上就不是深入的、成体系的,所以后续甚至需要再去上一个语言编程班来加强。

第三层:数据结构与算法
如果只能选一门最能代表计算机专业基本功的课,我大概会选数据结构与算法。
数据结构研究的是数据怎么放,算法研究的是问题怎么解。
- 数组、链表、栈、队列、树、图、哈希表、堆,这些都是常见的数据结构。
- 排序、查找、递归、动态规划、贪心、图算法,这些则是常见的算法思想。
这门课一开始最让我感到痛苦,因为它不像写一个网页那样马上能看到结果,也不像做一个小软件那样有明确界面,有很及时的正反馈。它就像是在练内功,很多东西看着很好理解,很容易掌握,但大多数时间却是在不断失败中寻找出路。
数据结构和算法这两项构成了所有程序的底层。也常常会有用途一致,但是由于数据结构的不同产生了两种同生态位的优秀产品。
比如Notion 和 Obsidian 都用来“记笔记”,界面上同样支持页面、嵌套和链接,但底层的数据管理截然不同。Notion 把文档拆成 Block,用树结构管理层级与嵌套,一切操作本质上是子树的移动与折叠;Obsidian 则把每篇笔记当作 图中的一个节点 ,通过一个双向链接建立边,靠邻接表维护关联与反向索引。
简单来说,Notion 像是在整理一个多层文件夹,而 Obsidian 更像是在编织一张蜘蛛网,前者关心上下级,后者关心连接点。正因如此,同样是“整理笔记”,Notion 在思考“谁属于谁”,Obsidian 在思考“谁和谁有关”——数据结构并没有改变你能做什么,却决定了你是如何思考这件事的。
所以,数据结构与算法不是为了刷题而存在的。刷题只是训练方式之一,它真正训练的是:面对问题时,如何选择合适的抽象和解决策略。
第四层:计算机整体系统
计算机专业和一些纯软件培训最大的不同,是它会要求你理解“代码下面发生了什么”。
这部分通常包括计算机组成原理、操作系统、计算机网络、数据库系统、编译原理等课程。
计算机组成原理会告诉你,CPU、内存、指令、寄存器、缓存这些东西是怎么配合的。也就是屏幕上发生的一切,是如何通过二进制的0和1,在电子器件上进行变换,最后变成软件或者游戏的。
操作系统会讲进程、线程、内存管理、文件系统、调度、死锁。你会理解为什么电脑可以同时开很多软件,为什么程序会卡死,为什么内存不够会变慢,为什么多线程写不好会出现奇怪 bug。
计算机网络会讲 TCP/IP、HTTP、DNS、路由、拥塞控制。你每天打开网页、发消息、看视频,其实都在使用这些协议。学完之后,至少会知道“网络不好”不是一句万能解释,背后可能是延迟、丢包、带宽、DNS、服务器、客户端等一堆环节共同造成的。
数据库会讲关系模型、SQL、索引、事务、并发控制、数据一致性。它解决的是数据怎么长期、可靠、有组织地存起来,并且在多人同时访问时尽量不出乱子。
编译原理则会讲一门语言如何从源代码变成机器能执行的形式。词法分析、语法分析、语义分析、优化、代码生成,听起来很硬核,但它会让你理解编程语言不是凭空出现的,而是可以被设计和实现的系统。(这门课确实很考验逻辑,难度不低)
这些课共同构成了计算机专业的系统底座。你不一定以后都直接做操作系统或编译器,但理解这些内容,会让你在面对复杂问题时更有“底层感”,如果学习的够深,甚至可以在面对奇怪bug时,找出底层方向,比如我在看这个帖子的问题描述到后期的时候,就猜到或许与历史原因导致的数字的浮点计算有关。

最后一层:专业方向课
到了大三、大四,很多学校会开设方向课或选修课。不同学校差异会比较明显,但常见方向大概有下面这些,也可以通过csdiy.wiki去寻找自己想要的课程 (如果你很厉害的话,可以参考下作者的评价,对于我这种资质普通的学生来说,耗得时长比作者的高出不少,难度感觉要高一些,且学习完真不一定就记住了)。
人工智能与机器学习。 包括机器学习、深度学习、自然语言处理、计算机视觉、数据挖掘等内容。现在很热门,但真正学起来并不只是“调大模型”。你需要理解数据、模型、训练、评估、过拟合、损失函数、优化方法这些基本概念,还要学习pytorch等框架,刚刚上手确实令人兴奋,看到训练的时候损失在降,真得让人有种单纯的有点silly的高兴。
网络与信息安全。 包括密码学、网络安全、系统安全、Web 安全、逆向工程等内容。这个部分我几乎没有了解,只是有过一次机会采访过公安里面的网安人员和企业里的网安人员,浅浅的获得了部分知识。知道现在的市场对这方面的需求还在增加,但真要继续深入,就是网安这个专业的内容了。
嵌入式与物联网。 偏硬件和系统结合,可能会接触单片机、传感器、实时系统、嵌入式 Linux 等。它更关心程序如何在资源有限的设备上稳定运行。
软件开发与工程实践。 包括 Web 开发、移动开发、云计算、微服务、软件测试、DevOps 等。这个方向和实际就业联系很紧密,强调工程能力和系统开发经验。
大一的时候我们的院长(现在是副校)曾给我们上过《计算机导论》,他在课上推荐了《人月神话》这本书,我一看是上世纪70年代的书,还觉得院长真是个“老东西”(没有不尊敬的意思)。一直到我组织大创,真的开发一个项目的时候,想起来老师的推荐,才发现自己踩得坑别人早在50年前就有了更好的解决思路。如果想要了解开发的过程,《人月神话》是一本没有门槛的贯彻开发全程的故事书。
图形学、游戏、虚拟现实。 会涉及几何、渲染、物理模拟、引擎、交互等内容。它看起来很酷,但背后有大量数学、算法和工程细节。我曾经学习过GAMES101,后续实在是没有时间,课程也有点点难,就放弃了。但是这不算短暂的接触也让我在玩游戏时,会很注重游戏引擎的渲染逻辑,也会时常看一些虚幻引擎的发布会,了解这炫酷的技术。其实图形学不仅仅是面对游戏引擎这一类的知识,背后的方向还有很多,后续再进行介绍吧。
大数据与数据库。 包括分布式系统、数据仓库、数据分析、推荐系统等内容。它处理的问题通常是数据规模大、并发高、系统复杂。大数据的内容我没有深入接触,不好做出有专业性的评价。
这些方向不是互相割裂的。比如人工智能需要算法和数学,也需要系统和工程;网络安全需要操作系统和网络基础;后端开发离不开数据库、网络和软件工程。
计算机专业的特点就是这样:越往后学,越会发现很多课程在互相连接。想要把上述的专业方向全部学明白,或者说全部学一遍,在我看来没有人可以做到,即使是专精一个方向,也需要以年来记的时光。我在大学四年的探索不算少,但后续的深入研究,大抵就是研究生的方向和目的了。
具体可以看这一篇知乎回答:
计算机本科生花大量时间写编译器,操作系统是不是不务正业? - Freezy的回答 - 知乎 https://www.zhihu.com/question/321433640/answer/2066636784763720375
学计算机需要什么特质?
我觉得最重要的不是“数学天才”,也不是“从小会写代码”。
更重要的是几种比较朴素但又少见的能力。
一是愿意自己查资料。计算机领域变化很快,很多问题不会再有老师一步一步带你解决,甚至好多同学也没有时间手把手教你。报错信息、官方文档、搜索引擎、开源项目、论文、社区讨论,都会成为你学习的一部分,这个能力即使在现在的ai时代,也显得尤为重要。
二是能忍受挫败感。程序报错是家常便饭,环境配不起来也很正常。我曾经配环境配了3天才成功跑通,一个bug修了一周,天天熬夜。可能是我菜,但据论坛上的经历,貌似并不少见。
三是喜欢拆问题。计算机很少直接解决一个巨大问题,而是不断把问题拆小,把模糊需求变成明确步骤,把复杂系统拆成模块,这种思维一旦形成,即使是在浏览网页,也会尝试不自觉地去抽象里面的数据结构。(其实蛮像高中物理里的受力分析)
四是有一点持续学习的耐心。你可能刚学会一个框架,新的工具又出来了;刚理解一个方向,行业热点又变了。计算机专业不太适合只靠大学四年吃一辈子老本,更何况现在的ai时代来临,老本可能直接清零,保持学习或许是我们普通人唯一能与之抗衡的方法。
最后
计算机科学与技术专业学的东西很多,也很杂。
它既有数学,也有工程;既有理论,也有实践;既要理解底层系统,也要能做出上层应用。刚开始学的时候,很容易觉得这些课彼此之间没什么关系:数学是数学,C 语言是 C 语言,操作系统是操作系统,数据库是数据库。但学到后面会慢慢发现,它们其实都在回答同一个问题:
如何让信息被更好地表示、存储、传输、处理和使用?
这篇文章是一个很粗略的介绍,主要作为我大学四年来,一直学习的心得体会,以及我感受到问题和最真诚的建议。虽然一个对未来充满迷茫的普通双非大学生的学习体验不能覆盖全面,但至少希望它能帮助家长和对计算机感兴趣的同学建立一个基本印象:计算机不是大段的数学,也不是简单敲代码。而是去理解计算机底层的方方面面。
如果你真的选择去学习它,后面大概率会遇到很多让人头疼的 bug、看不懂的课、配不好的环境、做不完的项目。
但也会有一些很开心的时刻:程序第一次跑通,网页第一次上线,模型第一次出结果,自己写的小工具真的帮到了别人。那些瞬间会让你觉得,自己确实在一点点把脑子里的想法变成现实。
这些微不足道的小确幸和正反馈,大概就是计算机专业最吸引我的地方。
- Author:Mark Xu
- Copyright:All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating otherwise.

