Deep Dive to OCW(Chinese)
前言:本文是一篇对 MIT open course ware 及 MIT 系公开课程的推广。
因为我经常看到网上有对 ucb, stanford, harvard 公开课的强推,但很少有 mit 系列的。珠玉在前,我希望能够写出一些真实的问题和分享一些个人体验。在自学计算机中,我尤其受到两个人的影响,因此坚定了实践(learn things by doing)才是学懂一件事的最佳途径。其起点又分别来源于两篇文章:
- Alex Chi: CS自救指北 - SurviveSJTUManual
- Hu Jinming: 19CS小硕校招面试心得与自学CS经验及找工作分享 | Jinming Hu
我在这个过程中遇到了许多问题,由于我是一个非常慢的学习者,其它自学的小伙伴们能够比我快很多的刷一门公开课,而我却常常死磕在一个坑里走不出来。非常幸运的是我遇到了一些朋友帮助,不至于在这条路上是完全孤独无助。然而,自学公开课并不能保证一份完美的工作/出色的绩点/许多其它认为有的东西。
动机¶
问题1:为什么要自学?
这更多只是个人的兴趣爱好和偏好的学习方式,并不是对未来生活的保证。据我所了解到的,“公开课只能保证一个人(面试者)的下限”(来自某面试官)。同时,计算机相关的同学有不少的人正在自学计算机系统方向的几门课程,无论是作为面试的项目,还是作为基础巩固专业知识。不过,自学这些课程可以提供一个继续深入相关领域的切入口,探索自己真正喜欢的想从事的行业。尽管这听起来有些幼稚,毕竟我还是个尚未接受过太多社会直接摧残的大学生,但这对我来说是一个值得反思回顾的起点。
问题2: 什么是自学?
我认为自学就是指一个人能够去学习自己感兴趣的任何东西。由于疫情的影响,2020 后的公开课雨后春笋般得出现。对苦学校老旧的培养体系已久的广大大学生来说算是个福音。OCW 的不同在于其长期以来对教育公平的促进。在北美的诸多高校中,MIT 的 CS 课程 无疑是在这一方面做出最多的,其最大程度的开放了相关资源让全世界的人都能学习到顶尖的课程。
问题3: 怎么自学?
我认为学习是一件比较私人的事,每个人有 ta 适合的学习方法,学习习惯。我更想介绍一些在学习中遇到的问题。
课程资源¶
先简要介绍一下 MIT 系的公开课程来源有:
- OCW: 主要公开课来源。最近改版后的 OCW 的亮点在于搜索功能更强了。排版的改进和 MIT 其它的公开课学习平台风格(edx 风格)差不多了。
- MITx 和 MIT Open Learning Library | Open Learning :作为 ocw 和 edx 上部分课程的存档,作为对 edx 上有时期限制的课程的补充。
- 直接的课程网页。MIT 大部分 CS 课程都有独立的课程主页,并且有不小数量是开放的。我在大一下时经常没事就根据 6-3 课程计划去搜一下相关课程,了解一下之后想学什么。虽然当时我主要在 edx 看编程基础,数学类,物理,化学,生物的课程。
- Stellar: Electrical Engineering and Computer Science (Course 6) : 每个学期开设的课程单子。无意中搜到的一个网页,有 public 显示的会开放部分资源。不过大部分课程都是仅限校内的,除了 6.006 几乎会把每学期的课程资料都放在上面以外。
个人认为一门适合自学的课程至少需要具备的条件是,有 lecture videos + recitations + hw + solutions。年代是否最近得具体看课程质量,比如我认为 6.006 算法课就是 10 版本讲得比 20 版本的更好,尤其是 recitation 部分,助教讲的东西仍然是现在人们所看重的问题。但作业最好做最近版本的。
课程评价网¶
虽然现在知名度更高的是一位北大同学的 CS 自学指南,但其实还有一份内容更详实的名校公开课程评价网。在这两个项目初期都有些了解,前者的目标是希望同学能够设计出自己的课程计划方案,去探索个人兴趣。而后者的目标是为了给之后自学的同学指出一些坑和合适的学习方式。
Sys basics¶
刚开始很难知道想做哪个方向,但不去试试你不会知道自己真正想要的东西。我在刚升学时只是大致坚定想学计算机,但具体是什么我并不清楚,大学前两年尝试了一些事以及和同伴聊了很久后才逐渐有了模糊的方向感。大一我主要明白科学计算和软件工程完全是两个不同的方向。而且,相比应用,我对纯数学理论没有太大兴趣。当时我还跟风玩了短暂时间的 WolframAlpha 和 一些别的计算软件。
一个比较有效判断是否对某门课程感兴趣的方式就是听完第一节课和完成第一份作业。如果在第一节课就打瞌睡,那可能这门课程并不是很合适深入了解。大一下我打瞌睡的课分别有:读公正的课后阅读,微观经济学,修辞学,生物导论,计算思维导论,统计学;大二上有机器学习(python)。
无法完成一门公开课是一件正常的事。在不同阶段总会有一些特别的原因导致这种停滞,因人而异。这并不代表智商低下,而是这些事情的理解学习本来就需要时间,尤其是在自学时。我很喜欢的积极心理学的一句话:
Learn to fail, or fail to learn.
同样的,这些问题由自己决定是否能够解决。一个理想的情况是:这个课里的 lab 都会做,bug free。当看到其它人能很快的做完一门课的课程项目时难免就会怀疑自己。这种怀疑可以从智商,学历水平,数学能力,前置知识到无助放弃。
我对研究一个复杂系统有很大的兴趣。因此我也希望自己能够独立地真正学好一门课程。
实习¶
首先,本人在各方面都是一个小白,以下更多是分享一些这个暑假前后的学习计划和对行业的一点看法。科技行业职业发展的方向挺多的,由于我目前对存储系统最感兴趣,会主要讲述这个方向相关的想探索的实习方向。同时,同龄人中做数据库方向的人也挺多的,也会谈一些非常粗浅的想法。
行业观察¶
对存储系统(软件方向)更感兴趣。我认为至少可以从三个方向测试和学习这一方向。
- storage device (current state)
- database storage engines
- cloud storage
存储感觉到背后总会交集在某个地方,关键是要把简单的事做对,而不是重复做某一件事。最近发现这个实习项目背后和另一些熟悉的人的工作连接起来,觉得很巧合。
5
有时候比较羡慕别人能够那么快就确定投入一个行业方向,有很多同龄人去从事数据库开发方向了,在一些初创公司做内核开发。比如现在众多人都向往的 s 厂(singularity data) 成长得就很快和 p 社(Pingcap)。经常听到有人说数据库开发是可以做很久的行业。但我目前对数据库没有太大的偏好。看了一些在相关厂工作几年后记录工作的文章,我对这样的生活没有特别向往。
6/21: update
在和一些人聊过后豁然开朗,前期我不用太纠结于具体做系统编程的哪个方向,做存储可能没有搞数据库的人看起来光鲜亮丽,但只要是自己喜欢做的事,才能更长久地发展。
学习规划¶
22/5/28:
其实写这篇文有部分原因是对下周一开始的实习感到有些害怕。新的生活总有一些担忧的问题,新的交流,认识更多的人。不过也正是因为这样,我能够在这三个月里尽我所能地去学习新的东西,搞懂之前没懂的东西。比起犯错,更糟糕的是自以为没错。早发现问题才能早解决。
开源活动¶
现在比较活跃的开源活动有:GSOC, Outreachy, CNCF, OSPP(开源之夏), MLFx, Pingcap’s talent plan。
最近有个小小的感触,在这些活动中女性比例好少。今年 GSOC 中选人里有显示的大概低于10%。在观察某个行业方向的技术从业人员时,我也几乎没看到女性开发者的存在。
开源活动真的非常神奇,一个好的项目背后聚集的是来自全世界的专业人才,不同时区地点贡献代码。
远程工作¶
我认为工作最重要的是效率而不是怼时长。我还在适应这种工作方式,目前的认为比较合理的时间分配是:9-12,12-1(午饭),1-6。之后的问题就是如何能够利用这段时间高效地完成任务。然而实际执行中,时间安排会更加灵活,可能一天很忙一天很闲,看自己怎么分配工作了。
常见问题¶
初期¶
问题1: 学什么?
学习是一件需要投入时间精力的事,我一直认为兴趣是最好的老师。在刚开始对这个专业还一无所知时,我们会倾向于看别人尤其推荐的。比如 TeachYourselfCS-CN,Open Source Society University,或者知乎上某篇列举了各个北美某校课程名的文章。这些推荐内容有一个问题:列举的课程太多而没有实际经验,里面的坑没有说明。而课程评价网可以给出比较贴合实际情况的评述,因为大多数人是自己上手去做了课程项目的,在主页中也详细说明了可能的问题。
问题2: 遇到自己难以解决的问题怎么办?
联系和交流。和了解这方面的人交流,问对问题。
中期¶
问题1: 学完一门公开课的标准?
刚开始我以为学完一门课指的是做每一道练习题,看每一页课后阅读,最后结果就像背单词只背abandon 一样。尤其是在遇到不会的题,受挫感直线上升,导致很长的停滞。我失败学完的公开课实在是有点多了,因为不同的原因。
另一个误区就是过高的标准下没有合适的思考问题的方式。比如我有段时间在想写 binary search tree 时,试了几遍不对我就开始怀疑自己太傻了,花了这么长时间没什么进展。但其实在写还不熟悉的东西时, test drive development 才是比较好的方式。我当时估计连基本的语法结构都没搞清楚……
问题2: 怎样才算学好一门课?比如能够写在简历的课程项目。
通过最近的实习相对完整得过了一遍完成一个中等项目(450+150h)流程,我发现了一些自己之前理解有偏差的地方,梳理如下。
- 先进行相对简单的任务,当对依托的项目不太了解时。好处是可以在难度不太高的任务中熟悉所需理解的部分结构。然后再完成相对困难的任务时,不必再经历一遍不熟悉某些 callback 的坑。
- 阅读先从感兴趣的部分开始。作为有点囤积狂的人,我经常扔一堆东西到收藏夹,但大部分内容只是草草地略读了一下,并没有太多深入的思考。最近想出了一个办法或许可以解决这个问题,选择自己最感兴趣的一个主题,相关的资料(包含代码,练习等)可以放在一个文件夹里,然后集中时间阅读学习。然后可以附一个 topic_log.md 在相同路径下。
- 做课程项目(只适用于 lab 间没有依靠性)可以跳跃式地选择感兴趣的任务先完成。同样的,最近打算试试这样能否解决挤压的太多课程任务。
- 做课程项目的过程同样是学习样例,test case 的过程。独立思考很重要,但从学这些(不是说抄袭)开始可以更好地延伸思考,不然老卡在一个 task(在说我自己)。
- 在开始一个较大的项目时,除了思考大致的任务需要完成哪些(设计)以外,在开始入手实现时可以先思考一个最小的可以实现测试的单元 (Test driven development)。比较好查 bug
问题3: 当学习公开课程时,我们在学什么?
近一年投入到某个开源项目下的某个任务中,出现过几次醍醐灌顶的时刻,突然就理解了之前觉得非常生硬的理论和定位到更小的问题。学系统类课程应该也和实现任务有同样的思路和方法,衡量标准为通过测试,但每个人缺失的部分和对过程的领会都是不同的。如果我不知道自己在学什么,就很难继续进行下去。