java面試經(jīng)典題目一(Java基礎(chǔ))

本人經(jīng)歷了幾家大公司的Java研發(fā)的面試,現(xiàn)就面試中货矮,經(jīng)常遇到的問題整理如下:(java研發(fā)工程師)

不吹不捧羊精,本人靠著這一系列題目拿到了校招百度、京東囚玫、螞蟻金服的offer??喧锦。

Java基礎(chǔ)部分


【重點】:線程池

https://www.cnblogs.com/exe19/p/5359885.html

【1】java中對集合的理解?(小米抓督、京東)

答:下圖畫的不是很準(zhǔn)確燃少,具體的類的關(guān)系圖可參考:java集合

分析arrayList與LinkedList的區(qū)別:

1. ArrayList(默認(rèn)長度是10個):數(shù)組列表,可以動態(tài)的擴展空間铃在,隨機查詢一個元素速度比較快阵具,刪除和插入一個元素速度較慢,因為需要移動元素定铜;

2. LinkedList:鏈?zhǔn)酱鎯涌谘粢海蚣喜迦朐貢r效率較高,但是查詢元素效率較低揣炕,因為不支持隨機訪問

附加:Java中隊列有哪些帘皿?


普通隊列


LinkedList實現(xiàn)了queue接口,可以作為隊列使用畸陡。


ArrayDeque:以循環(huán)數(shù)組實現(xiàn)的雙向Queue鹰溜。 普通數(shù)組只能快速在末尾添加元素,為了支持FIFO丁恭,從數(shù)組頭快速取出元素曹动,就需要使用循環(huán)數(shù)組:有隊頭隊尾兩個下標(biāo):彈出元素時,隊頭下標(biāo)遞增涩惑;加入元素時仁期,如果已到數(shù)組空間的末尾,則將元素循環(huán)賦值到數(shù)組[0](如果此時隊頭下標(biāo)大于0,說明隊頭彈出過元素跛蛋,有空位)熬的,同時隊尾下標(biāo)指向0,再插入下一個元素則賦值到數(shù)組[1]赊级,隊尾下標(biāo)指向1押框。如果隊尾的下標(biāo)追上隊頭,說明數(shù)組所有空間已用完理逊,進行雙倍的數(shù)組擴容橡伞。?


PriorityQueue :用二叉堆實現(xiàn)的優(yōu)先級隊列,詳見入門教程晋被,不再是FIFO而是按元素實現(xiàn)的Comparable接口或傳入Comparator的比較結(jié)果來出隊兑徘,數(shù)值越小,優(yōu)先級越高羡洛,越先出隊挂脑。但是注意其iterator()的返回不會排序。


–線程安全的隊列–


?ConcurrentLinkedQueue/ConcurrentLinkedDeque:


?無界的并發(fā)優(yōu)化的Queue欲侮,基于鏈表崭闲,實現(xiàn)了依賴于CAS的無鎖算法。?ConcurrentLinkedQueue的結(jié)構(gòu)是單向鏈表和head/tail兩個指針威蕉,因為入隊時需要修改隊尾元素的next指針刁俭,以及修改tail指向新入隊的元素兩個CAS動作無法原子,所以需要的特殊的算法韧涨,篇幅所限見入門教程牍戚。?


PriorityBlockingQueue :無界的并發(fā)優(yōu)化的PriorityQueue,也是基于二叉堆虑粥。使用一把公共的讀寫鎖翘魄。雖然實現(xiàn)了BlockingQueue接口,其實沒有任何阻塞隊列的特征舀奶,空間不夠時會自動擴容。?


DelayQueue: 內(nèi)部包含一個PriorityQueue斋射,同樣是無界的育勺。元素需實現(xiàn)Delayed接口,每次調(diào)用時需返回當(dāng)前離觸發(fā)時間還有多久罗岖,小于0表示該觸發(fā)了涧至。?pull()時會用peek()查看隊頭的元素,檢查是否到達觸發(fā)時間桑包。ScheduledThreadPoolExecutor用了類似的結(jié)構(gòu)南蓬。


–線程安全的阻塞隊列–


BlockingQueue:的隊列長度受限,用以保證生產(chǎn)者與消費者的速度不會相差太遠,避免內(nèi)存耗盡赘方。隊列長度設(shè)定后不可改變烧颖。


