因为飞书底层是用Rust开发的,所以最近一段时间都在写Rust的代码,我对写Rust也越来越顺手,速度甚至已经比我用了很多年的c++要更快了,虽然主要原因是Rust有很多语法糖,可以加快写代码的速度。作为了一个之前完全没接触过Rust的新手,也就花了几天时间,便能熟练的进行Rust项目的实战开发了。
我想到我曾经还是一位菜鸟程序员得时候,学习并且掌握一门语言要花很长的时间,并且还会到处向朋友炫耀,自己会多少种编程语言,到如今,已经完全不关注自己会多少种编程语言了(因为写过的语言太多,起码也十几种),学习一门新的编程语言所需的成本也已经很低了,一般也几天时间,就能掌握这门语言,我的关注点也从我会多少种语言,转移到这门语言在解决问题和提高效率上的实用性上。
所以我写这篇文章不是为了介绍Rust怎么学,主要是想讲讲作为一个经验丰富的程序员,如何能做到前面提到的两点:
- 如何用很短的时间掌握一门新的编程语言
- 如何基于实用性出发选择合适的编程语言
如何短时间内掌握一门新的编程语言
编程语言千千万,但是基本都要解决同样的问题,我这里列出了一些最主要的问题:
- 如何进行任务调度
- 如何处理数据
- 如何处理异常
- 如何管理内存
不管我们学习哪种编程语言,都要带着这些共通的问题去进行学习。针对这几个问题,下面我一一进行讲解。
如何进行任务调度
在任务调用上,无非就是两种方式:线程和协程。线程和协程的原理我不深入介绍,就简单讲一下,线程就是一个应用线程对应了一个系统的进程,是一对一的关系,而协程是多个协程对应了一个系统进程,是多对一关系。在使用场景,线程适合高CPU消耗任务,而协程适合高频的IO任务。当我们深入掌握了线程和协程的原理,线程安全的原理,线程协作的原理等基础知识点,那么面对任何我们没接触过的新语言时,我们只需要知道该编程语言支持哪种调度方式,比如Java支持线程,Kotlin支持协程(假协程),Rust支持线程和协程,然后再熟悉这门语言进行任务调度,加锁,等待,休眠等特性的代码要怎么写,我们便掌握了这门语言至少20%的知识点了。
如何处理数据
在数据处理上,所有的编程语言都需要提供基本的数据结构,如数组,队列,Map等等。我们需要掌握的是数据结构的原理,面对不同的数据类型特性,如何选择更合适的数据结构,而当我们学习一门新的语言时,只需要了解这些基本的数据结构对应的是哪些类即可,比如Rust中的Vec,Java中的ArrayList,其实都是动态数组这一基本的数据结构,所以在Rust学习时,我很快就能熟练的使用Vec等这门语言提供的集合容器。到这里,我们已经掌握了这门新语言40%的知识点了。
如何处理异常
异常处理是编程语言中很重要的一块知识,但是新人却很容易忽略。我们都不希望程序动不动就crash了,越是优秀的语言,对异常的处理越是完善,写出的代码crash也越少,比如用Kotlin写的程序,空指针导致的crash比java要少很多。其中Rust是我遇到的在异常处理上最为严苛的,需要手动处理每一个异常。当我们熟悉这门语言该如何处理异常时,到这里便已经掌握了这门新语言60%的知识点了。
如何管理内存
习惯了使用解释性语言的开发者可能不太关注内存的管理,当我们使用Java时,Kotlin时,并不需要我们主动去释放内存,因为虚拟机会帮我们做。但是对于其他编译型语言来说,内存的回收和释放,都只能我们自己做了,最常见的就是c++语言,内存的申请和释放都是让我们写起来觉得很麻烦的地方。当我们学一门新语言的时候,一定要熟悉这门语言是怎么管理内存,即使是Java这种不需要我们手动管理内存的语言,我们需要了解它的虚拟机是如何进行内存管理的。当我在学习Rust时,我首先关注的就是Rust需要如何管理内存,因为他是一门编译型语言,性能上不会逊色c++,我以为它依然需要自己手动申请和释放内存,结果发现Rust通过所有权的机制,使得我们不需要自己手动的申请和释放内存,这种机制立刻就让我眼前一亮,因为这是我之前从没接触过的一种新的思维。到这里,当我们掌握了这门语言是如何进行内存管理的,我们便掌握了这门语言80%的知识点了。
其他
剩下20%的知识点,包括这门语言基本类型的申明,提供的API,独有的一些特性,语法糖等等,在使用过程中,就能慢慢孰能熟能生巧了。
基于实用性出发选择合适的编程语言
我们学习或者在项目中选择一门新的语言,不能谁便拍脑袋,而是要基于实用性的考虑。我常常考虑的主要有下面这些点:
- 性能
- 简单易用
- 安全
- 跨平台
- 足够多的社区支持
编译型的语言在性能上是要好于解释性语言的,所以我们在客户端开发时,很多对性能要求高的逻辑都是用c++来写,而不是用Java来写。我在前面提到过飞书的底层是用Rust写的,这里的底层主要是数据层,包括db,网络请求等和数据相关的逻辑,都是用Rust完成,其中一个主要的原因就是因为Rust支持携程,在IO场景上性能会更好的,在加上其他的一些考虑,比如简单易用,跨平台等特性,Rust自然便承担了这一重任。
其他的点我就不一一展开说了。我们在选择语言的时候,都会有原因,新人可能在意简单易用;创业团队可能在意跨平台;对我来说,我对性能的要求是比较高的,因为我本身就是做性能优化这一领域的。只要我们有自己的原因和目的,而不是盲目的去选择和学习即可。
我听不少开发都说过,互联网行业技术更新迭代快,学的知识很容易就过时,然后就需要重新学习。我实际是不认可这些说法的,底层的知识更新迭代很慢的,比如计算机的原理,Linux系统的原理等等,只要我们深入掌握了,其实是可以使用很长时间的,是投入产出比很高的事情,我们认为迭代快的东西,往往都是上层的技术,比如一个框架,一个门编程语言等等。但只要掌握那些迭代慢的底层技术原理,不管上层的技术迭代多块,我们都是能很快速的进行响应和跟进的。