java面试题集合
文章目錄
- 面試題一
- 1.面向?qū)ο蠛兔嫦蜻^程的區(qū)別
- 2.Java的四個基本特性(抽象、封裝、繼承,多態(tài))
- 3.重載和重寫的區(qū)別
- 4.構(gòu)造器Constructor是否可被override
- 5.訪問控制符public,protected,private,以及默認的區(qū)別
- 6.是否可以繼承String類
- 7.String和StringBuffer、StringBuilder的區(qū)別
- 8.hashCode和equals方法的關(guān)系
- 9.抽象類和接口的區(qū)別
- 10.自動裝箱與拆箱
- 11.什么是泛型、為什么要使用以及泛型擦除
- 12.Java中的集合類及關(guān)系圖
- 面試題二
- 13.HashMap實現(xiàn)原理
- 14.HashTable實現(xiàn)原理
- 15.HashMap和HashTable區(qū)別
- 16.ArrayList和vector區(qū)別
- 17.ArrayList和LinkedList區(qū)別及使用場景
- 18.Collection和Collections的區(qū)別
- 19.Concurrenthashmap實現(xiàn)原理
- 20.Error、Exception區(qū)別
- 21.Unchecked
- 面試題三
- 39.Java中的NIO,BIO,AIO分別是什么
- 40.IO和NIO區(qū)別
- 41.序列化與反序列化
- 42.常見的序列化協(xié)議有哪些
- 43.內(nèi)存溢出和內(nèi)存泄漏的區(qū)別
- 44.Java內(nèi)存模型及各個區(qū)域的OOM,如何重現(xiàn)OOM
- 45.出現(xiàn)OOM如何解決
- 47.Java內(nèi)存管理及回收算法
- 48.Statement和PreparedStatement之間的區(qū)別
- 51.servlet生命周期及各個方法
- 52.servlet中如何自定義filter
- 53.JSP原理
- 54.JSP和Servlet的區(qū)別
- 55.JSP的動態(tài)include和靜態(tài)include
- 面試題五
- 72.Tomcat,Apache,JBoss的區(qū)別
- 73.memcached和redis的區(qū)別
- 74.如何理解分布式鎖
- 75.你知道的開源協(xié)議有哪些
- 76.json和xml區(qū)別
- 面試題六
- 23.多線程的實現(xiàn)方式
- 24.線程的狀態(tài)轉(zhuǎn)換
- 25.如何停止一個線程
- 26.什么是線程安全
- 27.如何保證線程安全
- 28.synchronized如何使用
- 29.synchronized和Lock的區(qū)別
- 30.多線程如何進行等待通知/信息交互
- 31.sleep和wait的區(qū)別(考察的方向是是否會釋放鎖)
- 32.多線程與死鎖
- 33.如何才能產(chǎn)生死鎖
- 34.死鎖的預(yù)防
- 面試題七
- 35.什么叫守護線程,用什么方法實現(xiàn)守護線程
- 36.Java線程池技術(shù)及原理
- 37.java并發(fā)包concurrent及常用的類
- 38.volatile關(guān)鍵字
- 面試題八
- 22.Java中如何實現(xiàn)代理機制(JDK、CGLIB)
- 48.Java類加載器及如何加載類(雙親委派)
- 57.MVC概念
- 58.Springmvc與Struts區(qū)別
面試題一
1.面向?qū)ο蠛兔嫦蜻^程的區(qū)別
面向過程
優(yōu)點:性能比面向?qū)ο蟾?#xff0c;因為類調(diào)用時需要實例化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發(fā)、Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。
缺點:沒有面向?qū)ο笠拙S護、易復(fù)用、易擴展
面向?qū)ο?br /> 優(yōu)點:易維護、易復(fù)用、易擴展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計出低耦合的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護
缺點:性能比面向過程低
2.Java的四個基本特性(抽象、封裝、繼承,多態(tài))
抽象:就是把現(xiàn)實生活中的某一類東西提取出來,用程序代碼表示,我們通常叫做類或者接口。抽象包括兩個方面:一個是數(shù)據(jù)抽象,一個是過程抽象。數(shù)據(jù)抽象也就是對象的屬性。過程抽象是對象的行為特征。
封裝:把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進行封裝隱藏。封裝分為屬性的封裝和方法的封裝。
繼承:是對有著共同特性的多類事物,進行再抽象成一個類。這個類就是多類事物的父類。父類的意義在于抽取多類事物的共性。
多態(tài):允許不同類的對象對同一消息做出響應(yīng)。方法的重載、類的覆蓋正體現(xiàn)了多態(tài)。
3.重載和重寫的區(qū)別
重載:發(fā)生在同一個類中,方法名必須相同,參數(shù)類型不同、個數(shù)不同、順序不同,方法返回值和訪問修飾符可以不同,發(fā)生在編譯時。
重寫:發(fā)生在父子類中,方法名、參數(shù)列表必須相同,返回值小于等于父類,拋出的異常小于等于父類,訪問修飾符大于等于父類;如果父類方法訪問修飾符為private則子類中就不是重寫。
4.構(gòu)造器Constructor是否可被override
構(gòu)造器不能被重寫,不能用static修飾構(gòu)造器,只能用public,private protected這三個權(quán)限修飾符,且不能有返回語句。
5.訪問控制符public,protected,private,以及默認的區(qū)別
private只有在本類中才能訪問;
public在任何地方都能訪問;
protected在同包內(nèi)的類及包外的子類能訪問;
默認不寫在同包內(nèi)能訪問。
6.是否可以繼承String類
String類是final類故不可以繼承,一切由final修飾過的都不能繼承。
7.String和StringBuffer、StringBuilder的區(qū)別
可變性
String類中使用字符數(shù)組保存字符串,private final char value[],所以string對象是不可變的。StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,char[] value,這兩種對象都是可變的。
線程安全性
String中的對象是不可變的,也就可以理解為常量,線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對方法加了同步鎖或者對調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder并沒有對方法進行加同步鎖,所以是非線程安全的。
性能
每次對String 類型進行改變的時候,都會生成一個新的String 對象,然后將指針指向新的String 對象。StringBuffer每次都會對StringBuffer 對象本身進行操作,而不是生成新的對象并改變對象引用。相同情況下使用StirngBuilder 相比使用StringBuffer 僅能獲得10%~15% 左右的性能提升,但卻要冒多線程不安全的風險。
8.hashCode和equals方法的關(guān)系
equals相等,hashcode必相等;hashcode相等,equals可能不相等。
9.抽象類和接口的區(qū)別
語法層次
抽象類和接口分別給出了不同的語法定義。
設(shè)計層次
抽象層次不同,抽象類是對類抽象,而接口是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是接口卻是對類局部(行為)進行抽象。抽象類是自底向上抽象而來的,接口是自頂向下設(shè)計出來的。
跨域不同
抽象類所體現(xiàn)的是一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is-a"
關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于接口則不然,并不要求接口的實現(xiàn)者和接口定義在概念本質(zhì)上是一致的,僅僅是實現(xiàn)了接口定義的契約而已,"like-a"的關(guān)系。
10.自動裝箱與拆箱
裝箱:將基本類型用它們對應(yīng)的引用類型包裝起來;
拆箱:將包裝類型轉(zhuǎn)換為基本數(shù)據(jù)類型;
Java使用自動裝箱和拆箱機制,節(jié)省了常用數(shù)值的內(nèi)存開銷和創(chuàng)建對象的開銷,提高了效率,由編譯器來完成,編譯器會在編譯期根據(jù)語法決定是否進行裝箱和拆箱動作。
11.什么是泛型、為什么要使用以及泛型擦除
泛型,即“參數(shù)化類型”。
創(chuàng)建集合時就指定集合元素的類型,該集合只能保存其指定類型的元素,避免使用強制類型轉(zhuǎn)換。
Java編譯器生成的字節(jié)碼是不包涵泛型信息的,泛型類型信息將在編譯處理是被擦除,這個過程即類型擦除。泛型擦除可以簡單的理解為將泛型java代碼轉(zhuǎn)換為普通java代碼,只不過編譯器更直接點,將泛型java代碼直接轉(zhuǎn)換成普通java字節(jié)碼。
類型擦除的主要過程如下:
1).將所有的泛型參數(shù)用其最左邊界(最頂級的父類型)類型替換。
2).移除所有的類型參數(shù)。
12.Java中的集合類及關(guān)系圖
List和Set繼承自Collection接口。
Set無序不允許元素重復(fù)。HashSet和TreeSet是兩個主要的實現(xiàn)類。
List有序且允許元素重復(fù)。ArrayList、LinkedList和Vector是三個主要的實現(xiàn)類。
Map也屬于集合系統(tǒng),但和Collection接口沒關(guān)系。Map是key對value的映射集合,其中key列就是一個集合。key不能重復(fù),但是value可以重復(fù)。HashMap、TreeMap和Hashtable是三個主要的實現(xiàn)類。
SortedSet和SortedMap接口對元素按指定規(guī)則排序,SortedMap是對key列進行排序。
面試題二
13.HashMap實現(xiàn)原理
? https://www.iteye.com/blog/zhangshixi-672697
14.HashTable實現(xiàn)原理
? https://www.cnblogs.com/skywang12345/p/3310887.html
? https://blog.csdn.net/chdjj/article/details/38581035
15.HashMap和HashTable區(qū)別
? 1)HashTable的方法前面都有synchronized來同步,是線程安全的;HashMap未經(jīng)同步,是非線程安全的。
? 2)HashTable不允許null值(key和value都不可以) ;HashMap允許null值(key和value都可以)。
? 3)HashTable有一個contains(Object value)功能和containsValue(Object value)功能一樣。
? 4)HashTable使用Enumeration進行遍歷;HashMap使用Iterator進行遍歷。
? 5)HashTable中hash數(shù)組默認大小是11,增加的方式是old*2+1;HashMap中hash數(shù)組的默認大小是16,而且一定是2的指數(shù)。
? 6)哈希值的使用不同,HashTable直接使用對象的hashCode; HashMap重新計算hash值,而且用與代替求模。
16.ArrayList和vector區(qū)別
? ArrayList和Vector都實現(xiàn)了List接口,都是通過數(shù)組實現(xiàn)的。
? Vector是線程安全的,而ArrayList是非線程安全的。
? List第一次創(chuàng)建的時候,會有一個初始大小,隨著不斷向List中增加元素,當List 認為容量不夠的時候就會進行擴容。Vector缺省情況下自動增長原來一倍的數(shù)組長度,ArrayList增長原來的50%。
17.ArrayList和LinkedList區(qū)別及使用場景
? 區(qū)別
? ArrayList底層是用數(shù)組實現(xiàn)的,可以認為ArrayList是一個可改變大小的數(shù)組。隨著越來越多的元素被添加到ArrayList中,其規(guī)模是動態(tài)增加的。
? LinkedList底層是通過雙向鏈表實現(xiàn)的, LinkedList和ArrayList相比,增刪的速度較快。但是查詢和修改值的速度較慢。同時,LinkedList還實現(xiàn)了Queue接 口,所以他還提供了offer(),peek(), poll()等方法。
? 使用場景
? LinkedList更適合從中間插入或者刪除(鏈表的特性)。
? ArrayList更適合檢索和在末尾插入或刪除(數(shù)組的特性)。
18.Collection和Collections的區(qū)別
? java.util.Collection 是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。Collection接口在Java 類庫中有很多具體的實現(xiàn)。Collection接口的意義是為各種具體的集合提供了最大化的統(tǒng)一操作方式。
? java.util.Collections 是一個包裝類。它包含有各種有關(guān)集合操作的靜態(tài)多態(tài)方法。此類不能實例化,就像一個工具類,服務(wù)于Java的Collection框架。
19.Concurrenthashmap實現(xiàn)原理
? https://blog.csdn.net/weixin_43185598/article/details/87938882
20.Error、Exception區(qū)別
? Error類和Exception類的父類都是throwable類,他們的區(qū)別是:
? Error類一般是指與虛擬機相關(guān)的問題,如系統(tǒng)崩潰,虛擬機錯誤,內(nèi)存空間不足,方法調(diào)用棧溢等。對于這類錯誤的導(dǎo)致的應(yīng)用程序中斷,僅靠程序本身無法恢復(fù)和和預(yù)防,遇到這樣的錯誤,建議讓程序終止。
? Exception類表示程序可以處理的異常,可以捕獲且可能恢復(fù)。遇到這類異常,應(yīng)該盡可能處理異常,使程序恢復(fù)運行,而不應(yīng)該隨意終止異常。
21.Unchecked
? Exception和Checked Exception,各列舉幾個#
? Unchecked Exception:
? a. 指的是程序的瑕疵或邏輯錯誤,并且在運行時無法恢復(fù)。
? b. 包括Error與RuntimeException及其子類,如:OutOfMemoryError,
? UncheckedndeclaredThrowableException, IllegalArgumentException,
? IllegalMonitorStateException, NullPointerException, IllegalStateException,
? IndexOutOfBoundsException等。
? c. 語法上不需要聲明拋出異常。
? Checked Exception:
? a. 代表程序不能直接控制的無效外界情況(如用戶輸入,數(shù)據(jù)庫問題,網(wǎng)絡(luò)異常,文件丟失等)
? b. 除了Error和RuntimeException及其子類之外,如:ClassNotFoundException,
? NamingException, ServletException, SQLException, IOException等。
? c. 需要try catch處理或throws聲明拋出異常。
面試題三
39.Java中的NIO,BIO,AIO分別是什么
BIO:同步并阻塞,服務(wù)器實現(xiàn)模式為一個連接一個線程,即客戶端有連接請求時服務(wù)器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。BIO方式適用于連接數(shù)目比較小且固定的架構(gòu),這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解。
NIO:同步非阻塞,服務(wù)器實現(xiàn)模式為一個請求一個線程,即客戶端發(fā)送的連接請求都會注冊到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請求時才啟動一個線程進行處理。NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu),比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中,編程比較復(fù)雜,JDK1.4開始支持。
AIO:異步非阻塞,服務(wù)器實現(xiàn)模式為一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動線程進行處理.AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構(gòu),比如相冊服務(wù)器,充分調(diào)用OS參與并發(fā)操作,編程比較復(fù)雜,JDK7開始支持。
40.IO和NIO區(qū)別
一.IO是面向流的,NIO是面向緩沖區(qū)的。
二.IO的各種流是阻塞的,NIO是非阻塞模式。
三.Java NIO的選擇器允許一個單獨的線程來監(jiān)視多個輸入通道,你可以注冊多個通道使用一個選擇器,然后使用一個單獨的線程來“選擇”通道:這些通道里已經(jīng)有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。
41.序列化與反序列化
把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。
把字節(jié)序列恢復(fù)為對象的過程稱為對象的反序列化。
對象的序列化主要有兩種用途:
一.把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中;
二.在網(wǎng)絡(luò)上傳送對象的字節(jié)序列。
當兩個進程在進行遠程通信時,彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會以二進制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個Java對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為Java對象。
42.常見的序列化協(xié)議有哪些
Protobuf, Thrift, Hessian, Kryo
43.內(nèi)存溢出和內(nèi)存泄漏的區(qū)別
內(nèi)存溢出是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory。
內(nèi)存泄漏是指分配出去的內(nèi)存不再使用,但是無法回收。
44.Java內(nèi)存模型及各個區(qū)域的OOM,如何重現(xiàn)OOM
https://hllvm-group.iteye.com/group/wiki/2857-JVM45.出現(xiàn)OOM如何解決
一. 可通過命令定期抓取heap dump或者啟動參數(shù)OOM時自動抓取heap dump文件。
二. 通過對比多個heap dump,以及heap dump的內(nèi)容,分析代碼找出內(nèi)存占用最多的地方。
三. 分析占用的內(nèi)存對象,是否是因為錯誤導(dǎo)致的內(nèi)存未及時釋放,或者數(shù)據(jù)過多導(dǎo)致的內(nèi)存溢出。
47.Java內(nèi)存管理及回收算法
閱讀這篇文章:
Java 內(nèi)存區(qū)域和GC機制
https://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html
48.Statement和PreparedStatement之間的區(qū)別
關(guān)系:PreparedStatement繼承自Statement,都是接口
區(qū)別:PreparedStatement可以使用占位符,是預(yù)編譯的,批處理比Statement效率高
詳解:
1、PreparedStatement:表示預(yù)編譯的 SQL 語句的對象。
接口:public interface PreparedStatement extends Statement之間的繼承關(guān)系
SQL 語句被預(yù)編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次高效地執(zhí)行該語句。
注:用于設(shè)置 IN 參數(shù)值的設(shè)置方法(setShort、setString 等等)必須指定與輸入?yún)?shù)的已定義 SQL 類型兼容的類型。例如,如果 IN 參數(shù)具有 SQL 類型 INTEGER,那么應(yīng)該使用 setInt 方法,問號的位置也是應(yīng)該注意的,因為第一個問好的位置為1,第二個問號的位置為2.以此類推。
2、Statement:用于執(zhí)行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象。
接口:public interface Statement extends Wrapper
在默認情況下,同一時間每個 Statement 對象只能打開一個 ResultSet 對象。因此,如果讀取一個 ResultSet 對象與另一個交叉,則這兩個對象必須是由不同的 Statement 對象生成的。如果存在某個語句的打開的當前 ResultSet 對象,則 Statement 接口中的所有執(zhí)行方法都會隱式關(guān)閉它。
51.servlet生命周期及各個方法
參考文章 https://www.cnblogs.com/xuekyo/archive/2013/02/24/2924072.html Servlet 生命周期、工作原理
52.servlet中如何自定義filter
參考文章 https://www.cnblogs.com/xuekyo/archive/2013/02/24/2924072.html Servlet Filter - javawebsoa - 博客園
53.JSP原理
參考文章 https://blog.csdn.net/hanxuemin12345/article/details/23831645 JSP運行原理及運行過程 - 韓學(xué)敏 專欄 - 博客頻道 - CSDN.NET
54.JSP和Servlet的區(qū)別
(1)JSP經(jīng)編譯后就變成了“類servlet”。
(2)JSP由HTML代碼和JSP標簽構(gòu)成,更擅長頁面顯示;Servlet更擅長流程控制。
(3)JSP中嵌入JAVA代碼,而Servlet中嵌入HTML代碼。
55.JSP的動態(tài)include和靜態(tài)include
(1)動態(tài)include用jsp:include動作實現(xiàn),如<jsp:include page=“abc.jsp” flush=“true” />,它總是會檢查所含文件中的變化,適合用于包含動態(tài)頁面,并且可以帶參數(shù)。會先解析所要包含的頁面,解析后和主頁面合并一起顯示,即先編譯后包含。
(2)靜態(tài)include用include偽碼實現(xiàn),不會檢查所含文件的變化,適用于包含靜態(tài)頁面,如<%@
include file=“qq.htm” %>,不會提前解析所要包含的頁面,先把要顯示的頁面包含進來,然后統(tǒng)一編譯,即先包含后編譯。
55.JSP的動態(tài)include和靜態(tài)include
(1)動態(tài)include用jsp:include動作實現(xiàn),如<jsp:include page=“abc.jsp” flush=“true” />,它總是會檢查所含文件中的變化,適合用于包含動態(tài)頁面,并且可以帶參數(shù)。會先解析所要包含的頁面,解析后和主頁面合并一起顯示,即先編譯后包含。
(2)靜態(tài)include用include偽碼實現(xiàn),不會檢查所含文件的變化,適用于包含靜態(tài)頁面,如<%@
include file=“qq.htm” %>,不會提前解析所要包含的頁面,先把要顯示的頁面包含進來,然后統(tǒng)一編譯,即先包含后編譯。
面試題五
72.Tomcat,Apache,JBoss的區(qū)別
Apache:HTTP服務(wù)器(WEB服務(wù)器),類似IIS,可以用于建立虛擬站點,編譯處理靜態(tài)頁面,可以支持SSL技術(shù),支持多個虛擬主機等功能。
Tomcat:Servlet容器,用于解析jsp,Servlet的Servlet容器,是高效,輕量級的容器。缺點是不支持EJB,只能用于java應(yīng)用。
Jboss:應(yīng)用服務(wù)器,運行EJB的J2EE應(yīng)用服務(wù)器,遵循J2EE規(guī)范,能夠提供更多平臺的支持和更多集成功能,如數(shù)據(jù)庫連接,JCA等,其對Servlet的支持是通過集成其他Servlet容器來實現(xiàn)的,如tomcat和jetty。
73.memcached和redis的區(qū)別
(1)性能對比:由于Redis只使用單核,而Memcached可以使用多核,所以平均每一個核上Redis在存儲小數(shù)據(jù)時比Memcached性能更高。而在100k以上的數(shù)據(jù)中,Memcached性能要高于Redis,雖然Redis最近也在存儲大數(shù)據(jù)的性能上進行優(yōu)化,但是比起Memcached,還是稍有遜色。
(2)內(nèi)存使用效率對比:使用簡單的key-value存儲的話,Memcached的內(nèi)存利用率更高,而如果Redis采用hash結(jié)構(gòu)來做key-value存儲,由于其組合式的壓縮,其內(nèi)存利用率會高于Memcached。
(3)Redis支持服務(wù)器端的數(shù)據(jù)操作:Redis相比Memcached來說,擁有更多的數(shù)據(jù)結(jié)構(gòu)和并支持更豐富的數(shù)據(jù)操作,通常在Memcached里,你需要將數(shù)據(jù)拿到客戶端來進行類似的修改再set回去。這大大增加了網(wǎng)絡(luò)IO的次數(shù)和數(shù)據(jù)體積。在Redis中,這些復(fù)雜的操作通常和一般的GET/SET一樣高效。所以,如果需要緩存能夠支持更復(fù)雜的結(jié)構(gòu)和操作,那么Redis會是不錯的選擇。
74.如何理解分布式鎖
參考文章:
https://www.cnblogs.com/PurpleDream/p/5559352.html
http://blog.csdn.net/nicewuranran/article/details/51730131
75.你知道的開源協(xié)議有哪些
常見的開源協(xié)議有GPL、LGPL、BSD、Apache Licence
vesion 2.0、MIT,詳細內(nèi)容參考文章:
http://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html。
76.json和xml區(qū)別
XML:
(1)應(yīng)用廣泛,可擴展性強,被廣泛應(yīng)用各種場合;
(2)讀取、解析沒有JSON快;
(3)可讀性強,可描述復(fù)雜結(jié)構(gòu)。
JSON:
(1)結(jié)構(gòu)簡單,都是鍵值對;
(2)讀取、解析速度快,很多語言支持;
(3)傳輸數(shù)據(jù)量小,傳輸速率大大提高;
(4)描述復(fù)雜結(jié)構(gòu)能力較弱。
面試題六
23.多線程的實現(xiàn)方式
1)繼承Thread類
實現(xiàn)Runnable接口
實現(xiàn) Callable 接口。 相較于實現(xiàn) Runnable 接口的方式,方法可以有返回值,并且可以拋出異常,執(zhí)行 Callable 方式,需要 FutureTask 實現(xiàn)類的支持,用于接收運算結(jié)果。 FutureTask 是 Future 接口的實現(xiàn)類
24.線程的狀態(tài)轉(zhuǎn)換
25.如何停止一個線程
線程自然終止:自然執(zhí)行完或拋出未處理異常
使用stop方法強行終止線程,但線程中的stop(), resume(),suspend()已不建議使用,stop()會導(dǎo)致線程不會正確釋放資源,suspend()容易導(dǎo)致死鎖。因為java線程是協(xié)作式,而非搶占式.
使用interrupt方法終止線程. 調(diào)用一個線程的interrupt() 方法中斷一個線程,并不是強行關(guān)閉這個線程,只是跟這個線程打個招呼,將線程的中斷標志位置為true,線程是否中斷,由線程本身決定。而isInterrupted() 判定當前線程是否處于中斷狀態(tài)。static方法interrupted() 判定當前線程是否處于中斷狀態(tài),同時中斷標志位改為false。方法里如果拋出InterruptedException,線程的中斷標志位會被復(fù)位成false,如果確實是需要中斷線程,要求我們自己在catch語句塊里再次調(diào)用interrupt()。
參考: https://blog.csdn.net/anhuidelinger/article/details/11746365
26.什么是線程安全
當多個線程訪問某一個類(對象或方法)時,對象對應(yīng)的公共數(shù)據(jù)區(qū)始終都能表現(xiàn)正確,那么這個類(對象或方法)就是線程安全的
27.如何保證線程安全
線程安全在三個方面體現(xiàn)1.原子性:提供互斥訪問,同一時刻只能有一個線程對數(shù)據(jù)進行操作,(atomic,synchronized);2.可見性:一個線程對主內(nèi)存的修改可以及時地被其他線程看到,(synchronized,volatile);3.有序性:一個線程觀察其他線程中的指令執(zhí)行順序,由于指令重排序,該觀察結(jié)果一般雜亂無序,(happens-before原則).
那么保證線程的安全性可以從以下三個方面著手: 1. 對非安全的代碼進行加鎖控制;2. 使用線程安全的類;3. 多線程并發(fā)情況下,線程共享的變量改為方法級的局部變量
28.synchronized如何使用
1). 無論synchronized關(guān)鍵字加在方法上還是對象上,如果它作用的對象是非靜態(tài)的,則它取得的鎖是對象(對象鎖);如果synchronized作用的對象是一個靜態(tài)方法或一個類,則它取得的鎖是對類,該類所有的對象同一把鎖(類鎖)。
2). 每個對象只有一個鎖(lock)與之相關(guān)聯(lián),誰拿到這個鎖誰就可以運行它所控制的那段代碼。
3) . 實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制
29.synchronized和Lock的區(qū)別
synchronized原始采用的是CPU悲觀鎖機制,即線程獲得的是獨占鎖。獨占鎖意味著其他線程只能依靠阻塞來等待線程釋放鎖。而在CPU轉(zhuǎn)換線程阻塞時會引起線程上下文切換,當有很多線程競爭鎖的時候,會引起CPU頻繁的上下文切換導(dǎo)致效率很低。
而Lock用的是樂觀鎖方式。所謂樂觀鎖就是,每次不加鎖而是假設(shè)沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。樂觀鎖實現(xiàn)的機制就是CAS操作(Compare and Swap)。研究java.util.concurrent.ReentrantLock的源代碼,會發(fā)現(xiàn)其中比較重要的獲得鎖的一個方法是compareAndSetState。這里其實就是調(diào)用的CPU提供的特殊指令。現(xiàn)代的CPU提供了指令,可以自動更新共享數(shù)據(jù),而且能夠檢測到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定。這個算法稱作非阻塞算法,意思是一個線程的失敗或者掛起不應(yīng)該影響其他線程的失敗或掛起的算法.
synchronized原語和ReentrantLock在一般情況下沒有什么區(qū)別,但是在非常復(fù)雜的同步應(yīng)用中,請考慮使用ReentrantLock,特別是遇到下面需求的時候。
1.某個線程在等待一個鎖的控制權(quán)的這段時間需要中斷
2.需要分開處理一些wait-notify,ReentrantLock里面的Condition應(yīng)用,能夠控制notify哪個線程
另外: synchronized是托管給JVM執(zhí)行的,而lock是java寫的控制鎖的代碼. 在Java1.5中,synchronize是性能低效的。因為這是一個重量級操作,需要調(diào)用操作接口,導(dǎo)致有可能加鎖消耗的系統(tǒng)時間比加鎖以外的操作還多。相比之下使用Java提供的Lock對象,性能更高一些。但是到了Java1.6,發(fā)生了變化。synchronized在語義上很清晰,可以進行很多優(yōu)化,有適應(yīng)自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導(dǎo)致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他們也更支持synchronize,在未來的版本中還有優(yōu)化余地.
30.多線程如何進行等待通知/信息交互
void notify() 喚醒在此對象監(jiān)視器上等待的單個線程。
void notifyAll() 喚醒在此對象監(jiān)視器上等待的所有線程。
void wait() 導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法。
void wait(long timeout) 導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法,或者超過指定的時間量。
void wait(long timeout, int nanos) 導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的notify()方法或notifyAll()方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量。
31.sleep和wait的區(qū)別(考察的方向是是否會釋放鎖)
sleep和wait的區(qū)別在于這兩個方法來自不同的類分別是Thread和Object,sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。wait只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用(使用范圍)。
32.多線程與死鎖
死鎖是指兩個或兩個以上的進程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去。
產(chǎn)生死鎖的原因:
一.因為系統(tǒng)資源不足。
二.進程運行推進的順序不合適。
三.資源分配不當。
33.如何才能產(chǎn)生死鎖
產(chǎn)生死鎖的四個必要條件:
一.互斥條件:所謂互斥就是進程在某一時間內(nèi)獨占資源。
二.請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
三.不剝奪條件:進程已獲得資源,在末使用完之前,不能強行剝奪。
四.循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
34.死鎖的預(yù)防
打破產(chǎn)生死鎖的四個必要條件中的一個或幾個,保證系統(tǒng)不會進入死鎖狀態(tài)。
一.打破互斥條件。即允許進程同時訪問某些資源。但是,有的資源是不允許被同時訪問的,像打印機等等,這是由資源本身的屬性所決定的。所以,這種辦法并無實用價值。
二.打破不可搶占條件。即允許進程強行從占有者那里奪取某些資源。就是說,當一個進程已占有了某些資源,它又申請新的資源,但不能立即被滿足時,它必須釋放所占有的全部資源,以后再重新申請。它所釋放的資源可以分配給其它進程。這就相當于該進程占有的資源被隱蔽地強占了。這種預(yù)防死鎖的方法實現(xiàn)起來困難,會降低系統(tǒng)性能。
三.打破占有且申請條件。可以實行資源預(yù)先分配策略。即進程在運行前一次性地向系統(tǒng)申請它所需要的全部資源。如果某個進程所需的全部資源得不到滿足,則不分配任何資源,此進程暫不運行。只有當系統(tǒng)能夠滿足當前進程的全部資源需求時,才一次性地將所申請的資源全部分配給該進程。由于運行的進程已占有了它所需的全部資源,所以不會發(fā)生占有資源又申請資源的現(xiàn)象,因此不會發(fā)生死鎖。
四.打破循環(huán)等待條件,實行資源有序分配策略。采用這種策略,即把資源事先分類編號,按號分配,使進程在申請,占用資源時不會形成環(huán)路。所有進程對資源的請求必須嚴格按資源序號遞增的順序提出。進程占用了小號資源,才能申請大號資源,就不會產(chǎn)生環(huán)路,從而預(yù)防了死鎖。
面試題七
35.什么叫守護線程,用什么方法實現(xiàn)守護線程
? 守護線程擁有自動結(jié)束自己生命周期的特性,而非守護線程不具備這個特點。
? .setDaemon(true)
36.Java線程池技術(shù)及原理
線程池(Thread Pool)是一種基于池化思想管理線程的工具,經(jīng)常出現(xiàn)在多線程服務(wù)器中, 線程池維護多個線程,等待監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù)。這種做法,一方面避免了處理任務(wù)時創(chuàng)建銷毀線程開銷的代價,另一方面避免了線程數(shù)量膨脹導(dǎo)致的過分調(diào)度問題,保證了對內(nèi)核的充分利用。
37.java并發(fā)包concurrent及常用的類
參見: https://www.raychase.net/1912
38.volatile關(guān)鍵字
? 參見: https://www.cnblogs.com/dolphin0520/p/3920373.html
面試題八
22.Java中如何實現(xiàn)代理機制(JDK、CGLIB)
JDK動態(tài)代理:代理類和目標類實現(xiàn)了共同的接口,用到InvocationHandler接口。
CGLIB動態(tài)代理:代理類是目標類的子類,用到MethodInterceptor接口。
48.Java類加載器及如何加載類(雙親委派)
閱讀文章:
深入理解Java類加載器(1):Java類加載原理解析 - Jack Zhou的專欄 - 博客頻道 - CSDN.NET
57.MVC概念
參考文章MVC的概念 - 一江春水 - 博客園
58.Springmvc與Struts區(qū)別
參考文章:
同是流行MVC框架,比較Strtus2和SpringMVC的區(qū)別 - 湯長海的博客 - 博客頻道 - CSDN.NET
SpringMVC與Struts2區(qū)別與比較總結(jié) - Java我人生的技術(shù)博客 - 博客頻道 - CSDN.NET
總結(jié)
- 上一篇: flutter中android子工程报错
- 下一篇: 2020年中山大学CS夏令营