0
0
Rustprogramming~20 mins

Concurrency safety guarantees in Rust - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Concurrency Safety Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Output of shared mutable state with Mutex
What is the output of this Rust program that uses a Mutex to safely increment a shared counter across threads?
Rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..5 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", *counter.lock().unwrap());
}
A5
B0
CCompilation error due to Mutex usage
DRuntime panic due to deadlock
Attempts:
2 left
💡 Hint
Think about how Mutex and Arc work together to allow safe shared mutable access.
🧠 Conceptual
intermediate
1:30remaining
Rust's Send and Sync traits purpose
Which statement best describes the purpose of Rust's Send and Sync traits in concurrency safety?
ASend allows ownership transfer between threads; Sync allows safe shared references between threads.
BSend allows multiple threads to mutate data simultaneously; Sync prevents data races by locking.
CSend and Sync traits automatically implement thread pools for concurrency.
DSend and Sync are used to serialize data for network transmission.
Attempts:
2 left
💡 Hint
Think about what it means to move or share data safely across threads.
🔧 Debug
advanced
2:00remaining
Identify the concurrency safety issue
What error will this Rust code produce when compiled or run?
Rust
use std::thread;

fn main() {
    let mut data = vec![1, 2, 3];
    let handle = thread::spawn(|| {
        data.push(4);
    });
    handle.join().unwrap();
    println!("{:?}", data);
}
ARuntime panic due to data race
BCompilation error: cannot move `data` into closure because it is borrowed
CCompilation error: closure may outlive the current function but borrows `data`
DProgram prints [1, 2, 3, 4]
Attempts:
2 left
💡 Hint
Consider how Rust handles ownership and borrowing when spawning threads.
📝 Syntax
advanced
1:30remaining
Correct syntax for atomic increment
Which option correctly increments an AtomicUsize safely in multiple threads?
Rust
use std::sync::atomic::{AtomicUsize, Ordering};

fn main() {
    let counter = AtomicUsize::new(0);
    // increment code here
    println!("{}", counter.load(Ordering::SeqCst));
}
Acounter.increment();
Bcounter += 1;
Ccounter.load(Ordering::SeqCst) += 1;
Dcounter.fetch_add(1, Ordering::SeqCst);
Attempts:
2 left
💡 Hint
Atomic types have special methods for safe mutation.
🚀 Application
expert
2:30remaining
Number of items in a concurrent HashMap after insertions
Given this Rust code using the `dashmap` crate for concurrent hashmap, how many items will be in the map after all threads finish?
Rust
use dashmap::DashMap;
use std::sync::Arc;
use std::thread;

fn main() {
    let map = Arc::new(DashMap::new());
    let mut handles = vec![];

    for i in 0..10 {
        let map = Arc::clone(&map);
        let handle = thread::spawn(move || {
            for j in 0..5 {
                map.insert(i * 5 + j, i);
            }
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", map.len());
}
A10
B50
C5
DCompilation error due to DashMap usage
Attempts:
2 left
💡 Hint
Each thread inserts 5 unique keys; there are 10 threads.