字節跳動Android實習面經覆盤;Flutter+dart

作者:Rreply鏈接:https://www.jianshu.com/p/e5cebe3356f8

字節跳動Android實習面經覆盤;Flutter+dart


一面問的Java 和Android基礎

  1. Jvm虛擬機
  2. messageQueue會不會阻塞ui線程
  3. 對象鎖和類鎖
  4. 之字形打印樹
  5. 還有其他的記不清了,主要是我對二面印象太深刻了。

二面問的Flutter和Dart

  1. dart是值傳遞還是引用傳遞
  2. Widget和element和RenderObject之間的關係
  3. widget的root節點
  4. mixin extends implement之間的關係(除了extends其他的沒怎麼用過。。)
  5. jvm內存模型(感覺這個是面試官可憐我,看我什麼都不會才問的=。=)
  6. Future和microtask執行順序
  7. dart中..的用法(基本沒用過。。)
  8. await for(沒用過。。)

說實話,第一個、第三個、第六個我準備的話應該能答出來的,但是一個多月沒碰Flutter了,忘了都差不多。。。等下把二面的答案寫出來,希望能幫助後來人。此外GitHub和博客維護好很重要,像我這種demo隨手寫,隨手刪的人直接GG。。

1. dart是值傳遞還是引用傳遞

首先給個結論,dart是值傳遞。先來看段代碼

<code>main(){
Test a = new Test(5);
print("a的初始值為:${a.value}");
setValue(a);
print("修改後a的值為: ${a.value}");
}

class Test{
int value = 1;
Test(int newValue){
this.value = newValue;
}
}

setValue(Test s){
print("修改value為100");
s.value = 100;
}

/<code>

輸出結果為:

<code>a的初始值為:5 

修改value為100
修改後a的值為:100

/<code>

從這裡可以看出是值傳遞,如果只是複製了一個對象的話,main函數中的a值是不會發生變化的。有些人可能會以以下代碼反駁我:

<code>main(){
int s = 6;
setValue(s);
print(s); //輸出6,而不是7
}

class Test{
int value = 1;
Test(int newValue){
this.value = newValue;
}
}

setValue(int s){
s += 1;
}

/<code>

你看,這輸出的不是6嗎,在dart中一切皆為對象,如果是值傳遞,那為什麼是6啊。

答案是這樣的,在setValue()方法中,參數s實際上和我們初始化int s = 6的s不是一個對象,只是他們現在指的是同一塊內存區域,然後在setValue()中調用s += 1的時候,這塊內存區域的對象執行+1操作,然後在堆(類比java)中產生了一個新的對象,s再指向這個對象。所以s參數只是把main函數中的s的內存地址複製過去了,就比如java中的:

<code>public class Test {
public static void main(String[] args) {
//相當於dart中main函數初始化
Test a = new Test();
//相當於setValue()中的s,並把參數代表的內存地址賦值給b
Test b = a;
//s指向一個新對象,即為dart中的s += 1
b = new Test();
}
}

/<code>

我們只要記住一點,參數是把內存地址傳過去了,如果對這個內存地址上的對象修改,那麼其他位置的引用該內存地址的變量值也會修改。千萬要記住dart中一切都是對象。

偷偷說一句,我覺得面試官這個地方面試的不好,這種細節問題,如果不是遇到什麼bug,業務忙的時候是沒時間注意這個的,面試官可以把這兩種情況展示下,然後問面試者原因是什麼。。然後我就能回答出來了。。哭唧唧。。

2. Widget和element和RenderObject之間的關係

首先我詳細說下當時的情景,面試官問我Widget和Element之間是不是一對多的關係,如果是增加一個Widget之後,這個關係又是什麼。這部分還是沒有很好地答案,現在只是一個猜想,如果添加了一個widget,Element樹遍歷後面所有的Element看類型是否發生改變,有的話再重建RenderObject。Element和Widget之間應該還是一對一的關係,因為每個Widget的context都是獨一無二的。等想好了再寫上去吧。

3. widget樹的root節點

還是沒能理解面試官的意思。。有能夠理解的同學請評論告知我一下。現在理解了,面試官的意思應該指是runApp()方法中的那個的Widget。我當時也想說的不過忘記這個方法名是啥了。。。

4. mixin extends implement之間的關係

這部分可以參考掘金的小德大佬的文章,高產似那啥。。Flutter Dart mixins 探究Flutter Dart語法(1):extends 、 implements 、 with的用法與區別

6. Future和microtask執行順序

