阿里Android三面真題,想進阿里關於LiveData的這三個問題你至少得答出來

南方吳彥祖_藍斯發表於2020-11-23

今天一起來看看阿里面試真題LiveData的有關問題:

  • LiveData 是什麼?
  • LiveData 為什麼被設計出來,解決了什麼問題?
  • 說說LiveData原理。

LiveData 是什麼?

LiveData 是一種可觀察的資料儲存器類。與常規的可觀察類不同,LiveData 具有生命週期感知能力,意指它遵循其他應用元件(如 Activity、Fragment 或 Service)的生命週期。這種感知能力可確保 LiveData 僅更新處於活躍生命週期狀態的應用元件觀察者。

官方介紹如下,其實說的比較清楚了,主要作用在兩點:

  • 資料儲存器類。也就是一個用來儲存資料的類。

  • 可觀察。這個資料儲存類是可以觀察的,也就是比一般的資料儲存類多了這麼一個功能,對於資料的變動能進行響應。

主要思想就是用到了 觀察者模式思想,讓觀察者和被觀察者解耦,同時還能感知到資料的變化,所以一般被用到ViewModel中, ViewModel負責觸發資料的更新,更新會通知到 LiveData,然後LiveData再通知活躍狀態的觀察者。

        var liveData = MutableLiveData<String>()
        liveData.observe(this, object : Observer<String> {
            override fun onChanged(t: String?) {
            }
        })
        liveData.setVaile("xixi")
        //子執行緒呼叫
        liveData.postValue("test")

LiveData 為什麼被設計出來,解決了什麼問題?

LiveData作為一種觀察者模式設計思想,常常被和 Rxjava一起比較,觀察者模式的最大好處就是事件發射的上游 和 接收事件的下游 互不干涉,大幅降低了互相持有的依賴關係所帶來的 強耦合性

其次,LiveData還能無縫銜接到 MVVM架構中,主要體現在其可以感知到 Activity等生命週期,這樣就帶來了很多好處:

  • 不會發生記憶體洩漏 觀察者會繫結到  Lifecycle物件,並在其關聯的生命週期遭到銷燬後進行自我清理。

  • 不會因 Activity 停止而導致崩潰 如果觀察者的生命週期處於 非活躍狀態(如返回棧中的 Activity),則它不會接收任何 LiveData 事件。

  • 自動判斷生命週期並回撥方法 如果觀察者的生命週期處於  STARTED或  RESUMED狀態,則 LiveData 會認為該觀察者處於活躍狀態,就會呼叫 onActive方法,否則,如果 LiveData 物件沒有任何活躍觀察者時,會呼叫  onInactive()方法。

說說LiveData原理。

說到原理,其實就是兩個方法:

  • 訂閱方法,也就是 observe方法。透過該方法把訂閱者和被觀察者關聯起來,形成觀察者模式。

簡單看看原始碼:

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //...
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }
      public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> entry = get(key);
        if (entry != null) {
            return entry.mValue;
        }
        put(key, v);
        return null;
    }

這裡 putIfAbsent方法是講生命週期相關的 wrapper和觀察者 observer作為key和value存到了 mObservers中。

  • 回撥方法,也就是 onChanged方法。透過改變儲存值,來通知到觀察者也就是呼叫 onChanged方法。從改變儲存值方法 setValue看起:
@MainThreadprotected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);}private void dispatchingValue(@Nullable ObserverWrapper initiator) {
    //...
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;}private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
    //
    // we still first check observer.active to keep it as the entrance for events. So even if
    // the observer moved to an active state, if we've not received that event, we better not
    // notify for a more predictable notification order.
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);}

這一套下來邏輯還是比較簡單的,遍歷剛才的map—— mObservers,然後找到觀察者 observer,如果觀察者不在活躍狀態(活躍狀態,也就是可見狀態,處於 STARTED 或 RESUMED狀態),則直接返回,不去通知。否則正常通知到觀察者的onChanged方法。

當然,如果想任何時候都能監聽到,都能獲取回撥,呼叫 observeForever方法即可。

總結

講一下大廠面試一些必備的技能

1. 一般情況下第一輪都是基礎面試,需要紮實的基礎

  • 最常用的Android 基礎知識
  • Java 基礎知識
  • 瞭解一些 常用東西的原理,例如:handler, thread 等
  • 專案中的技術點

2. 第二輪的時候需要了解更深層次的東西

  • Android 事件分發機制原理
  • Android 繪圖機制原理
  • WindowManager 的相關知識
  • 程式間傳輸方式
  • Java 記憶體管理機制

3. 能進入第三輪基本沒什麼問題,但是要注意以下問題

  • 該輪一般是 老大或者部門負責人,問的問題一般都看 深度與廣度

  • 當問及薪水的時候,要說一個合適的,小公司隨意,大公司一定要慎重,當心裡沒底的時候,可以告訴對方,讓對方給一個合理的薪資。一般都是在原工資基礎之上增長,聽獵頭說一般漲幅都在15%-30%,超 NB 的可以要30%及以上,如果感覺自己還不錯的,挺厲害的,建議最高20%,一般人就定在15% 左右最靠譜。公司內部一般有一套機制,根據公司情況而定。

  • 我們的面試原則就是拿到合理薪資,得到 offer

  • 個人發展情況,這個問題很難回答,如果和公司方向不符合,極有可能和公司無緣。建議多試探性的問問公司缺少什麼,你能否給予公司對應的東西。當然對於有自我追求的人,那可以放心大膽的提。我的方向就是架構師,哈哈哈,挺極端的,別學我哦。我感覺選擇都是雙向的,因此我知道自己需要的是什麼。

  • 你最擅長什麼UI 還是其他什麼?這個問題更不好回答。你要說你擅長 UI,是不是意味著你其他能力就不行?雖然我不知道面試官的用意,但是我能感覺到,這個問題不是那麼好回答,我會回答說自己都行,來什麼業務接什麼需求。可能回答不太好,總之和公司的職位吻合就行,這樣總不至於出錯吧。

那麼該如何複習?

其實客戶端開發的知識點就那麼多,面試問來問去還是那麼點東西。所以面試沒有其他的訣竅,只看你對這些知識點準備的充分程度。so,出去面試時先看看自己複習到了哪個階段就好。

這裡再分享一下我面試期間的複習路線:(以下體系的複習資料是我從各路大佬收集整理好的)

《Android開發七大模組核心知識筆記》

阿里Android三面真題,想進阿里關於LiveData的這三個問題你至少得答出來

《379頁Android開發面試寶典》

歷時半年,我們整理了這份市面上最全面的安卓面試題解析大全。

1.可以透過目錄索引直接翻看需要的知識點,查漏補缺。
2.五角星數表示面試問到的頻率,代表重要推薦指數

阿里Android三面真題,想進阿里關於LiveData的這三個問題你至少得答出來

《507頁Android開發相關原始碼解析》

只要是程式設計師,不管是Java還是Android,如果不去閱讀原始碼,只看API文件,那就只是停留於皮毛,這對我們知識體系的建立和完備以及實戰技術的提升都是不利的。

真正最能鍛鍊能力的便是直接去閱讀原始碼,不僅限於閱讀各大系統原始碼,還包括各種優秀的開源庫。

阿里Android三面真題,想進阿里關於LiveData的這三個問題你至少得答出來


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983917/viewspace-2736100/,如需轉載,請註明出處,否則將追究法律責任。

相關文章