GithubHelp home page GithubHelp logo

ferrous-systems / teaching-material Goto Github PK

View Code? Open in Web Editor NEW
568.0 23.0 72.0 3.8 MB

Home Page: https://ferrous-systems.github.io/teaching-material/index.html

Ruby 0.97% Shell 2.33% Rust 93.64% C 0.85% CSS 0.21% WebAssembly 0.52% HTML 0.44% Python 0.90% JavaScript 0.15%

teaching-material's Introduction

Please see our new Ferrous Teaching Material

Our material has moved!

Our training slides now live at https://github.com/ferrous-systems/rust-training.

Our training exercises now live at https://github.com/ferrous-systems/rust-exercises.

This repository will be archived to retain any external links.


Ferrous Teaching Material

This is free workshop material produced by Ferrous Systems for trainings. Get in touch for a custom quote. The time for the full course is around three to four days.

The material is created with people with zero Rust experience but with a programming background in mind.

Ferrous Systems offers a large Rust curriculum for both beginner and advanced Rust developers.

Ferrous Systems specialises in custom, topic focused workshops for enterprises starting or expanding their use of Rust. Supplemental to our courses, we offer ongoing help and feedback.

Overview

The materials are presented as a set of small, self-contained lessons on a specific topic. Note that lessons might be revised, extended, or removed, when necessary to keep material up to date or relevant to new audiences. Lessons can be arranged into courses exploring various aspects of Rust.

Booking

See https://ferrous-systems.com/training for open courses or mail [email protected] for custom offers.

Group setup

Ferrous Systems recommends a trainer per 6 attendees for full trainer bandwidth. If possible, we recommend opting for groups of at least 12, to efficiently allow for 2 trainers.

When selecting groups for training, we recommend that participants have a similar experience level in Rust, and similar goals for using the language when possible. We are experienced with training developers from a wide range of backgrounds and experience levels, and can design a training suitable for your team.

Training material

Ferrous Systems offers our training material under MIT/Apache-2.0 license for source code (examples and exercises) and Creative Commons (CC-BY-SA) for textual content.

Custom course material developed on request, including any provided examples or exercises, will be delivered directly to you as part of the training.

Trainer staff

The Ferrous Systems training staff consists of multiple Rust project maintainers and domain experts, active in multiple working groups. This makes sure our trainers are always up to speed on new developments and can give current and authoritive answers.

Among those are:

  • Florian Gilcher: Training Rust since 2015. Over 30 trainings, most for large enterprises. Rust core team member and community team manager. Broad knowledge about all aspects of Rust, with special knowledge on network and async/concurrent programming.

  • Jonathan Pallant: Training Rust since 2018. Focus on Rust for Beginners, and Embedded Rust. Member of the Rust Embedded Working Group. Rust 'firsts' include running code on the nRF9160, TM4C123 and RP2040 MCUs.

  • Jonas Schievek: Training Rust since 2019. Focus on general Rust and multiple architectures. Contributor to the Rust compiler. Great knowledge of compilation details and performance concerns.

  • Tanks Transfeld: Training Rust since 2018. Focus on general Rust and Rust for beginners. Part of several Rust learning projects. All Rust subjects, from async to bare metal. Great knowledge around beginners concerns and how to get started.

Ferrous Systems can also collaborate with local trainers in Europe, US, Canada, South America, South Africa, and Oceania.

Courses

Tailoring

Ferrous Systems offers courses in many different settings.

Courses will be tailored to the clients needs during an interview before the event. This interview should happen as early as possible.

Specifically courses for companies in a transformation towards using Rust will be tailored to the companies core subjects.

The "three days" core

Ferrous Systems builds its core course around a base course of three days. This course consists of introduction into shared Rust subjects plus application in one domain. Three days gives enough time to focus on this domain for at least one day, plus enough time to answer questions coming up from the audience.

After a three days course, attendees will have a solid knowledge in Rusts core concepts, especially Ownership and Borrowing. They will also have the core skills necessary for efficient self-guided learning.

Variations

Variations of the course, such as a shorter or a longer version are available.

"Three days" overview