ArrayBlockingQueue :定長的并發(fā)優(yōu)化的BlockingQueue,基于循環(huán)數(shù)組實現(xiàn)窄陡。有一把公共的讀寫鎖與notFull炕淮、notEmpty兩個Condition管理隊列滿或空時的阻塞狀態(tài)。


LinkedBlockingQueue/LinkedBlockingDeque :可選定長的并發(fā)優(yōu)化的BlockingQueue跳夭,基于鏈表實現(xiàn)涂圆,所以可以把長度設(shè)為Integer.MAX_VALUE。利用鏈表的特征币叹,分離了takeLock與putLock兩把鎖润歉,繼續(xù)用notEmpty、notFull管理隊列滿或空時的阻塞狀態(tài)颈抚。



【2】如何理解HashMap和HashTable?(百度)

答:HashMap是非synchronized的踩衩,線程不安全的,,允許null的key和null的value邪意,而HashTable是synchronized九妈,這意味著Hashtable是線程安全的,多個線程可以共享一個Hashtable雾鬼。就單個線程來講萌朱,HashMap速度比HashTable速度要快。

hashmap結(jié)構(gòu)可參考博客:hashmap

*******HashMap是如何擴容的策菜?(必知必會*****)

[詳細參考]

擴容的代價


有哪些map是線程安全的晶疼?


Hashtable、synchronizedMap又憨、ConcurrentHashMap


ConcurrentHashMap為啥是安全的翠霍?


答: 鎖分段技術(shù)HashTable容器在競爭激烈的并發(fā)環(huán)境下表現(xiàn)出效率低下的原因是所有訪問HashTable的線程都必須競爭同一把鎖,那假如容器里有多把 鎖蠢莺,每一把鎖用于鎖容器其中一部分?jǐn)?shù)據(jù)寒匙,那么當(dāng)多線程訪問容器里不同數(shù)據(jù)段的數(shù)據(jù)時,線程間就不會存在鎖競爭躏将,從而可以有效的提高并發(fā)訪問效率锄弱,這就是 ConcurrentHashMap所使用的鎖分段技術(shù),首先將數(shù)據(jù)分成一段一段的存儲祸憋,然后給每一段數(shù)據(jù)配一把鎖会宪,當(dāng)一個線程占用鎖訪問其中一個段數(shù)據(jù) 的時候,其他段的數(shù)據(jù)也能被其他線程訪問蚯窥。


【3】String掸鹅、StringBuffer和StringBuilder三者的區(qū)別塞帐?(京東、小米)

答: 簡言之:String代表字符串常量巍沙,StringBuffer 字符串變量(有syncronized修飾葵姥,線程安全),StringBuilder 字符串變量(非線程安全)赎瞎。

StringBuffer()的初始容量可以容納16個字符牌里,當(dāng)該對象的實體存放的字符的長度大于16時,實體容量就自動增加务甥。經(jīng)常改變內(nèi)容的字符串最好不要用 String牡辽,Java中對String對象進行的操作實際上是一個不斷創(chuàng)建新的對象并且將舊的對象回收的一個過程,所以執(zhí)行速度很慢敞临。

【4】equals和==區(qū)別态辛?(小米、百度)

答:在java中基本數(shù)據(jù)類型(int挺尿、boolean奏黑、char、long编矾、float熟史、double)的比較用==,==比較的是基本數(shù)據(jù)類型的值窄俏。除了基本數(shù)據(jù)類型外蹂匹,java還有復(fù)合的數(shù)據(jù)類型(類),當(dāng)用==比較的時候凹蜈,比較的是他們在內(nèi)存中的存放地址限寞。so,除非是同一個new出來的對象仰坦,比較結(jié)果為true履植,否則,都為false悄晃。equals就不同了玫霎,equals是object類的一個方法,原始的equals()方法是比較內(nèi)存中的地址妈橄,跟==是一樣的鼠渺,但是這個方法在一些類庫當(dāng)中被override了(如String,Integer眷细,Date等),覆寫后的方法比較的不再是內(nèi)存地址而是值鹃祖。

【5】short s1 = 1; s1 = s1 + 1;有錯嗎?(錯)short s1 = 1; s1 += 1;有錯嗎溪椎?(對)

答:

short s1 = 1;

s1 = s1 + 1;

1是int類型,so,s1 + 1的類型也為int類型校读,需要強制類型轉(zhuǎn)換才能賦值給short s1沼侣。而s1+=1相當(dāng)于s1 = (short)(s1 + 1);其中隱藏著強制類型轉(zhuǎn)換。

【6】兩個對象值相同(x.equals(y) == true)歉秫,但卻可有不同的hash code蛾洛,這句話對不對?(不對)(京東)

答:如果對象x和y相同那么他們的hashcode一定相同雁芙,Java對于eqauls方法和hashCode方法是這樣規(guī)定的:


(1)如果兩個對象相同(equals方法返回true)轧膘,那么它們的hashCode值一定要相同;


(2)如果兩個對象的hashCode相同兔甘,它們并不一定相同谎碍。


【7】重載(Overload)和重寫(Override)的區(qū)別。

答:重載和重寫都是實現(xiàn)多態(tài)的方式洞焙,只不過一個是在前期(編譯期實現(xiàn))蟆淀,一個是在后期(運行時實現(xiàn))。overload實現(xiàn)的是編譯時的多態(tài)性澡匪,override實現(xiàn)的是運行時的多態(tài)性熔任。

overload發(fā)生在類中,函數(shù)名相同唁情,但有不同的入?yún)?shù)類型疑苔、個數(shù),不考慮函數(shù)返回類型荠瘪;

override一般是子類繼承了父類夯巷,重寫父類的函數(shù),返回值類型和父類保持一致哀墓。

【8】抽象類(abstract class)和接口(interface)的區(qū)別趁餐。

答:抽象類,顧名思義篮绰,是類的抽象后雷,抽象類不能實例化,抽象類可以有構(gòu)造器吠各,誰繼承了抽象類臀突,就要對抽象類中的所有抽象方法進行實現(xiàn)。接口interface是一種特殊的抽象類贾漏,但是接口中不能有構(gòu)造函數(shù)候学,接口中的所有方法都不能有實現(xiàn),接口可以多繼承纵散。抽象類可以實現(xiàn)(implement)接口梳码,抽象類可以繼承(extends)具體類

【9】String s = new String(“xyz”);創(chuàng)建了幾個字符串對象隐圾?(2)

答:首先在string池內(nèi)找xyz,找到掰茶?不創(chuàng)建string對象暇藏,否則創(chuàng)建, 這樣就一個string對象濒蒋,遇到new運算符號了盐碱,在內(nèi)存上創(chuàng)建string對象,并將其返回給s沪伙,又一個對象瓮顽。所以總共是2個對象。

補充:

詳細內(nèi)容可參考:深入理解string

【10】描述一下Java加載class文件的原理機制焰坪?

答:【詳細參考

【11】Arrays類的copyOf()函數(shù)趣倾,是淺拷貝。

最后返回都是30某饰。Arrays.copyOf功能是實現(xiàn)數(shù)組的復(fù)制儒恋,返回復(fù)制后的數(shù)組。參數(shù)是被復(fù)制的數(shù)組復(fù)制的長度黔漂。

【12】你對消息中間件熟悉嗎诫尽?應(yīng)用場景?(小米)

答:消息中間件是分布式系統(tǒng)中的重要組件炬守,主要解決應(yīng)用解耦牧嫉、異步處理、流量削峰和消息通訊的問題(在電商减途、日志處理上應(yīng)用廣泛)酣藻。目前使用較多的消息隊列有:ActiveMQ,Kafka鳍置,RabbitMQ辽剧,ZeroMQ,MetaMQ税产,RocketMQ等怕轿。[詳細參考]

【13】下面程序的運行結(jié)果是(false)


String str1 = "hello";


String str2 = "he" + new String("llo");


System.err.println(str1 == str2);


答:看懂了前面equals和==的問題,以及jvm的相關(guān)知識辟拷,這個就很簡單了撞羽。

【14】GC線程是否為守護線程?()

答案:是衫冻。線程分為守護線程非守護線程(即用戶線程)诀紊。

只要當(dāng)前JVM實例中尚存在任何一個非守護線程沒有結(jié)束,守護線程就全部工作隅俘;只有當(dāng)最后一個非守護線程結(jié)束時邻奠,守護線程隨著JVM一同結(jié)束工作到推。守護線程最典型的應(yīng)用就是 GC (垃圾回收器)

【15】如何理解volatile和synchronized?(京東)

????????在多線程并發(fā)的問題中,線程對共享變量的操作都是在自己的工作內(nèi)存中進行的惕澎,線程之間無法達到共享,線程之間的變量值的傳遞需要經(jīng)過主內(nèi)存作為橋梁颜骤。


共享變量可見性的原理如下:


(1)工作線程1中更新了的共享變量如果想被工作線程2看到(可見)唧喉,需要先將工作內(nèi)存刷新到主內(nèi)存;


(2)主內(nèi)存中共享變量發(fā)生變化忍抽,更新到工作線程2的工作內(nèi)存中八孝。


想要實現(xiàn)可見性,需要保證兩點:


1.工作線程中的工作內(nèi)存的變量值鸠项,一旦發(fā)生改變要及時地刷新到主內(nèi)存中干跛;


2.主內(nèi)存中的變量一旦發(fā)生變化,工作線程能及時地從主內(nèi)存刷新到自己的工作內(nèi)存祟绊。


接下來楼入,切入我們的正題:

可見性的實現(xiàn)方式:synchronized和volatile

synchronized實現(xiàn)過程如下:


1.獲得互斥鎖;


2.清空工作內(nèi)存


3.從主內(nèi)存拷貝變量的工作副本到自己的工作內(nèi)存


4.執(zhí)行代碼


5.將更改后的共享變量的值刷新到主內(nèi)存中


6.釋放互斥鎖


????????那么牧抽,導(dǎo)致共享變量在線程中不可見的原因是什么嘉熊?主要有這么幾點:多線程交叉執(zhí)行;重排序結(jié)合線程交叉執(zhí)行扬舒;共享變量的值在發(fā)生改變后未能在主內(nèi)存和工作內(nèi)存中及時更新阐肤。synchronized解決的問題是,線程交叉執(zhí)行讲坎,synchronized保證原子性孕惜,重排序集合線程交叉,synchronized保證原子性晨炕,最后一個衫画,synchronized保證可見性。簡化成圖片就是如下:

synchronized保證可見性

????????then府瞄,對于volatile碧磅,它又是如何解決可見性問題的呢?volatile是通過加入內(nèi)存屏障和禁止重排序優(yōu)化實現(xiàn)的遵馆。(volatile在執(zhí)行讀操作時候鲸郊,會在讀操作前面加一條load的屏障指令,同理货邓,在執(zhí)行寫操作時候會在寫操作后加一條store的屏障指令)

????????volatile是如何實現(xiàn)的秆撮?通俗的將,變量每次被線程訪問時换况,都會被迫從主內(nèi)存中重讀變量的值职辨,當(dāng)變量的值發(fā)生變化時盗蟆,由會強迫線程將變量的值刷新到主內(nèi)存中,這樣舒裤,任何時刻喳资,不同的線程之間均能看到該變量的最新值。

synchronized和volatile的比較:

【16】ArrayList list = new ArrayList(20);中的list擴充幾次(0)(京東)

答:不擴容腾供。默認(rèn)ArrayList的長度是10個仆邓,如果往list里添加20個元素肯定要擴充一次(擴充為原來的1.5倍),但是這里顯示指明了需要多少空間伴鳖,所以就一次性分配這么多空間节值,也就是不需要擴充了。

【17】下列程序輸出什么榜聂?


輸出順序如下:


static A


static B


I'm A class


HelloA


I'm B class


HelloB


答:對象的初始化順序:(1)類加載之后搞疗,按從上到下(從父類到子類)執(zhí)行被static修飾的語句;(2)當(dāng)static語句執(zhí)行完之后,再執(zhí)行main方法须肆;(3)如果有語句new了自身的對象匿乃,將從上到下執(zhí)行構(gòu)造代碼塊、構(gòu)造器(兩者可以說綁定在一起)

稍微修改下如下:

答案:


static A


static B


-------main start-------


I'm A class


HelloA


I'm B class


HelloB


I'm A class


HelloA


I'm B class


HelloB


-------main end-------


【18】Thread類中run()和start()方法的區(qū)別休吠。

:run()是執(zhí)行體扳埂,start()是開啟一個多線程,已知線程的狀態(tài)分為:創(chuàng)建瘤礁、就緒阳懂、運行、阻塞柜思、死亡五個岩调。線程狀態(tài)轉(zhuǎn)換圖如下所示。

[參考文章]


線程狀態(tài)轉(zhuǎn)換圖

1.創(chuàng)建狀態(tài):此時還沒調(diào)用start()方法

2.就緒狀態(tài):調(diào)用了start()方法之后赡盘,線程處于就緒狀態(tài)号枕,線程調(diào)度程序還沒把該線程設(shè)置成當(dāng)前線程。當(dāng)然陨享,程序運行后葱淳,等待或者睡眠之后也會處于就緒狀態(tài)。

3.運行狀態(tài):程序調(diào)度器將就緒線程設(shè)置成當(dāng)前線程抛姑,此時就會執(zhí)行程序執(zhí)行體run()函數(shù)赞厕。

4.阻塞狀態(tài):正在運行的程序被阻塞,一般是sleep()定硝、suspend()皿桑、wait()等方法導(dǎo)致。

5.死亡狀態(tài):run()執(zhí)行結(jié)束或者調(diào)用了stop()方法,線程會處于死亡狀態(tài)诲侮。死亡的線程不能再通過start()方法使其處于就緒狀態(tài)镀虐。


多線程原理:


????????相當(dāng)于多個人玩玩具,只有一個玩具(cpu)沟绪,好多人都想玩刮便,怎么辦?排隊U来取I悼А顾孽!start()就起到了排隊的作用脖含。等cpu輪到你蝴猪,你就run()漓摩,當(dāng)cpu的運行時間結(jié)束裙士,就繼續(xù)排隊,等待下一次的run()管毙。


????????調(diào)用start()后腿椎,線程會被放到等待隊列,等待CPU調(diào)度夭咬,并不一定要馬上開始執(zhí)行啃炸,只是將這個線程置于可運行狀態(tài)。然后通過JVM卓舵,線程Thread會調(diào)用run()方法南用,執(zhí)行本線程的線程體。先調(diào)用start后調(diào)用run掏湾,這么麻煩裹虫,為了不直接調(diào)用run?就是為了實現(xiàn)多線程的優(yōu)點融击,沒這個start不行筑公。


所以,start()方法用來啟動線程尊浪,此時線程并沒有處于運行狀態(tài)匣屡,只是就緒狀態(tài)。start()方法執(zhí)行后可不用等待run()方法里面的程序執(zhí)行完拇涤,可以繼續(xù)執(zhí)行下面的程序捣作。

如果run()方法被當(dāng)做普通方法來執(zhí)行,不能實現(xiàn)多線程并發(fā)的效果工育。下面的程序需要等待run()里面的代碼執(zhí)行結(jié)束才能執(zhí)行虾宇,程序中只有主線程這一個線程。

【19】sleep()和wait()的區(qū)別如绸?(百度嘱朽、新浪)

答:wait()和sleep()的關(guān)鍵的區(qū)別在于旭贬,wait()是用于線程間通信的,而sleep()是用于短時間暫停當(dāng)前線程搪泳。其中稀轨,sleep()是Thread類中的靜態(tài)方法,wait()是是定義在Object類中的岸军。

另外奋刽,sleep()是使當(dāng)前的程序處于阻塞狀態(tài),在其睡眠時間段內(nèi)艰赞,該線程不會獲得執(zhí)行的機會佣谐。而wait(),線程會釋放掉它所占有的“鎖標(biāo)志”方妖,從而使別的線程有機會搶占該鎖狭魂,wait()和notify()必須在synchronized函數(shù)或synchronized block中進行調(diào)用。

【20】下面哪個流類屬于面向 字符 的輸入流(?D )

A. BufferedWriter?????????? B. FileInputStream? ? ??

C. ObjectInputStream? ? D. InputStreamReader

答:看圖一目了然党觅。

對于Io,分為字符流和字節(jié)流雌澄。

字節(jié)流:reader writer,

字符流:InputStream(FileInpuStream)杯瞻、OutputStream(FileOutputStream->BufferedOutputStream)具體如下表所示:


1.什么時候使用字節(jié)流镐牺?什么時候使用字符流?


答:


所有的輸入都是轉(zhuǎn)化成字節(jié)流后魁莉,在內(nèi)存中轉(zhuǎn)化成字符流睬涧。因此一般建議使用字符流,當(dāng)遇到中文出現(xiàn)亂碼時旗唁,使用字節(jié)流宙地。(所有硬盤上保存的文件或者傳輸文件時,都是通過字節(jié)流的形式進行的逆皮,包括圖片也是字節(jié)流宅粥,在內(nèi)存中才轉(zhuǎn)化成字符流,使用字節(jié)的操作是最多的)


2.遞歸讀取文件夾的文件电谣,代碼怎么實現(xiàn)秽梅?


代碼如下:

詳細參考

【21】泛型的作用?

:泛型主要是用在集合中剿牺,如果不指定加入集合的元素的類型企垦,集合就會忘記被“丟進”的元素類型。在程序編譯過程中晒来,如果不使用泛型钞诡,編譯器不會報錯,但是在foreach過程中會出現(xiàn)ClassCastException異常。

【22】如何理解多態(tài)性荧降?(新浪)

答:用專業(yè)一點的話說就是接箫,類中所定義引用變量或者由引用變量所調(diào)用的方法在程序編譯期間并不能夠知曉,只有在程序運行期間才能知道朵诫,調(diào)用了哪個類的方法辛友。、

????????如果講給大街上的老頭剪返,桌子上有三杯酒废累,a(茅臺) b(五糧液) c(二鍋頭),都是白酒脱盲,在沒喝(相當(dāng)于程序運行)之前邑滨,我們不知道誰是誰,只有品嘗了一口钱反,才知道驼修,哦,哪個是二鍋頭诈铛,哪個是茅臺(abc都是酒的子類)。

【23】解釋內(nèi)存中的棧(stack)墨礁、堆(heap)和方法區(qū)(method area)的用法幢竹。

答:通常我們定義一個基本數(shù)據(jù)類型的變量,一個對象的引用恩静,還有就是函數(shù)調(diào)用的現(xiàn)場保存都使用JVM中的椈篮粒空間;

????????通過new關(guān)鍵字和構(gòu)造器創(chuàng)建的對象則放在堆空間驶乾,堆是垃圾收集器管理的主要區(qū)域邑飒,由于現(xiàn)在的垃圾收集器都采用分代收集算法,所以堆空間還可以細分為新生代和老生代级乐,再具體一點可以分為Eden疙咸、Survivor(又可分為From Survivor和To Survivor)、Tenured风科;

????????方法區(qū)和堆都是各個線程共享的內(nèi)存區(qū)域撒轮,用于存儲已經(jīng)被JVM加載的類信息、常量贼穆、靜態(tài)變量题山、JIT編譯器編譯后的代碼等數(shù)據(jù);程序中的字面量(literal)如直接書寫100故痊、"hello"和常量都是放在常量池中顶瞳,常量池是方法區(qū)的一部分。棧空間操作起來最快但是棧很小慨菱,通常大量的對象都是放在堆空間焰络,棧和堆的大小都可以通過JVM的啟動參數(shù)來進行調(diào)整,椔帐粒空間用光了會引發(fā)StackOverflowError舔琅,而堆和常量池空間不足則會引發(fā)OutOfMemoryError。

String str = new String("hello");

????上面的語句中變量str放在棧上洲劣,用new創(chuàng)建出來的字符串對象放在堆上备蚓,而"hello"這個字面量是放在方法區(qū)的。

最后囱稽,堆郊尝、棧在數(shù)據(jù)上面的共享問題(棧區(qū),本地方法區(qū)和pc計數(shù)器屬于線程內(nèi)存战惊,每個獨立線程都擁有自己的線程內(nèi)存流昏,這些是不可共享的, 堆區(qū)吞获,方法區(qū)和常量池是可以共享的)

更加詳細的內(nèi)存模型及GC算法內(nèi)容參考【詳細參考

【24】如何理解線程和進程况凉?線程之間如何通訊的?(面試必問※)

答:在操作系統(tǒng)中各拷,每一個任務(wù)的執(zhí)行都會占用系統(tǒng)一部分資源(或者說刁绒,系統(tǒng)為每一個任務(wù)分配一定的cpu資源),每一個任務(wù)的執(zhí)行稱為一個進程烤黍,進程具有獨立性知市,也就說相互進程之間無法進行直接的交流,進程具有并發(fā)性速蕊,在操作系統(tǒng)中嫂丙,每一時刻僅有一個進程運行,但是多個進程之間是輪換轉(zhuǎn)變的规哲,宏觀上講進程具有并發(fā)性跟啤。

線程是進程的微小單元,一個任務(wù)的執(zhí)行是一個進程唉锌,一個進程可以包含多個線程腥光,這樣的好處就是,線程之間可以共享內(nèi)存糊秆,而進程之間是無法共享的武福。

當(dāng)操作系統(tǒng)創(chuàng)建一個進程時,系統(tǒng)需要為每一個進程分配一定的內(nèi)存空間及相關(guān)的資源痘番,而線程的創(chuàng)建則代價小得多捉片,因此多線程的并發(fā)要比多進程的并發(fā)性能高的多平痰。

線程之間的通訊方式?

我們知道線程之間是可以進行內(nèi)存共享的伍纫,如何進行共享的呢宗雇?

