Java面試題—基礎題目

本文來源于并發(fā)編程網清英的一篇文章:你應該知道的JAVA面試題,最近自己也在面試一些候選人睛低,發(fā)現(xiàn)這篇文章中的有些點我也拿不準案狠,因此按照自己的理解整理一份參考回答。

基礎題目

1. Java線程的狀態(tài)

Java線程在某個時刻只能處于以下六個狀態(tài)中的一個钱雷。

  • New(新創(chuàng)建)骂铁,一個線程剛剛被創(chuàng)建出來,還沒有開始運行的狀態(tài)罩抗,更通俗點說:還沒有調用start方法拉庵;
  • Runnable(可運行),可以在Java虛擬機中運行的狀態(tài)套蒂;一個可運行的線程可能正在運行自己的代碼也可能沒有钞支,這取決于操作系統(tǒng)提供的時間片;
  • Blocked(被阻塞)操刀,當一個線程試圖獲取一個內部的對象鎖(不是java.util.concurrent庫中的鎖)烁挟,而該鎖此時正被其他線程持有,則該線程進入阻塞狀態(tài)骨坑;
  • Waiting(等待)撼嗓,當線程等待另一個線程通知調度器一個條件時,它自己進入等待狀態(tài)欢唾。在調用Object.wait方法或Thread.join方法且警,或者是等待java.util.concurrent庫中的Lock或Condition時,就會出現(xiàn)這種情況匈辱;
  • Timed waiting(計時等待)振湾,Object.wait、Thread.join亡脸、Lock.tryLock和Condition.await等方法有超時參數(shù)押搪,還有Thread.sleep方法、LockSupport.parkNanos方法和LockSupport.parkUntil方法浅碾,這些方法會導致線程進入計時等待狀態(tài)大州,如果超時或者出現(xiàn)通知,都會切換會可運行狀態(tài)垂谢;
  • Terminated(被終止)厦画,因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。
Java線程狀態(tài).png

參考資料:

2. 進程與線程的區(qū)別根暑,進程間如何通訊力试,線程間如何通訊?

在并發(fā)編程領域排嫌,有進程和線程兩個概念畸裳,在Java語言中說起并發(fā)編程,常常是指多線程淳地,但是了解進程的概念也非常重要:

  • 進程是操作系統(tǒng)的資源調度實體怖糊,有自己的內存地址空間和運行環(huán)境;
  • 線程一般被稱為輕量級的進程颇象,線程和進程一樣伍伤,也有自己的運行環(huán)境,但是創(chuàng)建一個線程要需要的資源比創(chuàng)建一個進程要少遣钳。線程存在于進程之中——每個進程至少有一個線程扰魂。一個進程下的多個線程之間可以共享進程的資源,包括內存空間和打開的文件蕴茴。
  • 進程跟程序(programs)阅爽、應用(applications)具備相同的含義,進程間通訊依靠IPC資源荐开,例如管道(pipes)、套接字(sockets)等简肴;
  • 線程間通訊依靠JVM提供的API晃听,例如wait方法、notify方法和notifyAll方法砰识,線程間還可以通過共享的主內存來進行值的傳遞能扒;

參考資料:

3. HashMap的數(shù)據(jù)結構是什么?如何實現(xiàn)的辫狼?和HashTable初斑、ConcurrentHashMap的區(qū)別?

  • 在Java 8中膨处,HashMap的數(shù)據(jù)結構是由Node<K,V>作為元素組成的數(shù)組:(1)如果有多個值hash到同一個桶中见秤,則組織成一個鏈表,而且真椿,當這個鏈表的節(jié)點個數(shù)超過某個值(TREEIFY_THRESHOLD參數(shù)指定)時鹃答,則將這個鏈表重構為一個二叉樹;(2)如果發(fā)現(xiàn)map中的元素個數(shù)超過了threshold突硝,則進行空間擴容——二倍空間测摔。
  • HashMap和HashTable的數(shù)據(jù)結構和操作基本相同,區(qū)別是前者是非線程安全,并且HashMap接受value為null锋八。
  • ConcurrentHashMap和HashTable一樣浙于,都是線程安全的,但是區(qū)別是:HashTable每次操作都會鎖住整個表結構——導致一次只能有一個線程訪問HashTable對象挟纱,而ConcurrentHashMap不會羞酗,只會鎖住某個節(jié)點,只有在涉及到size的操作時才會鎖整個表結構樊销。
  • 參考資料:《Java并發(fā)編程實戰(zhàn)》

