flutter 面试题指南(一)

1、Dart是什么? 和Flutter是什么关系?

Dart是Google开发的一种面向对象的计算机编程语言,和Java类似
Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台
Dart是flutter的程序开发语言

2. main()和runApp()函数在flutter的作用分别是什么?有什么关系吗?

main函数是类似于java语言的程序运行入口函数
runApp函数是渲染根widget树的函数
一般情况下runApp函数会在main函数里执行

3. 什么是widget? 在flutter里有几种类型的widget?分别有什么区别?能分别说一下生命周期吗?

Widget在flutter里基本是一些UI组件,和
在 Flutter 中,有两类常用的 Widget:

  • 无状态的 StatelessWidget
  • 有状态的 StatefulWidget
    在开发过程中,我们经常需要继承它们两来实现自己的 Widget。
A、无状态的StatelessWidget

如果你的控件一旦显示,就不需要再做任何的变更,那么你应该使用 StatelessWidget。
实现一个自己的 StatelessWidget 很简单。
当你看到下面这个例子时,你就知道它有多简单了。

class PageWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return _buildBody(context);
  }

Widget _buildBody(BuildContext context){
  return Container(
      …
  );
}

B、有状态的StatefulWidget

它可以改变界面的状态,比如显示的文字Text、选中状态CheckBox Switch
我们之所以可以改变状态是因为setState,当调用setState后,就会触发 StatefulWidget 的视图树重建。

setState((){
    // 更新状态、数据
})

因此,当我们需要一个可交互的,即能根据用户操作或数据变化而改变视图的 Widget 时,那就得用上 StatefulWidget 了。

周期

State的生命周期和StatefulWidget不同,当StatefulWidget的状态改变之后就会被重建,但是State不会改变,但是 StatefulWidget在View树中移除再插入又会生成新的State.

StatefulWidget周期

总体介绍一下生命周期,大致可以看成三个阶段:

  • 初始化 (插入渲染树)
  • 状态改变 (在渲染树中存在)
  • 销毁 (从渲染树中移除)

生命周期详解

initState

当插入渲染树的时候调用,这个函数在生命周期中只调用一次. 这里可以做一些初始化的工作,比如初始化State的变量

didChangeDependencies

这个函数会紧跟在initState之后调用,并且可以调用BuildContext.inheritFromWidgetOfExactType, 那么BuildContext.inheritFromWidgetOfExactType的使用场景是什么呢?

 static TabController of(BuildContext context) {
    final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
    return scope?.controller;
  }

实际上就是调用BuildContext.inheritFromWidgetOfExactType,也就是说在didChangeDependencies中,可以跨组件拿到数据

didUpdateWidget

当组件的状态改变的时候就会调用didUpdateWidget, 比如调用setState,
实际flutter框架会创建一个新的Widget绑定State,并在函数中传递老的Widget.
这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整.
需要注意的是涉及到controller的变更,需要在这个函数中移除老的controller的监听,并创建新controller.

deactivate

在dispoes之前,会调用这个函数

dispose

一旦到这个阶段,组件就会被销毁,这个函数一般会移除监听,清理环境

总结

阶段 调用次数
构造函数 1
initState 1
didChangeDependencies >=1
didUpdateWidget >=1
deactivate >=1
dispose 1

各方解释

  • initState: 插入渲染树时调用只调用一次, widget创建执行的第一个方法, 可以再里面初始化一些数据,以及绑定控制器
  • didChangeDependencies: 当State对象的依赖发生变化时被调用
  • build: 它主要用户构建Widget字树的,调用次数:多次,初始化之后开始绘制界面,当调用setState触发的时候会再次被调用
  • deactivate: 当State被暂时从视图树中移除时,会调用这个函数.
    页面切换时也会调用它,因为此时State在视图树中的位置发送了变化,需要先暂时移除后添加
  • dispose: 当State对象从树中被永久移除时调用; 通常在此回调中释放资源.
  • reassemble: 此回调是为了专门开发调试而提供的,在热重载(hot reload)时会被调用, 此回调在Release模式下永远不会被调用

4. Hot Restart 和 Hot Reload 有什么区别吗?

