Start Practicing

Flutter Developer Interview Questions & Answers (2026 Guide)

Flutter interviews in 2026 test three things: whether you understand widget composition deeply enough to build and debug complex layouts, whether you can manage state correctly across large apps, and whether you know Dart well enough to write performant async code.

Start Free Practice Interview →
Widget tree, element tree & rendering pipeline with code examples
State management: Riverpod, Bloc, Provider & InheritedWidget
Dart fundamentals: null safety, async/await, isolates & streams
Platform channels, performance optimization & testing

AI-powered mock interviews tailored to Flutter developer roles

Last updated: February 2026

Flutter has matured from a mobile-only toolkit into a cross-platform framework targeting iOS, Android, web, desktop, and embedded devices. Widgets and the rendering pipeline are the foundation, state management is the most debated and heavily tested topic, and Dart's single-threaded async model underpins everything.

Every section includes runnable code because Flutter interviews are heavily practical. Interviewers expect idiomatic Dart and widgets that are both correct and maintainable.

What Flutter Developer Interviews Cover in 2026

Widgets, layout, and the rendering pipeline — the three-tree architecture (widget tree, element tree, render tree), how Flutter decides what to rebuild, BuildContext, keys, layout constraints, slivers, RepaintBoundary, and const constructors.

State management — setState and its limitations, InheritedWidget, Provider, Riverpod (type-safe, testable, increasingly popular), Bloc/Cubit (event-driven, enterprise), and when to use ephemeral vs app state.

Dart language fundamentals — null safety, Future/async/await, Stream/StreamController, isolates for parallel computation, generics, mixins, and extension methods.

Platform integration — platform channels (MethodChannel, EventChannel, BasicMessageChannel), Pigeon for type-safe communication, FFI for C interop, and platform-specific UI adaptations.

Navigation and routing — GoRouter, deep linking, route guards, nested navigation, and the declarative navigation model.

Testing and performance — widget tests, integration tests, golden tests, identifying jank with DevTools, reducing rebuilds, ListView.builder, and image caching.

Flutter vs React Native vs SwiftUI vs Jetpack Compose

Flutter's rendering model is fundamentally different from React Native's bridge architecture. Understanding what Flutter interviews emphasize differently helps focus preparation.

DimensionFlutter InterviewReact Native InterviewSwiftUI InterviewJetpack Compose Interview
RenderingCustom engine (Skia/Impeller) draws every pixel. Three-tree architecture is core interview topicJS bridge to native views (or JSI). Focus on bridge overhead and optimizationNative Apple rendering with declarative syntax. View lifecycle and UIKit interopNative Android rendering, declarative. Composition and recomposition focus
State managementMultiple options: Provider, Riverpod, Bloc, Redux. Choice and tradeoffs are a major topicReact model: useState, useReducer, Context, Redux, Zustand. Familiar from ReactCombine, @State, @Binding, @ObservedObject. Apple's opinionated approachremember, mutableStateOf, ViewModel. Kotlin-native state model
LanguageDart with sound null safety, event loop, isolates. Dart fundamentals always testedJavaScript/TypeScript. Language questions rare — framework dominatesSwift mastery expected — optionals, protocols, value typesKotlin — coroutines, null safety, scope functions tested alongside Compose
Platform accessPlatform channels (MethodChannel, EventChannel), Pigeon, FFI. Tested for senior rolesNative Modules or Turbo Modules. Bridge-based native accessFull native API access by defaultFull native API access. View-based Android interop tested
Layout modelConstraints-based: down/up/parent-sets-position. Box constraints, slivers, custom layoutsFlexbox (Yoga engine). Similar to CSS FlexboxStacks (HStack, VStack, ZStack), GeometryReaderRow, Column, Box, Modifier chains, custom layouts
TestingWidget tests, integration tests, golden tests. Testing without a device is a major advantageJest, React Testing Library, Detox E2EXCTest, Preview testing. More limitedCompose testing rules, semantics testing. Similar to Flutter

Widgets, Layout & Rendering Pipeline Questions

These questions test whether you understand Flutter's architecture beyond the surface API. The three-tree model and layout constraints are where candidates struggle most.

Explain the three-tree architecture: widget tree, element tree, and render tree.
Why They Ask It

The most fundamental Flutter architecture question. Separates developers who understand internals from those who only know the widget API.

