0%

背景

作为一名非计算机相关专业的学生,我写过的代码并不多,编程语言也仅了解C/C++,Python。参加这个训练营是因为有读研转码的想法,希望提前积攒些项目经验。浏览完该训练营的大致内容后觉得对于Rust零基础操作系统零基础的我来说算是蛮困难的一个挑战,希望自己能坚持到最后。

语言神,启动!

第一阶段总结

从4月6号开始学习Rust,到4月22号完成Rustlings共计17天大致学习了Rust的一些语法和特点。学习过程中最大的感受就是安全,安全,还是安全,相比于C/C++,Rust施加了太多的限制以保证安全,初次学习比较难以适应,但好在编译器的提示功能非常强大,帮助我解决了很多困难。目前个人觉得Rust中最难的部分就在生命周期,学起来非常打脑壳。

我主要通过读《Programming Rust,Second Edition》这本书来学习,主要学习了Rustlings涉及到的基本数据类型,所有权与移动,引用,表达式,错误处理,Crate与模块,结构体,枚举与模式等章节,而并发,异步编程这些章节暂时还未涉足。

完成Rustlings的过程中,前100题有编译器的帮忙都还较顺利,后10题涉及到数据结构与算法我还得先去学学前置知识,再加上整体也比前面复杂了不少,最后也是花了好几天才完成。

总之第一阶段算是坚持了下来,收获也蛮大的,希望第二阶段再接再厉。

Rust学习感悟

整体来讲,学习Rust的语法和性质是一个较为享受的过程。对于一个长期编写C++程序的人而言,在运行时出现内存泄漏、多线程死锁的问题并调试是十分棘手的,为了保证写出健壮的程序,程序员通常会有很大的心智负担,而Rust语法从编译层面就很大程度上保障了安全性,使通过编译的程序能在运行时也不出岔子的可能性大大增加。此外,Rust拥有很好的文档帮助新手入门,拥有完善的工具链,能够胜任各方面的开发。Rust的编译器十分强大,能够在所有权,生命周期等方面及早扼杀bug。

exercise 心路历程

我更倾向于在练习中学习语法,所以我在简单阅读了Rust圣经后,就开始进行rustlings的exercise了。基本上每个题,在查阅了相应语法后,都能顺利解决。最后10道编程题,考察了一些基础数据结构在Rust语言上的实现,由于对数据结构本身比较熟练,所以这些算法题更是考察对Rust语言本身的理解。

总结

rustlings是个很好的Rust学习项目,很适合rCore Lab入门Rust使用。Rustlings的练习顺利完成了,希望后期也能继续跟进。

在参与了2024年春夏季开源操作系统训练营的第一阶段后,我对Rust语言和操作系统的基础知识有了更深入的理解和实践。以下是我在这一阶段学习中的一些关键点和遇到的挑战。

Rust语法

所有权和生命周期

  • 所有权系统:Rust的所有权系统是其最核心的特性之一。它通过编译时的严格检查,确保了内存安全,避免了内存泄漏和悬挂指针的问题。所有权的转移和借用机制,让我对资源管理有了全新的认识。
  • 生命周期标注:生命周期的概念在Rust中至关重要,它帮助编译器理解引用的生命周期。在实际编程中,合理地标注生命周期对于避免悬垂引用非常关键。

语法问题

  • 在处理Option类型时,我曾错误地尝试解引用一个None值,这在Rust中是不允许的,因为它会导致运行时的panic

以下是我在 Rust 中编写的一个简单示例,演示了如何使用 Rust 进行错误处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fn main() {
let result: Result<i32, &str> = divide(10, 0);
match result {
Ok(value) => println!("Result: {}", value),
Err(err_msg) => println!("Error: {}", err_msg),
}
}

fn divide(x: i32, y: i32) -> Result<i32, &str> {
if y == 0 {
Err("Cannot divide by zero")
} else {
Ok(x / y)
}
}

我定义了一个 divide 函数来执行整数的除法运算,并返回一个 Result 类型,表示运算结果或错误信息。在 main 函数中,我们调用 divide 函数并使用 match 表达式来处理返回的结果,打印出相应的信息。


这学期学操作系统让我发现了蒋炎岩老师的操作系统,又偶然了解到这次的OS训练营,又是rust,刚好就报名参加,第一阶段学习了rust,让我收获颇多,希望在第二阶段能学到更多的知识(希望能完成)。