A course that focuses more on an ecosystem overview over a detailed core subject. It may cover up to 4 topics.

Attendees may not become productive in all areas, but get a good feeling for them.

This course is perfect for engineering management that will most likely not end up using Rust daily, but needs broad knowledge to assess Rust as a technology. It is also frequently given in academic settings.

5 days

The longer versions covers similar subjects as above, but in more detail. This allows for exercises such as the construction of a larger piece of software in the training group collaboratively.

These courses are recommended for people that are intended to be multipliers in your organisation, teaching or leading other teams using Rust.

After 5 days, attendees will have solid knowledge in a topical domain and full productivity.

2 days

A condensed version of the three days course. Detailed topic deep dives will be reduced and some self-guided exercises reduced to "code along" sessions.

2,4 and 8 hours topic tasters

Taster sessions that favor experiences over solid knowledge and get people excited.

Perfect for conferences and internal all-hands to expand people’s horizons.

Advanced courses

Advanced courses deepen a Rust subject and are indended for groups that have already attended a course previously. They quickly refresh core knowledge and then add a specific deep dive on topic. Advanced courses also differ from base courses in that they include a number facilitated discussions for attendees to share their experience.

Advanced courses are tailored like base courses to the need of the group. For example, an basic course for for asynchronous programming explains how concurrent execution in Rust works, while the advanced one may include writing your own execution engine.

Topics

Ferrous Systems offers Rust courses for a wide variety of subjects. The following is a non-exhaustive list of subjects.

Every subject with be taught with hands-on exercises.

Core topics

This is the core component of the course. In this course, attendees will learn:

  • Ownership

  • Borrowing

  • Lifetimes

  • Working with memory and data structures

  • Control flow

  • Structuring of applications

  • Using and configuring cargo and rustup

  • Introducing Rust into existing products

  • General Rust patterns

  • Error Handling

  • Using Generic APIs

  • Using Rust’s guarantees as foundation for secure programming

  • Testing and Debugging

  • Documentation tooling

  • Basics of concurrency safety

  • Overview of important documentation

  • Overview the standard library, especially core interface like collections, input/output and networking

  • Overview of common libraries

  • "Refactoring towards Speed" a core technique to safely derive a fast program from a working program

Exercises will be tailored to the chosen special subjects.

Advanced Generic Programming in Rust

Although the use of generics is taught in the core course, this section instead focuses on how, and when, to use them effectively. For developers of widely used libraries (internal or public), this material is particularly important.

In this module, attendees will learn:

  • Introduction into advanced programming with generics in Rust

  • Writing generic APIs

  • Impact on compile time, size and runtime speed

  • Useful generics patterns

  • Patterns to avoid

Rust in C/C++ Environments

Rust is often deployed in existing products, especially within or among solutions written in C/C. This module explains binding efficiently from C/C to Rust and from Rust to C/C++ codebases.

In this module, attendees will learn:

  • Rusts FFI (Foreign Function Interface)

  • unsafe, as needed for FFI

  • Safe binding, both manually and automatically

  • Binding strategies

  • Working with raw pointers and helping pointers

  • Costs of boundary crossing

  • Assessment of feasibility

Unsafe Rust

Rusts unsafe feature is sometimes necessary for speed optimisations or implementation of special data structures. This module explains its position and use in the language.

In this module, attendees will learn:

  • The role of unsafe

  • The scope of unsafe

  • Do’s and Don’ts of unsafe Rust

  • Introduction into support APIs, like non-null pointers

  • Potential undefined behaviour arising from the use of unsafe

  • Checking unsafe Rust for safety

Rust Testing

This module teaches advanced Rust testing techniques.

In this module, attendees will learn:

  • Fuzzing of Rust applications

  • Using property based testing

  • Rust in continous integration

  • Documentation testing

Rust for Application Development

This module is meant for developers that mostly produce application layer code and work less on libraries. It focuses less on line-by-line details, but on system construction and usage of foreign code.

In this module, attendees will learn:

  • Useful libraries for many common usecases

  • How to evaluate a library

  • Componentising Rust projects

  • Error handling at large

  • Logging and tracing

Binary Size Optimisation