What They Evaluate
  • Immutable widget descriptions vs mutable elements vs render objects
  • How Flutter decides what to rebuild
  • Why keys matter for element matching
Answer Framework

Three trees with different responsibilities. Widget tree: lightweight, immutable configuration descriptions — cheap to recreate. Element tree: mutable, long-lived objects managing lifecycle and identity between widgets and render objects. When a widget rebuilds, Flutter calls updateWidget on the existing element if type and key match. Render tree: handles actual layout and painting — expensive objects that calculate sizes and paint. The optimization: widgets are cheap and rebuilt freely; render objects only update what changed.

Sample Answer

Flutter uses three trees that each handle a different concern. The widget tree is the configuration layer — widgets are lightweight, immutable descriptions of UI, not the UI itself. Because they're cheap to create, Flutter rebuilds them freely. The element tree manages identity and lifecycle. Elements are mutable, long-lived objects between widgets and render objects. When setState triggers a rebuild, Flutter doesn't destroy elements — it compares new widgets with existing elements using Widget.canUpdate (same runtimeType and key). If they match, the element updates in place. The render tree handles actual layout and painting — render objects calculate sizes, positions, and paint to screen. This three-tree design means you freely rebuild the cheap widget tree while the expensive render tree only updates what changed. This is also why keys matter: without keys, Flutter matches by position, which breaks when you reorder a list of StatefulWidgets.

How does Flutter's layout system work? Explain the constraint model.
Why They Ask It

Layout bugs are the most common Flutter issue. Understanding constraints is essential for debugging overflow and layout errors.

What They Evaluate
  • Constraints-go-down, sizes-go-up, parent-sets-position model
  • Tight vs loose vs unbounded constraints
  • Common layout errors and debugging
Answer Framework

Core rule: constraints go down, sizes go up, parent sets position. Parent passes constraints (min/max width and height) to child. Child chooses a size within those constraints. Parent decides position. Tight constraints: min equals max (no choice). Loose: min is zero (child can be smaller). Unbounded: max is infinity (scrollable contexts — children must self-size). Common errors: RenderBox was not laid out (Expanded inside ListView), overflow (child exceeds parent). Use LayoutBuilder to inspect constraints and build responsive layouts.

What are keys in Flutter and when should you use them?
Why They Ask It

Keys are one of the most misunderstood Flutter concepts. Most developers either never use them or use them incorrectly.

What They Evaluate
  • When Flutter can/cannot preserve element state without keys
  • Which key type for different scenarios
  • Practical impact on list reordering
Answer Framework

Keys help Flutter match widgets to elements. Without keys, matching is by position — works for static lists, breaks for reorderable/insertable/deletable lists of StatefulWidgets. ValueKey<T>: matches by value (unique ID). ObjectKey: matches by object identity. UniqueKey: forces state reset (always new element). GlobalKey: access state/context across the tree (expensive, use sparingly). Rule of thumb: need keys for lists of StatefulWidgets that can be reordered/added/removed.

How do const constructors improve Flutter performance?
Why They Ask It

A simple optimization with outsized impact. Tests understanding of widget identity and rebuild behavior.

What They Evaluate
  • Compile-time constants and widget canonicalization
  • How const prevents unnecessary rebuilds
  • When const can and can't be used
Answer Framework

const creates compile-time constants — same const widget is literally the same object in memory. During rebuild, if the widget is the exact same const instance, Flutter skips the entire subtree. Use for: static text, icons, padding, spacing, decorations. Enable prefer_const_constructors lint. Only works when all constructor arguments are also compile-time constants.

What is BuildContext and what common mistakes do developers make with it?
Why They Ask It

BuildContext confusion causes real bugs — wrong context for navigation, disposed context after async gaps, wrong InheritedWidget lookup.

What They Evaluate
  • BuildContext as element position in the tree
  • Common context-related bugs
  • Proper async context handling
Answer Framework

BuildContext is a reference to the widget's Element in the element tree — its position in the hierarchy. Theme.of(context) walks UP from that position. Mistake 1: using context above Scaffold for Scaffold.of() — fix with Builder to get context below. Mistake 2: using context after async gap when widget may be disposed — always check context.mounted after await before using context.

State Management Questions

State management is the most debated area in Flutter — and the most heavily tested. Interviewers want to see you reason about tradeoffs, not just advocate for one approach.