​ 一转眼110道题目已经结束,100道语法练习和10道算法题下来让我受益匪浅。对于此前只有一些c语言和python语言基础的我来说,难度比较大,很多概念还是理解不清楚,算法也是临时学的,可谓非常艰难。不过对rust的学习对我的编程思维很有启发,也是我第一次直接接触到并发和所有权的概念。

​ 此前编程单纯考虑能跑就行,但实际上是不够的,作为信息安全专业的人这几年写代码从不考虑安全实在是惭愧,所幸在学生时期接触到了rust,不至于在未来项目出现一些令人痛苦的问题后惊觉对底层知识的忽视。随着学习的深入,越发理解底层知识对编程的重要性,当然这也是我参加2024oscamp的原因。不罗嗦了,那么作为简单的记录,先总结一下吧!

:Rust 中有两种字符串类型:String&str

String 被存储为由字节组成的 vector(Vec<u8>),是一个有效的 UTF-8 序列。String 是堆分配的,可增长的,且不是零结尾的。&str 是一个总是指向有效 UTF-8 序列的切片(&[u8]),并可用来查看 String 的内容,就如同 &[T]Vec<T> 的全部或部分引用。

自定义的错误特征,错误之间很可能会存在上下级关系,例如标准库中的 std::io::Errorstd::error::Error,前者是 IO 相关的错误结构体,后者是一个最最通用的标准错误特征,同时前者实现了后者,因此 std::io::Error 可以转换为 std:error::Error

在存在多个引用时,编译器有时会无法自动推导生命周期,此时就需要我们手动去标注,通过为参数标注合适的生命周期来帮助编译器进行借用检查的分析。

生命周期标注并不会改变任何引用的实际作用域

标记的生命周期只是为了取悦编译器,让编译器不要难为我们

​ ——RUST语言圣经

生命周期注释有一个特别的:‘static 。所有用双引号包括的字符串常量所代表的精确数据类型都是 &’static str ,’static 所表示的生命周期从程序运行开始到程序运行结束。

map 方法是一个迭代者适配器,它最大的好处不仅在于可以就地实现迭代器中元素的处理,还在于可以捕获环境值。它是惰性的,不产生任何行为,因此我们还需要一个消费者适配器进行收尾:

消费者适配器是消费掉迭代器,然后返回一个值。那么迭代器适配器,顾名思义,会返回一个新的迭代器,这是实现链式方法调用的关键:v.iter().map().filter()...

filter() 的闭包需要用一个引用,并且许多迭代器迭代引用,所以这可能导致混乱的情况,其中闭包的类型是双引用:通常在参数上使用解构来去掉一个

1
2
let mut iter = a.iter().filter(|x| **x > 1);
let mut iter = a.iter().filter(|&x| *x > 1);

flat_map()

map 适配器非常有用,但仅当闭包参数产生值时才使用。 如果它产生一个迭代器,则存在一个额外的间接层。 flat_map() 将自行删除这个额外的层。

特性(trait)概念接近于 Java 中的接口(Interface),但两者不完全相同。特性与接口相同的地方在于它们都是一种行为规范,可以用于标识哪些类有哪些方法。

特性在 Rust 中用 trait 表示:

格式是:

1
impl <特性名> for <所实现的类型名>

Rust 同一个类可以实现多个特性,每个 impl 块只能实现一个。

  • Box<T>,可以将值分配到堆上

  • Rc<T>,引用计数类型,允许多所有权存在

  • Ref<T>RefMut<T>,允许将借用规则检查从编译期移动到运行期进行.写链表的时候再回忆一下……

  • AsRef 是一个 trait(特质),用于将一个类型转换为另一种类型的引用。

  • AsRef 的作用是允许我们以统一的方式处理不同类型之间的转换。通过实现 AsRef trait,我们可以定义一个类型转换函数,该函数将一个类型转换为另一个类型的引用。

  • 如果我们有一个类型 T,并且希望将其转换为类型 U 的引用,我们可以实现 AsRef <U> trait 来完成这个转换。在实现中,我们需要提供一个名为 as_ref 的方法,该方法返回类型 &U。这样,我们就可以使用 as_ref 方法来将 T 转换为 U 的引用。

fn num_sq<T: AsMut>(arg: &mut T)

AsMut< >可变引用。其他同上

Rust 宏(Macros)是一种在编译时生成代码的强大工具,它允许你在编写代码时创建自定义语法扩展。

