A stack is a collection where elements are added and removed only from the top, following Last In First Out (LIFO) order.
Click to reveal answer
beginner
Why not use arrays directly instead of a stack abstraction?
Using arrays directly can lead to errors like accessing wrong indexes or forgetting to follow LIFO rules. Stack abstraction hides these details and provides safe, clear operations.
Click to reveal answer
beginner
Name two main operations provided by a stack abstraction.
Push (add an element to the top) and Pop (remove the top element).
Click to reveal answer
intermediate
How does stack abstraction improve code safety compared to direct array use?
It prevents invalid operations like popping from an empty stack or pushing beyond capacity by controlling access through defined methods.
Click to reveal answer
intermediate
In Rust, what feature helps enforce stack abstraction safety?
Rust's ownership and borrowing rules help prevent bugs by ensuring safe access and modification of stack data through methods.
Click to reveal answer
What order does a stack follow when adding and removing elements?
ARandom Order
BFirst In First Out (FIFO)
CLast In First Out (LIFO)
DSorted Order
✗ Incorrect
Stacks follow LIFO order, meaning the last element added is the first to be removed.
Which operation removes the top element from a stack?
AInsert
BPush
CPeek
DPop
✗ Incorrect
Pop removes the top element from the stack.
Why is using a stack abstraction better than using an array directly?
AIt uses less memory
BIt hides complexity and prevents errors
CIt sorts elements automatically
DIt allows random access
✗ Incorrect
Stack abstraction hides details and enforces correct usage, reducing errors.
What happens if you try to pop from an empty stack using a proper stack abstraction?
AIt returns an error or None
BIt crashes the program
CIt returns a random value
DIt adds a new element
✗ Incorrect
A stack abstraction safely handles empty stack pops by returning an error or None.
In Rust, what helps ensure safe stack operations?
AOwnership and borrowing rules
BGarbage collection
CManual memory management
DGlobal variables
✗ Incorrect
Rust's ownership and borrowing rules enforce safe access and modification.
Explain why stack abstraction is needed instead of using arrays directly.
Think about how arrays can be misused and how stack methods help.
You got /4 concepts.
Describe the main operations of a stack and how they differ from array operations.
Focus on how stack limits access compared to arrays.
You got /4 concepts.
Practice
(1/5)
1. Why do we prefer using a stack abstraction over directly using an array for stack operations?
easy
A. Because stack abstraction hides internal details and enforces correct usage
B. Because arrays are slower than stacks in all cases
C. Because arrays cannot store multiple data types
D. Because stack abstraction uses less memory than arrays
Solution
Step 1: Understand array direct use limitations
Using arrays directly exposes internal details like indices and size, which can lead to incorrect usage such as accessing invalid positions.
Step 2: Benefits of stack abstraction
Stack abstraction provides controlled access through push/pop methods, hiding internal details and preventing misuse.
Final Answer:
Because stack abstraction hides internal details and enforces correct usage -> Option A
2. Which of the following Rust code snippets correctly pushes an element onto a stack implemented as a vector?
easy
A. stack.insert(5);
B. stack.add(5);
C. stack.push(5);
D. stack.append(5);
Solution
Step 1: Recall Rust vector push syntax
In Rust, vectors use the method push() to add elements at the end.
Step 2: Check other options
Methods add(), insert(), and append() either don't exist or have different signatures in Rust vectors.
Final Answer:
stack.push(5); -> Option C
Quick Check:
Rust vector push method = push() [OK]
Hint: Use push() to add elements to Rust vectors [OK]
Common Mistakes:
Using add() which is not a Rust vector method
Confusing insert() which requires index
Using append() which expects another vector
3. What will be the output of this Rust code using a vector as a stack?
let mut stack = Vec::new();
stack.push(10);
stack.push(20);
let x = stack.pop();
println!("{:?}", stack);
medium
A. [20]
B. [10]
C. [10, 20]
D. []
Solution
Step 1: Trace push operations
stack.push(10) adds 10, stack.push(20) adds 20, so stack is [10, 20].
Step 2: Trace pop operation
stack.pop() removes and returns the last element 20, so stack becomes [10].
Final Answer:
[10] -> Option B
Quick Check:
Pop removes last element, stack left with [10] [OK]
Hint: Pop removes last pushed element from vector [OK]
Common Mistakes:
Thinking pop removes first element
Confusing push order
Expecting stack unchanged after pop
4. Identify the error in this Rust code that tries to implement a stack using an array:
let mut stack: [i32; 3] = [0; 3];
stack.push(5);
medium
A. Array size must be dynamic to push elements
B. Array elements cannot be zero-initialized
C. Stack must be mutable to push elements
D. Arrays in Rust do not have a push method
Solution
Step 1: Check array methods in Rust
Fixed-size arrays in Rust do not have a push() method because their size is fixed at compile time.
Step 2: Understand push method availability
Only vectors (Vec) support push() to add elements dynamically.
Final Answer:
Arrays in Rust do not have a push method -> Option D
Quick Check:
Fixed arrays lack push() method [OK]
Hint: Only Vec supports push(), arrays do not [OK]
Common Mistakes:
Thinking arrays can grow dynamically
Confusing mutability with method availability
Believing zero initialization prevents push
5. You want to implement a stack that can grow dynamically and prevent invalid access errors. Which Rust data structure and approach should you choose?
hard
A. Use a vector (Vec) with push and pop methods encapsulated in a Stack struct
B. Use a tuple to store elements and access by index
C. Use a linked list without any abstraction
D. Use a fixed-size array and manually track top index
Solution
Step 1: Consider dynamic growth requirement
Fixed-size arrays cannot grow dynamically, so Use a fixed-size array and manually track top index is unsuitable.
Step 2: Consider safe access and abstraction
Using a vector with push/pop inside a Stack struct provides dynamic size and controlled access, preventing invalid operations.
Step 3: Linked list without abstraction risks misuse
Use a linked list without any abstraction lacks abstraction, increasing error risk.
Final Answer:
Use a vector (Vec) with push and pop methods encapsulated in a Stack struct -> Option A
Quick Check:
Dynamic stack with Vec and abstraction = Use a vector (Vec) with push and pop methods encapsulated in a Stack struct [OK]
Hint: Use Vec with Stack struct for safe dynamic stack [OK]
Common Mistakes:
Choosing fixed arrays for dynamic needs
Ignoring abstraction benefits
Using tuples which are fixed size
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.