1.傳統(tǒng)的通訊方式是基于同步代碼塊、同步方法(也就是由synchronized修飾的時候)莹规,用到三個方法赔蒲,wait(),notify()及notifyAll()良漱,但這三個方法必須有同步監(jiān)視器對象來調(diào)用舞虱。分兩種情況:


1. synchronized修飾同步代碼塊,同步監(jiān)視器是 synchronized后面括號里面的對象母市,使用該對象調(diào)用三個方法矾兜。


2. synchronized修飾同步方法,因為該類的實例默認(rèn)(this)就是同步監(jiān)視器患久,所以可以直接調(diào)用這三個方法椅寺。


wait()方法是object類方法,是針對線程之間的蒋失,使用wait()方法會使得當(dāng)前線程等待返帕,調(diào)用wait()方法的線程會釋放對該同步監(jiān)視器的鎖。直到其他線程調(diào)用該同步監(jiān)視器的notify()或者notifyAll()方法來喚醒篙挽。

notify()喚醒在此同步監(jiān)視器上等待的單個線程

notifyAll()喚醒在此同步監(jiān)視器上等待的所有線程荆萤。

2.使用Condition控制線程通訊

倘若程序中沒有使用synchronized關(guān)鍵字來修飾,而是使用了同步鎖Lock來保證同步嫉髓,系統(tǒng)中沒有了隱式的同步監(jiān)視器,也就無法使用wait()邑闲,notify()及notifyAll()了算行,此時可使用Condition類。

condition實例被綁定在一個Lock對象上苫耸,要獲得特定的Lock實例的Condition實例州邢,調(diào)用Lock對象的newCondition()方法即可。其提供的三個方法:


1.await()類似于wait()方法褪子,導(dǎo)致線程等待量淌,直到其他線程調(diào)用signal()或signalAll()喚醒


2.signal()喚醒單個線程


3.signalAll()喚醒所有線程。


//顯示定義Lock對象


private final Lock lock = new ReentrantLock();


//獲得指定Lock對象對應(yīng)的Condition


private final Condition cond? = lock.newCondition();


3.使用阻塞隊列(BlockingQueue)控制線程通訊

【25】線程池的使用原理及示例嫌褪?

線程池


1.為什么使用線程池呀枢?


合理的使用線程池便可重復(fù)利用已創(chuàng)建的線程,以減少在創(chuàng)建線程和銷毀線程上花費的時間和資源笼痛。


2. 線程池的簡要工作模型


簡要工作模型

【26】利用多線程循環(huán)輸出AB

答:


【27】final關(guān)鍵字的理解和認(rèn)識裙秋?

答:在使用匿名內(nèi)部類的時候可能會經(jīng)常用到final關(guān)鍵字琅拌。在Java中String類就是一個final類。

final可以修飾類摘刑、方法和變量(成員變量进宝、局部變量)。

1.修飾類

final修飾類時候枷恕,此類不能被繼承党晋。

2.修飾方法

一個類中用final修飾方法,繼承此類的子類無法override父類的方法徐块。

3.修飾變量

當(dāng)final修飾類的成員變量時未玻,定義變量的時候要對變量進行初始化,而且final變量一旦被初始化賦值之后蛹锰,就不能再被賦值了深胳。

final修飾的成員變量和普通變量有啥區(qū)別?(true铜犬、false)

final修飾基本數(shù)據(jù)類型及string類型時舞终,在編譯期間,變量就被認(rèn)為是編譯常量癣猾,會直接加載敛劝,不會等到運行期間再加載,因此final修飾的string b="hello",b在編譯期間就被直接調(diào)用了纷宇。

被final修飾的引用變量指向的對象內(nèi)容可變嗎夸盟?

在上面提到被final修飾的引用變量一旦初始化賦值之后就不能再指向其他的對象,那么該引用變量指向的對象的內(nèi)容可變嗎像捶?看下面這個例子:

這段代碼可以順利編譯通過并且有輸出結(jié)果上陕,輸出結(jié)果為1。這說明引用變量被final修飾之后拓春,雖然不能再指向其他對象释簿,但是它指向的對象的內(nèi)容是可變的


最后硼莽,final和static有什么區(qū)別庶溶?


static作用于成員變量用來表示只保存一份副本,而final的作用是用來保證變量不可變懂鸵∑荩看下面這個例子:


運行這段代碼就會發(fā)現(xiàn),每次打印的兩個j值都是一樣的匆光,而i的值卻是不同的套像。