1
2
3
4
5
6
7
macro_rules! my_macro {
// 模式匹配和展开
($arg:expr) => {
// 生成的代码
// 使用 $arg 来代替匹配到的表达式
};
}

还有很多没写,笔记记在其他地方了,不过太零散了,有空整理一下。

一、引言

本人参加2024春夏季开源操作系统训练营,主要基于对Rust编程语言的浓厚兴趣以及从事操作系统相关工作的背景。训练营的第一阶段聚焦Rust语言学习、习题实践以及算法研究,旨在深化对Rust与操作系统的理解,提升实际工作能力。经过这一阶段的学习,我收获颇丰,现对本次学习进行总结。

二、Rust语言深度探索

Rust以其内存安全性和高性能特性在操作系统开发领域受到广泛关注。在本阶段,我深入学习了Rust的核心概念,如所有权、借用检查器和生命周期管理等。这些特性确保了代码的安全性和可靠性,尤其在并发和内存管理方面表现优异。

通过编写简单的Rust程序,我逐渐掌握了语言的特性和风格。同时,我也浏览了Rust的标准库和生态系统,了解了其在并发编程、网络编程和系统级编程等方面的优势。

三、习题实践

为了巩固所学知识,我积极完成了训练营提供的Rust习题。这些习题涉及从基础语法到高级特性的各个方面,通过实践编程,我加深了对Rust语言的理解,并提高了编程技能。

四、算法

算法是操作系统设计中的关键部分,但是由于时间问题,我最后10个algorithms点到即止,后续在深入研究其思想。

五、Rust与操作系统的结合理解

通过本阶段的学习和实践,我深刻体会到了Rust在操作系统开发中的优势。Rust的内存安全性和并发性能使得它成为构建高效、稳定操作系统的理想选择。同时,Rust的丰富生态系统和活跃的社区也为开发者提供了强大的支持。

我也意识到,将Rust与操作系统知识相结合,不仅可以提升代码的质量和性能,还可以拓展操作系统的功能和特性。因此,在未来的学习和工作中,我将继续深化对Rust和操作系统的理解,探索更多结合两者的可能性。

六、总结与展望

本次训练营的第一阶段学习让我对Rust编程语言和有了更深入的理解。展望未来,我将继续深入学习Rust的高级特性和生态系统,探索更多与操作系统相关的应用场景。同时,我也将积极参与开源社区的建设,与同行交流学习,共同推动Rust在操作系统领域的发展。

最后,我要感谢训练营的组织者和导师们的辛勤付出和悉心指导。在未来的学习和实践中,我将继续努力,不断提升自己,为Rust和操作系统的结合做出更大的贡献。

总结

之前对rust有过了解和使用,所以做 rustlings 题目时主要以复习巩固为主,对之前没掌握好的细节再次通过文档等学了一遍,例如一些编译属性等等。最后10道算法题也比较考验对rust的理解,尽量控制unsafe的使用范围是其中挑战的地方。

同时翻看了一些risc-v的文档,单看文档理解不深,配合rCore-Tutorial-Book看效果更好一些

第一阶段的任务只是开胃小菜,希望后面第二阶段继续努力,全程follow完成所有的任务。

关于

首先非常感谢清华大学提供的平台,让我能够有机会参与到这么了不起的课程中。作为一个非科班的程序员,其实一直很想好好学习一下操作系统和编程原理这些底层的知识,好让自己的基础更加牢固。但由于各种原因,尝试多次都未能坚持下来,都是找几本书走马观花地看看,浅尝辄止。那天无意中在某个微信群看到有个朋友发的这个课程的推广链接,点进去了解了一下后毫不犹豫地报了名,因为既可以学习Rust,又可以学习操作系统。

其实在很早之前就对Rust和Go这两名现代化语言有所了解,也都初步学习过。但是由于Rust的语法较为复杂,上手困难,并没有在实际工作中使用。因此简单学习后就因为没有实践的机会而忘了个七七八八。

Rust

借着这次机会,又好好复习了一下Rust的基础知识。花了点时间仔细阅读了The Book和The Rustonomicon。这两本书确实是值得仔细阅读的,以后还得多读几遍。

关于Rust备受推崇的原因有个就是他的所有权机制和编译前解决大部分内存安全问题吧。其实C++的智能指针支持这种操作,因为日常会使用到C++,因此理解这部分概念的时候并没有遇到太大的困难。有一段时间一度怀疑过Rust是不是有点过于被吹捧了,因为相比于同样现代化、简单且高效的Go,Rust对初学者实在是太不友好了。

