2020Android常见面试题,kotlin扩展函数
20、Object類的equal和hashCode方法重寫,為什么?
首先equals與hashcode間的關系是這樣的:
1、如果兩個對象相同(即用equals比較返回true),那么它們的hashCode值一定要相同;
2、如果兩個對象的hashCode相同,它們并不一定相同(即用equals比較返回false)
由于為了提高程序的效率才實現了hashcode方法,先進行hashcode的比較,如果不同,那沒就不必在進行equals的比較了,這樣就大大減少了equals比較的次數,這對比需要比較的數量很大的效率提高是很明顯的
21、List,Set,Map的區別
Set是最簡單的一種集合。集合中的對象不按特定的方式排序,并且沒有重復對象。 Set接口主要實現了兩個實現類:HashSet: HashSet類按照哈希算法來存取集合中的對象,存取速度比較快
TreeSet :TreeSet類實現了SortedSet接口,能夠對集合中的對象進行排序。
List的特征是其元素以線性方式存儲,集合中可以存放重復對象。
ArrayList() : 代表長度可以改變得數組。可以對元素進行隨機的訪問,向ArrayList()中插入與刪除元素的速度慢。
LinkedList(): 在實現中采用鏈表數據結構。插入和刪除速度快,訪問速度慢。
Map 是一種把鍵對象和值對象映射的集合,它的每一個元素都包含一對鍵對象和值對象。 Map沒有繼承于Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。
HashMap:Map基于散列表的實現。插入和查詢“鍵值對”的開銷是固定的。可以通過構造器設置容量capacity和負載因子load factor,以調整容器的性能。
LinkedHashMap: 類似于HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發而更快,因為它使用鏈表維護內部次序。
TreeMap : 基于紅黑樹數據結構的實現。查看“鍵”或“鍵值對”時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點在 于,你得到的結果是經過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。
WeakHashMao :弱鍵(weak key)Map,Map中使用的對象也被允許釋放: 這是為解決特殊問題設計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。
26、ArrayMap和HashMap的對比
1、存儲方式不同
HashMap內部有一個HashMapEntry<K, V>[]對象,每一個鍵值對都存儲在這個對象里,當使用put方法添加鍵值對時,就會new一個HashMapEntry對象,
2、添加數據時擴容時的處理不一樣,進行了new操作,重新創建對象,開銷很大。ArrayMap用的是copy數據,所以效率相對要高。
3、ArrayMap提供了數組收縮的功能,在clear或remove后,會重新收縮數組,是否空間
4、ArrayMap采用二分法查找;
29、HashMap和HashTable的區別
1 HashMap不是線程安全的,效率高一點、方法不是Synchronize的要提供外同步,有containsvalue和containsKey方法。
hashtable是,線程安全,不允許有null的鍵和值,效率稍低,方法是是Synchronize的。有contains方法方法。Hashtable 繼承于Dictionary 類
30、HashMap與HashSet的區別
hashMap:HashMap實現了Map接口,HashMap儲存鍵值對,使用put()方法將元素放入map中,HashMap中使用鍵對象來計算hashcode值,HashMap比較快,因為是使用唯一的鍵來獲取對象。
HashSet實現了Set接口,HashSet僅僅存儲對象,使用add()方法將元素放入set中,HashSet使用成員對象來計算hashcode值,對于兩個對象來說hashcode可能相同,所以equals()方法用來判斷對象的相等性,如果兩個對象不同的話,那么返回false。HashSet較HashMap來說比較慢。
31、HashSet與HashMap怎么判斷集合元素重復?
HashSet不能添加重復的元素,當調用add(Object)方法時候,
首先會調用Object的hashCode方法判hashCode是否已經存在,如不存在則直接插入元素;如果已存在則調用Object對象的equals方法判斷是否返回true,如果為true則說明元素已經存在,如為false則插入元素。
33、ArrayList和LinkedList的區別,以及應用場景
ArrayList是基于數組實現的,ArrayList線程不安全。
LinkedList是基于雙鏈表實現的:
使用場景:
(1)如果應用程序對各個索引位置的元素進行大量的存取或刪除操作,ArrayList對象要遠優于LinkedList對象;
( 2 ) 如果應用程序主要是對列表進行循環,并且循環時候進行插入或者刪除操作,LinkedList對象要遠優于ArrayList對象;
34、數組和鏈表的區別
數組:是將元素在內存中連續存儲的;它的優點:因為數據是連續存儲的,內存地址連續,所以在查找數據的時候效率比較高;它的缺點:在存儲之前,我們需要申請一塊連續的內存空間,并且在編譯的時候就必須確定好它的空間的大小。在運行的時候空間的大小是無法隨著你的需要進行增加和減少而改變的,當數據兩比較大的時候,有可能會出現越界的情況,數據比較小的時候,又有可能會浪費掉內存空間。在改變數據個數時,增加、插入、刪除數據效率比較低。
鏈表:是動態申請內存空間,不需要像數組需要提前申請好內存的大小,鏈表只需在用的時候申請就可以,根據需要來動態申請或者刪除內存空間,對于數據增加和刪除以及插入比數組靈活。還有就是鏈表中數據在內存中可以在任意的位置,通過應用來關聯數據(就是通過存在元素的指針來聯系)
35、開啟線程的三種方式?
ava有三種創建線程的方式,分別是繼承Thread類、實現Runable接口和使用線程池
36、線程和進程的區別?
線程是進程的子集,一個進程可以有很多線程,每條線程并行執行不同的任務。不同的進程使用不同的內存空間,而所有的線程共享一片相同的內存空間。別把它和棧內存搞混,每個線程都擁有單獨的棧內存用來存儲本地數據。
38、run()和start()方法區別
這個問題經常被問到,但還是能從此區分出面試者對Java線程模型的理解程度。start()方法被用來啟動新創建的線程,而且start()內部調用了run()方法,這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啟動,start()方法才會啟動新線程。
39、如何控制某個方法允許并發訪問線程的個數?
semaphore.acquire() 請求一個信號量,這時候的信號量個數-1(一旦沒有可使用的信號量,也即信號量個數變為負數時,再次請求的時候就會阻塞,直到其他線程釋放了信號量)
semaphore.release() 釋放一個信號量,此時信號量個數+1
40、在Java中wait和seelp方法的不同;
Java程序中wait 和 sleep都會造成某種形式的暫停
,它們可以滿足不同的需要。wait()方法用于線程間通信,如果等待條件為真且其它線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放CPU資源或者讓當前線程停止執行一段時間,但不會釋放鎖。
41、談談wait/notify關鍵字的理解
等待對象的同步鎖,需要獲得該對象的同步鎖才可以調用這個方法,否則編譯可以通過,但運行時會收到一個異常:IllegalMonitorStateException。
調用任意對象的 wait() 方法導致該線程阻塞,該線程不可繼續執行,并且該對象上的鎖被釋放。
喚醒在等待該對象同步鎖的線程(只喚醒一個,如果有多個在等待),注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
調用任意對象的notify()方法則導致因調用該對象的 wait()方法而阻塞的線程中隨機選擇的一個解除阻塞(但要等到獲得鎖后才真正可執行)。
42、什么導致線程阻塞?線程如何關閉?
阻塞式方法是指程序會一直等待該方法完成期間不做其他事情,ServerSocket的accept()方法就是一直等待客戶端連接。這里的阻塞是指調用結果返回之前,當前線程會被掛起,直到得到結果之后才會返回。此外,還有異步和非阻塞式方法在任務完成前就返回。
一種是調用它里面的stop()方法
另一種就是你自己設置一個停止線程的標記 (推薦這種)
43、如何保證線程安全?
1.synchronized;
2.Object方法中的wait,notify;
3.ThreadLocal機制 來實現的。
44、如何實現線程同步?
1、synchronized關鍵字修改的方法。2、synchronized關鍵字修飾的語句塊3、使用特殊域變量(volatile)實現線程同步
45、線程間操作List
List list = Collections.synchronizedList(new ArrayList());
46、談談對Synchronized關鍵字,類鎖,方法鎖,重入鎖的理解
java的對象鎖和類鎖:java的對象鎖和類鎖在鎖的概念上基本上和內置鎖是一致的,但是,兩個鎖實際是有很大的區別的,對象鎖是用于對象實例方法,或者一個對象實例上的,類鎖是用于類的靜態方法或者一個類的class對象上的。我們知道,類的對象實例可以有很多個,但是每個類只有一個class對象,所以不同對象實例的對象鎖是互不干擾的,但是每個類只有一個類鎖。但是有一點必須注意的是,其實類鎖只是一個概念上的東西,并不是真實存在的,它只是用來幫助我們理解鎖定實例方法和靜態方法的區別的
49、synchronized 和volatile 關鍵字的區別
1.volatile本質是在告訴jvm當前變量在寄存器(工作內存)中的值是不確定的,需要從主存中讀取;synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞住。
2.volatile僅能使用在變量級別;synchronized則可以使用在變量、方法、和類級別的
3.volatile僅能實現變量的修改可見性,不能保證原子性;而synchronized則可以保證變量的修改可見性和原子性
4.volatile不會造成線程的阻塞;synchronized可能會造成線程的阻塞。
5.volatile標記的變量不會被編譯器優化;synchronized標記的變量可以被編譯器優化
51、ReentrantLock 、synchronized和volatile比較
ava在過去很長一段時間只能通過synchronized關鍵字來實現互斥,它有一些缺點。比如你不能擴展鎖之外的方法或者塊邊界,嘗試獲取鎖時不能中途取消等。Java 5 通過Lock接口提供了更復雜的控制來解決這些問題。 ReentrantLock 類實現了 Lock,它擁有與 synchronized 相同的并發性和內存語義且它還具有可擴展性。
53、死鎖的四個必要條件?
死鎖產生的原因
系統資源的競爭
系統資源的競爭導致系統資源不足,以及資源分配不當,導致死鎖。
進程運行推進順序不合適
互斥條件:一個資源每次只能被一個進程使用,即在一段時間內某 資源僅為一個進程所占有。此時若有其他進程請求該資源,則請求進程只能等待。
請求與保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源 已被其他進程占有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。
不可剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能 由獲得該資源的進程自己來釋放(只能是主動釋放)。
循環等待條件: 若干進程間形成首尾相接循環等待資源的關系
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
死鎖的避免與預防:
死鎖避免的基本思想:
系統對進程發出每一個系統能夠滿足的資源申請進行動態檢查,并根據檢查結果決定是否分配資源,如果分配后系統可能發生死鎖,則不予分配,否則予以分配。這是一種保證系統不進入死鎖狀態的動態策略。
理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和解除死鎖。所以,在系統設計、進程調度等方面注意如何讓這四個必要條件不成立,如何確定資源的合理分配算法,避免進程永久占據系統資源。此外,也要防止進程在處于等待狀態的情況下占用資源。因此,對資源的分配要給予合理的規劃。
死鎖避免和死鎖預防的區別:
死鎖預防是設法至少破壞產生死鎖的四個必要條件之一,嚴格的防止死鎖的出現,而死鎖避免則不那么嚴格的限制產生死鎖的必要條件的存在,因為即使死鎖的必要條件存在,也不一定發生死鎖。死鎖避免是在系統運行過程中注意避免死鎖的最終發生。
56、什么是線程池,如何使用?
創建線程要花費昂貴的資源和時間,如果任務來了才創建線程那么響應時間會變長,而且一個進程能創建的線程數有限。為了避免這些問題,在程序啟動的時候就創建若干線程來響應處理,它們被稱為線程池,里面的線程叫工作線程。從JDK1.5開始,Java API提供了Executor框架讓你可以創建不同的線程池。比如單線程池,每次處理一個任務;數目固定的線程池或者是緩存線程池(一個適合很多生存期短的任務的程序的可擴展線程池)。
57、Java中堆和棧有什么不同?
為什么把這個問題歸類在多線程和并發面試題里?因為棧是一塊和線程緊密相關的內存區域。每個線程都有自己的棧內存,用于存儲本地變量,方法參數和棧調用,一個線程中存儲的變量對其它線程是不可見的。而堆是所有線程共享的一片公用內存區域。對象都在堆里創建,為了提升效率線程會從堆中弄一個緩存到自己的棧,如果多個線程使用該變量就可能引發問題,這時volatile 變量就可以發揮作用了,它要求線程從主存中讀取變量的值。
58、有三個線程T1,T2,T3,怎么確保它們按順序執行?
在多線程中有多種方法讓線程按特定順序執行,你可以用線程類的join()方法在一個線程中啟動另一個線程,另外一個線程完成該線程繼續執行。為了確保三個線程的順序你應該先啟動最后一個(T3調用T2,T2調用T1),這樣T1就會先完成而T3最后完成。
線程間通信
我們知道線程是CPU調度的最小單位。在Android中主線程是不能夠做耗時操作的,子線程是不能夠更新UI的。而線程間通信的方式有很多,比如廣播,Eventbus,接口回掉,在Android中主要是使用handler。handler通過調用sendmessage方法,將保存消息的Message發送到Messagequeue中,而looper對象不斷的調用loop方法,從messageueue中取出message,交給handler處理,從而完成線程間通信。
總結
最后為了幫助大家深刻理解Android相關知識點的原理以及面試相關知識,這里放上相關的我搜集整理的14套騰訊、字節跳動、阿里、百度等**2020面試真題解析**,我把技術點整理成了視頻和PDF(實際上比預期多花了不少精力),包知識脈絡 + 諸多細節。
網上學習 Android的資料一大堆,但如果學到的知識不成體系,遇到問題時只是淺嘗輒止,不再深入研究,那么很難做到真正的技術提升。希望這份系統化的技術體系對大家有一個方向參考。
復制石墨文檔可見:https://shimo.im/docs/QdyGqGHXX8PyQ8pw
再深入研究,那么很難做到真正的技術提升。希望這份系統化的技術體系對大家有一個方向參考。
復制石墨文檔可見:https://shimo.im/docs/QdyGqGHXX8PyQ8pw
[外鏈圖片轉存中…(img-SKxRMozD-1642641770391)]
總結
以上是生活随笔為你收集整理的2020Android常见面试题,kotlin扩展函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业服务器搭建与维护论文,《企业服务器搭
- 下一篇: 微信小程序用canvasToTempFi