同樣參考小德的文章深入瞭解Flutter的isolate(1) ---- 事件循環(event loop)及代碼運行順序深入瞭解Flutter的isolate(2) --- 創建自己的isolate深入瞭解Flutter的isolate(3) --- Flutter的thread model(線程模型)深入瞭解Flutter的isolate(4) --- 使用Compute寫isolates

7. dart中..是什麼

級聯符號 .. 可以讓你連續操作相同的對象,不單可以連續地調用函數,還可以連續地訪問方法,這樣做可以避免創建臨時變量,從而寫出更流暢的代碼,流式編程更符合現代編程習慣和編程風格:

<code>main(){
Tree tree = new Tree(1);
tree..test1 = 1..test2 =5;
print(tree.test1);
print(tree.test2);
}


class Tree{
int value;
int test1 = 2;
int test2 = 3;
Tree(int a){
this.value = a;
}
}

/<code>

8. await for使用

先來一段官方文檔

await-for

As every Dart programmer knows, the for-in loop plays well with iterables. Similarly, the await-for loop is designed to play well with streams.Given a stream, one can loop over its values:Every time an element is added to the stream, the loop body is run. After each iteration, the function enclosing the loop suspends until the next element is available or the stream is done. Just like await expressions, await-for loops can only appear inside asynchronous functions.

大概意思就是await for是不斷獲取stream流中的數據,然後執行循環體中的操作。

<code>Stream<string> stream = new Stream<string>.fromIterable(['不開心', '面試', '沒', '過']);
main() async{
print('上午被開水燙了腳');
await for(String s in stream){
print(s);
}
print('晚上還沒吃飯');
}

/<string>/<string>/<code>

輸出為

<code>上午被開水燙了腳 

不開心
面試


晚上還沒吃飯

/<code>

await for 和 listen的作用很相似,都是獲取流中數據然後輸出,但是正如await for中的await所示,如果stream沒有傳遞完成,就會一直阻塞在這個位置,上面沒吃飯是最後輸出的,下面給個listen的實例,一看就懂。

<code>Stream<string> stream = new Stream<string>.fromIterable(['不開心', '面試', '沒', '過']);
main(){
print('上午被開水燙了腳');
stream.listen((s) { print(s); });
print('晚上還沒吃飯');
}

/<string>/<string>/<code>

輸出為

<code>上午被開水燙了腳
晚上還沒吃飯
不開心
面試



/<code>

所以await for一般用在直到stream什麼時候完成,並且必須等待傳遞完成之後才能使用,不然就會一直阻塞,造成類似於Android ANR的問題。

總結

其實面試官還是很nice的,第一次見到活的大佬。。大佬對flutter和dart的研究真的很深入,遠不是我這種只會調api的人可以比擬的。主要還是我一個半月沒使用過flutter了,然後之前問其他大佬要不要準備Flutter,大佬們說不用,以前看的很多東西都忘的差不多了。哎,還是自己準備不充分,或者開始大佬問我的時候直接回答忘得差不多了,應該就能過了吧。


覆盤分享

對於程序員來說,要學習的知識內容、技術有太多太多,要想不被環境淘汰就只有不斷提升自己,從來都是我們去適應環境,而不是環境來適應我們!

這裡附上我整理的幾十套騰訊、頭條、阿里、美團等公司19年的面試題,把技術點整理成了視頻和PDF(實際上比預期多花了不少精力),包含知識脈絡 + 諸多細節,由於篇幅有限,簡略圖;


字節跳動Android實習面經覆盤;Flutter+dart

後臺私信回覆關鍵詞【面試資料】,自動回覆,免費分享!

字節跳動Android實習面經覆盤;Flutter+dart


後臺私信回覆關鍵詞【視頻教程】,自動回覆,免費分享!

字節跳動Android實習面經覆盤;Flutter+dart


當程序員容易,當一個優秀的程序員是需要不斷學習的,從初級程序員到高級程序員,從初級架構師到資深架構師,或者走向管理,從技術經理到技術總監,每個階段都需要掌握不同的能力。早早確定自己的職業方向,才能在工作和能力提升中甩開同齡人。

  • 無論你現在水平怎麼樣一定要 持續學習 沒有雞湯,別人看起來的毫不費力,其實費了很大力,這四個字就是我的建議!!!!!!!!!
  • 我希望每一個努力生活的IT工程師,都會得到自己想要的,因為我們很辛苦,我們應得的。


Android進階高級並不能算得上順其自然,需要努力和堅持!


分享到:


相關文章: