Flutter面試

Dart語(yǔ)言都是值傳遞,每次調(diào)用函數(shù)都是傳遞對(duì)象的內(nèi)存地址,而不是復(fù)制對(duì)象

優(yōu)點(diǎn):熱重載(Hot Reload)

缺點(diǎn):不支持熱更新,三方庫(kù)有限,需要自己造輪子

Flutter的FrameWork層是用Drat編寫(xiě)的框架(SDK),它實(shí)現(xiàn)了一套基礎(chǔ)庫(kù),組件庫(kù),比Engine上層

Flutter的Engine層是Skia 2D的繪圖引擎庫(kù),跟GPU交互

StatelessWidget: 一旦創(chuàng)建就不關(guān)心任何變化,在下次構(gòu)建之前都不會(huì)改變;

StatefulWidget: 在生命周期內(nèi),該類(lèi)Widget所持有的數(shù)據(jù)可能會(huì)發(fā)生變化,這樣的數(shù)據(jù)被稱(chēng)為State;

1.生命周期:

StatefulWidget ---->? initState? ----->? didChangeDependencies? ----> build (中間會(huì)插入 didUpdateWidget)? ----> deactivate? ---->? dispose


2. 這個(gè)就是Flutter面向?qū)ο?/h4>

繼承 extends? ?混入mixins? 接口實(shí)現(xiàn) implements

優(yōu)先繼承,其次混入,最后接口實(shí)現(xiàn)

mixins不能有構(gòu)造函數(shù),其實(shí)也是單繼承;

抽象類(lèi)abstract:父類(lèi)可以只聲明,不實(shí)現(xiàn);由子類(lèi)去實(shí)現(xiàn);

私有變量加_,其他默認(rèn)公開(kāi)

3.Flutter渲染三棵樹(shù)

WidgetTree:存放渲染內(nèi)容,只是一個(gè)配置數(shù)據(jù)結(jié)構(gòu);

Element:中間層,同時(shí)持有Widget和RenderObject,會(huì)去遍歷視圖樹(shù);

RenderObject:負(fù)責(zé)真正的界面布局和渲染,包含大小和布局等信息,實(shí)例化RenderObject很耗時(shí);

4.Widget分類(lèi)

組合類(lèi):StatefulWidget和StatelessWidget

代理類(lèi):inheritedWidget和parentDataWidget:通過(guò)context獲取共享狀態(tài)

繪制類(lèi):RenderObjectWidget:布局相關(guān)方法調(diào)用順序:layout(準(zhǔn)備布局) --->performResize(計(jì)算大小)? ---> performLayout(開(kāi)始布局) ---> markNeedPaints(是否需要重繪)

5.單訂閱和多訂閱(Stream)

single和broadcast;Stream 默認(rèn)處于單訂閱模式,所以同一個(gè) stream 上的 listen 和其它大多數(shù)方法只能調(diào)用一次,調(diào)用第二次就會(huì)報(bào)錯(cuò)。但 Stream 可以通過(guò) transform() 方法(返回另一個(gè) Stream)進(jìn)行連續(xù)調(diào)用。通過(guò) Stream.asBroadcastStream() 可以將一個(gè)單訂閱模式的 Stream 轉(zhuǎn)換成一個(gè)多訂閱模式的 Stream

6.Widget? ?State? ?Context

Widget:Widget就是可視化組件,里面的結(jié)構(gòu)是樹(shù)狀的,所以說(shuō)是WidgetTree,父Widget和子Widget;

State:是StatefulWidget的實(shí)例化行為,可以交互和干預(yù)Widget的狀態(tài)和布局,任何變更都會(huì)觸發(fā)重建Widget;

Context:每一個(gè)Widget都會(huì)有對(duì)應(yīng)的Widget,用來(lái)描述它的位置引用,是Widget樹(shù)的一部分;

7.Isolate執(zhí)行順序和Future,Stream的區(qū)別

Main(主事件)? --->? ? MicroTask(微事件)? ?---->? EventQueue(事件循環(huán));

最后就在微事件和事件循環(huán)中反復(fù)循環(huán),并且遵循先進(jìn)先出

Isolate實(shí)際是一個(gè)隔離的Dart上下文環(huán)境(容器)。并且不同的Isolate線(xiàn)程之間的通信通過(guò)port來(lái)異步進(jìn)行,在內(nèi)存上是隔離開(kāi)的

耗時(shí)長(zhǎng)的并且影響應(yīng)用流暢性的就用Isolate(比如圖片處理,JSON解析),如果耗時(shí)短的就用Future;

Isolate.spawn() 和Isolate.exit()

Future表示延遲運(yùn)行的對(duì)象,用來(lái)表示一個(gè)潛在的值返回或錯(cuò)誤返回,這個(gè)返回值將在未來(lái)的某個(gè)時(shí)刻才可用。Future的調(diào)用者可以注冊(cè)回調(diào),一旦返回值或錯(cuò)誤可用,就可以通過(guò)回調(diào)函數(shù)對(duì)其進(jìn)行處理。

Future.delayed:創(chuàng)建在延遲一定時(shí)間后運(yùn)行的Future

Future.microtask:創(chuàng)建包含使用scheduleMicrotask異步調(diào)用計(jì)算的結(jié)果的Future

Future.value:創(chuàng)建一個(gè)有值返回的Future

Future.sync:返回包含立即調(diào)用計(jì)算結(jié)果的future


Stream:在Dart中,Stream 和 Future 一樣,都是用來(lái)處理異步編程的工具。它們的區(qū)別在于,Stream 可以接收多個(gè)異步結(jié)果,而Future 只有一個(gè)。多個(gè)是asBroadcastStream()。

await for 如何使用?

await for是不斷獲取stream流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作。它一般用在直到stream什么時(shí)候完成,并且必須等待傳遞完成之后才能使用,不然就會(huì)一直阻塞

8.組件渲染怎么完成的

通過(guò)代碼來(lái)構(gòu)建視圖結(jié)構(gòu)數(shù)據(jù),然后通過(guò)Skia圖像引擎加工成GPU數(shù)據(jù),最后通過(guò)OpenGL提供給GPU渲染

9.PlatformView原理

Platform view 就是 AndroidView 和 UIKitView 的總稱(chēng),允許將native view嵌入到Widget體系中,完成Dart對(duì)native view的控制;

Platform view 是在 native 側(cè)渲染的,并且底層實(shí)際是使用texture實(shí)現(xiàn),通過(guò)_textureId來(lái)展示,所以Platform view開(kāi)銷(xiāo)很大。因?yàn)樾枰獜腉PU切換到CPU,然后再切換到GPU,所以盡量避免使用Platform view;一般使用是webView;

Platform view大小由父節(jié)點(diǎn)的大小來(lái)控制,所以需要用Expanded包裹,不然就是父視圖的大小;


10.Flutter 線(xiàn)程管理模型

線(xiàn)程管理模型:Flutter Engine會(huì)創(chuàng)建一個(gè)isolate,dart代碼運(yùn)行在這個(gè)主isolate上,新創(chuàng)建的isolate由flutter進(jìn)行統(tǒng)一管理。

Flutter的線(xiàn)程管理由一個(gè)叫Embeder的中間層組件控制,Embeder提供了四個(gè)Task,分別是UITaskRunner、IOTaskRunner、GPUTaskRunner、platformTaskRunner

UITaskRunner:負(fù)責(zé)綁定渲染相關(guān)的操作,如timer,microtask,異步io操作;

IOTaskRunner:處理圖片數(shù)據(jù),為gpu渲染做準(zhǔn)備,比如讀取磁盤(pán)壓縮圖片的格式,將解壓成gpu能處理的格式,并傳給gpu,因其比較消耗性能所以單獨(dú)開(kāi)一個(gè)線(xiàn)程。

GPUTaskRunner:用于執(zhí)行g(shù)pu指令,負(fù)責(zé)將layer tree提供的信息轉(zhuǎn)換為平臺(tái)可執(zhí)行的gpu指令

platformTaskRunner:所有接口調(diào)用都使用該接口,長(zhǎng)時(shí)間卡頓將會(huì)被watchdog強(qiáng)殺。


11.Flutter狀態(tài)管理

狀態(tài)管理:

view:界面層,主要是UI

Logic:邏輯層,主要處理業(yè)務(wù)邏輯

State:狀態(tài)層,主要處理頁(yè)面所需數(shù)據(jù)狀態(tài)

Action:行為層,主要處理交互事件

Reducer:這個(gè)層級(jí),是專(zhuān)門(mén)用于處理數(shù)據(jù)變化的

Provider:是最為推薦的狀態(tài)管理庫(kù),對(duì)InheritedWidget進(jìn)行了上層封裝,解決原生setState方案的props臃腫、展示與邏輯耦合問(wèn)題;Provider將頁(yè)面分為業(yè)務(wù)和視圖兩層,并定義Notifier、Consumer兩個(gè)核心概念

Notifier負(fù)責(zé)實(shí)現(xiàn)業(yè)務(wù)邏輯,且在數(shù)據(jù)更新時(shí)發(fā)出通知。

Consumer負(fù)責(zé)實(shí)現(xiàn)界面邏輯,并在數(shù)據(jù)更新時(shí)更新自身,以及用戶(hù)交互時(shí)調(diào)用Notifier方法。

12.Flutter如何與原生Android,iOS進(jìn)行通信

Flutter通過(guò)PlatformChannel與原生進(jìn)行交互,總共有三種:

BasicMessageChannel:傳遞字符串和半結(jié)構(gòu)化信息;

MethodChannel:傳遞方法調(diào)用;一般就是MethodChannel.result;

EventChannel:傳遞數(shù)據(jù)流(event streams);

13.Flutter的熱重載

基于JIT編譯模式的代碼增量同步,總共分為五步:

掃描工程改動(dòng);增量編譯;推送更新;代碼合并;Widget重建;

所以并不會(huì)讓APP重新啟動(dòng),縮短時(shí)間;

14.Flutter布局

Row (行布局)

Column (列布局)

Container (容器)

ListView(類(lèi)似iOS中的UITableView):GlobalKey,通過(guò) key 去獲取到控件對(duì)象的 BuildContext(其實(shí)就是RenderObject);

15.Flutter集成聲網(wǎng)

在initState方法里初始化RtcEngine對(duì)象,通過(guò)initAgoraRtc和addAgoraEventHandlers,和joinChannel;

在回調(diào)中有加入頻道,離開(kāi)頻道,用戶(hù)加入頻道,第一次個(gè)視頻幀渲染回調(diào);

聊天相關(guān)的是單獨(dú)的createClient,通過(guò)AgoraRtmClient來(lái)管理用戶(hù)聊天等相關(guān)信息


-------------------------------------------------------------------------------------------------

Dart相關(guān)

1.Dart是類(lèi)型安全的語(yǔ)言,它會(huì)自動(dòng)做類(lèi)型轉(zhuǎn)換;并且會(huì)有靜態(tài)檢查和運(yùn)行時(shí)檢查;

所以它的維護(hù)性高,編譯器就可以顯示類(lèi)型錯(cuò)誤;

2.類(lèi)型

Number? String? Bool? List? Set? Map? Null

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容