Flutter 面试题及答案

2025年3月17日 | 阅读16分钟
Flutter Interview Questions

以下是一些经常被问到的 Flutter 面试题 及答案。

1) Flutter 是什么?

Flutter 是一个 UI 工具包,可以使用一种编程语言和单一的代码库,快速创建精美、原生编译的移动应用程序。它是由 Google 开发的开源开发框架。通常,Flutter 不是一种语言,而是一个 SDK。Flutter 应用使用 Dart 编程语言来创建应用。Flutter 的第一个 alpha 版本发布于 2017 年 5 月。

Flutter 主要针对可以在 Android 和 iOS 平台运行的 2D 移动应用进行了优化。我们还可以使用它来构建功能齐全的应用,包括相机、存储、地理定位、网络、第三方 SDK 等。

要阅读更多信息,请点击这里


2) Dart 是什么?

Dart 是一种通用的、面向对象的编程语言,具有 C 风格的语法。它是由 Google 于 2011 年开发并开源的。Dart 编程的目的是为 Web 和移动应用创建前端用户界面。它是创建 Flutter 应用的重要语言。Dart 语言可以进行 AOT(Ahead-of-Time)和 JIT(Just-in-Time)编译。

要阅读更多信息,请点击这里


3) 我应该为 Flutter 学习 Dart 吗?

是的,学习 Dart 语言对于构建 Flutter 应用程序来说非常必要。


4) Flutter 是免费的吗?

是的。Flutter 是免费且开源的。


5) 什么是 Flutter 的 Widget?

Flutter 应用始终被视为一个 Widget 树。每当你编写代码来构建 Flutter 中的任何内容时,它都会在一个 Widget 中。Widget 根据其当前配置和状态描述你的应用视图应该是什么样子。当你对代码进行任何更改时,Widget 会通过计算先前和当前 Widget 的差异来重建其描述,以确定渲染应用 UI 的最小更改。

Widgets 相互嵌套以构建应用。这意味着你的应用的根本身就是一个 Widget,一直向下也都是 Widget。例如,一个 Widget 可以显示内容,可以定义样式,可以处理交互等。

要阅读更多信息,请点击这里


6) 你如何理解有状态 Widget 和无状态 Widget?

有状态 Widget 包含状态信息。它被认为是动态的,因为它可以在 Widget 的生命周期内更改内部数据。允许我们刷新屏幕的 Widget 称为有状态 Widget。这个 Widget 没有 build() 方法。它有一个 createState() 方法,该方法返回一个扩展了 Flutter 状态类的类。有状态 Widget 的例子有 Checkbox、Radio、Slider、InkWell、Form 和 TextField。

无状态 Widget 没有状态信息。它在其生命周期内保持静态。无状态 Widget 的例子有 Text、Row、Column、Container 等。如果屏幕或 Widget 包含静态内容,它应该是一个无状态 Widget,但如果你想更改内容,它需要是一个有状态 Widget。


7) Flutter 开发最好的编辑器是什么?

Flutter 开发工具可以加快 Flutter 开发速度,从而提高开发者的工作流程。Flutter IDE 和工具需要一些插件来开发移动应用程序。插件帮助我们进行 Dart 编译、代码分析和 Flutter 开发。流行的 Flutter 开发 IDE 如下:

  • Android Studio
  • Visual Studio
  • IntelliJ IDEA
  • Xcode

要阅读更多信息,请点击这里


8) pubspec.yaml 文件是什么?

这是在使用 Flutter 项目时会大量使用的项目的配置文件。它允许你了解应用程序如何工作。它还允许我们为应用程序设置约束。此文件包含:

  • 项目常规设置,如项目的名称、描述和版本。
  • 项目依赖项。
  • 项目资源(例如,图像、音频等)。

9) Flutter 中的包(packages)和插件(plugins)是什么?

包是一组相似类型的类、接口和子包。包和插件帮助我们构建应用,而无需从头开发所有内容。在 Flutter 中,它允许你将新的 Widget 或功能导入到应用中。包和插件之间有很小的区别。通常,包是新组件或用 Dart 语言编写的代码,而插件通过使用原生代码在设备上提供更多功能。在 DartPub 中,包和插件都被称为包。