補充:為什么string類要final來修飾?【詳細參考


兩個方面回答:1.安全性终息;2.提高效率


【28】Java中內(nèi)部類有什么作用凉夯?

答:內(nèi)部類分為:1.成員內(nèi)部類货葬;2.局部內(nèi)部類;3.匿名內(nèi)部類劲够;4.靜態(tài)內(nèi)部類


1.成員內(nèi)部類是最普通的內(nèi)部類震桶,它的定義為位于另一個類的內(nèi)部。成員內(nèi)部類可以無條件( 事實上征绎,編譯器在進行編譯的時候蹲姐,會將成員內(nèi)部類單獨編譯成一個字節(jié)碼文件)訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員)


2. 局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi)人柿。


3. 匿名內(nèi)部類應(yīng)該是平時我們編寫代碼時用得最多的柴墩,在編寫事件監(jiān)聽的代碼時使用匿名內(nèi)部類不但方便,而且使代碼更加容易維護凫岖。多用于安卓監(jiān)聽器中江咳。


注意: 局部內(nèi)部類和匿名內(nèi)部類只能訪問局部final變量。


4. 靜態(tài)內(nèi)部類也是定義在另一個類里面的類哥放,只不過在類的前面多了一個關(guān)鍵字static歼指。靜態(tài)內(nèi)部類是不需要依賴于外部類的,這點和類的靜態(tài)成員屬性有點類似甥雕,并且它不能使用外部類的非static成員變量或者方法踩身。


為什么在Java中需要內(nèi)部類?總結(jié)一下主要有以下四點:

  1.每個內(nèi)部類都能獨立的繼承一個接口的實現(xiàn)社露,所以無論外部類是否已經(jīng)繼承了某個(接口的)實現(xiàn)挟阻,對于內(nèi)部類都沒有影響。內(nèi)部類使得多繼承的解決方案變得完整峭弟。

  2.方便將存在一定邏輯關(guān)系的類組織在一起附鸽,又可以對外界隱藏。

  3.方便編寫事件驅(qū)動程序

  4.方便編寫線程代碼

【29】Dubbo架構(gòu)原理

答:【詳細參考】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞒瘸,一起剝皮案震驚了整個濱河市坷备,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挨务,老刑警劉巖击你,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玉组,死亡現(xiàn)場離奇詭異谎柄,居然都是意外死亡,警方通過查閱死者的電腦和手機惯雳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門朝巫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人石景,你說我怎么就攤上這事劈猿∽炯” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵揪荣,是天一觀的道長筷黔。 經(jīng)常有香客問我,道長仗颈,這世上最難降的妖魔是什么佛舱? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮挨决,結(jié)果婚禮上请祖,老公的妹妹穿的比我還像新娘。我一直安慰自己脖祈,他們只是感情好肆捕,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盖高,像睡著了一般慎陵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上或舞,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天荆姆,我揣著相機與錄音,去河邊找鬼映凳。 笑死胆筒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诈豌。 我是一名探鬼主播仆救,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矫渔!你這毒婦竟也來了彤蔽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤庙洼,失蹤者是張志新(化名)和其女友劉穎顿痪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體油够,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蚁袭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了石咬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揩悄。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鬼悠,靈堂內(nèi)的尸體忽然破棺而出删性,到底是詐尸還是另有隱情亏娜,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布蹬挺,位于F島的核電站维贺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巴帮。R本人自食惡果不足惜幸缕,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晰韵。 院中可真熱鬧发乔,春花似錦、人聲如沸雪猪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽只恨。三九已至译仗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間官觅,已是汗流浹背纵菌。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留休涤,地道東北人咱圆。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像功氨,于是被迫代替她去往敵國和親序苏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實習(xí)到現(xiàn)在捷凄,面了一些公司忱详,掛了不少,但最終還是拿到小米跺涤、百度匈睁、阿里、京東桶错、新浪航唆、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,209評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法牛曹,類相關(guān)的語法佛点,內(nèi)部類的語法醇滥,繼承相關(guān)的語法黎比,異常的語法超营,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,071評論 0 14
  • 兩個星期前阅虫,班級里調(diào)換了座位演闭。一組八個同學(xué),我一直是在三四桌徘徊的颓帝,但這次著實出乎了我的意料米碰,我被安排到了倒數(shù)第二...
    舒煙吖閱讀 324評論 2 4
  • 負能量爆炸閱讀 90評論 0 0