Skip to content
tezvyn:

Top 30 Compiler Interview Questions and Answers

30 multiple-choice questions on Compiler, drawn from 30 bites out of the 41 tagged Compiler on Tezvyn. 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.

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

    How does Svelte's compiler-first design most directly improve the end-user experience compared to virtual DOM frameworks?

    Show the answer

    Answer: a · It shifts work to build time, producing smaller bundles and less browser CPU work for faster page loads.

    Svelte's compiler generates imperative vanilla JavaScript at build time, which shrinks bundles and eliminates virtual DOM diffing overhead for end users. Option D describes a developer experience benefit, not a user-facing performance improvement.

    Read the full bite: What is the primary end-user benefit of Svelte's compiler-first approach?

  2. Question 2 of 30

    What is the primary benefit of Svelte's architecture as a compiler, rather than a traditional runtime framework?

    Show the answer

    Answer: a · It generates highly optimized, vanilla JavaScript during the build process, eliminating the need for a runtime library in the browser.

    The card emphasizes that Svelte shifts work from runtime to compile time, generating efficient vanilla JavaScript and avoiding a large runtime library, which leads to smaller bundles and improved performance. While Svelte does offer a declarative syntax (option C), this is a feature of many frameworks and not the primary benefit of its *compiler* architecture.

    Read the full bite: Svelte: A Compiler, Not Just a Framework

  3. Question 3 of 30

    When a reactive variable changes in Svelte, how is the update triggered differently than in Vue 3's runtime Proxy system?

    Show the answer

    Answer: a · By compiler transforms that turn assignments into explicit update calls

    Svelte resolves dependencies at build time by transforming assignments into explicit update logic in the compiled output, so no runtime tracker is needed. Option B is tempting because Vue 3 uses runtime Proxies, but Svelte does not use them at all.

    Read the full bite: Compare and contrast Vue 3 and Svelte reactivity systems

  4. Question 4 of 30

    When using a Kotlin data class as a key in a HashMap, which statement about its compiler-generated behavior is true?

    Show the answer

    Answer: b · Only properties defined in the primary constructor marked as val or var are used in generated equals and hashCode, so the key remains consistent in the map.

    The compiler only incorporates primary constructor properties marked val or var into generated equals and hashCode, guaranteeing the contractual consistency required for safe use as a HashMap key. Option C is a tempting distractor because developers often assume body properties participate in structural equality, but the compiler intentionally excludes them.

    Read the full bite: What are the primary advantages of using a data class?

  5. Question 5 of 30

    You add a new case to a widely-used enum. When does this silently undermine compile-time safety?

    Show the answer

    Answer: b · When switches over the enum include a default clause

    A default clause catches the new case automatically, so the compiler cannot force you to handle it explicitly. Omitting a default clause produces a build error for unhandled cases, which preserves compile-time safety.

    Read the full bite: Swift Enums: Type-Safe Choice Modeling

  6. Question 6 of 30

    When reactive state changes in a Svelte component, how does the compiled application update the browser DOM?

    Show the answer

    Answer: d · It executes pre-generated imperative statements that directly mutate the affected DOM nodes.

    Svelte compiles components into imperative vanilla JavaScript that retains direct references to DOM nodes and executes precise update statements when state changes, so no intermediate tree is ever created. The distractor suggesting a hidden virtual DOM is wrong because the compiler deliberately avoids emitting any diffing or reconciliation runtime, generating direct DOM manipulation code instead.

    Read the full bite: How does Svelte update the DOM without a Virtual DOM?

  7. Question 7 of 30

    How does Svelte fundamentally differ from Virtual DOM-based frameworks in its approach to updating the user interface?

    Show the answer

    Answer: d · Svelte compiles components into vanilla JavaScript that directly modifies the DOM based on state changes, eliminating runtime diffing.

    Svelte is a compiler that generates highly optimized JavaScript to directly update the DOM when state changes, completely bypassing the Virtual DOM and its runtime diffing process. Option B is incorrect because Svelte eliminates the VDOM entirely, it doesn't optimize it.

    Read the full bite: Why Svelte Skips the Virtual DOM

  8. Question 8 of 30

    When building a no-code canvas where users assemble layouts from hundreds of possible components at runtime, what is a concrete downside of Svelte's compile-time model versus Vue or Angular?

    Show the answer

    Answer: d · Svelte must eagerly import all possible dynamic targets, sacrificing tree-shaking and reintroducing runtime overhead through escape hatches like svelte:component.

    The correct answer notes that Svelte requires eager imports and runtime escape hatches for open-ended dynamic sets, which reintroduces overhead and sacrifices tree-shaking. Distractor A is tempting because Svelte does compile to imperative DOM operations, but dynamic components are still possible via compiler-aware patterns rather than impossible.

    Read the full bite: Svelte compiler downsides vs Vue and Angular runtime

  9. Question 9 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

  10. Question 10 of 30

    What is the fundamental reason `reified` type parameters can only be used with `inline` functions in Kotlin?

    Show the answer

    Answer: c · inline allows the compiler to substitute the concrete type argument for the generic parameter directly into the bytecode at the call site, bypassing JVM type erasure.

    Option C correctly identifies that inline enables the compiler to replace the generic type with its concrete type at the call site, thus preserving it from JVM type erasure for runtime access. Option D is a common misconception; while inline offers performance, its necessity for reified is about enabling type information availability, not just optimizing checks.

    Read the full bite: What problem does `inline` solve, and how does `reified` relate?

  11. Question 11 of 30

    Why must a Kotlin function be declared `inline` to use a `reified` type parameter?

    Show the answer

    Answer: d · Because inlining moves the function's bytecode to the call site, where the compiler can access the concrete type argument.

    The `reified` keyword needs to know the actual type at runtime, which is normally erased by the JVM. The `inline` keyword enables this by copying the function's code to the call site, where the compiler knows the concrete type (e.g., `String`) and can substitute it directly into the bytecode. Option C is incorrect because `inline` doesn't prevent type erasure in general; it provides a clever workaround for a specific call.

    Read the full bite: Explain `inline` and `reified` in Kotlin

  12. Question 12 of 30

    Which statement accurately describes the Kotlin language rule for calling a suspend function?

    Show the answer

    Answer: a · It is only permitted from another suspend function or a coroutine builder.

    Kotlin enforces that suspend functions run inside a coroutine context, so they can only be called from another suspend function or a builder like launch or async. Option C is tempting because runBlocking is a valid bridge from regular code, but it is not required for every invocation.

    Read the full bite: What is a suspend function in Kotlin and its compiler rules?

  13. Question 13 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

  14. Question 14 of 30

    What is the core mechanism that allows a `reified` type parameter to be accessible at runtime in a Kotlin `inline` function?

    Show the answer

    Answer: a · The compiler copies the function's body and the actual type argument directly into the location where the function is called.

    `reified` works because the `inline` function's body and its actual type arguments are copied directly to the call site by the compiler, thus avoiding type erasure. Option D describes a common manual workaround for type erasure, not the automated mechanism of `reified`.

    Read the full bite: What is a reified type parameter in Kotlin?

  15. Question 15 of 30

    Why do type errors in result builder code sometimes reference compiler-generated boilerplate instead of the original developer code?

    Show the answer

    Answer: d · Because the compiler performs a silent source-to-source rewrite into static method calls during type checking, and errors are reported against the generated code.

    The card describes result builders as a compile-time source-to-source rewrite into static method calls, so type errors surface on the generated boilerplate rather than the original code. Distractor A incorrectly attributes the transformation to runtime metaprogramming, when the card explicitly states the rewrite happens during type checking.

    Read the full bite: Result Builders: Declarative Swift DSLs

  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

    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

  18. Question 18 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

  19. Question 19 of 30

    Given `src/lib.rs` declares `mod utils;` and `src/utils.rs` declares `pub mod helpers;`, where does Rust expect `helpers`'s code?

    Show the answer

    Answer: d · src/utils/helpers.rs

    The module system maps recursively; `helpers` is a submodule of `utils`, so its file is expected within the `utils` directory relative to `src`. Option B is incorrect because `src/helpers.rs` would be the location if `mod helpers;` was declared directly within `src/lib.rs`, not nested within `utils`.

    Read the full bite: Rust's Module-to-Filesystem Mapping

  20. Question 20 of 30

    Which function signature would require explicit lifetime annotations because Rust's lifetime elision rules cannot infer them?

    Show the answer

    Answer: a · fn compare_strings(a: &str, b: &str) -> &str

    The function `compare_strings` takes two input references and returns one, creating an ambiguous scenario where the compiler cannot determine which input's lifetime the output should inherit, thus requiring explicit annotation. In contrast, `find_first_char` has only one input reference, allowing elision rule 2 to apply.

    Read the full bite: Rust's Lifetime Elision: When You Can Skip 'a

  21. Question 21 of 30

    What fundamental change does Rust's Non-Lexical Lifetimes (NLL) introduce to the borrow checker's behavior?

    Show the answer

    Answer: a · It permits a borrow to end based on its last actual use, rather than strictly at the end of its declared lexical scope.

    NLL's core innovation is to make the borrow checker usage-based, ending a borrow after its last use, not its lexical scope, which allows for more flexible code. It does not change fundamental borrowing rules like preventing multiple mutable references, nor is it related to lifetime parameter inference or data deallocation.

    Read the full bite: Rust's NLL: Smarter Borrows Based on Use, Not Scope

  22. Question 22 of 30

    When a reactive variable changes in a Svelte component, what does the runtime do differently than a VDOM framework?

    Show the answer

    Answer: b · It executes pre-generated imperative code that mutates only the affected real DOM nodes

    Svelte's compiler generates imperative code that calls native DOM APIs to surgically update only affected nodes, eliminating virtual tree creation and diffing. The zero-runtime claim is a common misconception; Svelte still includes a small runtime, but it avoids reconciliation overhead rather than eliminating all runtime work.

    Read the full bite: How does Svelte surgically update the DOM without VDOM?

  23. Question 23 of 30

    What architectural approach allows Svelte to minimize its browser footprint compared to virtual DOM frameworks?

    Show the answer

    Answer: a · It transforms components into imperative vanilla JS at build time while shipping only a small runtime

    Svelte's compiler generates imperative vanilla JavaScript that manipulates the DOM directly, so the browser only needs a tiny runtime for reactivity rather than a full reconciler. Option D is tempting but incorrect because Svelte still ships a minimal runtime for signals and stores, not zero framework code.

    Read the full bite: Why is Svelte called a 'disappearing framework'?

  24. Question 24 of 30

    After Vue compiles a template with v-if and v-for into a render function, which statement accurately describes the result?

    Show the answer

    Answer: c · The render function replaces directive tokens with JavaScript conditionals and array iteration methods.

    Vue's compiler desugars v-if into conditional expressions or ternaries and v-for into array map calls, so the generated code contains no directive tokens at all. It is tempting to think directives survive as metadata on vnodes, but they are resolved entirely at compile time into imperative JavaScript control flow.

    Read the full bite: How is a Vue template compiled into a render function?

  25. Question 25 of 30

    When count += 1 executes in Svelte 5, what mechanism ensures the DOM reflects the new value without virtual DOM diffing?

    Show the answer

    Answer: b · The compiler treats $state as a build-time construct and emits imperative code that directly updates the specific DOM nodes.

    The compiler intercepts the $state rune during compilation and generates imperative DOM update logic, so reactivity happens at build time rather than through runtime Proxies or virtual DOM diffing. Option C is tempting because runes look like React hooks, but $state is a compiler construct, not a runtime store registration.

    Read the full bite: How does Svelte compile count += 1 into DOM updates?

  26. Question 26 of 30

    In Vue 3, how do patch flags and static hoisting work together during a component re-render?

    Show the answer

    Answer: d · The compiler marks dynamic nodes with bitmap flags and extracts static trees so the runtime skips unnecessary diffing

    Patch flags are compile-time bitmap annotations that tell the runtime exactly which dynamic bindings changed, avoiding recursive diffing, while static hoisting extracts unchanging nodes to module scope so they are skipped entirely. Distractor D is wrong because static hoisting lifts nodes outside the render closure rather than caching them inside it, and patch flags are not memoization but bitwise hints consumed during patching.

    Read the full bite: Explain patch flags and static hoisting in Vue 3's compiler

  27. Question 27 of 30

    A Rust developer is evaluating the runtime performance of a new sorting algorithm. Which command should they use for accurate results?

    Show the answer

    Answer: d · cargo run --release

    To accurately measure performance, the code must be compiled with optimizations enabled, which the 'release' profile provides. 'cargo run --release' uses this profile, while 'cargo run' defaults to the unoptimized 'dev' profile, leading to misleadingly slow results.

    Read the full bite: Rust Build Profiles: Tune for Speed vs. Debugging

  28. Question 28 of 30

    Which statement accurately describes a key performance benefit of Angular AOT compilation for an app using external templateUrl and styleUrls?

    Show the answer

    Answer: b · The AOT compiler inlines external templates and styles into the JavaScript bundle and removes the Angular compiler from the client payload, eliminating extra AJAX requests and reducing download size.

    AOT performs build-time inlining of templates and styles and strips the Angular compiler from the bundle, which removes separate AJAX fetches and cuts payload size by roughly half. Option D is tempting because minification and tree-shaking do reduce bundle size, but they are bundler concerns, not the semantic compilation step unique to AOT.

    Read the full bite: How does ngc work in Angular AOT and what artifacts improve performance?

  29. Question 29 of 30

    Which statement accurately describes Ivy's locality principle and its main exception?

    Show the answer

    Answer: b · Ivy converts decorators into static properties on the class using local file metadata, though @Component still requires its declaring @NgModule's selector scope.

    Ivy compiles decorators like @Injectable into self-contained static properties using only that file's metadata, but @Component is the exception—it needs the declaring @NgModule's selector scope to generate ɵcmp. Distractor A is tempting because it correctly captures the elimination of .metadata.json files but wrongly asserts that all decorators are purely local, ignoring the @NgModule scope requirement for components.

    Read the full bite: What is Angular Ivy's 'locality' and its benefits over View Engine?

  30. Question 30 of 30

    How does Angular Ivy primarily contribute to smaller application bundle sizes?

    Show the answer

    Answer: c · By transforming templates into plain JavaScript function calls that bundlers can effectively tree-shake.

    Ivy's core mechanism is to transform templates into simple JavaScript function calls. This format allows modern bundlers to easily identify and remove (tree-shake) any unused Angular features, directly leading to smaller bundles. Option B is incorrect because Ivy compiles components in isolation, and the format of the output, not necessarily a single monolithic file, is what enables tree-shaking.

    Read the full bite: Angular Ivy: The Tree-Shakable Compiler

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