要阅读更多信息,请点击这里


10) Flutter 有哪些优点?

Flutter 框架流行的优点如下:

  • 跨平台开发:此功能允许 Flutter 一次编写代码,维护一次,并在不同平台上运行。它为开发者节省了时间、精力和金钱。
  • 更快的开发:Flutter 应用的性能很快。Flutter 使用 arm C/C++ 库编译应用程序,使其更接近机器码,并为应用提供更好的原生性能。
  • 良好的社区:Flutter 拥有良好的社区支持,开发者可以在这里快速提出问题并得到答案。
  • 热重载和热重启:它使应用程序开发过程极其快速。此功能允许我们在进行更改后立即看到代码更改或更新。
  • 最小代码:Flutter 应用由 Dart 编程语言开发,该语言使用 JIT 和 AOT 编译来提高整体启动时间、功能并加速性能。JIT 增强了开发系统,并在无需额外构建新 UI 的情况下刷新 UI。
  • UI 焦点:它拥有出色的用户界面,因为它使用了以设计为中心的 Widget、高级开发工具、高级 API 等诸多功能。
  • 文档:Flutter 拥有非常好的文档支持。它组织有序且信息丰富。我们可以在一个地方找到我们想要的所有内容。

要阅读更多信息,请点击这里


11) 如何安装 Flutter?

要在 Windows 系统上安装和运行 Flutter,你需要首先满足开发环境的这些要求。

操作系统Windows 7 或更高版本(我使用的是 Windows 10。你也可以使用 Mac 或 Linux 操作系统)。
磁盘空间400 MB(不包括 IDE/工具的磁盘空间)。
工具1. Windows PowerShell
2. Git for Windows 2.x(在此处,选择“Use Git from Windows Command Prompt”选项)。
SDKWindows 版 Flutter SDK
IDEAndroid Studio (官方)

要阅读更多信息,请点击这里


12) Flutter 和 React Native 哪个更好?

Flutter 和 React Native 都用于从单一代码库开发原生混合应用。这些应用可以在 iOS 和 Android 平台运行。

React Native 由 Facebook 开发,而 Flutter 框架最初由 Google 推出。因此,这两个框架都拥有非常好的功能和社区。

Flutter 使用 Dart 语言创建应用,而 React Native 使用 JavaScript 构建应用。

从开发者的角度来看,在它们之间做出选择非常困难。因此,在 Flutter 和 React Native 之间选择一个赢家是非常具有挑战性的。

要阅读更多信息,请点击这里


13) 为什么第一个 Flutter 应用构建需要很长时间?

当你第一次构建 Flutter 应用时,需要花费更长的时间。这是因为 Flutter 构建了特定于设备的 APK 或 IPA 文件。因此,Gradle 和 Xcode 用于构建文件,这需要很长时间。


14) 为什么 Flutter 项目中有 Android 和 iOS 文件夹?

Android:此文件夹包含一个完整的 Android 项目。当你为 Android 创建 Flutter 应用程序时使用它。当 Flutter 代码编译为原生代码时,它将被注入到这个 Android 项目中,因此结果是一个原生的 Android 应用程序。例如:当你使用 Android 模拟器时,此 Android 项目用于构建 Android 应用,然后部署到 Android 虚拟设备。

iOS:此文件夹包含一个完整的 Mac 项目。当你为 iOS 构建 Flutter 应用程序时使用它。它类似于开发 Android 应用时使用的 Android 文件夹。当 Flutter 代码编译为原生代码时,它将被注入到这个 iOS 项目中,因此结果是一个原生的 iOS 应用程序。只有当你使用 macOS 和 Xcode IDE 时,才能构建 iOS 版的 Flutter 应用程序。


15) 什么是 Tween Animation(补间动画)?

