钟宇腾(Elton, GitHub 、 LinkedIn ),香港大学计算机系毕业,微信游戏开发组工程师。
CSDN:首先介绍下你自己及目前所从事的工作。
Elton: 我是香港大学计算机系研究生毕业,本科在中山大学计算机系。目前正在微信游戏工作,岗位是后台开发。
我接触计算机也算是比较早的,记得当时家里的电脑跑的是DOS,我经常看着老爸在电脑里敲着各种命令,然后屏幕的字就刷刷刷出来,感觉非常好奇,现在想起来依然记得当初在电脑上敲下的第一个命令:dir,然后看着屏幕刷出来的白字。虽然一点都看不懂那是什么意思,但觉得非常好玩。
快升初中的时候,老爸给我买了一个在电脑上跑的学习软件,并要求我每天都要在上面去做题,于是当时就学会了怎么读软盘,然后在DOS上进入软盘然后执行那个软件,再换其它软盘来把题目读出来,再做。
初中的时候,家里的电脑由于被我自己弄坏了很多次,已经可以熟练安装Windows 98/2000/ME,在学校里面,也是经常到办公室帮老师重装系统。后来家里电脑再次升了个级,终于可以安装XP了,当时是自己到电脑城买的盗版光盘(当时并不知道这是盗版的),然后在家里装上,还能想起当时安装完XP进入界面后,一边感叹绚丽的界面,一边把各种功能都点了个遍。
最初接触编程也是在初中,当时学校要举办班级网页大赛,因为在老师那里名声在外,自然而然地代表班级参赛。下载了FrontPage和DreamWeaver,然后去书店买了两本书依葫芦画瓢,拖控件做出了个静态的网站。有时觉得直接拖不好看,于是就点进源代码去试,虽然不懂,但还是靠猜和无数的尝试,做出了自己满意的效果,在大赛中也获得不错的成绩(好像是第一名,但已经不记得了)。之后高中(同一个学校),又被拉去做班级网页大赛,这次就不光是做了个静态的,还在网上搜索到了不少的可以实现某些特殊效果的JavaScript或者是VBScript的脚本,虽然也是完全不懂,靠摸索修改各种参数,把它嵌入到自己的网站然后调试出自己想要的效果。记得当时为了这个网站,每天晚上自习回家,一直弄到12点之后,各种调试,乐在其中哈。
说说第一次接触Linux,那是高三的时候,一天一个同学跟我说,我在网上看到一个好漂亮的系统叫做Ubuntu,你要不要看一下?然后搜索发现了各种Ubuntu的漂亮的效果图,大多是Compiz弄出来的效果,然后很果断地,下载了Ubuntu 9.04的ISO,刻盘,安装,一气呵成。但是问题一下子就来了,想安装软件,完全不会!搜索只看到Ubuntu Forum,进去发现很多人都在讲,在终端里输入 ./configure, make, sudo make install就可以啦,然后我花了一个星期,才搞明白,终端原来是那个在菜单里找到的叫终端的一个软件(Gnome 2),然后再花了一个星期通过搜索搞明白了什么叫目录结构,学会了少数几个shell命令,终于从终端进入到了那个文件夹,然后输入了那三板斧。之后的一个月,就是一直利用搜索引擎解决各种遇到的问题,终于把那个软件装了上去,成功入门。
之后到了大学,如愿上了计算机系,系统地学习了各种计算机领域的知识。
CSDN:你的 Rust 之路是怎样的?
Elton: 认识Rust是在大三的时候,我在网上(不记得是哪里了)有介绍Rust这一门新的编程语言,然后好奇就点进去官网看,当时版本好像是0.9dev吧,语法和现在可差远了。进Documentation读了两章发现这语言的设计有意思啊,指针虽然分了非常多种,还有个神奇的Lifetime的概念,认真读下来感觉和写C++程序的时候差不多,只不过这门语言想要在编译期就检测出大多数的错误,很有趣。于是向一个小伙伴介绍了这门语言,让他和我一起学习。学完基础之后,我就想做一个小项目来更好的理解这门语言,就选了做一个INI库(rust-ini)。这是我的第一个Rust项目,之后每一次Rust语法更新,因为强迫症的原因,就被迫读更新日志,然后根据更新修改项目让它可以在新的编译器下编译。
之后第二个项目就是shadowsocks-rust,因为GoAgent越来越不好用了,用了一些日子的VPN,就萌生了想自己写一个VPN,然后搭在linode上。当时混V2EX发现很多人都在聊ShadowSocks,花了一天把源代码读了一遍,感觉非常好实现,花了一个星期做出了初版,之后也是跟着Rust的版本一起升级,经历过几次大的变动,代码混乱不堪,最近有点时间,顺便利用了一下coroutine-rs这个协程库,把它重构成协程版。
CSDN:你在 GitHub 上组织和带领了多个项目,能不能详细说下经过?其中有没有什么有趣的事情?
Elton: 在Github上大多都是自己的个人项目,说到带领的话,coroutine-rs应该算是一个。当时在Rust中文社区的群里面,发现Young在研究libgreen(Rust早期0.12dev版本官方实现的一个协程库,后来已废弃),自己也在做相关的东西,两人一拍即合,合作做出了coroutine-rs。
rust-ini 是我学习Rust时做的第一个项目,经历过好多次的改版,最近的一次改版是为了试一下Rust标准库的Cow(Copy-on-write)库,把整个项目改了。
jsonrpc-rs 是最近和最初一起学习的那位小伙伴一起合作的项目,项目的主要原因是为了探索一种好的RPC库的设计。
bson-rs 项目实现了一个BSON库,这个纯粹就是因为无聊,然后看到了BSON的Specification,花了一天写出来的。现在有几个团队想用我这个库去实现MongoDB的Rust driver。
simplesched 和 eventedco 是基于coroutine-rs实现的调度器(Scheduler),包含各种Non-blocking I/O的支持。实际上我是想做成像Go那样的Work-stealing Scheduler,但是因为做了一个月发现做出来效率很差,就先退而求其次,放出了两个不同思路的简单的版本。
memcached-rs 这个也是一个周末,看了Memcached的几个Client实现之后,心血来潮,花了几天时间实现了一个Client库,最近在计划用Rust克隆一个Memcached,为了学习Memcached的设计。
其它的项目跟Rust关系不大,都是一些个人的兴趣项目,其中小部分是在学校的课程项目。
CSDN:你是何时、如何成为微信团队的一员?其中面试过程,你有什么心得体会可分享?
Elton: 去年10月的时候面试微信团队的。腾讯的面试相信大家在网上都能了解一二。面试内容无非一些基础的函数实现,还有操作系统相关的一些知识的题目,问到的知识我在学习的过程中都有深入了解过,因此面试非常顺利地就通过了。
CSDN:能否谈一下,你毕业时为何选择到腾讯工作?毕竟家里人想要迁居香港且希望你在香港工作。
Elton: 我曾经想过在香港工作,也面试了一家创业公司,组长非常看好我,老板也给也给出了很不错的薪资。但考虑过后我还是放弃了,回到深圳腾讯。主要是感觉香港的IT业没有深圳繁荣,虽然有不少的创业公司,但我个人还是希望先到大公司积累经验,以后再考虑创业公司闯荡。
Rust需要一个大公司带头做出一个成功的产品作为案例
CSDN:Rust 是一种怎样的语言?相比竞争对手 C/C++ 几何?各自的特点是什么?
Elton: Rust是一门系统编程语言,系统编程语言说明它有直接操作硬件的能力,就像C/C++一样,但是它还有一个重要的特性,那就是安全。在C/C++里面,很容易会因为内存管理的问题而出现Segmentation Fault,在Rust中,由于引入了所有权(Ownership)和生存期(Lifetime)的概念,实现了自动内存管理的同时,还避免了各种内存错误。但同时,也提供unsafe块和祼指针(Raw Pointer),提供更多的自由度。
在Rust中,还支持高阶函数(闭包,Closure),C++11 之后也提供了Lambda来支持闭包,但在C中还没有。
模式匹配(Pattern Match)和ADT(Algebraic Data Type),在C/C++中都没有提供。模式匹配和ADT在许多函数式编程语言中都作为标准来提供了。有了ADT,可以把许多操作都统一起来,并且利用模式匹配可以很方便地把其中的数据取出来。
默认情况下不可变,这在C/C++中是完全相反。默认不可变更有利于编译器优化,而且不可变对于写并发程序有不少的好处。
CSDN:Rust 学习中新人要注意哪些问题?
Elton: 新人刚接触Rust,特别是没有接触过函数式编程语言的新人,首先可能会被模式匹配、跟C/C++/Java等完全不同的枚举类型,还有各种指针类型难住。
其次,继续学习下去会发现Trait based OO跟以前接触的OO完全不同。
再之,深入学习的时候,对象所有权还有生存期的概念看起来完全不知道在讲什么。
最后,上手实践的时候:天哪,编译器我到底写错什么了啊!你好好说话啊!!
我就是一步步这样过来的,当时也没有接触过函数式编程语言,后来才学习了Haskell才深入理解了Rust中的ADT和模式匹配。对于平时习惯高级语言的新人,我建议在学习的时候,不要试图把Rust的一些概念直接套入到自己习惯的语言中去,因为那是肯定不可能的,而且还会影响你理解。对于语法上的不理解,建议使用play.rust-lang.org来学习,看完之后实际操作一下,在例子上做一些小修改尝试让它跑起来,不明白的地方找个人一起交流(现实中找一个小伙伴一起学习是最好的办法)。
在理解对象所有权及生存期的时候,文档读起来非常晦涩,可能会让人产生非常大的挫败感。其实,建议先从例子开始一步步理解:
所有权讲的是Ownership,思考一下当前对象的Owner是谁?如果用了Borrowed Pointer,那它被借给了谁?是可变的还是不可变的?
如果代码中有显式的Lifetime,如下例子
fn test<'a>(s: &'a str) -> &'a str { s }
当我这样调用函数时
let hello = "hello"; let hello2 = test(hello);
'a 是多少?因为 "hello" 的类型是 &'static str,所以生存期是 'static,把它代入到函数声明,就会发现,'a 就是 'static。绝大多数情况生存期都可以这样一步步的推导出来,并不难。
Rust编译器还嫩,许多错误提示还做不到很智能,因此错误会非常晦涩。遇到一直编译不过的问题,可以先弄一个Minimal Test Case,确定错误可以重现之后,把它拿出来一起讨论,Rust中文社区的群是一个非常好的交流地点,另一个就是Rust官方IRC,那上面几乎是有求必应。
CSDN:Rust 中有哪些坑?
Elton: 简单来说,有以下这些:
CSDN:你是否有一个比较系统的Rust资料来分享给你有兴趣的开发者?
Elton: 实际上,我自己用得最多的Rust资料就是官方文档。每一周看一下http://this-week-in-rust.org,看看官方最近有什么进展,有什么让人惊喜的改进,或者是好的新项目可以使用或参与。
CSDN:Rust 如何才能吸引开发者?最能吸引哪个群体?
Elton: Rust最吸引的开发者群体相信就是C/C++开发者,同样是关注性能的系统编程,C/C++群体想要转到Rust的难度应该是最小的。而且Rust解决了C++的不少弊端。
Mike :Rust对动态语言界的吸引力如何? (Mike,唐刚,妈咪问问CEO和Rust使用者)
Elton: 动态语言普遍都带GC,而且比较少关注系统编程以及内存管理,对于Rust的强制编译期检查所有权和生存期,在学习时有可能会遇到不小的挫败感。但动态语言在项目变大之后,会变得越来越难以维护,于是近年又开始从动态类型的语言向静态类型语言迁移,比较有代表性的就是Go、HHVM,Python 3.5的Type Hints。
Mike : 那Rust和Go各自优缺点是怎样的?Rust是不是会盖过Go?
Elton: 网上对于Rust和Go到底是不是竞争者有不小的争论,我认为Rust和Go在大多数领域并不是竞争者。Go是为了方便开发高并发的服务器,而Rust的目标是系统编程,关注内存安全、并发安全等。从目前来看,很难说Rust会盖过Go,Rust没有Go那么易上手,复杂的类型系统、所有权还有生存期的概念会难住不少编程新手,但真正用熟悉之后会发现Rust用起来比Go舒服太多。Rust更多会吸引一些C/C++擅长的领域,比如游戏开发、嵌入式开发等。
Mike : Rust在游戏领域有没作为?此外,Rust在教育培训方面有没机会?
Elton: 游戏开发主要关注性能,一直都是C++的固有领土。Rust目前刚推出,性能已经接近C/C++,已经有团队在着手实现 用Rust写的游戏引擎Piston ,项目虽然还在早期,但已有不少成果。
在University of Virginia,有位教授开了一门本科的操作系统课, 使用Rust作为教学语言 ,从这个网页可以看到学生的反馈,大多数学生还是比较喜欢使用Rust作为教学语言的。
Young:讲讲trait system如何解决现有开发中的痛处? (Young,吴畏远,UESTC学生, Strikingly 数据工程师,Rust使用者。)
Elton: Trait实际上就是定义了一些方法,与Java的Interface的不同点就是,Trait可以给方法提供默认实现。这看起来并没有什么特别的,但是Trait带来了一个显而易见的好处:避免了多继承和方法命名冲突,不同的Trait可以有完全相同的方法签名,它们可以同时被同一个struct实现,例如
trait Foo { fn who(&self); } trait Bar { fn who(&self); } struct Dummy; impl Foo for Dummy { fn who(&self) { println!(“Dummy Foo”); } } impl Bar for Dummy { fn who(&self) { println!(“Dummy Bar”); } }
从上面例子可以看到,Dummy实现了Foo和Bar,而Foo和Bar有一个命名签名完全一样的方法fn who(&self),那么调用的时候可以这样
let dummy = Dummy; Foo::who(&dummy); // 调用Foo::who Bar::who(&dummy); // 调用Bar::who
这种在Rust中叫作UFCS(UniversalFunctional Call Syntax)。
配合泛型使用,Trait可以实现很多非常方便的功能。比如在Rust里面,就用Send这个类型来约束一个struct是否可以安全地传递到另一个线程,而Sync可以表示一个struct是否可以安全地在不同的线程之间共享。
另外,借助impl,可以为已有的类型实现自定义的Trait,比如
trait Foo { fn hello(&self); } impl Foo for i32 { fn hello(&self) { println!(“Hello from {}”, self); } }
于是就可以这样 1.hello() 调用,然后输出 “Hello from 1”。
随着互联网发展,开发主要目标渐渐转移到移动和web,那么Rust能否很方便的进军Android/iOS开发呢?在WebAssembly的地盘是否能从c++那分一杯羹呢?
起码在Android上,使用JNI直接调用Rust交叉编译得到的动态链接库,那是肯定没有问题的,目前也已经有人在做: https://github.com/tomaka/android-rs-glue 。
对于iOS,有人还给出了教程: https://www.bignerdranch.com/blog/building-an-ios-app-in-rust-part-1/ 。
但这些例子只说明了是可行的,但实用性如何,得真正应用到生产环境中才能知道。我个人不做客户端方面的东西,所以我就不知道了。
CSDN:我们知道国内的Rust应用情况极差,你能谈谈原因是是什么吗?国外有哪些比较好的应用案例?
Elton: 实际上,国外也不见得有什么好的案例,日前刚在IRC上看到有Dropbox的员工在问Rust相关的事情,可能是要在项目中使用。Rust的1.0在今年才出,很少会有公司愿意冒险去做第一个吃螃蟹的人。Go 1.0是2012年推出的,火也是近一两年的事情。
简而言之,Rust需要一个大公司带头做出一个成功的产品作为案例。
CSDN:Rust能站住脚么? 对 Rust 未来发展你如何看?
Elton: 对Rust语言的未来非常看好,除了因为它是业界大佬Mozilla出品,还因为它准确击中了C/C++程序员的痛点,可以完美实现底层操作的同时,在编译时实现内存管理和错误检查,程序运行性能还不错,非常接近C/C++。但Rust的生态系统还需要完善,若能有其它大公司的参与,相关的可以提高生产力的库才能够完善。
CSDN : 对于推广Rust语言有什么好的建议?
Elton: 在编程界,Talk is cheap, show me the code是不变的真理。要想推广Rust,最好的办法就是使用Rust做一些好的库或项目。就像Docker之于Go,Rust的重量级应用在哪里?Servo?
爱折腾的Elton
CSDN:你目前认为自己牛的地方在哪里?
Elton: 我不认为自己很牛,在知乎以及其它平台看到的牛人太多,我觉得自己需要学习的东西太多。我觉得我自己的一个特点就是爱动手,而且保持着对新事物的好奇心。
CSDN: 除了 Rust 是业余爱好之外,在其他方面情况是?还喜欢折腾什么?
Elton: 我还喜欢玩其它各种新的语言还有工具,比如最近站在风口上的Nim语言,还有其它Geek最喜欢玩的Linux、Vim配置,为了改一个配置坐在电脑前一整天到深夜是常有的事。空闲时还会在Github上看一些关注的人Star的项目,点进去读读源码,读到精妙的设计跟小伙伴们分享一下。
CSDN:在技术人员/程序员的工作学习中,你是否有什么好的工具?有什么心得和体会可分享?
Elton: 以下仅是个人的一点小心得:
CSDN:你认为新人在选择语言学习时应该注意什么?
Elton: 如果是一个新人想要入门,那么建议选最容易学习的语言,比如Python/Ruby,因为新手在学习的过程中,尽量地减少去关注语言本身或实现相关的细节会更容易获得成就感,也容易引起新手学习的兴趣。在入门过后,如果是想深入学习,那么建议往C/C++方向走,有利于理解程序底层实现相关的内容,之后可以考虑学习一下函数式编程语言,如Haskell/Lisp/OCaml等,可以转变思维方式,防止思维定势,推荐《七周七语言》这本书,通常学习几门小众语言,了解一下各种不同的编程范式。
但如果只是想赶紧投入到工作中,那么就简单了,工作要学哪个就哪个。
相关阅读: 专访资深程序员庄晓立:我为什么要选择Rust?
为进一步给Rust爱好者提供沟通、交流的平台,我们建立了一个微信群,你可以直接向Elton提问,此外,我们也会邀请业内的Rust大牛进群,给大家带来更多干货。
微信扫描下面的二维码即可加入:
欢迎读者举荐或自荐Rust方面的专家和相关的应用实战案例,CSDN会提供采访和相关的分享平台,和你一同探索Rust的世界。(有意请联系qianshg@csdn.net)