4. Cookie和Session的區(qū)別

HTTP是無狀態(tài)協(xié)議整慎,但是在實際應用中有跟蹤客戶端狀態(tài)的需求,Cookie和Session是兩種不同的實現(xiàn)方案围苫。

  • Cookie保存在客戶端裤园,Session保存在服務端
  • Cookie沒有Session安全,侵入者可以通過分析客戶端的cookie信息侵入網站剂府;
  • 使用Session存儲重要信息拧揽,使用Cookie存儲不那么重要的信息;
  • 使用Session方案時腺占,常常需要依賴Cookie傳遞SID的值淤袜,如果客戶端禁用了Cookie,則轉而采取URL重寫技術(但是這種技術有安全風險)衰伯;
  • 參考資料:What is the difference between Sessions and Cookies in PHP?

5. 索引有什么用铡羡?如何建索引?

  • 索引的作用:索引是一種數(shù)據(jù)結構意鲸,用于加快mysql獲取數(shù)據(jù)的速度烦周;
  • 如何建索引?在使用InnoDB引擎的前提下討論:(1)最左前綴原理:分析業(yè)務中的查詢條件怎顾,區(qū)分度高的字段放在前面读慎,盡量減少一條SQL的影響行數(shù);(2)A+B可以代替A槐雾,A+B+C可以代替A+B夭委,如果查詢是A+C則只能使用到A列索引;
  • 關于InnoDB的認識:InnoDB使用B+Tree作為存儲數(shù)據(jù)結構募强,屬于聚簇索引株灸,每個輔助索引最后都會指向主鍵的值,每次查詢兩次钻注;(4)由于聚簇索引的特性蚂且,建議在使用InnoDB引擎的時候,使用自增ID作為主鍵幅恋,不要使用隨機的業(yè)務列作為主鍵杏死。
  • 參考資料

6. ArrayList是如何實現(xiàn)的,ArrayList和LinkedList的區(qū)別?ArrayList如何實現(xiàn)擴容淑翼?

  • 可變數(shù)組實現(xiàn)了List接口的所有操作腐巢,功能上跟Vector相同,區(qū)別是Vector是線程安全的玄括;
  • 區(qū)別:LinkedList實現(xiàn)了List和Deque接口冯丙,一般稱為雙向鏈表;LinkedList在插入和刪除數(shù)據(jù)時效率更高遭京,ArrayList在查找某個index的數(shù)據(jù)時效率更高胃惜;LinkedList比ArrayList需要更多的內存;
  • 關于可變數(shù)組的擴容策略哪雕,可以查看源碼船殉,不同的JDK實現(xiàn)不太一樣,我這里使用JDK 8:首先嘗試擴容為原來大小的1.5倍斯嚎,如果newCapacity還不夠大利虫,則再擴大為minCapacity值;如果newCapacity比數(shù)組的規(guī)定最大容量還大堡僻,則根據(jù)minCapacity的值進行定奪糠惫,參見hugeCapacity方法。
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
  • 在代碼中钉疫,如果預先知道需要增加大量元素硼讽,則可以提前對當前的可變數(shù)組調用ensureCapacity方法,可以避免多次遞增的內存重新分配牲阁;
  • 參考資料:

7. equals理郑、hashcode等Object類中一些方法的討論?

8. 面向對象

  • 三大特性
    • 封裝
    • 繼承
    • 多態(tài)

9. JVM如何加載字節(jié)碼文件法瑟?

虛擬機把描述類的數(shù)據(jù)從Class文件加載到內存,并對數(shù)據(jù)進行校驗唁奢、轉換解析和初始化霎挟,最終形成可被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制麻掸。

Java語言中類的加載酥夭、連接和初始化過程都是在程序運行期間完成的,領Java具備高度的靈活性。

類加載的過程:加載熬北、連接(驗證疙描、準備、解析)讶隐、初始化起胰。

  • 加載:通過一個類的名字獲取此類的二進制字節(jié)流(PS:不限于從文件中讀取)巫延;將這個字節(jié)流代表的靜態(tài)存儲結構轉換為方法區(qū)的運行時結構(由具體的虛擬機自己定義)效五;在內存中生成一個java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)結構的訪問入口炉峰。
  • 驗證:文件格式驗證畏妖、元數(shù)據(jù)驗證(語義分析,類與類的繼承關系等)讲冠、字節(jié)碼驗證(數(shù)據(jù)流和控制流分析)瓜客、符號引用驗證(對類自身以外的信息進行匹配校驗)
  • 準備:正式為類變量分配內存并設置初始值,這里類變量指的是被static修飾的變量竿开。例外:如果類字段是常量谱仪,則在這里會被初始化為表達式指定的值。
  • 解析:將常量池內的符號引用替換為直接引用否彩。符號引用:類似于OS中的邏輯地址疯攒;直接引用:類似于OS中的物理地址,直接指向目標的指針列荔、相對偏移量或一個能間接定位到目標的句柄敬尺。
  • 初始化:真正開始執(zhí)行類中定義的Java程序代碼;初始化用于執(zhí)行Java類的構造方法贴浙。類初始化的過程是不可逆的砂吞,如果中間一步出錯,則無法執(zhí)行下一步崎溃,參見不可逆的類初始化過程蜻直。

10. GC算法

  • 垃圾回收解決三個問題:哪些內存需要回收?什么時候回收袁串?如何回收概而?
  • 垃圾回收關注的是堆內存(heap);
  • 常見的垃圾收集算法
    • 標記-清除算法
    • 復制算法
    • 標記-整理算法
    • 分代收集算法

11. 什么情況下回出現(xiàn)Full GC囱修,什么情況下會出現(xiàn)Young GC

  • 對象優(yōu)先在新生代Eden區(qū)中分配赎瑰,如果Eden區(qū)沒有足夠的空間時,就會觸發(fā)一次young gc
  • Full gc的觸發(fā)條件有多個破镰,F(xiàn)ULL GC的時候會STOP THE WORD餐曼。
    • 在執(zhí)行Young gc之前压储,JVM會進行空間分配擔保——如果老年代的連續(xù)空間小于新生代對象的總大薪尽(或歷次晉升的平均大星觥),則觸發(fā)一次full gc瓶佳。
    • 顯式調用System.gc()方法時芋膘;
    • 大對象直接進入老年代持灰,從年輕代晉升上來的老對象譬嚣,嘗試在老年代分配內存時蟀悦,但是老年代內存空間不夠野芒;

12. JVM內存模型

JVM內存模型
  • Java虛擬機規(guī)范定義Java內存模型叹谁,嘗試屏蔽掉各種硬件和操作系統(tǒng)的訪問差異蜕猫;
  • JVM內存模型的目標:定義程序中各個變量的訪問規(guī)則祭阀,即在虛擬機中將變量存儲到內存和從內存取出來這樣的細節(jié)惦界;
  • volatile關鍵字:當一個變量用volatile關鍵字限定后傻工,會有兩個語義:(1)當這個變量的值被修改后霞溪,會立即刷新到主內存中,對其他線程可見中捆;當某個線程讀取這個變量的時候鸯匹,也會重新將主內存中的數(shù)據(jù)刷一份到工作內存中來。但是泄伪,如果多線程操作這個變量的計算中殴蓬,后一個值依賴前一個值,就還是會有并發(fā)問題蟋滴,說明volatile不具備原子性染厅;(2)禁止指令重排優(yōu)化,觀察voatile變量對應的字節(jié)碼文件津函,會發(fā)現(xiàn)變量的操作指令后面加了一句lock addl $0x0,(%esp)的操作肖粮,這個操作相當于一個內存屏障。
  • synchronized關鍵字:當一個線程對一個變量加鎖的時候尔苦,就會清空這個變量在當前工作內存中的值尿赚,因此該關鍵字同時滿足了可見性和原子性。
  • 參考資料

13. Java運行時數(shù)據(jù)區(qū)

