Skip to content
tezvyn:

Top 30 Go & Rust Concepts Quiz

30 multiple-choice questions on the Go & Rust fundamentals, drawn from 30 bites in the Go & Rust library. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.

Go web services, Rust backends, systems programming

30 questions. Pick an answer, or open “Show the answer” to read it.

Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.

  1. Question 1 of 30

    What is the fundamental principle guiding Go's design?

    Show the answer

    Answer: d · Optimizing for practical engineering challenges in large systems.

    Go was created to solve practical problems like slow builds and complexity in massive codebases, prioritizing engineering concerns such as maintainability and team productivity. It explicitly avoids being a research language or focusing on novel paradigms.

    Read the full bite: Go's Design Philosophy: Engineering Over Novelty

  2. Question 2 of 30

    What is a key advantage of Rust's philosophy of bundling its official documentation with the language installation?

    Show the answer

    Answer: c · It guarantees developers have immediate, offline access to comprehensive learning materials.

    The card states that bundling the documentation ensures every user has immediate, offline access to a high-quality learning resource. Option D is incorrect because documentation adds to the download size, it doesn't reduce it.

    Read the full bite: Rust's Philosophy: Documentation and Community First

  3. Question 3 of 30

    A Go server spawns a goroutine per incoming request, and one handler blocks forever reading from a channel that nothing will ever write to. What happens to that goroutine?

    Show the answer

    Answer: b · It stays alive indefinitely, quietly consuming its stack memory, because Go never force-cancels a blocked goroutine on its own

    Go has no automatic timeout or forced cancellation for a blocked goroutine, so it simply stays parked, leaking its stack, until the process exits or something explicitly unblocks it. The runtime does not kill it after a timeout, a single blocked goroutine does not crash the whole program since Go only reports a deadlock when every goroutine is blocked at once, and the garbage collector does not collect a goroutine that could still be unblocked.

    Read the full bite: Goroutines

  4. Question 4 of 30

    How does a concrete type in Go become an implementer of an interface?

    Show the answer

    Answer: b · By defining all the methods specified in the interface's method set.

    A type satisfies an interface implicitly by implementing its methods, without an 'implements' keyword. Option B accurately describes this structural typing, where a type automatically satisfies an interface if it provides all the required methods. Option C is incorrect because Go does not use an explicit 'implements' keyword.

    Read the full bite: Go Interfaces: Describe Behavior, Not Data

  5. Question 5 of 30

    What is the immediate consequence when ownership of a variable is moved to a function in Rust?

    Show the answer

    Answer: a · The original variable becomes invalid and cannot be accessed further.

    When ownership is moved, the original variable is invalidated, as the card states 'Once you've given it away, it's no longer yours to use' and the example demonstrates a compile error for subsequent use. Option D is incorrect because for complex types like String, ownership is moved, not copied, unless explicitly cloned. Option B is incorrect because the memory is freed when the new owner (the function's parameter) goes out of scope, not immediately upon the move.

    Read the full bite: Rust Ownership: Memory Safety Without a Garbage Collector

  6. Question 6 of 30

    Which scenario correctly describes a fundamental rule enforced by Rust's borrow checker for memory safety?

    Show the answer

    Answer: a · You can have either one mutable reference or any number of immutable references to data, but not both simultaneously.

    The borrow checker enforces that you can have either one mutable reference OR multiple immutable references to a piece of data at any given time, but never both, preventing data races. Option D is incorrect because the borrow checker strictly disallows multiple mutable references to the same data concurrently, regardless of the function scope.

    Read the full bite: Rust's Borrow Checker: Memory Safety at Compile Time

  7. Question 7 of 30

    What is the primary benefit of defining a Rust trait, such as Summary with a summarize method, and implementing it for multiple distinct types?

    Show the answer

    Answer: b · It allows writing generic functions that can operate on any type that fulfills the Summary contract, promoting code reuse.

    The card states traits enable "writing generic functions that can accept any type that fulfills a certain contract," which directly leads to code reuse and abstraction. Option D is a tempting distractor because traits can have default implementations, but the primary benefit isn't the automatic provision of a default, but rather the ability to treat different types uniformly based on their shared behavior.

    Read the full bite: Rust Traits: Defining Shared Behavior

  8. Question 8 of 30

    What is the primary benefit of Go's garbage collector for concurrent network services?

    Show the answer

    Answer: c · It performs most of its work concurrently with the application, ensuring high responsiveness.

    Go's GC is designed to run concurrently with the application, minimizing the duration of "stop-the-world" pauses to maintain responsiveness for services. While pauses are very short, they are not completely eliminated, making option A incorrect.

    Read the full bite: Go's Garbage Collector: The Concurrent Cleaner

  9. Question 9 of 30

    When a Rust function attempts to parse user input that might be malformed, which error handling approach is most appropriate?

    Show the answer

    Answer: b · Returning a Result<T, E> enum, allowing the caller to handle the potential parsing failure gracefully.

    The card specifies that Result<T, E> should be used for expected failures like parsing user input, which are conditions outside the program's direct control. panic! is reserved for unrecoverable programmer bugs, not anticipated external data issues.

    Read the full bite: Rust's Two Error Types: Recoverable vs. Unrecoverable

  10. Question 10 of 30

    What characteristic most directly prevents an abstraction from being considered 'zero-cost'?

    Show the answer

    Answer: b · It necessitates runtime data or dynamic dispatch.

    An abstraction is not zero-cost if it requires runtime information, such as dynamic dispatch or allocations, because the compiler cannot prove it away entirely. While many function calls (option C) might seem costly, they can often be inlined and optimized away at compile time, which is a hallmark of zero-cost abstractions.

    Read the full bite: Zero-Cost Abstractions: Pay at Compile Time, Not Runtime

  11. Question 11 of 30

    Regarding variable mutability, what is the fundamental difference between Rust and Go?

    Show the answer

    Answer: d · Rust variables are immutable by default and need an explicit keyword for mutability, whereas Go variables are mutable by default.

    The card explicitly states that Rust variables are immutable by default and require the 'mut' keyword to become mutable, while Go variables are mutable by default. Option A incorrectly swaps the default behaviors of the two languages.

    Read the full bite: Go vs. Rust: Variable Mutability by Default

  12. Question 12 of 30

    Given two slices, s1 and s2, where s2 is created by slicing s1, what happens if you modify an element in s2?

    Show the answer

    Answer: d · The modification will also be visible in s1, because both slices reference the same underlying array.

    Slices are descriptors that point to a segment of an underlying array. When s2 is created by slicing s1, both slices typically point to the same underlying array. Therefore, modifying an element through s2 will also reflect the change when accessing the same element through s1. The most tempting distractor (C) is incorrect because slices do not copy their data when created from another slice; they share the underlying storage.

    Read the full bite: Go Slices: A Window into an Array

  13. Question 13 of 30

    Why is the Last-In, First-Out (LIFO) execution order of Go's `defer` statements considered crucial for resource management?

    Show the answer

    Answer: d · It correctly handles dependencies, like unlocking a mutex that protects a resource before closing that resource.

    The card explains that LIFO is crucial because it naturally handles nested cleanup, giving the example: "if you open a file and then lock a mutex, you'll want to unlock the mutex first, then close the file. defer handles this naturally." Option C is a true statement about LIFO, but B explains the *benefit* of that order in resource management. Option B is a general benefit of `defer`, not specific to its LIFO order. Option A describes a scenario where `defer` should be avoided, as it can cause memory leaks in loops.

    Read the full bite: Go's `defer`: Guaranteed Cleanup

  14. Question 14 of 30

    Which scenario best justifies using a pointer in Go?

    Show the answer

    Answer: c · Passing a large data structure to a function to prevent expensive copying.

    The card states that a key reason to use pointers is "when you are passing a large struct to a function and want to avoid the performance overhead of making a copy." Option A describes pass-by-value behavior, which is the opposite of using a pointer to share or modify the original data.

    Read the full bite: Go Pointers: Memory Addresses, Not Math

  15. Question 15 of 30

    What is the fundamental difference between variable shadowing and variable mutation in Rust?

    Show the answer

    Answer: d · Shadowing declares a new variable that makes the previous one inaccessible, while mutation modifies the value of an existing variable in place.

    Shadowing creates a completely new variable, potentially allocating new memory, making the original inaccessible. Mutation, however, changes the value of an existing variable in its current memory location. Option B describes when to use each, not the fundamental difference in their operation.

    Read the full bite: Rust's Variable Shadowing: Re-binding, Not Mutating

  16. Question 16 of 30

    What is the primary purpose of using Rust's turbofish (`::<>`) or fully qualified syntax?

    Show the answer

    Answer: c · To specify which trait's method to use when multiple traits define methods with the same name for a given type, or to provide type hints for generic functions.

    The card states the turbofish is used to resolve ambiguity when a type implements multiple traits with same-named methods, or to provide type hints for generic functions like `collect()`. Option C accurately describes these scenarios. Option A describes defining generics, not resolving ambiguity during their use.

    Read the full bite: Rust's Turbofish (`::<>`): When the Compiler Needs Help

  17. Question 17 of 30

    What is the primary reason Box<T> is essential for defining recursive data structures in Rust?

    Show the answer

    Answer: d · It ensures that the overall size of the recursive type can be determined at compile time.

    The core problem Box<T> solves for recursive types is making their size known at compile time by storing the actual data on the heap and only keeping a fixed-size pointer on the stack. While Box<T> can help prevent stack overflows by moving data off the stack, this is a secondary effect; the primary issue for recursive types is their indeterminate size at compile time.

    Read the full bite: Using Box<T> for Heap Allocation in Rust

  18. Question 18 of 30

    What is the immediate consequence of attempting to assign a value to a Go map that has been declared but not initialized?

    Show the answer

    Answer: c · The program will encounter a runtime panic.

    The card explicitly states that 'Writing to a nil map causes a runtime panic.' A declared-only map is nil, meaning it points to no underlying hash table structure. While some errors are caught at compile time, this specific issue is a runtime problem because the type system allows the declaration, but the operation itself is invalid without an initialized structure.

    Read the full bite: Go Maps: Your Built-in Hash Table

  19. Question 19 of 30

    What happens when a Rust Vec<T> is full and a new item is pushed into it?

    Show the answer

    Answer: a · It allocates a larger memory block, copies all existing items, then adds the new item.

    When a Vec<T> is full, it reallocates by finding a new, larger contiguous memory block, copying all existing elements to it, and then adding the new element. This ensures the vector remains growable. Option D is incorrect because Vec<T> is designed to grow automatically, not to error out when capacity is reached.

    Read the full bite: Rust Vectors: Your Go-To Growable List

  20. Question 20 of 30

    Which action is most likely to lead to incorrect behavior or data loss when using a Rust HashMap?

    Show the answer

    Answer: b · Modifying a key's internal state in a way that changes its hash value after it has been inserted.

    Modifying a key's hash-relevant properties after insertion violates the HashMap's core invariants, leading to undefined behavior like panics or incorrect lookups. While using non-cryptographically secure keys can lead to performance degradation under attack (HashDoS), it doesn't inherently cause the map's internal logic to break or data to be lost in the same way as modifying an inserted key.

    Read the full bite: Rust HashMap: Fast, Secure Key-Value Storage

  21. Question 21 of 30

    What is the primary advantage of defining a function to accept `&[T]` instead of `&Vec<T>`?

    Show the answer

    Answer: d · It makes the function more generic, allowing it to operate on data from Vecs, arrays, or other slices.

    The card states that `&[T]` makes functions more generic, allowing them to operate on data from various sources like `Vec`s, arrays, or other slices. Option A is incorrect because slices are borrowed views, not copies, and option C is incorrect because while `&[T]` is immutable, `&Vec<T>` also provides immutability; the key advantage of `&[T]` is its genericity.

    Read the full bite: Rust Slices (&[T]): Views Without Ownership

  22. Question 22 of 30

    When writing a Rust function that needs to read and process string data without modifying or taking ownership, which parameter type is generally most flexible and efficient?

    Show the answer

    Answer: b · &str

    The card explicitly states to "Use &str as function parameters whenever you only need to read string data" because it is more flexible, accepting owned Strings, string literals, and other slices without unnecessary allocations. While &String is a reference, &str is more versatile as it can directly represent string literals.

    Read the full bite: Rust's Two String Types: String vs. &str

  23. Question 23 of 30

    When modeling a type that can be one of several kinds, each with different data, what is the key advantage of using a Rust enum with associated data over a struct containing a 'kind' enum and separate fields?

    Show the answer

    Answer: c · It guarantees that only valid data combinations for each variant can be represented, enhancing type safety.

    The card emphasizes that enums with associated data prevent the creation of 'invalid states' and are 'more idiomatic and type-safe' compared to using a struct with a 'kind' field. Option B, while a characteristic of enums, is not presented as the primary advantage over the alternative data modeling approach discussed.

    Read the full bite: Rust Enums: Attaching Data Directly to Variants

  24. Question 24 of 30

    For which access pattern is Go's sync.Map specifically optimized?

    Show the answer

    Answer: c · Keys that are written once or infrequently, but read many times concurrently.

    sync.Map is designed for read-heavy workloads where keys are stable and written once or infrequently, as stated in the card. It is explicitly not a general-purpose replacement for a map protected by a mutex, making option A a common but incorrect assumption.

    Read the full bite: Go's sync.Map: A Specialized Concurrent Map

  25. Question 25 of 30

    Which problem does Weak<T> primarily help mitigate when used in conjunction with Rc<T>?

    Show the answer

    Answer: a · Preventing memory leaks caused by reference cycles.

    The card states that "To prevent memory leaks from cycles, Rc<T> is often paired with Weak<T>." Option B describes the role of Arc<T>, while option C describes the role of types like RefCell<T> or Cell<T>.

    Read the full bite: Rust's Rc<T>: Shared Ownership on a Single Thread

  26. Question 26 of 30

    When should Arc<T> be preferred over Rc<T> in Rust?

    Show the answer

    Answer: c · To enable safe sharing of data ownership between multiple threads.

    Arc<T> is specifically designed for thread-safe shared ownership, allowing multiple threads to safely access the same data, unlike Rc<T> which is for single-threaded use. While shared data often needs to be mutable, Arc<T> itself only provides shared ownership, not mutability protection; a Mutex is typically combined with Arc<T> for that purpose.

    Read the full bite: Rust's Arc<T>: Share Data Ownership Across Threads

  27. Question 27 of 30

    To create reusable functionality that can be easily shared across different Rust projects, where should the core logic primarily reside?

    Show the answer

    Answer: a · Inside a library crate, typically rooted at src/lib.rs.

    The card explicitly states, "When you want to create shared, reusable functionality for other projects, you build a library crate." Option C is incorrect because `main.rs` is for the executable's entry point, not for shared logic, which the card advises against.

    Read the full bite: Rust Crates: Your Unit of Compilation

  28. Question 28 of 30

    To make a struct defined within a submodule vegetables (located at src/garden/vegetables.rs) accessible from the crate root (src/main.rs), which visibility declaration is absolutely necessary?

    Show the answer

    Answer: d · The vegetables module, the garden module, and the struct must all be explicitly marked pub.

    The card states that 'Every pub keyword here is essential; without them, the modules and the struct would be private and inaccessible from main.rs.' This means all modules and the item itself in the path must be public. The 'use' keyword only creates a shortcut to an item's path; it does not grant public visibility.

    Read the full bite: Rust Modules: Your Code's File System

  29. Question 29 of 30

    What is the primary mechanism Go uses to identify a program as an executable rather than a reusable library?

    Show the answer

    Answer: a · Declaring `package main` and defining a `func main()` function.

    The card explicitly states that `package main` and its `main()` function serve as the unambiguous signal for the Go compiler to create a runnable executable. Option D is incorrect because `go.mod` manages modules and dependencies, not the program's execution type.

    Read the full bite: Go's Entry Point: The `main` Package and Function

  30. Question 30 of 30

    To make a function `my_func` nested within `mod inner` (which is inside `mod outer`) accessible from the crate root, what visibility is required?

    Show the answer

    Answer: b · `my_func`, `mod inner`, and `mod outer` must all be marked `pub`.

    The card states that for an item deep inside a module tree to be accessible from the outside, "it and all of its parent modules in the path must be marked pub." Therefore, all modules in the path to `my_func` must be public. Option A is a tempting distractor because it makes the immediate parent public, but misses the higher-level parent module.

    Read the full bite: Rust Item Visibility: Private by Default

Could you explain these out loud?

That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon