iOS面试题
Flutter 的面试其实和 Android 面试的套路差不多,也是分两个部分:
1.Dart
2.Flutter
毕竟 Flutter 要使用 Dart 来写,那也就必须了解 Dart 的一些相关知识点。
Dart 相关面试题
1. Dart 当中的 「..」表示什么意思?**
Dart 当中的 「..」意思是 「级联操作符」,为了方便配置而使用。
「..」和「.」不同的是 调用「..」后返回的相当于是 this,而「.」返回的则是该方法返回的值 。
2. Dart 的作用域**
Dart 没有 「public」「private」等关键字,默认就是公开的,私有变量使用 下划线 _
开头。
3. Dart 是不是单线程模型?是如何运行的?**
Dart 是单线程模型,如何运行的看这张图:
引用《Flutter中文网》里的话:
Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。
入口函数 main() 执行完后,消息循环机制便启动了。首先会按照先进先出的顺序逐个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。
4. Dart 多任务如何并行的?**
刚才也说了,既然 Dart 不存在多线程,那如何进行多任务并行?
Dart 当中提供了一个 类似于新线程,但是不共享内存的独立运行的 worker - isolate。
那他们是如何交互的?
这里引用 flutter入门之dart中的并发编程、异步和事件驱动详解[1] 中的一部分答案:
在dart中,一个Isolate对象其实就是一个isolate执行环境的引用,一般来说我们都是通过当前的isolate去控制其他的isolate完成彼此之间的交互,而当我们想要创建一个新的Isolate可以使用Isolate.spawn方法获取返回的一个新的isolate对象,两个isolate之间使用SendPort相互发送消息,而isolate中也存在了一个与之对应的ReceivePort接受消息用来处理,但是我们需要注意的是,ReceivePort和SendPort在每个isolate都有一对,只有同一个isolate中的ReceivePort才能接受到当前类的SendPort发送的消息并且处理。
5. 说一下 Future?**
Future,字面意思「未来」,是用来处理异步的工具。
刚才也说过:
Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。
Future 默认情况下其实就是往「事件队列」里插入一个事件,当有空余时间的时候就去执行,当执行完毕后会回调 Future.then(v)
方法。
而我们也可以通过使用 Future.microtask
方法来向 「微任务队列」中插入一个任务,这样就会提高他执行的效率。
因为在 Dart 每一个 isolate 当中,执行优先级为 :Main > MicroTask > EventQueue
6. 说一下 Stream?**
Stream 和 Feature 一样,都是用来处理异步的工具。
但是 Stream 和 Feature 不同的地方是 Stream 可以接收多个异步结果,而Feature 只有一个。
Stream 的创建可以使用 Stream.fromFuture
,也可以使用 StreamController
来创建和控制。
还有一个注意点是:普通的 Stream 只可以有一个订阅者,如果想要多订阅的话,要使用 asBroadcastStream()
。
7. 说一下 mixin?**
关于什么是 mixin,引用 张风捷特烈 文章[2]中的:
首先mixin是一个定义类的关键字。直译出来是混入,混合的意思 Dart为了支持多重继承,引入了mixin关键字,它最大的特殊处在于:
mixin定义的类不能有构造方法
,这样可以避免继承多个类而产生的父类构造方法冲突
Flutter 相关面试题
1. StatefulWidget 的生命周期**
•initState()
:Widget 初始化当前 State,在当前方法中是不能获取到 Context 的,如想获取,可以试试 Future.delayed()
•didChangeDependencies()
:在 initState()
后调用,State
对象依赖关系发生变化的时候也会调用。•deactivate()
:当 State
被暂时从视图树中移除时会调用这个方法,页面切换时也会调用该方法,和Android里的 onPause
差不多。•dispose()
:Widget 销毁时调用。•didUpdateWidget
:Widget 状态发生变化的时候调用。
借用 CoorChice 文章[3] 里的一张图:
2. Flutter 如何与 Android iOS 通信?**
Flutter 通过 PlatformChannel
与原生进行交互,其中 PlatformChannel
分为三种:
1.BasicMessageChannel:用于传递字符串和半结构化的信息。2.MethodChannel:用于传递方法调用。Flutter主动调用Native的方法,并获取相应的返回值。3.EventChannel:用于数据流(event streams)的通信。
具体可以查看 闲鱼技术:深入理解 Flutter Platform Channel[4]。
3. 什么是 Widgets、RenderObjects 和 Elements?**
•Widget
仅用于存储渲染所需要的信息。•RenderObject
负责管理布局、绘制等操作。•Element
才是这颗巨大的控件树上的实体。
具体可以查看 [译] Flutter,什么是 Widgets、RenderObjects 和 Elements?[5]
4. 说一下什么是状态管理,为什么需要它?**
首先状态其实是一个概念上的东西,区分全局状态和局部状态。
局部状态比如说一个控件中输入的信息,全局状态比如是登陆后从后台请求回来的 userId。
当全局状态越来越多,多个页面共享一个状态时,我们就需要管理它。
常用的状态管理有:
•ScopedModel•BLoC•Redux / FishRedux•Provider
5. 说一下 BLoC 模式?**
具体可以查看: Vadaski - Flutter | 状态管理探索篇——BLoC(三)[6]
这里引用一部分:
BLoC是一种利用reactive programming方式构建应用的方法,这是一个由流构成的完全异步的世界。
6. 如何统一管理错误页面?**
我们都知道,如果在 Flutter 当中出错的话,那就是一片红。
可以使用 ErrorWidget.builder
来自定义一个 Widget 就 ok 了。
总结
暂时就写到这,写了这么多,自己对 Flutter & Dart 的基础认识也更深了,也欢迎各路大佬交流。
另外我个人创建了一个iOS交流群欢迎各位的加入,群里有免费的录播和面试资料。
原文