Flutter是Google推出的一套開源跨平臺UI框架,能夠快速地在Android、iOS和Web平臺上構建高質量的原生用戶界面。在過去的一年裏,Flutter的更新頻率是至關的快,也有不少的公司開始使用它來進行跨平臺應用開發,能夠說,將Flutter稱爲2019年最流行的跨平臺技術也不爲過。前端
在研究了Hybrid APP、React Native和Weex等技術以後,爲在今年的早些時候也入了Flutter的坑。總的來講,無論是從社羣和社區的活躍來看,仍是從技術的水準上來看,Flutter無疑是最優秀的,特別是Google將Flutter列爲重點推廣項目以後,全世界掀起了一股學習Flutter的熱潮。面試
在國內,除了阿里、騰訊、美團等大廠外,國內不少的中小團隊也開始使用Flutter來做爲移動應用開發的首選,而且不少公司在移動招聘方面也要求具備Flutter開發的背景。Flutter 的面試題主要分爲兩個Dart和Flutter部分,下面是一些常見的面試題。編程
1. Dart 當中的 「..」表示什麼意思?
Dart 當中的 「..」意思是 「級聯操做符」,爲了方便配置而使用。「..」和「.」不一樣的是 調用「..」後返回的至關因而 this,而「.」返回的則是該方法返回的值 。安全
2. Dart 的做用域
Dart 沒有 「public」「private」等關鍵字,默認就是公開的,私有變量使用 下劃線 _開頭。網絡
3. Dart 是否是單線程模型?是如何運行的?
Dart 是單線程模型,運行的的流程以下圖。
簡單來講,Dart 在單線程中是以消息循環機制來運行的,包含兩個任務隊列,一個是「微任務隊列」 microtask queue,另外一個叫作「事件隊列」 event queue。數據結構
當Flutter應用啓動後,消息循環機制便啓動了。首先會按照先進先出的順序逐個執行微任務隊列中的任務,當全部微任務隊列執行完後便開始執行事件隊列中的任務,事件任務執行完畢後再去執行微任務,如此循環往復,生生不息。多線程
4. Dart 是如何實現多任務並行的?
前面說過, Dart 是單線程的,不存在多線程,那如何進行多任務並行的呢?其實,Dart的多線程和前端的多線程有不少的類似之處。Flutter的多線程主要依賴Dart的併發編程、異步和事件驅動機制。
簡單的說,在Dart中,一個Isolate對象其實就是一個isolate執行環境的引用,通常來講咱們都是經過當前的isolate去控制其餘的isolate完成彼此之間的交互,而當咱們想要建立一個新的Isolate可使用Isolate.spawn方法獲取返回的一個新的isolate對象,兩個isolate之間使用SendPort相互發送消息,而isolate中也存在了一個與之對應的ReceivePort接受消息用來處理,可是咱們須要注意的是,ReceivePort和SendPort在每一個isolate都有一對,只有同一個isolate中的ReceivePort才能接受到當前類的SendPort發送的消息而且處理。架構
5. 說一下Dart異步編程中的 Future關鍵字?
前面說過,Dart 在單線程中是以消息循環機制來運行的,其中包含兩個任務隊列,一個是「微任務隊列」 microtask queue,另外一個叫作「事件隊列」 event queue。併發
在Java併發編程開發中,常常會使用Future來處理異步或者延遲處理任務等操做。而在Dart中,執行一個異步任務一樣也可使用Future來處理。在 Dart 的每個 Isolate 當中,執行的優先級爲 : Main > MicroTask > EventQueue。框架
6. 說一下Dart異步編程中的 Stream數據流?
在Dart中,Stream 和 Future 同樣,都是用來處理異步編程的工具。它們的區別在於,Stream 能夠接收多個異步結果,而Future 只有一個。
Stream 的建立可使用 Stream.fromFuture,也可使用 StreamController 來建立和控制。還有一個注意點是:普通的 Stream 只能夠有一個訂閱者,若是想要多訂閱的話,要使用 asBroadcastStream()。
7. Stream 有哪兩種訂閱模式?分別是怎麼調用的?
Stream有兩種訂閱模式:單訂閱(single) 和 多訂閱(broadcast)。單訂閱就是隻能有一個訂閱者,而廣播是能夠有多個訂閱者。這就有點相似於消息服務(Message Service)的處理模式。單訂閱相似於點對點,在訂閱者出現以前會持有數據,在訂閱者出現以後就才轉交給它。而廣播相似於發佈訂閱模式,能夠同時有多個訂閱者,當有數據時就會傳遞給全部的訂閱者,而無論當前是否已有訂閱者存在。
Stream 默認處於單訂閱模式,因此同一個 stream 上的 listen 和其它大多數方法只能調用一次,調用第二次就會報錯。但 Stream 能夠經過 transform() 方法(返回另外一個 Stream)進行連續調用。經過 Stream.asBroadcastStream() 能夠將一個單訂閱模式的 Stream 轉換成一個多訂閱模式的 Stream,isBroadcast 屬性能夠判斷當前 Stream 所處的模式。
8. await for 如何使用?
await for是不斷獲取stream流中的數據,而後執行循環體中的操做。它通常用在直到stream何時完成,而且必須等待傳遞完成以後才能使用,否則就會一直阻塞。
Stream<String> stream = new Stream<String>.fromIterable(['不開心', '面試', '沒', '過']); main() async{ await for(String s in stream){ print(s); } }
9. 說一下 mixin機制?
mixin 是Dart 2.1 加入的特性,之前版本一般使用abstract class代替。簡單來講,mixin是爲了解決繼承方面的問題而引入的機制,Dart爲了支持多重繼承,引入了mixin關鍵字,它最大的特殊處在於: mixin定義的類不能有構造方法,這樣能夠避免繼承多個類而產生的父類構造方法衝突。
mixins的對象是類,mixins毫不是繼承,也不是接口,而是一種全新的特性,能夠mixins多個類,mixins的使用須要知足必定條件。
1. 請簡單介紹下Flutter框架,以及它的優缺點?
Flutter是Google推出的一套開源跨平臺UI框架,能夠快速地在Android、iOS和Web平臺上構建高質量的原生用戶界面。同時,Flutter仍是Google新研發的Fuchsia操做系統的默認開發套件。在全世界,Flutter正在被愈來愈多的開發者和組織使用,而且Flutter是徹底免費、開源的。Flutter採用現代響應式框架構建,其中心思想是使用組件來構建應用的UI。當組件的狀態發生改變時,組件會重構它的描述,Flutter會對比以前的描述,以肯定底層渲染樹從當前狀態轉換到下一個狀態所須要的最小更改。
優勢
缺點
2. 介紹下Flutter的理念架構
其實也就是下面這張圖。
由上圖可知,Flutter框架自下而上分爲Embedder、Engine和Framework三層。其中,Embedder是操做系統適配層,實現了渲染 Surface設置,線程設置,以及平臺插件等平臺相關特性的適配;Engine層負責圖形繪製、文字排版和提供Dart運行時,Engine層具備獨立虛擬機,正是因爲它的存在,Flutter程序才能運行在不一樣的平臺上,實現跨平臺運行;Framework層則是使用Dart編寫的一套基礎視圖庫,包含了動畫、圖形繪製和手勢識別等功能,是使用頻率最高的一層。
3. 介紹下FFlutter的FrameWork層和Engine層,以及它們的做用
Flutter的FrameWork層是用Drat編寫的框架(SDK),它實現了一套基礎庫,包含Material(Android風格UI)和Cupertino(iOS風格)的UI界面,下面是通用的Widgets(組件),以後是一些動畫、繪製、渲染、手勢庫等。這個純 Dart實現的 SDK被封裝爲了一個叫做 dart:ui的 Dart庫。咱們在使用 Flutter寫 App的時候,直接導入這個庫便可使用組件等功能。
Flutter的Engine層是Skia 2D的繪圖引擎庫,其前身是一個向量繪圖軟件,Chrome和 Android均採用 Skia做爲繪圖引擎。Skia提供了很是友好的 API,而且在圖形轉換、文字渲染、位圖渲染方面都提供了友好、高效的表現。Skia是跨平臺的,因此能夠被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS閉源的 Core Graphics / Core Animation。Android自帶了 Skia,因此 Flutter Android SDK要比 iOS SDK小不少。
4. 介紹下Widget、State、Context 概念
5. 簡述Widget的StatelessWidget和StatefulWidget兩種狀態組件類
6. StatefulWidget 的生命週期
Flutter的Widget分爲StatelessWidget和StatefulWidget兩種。其中,StatelessWidget是無狀態的,StatefulWidget是有狀態的,所以實際使用時,更多的是StatefulWidget。StatefulWidget的生命週期以下圖。
7. 簡述Widgets、RenderObjects 和 Elements的關係
首先看一下這幾個對象的含義及做用。
Widget會被inflate(填充)到Element,並由Element管理底層渲染樹。Widget並不會直接管理狀態及渲染,而是經過State這個對象來管理狀態。Flutter建立Element的可見樹,相對於Widget來講,是可變的,一般界面開發中,咱們不用直接操做Element,而是由框架層實現內部邏輯。就如一個UI視圖樹中,可能包含有多個TextWidget(Widget被使用屢次),可是放在內部視圖樹的視角,這些TextWidget都是填充到一個個獨立的Element中。Element會持有renderObject和widget的實例。記住,Widget 只是一個配置,RenderObject 負責管理佈局、繪製等操做。
在第一次建立 Widget 的時候,會對應建立一個 Element, 而後將該元素插入樹中。若是以後 Widget 發生了變化,則將其與舊的 Widget 進行比較,而且相應地更新 Element。重要的是,Element 不會被重建,只是更新而已。
8. 什麼是狀態管理,你瞭解哪些狀態管理框架?
Flutter中的狀態和前端React中的狀態概念是一致的。React框架的核心思想是組件化,應用由組件搭建而成,組件最重要的概念就是狀態,狀態是一個組件的UI數據模型,是組件渲染時的數據依據。
Flutter的狀態能夠分爲全局狀態和局部狀態兩種。經常使用的狀態管理有ScopedModel、BLoC、Redux / FishRedux和Provider。詳細使用狀況和差別能夠自行了解。
9. 簡述Flutter的繪製流程
Flutter的繪製流程以下圖所示。
Flutter只關心向 GPU提供視圖數據,GPU的 VSync信號同步到 UI線程,UI線程使用 Dart來構建抽象的視圖結構,這份數據結構在 GPU線程進行圖層合成,視圖數據提供給 Skia引擎渲染爲 GPU數據,這些數據經過 OpenGL或者 Vulkan提供給 GPU。
10. 簡述Flutter的線程管理模型
默認狀況下,Flutter Engine層會建立一個Isolate,而且Dart代碼默認就運行在這個主Isolate上。必要時可使用spawnUri和spawn兩種方式來建立新的Isolate,在Flutter中,新建立的Isolate由Flutter進行統一的管理。
事實上,Flutter Engine本身不建立和管理線程,Flutter Engine線程的建立和管理是Embeder負責的,Embeder指的是將引擎移植到平臺的中間層代碼,Flutter Engine層的架構示意圖以下圖所示。
在Flutter的架構中,Embeder提供四個Task Runner,分別是Platform Task Runner、UI Task Runner Thread、GPU Task Runner和IO Task Runner,每一個Task Runner負責不一樣的任務,Flutter Engine不在意Task Runner運行在哪一個線程,可是它須要線程在整個生命週期裏面保持穩定。
11. Flutter 是如何與原生Android、iOS進行通訊的?
Flutter 經過 PlatformChannel 與原生進行交互,其中 PlatformChannel 分爲三種:
同時 Platform Channel 並不是是線程安全的 ,更多詳細可查閱閒魚技術的 《深刻理解Flutter Platform Channel》
12. 簡述Flutter 的熱重載
Flutter 的熱重載是基於 JIT 編譯模式的代碼增量同步。因爲 JIT 屬於動態編譯,可以將 Dart 代碼編譯成生成中間代碼,讓 Dart VM 在運行時解釋執行,所以能夠經過動態更新中間代碼實現增量同步。
熱重載的流程能夠分爲 5 步,包括:掃描工程改動、增量編譯、推送更新、代碼合併、Widget 重建。Flutter 在接收到代碼變動後,並不會讓 App 從新啓動執行,而只會觸發 Widget 樹的從新繪製,所以能夠保持改動前的狀態,大大縮短了從代碼修改到看到修改產生的變化之間所須要的時間。
另外一方面,因爲涉及到狀態的保存與恢復,涉及狀態兼容與狀態初始化的場景,熱重載是沒法支持的,如改動先後 Widget 狀態沒法兼容、全局變量與靜態屬性的更改、main 方法裏的更改、initState 方法裏的更改、枚舉和泛型的更改等。
能夠發現,熱重載提升了調試 UI 的效率,很是適合寫界面樣式這樣須要反覆查看修改效果的場景。但因爲其狀態保存的機制所限,熱重載自己也有一些沒法支持的邊界。
更多詳細的資料能夠參考Flutter的Hot Reload是如何實現的
參考資料
1,Flutter 應用程序調試
2,Flutter For Web入門實戰
3,Flutter開發之路由與導航
4,Flutter 必備開源項目
5,Flutter混合開發
6,Flutter的Hot Reload是如何作到的
7,《Flutter in action》開源
8,Flutter開發之JSON解析
9,Flutter開發之基礎Widgets
10,Flutter開發之導航與路由管理
11,Flutter開發之網絡請求
12,Flutter基礎知識
13,Flutter開發之Dart語言基礎
14,Flutter入門與環境搭建
15,移動跨平臺方案對比:WEEX、React Native、Flutter和PWA