This module is meant for developers working on systems with constraints on program size, such as switches or IoT gateways. It explains techniques to keep the binary size of Rust applications small.

In this module, attendees will learn:

  • Compiler options to optimise for size over aggressive optimisation

  • Programming techniques for smaller programs

  • Tools to further reduce the size of resulting binaries

Rust Speed Optimisation

This module is meant for developers working on systems with high speed demands. It explains techniques to test for performance and optimise for speed.

In this module, attendees will learn:

  • Tools to analyse speed and memory consumption

  • Programming techniques for faster programs

  • "Refactoring towards Speed": futher deepening for optimising working code bases

  • Optimising programs for specific resource usage needs

Rust for Networking

This module is meant for developers working on the networking layer. It combines well with the "Asynchronous and Concurrent Rust" module.

In this module, attendees will learn:

  • Rusts concurrency safety features

  • The Futures model

  • Rust async/.await programming

  • Available libraries and frameworks

  • Specifics of Rusts I/O libraries

Asynchronous and Concurrent Rust

This module is meant for developers interested in building highly concurrent systems. It combines well with the "Rust for Networking" module.

In this module, attendees will learn:

  • Rust threads vs. asynchronous tasks

  • Communication and sharing between concurrent units of a program

  • Effective memory safety features in concurrent applications

  • Available libraries and frameworks

Cross Compilation

This module is meant for developers targeting many different architectures.

In this module, attendees will learn:

  • Rust’s cross-compile toolchain

  • Dealing with target differences

  • Keeping programs portable

  • Configuring targets in cargo

  • (optional) Defining your own custom targets

  • (optional) cross-compiling mixed codebases

The optional targets are taught on client need.

Embedded Rust

This module is meant for developers interested in building bare metal systems such as microcontrollers. It includes the "Cross-Compilation" module, as far as it applies to microcontrollers.

In this module, attendees will learn:

  • Cross-compilation of Rust to embedded devices

  • Programming Rust without a standard library

  • Target specific libraries for microcontrollers

  • Rust embedded hardware abstraction layer ("embedded HAL")

  • Libraries for use in heapless environments

  • Managing memory mapped devices

Embedded Rust using RTIC

This module is similar to "Embedded Rust", but uses the RTIC concurrency framework for teaching (previously known as "Real Time For The Masses").

Writing Drivers for Embedded Rust

This module extends the "Embedded Rust" or "Embedded Rust using RTIC" module.

In this module, attendees will learn:

  • How to build a driver

  • Proper modularisation

  • Testing

Productive coding in Rust

This module further teaches Rust working techniques, also with the support of IDEs.

In this module, attendees will learn:

  • Setting up rust-analyzer or CLion to their needs

  • General development workflows

    • Draft coding

    • Going from draft to stable software

    • "Refactoring towards speed"

  • Fast testing

  • Tools for reactive development workflows (such as cargo watch)

Rust and WebAssembly (WASM)

WebAssembly (WASM) is a intermediate language optimised for fast evaluation in secure sandboxes. This module focuses on understanding the role of WebAssembly and its usage. It is taught on a platform relevant to the group.

In this module, attendees will learn:

  • What WASM is and what to use it for

  • Security properties of WASM and WASI

  • Common WASM implementations

  • Binding between a host language (usually JavaScript) and WASM

Credits

The development of this course is financed by Ferrous Systems.

They are open sourced as a contribution to the growth of the Rust language.

If you want to fund further development of the course, book a training!

Commercial use

This course is expressively intended for commercial and free use.

License

teaching-material's People

Contributors

amanjeev avatar andy-thomason avatar aplanas avatar darnuria avatar follower avatar jakeburden avatar jonas-schievink avatar jonathanpallant avatar justahero avatar lislis avatar listochkin avatar lotterleben avatar matklad avatar miguelraz avatar mirabellensaft avatar pietroalbini avatar skade avatar sophiajt avatar spookyvision avatar staszewski avatar turbo87 avatar xylakant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

teaching-material's Issues

add assignment for converting errors with `From<T>` and `Into<T>`

and using the ? to get the neat UX