Java虛擬機運行時數(shù)據(jù)區(qū)
  • 程序計數(shù)器(PC):Java線程私有蕉堰,類似于操作系統(tǒng)里的PC計數(shù)器,用于指定下一條需要執(zhí)行的字節(jié)碼的地址悲龟;
  • Java虛擬機棧:Java線程私有屋讶,虛擬機展描述的是Java方法執(zhí)行的內存模型:每個方法在執(zhí)行的時候,都會創(chuàng)建一個棧幀用于存儲局部變量须教、操作數(shù)皿渗、動態(tài)鏈接斩芭、方法出口等信息;每個方法調用都意味著一個棧幀在虛擬機棧中入棧到出棧的過程乐疆;
  • 本地方法棧:和Java虛擬機棧的作用類似划乖,區(qū)別是該該區(qū)域為JVM調用到的本地方法服務;
  • 堆(Heap):所有線程共享的一塊區(qū)域挤土,垃圾收集器管理的主要區(qū)域琴庵。目前主要的垃圾回收算法都是分代收集,因此該區(qū)域還可以細分為如下區(qū)域:
    • 年輕代
      • Eden空間
      • From Survivor空間1仰美,F(xiàn)rom Survivor空間2迷殿,用于存儲在Young gc過程中幸存的對象;
    • 老年代
  • 方法區(qū):各個線程共享的一個區(qū)域咖杂,用于存儲虛擬機加載的類信息庆寺、常量、靜態(tài)變量等信息诉字;
    • 運行時常量池:方法區(qū)的一部分懦尝,用于存放編譯器生成的各種字面量和符號引用;

14. 事務的實現(xiàn)原理


本號專注于后端技術、JVM問題排查和優(yōu)化墨叛、Java面試題止毕、個人成長和自我管理等主題,為讀者提供一線開發(fā)者的工作和成長經驗漠趁,期待你能在這里有所收獲扁凛。


javaadu
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市闯传,隨后出現(xiàn)的幾起案子谨朝,更是在濱河造成了極大的恐慌,老刑警劉巖甥绿,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件字币,死亡現(xiàn)場離奇詭異,居然都是意外死亡共缕,警方通過查閱死者的電腦和手機洗出,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來图谷,“玉大人翩活,你說我怎么就攤上這事阱洪。” “怎么了菠镇?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵冗荸,是天一觀的道長。 經常有香客問我利耍,道長蚌本,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任堂竟,我火速辦了婚禮魂毁,結果婚禮上,老公的妹妹穿的比我還像新娘出嘹。我一直安慰自己席楚,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布税稼。 她就那樣靜靜地躺著烦秩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪郎仆。 梳的紋絲不亂的頭發(fā)上只祠,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音扰肌,去河邊找鬼抛寝。 笑死,一個胖子當著我的面吹牛曙旭,可吹牛的內容都是我干的盗舰。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼桂躏,長吁一口氣:“原來是場噩夢啊……” “哼钻趋!你這毒婦竟也來了?” 一聲冷哼從身側響起剂习,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蛮位,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鳞绕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體失仁,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年们何,在試婚紗的時候發(fā)現(xiàn)自己被綠了萄焦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡垂蜗,死狀恐怖楷扬,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情贴见,我是刑警寧澤烘苹,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站片部,受9級特大地震影響镣衡,放射性物質發(fā)生泄漏。R本人自食惡果不足惜档悠,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一廊鸥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辖所,春花似錦惰说、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酥宴,卻和暖如春啦吧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拙寡。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工授滓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肆糕。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓般堆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親擎宝。 傳聞我的和親對象是個殘疾皇子郁妈,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容

  • 從三月份找實習到現(xiàn)在,面了一些公司绍申,掛了不少噩咪,但最終還是拿到小米、百度极阅、阿里胃碾、京東、新浪筋搏、CVTE仆百、樂視家的研發(fā)崗...
    時芥藍閱讀 42,184評論 11 349
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法奔脐,內部類的語法俄周,繼承相關的語法吁讨,異常的語法,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • Java線程的狀態(tài): New 剛被new出來峦朗,沒有調用start方法 Runnable 調用了start方法建丧,可以...
    DeppWang閱讀 384評論 0 1
  • Java SE 基礎: 封裝、繼承波势、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務)結合為一個獨立的整體翎朱,并盡...
    Jayden_Cao閱讀 2,099評論 0 8
  • 這個故事的主人翁是一德高望重拴曲、玉樹臨風的心理師。為尊者諱凛忿,寫這個故事時澈灼,我需要給他另取一個名字≈斗牵可我想啊想啊蕉汪,想破...
    吳益軍子閱讀 638評論 0 2