学习路径
本文档记录了笔者自 2017 年到现在的学习路径,涵盖前/后端开发、跨平台 App 开发、Android 应用开发、OI(信息学竞赛)算法、Linux、嵌入式、自动驾驶、MATLAB、硬件 PCB 设计、机械设计、数据科学与机器学习、强化学习、机器视觉、AUTOSAR、函数式编程、UI/UX 设计、建模与动画设计等领域。
经历
2017 年,我拥有了属于自己的第一台电脑。同期,学校(当时还是学校)为迎合教育部门政策,开设信息技术课程。这是我第一次接触电脑。在这门课上,我学习了 Scratch。这是由 MIT 提出的一个模块化、图形化编程软件,可以通过简单的鼠标拖拽来实现各种逻辑,控制小猫移动。

之后,这门课教授了另一门差不多的软件(你叫他编程语言也可以):GOTO。我现在已经在互联网上找不到这个软件,但是其大概逻辑比较相似,他通过各种命令控制小海龟移动:
RT 100
ST 100
...
区别就是,他第一次让我了解了文字形式的指令。
之后,在 2018 年(我小学的最后一个年头),我们教授了 Python。这是现在大家耳熟能详的语言,在当时,我们通过 turtle 库来控制小海龟的移动,和 GOTO 相似。从这时起,我好像对这种被称作“编程”的事物有些兴趣。于是,我用我自己的电脑,搜索了一段“用 Python 实现登录注册”的代码,抄在纸上,试图理解这些这些当时看起来有些晦涩东西。这些代码大概是这样的:
print("--- 注册账户 ---")
name = input("设置用户名: ")
pwd = input("设置密码: ")
print("注册成功!")
print("--- 登录系统 ---")
input_name = input("请输入用户名: ")
input_pwd = input("请输入密码: ")
# 验证逻辑
if input_name == name and input_pwd == pwd:
print("登录成功!")
else:
print("信息不符,登录失败。")
不得不承认,虽然这样的代码现在看起来非常简单,但是回头看时,这是我建立起基本的编程思维的第一步。这里面包含了一个基本系统的输入输出、判断分支、错误处理,其实是相当全面的。非常庆幸,当时我找到了这样一个很好的 example。
这时,我的父母知道了我在学这个,但是似乎并不十分赞同。后来在无数个深夜偷偷打开电脑琢磨的一系列故事,就不在这里探讨了。
接下来,我对“网页”这个事情产生了兴趣。这是在小升初的暑假。我非常好奇为什么一个 .htm 文件点开就可以变成网页,于是就开始疯狂在互联网上搜罗这些(当时哪里有 AI?),找到了这个网站:W3C School。于是,我开始学习基本的 HTML、CSS,按照自己的想法做了一个属于自己的网站,并学习着往里面塞图片、视频,试图让他看起来像一个“大公司的网站”。那时候我塞的第一个视频好像是 vivo 的官方宣传片,看来我跟这公司的纠葛从这时候就开始了(?)。
就这样,我熟悉了 HTML、CSS 这两个根本不能称之为语言的语言。但是从此,我对这些东西越发好奇,越来越好奇网上的那些有趣的网页动效是怎么来的,那些网页小游戏(没错就是4399)是怎么来的。
于是,我遇到了 JavaScript。这是我第一门认真学的编程语言(Python 在我小学毕业之后就再也没有人提过)。我学着用 js 处理网页上的各种逻辑事件(在这: Javascript.Info),学习各种编程语言应该有的特性,这是我在编程语言领域打下的重要地基之一。于是,我可以做出各种神神奇奇的动效,做出各种逻辑实现,比如一个真正的登录/注册界面,虽然没有数据存储部分。
之后,我在初中的信息技术课上听说了 C++,同时知道了 “信息学奥林匹克竞赛”这样一个听起来很有吸引力的东西。于是,我回到家后开始自己琢磨这个东西,从网上疯狂找 C++ 相关的教程、文档,如饥似渴的了解这些我看起来非常美妙的东西。当时,跟学 Python 一样,我把一段简单的程序誊写在纸上,带去学校,老师不注意的时候就偷偷看看,尝试理解他们。
我记得我誊写的这段程序长这样:
#include <iostream>
using namespace std;
int main() {
cout<<"Hello, world!"<<endl;
return 0;
}
没错,就是大家熟悉的那样。
当时的我甚至连
include这个单词还不认识,居然还能用 i-n-c-l-u-d-e 这样的方式记下来,我也是真佩服当时的自己()
这是我第一次学习 C++,第一次知道居然世界上还有这样一大片没有被发掘的领域。那会儿我买了一本特别厚的 C++ Primer,没事就在学校啃这本“巨著”,其实确实让我了解了很多语言特性,对这门语言了解的更为深刻。
因为语言都是相通的,所以在掌握了一个语言之后,其他的逻辑大多也比较明朗,更多是语法的区别。
在这时候,遇到了一个很滑稽的事情,就是我的电脑已经卡到不行了。当时我的电脑是 HP Probook 4321s,是惠普 2010 年推出的型号。于是,在某个机缘巧合,我知道 Linux 好像能更流程一点,所以我入坑了 Linux。那年还是 Ubuntu 16.04,我在我电脑上装了好多个 Linux,在开机的时候可以自己选要进那个系统。我觉得这好帅!
那时候,我装过的系统有 Ubuntu、ElementaryOS、Deepin、Manjaro、ZorinOS、Linux Mnit…… 我甚至把 Windows 给删掉了——我家没有第二台肯给我用的电脑,所以我没有办法重新装回去。所以,我只能逼迫着自己去学习 Linux 的各种知识、命令、特性。滑稽的是,到今天,当年用的 ZorinOS 依然是我最喜欢的 Linux 发行版之一。那一年,我注册了 GitHub。最初的用途是寻找梯子,后来竟然为我开启了一个新世界的大门——我开始往上面分享我自己写的一些好用小脚本,比如一键调整 ElementaryOS 的顶栏透明度,比如更改 screenfetch/neofetch 的图标…… 这成了我学 GitHub/Git 的契机。
同时,我也有机会加入了社区,我加入了 Deepin 发行版的一个社区,叫做 Depein 天天用(dddu)。这个社区以 QQ 群的形式似乎一直延续到现在。在此,我认识了 qygw、Ho 229、momen、paperdragon、maicss、shenmo……等等一系列大学生或者已经工作的人,他们大多是前端开发者,在他们的影响下,我加入了这一软件开发界最为活跃的领域。我开始学着为社区做贡献,开始了解更多现代的技术栈。
一个印象特别深的细节是,一个朋友在我给他演示我用纯 html、CSS、JavaScript 手搓的动画的时候,给了我特别高的赞扬,同时告诉我,现在业界没人用这些了,业务代码会使用在这些基础上搭建的一系列框架,比如 Vue、React。这为我打开了一扇大门。以这两个框架为指引,我逐渐学习了 Tailwind CSS、React Naive、Nuxt/Next.js 等等,甚至在了解“前后端融合”的概念之后开始学习 Node.js,这是一个可以在本地运行 js 程序并和系统交互的库。在这个的基础上,我又学习了 electron.js,这个库以 Node.js 为基础,能够编写桌面应用。当时我正特别好奇 QQ、微信这样的软件是从哪里来的,知道这个框架的存在时,我真的非常满足,算是了结了我的一个心愿。
这时是 2019 年,疫情。
因为疫情而居家听课的我,和前面提到的 qygw、Ho229 成立了我的第一个团队—— Left Studio。这个团队甚至在 Gitee 上依然存在:Gitee - Left Studio。
在那里面,我写了自己的第一个“有用的”网页,那就是他的官网。我们决定做一个文本编辑器,就是 SurZ Editor。从这里,我学了 Qt,这是一种可以跨平台的 C++ UI 框架。当时学习他纯粹是因为 qygw 同学非常热衷的使用 Linux,而 Ho 229 却喜欢 Windows,后来才知道这个框架在工业界是应用的多么广泛。所以,我们采用了这个折中的方案。


