新技术学习不完全指北:以 Rust 为例
共 11550字,需浏览 24分钟
·
2020-12-06 13:14
许多同学好奇,私信问我是如何学习技术的。正好最近在学习 Rust 语言,趁着记忆犹新,便以 Rust 为例,谈谈我的学习方式。
对 Rust 不感兴趣也没关系,其中包含的学习动机、学习素材、时间规划、训练项目、心态建设等理念,也适用于学习其它技术。
提前声明:本文分享的只是我个人的学习策略,仅供参考。
一、充分的学习动机是持续学习的源动力
学习技术,特别是学习新的技术,是一个高失败率的活动。
不知道多少次,我们停在安装项目依赖上,停在 Hello World 级别的尝鲜上。
很多同学把这些失败,归结为自己不够聪明,或者是不够坚持,或者没有一起学习的伙伴等原因。但是,大家忽略了一个很重要的核心因素——学习动机。
学习动机不是一个缥缈虚无的概念,最常见、最显著的一个学习动机就是——工作需求。
工作需求,是一个强烈的、持续性的、外部驱动的学习动机。那些跟工作关联起来的技术,通常就是我们掌握得最扎实、构成我们核心技术能力的部分。而那些跟工作关联程度弱的技术,则是最容易中途放弃的部分。
学习动机不够充分而过早放弃,是导致学习失败的重要诱因。
除了工作需求以外,个人兴趣是学习动机的另一大来源。大部分技术岗位的工作需求,可能没有那么多,甚至掌握陈旧的技术栈也能应付好多年。等到突然被输送到社会,才发现自己的技术竞争力不足。我们需要发掘出新的学习动机,去支撑我们不断地扩张技术广度和深度。
学习动机,跟感情一样,也需要培养。混迹于各个技术社区,听听其他人如何宣传不同的技术,我们可以看到那些技术分别做出的承诺,如内存安全、类型安全、跨平台、高性能、易用性、可维护性等等。渐渐的,某些技术就在我们的心里种下了兴趣的种子。
得到种子以后,我们需要亲自浇灌培育这些兴趣,让它们更加充沛。在所有感兴趣的技术中,去挖掘它们对我们现有工作的潜在价值。即便只是启发价值也好,我们需要让个人兴趣跟工作需求关联起来,如此可以得到更加持久的学习动机。
以我对 Rust 的动机浇灌为例:
我的本职工作是前端开发,涉及许多前端框架设计和前端基础设施建设等工作。
当前的前端架构,只用 JavaScript/TypeScript 和 Node.js 等技术栈,已经有点捉襟见肘。比如,用 JavaScript 实现的 Webpack 在应付大型前端项目的编译和构建,性能达不到要求。Vue 作者尤小右尝试借助浏览器原生的模块加载管理去优化这个问题,即最近热门的 Vite。其中 Vite 就选择了 Figma CTO 用 Go 实现的高性能 JavaScript bundler and minifier——esbuild。
未来前端开发基础设施里将包含越来越多系统级编程语言加持的工具。毕竟 V8,Node.js,Deno 就包含大量 C/C++ 和 Rust 语言实现代码。一切能用 JS 实现的,就算终将用 JS 实现,那些性能敏感的部分,也会更晚用 JS 实现。
也就是说,纯 JavaScript/TypeScript/Node.js/Deno 的前端架构师,将来的岗位胜任力和技术竞争力,很可能弱于掌握了一门或多门系统级编程语言及其生态的同行。因此,有志于前端架构方向的同学,在 C/C++, Go, Rust 等语言中选一门或多门进行持续学习,对将来或有帮助。(看到这里,不知道有没有埋下兴趣的种子呢?)
用系统级编程语言可以优化前端基础设施,但是要设计一个好用的前端框架,还需要学习其它知识。特别是函数式编程(FP)、编程语言理论(PLT)和类型论(Type Theory)等。比如学习 Haskell,理解 Monad,掌握 Algebraic-Effects,熟悉 Codata 等概念。
基于上述工作背景,Rust 相比 Go 等语言的学习优先级得以凸显。
1、Rust 语言设计更加现代,它很好地吸收了函数式编程特性,如模式匹配,代数数据类型,Trait,默认 Immutable 等
2、Rust 团队来自 Mozilla,对 WebAssembly 相对来说有更友好的支持和更多的投入,在 现代浏览器上通过 Wasm 去运行 Rust 代码提升性能,对于特定的、复杂的 Web App 很有帮助。在《Rust and WebAssembly》一书中可以看到更多相关内容:
Rust and WebAssembly
https://rustwasm.github.io/docs/book/why-rust-and-webassembly.html
3、Rust 在 Safe 和 Useful 上取得了更好的平衡
Haskell 的核心开发之一 Simon Peyton-Jones 在 2017 年的一个分享《Escape from the ivory tower: the Haskell journey》中,描绘了一个有趣的坐标图:
安全性和实用性坐标。有的语言(如 Haskell)是从安全性出发,在保证安全的情况下,增加 IO 能力,向实用性靠拢。而我们使用的大部分主流语言,则是从实用性出发,在保证足够的实用性的情况下,通过 Type System 等的约束方式,增加安全性。
安全但不实用 vs 实用但很危险。最终大家的目标都是,既安全又实用。
而 Rust 既比大多数主流语言更加安全,又比 Haskell 等偏学术的语言更实用,处于一个非常良好的位置。
此外,值得一提的是,安全性和实用性并不完全是对立的关系。一门 100 分实用性但不够安全的语言,普通开发者可能只能有效发挥出该语言 60 分的实用部分,只有少数高手才知道如何发挥出 100% 的实用价值。随着安全性的增加,普通开发者能落地的实用能力比率也将增加。
简单地说,Rust 编译器可以让我们对代码的内存安全、类型安全更加放心,从而敢于并且可以编写出功能更复杂的代码,而不必疲于跟内存问题做斗争,或者浪费大量时间去 debug。
通过以上分析,我为自己浇灌了学习 Rust 的强烈动机。通过 Rust,我有望获得更相比在 JavaScript/TypeScript 里更充沛的函数式特性实践经验,有机会编写高性能的前端基础设施去优化开发效率,有机会编写高性能的 wasm 模块优化 Web App 性能,有机会借鉴 Rust 语言设计思路去实现 runtime 小,无需 GC 的前端 DSL 等的各种可能性。
如此,学习 Rust 就跟我的工作内容产生了微妙的关联,创造了一个持续的学习动机来源。如果大家愿意,也可以通过类似的方式,去挖掘出学习一门新技术的强烈动机所在。
二、严肃学习是有效学习的核心部分
培养学习动机的根本目的,是为了让我们进入严肃学习的阶段。
很多同学的学习方式有一个重大问题,就是一直停留在培养学习动机的阶段。什么意思?
就是一直在看技术问答、小文章、技术视频以及参与一些线下聚会等,却没有考虑去官方网站里安装工具、下载依赖、阅读文档、编写代码、调试问题、搜索答案等。
技术社区是为了让我们从他人的技术宣传中获得学习的兴趣,获得学习的素材,但它们自身不等于严肃学习。
那么何谓严肃学习?
严肃学习是指通过权威的、一手的、经典的、系统化的学习材料进行学习的过程。
以 Rust 为例,入门 Rust 的严肃学习过程是,进入 rust-lang.org 官网,阅读首页里的基本信息,了解 Rust 给出的介绍和承诺,通过 GET STARTED 安装 Rust 和新建 hello world 项目,运行起来。
然后进入 LEARN MORE,官方文档指引我们去阅读 《The Rust Programming Language》书籍,于是我们乖乖阅读,做书里的练习题。不用等到看完这本书,我们又发现了的另一本书《Rust By Example》,放到阅读列表里。读完第一本,读第二本,以此类推。
这是属于严肃学习的过程,我们使用的材料,是官方权威发布的,是一手的,是系统化的,也是 Rust 当前的入门经典。而我们在技术社区里看到的,许多是其他开发者基于这些严肃材料而产出的技术文章,性质上属于读后感。读后感不是一手的,不是权威的,不是体系化的,不是经典的,不属于严肃学习的材料。
读后感/学习心得相比严肃材料,更简单和轻松一点,可以帮助我们建立对 Rust 等技术的初步印象和学习信心,但难以作为入门 Rust 的充分材料。包括这篇文章本身,也不属于严肃学习的范畴,而是一个激发学习动机的材料。
人脑是一个对信息来源很挑剔的器官,技术社区里混杂了很多八卦信息,它会轻视其中的少量干货。而读教科书、经典著作和论文等严肃内容时,大脑对信息的处理模式会切换成严肃学习的状态,更容易记住内容,并尝试去关联知识点。
那些停留在收藏夹里的严肃材料链接,是开启我们有效学习大门的钥匙,而在技术社区搜罗和收藏它们的过程,则是培养学习动机的阶段。
读了100篇读后感,起码要配合读一篇相关的严肃材料去升华和沉淀,去聚拢离散的知识点。
三、高强度间歇性是高效学习的秘诀
在具备了学习动机、准备好了严肃学习材料之后,下一步就是规划学习时间了。
我个人总结了一个学习技巧,分享给大家。
高强度间歇性训练方法,原本是用以健身,现在我们借用来描述知识学习的一种时间规划策略。
让学习更高效,本质上是让大脑非理性部分去重视理性认知的成果。人类的理性认知能力,相比大脑的其它功能,比如视觉加工、记忆、语言等,是更晚演化出来的部分。因此,人类记忆的工作机制很大程度上是相对独立的,不是我们想记住什么就记住什么,想忘记什么就忘记什么。在我们具备理性思考的能力之前,我们已经具备记住信息的能力了。
因此,我们需要利用人类的记忆偏好、对信息加工的偏好等各种既定特性,去让大脑记住我们理性上认定是重要的知识点。通过严肃材料进行学习,一方面是保证内容的正确性和系统性,另一方面也是诱导大脑去做深刻加工。
严肃材料对我们的大脑来说,有两重意义。一个是客观层面,学习材料由权威人士编写,经过了层层的检验和时间的考验。一个是主观层面,学习材料对我很重要,很有意义,关系很大。
找到严肃材料之后,只达成了第一个层面的严肃性。第二层面的严肃性,需要我们自我建设。世界上的严肃材料这么多,如何向我们的大脑证明眼前这一堆确实是严肃的、重要的材料呢?
一个有效途径是,让这些材料反复出现,即高频次、高密度、高强度地出现。
每天规划出一段时间,半小时到两小时左右,比如我规划出晚上10点到12点之间学习 Rust 严肃材料。让 Rust 每天都出现在我面前,每天都暴露在我的脑海里,随着它出现时间和频次的增加,大脑自动会逐渐认可 Rust 对我的生活的重要性。特别是,学习 Rust 过程中会遇到很多问题及其解决方案。它们会启动大脑的另一个认知偏好——对负面内容更敏感。也就是说,对我的大脑来说,每天都有 Rust 相关的问题在不断产生和解决,它会分配更多认知资源去处理和消化 Rust 知识,它会激发我们对 Rust 更有兴趣,因为它会想要获取更多 Rust 信息去加工。主观体验就是,我们会感到 Rust 越来越好玩。
高强度的持续信息暴露是必要的,三天打鱼两天晒网的学习方式,难以有效的激活大脑对 Rust 或其它技术的严肃定位。
除了高强度部分以外,间歇性的部分也很重要。它是指,我们必须适时停下来,娱乐、休息和睡眠。尽量不要废寝忘食地啃学习材料,仿佛一天要学完整本书。这是不现实的,一天强行看完整本书,不代表学习了整本书。大脑需要在睡眠阶段对当天所学习的内容进行加工和整合。不停下来提供消化知识的机会,对身体健康和学习质量都没有帮助。
用权威学习材料达成客观上的严肃性,用高强度间歇性训练思路达成主观上的严肃性,两者结合起来,我们学到了主客观层面都靠得住的严肃知识。
即便不了解上述严肃学习策略,其实很多同学也已有意或无意的通过增加严肃性来优化学习过程。只不过其中很多策略,可能不太经得起推敲。比如报一个培训班,增加老师和同学的监督角色,来提升学习的严肃性;比如去自习室、星巴克等地方增加学习氛围的严肃性;比如购买实体书籍,布置一个富有仪式感的环境去学习等。
在短时间内,这些做法固然是提升了学习的严肃性和质量;但这不是免费的。这些形式上、氛围上的严肃性,可能是成本高昂的。比如,当我们购买了 Rust 实体书回来后,很直观的看到,它像砖头一样厚。
可能每次学习时,都得鼓起莫大的勇气,把厚厚的书籍翻出来。每次都要洗漱打扮,出门去自习室占座,或者去星巴克占座,然后才开启学习之旅。这种启动学习的成本太高了,很可能导致我们学不起来,大砖头书籍最后垫显示器去了。
我个人的选择是,在线学习。我的 Chrome 设置为每次打开都还原上一次关闭时打开的链接。Rust 材料的 Tab 标签页在我完成学习之前,会一直出现在我的浏览器中,只要我有了心思,可以迅速地切换 Tab 进入学习,迅速的启动 VSCode 编写和运行代码。
学习材料的严肃性,包含了真正的知识。而学习环境和学习氛围包含的严肃性,并不包含知识。假设培训班老师自身水平也不过硬,所选教材既不系统也不权威,再严肃的学习氛围下我们也可能吸收不到可靠的知识。而不管身处什么环境,什么氛围,只要我们能沉浸到严肃知识材料中,有效的学习就发生了。
在制定学习规划时,我们需要明确有效学习的干货部分是否得到最优化:1)我们找的学习材料里包含严肃的知识;2)我们成功让我们大脑认可了这些知识的严肃性,使我们能长时间记住它们。即严肃性的知识得到主客观的统一。
尽可能低成本地启动严肃学习,可能是更好的途径。
四、超纲训练是巩固知识的可靠方式
找到严肃的学习材料,扎实且认真地学习了这些材料之后,下一个阶段是——超纲训练。
看过一遍书,不代表充分理解了书里的知识。我们要去证明自己确实在一定程度上领会了知识。
如何证明?
做那些没有参考答案的训练,即超纲训练。
以我学习 Rust 为例,《The Rust Programming Language》带领我们实现了一个简单的 grep cli 程序,一个简单的多线程 web server。但是,我们的代码实现,跟书里的答案太像了。即便我们能默写答案,也无法劝服我们的大脑,这些代码是我们的自主产出。
因此,在看完《The Rust Programming Language》和《Rust By Example》,我给自己安排了新的训练项目——光线追踪。
Ray Tracing in One Weekend
https://raytracing.github.io/books/RayTracingInOneWeekend.html
《Ray Tracing in One Weekend》是一本循序渐进的小书,里面的代码实现用的是 C++,我们可以用 Rust 做一个重新的实现。如此构成一个超纲训练,我们的代码有参考,但不是 Rust 代码,而是 C++ 代码。我们需要完成三个层次的理解:1)理解光线追踪算法;2)理解 C++实现方式;3)使用 Rust 实现。
光线追踪是一个学习新语言特别好的训练项目,它能囊括多种语言特性,又有性能要求,而且主要是数学计算,最后输出的是数字构成的列表/数组,几乎不需要使用其它 API,可以在多种环境里使用。
用 Rust 实现光线追踪时用到的功能大致如下:
0)基础特性:变量,循环,基本控制流,模式匹配,数据结构,数值计算,模块,文件系统接口等
1)操作符重载:Vec3 向量数据结构的 +-*/ 等运算需要重载。
2)Trait objects:多种类型的几何体,多种类型的材质,需要能够放到一个列表或者一个字段里做统一处理。
3)递归函数:光线追踪算法是一个在递归函数里不断产生新的光线路径的算法
4)包/crate 的使用:rand 和 threadpool
5)性能优化:使用多线程优化光线追踪算法性能
6)单元测试
7)cli 参数读取
8)代码组织结构设计
9)……
基本上覆盖到了 Rust 核心语言特性的一大部分。
如上图所示,我们跟着《Ray Tracing in One Weekend》,用 Rust 实现了十几个从简单到相对复杂的图形渲染,完成了 1000 行以上的有效代码量(已剔除demo之间重复部分)。
如此,我们完成了一个超纲训练,这个过程肯定会遇到很多困惑和问题,我们会反复翻看《The Rust Programming Language》和《Rust By Example》里的相关部分,查看 Rust 标准库文档,查看 crate 文档,Google 搜索其它问题等等。正是这些问题以及我们追索答案的过程,巩固了我们看书时有意无意疏漏的部分。
超纲训练是可以不断升级的,升级越多的层次,完成度和质量越高,训练效果则越好。当然训练难度也会不断增加,到某个程度后,我们自然会停下来。比如前面用多线程优化光线追踪的部分,就算一次升级,它是在《Ray Tracing in One Weekend》没有包含的部分。
另一个升级是,我们可以将 Rust 通过 Wasm 运行到浏览器上,然后对比 JavaScript 实现的光线追踪算法,看看两者的性能差异。这正符合我对 Rust 的学习动机之一:用 Rust + Wasm 优化浏览器里特定任务的性能表现。
因此,我开始阅读 Rust 官网里指引的另一本书《Rust and WebAssembly》,学习如何在浏览器里运行 Rust 代码,然后将我们的 Rust 光线追踪调整成 library crate。
如上图,Rust + Wasm 实现的 Ray Tracing 渲染到浏览器的 Canvas 上。第一张图片是渲染结果,第二张图片是呈现各个像素点的渲染次数(次数越多越白)。
值得一提的是,顶部导航栏还有 JavaScript 和 Rust: Small Image 的模块。其中 JavaScript 版本是我一年多前学习光线追踪算法时,所做的超纲训练项目。为此我还写了 3 篇文章,描述如何优化光线追踪的渲染表现:《React 优化技巧在 Web 版光线追踪里的应用:上、中和下》,恰好可以拿来跟 Rust 对比性能表现。
Rust: Small Image 模块则是另一个超纲升级。之前的渲染都是静态的一张图片,因为目前的实现无法支撑实时光线追踪的性能要求。但是,既然我们都在浏览器上了,绑定一些用户交互,切换观察视角之类的,总是更有趣的吧?而且,Rust + Wasm 比纯 JavaScript 实现确实性能好很多。我们将图片的分辨率调低,将物体的数量减少,然后实现了一个简陋的、可交互的实施光线追踪效果。
如上所示,尽管体验上不是特别好,但能够调整视角,还是不错的感觉。感兴趣的同学,可以访问下方 Demo 地址,在 PC 上体验一下噢。
Rust Ray Tracing Demo
https://lucifier129.github.io/rust-ray-tracing-demo/ray-tracing-web/build/index.html
目前我所做的超纲训练,就到上面为止了。其实还可以做更多升级,《Ray Tracing in One Weekend》的作者写的相关系列,一共有 3 本,还有另外两本的练习没有去做呢。即便都做完了,还是可以继续升级,将练习项目变成更加严肃的开源项目,成为一个 Rust 生态里的光线追踪 crate。都是可以的,但这不是我当前的目标,因此我还没有往这个方向努力的计划。总而言之,光线追踪作为我学习 Rust 的超纲训练,已经完成了它的使命。
超纲训练之所以重要,是因为一旦我们将学习到的技术,投入生产。我们所面对的各种问题,几乎都是超纲的,再没有书里的参考答案让我们照抄了。因此,在跟着官方书籍和教程学习完毕之后,立刻启动一个超纲项目加以巩固,可以有效提升学习的质量。
五、成果积累是获得技术自信的必要条件
一场学习之旅的最后一步,也是最容易被忽视的一步,就是将这次学习之旅汇聚成一个标志性的成果。
成果,可大可小。小到练习成果,大到科研成就。它是一个里程碑,昭示着某段时间的努力的价值。
它可以是一个具体的产物,也可以是一篇总结文章。当我们完成超纲训练时,其实已经自然而然得到了一个学习成果,当我们写成一篇文章时,又产生了另一个成果。尽管在将来的我们看来,这些成果实在微不足道,但是我们现在仍然需要一个成果。
我们的大脑需要一个成果性质的刺激。
是什么,区分了一次成功的学习和中途放弃的失败学习?是成果。
如前面所言,Rust 光线追踪还可以无限升级,根本学不到头。不管我做成怎样,本质上都是中途放弃了去无限升级难度。因此,我们要创造一个阶段性成果,去明确定义这次学习之旅是成功的,是达到预期的。上面那个托管在 Github 的 Demo 项目,以及这篇文章,都属于我这次学习 Rust 的阶段性成果。
随着我们学习的技术越来越多,我们累计的阶段性成果和文章也越来越多。我可以在 Rust 学习成果中,援引上次学习光线追踪的 JavaScript 版本的代码;可以在这篇文章中,援引上次我写的 3 篇文章。这些在时间长河中层叠和交织在一起的阶段性成果,可以告诉我们的大脑,它们真的很有用,很有价值,它们值得被铭记。
不断积累的成果,有大有小,有的可能已经被继续升级,甚至得到其他人的广泛认可,它们构成了你的成就。随着我们拥有的成果和成就的增加,我们的技术自信心也会增加,更容易启动去学习新的技术,去创造新的阶段性成果。
我们需要去保留成果,让它们留下痕迹,可举证。一旦我们知道,再也没有什么东西,可以证明我曾经学过和达成过某些目标和成果,我们的大脑可能不再认为它们对我们的生活是息息相关的。而如果我们一直记得,可以从哪里拿出某个材料,作为证据,昭示我们曾经的努力及其价值,我们的大脑会更乐意长时间的记住跟这个功勋章有关的知识。
对于技术学习而言,放在 Github 里的仓库,是一个很好的成果储存媒介。
六、心态建设是快乐学习的关键
学习技术,是一个长期的,甚至可能是终身学习的活动。在这个过程中,我们会碰到很多迷思,它们可能降低了我们学习的乐趣,可能打击了我们学习的自信心。如何抗住这些负面思绪,正确的看待学习中遇到的各种困惑,是我们需要长期努力的方向。
在此讨论几个迷思,希望可以带来一些启发。
6.1、失败是学习的常态,成功才是罕见的
开启一次学习之旅,最后却不得不宣告失败。这是很正常的现象,所有人都会经常碰到。
难道我现在收集量子力学的教科书,进行严肃学习,我就能学成吗?概率太低了。
很多学习是有前置知识要求的,在满足这些要求之前,越级去攻克某些知识,事倍功半,失败是很显然的。但是,很多时候,我们实在是不知道我们要学习的内容,究竟有什么前置要求,我究竟是否具备这些条件。我们只能亲自学上一学,用实际行动去检验我现在究竟有没有学会这些技术的资质。
也就是说,开启学习之旅,本身就是一场未知的冒险。学习失败,不完全是负面信号,不是指我们彻底完蛋了,它反而提供了很多正面线索:1)这些材料不适合我的情况;2)我需要寻找其它材料;3)我需要过一段时间,有了其它积累,再试试。
及时停止低质量的,甚至无效的学习,是在止损,是在保留精力,投资在更有回报的学习中去。不必气馁,来日方长。下一回,我们卷土重来时,胜算更高。
我们去积累成功,但不必去细数失败,徒增伤心,打击士气。
6.2、不必盲目攀比学习效率
在学习时,我们有时会忍不住跟其他人攀比学习效率,恨不得定下 1 天学会 XXX 技术的豪言。一旦在学习过程中卡住,特别是卡在基础概念上时,我们会感到焦急,认为我们学得不够顺畅,拖慢了学习的效率。
然而,仔细一想,我们会发现这些小心思是站不住脚的。首先,我们在学习,也就是在面对我们未知的事物,我们凭什么知道花多少天自己就能掌握呢?即便我们准确的说对了学习时间,那也是无根据的猜测,实属巧合。在没有外部时间压力的情况下,我们为什么要限制一个学习时间?如果我们的目的是学会这门技术,那么保持自己喜欢的学习节奏,默默前行,直到学完即可。时间长短,因人而异,不必攀比。
其次,遇到问题被卡住,也没什么值得烦恼的。所谓顺畅的学习,如果是指不被问题卡住的话,说明也没学习到什么,都是一些本质上已经知道和解决的问题。卡住,说明我们碰到了学习要点,在某种程度上是值得高兴的事情。
如果我们在卡住时,为了追求阅读进度这种百分比,而选择跳过问题,直奔后面的内容,可能带来我们无法想象的代价。在我们啃完大部头后,我们会认为自己已经掌握了基础知识,已经过了从头学习基础知识的阶段,到了实战或者进阶的时刻。
然而,其实我们基础知识并不扎实,我们跳过了自己当时不太理解的基础概念,它会反复困扰我们,成为我们进阶的瓶颈。我们以为自己是因为不够聪明,因此水平才一直没有质的提升,我们可能永远不知道,根源在当时我们跳过的基础知识上,我们不知道我们错过的是什么。
因此,在严肃学习时,除非是投入了足够的努力,证明继续纠结下去也是无益,否则轻易不跳过任何内容。
在学习 Rust 之前,我已经具备 JavaScript/TypeScript, Node.js/Npm/Webpack,Haskell 等语言、运行时和工具的学习和使用经验。Rust 很多语法、特性、概念对我而言,已经不算新颖,我仿佛可以跳过很多内容,通过 Examples 和 Cheat Sheet 等方式,边查边写,也能写出代码。
但是我没有。
我选择忍住冲动,默默一点点看,扎实的阅读,去培养自己 Thinking in Rust 的心智模型。一旦我们选择用 Haskell 的概念去理解 Rust 的特性,那么 Rust 就难以被我们的大脑认为是一等的事物,它可能被认为是衍生的、次要的,我们只要记住 Haskell 就好了。写出 Haskell 味道的 Rust 代码,让其他人难以适应,让自己也难以适应 Rust 里代码习俗。
严肃学习需要减少偷懒成分,去扎实的、诚恳的、谦卑的阅读系统化的材料吧,最后它们会给我们带来不可估量的价值。
不要去思考我是不是足够有学习效率,是否比别人学习效率高,转而思考,我是否在忠实地学习?
学习效率是一个客观统计,是我们扎实的学习完毕之后计算出来的,当我们走捷径,不求甚解的快速浏览内容,加快进度时,我们的学习效率并没有提升,只是它无法被正确统计了。只有当我们的学习处处是诚恳的、扎实的,我们阅读速度才反映了学习效率。否则阅读速度只是阅读速度而已,不代表我的学习速度,不代表我充分理解了内容。
我们不知道在学习初期的加速行为,是否导致了后续学习效率的变慢。我们不能盲目的加快入门速度,因为对于我们还不了解的技术,我们实在难以评估后果。有时看似愚笨的默默学习,或许反倒让我们后续的学习之路更加通畅。
严肃而诚恳地学习,即便不是最佳学习策略,也是一个明显不坏的选择。
6.3、不必成为焦虑的学习机器
学习可以是快乐的事情,我们不必追求每天都要有学习进展,不用觉得一天不学习,就落后于人。
人的成长曲线,可能是间歇性的突飞猛进,加上长时间的停滞甚至退步,构成的涨落。一年能完成一两次高质量的严肃学习,已经非常可观了。
去安然地享受看似不思进取的娱乐时光吧,然后认真对待每一次严肃学习的机遇。
七、总结与回顾
人类是故事动物,而学习,是我们对自己的大脑讲述的英雄冒险故事。
在技术社区里搜索有趣的内容,培养学习动机,是在为我们的大脑寻找宝藏的线索。
在技术社区里挖掘到的严肃学习材料,是献给我们的大脑的藏宝图。
开启严肃学习之旅,是我们的大脑正式迈上寻宝的脚步。
诚恳而忠实的学习,是让我们的大脑不错过任何知识宝藏。
而确立学习成果,则是让我们的大脑相信,我们终于获得了这次探险的目标——知识宝藏。
以上,就是这篇文章的全部内容,希望这篇文章可以带给大家学习新技术的启发。点击原文链接,可以跳转到 Github 仓库 Rust-Ray-Tracing-Demo,里面包含了我学习 Rust 的训练代码,可供参考。