cc @listochkin , who we were talking about this

  • buildup to the thiserror crate usage:
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
    #[error("Not enough operands")]
    NotEnoughOperands,
    #[error("Not a number {0}")]
    NotANumber(String),
}

#[derive(Debug, thiserror::Error)]
pub enum CalcError {
    #[error("{0}")]
    ParseError(#[from] ParseError),
    #[error("{0}")]
    EvalError(#[from] EvalError),
}
  • show the IDE "expand macro recursively" and "implement all fields"

basic types: add slide about `vec!`

the array slices mentioned on the last slide of basic-types are dynamic-but-not-quite: they still can't be resized? which caused some confusion. it'd be nice to have a slide after that briefly introducing vec![] as well, especially siince it's used in subsequent slides (and I think never really introduced?)

Fix control flow examples

The last two examples of the control flow slides are bugged.

  • Use correct code example in "return" slide
  • Use working code example in "?" slide

small fixes to slides

Writing this down so I don't forget over the long weekend:

  • stuct typo in Standard Types slide
  • typo with <> in Deref slides
  • [\T\] typo in Deref

Edit:
Moved more hefty slide content revamp to other issue.

Slides for arc, mutex and simple example?

I was looking for slides to introduce Arc and Mutex (maybe with comparisons to Rc and Cell or similar) and use them together with the slides on Send and Sync to talk about threading.
Or do they exist and are just not linked on the overview?

Visual cheet sheet and scaffolding/spiral curriculum

In feedback discussions with @amanjeev and @Mirabellensaft , I mentioned a visual cheat sheet that "grew" as more of the training material was covered would be very useful.
One of the biggest benefits that this can bring is to have a visual aid for teaching habits of the Ownership System.

Example:

A very useful mental model for how the Ownership system works is to know the difference between

foo(x)
foo(&x)
foo(&mut x)

I claim that a lot of material in our slides can be scaffolded (aka accommodate the spiral curriculum) with this method.
We already have slides that draw parallels like

foo(x) :: String : foo(&x) :: &str

but what I commit to by opening this issue is to building a visual aid that can help people build useful habits for how to explain the consequence of the Ownership variants.

Concretely, I want to have mini examples like the following 3 cases:

fn main() {
    let x = ...;
    foo(x); // `x` is consumed from now on!
    //  |
    //  |
    //  | No one can use `x` here
    //  |
    //  |
    // v
}

and say something along the lines of

Simple Ownership Rules trick # 1:
If you see `foo(x)`, `x` can't be used again because it was consumed, aka "look down".
If it is, that shouldn't compile
fn main() {
    let x = ...;
    {
        foo(&x); // `x` is immutably ref'd from now on!
    //  |
    //  |
    //  | Only `&x` can be used in this scope!
    //  |
        quz(&x);
    //  |
    // v
    }
    // `x` no longer has a ref, it can be consumed now
    baz(x); 
}

with

Simple Ownership Rules trick # 2:
If you see `foo(&x)`, only `&x` can be used in the same scope, aka "look side to side".
If it overlaps regions with any `&mut x`, that will not compile.

I'm not espousing these metaphors directly, but more so the idea of teaching the mental checking habit of how people can look at "complex" ownership worfklows with a few mental heuristics and have a good intuition for if it's correct or not.

I welcome feedback.

slides revamp / revision

  • Add spoiler boilerplate to Redisish assignment with solutions, like in Durable File/RustLatin
  • TCP echo server should have a solution at the end using nc localhost 8080
  • Lifetime elision snippets to build up intuition that Andrei mentioned
  • Add unsafe -> safe API build with Vec example (or atomics? Linked lists?)
  • add learning goal of enabling features of imported libraries (clap in Fizzbuzz CLI and borrowed data in serde)

add typestates assignment

Rework cool example from the RfR book by

  • Task 1:starting with a toy example like
struct Grounded;
struct Launched;
// and so on
struct Rocket<Stage = Grounded> {
    stage: std::marker::PhantomData<Stage>,
}
impl Default for Rocket<Grounded> {}
    impl Rocket<Grounded> {
    pub fn launch(self) -> Rocket<Launched> { }
}
impl Rocket<Launched> {
    pub fn accelerate(&mut self) { }
    pub fn decelerate(&mut self) { }
}
impl<Stage> Rocket<Stage> {
    pub fn color(&self) -> Color { }
    pub fn weight(&self) -> Kilograms { }
}

add `if let` illustration to slides?

As a visual person, I struggled a while to understand what goes where in if lets (and still struggle to explain it without a whiteboard :D)

During my Rust learning process, I ended up with this illustration:

83023112-c73eac80-a02c-11ea-9203-c657c38a04e1-2

I keep wondering whether we should add a cleaned-up version of this to our Control Flow slides

add slides about documentation?

This was requested in today's training.
they could cover (briefly!):

  • /// vs. //!
  • hint: you can use markdown in your comments
  • running cargo doc and looking at the generated html
    • how to navigate the created docs: side bar on the left; expanding function docs
    • caution: library docs only cover public members
    • hint: cargo doc will also generate the docs for my project's entire dependency tree
  • cross-documentation links
  • ✨doctests✨
    • 💡 this can be segwayed into by showing off ```rust formatted example code first; then run cargo test and tadaaaaah
    • -> effect: our examples can't accidentally fall out sync! and they're 2-in-1 unit tests
  • maybe add a link to https://doc.rust-lang.org/beta/rust-by-example/meta/doc.html and tell people to pay attention to the extra sources at the bottom
  • mdbooks
    • The Rust Book
    • mention: when Rustaceans refer to a book, they mean a mdbook
    • bigger libraries will publish books for conceptual explanation (like the embedded book, the async book, the rtic book...)

assigning @jamesmunns because he was giving the training and mentioned he'd like slides – not sure who's available to write these at the moment

Simple chat exercise doesn't isn't compatible with async-std 1.9.0

I've just tried to build the template linked from the simple-chat assignment and it fails with the following:

error[E0432]: unresolved import `async_std::sync::channel`
 --> src/main.rs:9:5
  |
9 | use async_std::sync::channel;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^ no `channel` in `sync`

error[E0432]: unresolved imports `async_std::sync::Sender`, `async_std::sync::Receiver`
  --> src/main.rs:10:23
   |
10 | use async_std::sync::{Sender,Receiver};
   |                       ^^^^^^ ^^^^^^^^ no `Receiver` in `sync`
   |                       |
   |                       no `Sender` in `sync

Updating 1) the imports to use what I understand to be the correct structs/traits (still working through the example) and 2) the channel creation resolves the initial errors (see below)

