You are being evaluated on your Rust programming ability.
Complete all tasks below. Do not skip any task. For each task:
- Briefly explain your reasoning.
- Provide compile-ready Rust code.
- Use idiomatic Rust.
- Mention important trade-offs or limitations when relevant.
General rules:
- Prefer stable Rust.
- Use the standard library unless a task explicitly requires an external crate.
- If a task requires a crate, include the Cargo.toml dependency snippet.
- Do not give pseudo-code unless explicitly asked.
- Keep explanations concise but technically accurate.
Output format:
- Use section headers: Task 1, Task 2, etc.
- For code, use fenced Rust code blocks.
- For conceptual questions, give a structured explanation.
- If you change a broken snippet, explain exactly why it was broken.
Tasks:
Task 1 β Word frequency Write a function:
fn word_frequency(text: &str) -> std::collections::HashMap<String, usize>
Requirements:
- Count word frequencies case-insensitively.
- Split by whitespace.
- Return a HashMap<String, usize>.
Task 2 β Borrow checker debugging This code does not compile:
fn main() { let mut v = vec![1, 2, 3]; let first = &v[0]; v.push(4); println!("{}", first); }
Explain precisely why it fails and fix it with minimal changes. Then show one alternative fix.
Task 3 β Lifetimes Implement:
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str
Then explain why the lifetime annotation is needed.
Task 4 β Struct with borrowed data Define a struct:
UserView
Requirements:
- It stores a borrowed user name as &str
- It stores age as u32
- Use the correct lifetime annotation
- Show a small usage example
Task 5 β Result and custom error type Implement:
fn parse_positive_int(input: &str) -> Result<u32, ParseNumberError>
Requirements:
- Return an error if parsing fails
- Return an error if the number is zero
- Define a custom enum error type named ParseNumberError
- Explain why this is better than returning String
Task 6 β Generics and trait bounds Implement:
fn max_of_two<T: Ord>(a: T, b: T) -> T
Then explain why T: Ord is needed.
Task 7 β Enums and pattern matching Define an enum for order state with these variants:
- Created
- Paid
- Shipped
- Delivered
- Cancelled
Implement a function:
fn can_cancel(status: OrderStatus) -> bool
Explain the business logic encoded in the match.
Task 8 β Recursive enum / AST Create a simple expression AST that supports:
- integer literal
- addition
- multiplication
Implement an evaluator function that computes the result. Use a recursive enum and Box where necessary.
Task 9 β Concurrency Write a Rust program that:
- creates a shared counter
- spawns 10 threads
- each thread increments the counter 1000 times
- waits for all threads to finish
- prints the final result
Use Arc<Mutex<_>> and explain why both Arc and Mutex are needed.
Task 10 β Async Rust Using tokio, write an example that runs 3 async operations concurrently and waits for all of them.
Requirements:
- include the Cargo.toml dependency snippet
- use async/await correctly
- explain the difference between async concurrency and OS threads at a high level
Task 11 β macro_rules! Write a macro:
make_vec!
Requirements:
- it accepts any number of arguments
- it returns a Vec containing them
- show a usage example
Task 12 β Idiomatic Rust / optimization Review this function:
fn greet(name: &str) -> String { format!("Hello, {}", name.to_string()) }
Explain what is non-idiomatic or inefficient here and rewrite it more idiomatically.
Task 13 β Testing Write:
fn is_prime(n: u64) -> bool
Then add unit tests that cover:
- small primes
- small non-primes
- edge cases such as 0 and 1
Task 14 β Trait object vs generics Explain the difference between:
fn draw_all<T: Draw>(items: &[T])
and
fn draw_all(items: &[Box])
Discuss:
- static dispatch
- dynamic dispatch
- monomorphization
- when each approach is preferable
Task 15 β Architecture Design a simple TCP chat server in Rust.
Do not implement the full server. Instead provide:
- a module structure
- key data structures
- where you would use async
- where shared state is needed
- major risks or failure points
- what crates you would likely use and why
Final requirement: At the end, add a short self-review with:
- the two tasks that are most error-prone in Rust,
- the two places where unsafe Rust might appear in real systems related to these tasks,
- one example of a common beginner mistake in Rust API design.