它是 in-betweening 的缩写。在补间动画中,需要定义动画的开始和结束点。这意味着动画从起始值开始,然后经过一系列中间值,最后达到结束值。它还提供时间线和曲线,定义过渡的时间和速度。Widget 框架提供了如何从起点和终点过渡的计算。

要阅读更多信息,请点击这里


16) 解释 Flutter 中的热重载(Hot Reload)?

热重载功能使你能够快速轻松地在项目中进行实验。它有助于构建 UI、添加新功能、修复错误并加快应用开发速度。要对 Flutter 应用执行热重载,请执行以下步骤:

  • 在支持的 Flutter 编辑器或终端窗口中运行应用。
  • 修改项目中的任何 Dart 文件。
  • 如果你使用的是支持 Flutter 的 IDE,则选择“保存全部”或单击工具栏上的“热重载”按钮。你将立即在模拟器或真实设备上看到结果。

17) 列举一些使用 Flutter 的流行应用?

如今,许多组织使用 Flutter 来构建应用。一些最流行的 Flutter 应用如下:

  • Google Ads
  • Reflectly
  • 阿里巴巴
  • Birch Finance
  • Coach Yourself
  • Tencent
  • Watermaniac

18) Flutter SDK 的最新版本是什么?

Flutter 框架的最新版本是 Flutter- v1.20.4,发布于 2020 年 9 月 15 日。


19) 列举 Flutter 中常用的数据库包?

Flutter 中最常用和最流行的数据库包如下:

  • sqflite 数据库:它允许访问和操作 SQLite 数据库。
  • Firebase 数据库:它将使你能够访问和操作云数据库。

20) 哪种类型的动画可以让你表示现实世界的行为?

基于物理的动画(Physics-based animation)允许你在 Flutter 中表示现实世界的行为。


21) 热重启(Hot Restart)和热重载(Hot Reload)有什么区别?

以下是热重启和热重载之间的重要区别:

热重载热重启
它在终端或命令提示符中使用小写 r 键来工作。它主要处理状态值。
热重载功能允许我们快速编译文件中新添加的代码,并将它们发送到 Dart 虚拟机 (DVM)。DVM 完成更新后,它会立即更新应用的 UI。它允许开发者获得一个完全编译的应用,因为它会销毁并重置状态值到其默认值。每次热重启时,我们的应用 Widget 树都会使用新输入的代码完全重建。
它有助于构建 UI、添加新功能、修复错误并加快应用开发速度。它比热重载需要更多时间来编译和更新应用。

22) 在下面的代码片段中,使用“胖箭头”(fat arrow)语法将 makeMangoShake() 转换为名为 mangoshake 的 getter。

当方法只包含一行代码时,可以使用胖箭头 (=>)。我们可以使用以下语法:

需要注意的是,我们不能在胖箭头 (=>) 中使用 return 关键字。将 makeMangoShake() 转换为胖箭头后,它将如下面的代码所示:


23) Flutter 中的 "main()" 和 "runApp()" 函数有什么区别?

我们可以通过以下方式区分 Flutter 中的 main 和 runApp 函数:

  • main() 函数负责启动程序。没有 main() 函数,我们就无法在 Flutter 中编写任何程序。
  • runApp() 函数负责返回附加到屏幕上的 Widget,作为 Widget 树的根,并将渲染到屏幕上。

24) 何时应使用 mainAxisAlignment 和 crossAxisAlignment?

我们可以使用 crossAxisAlignment 和 mainAxisAlignment 来根据我们的选择控制 Row 和 Column Widget 如何对其子 Widget 进行对齐。

Row 的交叉轴(cross-axis)将垂直运行,主轴(main axis)将水平运行。请参阅下面的可视化表示以更清楚地理解它。

Flutter Interview Questions

Column 的交叉轴将水平运行,主轴将垂直运行。下面的可视化表示更清楚地解释了这一点。

Flutter Interview Questions

要阅读更多信息,请点击这里


25) SizedBox 与 Container 有什么区别?