Compare setState, InheritedWidget, Provider, Riverpod, and Bloc. When would you choose each?
Why They Ask It

The definitive Flutter architecture question. Every team has opinions on state management — interviewers want tradeoff reasoning.

What They Evaluate
  • Understanding the state management spectrum
  • Matching solutions to problem complexity
  • Practical judgment about over/under-engineering
Answer Framework

setState — local UI state only (toggles, animations, form fields). InheritedWidget — foundation of all Flutter state management, exposes data to descendants via O(1) lookup. Provider — InheritedWidget wrapper reducing boilerplate, good for small-to-medium apps. Riverpod — compile-time safe, testable without widget tree, auto-dispose, handles async elegantly. Increasingly the community standard. Bloc/Cubit — event-driven with clear audit trails, structured, common in enterprise. Rule: setState for ephemeral, Riverpod for most apps, Bloc for event sourcing/audit trails.

Sample Answer

I think about state management as a spectrum. setState is perfect for ephemeral UI state — toggles, form fields, animations. The moment you share state between widgets or preserve it across navigation, setState isn't the tool. InheritedWidget is what everything else builds on — understanding it means understanding how Provider, Riverpod, and Bloc work under the hood. For new projects, I'd recommend Riverpod: compile-time safety Provider lacks, auto-dispose preventing memory leaks, and AsyncValue handling loading/data/error cleanly. Bloc is right when business logic is complex and you need clear event/state audit trails — e-commerce checkout, financial apps. The most common mistake is overcomplicating: not every toggle needs Bloc or Riverpod. Match the solution's complexity to the problem.

How does InheritedWidget work internally?
Why They Ask It

The foundation of Flutter's dependency injection. Understanding it explains how Provider and Riverpod work under the hood.

What They Evaluate
  • O(1) ancestor lookup mechanism
  • Dependency registration and selective rebuilds
  • dependOn vs getInherited distinction
Answer Framework

context.dependOnInheritedWidgetOfExactType<T>() returns the nearest ancestor T AND registers the caller as a dependent. When InheritedWidget updates and updateShouldNotify returns true, only registered dependents are marked dirty. Lookup is O(1) — Flutter maintains a hash map by type in each element. Key subtlety: dependOn registers rebuild dependency, getInherited reads without subscribing (useful for event handlers). Provider wraps InheritedWidget; Riverpod replaces it entirely.

What is the difference between ephemeral state and app state?
Why They Ask It

Misclassifying state leads to over-engineering (global state for a toggle) or under-engineering (setState for auth). Tests architectural judgment.

What They Evaluate
  • Correct state categorization
  • Appropriate management strategy selection
  • Awareness of gray areas
Answer Framework

Ephemeral state: belongs to a single widget, not shared, doesn't survive navigation — page index, expanded/collapsed, text field input, animation progress. Use setState. App state: shared across widgets, survives navigation, core business data — auth status, cart contents, cached API data, theme selection. Use Riverpod/Bloc/Provider. Gray area: state can migrate — a search query starts local but becomes app state when preserved across navigation or shared with a results count badge.

How do you prevent unnecessary widget rebuilds in a large app?
Why They Ask It

Unnecessary rebuilds are the primary cause of Flutter performance issues. Tests practical optimization knowledge.

What They Evaluate
  • const constructors
  • Selective rebuilding and state scoping
  • RepaintBoundary and ListView.builder
Answer Framework

Five strategies: (1) const constructors — simplest, most impactful; static widgets reuse the same instance. (2) Scope setState to smallest subtree — extract stateful parts into separate widgets. (3) Use select with Riverpod/Provider to watch specific fields, not entire objects. (4) RepaintBoundary to isolate expensive paint operations (charts, animations). (5) ListView.builder for long lists — only builds visible items. Profile with Flutter DevTools Widget Rebuild Stats.

Practice Flutter Interview Questions with AI

State management, widget lifecycle, and Dart async patterns are where Flutter interviews are won or lost. Our AI simulator generates role-specific follow-up questions and scores your technical depth.

Start Free Practice Interview →

Tailored to Flutter developer roles. No credit card required.

Dart Language & Async Questions

Dart is often underestimated in Flutter interviews — candidates prepare for widgets and state management but stumble on Dart fundamentals.

