<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java常見面試43題

          共 9534字,需瀏覽 20分鐘

           ·

          2020-11-07 16:03

          和你一起終身學(xué)習(xí),這里是程序員Android

          1.Java中==和equals和hashCode的區(qū)別

          基本數(shù)據(jù)類型的==比較的值相等.

          類的==比較的內(nèi)存的地址,即是否是同一個對象,在不覆蓋equals的情況下,同比較內(nèi)存地址,原實(shí)現(xiàn)也為==?,如String等重寫了equals方法.

          hashCode也是Object類的一個方法。返回一個離散的int型整數(shù)。在集合類操作中使用,為了提高查詢速度。(HashMap,HashSet等比較是否為同一個)

          如果兩個對象equals,Java運(yùn)行時環(huán)境會認(rèn)為他們的hashcode一定相等。

          如果兩個對象不equals,他們的hashcode有可能相等。

          如果兩個對象hashcode相等,他們不一定equals

          如果兩個對象hashcode不相等,他們一定不equals。

          2.int與integer的區(qū)別

          int
          基本類型

          integer
          對象int的封裝類

          3.String、StringBuffer、StringBuilder區(qū)別

          String:
          字符串常量 不適用于經(jīng)常要改變值得情況,每次改變相當(dāng)于生成一個新的對象

          StringBuffer:
          字符串變量 (線程安全)

          StringBuilder:
          字符串變量(線程不安全) 確保單線程下可用,效率略高于StringBuffer

          4.什么是內(nèi)部類?內(nèi)部類的作用

          內(nèi)部類可直接訪問外部類的屬性

          Java中內(nèi)部類主要分為成員內(nèi)部類、局部內(nèi)部類(嵌套在方法和作用域內(nèi))、匿名內(nèi)部類(沒構(gòu)造方法)、靜態(tài)內(nèi)部類(static修飾的類,不能使用任何外圍類的非static成員變量和方法, 不依賴外圍類)

          5.進(jìn)程和線程的區(qū)別

          進(jìn)程cpu資源分配的最小單位,
          線程cpu調(diào)度的最小單位。

          進(jìn)程之間不能共享資源,而線程共享所在進(jìn)程的地址空間和其它資源。

          一個進(jìn)程內(nèi)可擁有多個線程,進(jìn)程可開啟進(jìn)程,也可開啟線程。

          一個線程只能屬于一個進(jìn)程,線程可直接使用同進(jìn)程的資源,線程依賴于進(jìn)程而存在。

          6.final,finally,finalize的區(qū)別

          final:
          修飾類、成員變量和成員方法,類不可被繼承,成員變量不可變,成員方法不可重寫

          finally:
          try...catch...共同使用,確保無論是否出現(xiàn)異常都能被調(diào)用到

          finalize:
          類的方法,垃圾回收之前會調(diào)用此方法,子類可以重寫finalize()方法實(shí)現(xiàn)對資源的回收

          7.Serializable 和Parcelable 的區(qū)別

          Serializable
          Java序列化接口 在硬盤上讀寫 讀寫過程中有大量臨時變量的生成,內(nèi)部執(zhí)行大量的i/o操作,效率很低。

          Parcelable
          Android序列化接口 效率高 使用麻煩 在內(nèi)存中讀寫(AS有相關(guān)插件 一鍵生成所需方法) ,對象不能保存到磁盤中

          8.靜態(tài)屬性和靜態(tài)方法是否可以被繼承?是否可以被重寫?以及原因?

          可繼承 不可重寫 而是被隱藏

          如果子類里面定義了靜態(tài)方法和屬性,那么這時候父類的靜態(tài)方法或?qū)傩苑Q之為"隱藏"。如果你想要調(diào)用父類的靜態(tài)方法和屬性,直接通過父類名.方法變量名完成。

          9.成員內(nèi)部類、靜態(tài)內(nèi)部類、局部內(nèi)部類和匿名內(nèi)部類的理解,以及項目中的應(yīng)用

          Java中內(nèi)部類主要分為成員內(nèi)部類、局部內(nèi)部類(嵌套在方法和作用域內(nèi))、匿名內(nèi)部類(沒構(gòu)造方法)、靜態(tài)內(nèi)部類static修飾的類,不能使用任何外圍類的非static成員變量和方法, 不依賴外圍類)

          使用內(nèi)部類最吸引人的原因是:
          每個內(nèi)部類都能獨(dú)立地繼承一個(接口的)實(shí)現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(接口的)實(shí)現(xiàn),對于內(nèi)部類都沒有影響。

          因為Java不支持多繼承,支持實(shí)現(xiàn)多個接口。但有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內(nèi)部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設(shè)計問題??梢赃@樣說,接口只是解決了部分問題,而內(nèi)部類使得多重繼承的解決方案變得更加完整。

          10.string 轉(zhuǎn)換成 integer的方式及原理

          String to integer

          Intrger.parseInt(string);

          Integer to String

           Integer.toString();

          11.哪些情況下的對象會被垃圾回收機(jī)制處理掉?

          1. 所有實(shí)例都沒有活動線程訪問。

          2. 沒有被其他任何實(shí)例訪問的循環(huán)引用實(shí)例。

          3. Java?中有不同的引用類型。判斷實(shí)例是否符合垃圾收集的條件都依賴于它的引用類型。

          要判斷怎樣的對象是沒用的對象。這里有2種方法:

          1. 采用標(biāo)記計數(shù)的方法:

          給內(nèi)存中的對象給打上標(biāo)記,對象被引用一次,計數(shù)就加1,引用被釋放了,計數(shù)就減一,當(dāng)這個計數(shù)為0的時候,這個對象就可以被回收了。當(dāng)然,這也就引發(fā)了一個問題:循環(huán)引用的對象是無法被識別出來并且被回收的。所以就有了第二種方法:

          1. 采用根搜索算法:

          從一個根出發(fā),搜索所有的可達(dá)對象,這樣剩下的那些對象就是需要被回收的

          12.靜態(tài)代理和動態(tài)代理的區(qū)別,什么場景使用?

          靜態(tài)代理類:
          由程序員創(chuàng)建或由特定工具自動生成源代碼,再對其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。

          動態(tài)代理類:
          在程序運(yùn)行時,運(yùn)用反射機(jī)制動態(tài)創(chuàng)建而成。

          13.Java中實(shí)現(xiàn)多態(tài)的機(jī)制是什么?

          方法的重寫Overriding和重載OverloadingJava多態(tài)性的不同表現(xiàn)

          重寫
          Overriding是父類與子類之間多態(tài)性的一種表現(xiàn)

          重載
          Overloading是一個類中多態(tài)性的一種表現(xiàn).

          14.說說你對Java反射的理解

          Java反射機(jī)制是在運(yùn)行狀態(tài)中, 對于任意一個類, 都能夠知道這個類的所有屬性和方法; 對于任意一個對象, 都能夠調(diào)用它的任意一個方法和屬性。從對象出發(fā),通過反射(Class類)可以取得取得類的完整信息(類名 Class類型,所在包、具有的所有方法 Method[]類型)、某個方法的完整信息(包括修飾符、返回值類型、異常、參數(shù)類型)、所有屬性?(Field[]、某個屬性的完整信息、構(gòu)造器 Constructors),調(diào)用類的屬性或方法自己的總結(jié):在運(yùn)行過程中獲得類、對象、方法的所有信息。

          15.說說你對Java注解的理解

          元注解

          元注解的作用就是負(fù)責(zé)注解其他注解。java5.0的時候,定義了4個標(biāo)準(zhǔn)的meta-annotation類型,它們用來提供對其他注解的類型作說明。
          1.@Target
          2.@Retention
          3.@Documented
          4.@Inherited

          16.Java中String的了解

          在源碼中String是用final?進(jìn)行修飾,它是不可更改,不可繼承的常量。

          17.String為什么要設(shè)計成不可變的?

          1. 字符串池的需求

          字符串池是方法區(qū)(Method Area)中的一塊特殊的存儲區(qū)域。當(dāng)一個字符串已經(jīng)被創(chuàng)建并且該字符串在 池 中,該字符串的引用會立即返回給變量,而不是重新創(chuàng)建一個字符串再將引用返回給變量。如果字符串不是不可變的,那么改變一個引用(如: string2)的字符串將會導(dǎo)致另一個引用(如: string1)出現(xiàn)臟數(shù)據(jù)。

          1. 允許字符串緩存哈希碼

          Java中常常會用到字符串的哈希碼,例如:HashMap?。String的不變性保證哈希碼始終一,因此,他可以不用擔(dān)心變化的出現(xiàn)。這種方法意味著不必每次使用時都重新計算一次哈希碼——這樣,效率會高很多。

          1. 安全

          String廣泛的用于java?類中的參數(shù),如:網(wǎng)絡(luò)連接(Network connetion),打開文件(opening files )等等。如果String是可變的,網(wǎng)絡(luò)連接、文件將會被改變——這將會導(dǎo)致一系列的安全威脅。操作的方法本以為連接上了一臺機(jī)器,但實(shí)際上卻不是。由于反射中的參數(shù)都是字符串,同樣,也會引起一系列的安全問題。

          18.Object類的equal和hashCode方法重寫,為什么?

          首先equalshashcode間的關(guān)系是這樣的:

          1. 如果兩個對象相同(即用equals比較返回true),那么它們的hashCode值一定要相同;

          2. 如果兩個對象的hashCode相同,它們并不一定相同(即用equals比較返回false)。

          由于為了提高程序的效率才實(shí)現(xiàn)了hashcode方法,先進(jìn)行hashcode的比較,如果不同,那沒就不必在進(jìn)行equals的比較了,這樣就大大減少了equals比較的次數(shù),這對比需要比較的數(shù)量很大的效率提高是很明顯的

          19.List,Set,Map的區(qū)別

          Set
          是最簡單的一種集合。集合中的對象不按特定的方式排序,并且沒有重復(fù)對象。?Set接口主要實(shí)現(xiàn)了兩個實(shí)現(xiàn)類:
          HashSet:
          HashSet類按照哈希算法來存取集合中的對象,存取速度比較快

          TreeSet :
          TreeSet類實(shí)現(xiàn)了SortedSet接口,能夠?qū)现械膶ο筮M(jìn)行排序。

          List
          是其元素以線性方式存儲,集合中可以存放重復(fù)對象。

          ArrayList() :
          代表長度可以改變得數(shù)組??梢詫υ剡M(jìn)行隨機(jī)的訪問,向ArrayList()中插入與刪除元素的速度慢。

          LinkedList():
          在實(shí)現(xiàn)中采用鏈表數(shù)據(jù)結(jié)構(gòu)。插入和刪除速度快,訪問速度慢。

          Map
          是一種把鍵對象和值對象映射的集合,它的每一個元素都包含一對鍵對象和值對象。?Map沒有繼承于Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應(yīng)的值對象。

          HashMap:
          Map基于散列表的實(shí)現(xiàn)。插入和查詢鍵值對的開銷是固定的。可以通過構(gòu)造器設(shè)置容量capacity和負(fù)載因子load factor,以調(diào)整容器的性能。

          LinkedHashMap:
          類似于HashMap,但是迭代遍歷它時,取得鍵值對的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點(diǎn)。而在迭代訪問時發(fā)而更快,因為它使用鏈表維護(hù)內(nèi)部次序。

          TreeMap :
          基于紅黑樹數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)。查看鍵值對時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點(diǎn)在 于,你得到的結(jié)果是經(jīng)過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。

          WeakHashMao :
          弱鍵(weak key)Map,Map中使用的對象也被允許釋放: 這是為解決特殊問題設(shè)計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。

          20.ArrayMap和HashMap的對比

          1. 存儲方式不同

          HashMap內(nèi)部有一個HashMapEntry[]對象,每一個鍵值對都存儲在這個對象里,當(dāng)使用put方法添加鍵值對時,就會new一個HashMapEntry對象,

          1. 添加數(shù)據(jù)時擴(kuò)容時的處理不一樣,進(jìn)行了new操作,重新創(chuàng)建對象,開銷很大。ArrayMap用的是copy數(shù)據(jù),所以效率相對要高。

          3.ArrayMap提供了數(shù)組收縮的功能,在clearremove后,會重新收縮數(shù)組,是否空間

          1. ArrayMap采用二分法查找;

          21.HashMap和HashTable的區(qū)別

          HashMap
          不是線程安全的,效率高一點(diǎn)、方法不是Synchronize的要提供外同步,有containsvaluecontainsKey方法。

          hashtable
          是線程安全,不允許有null的鍵和值,效率稍低,方法是是Synchronize的。有contains方法方法。Hashtable繼承于Dictionary?類

          22.HashMap與HashSet的區(qū)別

          hashMap:
          HashMap實(shí)現(xiàn)了Map接口,HashMap儲存鍵值對,使用put()方法將元素放入map中,HashMap中使用鍵對象來計算hashcode值,HashMap比較快,因為是使用唯一的鍵來獲取對象。

          HashSet
          實(shí)現(xiàn)了Set接口,HashSet僅僅存儲對象,使用add()方法將元素放入set中,HashSet使用成員對象來計算hashcode值,對于兩個對象來說hashcode可能相同,所以equals()方法用來判斷對象的相等性,如果兩個對象不同的話,那么返回false。HashSetHashMap來說比較慢。

          23.HashSet與HashMap怎么判斷集合元素重復(fù)?

          HashSet
          不能添加重復(fù)的元素,當(dāng)調(diào)用add(Object)方法時候,

          首先會調(diào)用ObjecthashCode方法判hashCode是否已經(jīng)存在,如不存在則直接插入元素;如果已存在則調(diào)用Object對象的equals方法判斷是否返回true,如果為true則說明元素已經(jīng)存在,如為false則插入元素。

          24.ArrayList和LinkedList的區(qū)別,以及應(yīng)用場景

          ArrayList
          是基于數(shù)組實(shí)現(xiàn)的,ArrayList線程不安全。

          LinkedList
          是基于雙鏈表實(shí)現(xiàn)的:

          使用場景:

          1. 如果應(yīng)用程序?qū)Ω鱾€索引位置的元素進(jìn)行大量的存取或刪除操作,ArrayList對象要遠(yuǎn)優(yōu)于LinkedList對象;

          2. 如果應(yīng)用程序主要是對列表進(jìn)行循環(huán),并且循環(huán)時候進(jìn)行插入或者刪除操作,LinkedList對象要遠(yuǎn)優(yōu)于ArrayList對象;

          25.數(shù)組和鏈表的區(qū)別

          數(shù)組:
          是將元素在內(nèi)存中連續(xù)存儲的;它的優(yōu)點(diǎn):因為數(shù)據(jù)是連續(xù)存儲的,內(nèi)存地址連續(xù),所以在查找數(shù)據(jù)的時候效率比較高;它的缺點(diǎn):在存儲之前,我們需要申請一塊連續(xù)的內(nèi)存空間,并且在編譯的時候就必須確定好它的空間的大小。在運(yùn)行的時候空間的大小是無法隨著你的需要進(jìn)行增加和減少而改變的,當(dāng)數(shù)據(jù)兩比較大的時候,有可能會出現(xiàn)越界的情況,數(shù)據(jù)比較小的時候,又有可能會浪費(fèi)掉內(nèi)存空間。在改變數(shù)據(jù)個數(shù)時,增加、插入、刪除數(shù)據(jù)效率比較低。

          鏈表:
          是動態(tài)申請內(nèi)存空間,不需要像數(shù)組需要提前申請好內(nèi)存的大小,鏈表只需在用的時候申請就可以,根據(jù)需要來動態(tài)申請或者刪除內(nèi)存空間,對于數(shù)據(jù)增加和刪除以及插入比數(shù)組靈活。還有就是鏈表中數(shù)據(jù)在內(nèi)存中可以在任意的位置,通過應(yīng)用來關(guān)聯(lián)數(shù)據(jù)(就是通過存在元素的指針來聯(lián)系)

          26.開啟線程的三種方式?

          Java有三種創(chuàng)建線程的方式,分別是
          繼承Thread類、實(shí)現(xiàn)Runable接口使用線程池。

          27.線程和進(jìn)程的區(qū)別?

          線程是進(jìn)程的子集,一個進(jìn)程可以有很多線程,每條線程并行執(zhí)行不同的任務(wù)。不同的進(jìn)程使用不同的內(nèi)存空間,而所有的線程共享一片相同的內(nèi)存空間。別把它和棧內(nèi)存搞混,每個線程都擁有單獨(dú)的棧內(nèi)存用來存儲本地數(shù)據(jù)。

          28.run()和start()方法區(qū)別

          這個問題經(jīng)常被問到,但還是能從此區(qū)分出面試者對Java線程模型的理解程度。start()方法被用來啟動新創(chuàng)建的線程,而且start()內(nèi)部調(diào)用了run()方法,這和直接調(diào)用run()方法的效果不一樣。當(dāng)你調(diào)用run()方法的時候,只會是在原來的線程中調(diào)用,沒有新的線程啟動,start()方法才會啟動新線程。

          30.如何控制某個方法允許并發(fā)訪問線程的個數(shù)?

          semaphore.acquire()請求一個信號量,這時候的信號量個數(shù)-1(一旦沒有可使用的信號量,也即信號量個數(shù)變?yōu)樨?fù)數(shù)時,再次請求的時候就會阻塞,直到其他線程釋放了信號量)

          semaphore.release()釋放一個信號量,此時信號量個數(shù)+1

          31.在Java中wait和seelp方法的不同;

          Java程序中waitsleep都會造成某種形式的暫停,它們可以滿足不同的需要。wait()方法用于線程間通信,如果等待條件為真且其它線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放CPU資源或者讓當(dāng)前線程停止執(zhí)行一段時間,但不會釋放鎖。

          32.談?wù)剋ait/notify關(guān)鍵字的理解

          等待對象的同步鎖,需要獲得該對象的同步鎖才可以調(diào)用這個方法,否則編譯可以通過,但運(yùn)行時會收到一個異常:IllegalMonitorStateException。

          調(diào)用任意對象的?wait()方法導(dǎo)致該線程阻塞,該線程不可繼續(xù)執(zhí)行,并且該對象上的鎖被釋放。

          喚醒在等待該對象同步鎖的線程(只喚醒一個,如果有多個在等待),注意的是在調(diào)用此方法的時候,并不能確切的喚醒某一個等待狀態(tài)的線程,而是由JVM確定喚醒哪個線程,而且不是按優(yōu)先級。

          調(diào)用任意對象的notify()方法則導(dǎo)致因調(diào)用該對象的wait()方法而阻塞的線程中隨機(jī)選擇的一個解除阻塞(但要等到獲得鎖后才真正可執(zhí)行)。

          33.什么導(dǎo)致線程阻塞?線程如何關(guān)閉?

          阻塞式方法是指程序會一直等待該方法完成期間不做其他事情,ServerSocketaccept()方法就是一直等待客戶端連接。這里的阻塞是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起,直到得到結(jié)果之后才會返回。此外,還有異步和非阻塞式方法在任務(wù)完成前就返回。

          一種是調(diào)用它里面的stop()方法

          另一種就是你自己設(shè)置一個停止線程的標(biāo)記 (推薦這種)

          34.如何保證線程安全?

          • 1.synchronized;

          • 2.Object方法中的wait,notify;

          • 3.ThreadLocal機(jī)制 來實(shí)現(xiàn)的。

          35.如何實(shí)現(xiàn)線程同步?

          1. synchronized關(guān)鍵字修改的方法。

          2. synchronized關(guān)鍵字修飾的語句塊

          3. 使用特殊域變量(volatile)實(shí)現(xiàn)線程同步

          36.線程間操作List

          List list = Collections.synchronizedList(new ArrayList());

          37.談?wù)剬ynchronized關(guān)鍵字,類鎖,方法鎖,重入鎖的理解

          java的對象鎖和類鎖:
          java的對象鎖和類鎖在鎖的概念上基本上和內(nèi)置鎖是一致的,但是,兩個鎖實(shí)際是有很大的區(qū)別的,對象鎖是用于對象實(shí)例方法,或者一個對象實(shí)例上的,類鎖是用于類的靜態(tài)方法或者一個類的class對象上的。我們知道,類的對象實(shí)例可以有很多個,但是每個類只有一個class對象,所以不同對象實(shí)例的對象鎖是互不干擾的,但是每個類只有一個類鎖。但是有一點(diǎn)必須注意的是,其實(shí)類鎖只是一個概念上的東西,并不是真實(shí)存在的,它只是用來幫助我們理解鎖定實(shí)例方法和靜態(tài)方法的區(qū)別的

          38.synchronized 和volatile 關(guān)鍵字的區(qū)別

          1.volatile本質(zhì)是在告訴jvm當(dāng)前變量在寄存器(工作內(nèi)存)中的值是不確定的,需要從主存中讀??;synchronized則是鎖定當(dāng)前變量,只有當(dāng)前線程可以訪問該變量,其他線程被阻塞住。

          1. volatile僅能使用在變量級別;synchronized則可以使用在變量、方法、和類級別的

          2. volatile僅能實(shí)現(xiàn)變量的修改可見性,不能保證原子性;而synchronized則可以保證變量的修改可見性和原子性
            4.volatile不會造成線程的阻塞;synchronized可能會造成線程的阻塞。
            5.volatile標(biāo)記的變量不會被編譯器優(yōu)化;synchronized標(biāo)記的變量可以被編譯器優(yōu)化

          39.ReentrantLock 、synchronized和volatile比較

          Java在過去很長一段時間只能通過synchronized關(guān)鍵字來實(shí)現(xiàn)互斥,它有一些缺點(diǎn)。比如你不能擴(kuò)展鎖之外的方法或者塊邊界,嘗試獲取鎖時不能中途取消等。Java 5?通過Lock接口提供了更復(fù)雜的控制來解決這些問題。?ReentrantLock類實(shí)現(xiàn)了?Lock,它擁有與synchronized相同的并發(fā)性和內(nèi)存語義且它還具有可擴(kuò)展性。

          40.死鎖的四個必要條件?

          死鎖產(chǎn)生的原因

          1. 系統(tǒng)資源的競爭
            系統(tǒng)資源的競爭導(dǎo)致系統(tǒng)資源不足,以及資源分配不當(dāng),導(dǎo)致死鎖。

          2. 進(jìn)程運(yùn)行推進(jìn)順序不合適
            互斥條件:
            一個資源每次只能被一個進(jìn)程使用,即在一段時間內(nèi)某 資源僅為一個進(jìn)程所占有。此時若有其他進(jìn)程請求該資源,則請求進(jìn)程只能等待。
            請求與保持條件:
            進(jìn)程已經(jīng)保持了至少一個資源,但又提出了新的資源請求,而該資源 已被其他進(jìn)程占有,此時請求進(jìn)程被阻塞,但對自己已獲得的資源保持不放。
            不可剝奪條件:
            進(jìn)程所獲得的資源在未使用完畢之前,不能被其他進(jìn)程強(qiáng)行奪走,即只能 由獲得該資源的進(jìn)程自己來釋放(只能是主動釋放)。
            循環(huán)等待條件:
            若干進(jìn)程間形成首尾相接循環(huán)等待資源的關(guān)系
            這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖。

          死鎖的避免與預(yù)防

          死鎖避免的基本思想:
          系統(tǒng)對進(jìn)程發(fā)出每一個系統(tǒng)能夠滿足的資源申請進(jìn)行動態(tài)檢查,并根據(jù)檢查結(jié)果決定是否分配資源,如果分配后系統(tǒng)可能發(fā)生死鎖,則不予分配,否則予以分配。這是一種保證系統(tǒng)不進(jìn)入死鎖狀態(tài)的動態(tài)策略。
          理解了死鎖的原因,尤其是產(chǎn)生死鎖的四個必要條件,就可以最大可能地避免、預(yù)防和解除死鎖。所以,在系統(tǒng)設(shè)計、進(jìn)程調(diào)度等方面注意如何讓這四個必要條件不成立,如何確定資源的合理分配算法,避免進(jìn)程永久占據(jù)系統(tǒng)資源。此外,也要防止進(jìn)程在處于等待狀態(tài)的情況下占用資源。因此,對資源的分配要給予合理的規(guī)劃。
          死鎖預(yù)防是設(shè)法至少破壞產(chǎn)生死鎖的四個必要條件之一,嚴(yán)格的防止死鎖的出現(xiàn),而死鎖避免則不那么嚴(yán)格的限制產(chǎn)生死鎖的必要條件的存在,因為即使死鎖的必要條件存在,也不一定發(fā)生死鎖。死鎖避免是在系統(tǒng)運(yùn)行過程中注意避免死鎖的最終發(fā)生。

          41.什么是線程池,如何使用?

          創(chuàng)建線程要花費(fèi)昂貴的資源和時間,如果任務(wù)來了才創(chuàng)建線程那么響應(yīng)時間會變長,而且一個進(jìn)程能創(chuàng)建的線程數(shù)有限。為了避免這些問題,在程序啟動的時候就創(chuàng)建若干線程來響應(yīng)處理,它們被稱為線程池,里面的線程叫工作線程。從JDK1.5開始,Java API提供了Executor框架讓你可以創(chuàng)建不同的線程池。比如單線程池,每次處理一個任務(wù);數(shù)目固定的線程池或者是緩存線程池(一個適合很多生存期短的任務(wù)的程序的可擴(kuò)展線程池)。

          42.Java中堆和棧有什么不同?

          為什么把這個問題歸類在多線程和并發(fā)面試題里?因為棧是一塊和線程緊密相關(guān)的內(nèi)存區(qū)域。每個線程都有自己的棧內(nèi)存,用于存儲本地變量,方法參數(shù)和棧調(diào)用,一個線程中存儲的變量對其它線程是不可見的。而堆是所有線程共享的一片公用內(nèi)存區(qū)域。對象都在堆里創(chuàng)建,為了提升效率線程會從堆中弄一個緩存到自己的棧,如果多個線程使用該變量就可能引發(fā)問題,這時volatile變量就可以發(fā)揮作用了,它要求線程從主存中讀取變量的值。

          43.有三個線程T1,T2,T3,怎么確保它們按順序執(zhí)行?

          在多線程中有多種方法讓線程按特定順序執(zhí)行,你可以用線程類的join()方法在一個線程中啟動另一個線程,另外一個線程完成該線程繼續(xù)執(zhí)行。為了確保三個線程的順序你應(yīng)該先啟動最后一個(T3調(diào)用T2,T2調(diào)用T1),這樣T1就會先完成而T3最后完成。

          線程間通信
          我們知道線程是CPU調(diào)度的最小單位。在Android中主線程是不能夠做耗時操作的,子線程是不能夠更新UI的。而線程間通信的方式有很多,比如廣播,Eventbus,接口回掉,在Android中主要是使用handlerhandler通過調(diào)用sendmessage方法,將保存消息的Message發(fā)送到Messagequeue中,而looper對象不斷的調(diào)用loop方法,從messageueue中取出message,交給handler處理,從而完成線程間通信。

          至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,歡迎點(diǎn)擊閱讀原文,支持原創(chuàng)作者,如有侵權(quán),懇請聯(lián)系小編刪除。同時感謝您的閱讀,期待您的關(guān)注。


          瀏覽 73
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产福利在线导航 | 欧美人与禽乱婬A片 | 亚洲图片小说在线视频 | 中文字幕无码视频免费 | 男人的天堂网2 |