前言
最近金三銀四淳附,相信不少朋友都在躍躍欲動(dòng)帮辟,看看市場(chǎng)機(jī)會(huì),此份Java整理是平安科技(陸金所)項(xiàng)目組大神整理的Java面試資料(良心作品,都是精髓)幫你助力逆粹!
Java基礎(chǔ)
Http1與Http2的區(qū)別?
1?HTTP2使用的是二進(jìn)制傳送募疮,HTTP1.X是文本(字符串)傳送。 大家都知道HTTP1.X使用的是明文的文本傳送僻弹,而HTTP2使用的是二進(jìn)制傳送酝锅,二進(jìn)制傳送的單位是幀和流。幀組成了流奢方,同時(shí)流還有流ID標(biāo)示,通過(guò)流ID就牽扯出了第二個(gè)區(qū)別爸舒。
2?HTTP2支持多路復(fù)用蟋字。因?yàn)橛辛鱅D,所以通過(guò)同一個(gè)http請(qǐng)求實(shí)現(xiàn)多個(gè)http請(qǐng)求傳輸變成了可能扭勉,可以通過(guò)流ID來(lái)標(biāo)示究竟是哪個(gè)流從而定位到是哪個(gè)http請(qǐng)求鹊奖。
3?HTTP2頭部壓縮。HTTP2通過(guò)gzip和compress壓縮頭部然后再發(fā)送涂炎,同時(shí)客戶端和服務(wù)器端同時(shí)維護(hù)一張頭信息表忠聚,所有字段都記錄在這張表中,這樣后面每次傳輸只需要傳輸表里面的索引Id就行唱捣,通過(guò)索引ID就可以知道表頭的值了两蟀。
4?HTTP2支持服務(wù)器推送。HTTP2支持在客戶端未經(jīng)請(qǐng)求許可的情況下震缭,主動(dòng)向客戶端推送內(nèi)容赂毯。
String能被繼承嗎?? 為什么?
1?不可以,因?yàn)镾tring類(lèi)有final修飾符拣宰,而final修飾的類(lèi)是不能被繼承的党涕,實(shí)現(xiàn)細(xì)節(jié)不允許改變。
什么是深拷貝和淺拷貝?
一般步驟是(淺復(fù)制):
1?被復(fù)制的類(lèi)需要實(shí)現(xiàn)Clonenable接口(不實(shí)現(xiàn)的話在調(diào)用clone方法會(huì)拋出CloneNotSupportedException異常) 該接口為標(biāo)記接口(不含任何方法)
2?覆蓋clone()方法巡社,訪問(wèn)修飾符設(shè)為public膛堤。方法中調(diào)用super.clone()方法得到需要的復(fù)制對(duì)象,(native為本地方法)
3?總結(jié):淺拷貝是指在拷貝對(duì)象時(shí)晌该,對(duì)于基本數(shù)據(jù)類(lèi)型的變量會(huì)重新復(fù)制一份肥荔,而對(duì)于引用類(lèi)型的變量只是對(duì)引用進(jìn)行拷貝,沒(méi)有對(duì)引用指向的對(duì)象進(jìn)行拷貝气笙。而深拷貝是指在拷貝對(duì)象時(shí)次企,同時(shí)會(huì)對(duì)引用指向的對(duì)象進(jìn)行拷貝。區(qū)別就在于是否對(duì) 對(duì)象中的引用變量所指向的對(duì)象進(jìn)行拷貝潜圃。
說(shuō)說(shuō)常見(jiàn)的幾個(gè)運(yùn)行時(shí)異常
1缸棵、ClassCastException
2、NullPointerException
3谭期、ArrayIndexOutOfBoundsException
4堵第、NumberFormatException
5吧凉、NoClassDefFoundException
.....
JDK引入泛型是解決什么問(wèn)題的?
Java語(yǔ)言引入泛型的好處是安全簡(jiǎn)單。 在Java SE 1.5之前踏志,沒(méi)有泛型的情況的下阀捅,通過(guò)對(duì)類(lèi)型Object的
引用來(lái)實(shí)現(xiàn)參數(shù)的“任意化”,“任意化”帶來(lái)的缺點(diǎn)是要做顯式的強(qiáng)制類(lèi)型轉(zhuǎn)換针余,而這種轉(zhuǎn)換是要求開(kāi)發(fā)者對(duì)實(shí)際參數(shù)類(lèi)型可以預(yù)知的情況下進(jìn)行的饲鄙。對(duì)于強(qiáng)制類(lèi)型轉(zhuǎn)換錯(cuò)誤的情況,編譯器可能不提示錯(cuò)誤圆雁,在運(yùn)行的時(shí)候才出現(xiàn)異常忍级,這是一個(gè)安全隱患。 泛型的好處是在編譯的時(shí)候檢查類(lèi)型安全伪朽,并且所有的強(qiáng)制轉(zhuǎn)換都是自動(dòng)和隱式的轴咱,提高代碼的重用率。
談?wù)刪ashCode與equals之間的關(guān)系
??????? 因?yàn)槿绻桓采w了equals而沒(méi)有覆蓋hashCode, 則兩個(gè)不同的instance a和b雖然equals結(jié)果(業(yè)務(wù)邏輯上)相等,但卻會(huì)有不同的hashcode,這樣hashmap里面會(huì)同時(shí)存在a和b,而實(shí)際上我們需要hashmap里面只能保存其中一個(gè),因?yàn)閺臉I(yè)務(wù)邏輯方向看它們是相等的烈涮。 equals方法和hashCode方法如果不同時(shí)按你自己邏輯覆蓋的話朴肺,HashMap就會(huì)出問(wèn)題。比如你只覆蓋了equals方法而沒(méi)有覆蓋hashCode方法坚洽,那么HashMap在第一步尋找鏈表的時(shí)候會(huì)出錯(cuò)戈稿,有同樣值的兩個(gè)對(duì)象Key1和Key2并不會(huì)指向同一個(gè)鏈表或桶,因?yàn)槟銢](méi)有提供自己的hashCode方法酪术,那么就會(huì)使用Object的hashCode方法器瘪,該方法是根據(jù)內(nèi)存地址來(lái)比較兩個(gè)對(duì)象是否一致,由于Key1和Key2有不桶的內(nèi)存地址绘雁,所以會(huì)指向不同的鏈表橡疼,這樣HashMap會(huì)認(rèn)為key2不存在,雖然我們期望Key1和Key2是同一個(gè)對(duì)象;反之如果只覆蓋了hashCode方法而沒(méi)有覆蓋equals方法庐舟,那么雖然第一步操作會(huì)使Key1和Key2找到同一個(gè)鏈表欣除,但是由于equals沒(méi)有覆蓋,那么在遍歷鏈表的元素時(shí)挪略,key1.equals(key2)也會(huì)失敗(事實(shí)上Object的equals方法也是比較內(nèi)存地址)历帚,從而HashMap認(rèn)為不存在Key2對(duì)象,這同樣也是不正確的杠娱。
談?wù)劮瓷錂C(jī)制挽牢?
1.何謂反射機(jī)制。
??????? JAVA反射機(jī)制是在運(yùn)行狀態(tài)中摊求,對(duì)于任意一個(gè)類(lèi)禽拔,都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制。
2.反射機(jī)制如何實(shí)現(xiàn)睹栖。
??????? Java程序在運(yùn)行時(shí)硫惕,Java運(yùn)行時(shí)系統(tǒng)一直對(duì)所有的對(duì)象進(jìn)行所謂的運(yùn)行時(shí)類(lèi)型標(biāo)識(shí)。這項(xiàng)信息紀(jì)錄了每個(gè)對(duì)象所屬的類(lèi)野来。虛擬機(jī)通常使用運(yùn)行時(shí)類(lèi)型信息選準(zhǔn)正確方法去執(zhí)行恼除,用來(lái)保存這些類(lèi)型信息的類(lèi)是Class類(lèi)。也就是說(shuō)曼氛,ClassLoader找到了需要調(diào)用的類(lèi)時(shí)(java為了調(diào)控內(nèi)存的調(diào)用消耗豁辉,類(lèi)的加載都在需要時(shí)再進(jìn)行,很摳但是很有效)舀患,就會(huì)加載它秋忙,然后根據(jù).class文件內(nèi)記載的類(lèi)信息來(lái)產(chǎn)生一個(gè)與該類(lèi)相聯(lián)系的獨(dú)一無(wú)二的Class對(duì)象。該Class對(duì)象記載了該類(lèi)的字段构舟,方法等等信息。以后jvm要產(chǎn)生該類(lèi)的實(shí)例堵幽,就是根據(jù)內(nèi)存中存在的該Class類(lèi)所記載的信息(Class對(duì)象應(yīng)該和我所了解的其他類(lèi)一樣會(huì)在堆內(nèi)存內(nèi)產(chǎn)生狗超、消亡)來(lái)進(jìn)行。而java中的Class類(lèi)對(duì)象是可以人工自然性的(也就是說(shuō)開(kāi)放的)得到的(雖然你無(wú)法像其他類(lèi)一樣運(yùn)用構(gòu)造器來(lái)得到它的實(shí)例朴下,因?yàn)镃lass對(duì)象都是jvm產(chǎn)生的努咐。不過(guò)話說(shuō)回來(lái),客戶產(chǎn)生的話也是無(wú)意義的)殴胧,而且渗稍,更偉大的是,基于這個(gè)基礎(chǔ)团滥,java實(shí)現(xiàn)了反射竿屹。
3.獲取Class對(duì)象有三種方式:
1).通過(guò)Object類(lèi)的getClass()方法。
2).通過(guò)Class類(lèi)的靜態(tài)方法——forName()來(lái)實(shí)現(xiàn)灸姊。
3).如果T是一個(gè)已定義的類(lèi)型的話拱燃,在java中,它的.class文件名:T.class就代表了與其匹配的Class對(duì)象力惯。
常用的JVM設(shè)置參數(shù)都有哪些?
整體考慮堆大小
-Xms3550m碗誉, 初始化堆大小。通常情況和-Xmx大小設(shè)置一樣父晶,避免虛擬機(jī)頻繁自動(dòng)計(jì)算后調(diào)整堆大小哮缺。-Xmx3550m,最大堆大小甲喝。
新生代
-xmn2g尝苇,新生代大小。Sun官方推薦配置為整個(gè)堆的3/8。-XX:SurvivorRatio=8茎匠。Eden和Survivor的比值格仲。
老年代
老年代=整個(gè)堆大小-新生代-永久代
永久代
-XX:Permsize=512m,設(shè)置永久代初始值。-XX:MaxPermsize=512m诵冒,設(shè)置永久代的最大值凯肋。
注:Java8沒(méi)有永久代說(shuō)法,它們被稱(chēng)為元空間,-XX:MetaspaceSize=N
考慮本機(jī)直接內(nèi)存
-XX:MaxDirectMemorySize=100M汽馋。默認(rèn)與Java堆大最大值(-Xmx)
考慮虛擬機(jī)棧
每個(gè)線程池的堆棧大小侮东。在jdk5以上的版本,每個(gè)線程堆棧大小為1m豹芯,jdk5以前的版本是每個(gè)線程池大小
為256k悄雅。一般設(shè)置256k。 -Xss256K铁蹈。
......
HashMap和HashTable的區(qū)別?
1宽闲、繼承的父類(lèi)不同。 Hashtable繼承自Dictionary類(lèi)握牧,而HashMap繼承自AbstractMap類(lèi)容诬。但二者都實(shí)現(xiàn)了Map接口。
2沿腰、線程安全性不同览徒。Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情況下是非Synchronize的颂龙。在多線程并發(fā)的環(huán)境下习蓬,可以直接使用Hashtable,不需要自己為它的方法實(shí)現(xiàn)同步措嵌,但使用HashMap時(shí)就必須要自己增加同步處理躲叼。(結(jié)構(gòu)上的修改是指添加或刪除一個(gè)或多個(gè)映射關(guān)系的任何操作;僅改變與實(shí)例已經(jīng)包含的鍵關(guān)聯(lián)的值不是結(jié)構(gòu)上的修改。)這一般通過(guò)對(duì)自然封裝該映射的對(duì)象進(jìn)行同步操作來(lái)完成企巢。如果不存在這樣的對(duì)象押赊,則應(yīng)該使用 Collections.synchronizedMap 方法來(lái)“包裝”該映射。最好在創(chuàng)建時(shí)完成這一操作包斑,以防止對(duì)映射進(jìn)行意外的非同步訪問(wèn)流礁。
3、是否提供contains方法罗丰。 HashMap把Hashtable的contains方法去掉了神帅,改成containsValue和containsKey,因?yàn)閏ontains方法容易讓人引起誤解萌抵。Hashtable則保留了contains找御,containsValue和containsKey三個(gè)方法元镀,其中contains和containsValue功能相同。
4霎桅、key和value是否允許null值栖疑。 Hashtable中,key和value都不允許出現(xiàn)null值滔驶。但是如果在Hashtable中有類(lèi)似put(null,null)的操作遇革,編譯同樣可以通過(guò),因?yàn)閗ey和value都是Object類(lèi)型揭糕,但運(yùn)行時(shí)會(huì)拋出NullPointerException異常萝快,這是JDK的規(guī)范規(guī)定的。HashMap中著角,null可以作為鍵揪漩,這樣的鍵只有一個(gè),可以有一個(gè)或多個(gè)鍵所對(duì)應(yīng)的值為null吏口。
5奄容、兩個(gè)遍歷方式的內(nèi)部實(shí)現(xiàn)上不同。 Hashtable产徊、HashMap都使用了 Iterator嫩海。而由于歷史原因,Hashtable還使用了Enumeration的方式 囚痴。
6、hash值不同审葬。哈希值的使用不同深滚,HashTable直接使用對(duì)象的hashCode。而HashMap重新計(jì)算hash值涣觉。
7痴荐、內(nèi)部實(shí)現(xiàn)使用的數(shù)組初始化和擴(kuò)容方式不同。HashTable在不指定容量的情況下的默認(rèn)容量為11官册,而HashMap為16生兆,Hashtable不要求底層數(shù)組的容量一定要為2的整數(shù)次冪,而HashMap則要求一定為2的整數(shù)次冪膝宁。Hashtable擴(kuò)容時(shí)鸦难,將容量變?yōu)樵瓉?lái)的2倍加1,而HashMap擴(kuò)容時(shí)员淫,將容量變?yōu)樵瓉?lái)的2倍合蔽。
ArrayList和Vector的主要區(qū)別?
1?Vector是線程安全的,源碼中有很多的synchronized可以看出介返,而ArrayList不是拴事。導(dǎo)致Vector效率無(wú)法和ArrayList相比;
2?ArrayList和Vector都采用線性連續(xù)存儲(chǔ)空間沃斤,當(dāng)存儲(chǔ)空間不足的時(shí)候,ArrayList默認(rèn)增加為原來(lái)的50%刃宵,Vector默認(rèn)增加為原來(lái)的一倍;3.Vector可以設(shè)置capacityIncrement衡瓶,而ArrayList不可以,從字面理解就是capacity容量牲证,Increment增加哮针,容量增長(zhǎng)的參數(shù)。
List是有序的嗎?
有序可重。有序或無(wú)序是指是否按照其添加的順序來(lái)存儲(chǔ)對(duì)象犁珠。List 是按照元素的添加順序來(lái)存儲(chǔ)的材诽。
ArrayList和LinkedList的區(qū)別?分別用在什么場(chǎng)景?
1?ArrayList是最常用的List實(shí)現(xiàn)類(lèi),內(nèi)部是通過(guò)數(shù)組實(shí)現(xiàn)的寿烟,它允許對(duì)元素進(jìn)行快速隨機(jī)訪問(wèn)。數(shù)組的缺點(diǎn)是每個(gè)元素之間不能有間隔辛燥,當(dāng)數(shù)組大小不滿足時(shí)需要增加存儲(chǔ)能力筛武,就要講已經(jīng)有數(shù)組的數(shù)據(jù)復(fù)制到新的存儲(chǔ)空間中。當(dāng)從ArrayList的中間位置插入或者刪除元素時(shí)挎塌,需要對(duì)數(shù)組進(jìn)行復(fù)制徘六、移動(dòng)、代價(jià)比較高榴都。因此待锈,它適合隨機(jī)查找和遍歷,不適合插入和刪除嘴高。
2?LinkedList是用鏈表結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)的竿音,很適合數(shù)據(jù)的動(dòng)態(tài)插入和刪除,隨機(jī)訪問(wèn)和遍歷速度比較慢拴驮。另外春瞬,他還提供了List接口中沒(méi)有定義的方法,專(zhuān)門(mén)用于操作表頭和表尾元素套啤,可以當(dāng)作堆棧宽气、隊(duì)列和雙向隊(duì)列使用。
ArrayList默認(rèn)大小是多少潜沦,是如何擴(kuò)容的?
ArrayList默認(rèn)構(gòu)造的容量為10萄涯,沒(méi)錯(cuò)。 因?yàn)锳rrayList的底層是由一個(gè)Object[]數(shù)組構(gòu)成的唆鸡,而這個(gè)Object[]數(shù)組窃判,默認(rèn)的長(zhǎng)度是10,所以有的文章會(huì)說(shuō)ArrayList長(zhǎng)度容量為10喇闸。然而你所指的size()方法袄琳,指的是“邏輯”長(zhǎng)度询件。ArrayList默認(rèn)size()是0。ArrayList之后擴(kuò)容會(huì)按照1.5倍增長(zhǎng)唆樊。
List是線程安全的嗎?如果要線程安全要怎么做?
不安全宛琅。實(shí)現(xiàn)線程安全方法:
1?使用synchronized關(guān)鍵字。
2?使用Collections.synchronizedList()逗旁。
怎么給List排序?
1?實(shí)體類(lèi)自己實(shí)現(xiàn)比較嘿辟。實(shí)現(xiàn)comparable接口:public interface Comparable ,里面就一個(gè)方法聲明:public int compareTo(T o);用Java中提供的對(duì)集合進(jìn)行操作的工具類(lèi)Collections片效,其中的sort方法
2?Collections提供的第二種排序方法sort(List list, Comparator c)红伦。
Arrays.asList方法后的List可以擴(kuò)容嗎?
不能!原因是Arrays.asList方法返回的ArrayList是繼承自AbstractList同時(shí)實(shí)現(xiàn)了RandomAccess和Serializable接口淀衣。如果改變長(zhǎng)度會(huì)拋出UnsupportedOperationException異常昙读。
List和Array之間如何互相轉(zhuǎn)換?
list -> array =list.toArray()
array -> list = Arrays.asList()
迭代器循環(huán)法。
Collection集合接口和Map接口有什么關(guān)系?
都是集合框架體系膨桥,Collection定義的是單列集合蛮浑。Map定義的是雙列集合。
HashMap是線程安全的嗎?線程安全的Map都有哪些?性能最好的是哪個(gè)?
HashMap不安全只嚣,線程安全的Map有hashTable沮稚、ConcurrentHashMap、通過(guò)Collections.synchronizedMap()册舞。性能最好的是ConcurrentHashMap蕴掏。通過(guò)分段鎖來(lái)實(shí)現(xiàn)線程安全,默認(rèn)并發(fā)數(shù)是16调鲸,擴(kuò)容是按16的倍數(shù)增長(zhǎng)盛杰。hashMAP實(shí)現(xiàn)原理是由hash數(shù)組為主,存儲(chǔ)一個(gè)key-val結(jié)構(gòu)entry類(lèi)的數(shù)組线得,當(dāng)出現(xiàn)hash沖突時(shí),通過(guò)鏈表來(lái)解決問(wèn)題。Jdk1.8中引入了紅黑樹(shù),當(dāng)鏈表的長(zhǎng)度大于8 時(shí)會(huì)自動(dòng)將鏈表轉(zhuǎn)成紅黑樹(shù)徐伐。
hashMAp線程不安全贯钩,hashtable線程安全。Hash Table時(shí)不支持null的办素,hashmap支持nulll是因?yàn)閷ull放入hash表的0個(gè)buchect角雷。
實(shí)現(xiàn)線程安全的兩種方式:Collecttions.synchronizedMap()也可以用ConcurrentHashMap。Jdk7時(shí)通過(guò)桶的分段鎖的方式實(shí)現(xiàn)性穿,默認(rèn)設(shè)置16段勺三,當(dāng)并發(fā)度超過(guò)16段時(shí)按2的指冪增長(zhǎng)。JDK8放棄分段鎖的實(shí)現(xiàn)需曾,通過(guò)節(jié)點(diǎn)的原子鎖來(lái)實(shí)現(xiàn)鎖吗坚。將分段鎖的悲觀鎖改成平臺(tái)型的樂(lè)觀鎖祈远。樂(lè)觀鎖無(wú)法保證臟讀,所以要通過(guò)原子快照來(lái)保證商源。
使用HashMap有什么性能問(wèn)題嗎?
當(dāng)大量的key出現(xiàn)hash沖突時(shí)车份,鏈表會(huì)變長(zhǎng),從而影響get牡彻、put效率扫沼。而且當(dāng)鏈表長(zhǎng)度達(dá)到負(fù)載因子設(shè)置0.75長(zhǎng)度值時(shí),還會(huì)有擴(kuò)容操作會(huì)很影響性能庄吼。
hashMap默認(rèn)大小是多少?內(nèi)部是怎么擴(kuò)容的?
hashMap這里的默認(rèn)值是16缎除。當(dāng)元素個(gè)數(shù)大于0.75×16 = 12時(shí),HashMap會(huì)自動(dòng)進(jìn)行擴(kuò)容总寻。 oldlength *2個(gè)
怎么按添加順序存儲(chǔ)元素?怎么按A-Z自然順序存儲(chǔ)元素?怎么自定義排序?
1?hashMap的存儲(chǔ)是無(wú)序的器罐,想要有序存儲(chǔ)需要在存儲(chǔ)的key有序。其根本原因是存儲(chǔ)位置是由hashcode決定的废菱,hashcode是由key計(jì)算得來(lái)的技矮。
2?通過(guò)Collections.sort()來(lái)排序。
HashMap使用對(duì)象作為key殊轴,如果hashcode相同會(huì)怎么處理?
在hashmap中衰倦,由于key是不可以重復(fù)的,他在判斷key是不是重復(fù)的時(shí)候就判斷了hashcode這個(gè)方法旁理,而且也用到了equals方法樊零。這里不可以重復(fù)是說(shuō)equals和hashcode只要有一個(gè)不等就可以了。
HashMap中的get操作是什么原理?
只需要根據(jù)key的hashcode算出元素在數(shù)組中的下標(biāo),之后遍歷Entry對(duì)象鏈表,直到找到元素為止孽文。
TCP和UDP的區(qū)別驻襟,TCP為什么是三次握手,不是兩次芋哭?
TCP與UDP基本區(qū)別:
1?基于連接與無(wú)連接
2?TCP要求系統(tǒng)資源較多沉衣,UDP較少;
3?UDP程序結(jié)構(gòu)較簡(jiǎn)單
4?流模式(TCP)與數(shù)據(jù)報(bào)模式(UDP);
5?TCP保證數(shù)據(jù)正確性,UDP可能丟包
6?TCP保證數(shù)據(jù)順序减牺,UDP不保證
三次握手過(guò)程:
第一次握手:建立連接時(shí),客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進(jìn)入SYNSEND ,等待服務(wù)器確認(rèn)豌习。
第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶端的SYN ( ack=j+1 )拔疚,同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k)即SYN+ACK包 ,此時(shí)服務(wù)器進(jìn)入 SYNRECV狀態(tài);
第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手肥隆。
switch中可以使用String嗎?
在jdk 7 之前,switch 只能支持 byte稚失、short栋艳、char、int 這幾個(gè)基本數(shù)據(jù)類(lèi)型和其對(duì)應(yīng)的封裝類(lèi)型句各。Java 7中加入了對(duì)String類(lèi)型的支持,底層編譯時(shí)將語(yǔ)句轉(zhuǎn)換成if-else語(yǔ)句吸占,支持String只是為了簡(jiǎn)化書(shū)寫(xiě)晴叨。不建議在switch中使用String。
String旬昭、StringBuffer篙螟、StringBuilder有什么區(qū)別?
1?首先說(shuō)運(yùn)行速度,或者說(shuō)是執(zhí)行速度问拘,在這方面運(yùn)行速度快慢為:StringBuilder > StringBuffer > String
2?在線程安全上遍略,StringBuilder是線程不安全的,而StringBuffer是線程安全的
3?應(yīng)用場(chǎng)景骤坐,String-適用于少量的字符串操作的情況;StringBuilder-適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況;StringBuffer-適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況绪杏。
可以自定義java.lang.String類(lèi)并使用嗎?
不能!Java類(lèi)加載機(jī)制為代理模式纽绍,先交給其父加載器去加載蕾久,如果父加載器加載不了,則由自己加載拌夏。
我們自定義的類(lèi)是由系統(tǒng)類(lèi)加載器進(jìn)行加載僧著,而它的父加載器為擴(kuò)展類(lèi)加載器,擴(kuò)展類(lèi)加載器為引導(dǎo)類(lèi)加載器障簿。我們定義的java.lang.String最先由引導(dǎo)加載器加載盹愚,而它負(fù)責(zé)加載Java核心庫(kù),但java.lang.String正是系統(tǒng)中的類(lèi)站故,已經(jīng)被引導(dǎo)加載器記載過(guò)了皆怕,所以不再加載自定義的java.lang.String。
finally塊一定會(huì)執(zhí)行嗎?
不一定西篓!
1?finally沒(méi)在作用域無(wú)法執(zhí)行愈腾。
2?主線程退出也無(wú)法執(zhí)行。
線程和進(jìn)程的區(qū)別是什么?
1?進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位岂津。
2?線程是進(jìn)程的一個(gè)實(shí)體, 是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源虱黄。
3?一個(gè)線程可以創(chuàng)建和撤銷(xiāo)另一個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行吮成。
Java實(shí)現(xiàn)線程有哪幾種方式?
1橱乱、繼承Thread類(lèi)實(shí)現(xiàn)多線程
2、實(shí)現(xiàn)Runnable接口方式實(shí)現(xiàn)多線程
3赁豆、使用ExecutorService仅醇、Callable冗美、Future實(shí)現(xiàn)有返回結(jié)果的多線程
一個(gè)線程的生命周期有哪幾種狀態(tài)?它們之間如何流轉(zhuǎn)的?
1魔种、新建狀態(tài)(New):新創(chuàng)建了一個(gè)線程對(duì)象。
2粉洼、就緒狀態(tài)(Runnable):線程對(duì)象創(chuàng)建后节预,其他線程調(diào)用了該對(duì)象的start()方法叶摄。該狀態(tài)的線程位于“可運(yùn)行線程池”中,變得可運(yùn)行安拟,只等待獲取CPU的使用權(quán)蛤吓。即在就緒狀態(tài)的進(jìn)程除CPU之外,其它的運(yùn)行所需資源都已全部獲得糠赦。
3会傲、運(yùn)行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼拙泽。4淌山、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時(shí)停止運(yùn)行顾瞻。直到線程進(jìn)入就緒狀態(tài)泼疑,才有機(jī)會(huì)轉(zhuǎn)到運(yùn)行狀態(tài)。
阻塞的情況分三種:
(1)荷荤、等待阻塞:運(yùn)行的線程執(zhí)行wait()方法退渗,該線程會(huì)釋放占用的所有資源,JVM會(huì)把該線程放入“等待池”中蕴纳。進(jìn)入這個(gè)狀態(tài)后会油,是不能自動(dòng)喚醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒袱蚓,
(2)钞啸、同步阻塞:運(yùn)行的線程在獲取對(duì)象的同步鎖時(shí),若該同步鎖被別的線程占用喇潘,則JVM會(huì)把該線程放入“鎖池”中体斩。
(3)、其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法颖低,或者發(fā)出了I/O請(qǐng)求時(shí)絮吵,JVM會(huì)把該線程置為阻塞狀態(tài)。當(dāng)sleep()狀態(tài)超時(shí)忱屑、join()等待線程終止或者超時(shí)蹬敲、或者I/O處理完畢時(shí),線程重新轉(zhuǎn)入就緒狀態(tài)莺戒。
5伴嗡、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期从铲。
多線程同步有哪幾種方法?
1?同步方法,即有synchronized關(guān)鍵字修飾的方法瘪校。
2.同步代碼塊,即有synchronized關(guān)鍵字修飾的語(yǔ)句塊。
3?使用特殊域變量(volatile)實(shí)現(xiàn)線程同步
a.volatile關(guān)鍵字為域變量的訪問(wèn)提供了一種免鎖機(jī)制,
b.使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會(huì)被其他線程更新阱扬,
c.因此每次使用該域就要重新計(jì)算泣懊,而不是使用寄存器中的值d.volatile不會(huì)提供任何原子操作,它也不能用來(lái)修飾final類(lèi)型的變量
4?使用重入鎖實(shí)現(xiàn)線程同步,在JavaSE5.0中新增了一個(gè)java.util.concurrent包來(lái)支持同步麻惶。
5?使用局部變量實(shí)現(xiàn)線程同步 ,如果使用ThreadLocal管理變量馍刮,則每一個(gè)使用該變量的線程都獲得該變量的副本,副本之間相互獨(dú)立窃蹋,這樣每一個(gè)線程都可以隨意修改自己的變量副本卡啰,而不會(huì)對(duì)其他線程產(chǎn)生影響。
什么是死鎖?如何避免死鎖?
產(chǎn)生死鎖的原因主要是:
(1) 因?yàn)橄到y(tǒng)資源不足警没。
(2) 進(jìn)程運(yùn)行推進(jìn)的順序不合適碎乃。
(3) 資源分配不當(dāng)?shù)取?/p>
產(chǎn)生死鎖的四個(gè)必要條件:
(1) 互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用。
(2) 請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí)惠奸,對(duì)已獲得的資源保持不放梅誓。
(3) 不剝奪條件:進(jìn)程已獲得的資源,在末使用完之前佛南,不能強(qiáng)行剝奪梗掰。
(4) 循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
多線程之間如何進(jìn)行通信?
1?同步嗅回,這里講的同步是指多個(gè)線程通過(guò)synchronized關(guān)鍵字這種方式來(lái)實(shí)現(xiàn)線程間的通信及穗。
2?while輪詢的方式。
3?wait/notify機(jī)制绵载。
4?管道通信就是使用java.io.PipedInputStream 和java.io.PipedOutputStream進(jìn)行通信
新建T1埂陆、T2、T3三個(gè)線程娃豹,如何保證它們按順序執(zhí)行?
T3先執(zhí)行焚虱,在T3的run中,調(diào)用t2.join懂版,讓t2執(zhí)行完成后再執(zhí)行t3 在T2的run中鹃栽,調(diào)用t1.join,讓t1執(zhí)行完成后再讓T2執(zhí)行
為什么要使用線程池?
線程的執(zhí)行過(guò)程: 創(chuàng)建(t1) 運(yùn)行(t2) 銷(xiāo)毀(t3) 線程運(yùn)行的總時(shí)間 T= t1+t2+t3; 假如躯畴,有些業(yè)務(wù)邏輯需要頻繁的使用線程執(zhí)行某些簡(jiǎn)單的任務(wù)民鼓,那么很多時(shí)間都會(huì)浪費(fèi)t1和t3上。 為了避免這種問(wèn)題蓬抄,JAVA提供了線程池 在線程池中的線程可以復(fù)用丰嘉,當(dāng)線程運(yùn)行完任務(wù)之后,不被銷(xiāo)毀
常用的幾種線程池并講講其中的工作原理嚷缭。
1饮亏、newCachedThreadPool,創(chuàng)建一個(gè)可緩存線程池,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程克滴,若無(wú)可回收,則新建線程优床。
線程池特點(diǎn):
工作線程的創(chuàng)建數(shù)量幾乎沒(méi)有限制(其實(shí)也有限制的,數(shù)目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程劝赔。
如果長(zhǎng)時(shí)間沒(méi)有往線程池中提交任務(wù),即如果工作線程空閑了指定的時(shí)間(默認(rèn)為1分鐘)胆敞,則該工作線程將自動(dòng)終止着帽。終止后,如果你又提交了新的任務(wù)移层,則線程池重新創(chuàng)建一個(gè)工作線程仍翰。在使用CachedThreadPool時(shí),一定要注意控制任務(wù)的數(shù)量观话,否則予借,由于大量線程同時(shí)運(yùn)行,很有會(huì)造成系統(tǒng)癱瘓频蛔。
2灵迫、newFixedThreadPool,定長(zhǎng)線程晦溪。創(chuàng)建一個(gè)指定工作線程數(shù)量的線程池瀑粥。每當(dāng)提交一個(gè)任務(wù)就創(chuàng)建一個(gè)工作線程,如果工作線程數(shù)量達(dá)到線程池初始的最大數(shù)三圆,則將提交的任務(wù)存入到池隊(duì)列中狞换。FixedThreadPool是一個(gè)典型且優(yōu)秀的線程池,它具有線程池提高程序效率和節(jié)省創(chuàng)建線程時(shí)所耗的開(kāi)銷(xiāo)的優(yōu)點(diǎn)舟肉。但是修噪,在線程池空閑時(shí),即線程池中沒(méi)有可運(yùn)行任務(wù)時(shí)路媚,它不會(huì)釋放工作線程割按,還會(huì)占用一定的系統(tǒng)資源。
3.newScheduledThreadPool,定長(zhǎng)磷籍、周期性線程池
4适荣、newSingleThreadExecutor,單線程。創(chuàng)建一個(gè)單線程化的Executor院领,即只創(chuàng)建唯一的工作者線程來(lái)執(zhí)行任務(wù)弛矛,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行比然。如果這個(gè)線程異常結(jié)束丈氓,會(huì)有另一個(gè)取代它,保證順序執(zhí)行。單工作線程最大的特點(diǎn)是可保證順序地執(zhí)行各個(gè)任務(wù)万俗,并且在任意給定的時(shí)間不會(huì)有多個(gè)線程是活動(dòng)的湾笛。
什么是守護(hù)線程?有什么用?
1?守護(hù)線程就是main同生共死,當(dāng)main退出闰歪,它將終止嚎研,而普通線程是在任務(wù)執(zhí)行結(jié)束才停止。2.Java虛擬機(jī)在它所有非守護(hù)線程已經(jīng)離開(kāi)后自動(dòng)離開(kāi)库倘。守護(hù)線程則是用來(lái)服務(wù)用戶線程的临扮,如果沒(méi)有其他用戶線程在運(yùn)行,那么就沒(méi)有可服務(wù)對(duì)象教翩,也就沒(méi)有理由繼續(xù)下去杆勇。守護(hù)線程是用來(lái)保證用戶線程,有效可靠的執(zhí)行饱亿。
Java中notify和notifyAll有什么區(qū)別?
notify是通知一個(gè)線程獲取鎖蚜退,notifyAll是通知所有相關(guān)的線程去競(jìng)爭(zhēng)鎖。notify不能保證獲得鎖的線程彪笼,真正需要鎖关霸,并且可能產(chǎn)生死鎖。
提交任務(wù)時(shí)線程池隊(duì)列已滿會(huì)時(shí)發(fā)會(huì)生什么?
如果一個(gè)任務(wù)不能被調(diào)度執(zhí)行那么ThreadPoolExecutor’s submit()方法將會(huì)拋出一個(gè)RejectedExecutionException異常杰扫。
ThreadLocal實(shí)現(xiàn)原理是什么?
ThreadLocal整體上感覺(jué)是队寇,一個(gè)包裝類(lèi)。聲明了這個(gè)類(lèi)的對(duì)象之后章姓,每個(gè)線程的數(shù)據(jù)其實(shí)還是在自己線程內(nèi)部通過(guò)threadLocals引用到的自己的數(shù)據(jù)佳遣。只是通過(guò)ThreadLocal訪問(wèn)這個(gè)數(shù)據(jù)而已。當(dāng)線程中的threadlocalmap是null的時(shí)候凡伊,會(huì)調(diào)用createmap創(chuàng)建一個(gè)map零渐。同時(shí)根據(jù)函數(shù)參數(shù)設(shè)置上初始值。也就是說(shuō)系忙,當(dāng)前線程的threadlocalmap是在第一次調(diào)用set的時(shí)候創(chuàng)建map并且設(shè)置上相應(yīng)的值的诵盼。
附Gayhub:https://github.com/KnightOneAdmin/Java-Resources
總結(jié):以上是Java基礎(chǔ),以及Java Web 相關(guān)資料整理银还,希望能幫助到你7缒!蛹疯!? 有寫(xiě)錯(cuò)的地方戒财,勿噴!^嘞摇饮寞!