Hot Reload比Hot Restart快,Hot Reload会编译我们文件里新加的代码并发送给dart虚拟机,dart会更新widgets来改变UI,而Hot Restart会让dart 虚拟机重新编译应用。另一方面也是因为这样, Hot Reload会保留之前的state,而Hot Restart回你重置所有的state回到初始值。

5. 在flutter里streams是什么?有几种streams?有什么场景用到它?

Stream 用来处理连续的异步操作,Stream 是一个抽象类,用于表示一序列异步数据的源。它是一种产生连续事件的方式,可以生成数据事件或者错误事件,以及流结束时的完成事件

Stream 分单订阅流和广播流。

网络状态的监控

6. 简单说一下在flutter里async和await?

await的出现会把await之前和之后的代码分为两部分,await并不像字面意思所表示的程序运行到这里就阻塞了,而是立刻结束当前函数的执行并返回一个Future,函数内剩余代码通过调度异步执行。

async是和await搭配使用的,await只在async函数中出现。在async 函数里可以没有await或者有多个await。

7. future 和steam有什么不一样?

Dart异步编程的两个特性FutureStream

在 Flutter 中有两种处理异步操作的方式 Future 和 Stream,Future 用于处理单个异步操作,Stream 用来处理连续的异步操作.

  • Stream

a、Stream 就是事件流或者管道,是一些的异步事件,它会在上一个事件完成时通知你进行下一个事件.
b、Stream无论用什么方式创建,都会以相同的方式返回并使用: asynchronous for loop(await for). 例子:

Future sumStream(Stream stream) async {
    var sum = 0;
    await for (var value int stream) {
        sum += value;
    }
    return sum; 
}

c、Stream 提供 asynchronous序列化的数据.
d、该序列化数据包含了用户生成的时间和重文件中读取的数据.
e、你可以通过await for 的listen()来处理Stream API返回的数据流.
f、Stream 提供了错误相应的处理方法.
g、Streams 有两种方式:single subscription(订阅) 和 broadcast (广播), 下面是两种Streams类型说明:

1、Single subscription streams (单一订阅)

  • 最常见,最基本的streams实现方式
  • 它的数据大部分是sequence of events. 单一订阅必须以正确的顺序交付事件,并且中间不能有任何异常
  • 这是当你在读取文件或者接受网络请求的时候产生的stream.
  • 这样的流不具备幂等性,再次接收可能会不同于上次的请求
  • 当你开始监听, 数据将被提取并以块的形式提供

2、Broadcast streams (广播)

  • 适用于可以一次处理一个的单个消息, 例如:这种流可用于浏览器中的鼠标事件.
  • 可以随时监听开始监听这样的流, 并且再收听时会触发事件
  • 多个收听者可以同时收听, 也可以取消上一个订阅后再次收听
  • Future

8. 什么是flutter里的key? 有什么用?

key是Widgets,Elements和SemanticsNodes的标识符。

key有LocalKey 和 GlobalKey两种。

LocalKey 如果要修改集合中的控件的顺序或数量。GlobalKey允许 Widget 在应用中的任何位置更改父级而不会丢失 State。

9. 在什么场景下使用profile mode?

profile model 是用来评估app性能的,profile model 和release mode是相似的,只有保留了一些需要评估app性能的debug功能。在模拟器上profile model是不可用的。

10. 怎么做到只在debug mode运行代码?

foundation有一个静态的变量kReleaseMode来表示是否是release mode

11. 怎么理解Isolate?

isolate是Dart对actor并发模式的实现。 isolate是有自己的内存和单线程控制的运行实体。isolate本身的意思是“隔离”,因为isolate之间的内存在逻辑上是隔离的。isolate中的代码是按顺序执行的,任何Dart程序的并发都是运行多个isolate的结果。因为Dart没有共享内存的并发,没有竞争的可能性所以不需要锁,也就不用担心死锁的问题

12. 列举在flutter的状态管理方案?

  • Scoped Model
  • Redux
  • BLoC
  • RxDart
  • provider

你可能感兴趣的:(flutter 面试题指南(一))