flutter面试题——基础篇(1)

188 阅读4分钟

一、Dart是单线程还是多线程?是如何运行的? Dart本身是单线程模型。 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue 另一个是“事件队列” event queue。

主线程依赖事件循环持续处理任务,工作流程如下:

‌步骤1‌:执行 main() 函数中的同步代码。 ‌步骤2‌:检查并执行 ‌微任务队列(Microtask Queue)‌ 中的所有任务,直到队列清空。 ‌步骤3‌:处理 ‌事件队列(Event Queue)‌ 中的任务(如 I/O 回调、Timer、用户交互事件)。 ‌步骤4‌:重复步骤2和步骤3,直到应用退出。 二、描述一下Flutter的三棵树。 Widget:不可变的UI配置(如Text("Hello"))。

Element:Widget的实例化对象,管理生命周期和树结构。

RenderObject:负责布局和绘制(如尺寸、位置计算)。

三、flutter有几种widget? Flutter的Widget主要分为两种核心类型:

  1. StatelessWidget(无状态组件) ‌不可变性‌:一旦创建后无法更改内部状态,所有属性均为final类型 ‌构建特性‌:通过build()方法返回固定的UI结构,仅在初始化时构建一次 ‌典型场景‌:静态显示内容(如纯文本、图标)、无需响应交互变化的UI元素 ‌代码示例‌: class MyText extends StatelessWidget { final String title; MyText(this.title); // 构造函数接收不可变参数

@override Widget build(BuildContext context) { return Text(title); // 返回固定结构的组件 } } 一、Dart是单线程还是多线程?是如何运行的? Dart本身是单线程模型。 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue 另一个是“事件队列” event queue。

主线程依赖事件循环持续处理任务,工作流程如下:

‌步骤1‌:执行 main() 函数中的同步代码。 ‌步骤2‌:检查并执行 ‌微任务队列(Microtask Queue)‌ 中的所有任务,直到队列清空。 ‌步骤3‌:处理 ‌事件队列(Event Queue)‌ 中的任务(如 I/O 回调、Timer、用户交互事件)。 ‌步骤4‌:重复步骤2和步骤3,直到应用退出。 二、描述一下Flutter的三棵树。 Widget:不可变的UI配置(如Text("Hello"))。

Element:Widget的实例化对象,管理生命周期和树结构。

RenderObject:负责布局和绘制(如尺寸、位置计算)。

三、flutter有几种widget? Flutter的Widget主要分为两种核心类型:

  1. StatelessWidget(无状态组件) ‌不可变性‌:一旦创建后无法更改内部状态,所有属性均为final类型 ‌构建特性‌:通过build()方法返回固定的UI结构,仅在初始化时构建一次 ‌典型场景‌:静态显示内容(如纯文本、图标)、无需响应交互变化的UI元素 ‌代码示例‌: class MyText extends StatelessWidget { final String title; MyText(this.title); // 构造函数接收不可变参数

@override Widget build(BuildContext context) { return Text(title); // 返回固定结构的组件 } } 2. StatefulWidget(有状态组件) ‌状态可变性‌:通过关联的State对象管理动态数据,可调用setState()触发UI更新。 ‌生命周期‌:包含initState()、dispose()等生命周期方法,适合处理资源初始化和释放 ‌典型场景‌:用户交互(如按钮点击)、数据实时更新(如计时器、表单输入) ‌代码示例‌: class Counter extends StatefulWidget { @override _CounterState createState() => _CounterState(); // 创建对应的状态对象 }

class _CounterState extends State { int _count = 0;

void _increment() { setState(() { // 触发UI重绘 _count++; }); }

@override Widget build(BuildContext context) { return ElevatedButton( onPressed: _increment, child: Text('Count: $_count'), ); } } 四、说说几种常用的状态管理。它们之间有什么区别?

Provider:基于InheritedWidget,轻量级,适合中小项目。

Bloc:基于Stream和事件驱动,适合复杂状态逻辑。

Riverpod:Provider的改进版,解决依赖注入问题。

GetX:集成路由、依赖注入,API简洁。

五、说说几种平时常用的Key? 1. GlobalKey:

GlobalKey是所有Key类型中最常用的一个。它允许你访问widget的上下文,这对于需要直接与widget交互(例如获取或设置其状态)的情况非常有用。例如,当你需要在widget树之外访问某个特定widget的状态或调用其方法时,可以使用GlobalKey。

2. LocalKey:

LocalKey是Key的基础类,通常用于不需要跨组件通信的简单场景。例如,当你仅仅需要保持某个widget的重建稳定性时,可以使用LocalKey。

3. ValueKey:

ValueKey是LocalKey的一个具体实现,它接受一个值作为其参数,这个值必须是全局唯一的(即在应用的整个生命周期内唯一),以便于Flutter能够区分不同的widget实例。

4. ObjectKey:

ObjectKey接受一个对象作为其参数,这个对象在整个应用生命周期内应该是唯一的。它通常用于当你想用某个对象的引用作为key时。

5. UniqueKey:

当你需要在运行时动态创建多个具有唯一标识的widget时,可以使用UniqueKey。每次创建UniqueKey实例时,它都会生成一个唯一的标识符。