这是我们的软件:

到此,是 2020 年。
这一年的另一件大事,是 Momen 找到我们,提议要做一个社区(当年国内的社区环境还没有现在这么严苛),就叫 DOSU,用来给 Deepin 系统提供问题解决的场所。我欣然同意,并跟他们一起,维护这一套基于 forum 框架搭建起来的社区系统。在这里,我学会了 UI/UX 设计、文档的撰写、基于 Git 托管系统的团队协作。
再后来,Shenmo 找到我们,提议要做一个软件商店 Spark Store,为当时非常羸弱的 Deepin 社区提供稳定、及时的软件来源。在那里,我利用之前学习的 UI/UX 设计、React 框架,实现了一套视觉效果特别好的应用列表页,居然在官方社区得到了一定关注和好评。这是我第一次因为这些获得赞扬。我觉得我开心极了,这是我那一年中最开心的一天。
同时,在 qygw 的影响下,我学了写歌,用 Cubase、FL Studio 去写一些古典、电子的旋律,学了 Blender 建模,学了很多很多我从来没有见过的东西,让我知道世界上好多我从没思考过从何而来的东西的产生过程和运行原理。他到现在依然在坚持这些,我十分佩服。
再往后,因为学业压力和家里的反对,我离开了 Spark Store 开发团队,离开了 DOSU。后来,DOSU 变成了 Spark Store 的问题社区,Spark Store 也和官方(UOS) 达成合作,他们给我寄了一些纪念品,其中有一些我到现在还在用。那是一段很美好的记忆。
这时候,我初二,在信息课上被老师推荐去学信息学奥赛(OI)。可惜因为一些小事,被当时的班主任严厉阻止继续参加培训,这件事就这么搁置了。
不过闲不下来的我又去折腾别的了—— Windows 和 Android 原生开发。我利用各种深夜,学习了 WPF 开发、Android 原生开发,然后继续我的音乐事业(老实讲,我真的考虑以后的人生去走这一条路)。当时,我和 CMJ(现在全平台特别火的一个纯音乐作者)聊过很多,他建议我可以试一试,这其实给了我一些勇气。
之后,我初中毕业了。在经过一系列曲折之后,我去了隔壁城市(东营)上高中。在这里,我正式开启了我的 OI 时光。我跟 lampese、zzz 他们,在市一中信息综合楼 3 楼的机房里度过了两年的时光,这两年中,我们除了一起参加 NOIP(中国年奥林匹克信息学竞赛),还一起玩 Minecraft、CSGO,一起在下雪天打雪仗,一起用巨长的 HDMI 线玩滑铲,一起用泡面搭柱子到屋顶,一起挑战7天复习两本书应对期末考试和月考…… 从那,我才觉得我的人生丰富了起来。
在这段时间,我向 Lampese 学习了很多,知道了世界上还有函数式编程这种很有意思的东西(我第一次学这个东西,是从他那里顺来的一本 Haskell 书),同时他也写前端,写 Node.js,我也跟他学了一些这个领域的有趣的东西。这名同学高考那段时间参与了 Moonbit Language(一门势头很猛的语言)的开发,去了好多好多地方实习,大学期间还休学去创业,我觉得他非常有勇气,他的生活是我很向往的样子。
同时在这段时间,因为备赛需要,我学了很多数据结构、dp、图论数论相关的东西,这些东西在现在看来是很受用的。当然,我的 C++ 技术也在这段时间突飞猛进。我在这段时间第一次入门了 Rust,知道了这样现代的语言的编写逻辑和要素。同时,出于好奇,我还学了 Go、Kotlin、C#、OCaml、TypeScript 等等一系列语言,这其实很大程度上让我全场景的编程变得更加熟练。
后来,高考结束后的暑假,我本着我会学计算机的假设,重新学了一遍 Rust 和 OCaml,但是因为这语言比较难懂,依然没有入门成功()
大学进入自动化(机器人工程)这个专业之后,我加入了学校的方程式赛车队,在电气组工作。从此,我开始接触硬件相关的东西。
首先肯定是 STM32,我在大学的第一个寒假跟着 Bilibili 江协科技的视频学了很多,然后趁热打铁,在大年三十晚上开始把 STM32F103C8T6 的手册啃了一遍,然后又买了一块 ESP32S3,用 Arduino 为他写软件,去实现一个小的服务器。之后学习 ESP32 的官方支持包 ESP-IDf,然后以此为契机学习了 FreeRTOS。自此,我用了 11 天的时间,从 stm32 基础学到 FreeRTOS,再到我当时所追求的一种“泛化能力”。
我始终觉得泛化能力是很重要的。当给你一个你完全陌生的 SoC,你如何根据手册和支持库的文档,去为他写各种业务逻辑?这是个很重要的问题。
真不知道我当时哪来的劲。
这 11 天对我来说真的非常重要。我大学期间几乎所有的奖项、成果和后续的学习,都是以这个为基础的。
开了学,我接到了一个大任务,车队的研究生学长要做 VCU,就是要自己做我们的赛车上的一个很重要的控制器。我作为软件组的成员,就加入了他们,研究 AUTOSAR 相关的东西。我用了小半年时间,根据极其贫瘠的文档,通过各种尝试和推断,配置出了几乎所有需要的外设。这让我知道,我的嵌入式基础已经比较扎实了。
同时,我学了一部分 PCB 的绘制,并自己抄了一版前一代的 VCU,作为练习。
后来,我接手了 RES Sender 的后续开发。学长遗留的代码是用 RT-Thread 写的。我根据我的 FreeRTOS 基础,居然很快的就理清了代码结构,完成了需要的后续开发。这让我对我的 RTOS 知识抱有信心,同时喜欢上了 RT-Thread 这种结构和包管理的便携性。
再后来,到了暑假,我留校学习。我接手了一个利用红米手机刷 Linux 之后实现 HMI 的项目。这让我可以自己处理一个完整的 Linux 系统,并配置其和复杂外设交互。这让我熟悉起了尘封多年的 Linux 技术。
同时,我对 MATLAB 产生了兴趣,因为我发现他是一个非常强有力的快速验证和迭代的工具。他可以非常方便的实现我的想法,验证其是否有效。于是,我用了半个暑假的时间,尝试了很多很多我可能用到的工具包。
开学后,我们对 AUTOSAR 的探索更进一步,终于完成了整个的配置,打通了上下游的工具链和信息传递链。至此,我们终于对 AUTOSAR 架构有了初步的了解。同时,我用 MATLAB 写了一版用于数据采集、存储和分析的程序。这让我对这种技术更加轻车熟路。
后来,我当上了车队的无人总监,我从这时候,开始学习和无人车相关的技术,包括 ROS 和各种控制策略。这部分我正在学习,目前还不知道学到这个程度算什么水平。
通过无人车上的 ZED 2i 双目摄像头,我浅显的了解了一部分 SLAM 相关的内容,跑出了第一个 Visual SLAM。
再后来,车队的指导老师接下一个项目,是为宇树 G1 机器人去做动作控制,这让我第一次接触到 mjlab、isaacLab 等等强化学习的工具和理论。这部分我依然正在学习。
再后来,我发现 ST 公司针对 stm32 芯片推出了 STM32 AI Studio,可以向边缘设备部署模型,于是我计划学习一部分 AI 相关的内容。
然后就到了现在
总结
整篇看下来,可以发现从九年前到现在,我越写越简略。这当然不是因为我写累了 (也不一定) ,而是因为,当故事有了一个很美好的开始,那么一切都是水到渠成。很多人说我很有自驱力,我全然不这么觉得。学这些东西,更多是这九年的积累之后一种自然而然的成果。我无意去学新技术,而是当需求和我的经历与惯性重合时,会自然碰出这样的结果,我会自然的对这样的碰撞产生的火花感兴趣。
所以,当你苦恼自己应该做什么时,不如先做自己喜欢的。事情总会向一个不错的方向发展。
另外:去年,我和文中的 Momen 和 paperdragon 面基。Paperdragon 出差来西安,而 momen 居然一直在西安工作。我们相谈甚欢,与六年前一样。