知道最近时间看到一些报道说Google使用了Rust替换C++之后,效率提高了两倍不止;而且Cloudflare也开源了他们的Pingorg,作为Nginx的代替。看来确实得好好学习一下这门语言了。

很喜欢Rust的一点是使用Trait实现面向对象的功能吧,相比于C++的Class,这样更简洁,也好理解。

不过接受不了的一点是学了之后才发现用Rust实现一个双向链表都如此费劲。因为日常使用C开发,最常用到的数据结构就是这个了。本来想这两天好好研究一下有没有好的双向链表的实现,看来Rust std里的实现,居然也使用了unsafe,觉得有点不够优雅。好吧,由于今天是提交总结的最后一天了,我还没想好好的实现,只好先草草地提交一个总结了。

最后

感觉其他同学真的很热情,第一阶段刚开始一天就把100题做完了,作为一个毕业五六年的人,不得不佩服。
立个Flag,希望自己下次不要提交的这么晚了。

1. 引言

本人参加2024春夏季开源操作系统训练营,主要基于对Rust编程语言的浓厚兴趣以及从事操作系统相关工作的背景。训练营的第一阶段聚焦Rust语言学习、习题实践以及算法研究,旨在深化对Rust与操作系统的理解,提升实际工作能力。经过这一阶段的学习,我收获颇丰,现对本次学习进行总结。

2. Rust语言的学习:

  1. 通过对 训练营中的 rust资源学习 比如 带有测验的文档 对rust语言的设计 拥有更深入的理解, 明白 rust语法以及规则上的设计道理,而非仅仅通过编译器的编译。
  2. 通过 项目的事件项目 rcore的rustling 对 rust语法规则更加熟练的掌握, 对于 unsafe 以及FFI 的使用有一定的掌握。
  3. 通过 训练营 中 徐老师的 直播视频讲解,对 rust 的生态,以及 Future,类型 变换(协变、逆变、不变) 以及一些其他的 冷门 rust知识 有更深入的理解。(感谢老师的付出

3. 总结与展望

总体来讲, 这些天的rust项目实践带来了不少的收获。本人自身对于OS也比较好奇和一定的知识储备, 希望能够在接下来的课程中通过rcore的项目实践,能够带来 更多对于rust以及OS的 深入理解。

第一阶段总结报告

我大概在一年前知道了开源操作系统训练营,但是因为种种原因没有参加。在今年4月的时候我看到2024春训练营,正好有时间就赶紧报名上车了。

学到的东西

虽然我学习过rust,但是在做rustlings时我还是学到很多东西。

  • Rust Docs
    这次解题的时候因为很多东西都需要自己去了解,这个时候我们就需要去看看相关rust文档,尤其是test7和test8中的那个build.rs。
  • Iterator
    rust的迭代器实在太强了,过去只是简单用一下。在这次rustling的拷打下,我边做题边翻rust的Iterator文档,学到了很多新的Method,多个Method组合在一起解题太舒服了。
  • Heap
    因为我本科没学过数据结构,所以做到第109题的时候发现自己竟然连堆这个数据结构都不知道,然后赶紧去学习Heap。
  • FFI
    我被test9这道题给卡了很久,看文档也不懂,一直对提示的2个attribute的用法不太明白,最后看了一篇关于这个问题的rust社区讨论才明白。
  • Codespace
    最开始我只是想要在上水课的时候用平板做一下题,然后就选择体验一下codespace。我使用了一下后发现体验还不错,就选择在codespace上做完了rustlings,这篇blog也是在codespace上写的。
  • Match Ref Mut
    我在做一道题的题的时候遇到了模式匹配的可变引用问题,被它卡了很久,最后看了下rust blogrust by example和编译器的帮助下解决了它。

总结

第一阶段学到了不少东西,希望自己后面能挺过第二阶段。顺便吐槽一下,后面10道算法题的测试用例有点弱和少,希望后面可以加强一下。

一阶段总结

没有太多可说,rustlings 中规中矩,最后新增的十道算法题有一种复古的感觉。期待二阶段的内容。

想法 rustlings, kotlin koans and others

类似这样的一连串渐进的练习组成的交互式教程,感觉没有直接看书那么有意思,有时甚至都懒得看代码就改完了。
速成也没有 learn x in y minutes 快。也许比较交互,减少代码恶意 :P

想法 stage-2: rcore os lab

提高 OS & RISC-V 知识水平。