Android-kotlin協程學習總結

Kotlin協程實戰對話?

?真題1:協程與線程的本質區別是什么?為什么說協程是輕量級的???

?面試官?:
“我看你項目中用協程替代了線程池,能說說協程和線程的核心區別嗎?為什么協程更適合高并發?”

?候選人?:
“協程和線程的區別有點像‘快遞員’和‘卡車’的關系。線程是操作系統直接管理的‘大卡車’,每輛卡車得自己帶一整個貨箱(1MB的棧內存),啟動和換路線得經過調度中心(內核態),成本高還慢。而協程更像是快遞員,他們騎電動車(用戶態調度),一輛卡車能裝幾千個快遞員,換任務時只需要記下當前位置,輕裝上陣,內存開銷只有幾十KB。

比如我們做電商秒殺,10萬用戶同時搶購。如果用線程池,開500個線程就得吃掉500MB內存,線程切換還得排隊等調度,CPU都忙不過來。換成協程,一個線程就能跑幾萬個請求,內存省了90%,QPS直接翻倍——這就像用電動車送快遞,不堵車還省油。”


?真題2:GlobalScope為什么會導致內存泄漏?如何正確使用作用域???

?面試官?:
“你們項目里把GlobalScope全換成了lifecycleScope,是踩過坑吧?”

?候選人?:
“沒錯!之前做視頻彈幕功能時,用GlobalScope啟動了一個無限循環的彈幕請求。結果用戶退出了頁面,協程還在后臺瘋狂拉數據,Fragment像僵尸一樣賴在內存里,直接導致OOM崩潰。后來發現GlobalScope是‘長生不老’的,它的生命周期和整個App綁定,根本不管Activity的死活。

現在我們用lifecycleScope,相當于給協程裝了‘智能開關’。Activity銷毀時,自動觸發onDestroy里的取消邏輯。就像給電器裝了個漏電保護器——頁面一關,所有后臺任務立馬斷電,內存泄漏風險直接清零。

比如在ViewModel里這么寫:

viewModelScope.launch { val data = withContext(Dispatchers.IO) { fetchData() } _liveData.value = data  //自動綁定到ViewModel生命周期
}

就算用戶瘋狂滑動頁面,舊的請求也會被及時取消,再也不用擔心后臺跑‘幽靈任務’了。”


?真題3:如何處理協程中的并發任務?async和launch有什么區別???

?面試官?:
“如果要同時調三個接口,等結果全到了再更新UI,用協程怎么搞?如果有一個接口掛了怎么辦?”

?候選人?:
“這得請出‘協程三劍客’——asyncawaitcoroutineScope。比如用戶主頁需要同時拉取用戶信息、訂單列表和消息通知,可以這么寫:

lifecycleScope.launch {try {val (user, orders, messages) = coroutineScope {val userDeferred = async { api.getUser() }      // 并行啟動val ordersDeferred = async { api.getOrders() }val messagesDeferred = async { api.getMessages() }Triple(userDeferred.await(), ordersDeferred.await(), messagesDeferred.await())}updateUI(user, orders, messages)  // 三個結果都到了才更新} catch (e: Exception) {showErrorToast("有一個接口掛了:${e.message}")  // 任一失敗都會跳到這里}
}

這里的關鍵是coroutineScope會‘一損俱損’——只要有一個子協程拋異常,整個作用域里的任務全取消。而async和launch的核心區別在于‘帶不帶回執’——async返回Deferred對象(類似快遞單號),需要用await獲取結果,適合需要聚合數據的場景;launch則像‘寄平郵’,適合日志上報等無需返回值的任務


?真題4:協程的掛起函數底層是如何實現的???

?面試官?:
“你說delay(1000)不阻塞線程,那協程怎么做到‘暫停而不卡死’的?”

?候選人?:
“這得看Kotlin編譯器的‘魔法’——CPS變換狀態機。比如這個掛起函數:

suspend fun fetchData(): String {delay(1000)          // 掛起點1return "Data"         // 掛起點2
}

編譯后會變成‘代碼樂高’:

Object fetchData(Continuation $completion) {switch (label) {case 0: delay(1000, $completion);  // 記錄位置1label = 1;return COROUTINE_SUSPENDED; // 掛起case 1: return "Data";             // 從位置1恢復}
}

Continuation就像書簽,記錄執行到哪里了。當delay觸發時,協程把書簽交給線程:‘你先去忙別的,1秒后喊我’。這時候線程騰出手來處理UI點擊或者別的請求,完全不卡頓。時間一到,線程通過resume()把書簽插回去,繼續執行——整個過程像接力賽,而不是傻站著等。”


?真題5:如何用協程優化RecyclerView的圖片加載???

?面試官?:
“列表快速滑動時圖片加載卡頓,你們怎么用協程解決的?”

?候選人?:
“傳統方案在onBindViewHolder里直接開線程,用戶一滑到底,幾百個請求把線程池擠爆。我們給每個Item綁定獨立的Job,滑動時自動取消不可見的請求:

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {private var loadJob: Job? = nullfun bind(url: String) {loadJob?.cancel()  // 先取消之前的任務loadJob = lifecycleScope.launch {val bitmap = withContext(Dispatchers.IO) { loadImage(url)  // 耗時操作}if (isActive) {     // 檢查是否已被取消itemView.image.setImageBitmap(bitmap)}}}fun unbind() {loadJob?.cancel()  // 視圖滾出屏幕時取消}
}

對比Glide,這套方案更靈活——比如先加載縮略圖,再用協程組合高清圖加載,還能統一處理異常。之前列表滑動FPS只有30,優化后穩定60,內存波動減少70%。”

面試追問擴展

?面試官?:

“協程和線程的本質區別是什么?為什么說協程更適合高并發場景?”

?候選人?:

“您可以想象協程就像快遞站里的一群快遞員,而線程是送貨的大卡車。卡車每次出發都要裝貨、申請路線、排隊等調度,一趟只能送一個包裹,成本高還慢。而快遞員們共用幾輛電動車,一個卡車能塞下幾百個快遞員,每個人記下自己的送貨路線,到了路口靈活切換——協程就這么干的。它不用等操作系統調度,自己管理任務切換,一個線程能跑幾萬個協程,內存開銷只有幾十KB。比如我們做秒殺活動,10萬人同時搶購,用線程池開500個線程內存就爆了,但換成協程,一個線程輕松扛住,還能自動取消沒必要的請求,這就是輕量級的威力。”


?面試官?:

“聽說GlobalScope容易導致內存泄漏,你們項目里是怎么解決的?”

?候選人?:

“這真是血淚教訓!之前做視頻彈幕功能,用GlobalScope啟動了一個無限循環的彈幕請求,結果用戶退出頁面后,協程還在后臺瘋狂拉數據,Fragment像‘僵尸’一樣賴在內存里,最后直接OOM崩潰。后來才明白,GlobalScope是‘長生不老’的,它的生命周期和整個App綁定,根本不管Activity的死活。現在我們全員改用lifecycleScope——相當于給協程裝了智能開關,頁面銷毀時自動斷電。比如在Fragment里發起網絡請求,只要用lifecycleScope.launch,用戶一返回,請求立刻取消,再也不會出現后臺偷偷耗流量的問題了。”


?面試官?:

“用戶快速滑動商品列表,每個Item都要加載圖片,用協程怎么防止卡頓和錯亂?”

候選人?:

“這個問題我們優化了三個月!首先,?給每個圖片加載任務打標簽。比如商品ID是123,加載完成后對比ImageView當前綁定的ID,如果不一樣就直接丟棄,防止圖片錯位。其次,?用協程作用域控制生命周期。在RecyclerView的ViewHolder里,每次綁定新數據時,先取消前一個協程任務,像這樣——”

候選人用手比劃著空氣代碼:
“在onBindViewHolder里啟動協程前,先檢查job是否活躍,如果還在跑就立刻cancel。最后,?給IO操作加限流。比如用Dispatchers.IO的limitedParallelism限制同時加載的圖片數,避免100張圖同時開線程,線程池直接被打爆。現在我們的列表滑動FPS穩定在60幀,內存占用降了60%。”


?面試官?:

“如果協程嵌套了三層異步任務,突然父協程被取消,會發生什么?”

?候選人?:

“這就好比拆炸彈時剪錯了線——子協程會連鎖爆炸!結構化并發的核心思想就是‘要活一起活,要死一起死’。比如父協程負責訂單支付,內部啟動了子協程A查庫存、子協程B扣積分。如果用戶突然退出了頁面,父協程取消,A和B會立刻收到取消信號,哪怕B已經完成了90%,也會立刻回滾。這雖然殘酷,但保證了資源不會部分提交(比如積分扣了但庫存沒鎖)。如果想讓某個子協程‘茍活’,比如日志上報任務,可以用SupervisorJob把它包起來,這樣即使父協程掛了,它還能在后臺默默執行完。”

Android學習總結之Kotlin 協程_android kotlin協程-CSDN博客https://blog.csdn.net/2301_80329517/article/details/146909197Android學習總結之協程對比優缺點(協程一)_android 協程和線程-CSDN博客https://blog.csdn.net/2301_80329517/article/details/147256220

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82823.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82823.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82823.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uni-app學習筆記十四-vue3中emit的使用

在組件傳值中&#xff0c;無論是props還是slot都是單向數據流&#xff0c;父組件向子組件傳值&#xff0c;子組件不能直接對父組件傳過來的值進行重新賦值。 下面學習子組件向父組件傳值的工具--emit。 在子組件emit設置傳遞的函數名和值 <template><view>子組件…

Java設計模式從基礎到實際運用

第一部分&#xff1a;設計模式基礎 1. 設計模式概述 設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類編目的代碼設計經驗的總結&#xff0c;它描述了在軟件設計過程中一些不斷重復出現的問題以及該問題的解決方案。設計模式是在特定環境下解決軟件設計問題…

鴻蒙OSUniApp 制作自定義的進度條組件#三方框架 #Uniapp

使用 UniApp 制作自定義的進度條組件 在移動應用開發中&#xff0c;進度條是非常常見的 UI 組件&#xff0c;無論是文件上傳、下載、任務進度還是表單填寫反饋&#xff0c;進度條都能為用戶提供直觀的進度提示。雖然 UniApp 提供了一些基礎的進度條能力&#xff0c;但在實際項…

Python爬蟲實戰:研究Beautiful Soup框架相關技術

1. 引言 1.1 研究背景與意義 隨著互聯網的快速發展,網絡上的數據量呈爆炸式增長。如何從海量的網頁數據中高效提取有價值的信息,成為信息科學領域的重要研究課題。網絡爬蟲作為一種自動獲取網頁內容的技術,能夠按照預設規則遍歷互聯網并采集數據,為信息檢索、輿情分析、商…

【Tips】關于PCI和PCIe的配置空間差異和io/memory io讀寫

最近在看同事2023年講的PCI基礎課&#xff0c;感覺確實是豁然開朗了&#xff0c;贊美同事。 PCIe實際上是PCI的擴展&#xff08;extended&#xff09;&#xff0c;PCIe設備相當于是迭代升級產品。 而PCIe的配置空間基于PCI原有的0xFF&#xff08;256字節&#xff09;配置空間…

桂花網體育運動監測方案:開啟幼兒園運動健康管理新篇章

在幼兒教育領域&#xff0c;運動能力的培養與健康監測始終是備受關注的核心環節。隨著科技的飛速發展&#xff0c;如何科學、有效地監測幼兒的運動狀態&#xff0c;成為了幼兒園教育者面臨的一大挑戰。桂花網體育運動監測方案憑借其高效、精準、智能化的特性&#xff0c;為幼兒…

Perforce P4產品簡介:無限擴展+全球協作+安全管控+工具集成(附下載)

本產品簡介由Perforce中國授權合作伙伴——龍智編輯整理&#xff0c;旨在帶您快速了解Perforce P4版本控制系統的強大之處。 世界級無限可擴展的版本控制系統 Perforce P4&#xff08;原Helix Core&#xff09;是業界領先的版本控制平臺&#xff0c;備受19家全球Top20 AAA級游…

pikachu靶場通關筆記08 XSS關卡04-DOM型XSS

目錄 一、XSS原理 二、DOM型XSS 三、源碼分析 1、進入靶場 2、XSS探測 3、源碼分析 四、滲透實戰 1、Payload1 2、Payload2 3、Payload3 本系列為通過《pikachu靶場通關筆記》的XSS關卡(共10關&#xff09;滲透集合&#xff0c;通過對XSS關卡源碼的代碼審計找到XSS風…

安全訪問 std::tuple 的容錯方法及氣象領域應用

安全訪問 std::tuple 的容錯方法及氣象領域應用 1. std::tuple 安全訪問的核心問題 1.1 元組結構性問題&#xff08;編譯時錯誤&#xff09; 當元組元素數量為空時&#xff08;std::tuple<>&#xff09;&#xff0c;任何訪問元素的嘗試都會導致編譯錯誤?&#xff1a;…

Webug4.0靶場通關筆記03- 第3關SQL注入之時間盲注(手注法+腳本法 兩種方法)

目錄 一、源碼分析 1.分析閉合 2.分析輸出 &#xff08;1&#xff09;查詢成功 &#xff08;2&#xff09;查詢失敗 &#xff08;3&#xff09;SQL語句執行報錯 二、第03關 延時注入 1.打開靶場 2.SQL手注 &#xff08;1&#xff09;盲注分析 &#xff08;2&#xf…

【大模型學習網絡互聯】Memory-Mapped I/O MMIO語義與MEM語義

MMIO語義和MEM語義的區別 嗯&#xff0c;用戶要求更詳細地區分MMIO和MEM語義&#xff0c;看來之前的中文對比雖然系統但還不夠深入。用戶可能是嵌入式開發者或OS內核學習者&#xff0c;需要從硬件行為層面理解差異。 用戶連續追問MMIO相關概念&#xff0c;說明ta在接觸底層開發…

如何在使用kickstart安裝物理機操作系統的過程中核對服務器的SN

原因 在使用kickstart對物理機進行重裝的時候&#xff0c;由于自動化配置&#xff0c;掛載鏡像重啟之后就會自動化開始安裝部署&#xff0c;不夠安全&#xff0c;萬一選錯服務器沒有辦法回退。因此可以在kickstart的ks配置文件中新增服務器SN的校驗&#xff0c;當校驗不通過的…

spring4第4課-ioc控制反轉-詳解如何注入參數

堅持住&#xff0c;第四天&#xff0c;繼續學習spring4.詳解如何注入參數 先總結&#xff0c;主要有如下6種&#xff1a; 1&#xff0c;基本類型值&#xff1b; 2&#xff0c;注入 bean&#xff1b; 3&#xff0c;內部 bean&#xff1b; 4&#xff0c;null 值&#xff1b; 5&…

cf2067A

原題鏈接&#xff1a;https://codeforces.com/contest/2067/problem/A 題目背景&#xff1a; 給定x,y&#xff0c;判讀是否存在 n 滿足S(n) x&#xff0c;S(n 1) y。定義 S(a) 等于 a 的十進制位數之和。 思路&#xff1a; 不難發現一般 n 和 n 1 的位數之和相差為 1&…

微信小程序獲取手機號

詳細代碼 <t-button size"large" theme"primary" variant"outline" data-type"hasCancelBtn" bind:tap"showDialog" block style"display: none;">開放能力按鈕 </t-button> <t-dialog id"t-…

AI重構SEO關鍵詞精準定位

內容概要 隨著AI技術深度滲透數字營銷領域&#xff0c;傳統SEO關鍵詞定位模式正經歷系統性重構。基于自然語言處理&#xff08;NLP&#xff09;的智能語義分析引擎&#xff0c;可突破傳統關鍵詞工具的局限性&#xff0c;通過解析長尾搜索詞中的隱含意圖與語境關聯&#xff0c;…

四足機器人環境監測系統相關問題

一、在設計四足機器人監測與跟蹤系統整體架構時&#xff0c;你主要考慮了哪些因素&#xff1f;為什么這樣設計以確保系統的高效性與穩定性&#xff1f; 在設計四足機器人監測與跟蹤系統整體架構時&#xff0c;主要考慮了傳感器兼容性與通信效率、多任務并發處理能力、實時數據…

uniapp 開發安卓app 微信授權獲取昵稱 頭像登錄

在manifest.json中配置appid 以及appsecret uni.login({provider: weixin,success: function (loginRes) {console.log(loginRes.authResult);// 獲取用戶信息uni.getUserInfo({provider: weixin,success: function (infoRes) {console.log(用戶昵稱為&#xff1a; infoRes.u…

MySQL8.4組復制

https://dev.mysql.com/doc/refman/8.4/en/group-replication.html 1 什么是組復制 組復制主要解決了傳統異步復制主機宕機時可能造成主從節點數據不一致問題MySQL Group Replication&#xff0c;簡稱MGR將原有的gtid復制功能進行可增強&#xff0c;支持單主模式和多主模式組復…

Python后端開發實戰:從0到1搭建高可用API服務

引言 Python憑借其簡潔的語法和豐富的生態(如Django、Flask、FastAPI等框架),已成為后端開發的主流語言之一。本文將結合一個真實電商API項目,分享從架構設計到部署上線的完整流程,并總結開發過程中常見的坑與最佳實踐。 一、實戰案例:電商API開發流程 1.1 技術選型 框…