Explain Dart's null safety system. How does sound null safety work?
Why They Ask It

Dart 2.12 introduced sound null safety — a breaking change affecting every codebase. Tests whether you understand the guarantees.

What They Evaluate
  • Nullable vs non-nullable types
  • late, required, flow analysis
  • Sound null safety vs TypeScript's unsound approach
Answer Framework

Dart's null safety is sound — the compiler guarantees non-nullable variables can never be null at runtime (stronger than TypeScript). Non-nullable by default: String can't be null, String? can. Flow analysis: after a null check, compiler promotes nullable to non-nullable. late: defer initialization, maintain non-nullability (throws LateInitializationError if accessed before assignment). required: named parameters must be provided. The ! operator: assertion that value is non-null — use sparingly.

How does Dart's event loop work? Explain Futures, async/await, and microtasks.
Why They Ask It

Dart is single-threaded. Understanding the event loop is essential for correct async code and avoiding ordering bugs.

What They Evaluate
  • Single-threaded execution with two queues
  • Microtask queue vs event queue priority
  • Flutter UI responsiveness implications
Answer Framework

Dart runs on a single thread with an event loop. Two queues: microtask queue (higher priority, drained first) and event queue (I/O, timers, UI events). Execution order: synchronous code → all microtasks → next event. async/await is sugar over Futures. Critical for Flutter: long synchronous code blocks the UI. Futures help with I/O-bound work only. For CPU-bound work, you need isolates.

What are isolates and when should you use them?
Why They Ask It

Isolates are Dart's answer to multi-threaded computation. Misunderstanding when to use them leads to jank or over-engineering.

What They Evaluate
  • Dart's memory isolation model
  • Message passing vs shared memory
  • compute() vs long-lived isolates
Answer Framework

Isolates are independent execution contexts with their own memory heap. Unlike threads, they don't share memory — communicate via message passing (SendPort/ReceivePort). Use compute() for one-shot heavy tasks (JSON parsing >1MB, image processing, crypto). Long-lived isolates for continuous background work. When NOT to use: simple API calls (Futures handle I/O fine), small data transformations. Isolate.run() (Dart 2.19+) is the simplest API for one-shot tasks.

Explain Dart Streams vs Futures. When use a StreamController?
Why They Ask It

Streams power reactive data flows — Firestore updates, Bloc state, sensor data. Confusing with Futures is a common mistake.

What They Evaluate
  • Single-value (Future) vs multi-value (Stream) async
  • Broadcast vs single-subscription streams
  • StreamController patterns and lifecycle
Answer Framework

Future<T>: single async value, completes once. Stream<T>: sequence of async values over time. StreamController creates custom streams — use .broadcast() for multiple listeners (events, location), default for single listener (file reads, HTTP). Always close() controllers and cancel() subscriptions to prevent leaks. async*/yield creates generator-based streams. Use StreamBuilder in Flutter for declarative stream consumption.

What are mixins in Dart? How do they differ from abstract classes and extensions?
Why They Ask It

Dart's mixin system enables code reuse without multiple inheritance. Tests understanding of composition strategies.

What They Evaluate
  • Mixin linearization and the with keyword
  • Mixin vs extends vs implements vs extension
  • Practical patterns (SingleTickerProviderStateMixin)
Answer Framework

Three code reuse mechanisms: Mixins add reusable behavior to any class (with keyword) — a class can use multiple mixins. Abstract classes define contracts with optional implementations — single inheritance only. Extension methods add syntactic convenience to existing types without affecting hierarchy. mixin on Widget constrains usage to specific superclasses — how Flutter's SingleTickerProviderStateMixin works (only mixes into State subclasses).

Platform Integration & Native Code Questions

Platform integration separates senior Flutter developers from junior ones. Cross-platform abstractions eventually leak, and interviewers test whether you can handle the native layer.

How do platform channels work? Compare MethodChannel, EventChannel, and BasicMessageChannel.
Why They Ask It

Platform channels are how Flutter talks to native iOS/Android code. Essential for any feature not covered by existing packages.

What They Evaluate
  • Message-passing architecture between Dart and native
  • Codec serialization
  • Choosing the right channel type
Answer Framework