Flutter 中的 Container 是一个父 Widget,它可以包含多个子 Widget,并通过宽度、高度、内边距、背景色等对其进行高效管理。如果我们需要一个需要一些背景样式(可能是颜色、形状或尺寸约束)的 Widget,我们可以将其包装在 Container Widget 中。

Flutter 中的 SizedBox Widget 是一个具有指定尺寸的盒子。与 Container 不同,它不允许我们为 Widget 设置颜色或装饰。我们只能使用它来调整作为子 Widget 的 Widget 的大小。这意味着它强制其子 Widget 具有特定的宽度或高度。

要阅读更多信息,请点击这里


26) Flutter 中的 Stream 是什么?

Stream 是一系列异步事件。它提供了一个异步数据序列。它就像一个管道,我们在管道的一端放入一个值,如果在另一端有监听器,它就会接收到该值。我们可以有多个监听器订阅一个 Stream,并且当数据被放入管道时,所有监听器都会接收到相同的值。

我们可以使用 await for 或 Stream API 的 listen() 方法来处理 Stream。它有一种响应错误的方式。我们可以通过多种方式创建 Stream,但它们的使用方式相同。请看下面的示例:


27) 解释不同类型的 Stream?

Stream 有两种类型,它们是:

单订阅流 (Single subscription streams)

这是最常见的流类型,包含一系列事件,这些事件是一个更大整体的一部分。它将按正确的顺序传递事件,不会遗漏任何一个。如果遗漏了任何一个事件,那么其余的流就没有意义了。这种流主要用于读取文件或接收 Web 请求。它只会监听一次,如果再次监听,则意味着遗漏了初始事件。当它开始监听时,数据将以块的形式获取并提供。

广播流 (Broadcast streams)

这是一种用于单个消息的流类型,可以一次处理,而无需了解之前的事件。它可以有多个监听器同时监听,并且我们可以在取消之前的订阅后再次监听。浏览器中的鼠标事件就是这种流的一种。


28) 为什么 build() 方法在 State 而不是 StatefulWidget 上?

主要原因是 StatefulWidget 使用一个单独的 State 类,而没有在其主体内创建 build 方法。这意味着 Widget 中的所有字段都是不可变的,包括其所有子类。

另一方面,StatelessWidget 将其 build 方法和相关方法放在其主体内部。这是由于 StatelessWidget 的性质,它完全根据提供的信息在屏幕上渲染。它也不允许对其状态信息进行任何未来的更改。

StatefulWidget 允许我们在应用过程中更改状态信息。因此,为了满足 Widget 类中所有字段都不可变的条件,不适合将其存储在 build 方法中。这是引入 State 类的主要原因。在这里,我们只需要重写 createState() 函数来将定义的 State 附加到 StatefulWidget,然后在单独的类中发生所有预期的更改。


29) Flutter 有哪些不同的构建模式?

Flutter 工具支持在编译应用程序时使用三种模式。这些编译模式可以根据我们所处的开发周期阶段来选择。模式的名称是:

  • 调试
  • Profile
  • Release

30) 解释 "??" 和 "?" 操作符的区别。

?? 操作符? 操作符
?? 操作符用于评估并返回两个表达式之间的值。它可以使用如下:
expr1 ?? expr2
此操作符首先检查表达式 1,如果它不为 null,则返回其值;否则,它将评估并返回表达式 2 的值。
? 操作符用于根据给定条件评估并返回两个表达式之间的值。它可以使用如下:
condition ? expr1 : expr2
此操作符首先检查条件,如果条件为 true,则评估 expr1 并返回其值(如果条件匹配)。否则,它评估并返回 expr2 的值。

31) 为什么我们需要 Mixins?

Dart 不支持多重继承。因此,要在 Flutter/Dart 中实现多重继承,我们需要 Mixins。Mixins 提供了一种在多个类层次结构中编写可重用类代码的方法。


32) 为什么我们在 Flutter 中使用 Ticker?

