坐在工位,沒事干心慌的不行,可能也是房貸壓的。一閑下來就開始胡思亂想,無法沉下心去背那些八股文。這才剛剛接到離職通知第三天啊。而且、我還在坐班呢!!!? 哎、怪不得有句老話說的,人窮志短,別人都說解放了 可以休息幾天了。我是心焦、心慌、不停的刷BOSS; 所以還是找點事情干,不然待壓抑死。看到boss廣場上有人發面試題,咱也就當自己去面試了,看看怎么回答。
目錄
面試官:能給我說說關于RecycleView的LayoutManager相關的嗎?
面試官:線程池中的線程如果銷毀
面試官:view繪制流程簡述下
面試官:簡述Binder原理
面試官:ActivityThread AMS WMS的工作原理
面試官:ContentProvider是如何實現數據共享的
面試官:能給我說說關于RecycleView的LayoutManager相關的嗎?
首先、LayoutManager是RecycleView的一個重要組件,負責子項布局和視圖回收。決定RecycleView的排列方式,內置了 線性、橫向、瀑布流等布局。特殊布局可以自定義LayoutManager;并且它還提供操作列表的相關api,比如獲取屏幕上可見的item位置,快速滾動等。
如果延伸,就是陳述下如何自定義LayoutManager。
自定義LayoutManager必須關注其核心方法 onLayoutChildren ; 這個方法是繼承LayoutManger必須實現的方法。它負責所有子Item的布局,也就是決定顯示那些Item,如果排列回收。一般都是數據變化時被調用。其次是 generateDefaultLayoutParams ; 返回默認布局參數,必須實現;其次就是是否可滑動、橫向、豎向等方法。
import android.content.Context
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerViewclass CustomLayoutManager : RecyclerView.LayoutManager() {// 必須實現,提供默認布局參數override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {return RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)}// 是否支持縱向滾動override fun canScrollVertically(): Boolean = true// 用于追蹤滑動偏移private var verticalScrollOffset = 0// 核心布局方法override fun onLayoutChildren(recycler: RecyclerView.Recycler,state: RecyclerView.State) {// 沒有item直接返回if (itemCount == 0) {detachAndScrapAttachedViews(recycler)return}// 回收所有子ViewdetachAndScrapAttachedViews(recycler)var offsetY = verticalScrollOffsetvar topOffset = -offsetY// 布局每一個itemfor (i in 0 until itemCount) {val view = recycler.getViewForPosition(i)addView(view)measureChildWithMargins(view, 0, 0)val width = getDecoratedMeasuredWidth(view)val height = getDecoratedMeasuredHeight(view)layoutDecorated(view, 0, topOffset, width, topOffset + height)topOffset += height// 超出下邊界不再布局if (topOffset > height + height) break}}// 縱向滑動處理override fun scrollVerticallyBy(dy: Int,recycler: RecyclerView.Recycler,state: RecyclerView.State): Int {val travel = dy// 更新偏移量verticalScrollOffset += travel// 限制滑動范圍if (verticalScrollOffset < 0) {verticalScrollOffset = 0}// 最大滑動到最后一個item底部val maxScroll = getTotalHeight() - heightif (verticalScrollOffset > maxScroll) {verticalScrollOffset = maxScroll}// 移動所有子ViewoffsetChildrenVertical(-travel)onLayoutChildren(recycler, state)return travel}// 計算所有item的總高度private fun getTotalHeight(): Int {var totalHeight = 0for (i in 0 until itemCount) {totalHeight += 100 // 這里假設每個item高度為100,可根據實際測量}return totalHeight}
}
上面是一個簡單的自定義LayoutManager 幫助大家理解。回答的話上面的話能說出來,基本算是過關了。
面試官:線程池中的線程如果銷毀
線程池中的線程由線程池統一管理,非核心線程空閑超過keepAliveTime會被自動銷毀,關閉線程時,所有線程會被完全銷毀,無需手動。銷毀線程池 shutdown 方法會等待提交任務,銷毀所有線程。shutdownNow方法會嘗試立即終止所有線程。
面試官:lock和syncrognized原理區別,適合什么場景。
synchronized 是JVM層面的內置鎖、適合簡單互斥場景。Lock是顯示鎖,功能更豐富,支持超時、中斷、公平鎖等,適合復雜的并發場景。
面試官:view繪制流程簡述下
View的繪制流程分為measure layout draw三個階段,分別是確定view的尺寸,位置、顯示內容。由ViewRootImpi遞歸完成整個view繪制。
其中measure 階段是 View 繪制流程的第一步,主要負責測量每個 View 的寬高。它通過 MeasureSpec 約束進行遞歸測量,最終每個 View 都會保存自己的尺寸,為后續 layout 和 draw 階段做準備;
面試官:簡述Binder原理
Binder是android的核心IPC機制,通過內核Binder驅動和序列化技術,實現不同進程間通訊,
追問:怎么Binder怎么做到一次copy的?
- Binder 通過共享內存(mmap)機制實現一次拷貝:
- Client 進程和 Server 進程都通過 Binder 驅動映射一塊緩沖區到各自用戶空間。
- 客戶端寫數據到緩沖區,驅動只需把緩沖區引用傳遞給服務端。
- 服務端直接從映射區讀取數據,無需再做一次拷貝。
- 數據流:Client 用戶空間 → Binder 映射區(內核空間) → Server 用戶空間(同一塊物理內存)
- 這樣只需一次物理內存拷貝,大大提升了 IPC 性能。
面試官:ActivityThread AMS WMS的工作原理
ActivityThread 是應用進程的主線程管理類,負責組件創建和消息分發。AMS 運行在 system_server,負責 Activity 和進程的調度與生命周期管理。WMS 管理所有窗口的顯示、層級和輸入事件。三者通過 Binder 通信,協作實現應用的啟動、界面顯示和系統調度
面試官:ContentProvider是如何實現數據共享的
ContentProvider 提供了統一的訪問接口(CRUD:query、insert、update、delete),其他應用可通過標準 URI 訪問其數據
首次面試歸來,微信視頻面試。緊張、還有就是對于自己的認知;真的是不學習新技術就要落后。現在主流是kotlin,而我真正的kotlin項目是 18年。這就比較尷尬,對于現在kotlin的新特性,高階函數一問三不知。另外,對于自己的語言表達能力表示唾棄~ 真的太久不和人交流,語言組織能力就會退化。
面試官問:講下你現在的項目框架搭建。
我當前項目是一個地圖類應用,采用了組件化架構和MVVM模式;項目組件化架構分為Library,和module ,其中library是公共組件部分,比如網絡庫組件、數據庫組件、widget 通用組件,base組件等。而Module是對業務的拆分,如首頁、組隊、算路、導航等。每個組件獨立開發,維護。我在團隊中負責 框架搭建、Library庫開發維護;
其實目前框架的技術選型有點問題,我們是地圖類項目,要求整個項目共用一個主圖,那么就只能采用單Activity+NFragment,但是有使用了組件化架構導致Fragment的退出棧都需要自己去管理,并且地圖的管理也需要抽出管理類。
面試官:那你們是怎么管理的?
我們采用多個單利去管理比如FragmentController、MapController ,這些管理類堆積在Base組件內,滿足每個業務組件的調用。我們把對于Fragment、或這地圖的操作都由這兩個管理去控制,模塊自身不允許直接操控 map。