Flutter runs in its own rendering engine, separate from native. Platform channels bridge Dart ↔ native (Kotlin/Java, Swift/ObjC). MethodChannel: request/response (get battery level, take photo) — most common. EventChannel: continuous native-to-Dart streams (sensor data, location updates). BasicMessageChannel: bidirectional messaging with custom codecs. Mention Pigeon for type-safe code generation eliminating stringly-typed method names.

How do you handle platform-specific behavior without scattering platform checks?
Why They Ask It

Every cross-platform app needs platform-specific behavior. Tests clean architecture under platform differences.

What They Evaluate
  • Interface-based service abstraction
  • Platform-adaptive widgets
  • Conditional imports for web vs mobile
Answer Framework

Three patterns: (1) Platform-aware service layer — abstract interface with platform-specific implementations, registered via DI. (2) Platform-adaptive widgets — single widget that renders Material on Android, Cupertino on iOS. (3) Conditional imports — compile-time platform selection (if (dart.library.io) vs if (dart.library.html)). Key principle: platform checks live in service layer or widget implementation, never in business logic.

How would you implement deep linking in a Flutter app?
Why They Ask It

Deep linking is essential for production apps — marketing links, push notifications, web URLs. Flutter's navigation makes this non-trivial.

What They Evaluate
  • GoRouter declarative routing
  • Platform-specific deep link configuration
  • Route guards and auth redirects
Answer Framework

GoRouter is the community standard. Declarative route definitions with path parameters. redirect callback for auth guards. context.go() replaces route, context.push() adds to stack. Platform setup: Android needs intent filters in AndroidManifest.xml, iOS needs Associated Domains in Info.plist. Handle initial deep link that launched the app when it wasn't running.

Flutter Coding Questions

Flutter coding questions test whether you can compose widgets, manage state, and write idiomatic Dart under interview conditions.

Build a debounced search widget with loading and error states.
Why They Ask It

The most common Flutter coding challenge. Combines text input, debouncing, async state, and error handling in one widget.

What They Evaluate
  • Widget composition and async lifecycle
  • Timer-based debouncing
  • mounted checks after async gaps, stale result prevention
Answer Framework

TextEditingController with listener that cancels/restarts a Timer on each keystroke. After debounce duration, fire async search. Check mounted after await. Compare current query to prevent stale results overwriting newer ones. Track loading/error/results with setState. Dispose timer and controller in dispose(). Show loading indicator in TextField suffixIcon.

Implement a custom InheritedWidget that provides theme data to descendants.
Why They Ask It

Tests understanding of Flutter's dependency injection at the framework level — not just using Provider, but understanding what it does internally.

What They Evaluate
  • InheritedWidget mechanics
  • Selective rebuild logic with updateShouldNotify
  • dependOn vs getInherited distinction
Answer Framework

InheritedWidget with custom data class. of(context) static method using dependOnInheritedWidgetOfExactType (registers rebuild dependency). Optional readOf using getInheritedWidgetOfExactType (reads without subscribing — for event handlers). updateShouldNotify compares data with == to control when dependents rebuild. Wrap in StatefulWidget for the mutable state that triggers InheritedWidget rebuilds.

Build a responsive layout widget with mobile/tablet/desktop breakpoints.
Why They Ask It

Flutter targets multiple platforms. Tests whether you build adaptive layouts across form factors.

What They Evaluate
  • LayoutBuilder and MediaQuery usage
  • Breakpoint patterns
  • Responsive design thinking in Flutter
Answer Framework

Reusable ResponsiveLayout widget accepting mobile, tablet, desktop children. Use LayoutBuilder to get parent constraints. Breakpoints at 600px (tablet) and 1024px (desktop). Fall back gracefully: desktop → tablet → mobile. Use MediaQuery.sizeOf(context) instead of MediaQuery.of(context).size to avoid unnecessary rebuilds when unrelated MediaQuery properties change.

Behavioral Questions for Flutter Developers

Behavioral questions focus on cross-platform decision-making, state management debates, and performance diagnosis — the unique challenges of Flutter development.

Tell me about choosing between a cross-platform Flutter solution and a native implementation.
Why They Ask It

The defining tension of Flutter development. Interviewers want pragmatic tradeoff reasoning.

What They Evaluate
  • Decision framework for platform abstraction vs native
  • Technical judgment
  • Context-dependent reasoning
Answer Framework

STAR format. Describe a feature where Flutter's abstraction wasn't sufficient — camera, complex animation, notifications. Evaluation criteria: existing package coverage, native API quality, maintenance cost of platform channel vs UX cost of Flutter-only solution. Strong answers: a startup might accept Flutter-only with some compromise; a product-led company might invest in native for polish.

Describe a team disagreement about which state management approach to use.
Why They Ask It

State management is the most opinionated Flutter topic. Tests navigating technical disagreements constructively.

What They Evaluate
  • Technical communication
  • Objective tradeoff evaluation
  • Team context awareness
Answer Framework

STAR format. Describe real disagreement — Provider vs Riverpod, Bloc vs simpler approach. Explain positions and valid reasoning behind each. How the team evaluated: prototypes, benchmarks, learning curve, existing expertise. Strongest answers consider team constraints and project needs, not just technical merits.

Walk me through a specific Flutter performance optimization.
Why They Ask It

Performance issues require rendering pipeline understanding. Tests systematic diagnosis and real optimization experience.

What They Evaluate
  • Systematic debugging with DevTools
  • Build vs layout vs paint phase awareness
  • Quantitative before/after metrics
Answer Framework

STAR format. Specific issue — jank during scrolling, slow transitions, memory consumption. Diagnostic process: DevTools to identify expensive rebuilds, missing const constructors, build/layout/paint phase bottleneck. Specific optimization applied and measured improvement. Strong answers: quantitative metrics like 'reduced frame build time from 24ms to 8ms' or 'eliminated 340 unnecessary rebuilds per frame.'

Frequently Asked Questions

How long are Flutter developer interviews in 2026?

Flutter interviews typically run 3-5 rounds over 1-2 weeks: a phone screen (30-45 minutes on Flutter and Dart basics), a technical deep-dive (60 minutes on widget architecture, state management, and platform integration), a live coding round (45-60 minutes building a Flutter widget or feature), a system design round for senior roles, and a behavioral round. Some companies add a take-home project building a small app feature with specific state management and testing requirements.

What's the difference between Flutter and React Native interviews?

Flutter interviews focus on the widget tree, element tree, and rendering pipeline — Flutter draws every pixel using its own engine (Skia/Impeller). State management centers on Riverpod, Bloc, and Provider. Dart language questions (null safety, isolates, Streams) are common. React Native interviews focus on the JavaScript bridge, React lifecycle, and JS/TS. The frameworks have different rendering models so optimization strategies differ significantly.

Should I learn Riverpod or Bloc for Flutter interviews?

Learn both conceptually, go deep on one. Riverpod is increasingly the community standard — type-safe, testable without a widget tree, handles async elegantly. Bloc is widely used in enterprise apps with event-driven architecture. Understanding tradeoffs matters more than mastering every API detail.

How important is Dart knowledge for Flutter interviews?

Very important. Sound null safety, the event loop with Futures and Streams, isolates for CPU-bound work, mixins, and extension methods are all common topics. Expect 25-30% of technical questions to focus on Dart specifically. Candidates who know Flutter's widget API but stumble on Dart fundamentals are at a significant disadvantage.

How do platform channels work and how do I prepare?

Platform channels are Flutter's message-passing bridge between Dart and native code. MethodChannel handles request/response, EventChannel handles native-to-Dart streams, BasicMessageChannel handles bidirectional messaging. Build at least one feature using a MethodChannel — even reading battery level. Understand serialization boundaries and PlatformException error handling. Learn Pigeon for type-safe code generation.

What performance optimization techniques should I know?

Key techniques: const constructors (prevents unnecessary rebuilds), ListView.builder (only builds visible items), RepaintBoundary (isolates expensive paint), selective rebuilds with Riverpod select or Bloc buildWhen, proper keys for list reordering, and MediaQuery.sizeOf for size-only dependencies. Know Flutter DevTools — Widget Rebuild Stats, Performance Overlay, and Memory tab. Being able to discuss a specific issue you diagnosed and fixed is the strongest preparation.

Ready for Your Flutter Developer Interview?

Upload your resume and the job description. Our AI generates Flutter-specific questions covering widget lifecycle, state management, Dart async patterns, and platform integration. Practice with timed responses, live camera for realistic pressure, and AI-powered follow-up questions that adapt to your answers. No video is recorded or stored.

Start Free Practice Interview →

Personalized Flutter developer interview prep. No credit card required.