Java面試指南

01、String 為什么是 final


??1枫攀、String 類是一個不可變類括饶,被 final 修改的類不能被繼承,這樣提高了 String 類使用的安全性来涨。
??2图焰、String 類的主要變量 value[]都被設計成private final 的,這樣在多線程時蹦掐,對 String對象的訪問是可以保證安全技羔。
??3、JVM 對 final 修飾的類進行了編譯優(yōu)化卧抗,設計成 final藤滥,JVM 不用對相關(guān)方法在虛函數(shù)表中查詢,直接定位到 String 類的相關(guān)方法調(diào)用社裆,提高了執(zhí)行效率拙绊。


02、Class.forName 和 和 ClassLoader 的區(qū)別


??Class.forNameClassLoader 都是用來裝載類的,對于類的裝載一般為分三個階段加載标沪、鏈接榄攀、編譯,它們裝載類的方式是有區(qū)別金句。
??首先看一下 Class.forName(..)檩赢,forName(..)方法有一個重載方法 forName(className,boolean,ClassLoader)。 它有三個參數(shù)违寞,第一個參數(shù)是類的包路徑贞瞒,第二個參數(shù)是 boolean類型,為 true 地表示 Loading 時會進行初始化趁曼,第三個就是指定一個加載器憔狞;當你調(diào)用class.forName(..)時,默認調(diào)用的是有三個參數(shù)的重載方法彰阴,第二個參數(shù)默認傳入 true,第三個參數(shù)默認使用的是當前類加載時用的加載器瘾敢。
??ClassLoader.loadClass()也有一個重載方法,從源碼中可以看出它默認調(diào)的是它的重載方法 loadClass(name, false)尿这,當?shù)诙?shù)為 false 時簇抵,說明類加載時不會被鏈接。 這也是兩者之間最大區(qū)別射众,前者在加載的時候已經(jīng)初始化碟摆,后者在加載的時候還沒有鏈接。如果你需要在加載時初始化一些東西叨橱,就要用 Class.forName 了典蜕,比如我們常用的驅(qū)動加載,實際上它的注冊動作就是在加載時的一個靜態(tài)塊中完成的。所以它不能被 ClassLoader 加載代替。


03笨使、進程和線程的區(qū)別


image.png

??定義:進程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位嗜憔。線程是進程的一個實體,是 CPU 調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位悄泥。
??特點:
??1、一個進程可以擁有很多個線程,但每個線程只屬于一個進程。
??2火的、線程相對進程而言,劃分尺度更小淑倾,并發(fā)性能更高馏鹤。
??3、進程在執(zhí)行過程中擁有獨立的內(nèi)存單元娇哆,而多個線程共享內(nèi)存湃累,從而極大地提高了程序的運行效率勃救。
??4、線程必須依賴應用脱茉,在應用中調(diào)度,每個線程必須執(zhí)行的入口垄开、出口琴许、執(zhí)行序列,線程是不能夠獨立存在運行的溉躲。
??5榜田、進程是資源分配的基本單位,線程是處理機調(diào)度的基本單位锻梳,所有的線程共享其所屬進程的所有資源與代碼箭券。
??6、多線程的意義在于一個應用程序中疑枯,有多個執(zhí)行部分可以同時執(zhí)行辩块。但操作系統(tǒng)并沒有將多個線程看做多個獨立的應用,來實現(xiàn)進程的調(diào)度和管理以及資源分配荆永。


04废亭、Java 的引用類型有哪幾種


??Java 自從 JDK1.2 版本開始,引入四種引用的類型具钥,它們由強到弱依次是:強引用(StongReference) 豆村、軟引用(SoftReference)、弱引用(WeakReference )骂删、虛引用(PhantomReference) 掌动,它們的各自特點及使用領域。
??強引用: 代碼中最常用看到的 Object o = new Object();這里就是強引用宁玫,只要引用在粗恢,GC 就不回收它,如果 JVM 內(nèi)存空間不足會拋出 OutOfMemoryError欧瘪。
??軟引用:通常用描述一些有用但不是必需的對象适滓,如果 JVM 內(nèi)存不足時,會被 GC恋追,通常被用來作為一些緩存模塊的設計凭迹,而且不容易 OOM。
??弱引用:比軟引用還低級別的引用苦囱,軟引用一般是內(nèi)存不足時回收嗅绸,而弱引用只要被 GC 掃描線程發(fā)現(xiàn)就會回收掉,即便是 JVM 內(nèi)存還充足的情況下撕彤。
??虛引用:如其名鱼鸠,虛無般的存在猛拴,完全不會影響對象的生命周期,如果一個對象僅持有虛引用蚀狰,就如同沒有引用一樣愉昆,可能隨時被回收掉,一般會與強用隊列關(guān)聯(lián)使用麻蹋,一般只用于對象回收的事件傳遞跛溉。


05、Http報文結(jié)構(gòu)


image.png

image.png

??上圖為請求報文扮授,包括“請求行①②③”芳室、“請求頭部④”、“請求包體⑤”刹勃,請求行①②③之間是用空格隔開的堪侯,面試回答時撿主要的說,沒必要把所有的參數(shù)都介紹一下荔仁。
??請求報文包括 “請求行” 伍宦、“ 請 求頭部”“ 請求包體”乏梁;請求行中主要包括:請求方式雹拄、請求地址、Http 版本掌呜,它們之間用空格分開滓玖。請求頭部主要包括 : Accept: 告 訴 服 務 端 客 戶 端 接 受 什 么 類 型 的 響 應 ;Accept-Language:客戶端可接受的自然語言;User-Agent:請求端的瀏覽器以及服務器類型;Accept-Encoding:客戶端可接受的編碼壓縮格式; Accept-Charset:可接受的應答的字符集;Host:請求的主名质蕉,允許多個域名同處一個 IP 地址势篡,即虛擬主機;connection:連接方式(close 或 keep-alive);Cookie:存儲于客戶端擴展字段,向同一域名的服務端發(fā)送屬于該域的 cookie;空行:最后一個請求頭之后是一個空行模暗,發(fā)送回車符和換行符禁悠,通知服務器以下不再有請求頭;
??請求包體:也是請求正文,業(yè)務報文兑宇。
??響應報文包括“狀態(tài)行” 碍侦、“響應頭部”“響應包體”隶糕;狀態(tài)行中包括:Http 協(xié)議版本瓷产、狀態(tài)碼以及狀態(tài)碼描述(常用狀態(tài)碼及描述,500:服務器內(nèi)部錯誤枚驻,404:頁面找不到濒旦,200OK:表示請求成功返回,403:服務器收到請求但拒絕服務再登;其它的 1xx,2xx,3xx,4xx,5xx系尔邓,大家可以網(wǎng)上查找一下晾剖,蠻重要,能說出來就行)梯嗽。
??響應頭部齿尽,Server:響應服務器類型;Content-Type:響應數(shù)據(jù)的文檔類型灯节;Cache-Control:響應輸出到客戶端后循头,服務端通過該報文頭屬告訴客戶端如何控制響應內(nèi)容的緩存。
??響應包體显晶,真正的業(yè)務報文贷岸,也就是請求期望的返回數(shù)據(jù)壹士。


06磷雇、Http 如何 處理長連接


??Http目前有兩個版本分別是 Http1.0 和 Http1.1,Http1.0 默認是短連接躏救,如果需要長連接支持唯笙,需要加上Connection: Keep-alive;Http1.1 的版本默認是支持長連接請求的方式盒使,可以在抓取的請求中看到 Connection: Keep-alive崩掘,如果不想用長連接,需要在報文首部加上 Connection:close;對于默認的長連接可以通過 Keep-Alive:timeout=N 進行超時時間設置少办。
??[追問]對長連接數(shù)據(jù)傳輸完成的識別:第一種:通過 Content-Length 指示的大小苞慢,如果傳的報文長度達到了 Content-Length,則認為傳輸完成英妓。
??第二種:動態(tài)請求生成的文件中往往不包含 Content-Length挽放,往往是通過分塊傳輸入,服務器不能預先判斷文件大小蔓纠,這里要通過 Transfer-Encoding:chunked 模式來傳輸數(shù)據(jù)辑畦。Chunked 是按塊進行數(shù)據(jù)傳輸?shù)模@時候就要根據(jù) chunked 編碼來判斷腿倚,chunked 編碼的數(shù)據(jù)在最后有一個空 chunked 塊纯出,表明本次傳輸數(shù)據(jù)結(jié)束。


07敷燎、TCP三次握手和四次揮手


image.png

image.png

??圖來源于網(wǎng)上暂筝,如果要看懂這個圖,先來了解一下幾個簡單的概念:SYN 表示建立連接硬贯,F(xiàn)IN 表示關(guān)閉連接乖杠,ACK 表示響應,序號是隨機產(chǎn)生的但作用很大澄成,這里不詳細說了胧洒,這幾個關(guān)鍵字在面試的時候有必要先解釋一下畏吓。
??TCP 建立連接和斷開連接的操作有幾個很重要的關(guān)鍵字,分別:SYN 表示請求建立連接卫漫、ACK 表示響應菲饼、FIN 表示關(guān)閉連接請求、隨機序列 會 隨傳送報文 的 字節(jié)數(shù)增加 (SYN 列赎、FIN 都) 算位的宏悦,即便沒有字節(jié)傳送,序列也會增加)包吝。
??TCP 建立連接的三次握手饼煞, 第一次握手:主機 A 發(fā)送位碼為 syn=1,隨機產(chǎn)生 seq =200的數(shù)據(jù)包到服務器,主機 B 由 SYN=1 知道诗越,A 要求建立聯(lián)機砖瞧;
??第二次握手:主機 B 收到請求后要確認聯(lián)機信息,向 A 發(fā)送 ack 確認序列=(主機 A的 seq+1),syn=1,ack=1,隨機產(chǎn)生 seq=500 的包嚷狞;
??第三次握手:主機 A 收到后檢查 ack 確認序列是否正確块促,即第一次發(fā)送的 seq number+1,以及位碼 ack 是否為 1,若正確床未,主機 A 會再發(fā)送 ack number=(主機 B 的seq+1),ack=1竭翠,主機B收到后確認 seq 值與 ack=1 則連接建立成功。
??【三次握手總結(jié)】 主機A發(fā) syn 給主機B薇搁,主機B回 ack,syn 斋扰,主機 A 回 ack ,三次握手啃洋,連接成功传货。
??四次揮手, 第一次揮手:主機A發(fā)送一個FIN裂允,用來關(guān)閉客戶A到服務器B的數(shù)據(jù)傳送损离。
??第二 次揮手:主機B收到這個FIN,它發(fā)回一個ACK绝编,確認序號為收到的序號加 1僻澎。和SYN一樣,一個FIN將占用一個序號十饥。
??第三 次揮手:主機B關(guān)閉與主機A的連接窟勃,發(fā)送一個 FIN 給主機 A。


08逗堵、線程啟動用 start 方法還是run


??下面是 JDK 中 start()方法的源碼秉氧,可以看到 start()調(diào)用的是 start0(),而start0()是一個 native 方法蜒秤,通過注釋可以知道汁咏,它的作用主要是為線程分配系統(tǒng)資源的亚斋;而 run 只是一個普通的方法,所以線程的啟動是通過 start 方法實現(xiàn)的攘滩。

public synchronized void start() {
        if (threadStatus != 0 || this != me)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
            stop0(throwableFromStop);
        }
    }
    private native void start0();

09帅刊、ThreadLocal 的基本原理


??下面兩個問題是一個同學面試的時候遇到的,網(wǎng)上也能看到漂问,問題不難但平時不留意也不太容易回答赖瞒。1、每個線程的變量副本是存儲在哪里的蚤假?2栏饮、threadlocal 是何時初始化的?變量副本是如何為共享的那個變量賦值的磷仰?回答這樣的問題袍嬉,建議大家看一下 JDK相關(guān) threadlocal 部分的源碼,下面只引用部分源碼來解釋說明芒划。
??ThreadLocal 并非是線程的本地實現(xiàn)冬竟,而是線程的本地變量欧穴,它歸附于具體的線程民逼,為每個使用該變量的線程提供一個副本,每個線程都可以獨立的操作這個副本涮帘,在外面看來拼苍,貌似每個線程都有一份變量。線程的變量存在哪里调缨,這里可以結(jié)果 ThreadLocal 的源碼說明疮鲫,這里看一下 get 實現(xiàn)

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

??在 get 方法中,會先獲得當前線程對象弦叶,然后傳到 getMap()中獲取 ThreadLocalMap對象俊犯,我們要的變量副本是從 ThreadLocalMap 對象中取出來的,可見每個線程的變量副本是保存在 ThreadLocalMap 對象里伤哺,而跟一下代碼可以看到 ThreadLocalMap 是在 Thread中聲明實現(xiàn)的燕侠,所以 每個線程的變量副本就保 存 在相應線程的 ThreadLocalMap 對象中。
??第二個問題立莉,可以理解 ThreadLocal 如何把變量的副本復制并且初始化的(聲明和初始化)绢彤,這里看一下源碼中的 set 方法實現(xiàn)

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

??當?shù)谝淮握{(diào)用 set 方法時,獲取的 ThreadLocalMap 對象為空蜓耻,這里會調(diào)用 createMap方法創(chuàng)建一個 ThreadLocalMap 對象茫舶,并且完成相應的初始,將 value 值存放進去刹淌。后面再次調(diào)用將會直接從線程中獲取ThreadLocalMap 對象饶氏,然后將副本保存進去讥耗。


10、JVM內(nèi)存泄露的原因有哪些


??這個問題看似簡單疹启,卻用一個問題考察了 JVM 很多個相關(guān)的知識點葛账,回答這個問題你首先要了解 JVM 的結(jié)構(gòu)、對象的分配與存儲皮仁、GC 的原理等籍琳,但你看到此的時候如果對上面的知識點還不是很熟悉的話,先翻開其相關(guān)知識點贷祈,之前都已經(jīng)談到過趋急,然后這個問題就容易回答了。
??JVM 結(jié)構(gòu)上一般分為堆內(nèi)存势誊、棧內(nèi)存呜达、方法區(qū),內(nèi)存泄露可能會發(fā)生在任何一個位置粟耻;在 JVM 劃分上方法區(qū)通常劃給堆查近,所以這兩塊可以一起。而棧內(nèi)存通常是用來存放普通變量和對象引用挤忙,回收速度速度快霜威,一般不會造成內(nèi)存泄露,一旦溢出通常是棧內(nèi)存大小分配不合理册烈,或者可能顯示的將對象空間分配到棧內(nèi)存來追求效率造成的戈泼。下面我們重點探討堆內(nèi)存的溢出(根據(jù)面試的場景來判斷有沒有談棧內(nèi)存這塊)。
??參考: 首先造成 Java JVM 泄露的主要原因:JVM 未及時的對垃圾進行回收造成的赏僧;當對象失去引用且持續(xù)占有內(nèi)存或無用對象的內(nèi)存得不到及時釋放大猛,從而造成內(nèi)存空間的浪費稱為內(nèi)存泄漏。造成這種對象無法及時釋放導致內(nèi)存泄露的原因淀零,可以簡單的為歸分兩類挽绩。
??一是基 于設計方面 :1、對應用加載數(shù)據(jù)級別判斷失誤驾中,從而導致 JVM 內(nèi)存分配不合理(企業(yè)單機部署應用常見到)唉堪。2、應用請求的常連接設計哀卫,常連接會一直占用后臺資源巨坊,不能及時釋放。3此改、數(shù)據(jù)庫操作時趾撵,存在很多耗時連接,導致大量資源不能釋放。4占调、大量的監(jiān)聽設計等暂题。
??二 是基于開發(fā)方面:1、大量靜態(tài)變量的使用(靜態(tài)變量的生成周期與應用一致)究珊,如果靜態(tài)引用指向的是集合或者數(shù)據(jù)薪者,會一直占用資源。2剿涮、不合理的方法使用言津,比如 jdk6之前的 substring 就可能導致內(nèi)存泄露。3取试、數(shù)據(jù)庫連接未能及時關(guān)閉悬槽,剛工作不久的同學容易忽略。4瞬浓、單例模式使用初婆,單例通常用來加載資源信息,但如果加載信息里有大量的集合猿棉、數(shù)組等對象磅叛,這些資源會一直駐留內(nèi)存中,不易釋放萨赁。5弊琴、在循環(huán)中創(chuàng)建復雜對象、一次性讀取加載大量信息到內(nèi)存中位迂,都有可能造成內(nèi)存泄露访雪。


11详瑞、OO的設計原則


??面向?qū)ο笤O計原則通常歸結(jié)為五大類掂林,
??第 一 “單 一職責原則” (SRP):一個設計元素只做一件事,不要隨意耦合坝橡,多管閑事泻帮;
??第二 “開 放 封閉 原則” (OCP):對變更關(guān)閉、對擴展開放计寇,提倡基于接口設計锣杂,新的需要最好不要去變更已經(jīng)完成的功能,可以靈活通過接口擴展新功能番宁;
??第三 “里氏 替換原則” (LSP):子類可以替換父類并且出現(xiàn)在父類能夠出現(xiàn)的任何地方元莫,這個也是提倡面向接口編程思想的;
??第四 “依賴 倒置原則” (DIP):要依賴于抽象蝶押,不要依賴于具體踱蠢,簡單的說就是面對抽象編程,不要過于依賴于細節(jié)棋电;
??第 五 “接口 隔離原則” (ISP):使用多個專門的接口比使用單個接口要好茎截,在設計中不要把各種業(yè)務類型的東西放到一個接口中造成臃腫苇侵。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市企锌,隨后出現(xiàn)的幾起案子榆浓,更是在濱河造成了極大的恐慌,老刑警劉巖撕攒,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陡鹃,死亡現(xiàn)場離奇詭異,居然都是意外死亡抖坪,警方通過查閱死者的電腦和手機杉适,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柳击,“玉大人猿推,你說我怎么就攤上這事“齐龋” “怎么了蹬叭?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長状知。 經(jīng)常有香客問我秽五,道長,這世上最難降的妖魔是什么饥悴? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任坦喘,我火速辦了婚禮,結(jié)果婚禮上西设,老公的妹妹穿的比我還像新娘瓣铣。我一直安慰自己,他們只是感情好贷揽,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布棠笑。 她就那樣靜靜地躺著,像睡著了一般禽绪。 火紅的嫁衣襯著肌膚如雪蓖救。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天印屁,我揣著相機與錄音循捺,去河邊找鬼。 笑死雄人,一個胖子當著我的面吹牛从橘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼洋满,長吁一口氣:“原來是場噩夢啊……” “哼晶乔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起牺勾,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤正罢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驻民,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翻具,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年回还,在試婚紗的時候發(fā)現(xiàn)自己被綠了裆泳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柠硕,死狀恐怖工禾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蝗柔,我是刑警寧澤闻葵,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站癣丧,受9級特大地震影響槽畔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胁编,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一厢钧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嬉橙,春花似錦早直、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拾给,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兔沃,已是汗流浹背蒋得。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乒疏,地道東北人额衙。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親窍侧。 傳聞我的和親對象是個殘疾皇子县踢,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)伟件,斷路器硼啤,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 風靡世界的“LV”被國內(nèi)一家企業(yè)注冊成煮飯鍋等烹飪工具的商標,法國LVMH酩悅軒尼詩路易斯威登集團公司將核準商標注...
    小好閱讀 167評論 0 1
  • 1.所謂幸福也就是在你追尋了好久的愛情路上流過淚傷過心之后斧账,峰回路轉(zhuǎn)谴返,有一個人出現(xiàn),陪著你咧织,愛著你嗓袱,守護著你. 2...
    夏洛克閱讀 277評論 0 13
  • 什么是管理工作?這可是個很大的話題习绢。但是今天我們不打算去探索一個大而完備的解答渠抹,而是把受眾稍稍聚焦一下,只跟剛剛晉...
    格致教練蔣海濤閱讀 1,982評論 0 8