File size: 4,522 Bytes
03f14cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
You are being evaluated on your Rust programming ability.

Complete all tasks below. Do not skip any task. For each task:
1. Briefly explain your reasoning.
2. Provide compile-ready Rust code.
3. Use idiomatic Rust.
4. 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<dyn Draw>])

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:
1. the two tasks that are most error-prone in Rust,
2. the two places where unsafe Rust might appear in real systems related to these tasks,
3. one example of a common beginner mistake in Rust API design.