use async_std::channel::{bounded, Sender, Receiver};
...
let (broker_sender, broker_receiver): (Sender<ClientEvent>, Receiver<ClientEvent>) = bounded(10);

but results in

error[E0308]: mismatched types
  --> src/main.rs:34:21
   |
34 |                     c.sender.send(format!("{}: {}\n", sender_name, msg)).await 
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found enum `std::result::Result`
   |
   = note: expected unit type `()`
                   found enum `std::result::Result<(), async_std::channel::SendError<String>>`

It looks like this template needs to be updated for the latest async-std version or pinned to a specific version rather than what is currently in the Cargo.toml which is async-std = { version = "1", features = ["unstable"] }. I'm not sure when I'll get through the example but I'm happy to open a PR if this isn't resolved by the time I've got around to completing this.

Change default branch from master to main

The use or master in Git is considered harmful and as such we should try to move away from it.

@pietroalbini I am assigning this to you mostly because I want to know if you have any issues with this, deployment an dependency wise. If not, then please assign this to me and I will change this.

Option and Result

I think we should mention Option<T> and Result<T, E> on the Compound Types deck, even if it means mentioning generics briefly. Especially as they come up in the Control Flow page, but without much of an introduction.

Mark copyright/licenses

(At least for code but ideally for everything) As an open source consultancy we're well attuned to the requirements of licenses. It would be good if you could mark at least the example code with copyright and license data (SPDX-License-Identifier preferred). I recommend the https://reuse.software standard, because it's straightforward and comes with a nice tool you can even have in ci, reuse lint

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.