Flutter 中的 Ticker 是我们动画的刷新速率。它是一个类,以规则的间隔发送信号,即每秒大约 60 次。我们可以通过我们的手表来理解它,手表以规则的间隔发出滴答声。每次滴答时,Ticker 会提供一个回调方法,该方法包含自第一次滴答以来每秒的时间,在它启动之后。即使 Ticker 在不同的时间启动,它也会自动同步。


33) Flutter 中的 Keys 是什么,何时使用?

  • Keys 在 Flutter 中用作 Widget、Element 和 SemanticsNode 的标识符。当新 Widget 尝试更新现有 Element 时,我们可以使用它;然后,它的 Key 应该与与 Element 相关联的当前 Widget Key 相同。
  • 在同一父元素内的 Element 之间,Keys 不应不同。
  • Key 的子类必须是 GlobalKey 或 LocalKey。
  • 当我们在处理同一类型且带有状态的 Widget 集合(例如添加、删除或重新排序)时,Keys 非常有用。

34) 如何仅在调试模式下执行代码?

要仅在调试模式下执行代码,我们需要先导入 `dart:foundation`,如下所示:

接下来,我们需要使用 `kReleaseMode`,如下所示:


35) 什么是 Profile 模式,何时使用?

Profile 模式用于测量我们应用程序的性能。在此模式下,会保留一些调试功能来分析您的应用性能。此模式在模拟器和仿真器上禁用,因为它们不能代表真实性能。

我们可以使用以下命令来编译 Profile 模式:


36) 什么是 Release 模式,何时使用?

Release 模式允许我们优化代码并生成完全优化的代码,没有任何调试数据。在此模式下,应用程序的许多代码将被完全删除或重写。

当我们准备发布应用时,会使用此模式。它实现了最大程度的优化和最小的应用占用空间。

我们可以使用以下命令来编译 Release 模式:


37) WidgetsApp 和 MaterialApp 有什么区别?

下面的比较表解释了 WidgetsApp 和 MaterialApp 之间的基本区别:

WidgetsAppMaterialApp
WidgetsApp 用于基本导航。它包含许多基础 Widget 以及 Flutter 用来创建我们应用程序 UI 的 Widget 库。MaterialApp 连同 Material 库,是构建在 WidgetsApp 及其库之上的一个层。它实现了 Material Design,为我们在任何平台上运行的应用提供统一的外观和感觉。
WidgetsApp 类是 MaterialApp 类的基类。它提供了许多用于开发应用程序的有趣工具,如 Navigator 或 Theme。
它封装了构建应用程序所需的多个 Widget。它封装了构建 Material Design 应用程序所需的多个 Widget。

38) 什么是 BuildContext?

Flutter 中的 BuildContext 是 Element 树中 Widget 的一部分,因此每个 Widget 都有自己的 BuildContext。我们主要使用它来引用另一个 Widget 或主题。例如,如果我们想使用 Material Design 元素,就需要将其引用到 Scaffold。我们可以使用 Scaffold.of(context) 方法获取它。


39) Flutter 中可以执行哪些类型的测试?

测试是用于验证和确认应用程序无 bug 且符合用户需求的一项活动。通常,我们在 Flutter 中可以使用这三种类型的测试:

单元测试:它测试单个函数、方法或类。其目标是确保代码在各种条件下的正确性。此测试用于检查我们业务逻辑的有效性。

Widget 测试:它测试单个 Widget。其目标是确保 Widget 的 UI 看起来和与其他 Widget 的交互符合预期。

集成测试:它验证整个应用或应用的大部分。其目标是确保所有 Widget 和服务都能按预期协同工作。

Flutter 还提供了一种额外的测试,称为 Golden 测试。其目标是确保你有一个 Widget 或屏幕的图像,并检查实际 Widget 是否与之匹配。

要阅读更多信息,请点击这里


40) 什么是 Null-aware 操作符?

Dart 提供了一些有用的信息来处理 null 值。

1. ??= 赋值操作符,仅当变量为 null 时才为其赋值。

2. ?? Null-aware 操作符,用于评估并返回两个表达式之间的值。它首先检查表达式 1,如果它不为 null,则返回其值;否则,它将评估并返回表达式 2 的值。