Skip to content
tezvyn:

Top 30 Dart Interview Questions and Answers

30 multiple-choice questions on Dart, drawn from 30 bites out of the 199 tagged Dart 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

    Which statement accurately describes a key difference between final and const in Dart?

    Show the answer

    Answer: a · A final variable can hold a runtime value like DateTime.now(), while const requires a compile-time constant.

    final allows single assignment at runtime, so DateTime.now() is valid, whereas const requires a compile-time constant and deep immutability. Option D is wrong because final only prevents reassignment of the variable, not mutation of the object's contents.

    Read the full bite: What is the difference between final and const in Dart?

  2. Question 2 of 30

    Which keyword is best for a variable initialized at runtime from an API call, never to change?

    Show the answer

    Answer: a · final

    The 'final' keyword is used for variables whose values are determined at runtime and assigned once, making them immutable thereafter. 'const' is incorrect because it requires the value to be known at compile-time, which is not the case for an API response.

    Read the full bite: Dart Variables: var, final, and const

  3. Question 3 of 30

    Which statement accurately describes Dart's positional and named parameter rules?

    Show the answer

    Answer: c · Optional positional parameters use square brackets and must appear before named ones.

    The card states optional positional parameters use square brackets and must precede named ones, while named parameters use curly braces and can be required. D is the most tempting distractor because it repeats the common red-flag misconception that optional positional parameters use curly braces.

    Read the full bite: Explain Dart positional vs named parameters and write one signature

  4. Question 4 of 30

    What is a direct consequence of Dart's principle that "everything is an object"?

    Show the answer

    Answer: c · Even basic data types like integers and strings have callable methods.

    The core idea is that even simple types like int and String are objects, meaning they come with built-in methods and properties, unlike primitive types in other languages. Dart does not have primitive types that need conversion; all values are objects from the start, and 'null' itself is an object of type 'Null'.

    Read the full bite: Dart's Core Data Types: Everything is an Object

  5. Question 5 of 30

    When accessing a property on a nullable object in Dart, what is the fundamental difference between using ?. and !?

    Show the answer

    Answer: c · ?. evaluates to null when the receiver is null, while ! casts to non-nullable and may throw at runtime.

    The null-aware operator ?. short-circuits and yields null if the receiver is null, whereas ! forcibly casts away nullability and throws a runtime exception if the value is actually null. Option D is wrong because it confuses ?. with the ?? default-value operator and incorrectly suggests ! is compile-time safe.

    Read the full bite: Describe Dart's null-aware ?. and null assertion ! operators

  6. Question 6 of 30

    What is the primary reason for using control flow statements in a program?

    Show the answer

    Answer: a · To allow the program to make decisions and repeat actions based on conditions.

    The card explains that control flow allows programs to "react to different inputs, repeat tasks, and handle problems," which directly translates to making decisions and repeating actions. Defining reusable code blocks (functions) is a separate concept, even though functions often contain control flow.

    Read the full bite: Dart's Control Flow: Telling Your Code What to Do Next

  7. Question 7 of 30

    What is the primary characteristic that makes Dart's arrow function syntax (=>) suitable for a function?

    Show the answer

    Answer: a · It implicitly returns the result of a single, concise expression.

    Arrow syntax is designed for functions that compute and return the result of a single expression, implicitly handling the return. Options A and B describe scenarios where a block body function is required, while option D incorrectly states that arrow syntax requires an explicit return keyword.

    Read the full bite: Dart Function Syntax: Block Body vs. Arrow Notation

  8. Question 8 of 30

    A class declares late final UserService repo and assigns it in initState. What happens if repo is read in build before that assignment?

    Show the answer

    Answer: a · A LateInitializationError is thrown at the point of access

    late shifts definite-assignment checks from compile time to runtime, so accessing the field before assignment throws LateInitializationError. Distractor C is tempting because that is exactly the compile-time error you would receive if the field were not marked late.

    Read the full bite: What problem does late solve in Dart?

  9. Question 9 of 30

    You need to store a collection of unique product SKUs that are currently in stock and frequently check if a particular SKU is available. Which Dart collection is the most efficient choice for this task?

    Show the answer

    Answer: a · Set, because it guarantees uniqueness and optimizes for fast existence checks.

    Set is specifically designed for storing unique items and provides highly efficient checks for an item's existence, making it ideal for this scenario. While a Map can also provide fast lookups, a Set is the most direct and efficient choice when only uniqueness and existence checking are required, without needing to associate a value.

    Read the full bite: Dart Collections: Choosing List, Set, or Map

  10. Question 10 of 30

    Given List<int> nums = [1, 2, 3, 4] and bool includeZero = true, which literal produces [0, 2, 4]?

    Show the answer

    Answer: a · [if (includeZero) 0, for (var n in nums) if (n.isEven) n]

    Option A correctly uses collection-if to prepend 0 and collection-for with a nested collection-if to filter evens inside one literal. Option B is tempting because where looks declarative, but without the spread operator it inserts the Iterable object itself as a single element rather than flattening its contents.

    Read the full bite: How do you use collection-if and collection-for to declaratively build a list?

  11. Question 11 of 30

    Which statement accurately describes how Dart closures handle captured variables from an enclosing function?

    Show the answer

    Answer: d · They capture the variable binding by reference in a heap-allocated environment

    Dart closures capture the variable binding by reference in the heap, so the inner function retains access even after the outer function returns and its stack frame is popped. This makes B incorrect because the enclosing function's stack frame does not remain on the call stack after it returns.

    Read the full bite: What is a Dart closure? Write a function that returns a function.

  12. Question 12 of 30

    How does Dart's sound null safety fundamentally alter variable nullability?

    Show the answer

    Answer: b · Variables are non-nullable by default, requiring explicit opt-in for nullability.

    Dart's sound null safety makes variables non-nullable by default, meaning they are guaranteed to hold a value. To allow a variable to be null, developers must explicitly opt-in by adding a '?' to its type. Option D describes the opposite behavior, which is common in many other languages but not Dart with null safety.

    Read the full bite: Dart's Sound Null Safety: No More Null Errors

  13. Question 13 of 30

    When a variable is declared as dynamic, why does calling toIntOrDefault on it fail to compile?

    Show the answer

    Answer: b · Because extension methods are resolved statically and dynamic bypasses static type information

    The card explains that extension methods are static sugar resolved at compile time based on the declared type, so dynamic variables bypass static extension resolution. Option A is tempting because it uses precise-sounding terminology, but it incorrectly claims runtime resolution, which contradicts the fundamental static nature of Dart extensions.

    Read the full bite: What are Dart extension methods? Implement toIntOrDefault on String.

  14. Question 14 of 30

    Which statement accurately describes the primary function of Dart's null-aware access operator (?. )?

    Show the answer

    Answer: a · It safely attempts to access a member, returning null if the object itself is null.

    The null-aware access operator (?. ) safely checks if an object is null before attempting to access its members. If the object is null, the expression short-circuits and returns null, preventing a runtime error. Option D describes the if-null operator (??), and Option C describes the unsafe not-null assertion operator (!).

    Read the full bite: Dart's Null-Aware Operators: Safely Handle Nulls

  15. Question 15 of 30

    What is the primary advantage of using a sealed class instead of an enum for exhaustiveness-checked state machines in Dart 3?

    Show the answer

    Answer: c · Sealed classes let each subtype carry distinct constructor parameters and fields while keeping exhaustive switch safety.

    Sealed classes enable algebraic data types where each variant holds distinct payload data while the compiler verifies exhaustive handling, unlike enums which share a single shape. Distractor A is wrong because sealed subclasses must remain in the same library for the compiler to prove exhaustiveness; adding them elsewhere breaks that guarantee.

    Read the full bite: Explain Dart switch exhaustiveness for enums versus sealed classes

  16. Question 16 of 30

    In a Dart isolate, what is the consequence of a microtask that keeps rescheduling new microtasks recursively?

    Show the answer

    Answer: a · The event queue is starved until the recursive microtask chain ends

    The event loop always drains the entire microtask queue before processing any event queue tasks, so a self-rescheduling microtask chain blocks the event queue indefinitely. Option C is wrong because Dart does not interleave the two queues one-for-one.

    Read the full bite: Explain Dart's event loop, microtask queue, event queue, and await behavior

  17. Question 17 of 30

    When using Dart's cascade notation (..), what is a crucial difference compared to standard method chaining (.)?

    Show the answer

    Answer: c · The entire cascade expression evaluates to the original object, not the result of the last operation.

    The card explicitly states that the cascade expression gives back the original object, not the result of the final task, which is the crucial difference from standard method chaining. Option B is incorrect because cascade notation modifies the original object in place and returns it, rather than creating a new one.

    Read the full bite: Dart's Cascade Notation: Chain Calls on One Object

  18. Question 18 of 30

    In Dart, what is the result of building a Map<String, User> with {for (var u in users) u.id: u} when two users share the same id?

    Show the answer

    Answer: c · The last user encountered silently overwrites the previous entry

    Dart map literals silently overwrite duplicate keys, so the last user wins without throwing. Many candidates incorrectly assume a runtime exception occurs, but Dart LinkedHashMap simply replaces the previous value.

    Read the full bite: Convert List<User> to Map<String, User> keyed by user id

  19. Question 19 of 30

    What is the most direct consequence of calling an `async` function in Dart without using the `await` keyword?

    Show the answer

    Answer: a · The variable assigned the result will hold a `Future` object instead of the completed value.

    The card explicitly states that forgetting `await` results in receiving a `Future` object instead of the actual data, which can lead to downstream type errors. The `async` function itself still executes non-blockingly, and it doesn't immediately throw an exception or prevent execution.

    Read the full bite: Dart's async/await: Non-Blocking Code That Reads Synchronously

  20. Question 20 of 30

    What primary problem do Dart generics address in software development?

    Show the answer

    Answer: b · Allowing code to operate on different data types without sacrificing compile-time type safety.

    Generics solve the problem of writing code that works with various data types while maintaining type safety at compile time, preventing errors that would arise from using less specific types like Object or dynamic. Option A is incorrect because generics enforce type safety at compile-time, which is distinct from dynamic typing that defers type checking to runtime.

    Read the full bite: Dart Generics: Type-Safe Containers and Reusable Code

  21. Question 21 of 30

    Which statement accurately describes the difference between final and const fields when declared inside a Dart class?

    Show the answer

    Answer: c · const fields must be static, while final fields can be instance fields

    Inside a Dart class, const fields must be static because they are compile-time constants, whereas final fields may be instance-level since they are assigned once at runtime. Distractor A reverses this relationship, a red flag the card specifically identifies.

    Read the full bite: Difference between final and const Dart class properties?

  22. Question 22 of 30

    When is a Dart Stream the most appropriate choice for handling asynchronous data?

    Show the answer

    Answer: d · Processing a series of real-time sensor readings from an IoT device.

    Option D describes a continuous flow of data (real-time sensor readings), which is the primary use case for Dart Streams, as they handle sequences of asynchronous events over time. Options A, C, and D all represent scenarios where a single asynchronous value is expected, making a Future a more appropriate and simpler choice.

    Read the full bite: Dart Streams: Asynchronous Data Sequences

  23. Question 23 of 30

    When deduplicating emails in Dart, why is emails.toSet().toList() preferred over manually looping with contains?

    Show the answer

    Answer: d · It preserves first-occurrence order and runs in average O(n) time instead of O(n^2)

    Converting to a Set uses Dart's LinkedHashSet to drop duplicates in average O(n) time while keeping the first occurrence of each email in its original position. Option B is tempting because distinct sounds like a standard operation, but it is not part of Dart's core Iterable API and comes from external packages like RxDart.

    Read the full bite: Deduplicate a List of emails in Dart

  24. Question 24 of 30

    Which statement accurately contrasts Dart's extends, implements, and with keywords for class reuse?

    Show the answer

    Answer: a · extends inherits from one superclass; implements requires reimplementing every public member; with injects behavior without subtyping.

    Option A is correct because extends provides single inheritance of implementation, implements forces the class to reimplement every public member itself, and with injects reusable behavior without creating an is-a relationship. Option B is wrong because extends does not allow multiple superclasses, implements does not reuse parent code, and with does not establish an is-a inheritance chain.

    Read the full bite: What are the key differences between Dart extends, implements, and with?

  25. Question 25 of 30

    Which statement accurately describes a semantic difference between a Dart factory constructor and a generative constructor?

    Show the answer

    Answer: c · A factory constructor can return an existing cached instance or a subtype, while a generative constructor always produces a fresh instance of the exact class.

    A factory constructor is not required to create a new instance and may return a cached object or subtype, whereas a generative constructor always allocates a fresh instance of the exact class. Option B is tempting because factories resemble static methods, but they remain part of the constructor namespace and are called with standard constructor syntax.

    Read the full bite: What is a Dart factory constructor and common use cases?

  26. Question 26 of 30

    You need to parse a dynamic JSON array into List<Product> where some objects may contain missing or mistyped fields. Which approach best preserves type safety and prevents runtime crashes?

    Show the answer

    Answer: a · Use a factory constructor that checks runtime types and defaults, then map over the list while isolating or skipping invalid rows.

    Defensive parsing inside a factory constructor centralizes validation and runtime type checks in the model layer, while isolating or skipping invalid rows during mapping prevents one malformed item from crashing the entire list. Option C spreads uncertainty by pushing null handling into the UI, and C fails because a Map cannot be directly cast to a custom class.

    Read the full bite: How do you model Product and safely parse JSON into List<Product>?

  27. Question 27 of 30

    Which statement accurately describes a limitation of static methods in Dart?

    Show the answer

    Answer: b · They cannot use the 'this' keyword or access instance-specific data.

    Static methods belong to the class, not an individual instance. Therefore, they cannot refer to instance-specific data or the 'this' keyword, which points to the current instance. Option D is incorrect because static methods are called directly on the class, without needing an instance.

    Read the full bite: Static Members: Belong to the Class, Not the Instance

  28. Question 28 of 30

    In Dart, given class C extends S with M1, M2 where all define foo(), if C overrides foo() and calls super.foo(), which implementation does the call reach?

    Show the answer

    Answer: a · It reaches M2's implementation because the rightmost mixin becomes the immediate superclass.

    Dart applies mixins left-to-right, so the last mixin becomes the immediate superclass and shadows earlier ones; thus super.foo() from C resolves to M2. Distractor B confuses application order with inheritance priority, but left-to-right application means M2 is layered on top of M1, not beneath it.

    Read the full bite: How does Dart resolve mixin method conflicts and application order?

  29. Question 29 of 30

    Which statement accurately describes how to consume a Future<String> and handle errors idiomatically in Dart?

    Show the answer

    Answer: b · Use an async function with try/catch around an await, or chain .then() with .catchError() on the Future.

    Option B correctly identifies both callback-style and async/await patterns for handling values and errors. Option A is wrong because a Future<String> is a pending object, not an actual String, so assigning it directly causes a type mismatch and synchronous try/catch cannot catch its asynchronous errors.

    Read the full bite: Define a Dart Future, return Future<String>, and handle errors with both patterns.

  30. Question 30 of 30

    What is the practical consequence of declaring an async Dart function as void instead of Future<void>?

    Show the answer

    Answer: a · The caller gets no Future handle, so they cannot await completion or catch async errors.

    A void return type hides the implicit Future from the caller, which prevents awaiting completion and catching errors with try/catch. Option C is tempting but wrong because without a Future handle, exceptions become uncaught async errors instead of propagating to the caller.

    Read the full bite: Difference between Future<void> and void from an async function

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