二、Java基礎(chǔ)
1.接口與抽象類的區(qū)別?
- 接口是抽象方法的集合,一個(gè)類實(shí)現(xiàn)了某個(gè)接口,就必須實(shí)現(xiàn)接口中的所有方法。
- 抽象類是用來(lái)描述子類的通用特性的,不能被實(shí)例化,只能作為子類的超類。
各項(xiàng)差異對(duì)比:
參數(shù) | 抽象類 | 接口 |
---|---|---|
默認(rèn)的方法實(shí)現(xiàn) | 它可以有默認(rèn)的方法實(shí)現(xiàn) | 接口完全是抽象的。它根本不存在方法的實(shí)現(xiàn) |
實(shí)現(xiàn) | 子類使用extends 關(guān)鍵字來(lái)繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實(shí)現(xiàn)。 |
子類使用關(guān)鍵字implements 來(lái)實(shí)現(xiàn)接口。它需要提供接口中所有聲明的方法的實(shí)現(xiàn) |
構(gòu)造器 | 抽象類可以有構(gòu)造器 | 接口不能有構(gòu)造器 |
與普通Java類的區(qū)別 | 除了你不能實(shí)例化抽象類之外,它和普通Java類沒(méi)有任何區(qū)別 | 接口是完全不同的類型 |
訪問(wèn)修飾符 | 抽象方法可以有public 、protected 和default 這些修飾符 |
接口方法默認(rèn)修飾符是public 。你不可以使用其它修飾符。 |
main方法 | 抽象方法可以有main方法并且我們可以運(yùn)行它 | 接口沒(méi)有main方法,因此我們不能運(yùn)行它。 |
多繼承 | 抽象方法可以繼承一個(gè)類和實(shí)現(xiàn)多個(gè)接口 | 接口只可以繼承一個(gè)或多個(gè)其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有點(diǎn)慢的,因?yàn)樗枰獣r(shí)間去尋找在類中實(shí)現(xiàn)的方法。 |
添加新方法 | 如果你往抽象類中添加新的方法,你可以給它提供默認(rèn)的實(shí)現(xiàn)。因此你不需要改變你現(xiàn)在的代碼。 | 如果你往接口中添加方法,那么你必須改變實(shí)現(xiàn)該接口的類。 |
2.Java中的異常有哪幾類?分別怎么使用?
Java的異常分為兩大類:Checked異常和Runtime異常(運(yùn)行時(shí)異常)。所有的RuntimeException類及其子類的實(shí)例被稱為Runtime異常,不是RuntimeException或其子類的異常實(shí)例則被稱為Checked異常。
常見(jiàn)的Checked異常有:IOException, SQLException
常見(jiàn)的Runtime異常有:ArithmeticException, ClassCastException, IllegalArgumentException, NullPointerException
3.常用的集合類有哪些?比如List如何排序?
Java集合類主要從兩個(gè)接口派生而出:Collection
和Map
。
Collection
又派生出Set
,Queue
和List
三個(gè)重要接口。常用實(shí)現(xiàn)類有,HashSet
,LinkedHashSet
,TreeSet
(采用紅黑樹(shù)數(shù)據(jù)結(jié)構(gòu)),EnumSet
(專門(mén)用于存放枚舉變量的Set); ArrayList
(以數(shù)組結(jié)構(gòu)),LinkedList
(以鏈表結(jié)構(gòu)),Vector
(不建議使用), Stack
(不建議使用); PriorityQueue
,ArrayDeque
;
Map
的常見(jiàn)實(shí)現(xiàn)類有HashMap
,LinkedHashMap
,TreeMap
,EnumMap
,Hashtable
(不建議使用)
對(duì)List排序可以采用 Collections.sort(arr)
4.ArrayList和LinkedList內(nèi)部的實(shí)現(xiàn)大致是怎樣的?他們之間的區(qū)別和優(yōu)缺點(diǎn)?
ArrayList
內(nèi)部采用數(shù)組的方式實(shí)現(xiàn),LinkedList
內(nèi)部采用鏈表的方式實(shí)現(xiàn)。由于數(shù)組以一塊連續(xù)內(nèi)存區(qū)域來(lái)保存所有的數(shù)組元素,所以數(shù)組在隨機(jī)訪問(wèn)時(shí)性能最好,即如果訪問(wèn)的頻率遠(yuǎn)高于插入和刪除時(shí),應(yīng)選用ArrayList
。如果插入和刪除的頻率遠(yuǎn)高于訪問(wèn),那么應(yīng)該選用LinkedList
。
5.內(nèi)存溢出是怎么回事?請(qǐng)舉一個(gè)例子?
計(jì)算機(jī)內(nèi)存分配不夠用了。比如遞歸函數(shù)沒(méi)有寫(xiě)跳出,就會(huì)出現(xiàn)棧內(nèi)存溢出。
6.==和equals的區(qū)別?
- 使用==比較原生類型如:boolean、int、char等等,使用equals()比較對(duì)象。
- ==返回true如果兩個(gè)引用指向相同的對(duì)象,equals()的返回結(jié)果依賴于具體業(yè)務(wù)實(shí)現(xiàn)
- 字符串的對(duì)比使用equals()代替==操作符
7.hashCode方法的作用?
- equal()相等的兩個(gè)對(duì)象他們的hashCode()肯定相等,也就是用equal()對(duì)比是絕對(duì)可靠的。
- hashCode()相等的兩個(gè)對(duì)象他們的equal()不一定相等,也就是hashCode()不是絕對(duì)可靠的。
所有對(duì)于需要大量并且快速的對(duì)比的話如果都用equal()去做顯然效率太低,所以解決方式是,每當(dāng)需要對(duì)比的時(shí)候,首先用hashCode()去對(duì)比,如果hashCode()不一樣,則表示這兩個(gè)對(duì)象肯定不相等(也就是不必再用equal()去再對(duì)比了),如果hashCode()相同,此時(shí)再對(duì)比他們的equal(),如果equal()也相同,則表示這兩個(gè)對(duì)象是真的相同了,這樣既能大大提高了效率也保證了對(duì)比的絕對(duì)正確性!
這種大量的并且快速的對(duì)象對(duì)比一般使用的hash容器中,比如HashSet
,HashMap
,Hashtable
等等
8.NIO是什么?適用于何種場(chǎng)景?
簡(jiǎn)而言之,io是面向流的,是就用多少拿多少。是阻塞的。數(shù)據(jù)量不大的或者不在意阻塞的時(shí)可以用。nio是面向塊的,先把數(shù)據(jù)搬過(guò)來(lái),先存到緩存區(qū)里面,如果線程要用從緩存區(qū)拿。所以線程不需要時(shí)刻盯著io了,可以先做一些其他的事情,過(guò)幾天再來(lái)看一下緩存。是同步非阻塞的。因此,nio里有Buffer類作為緩沖區(qū),Channel(通道)相當(dāng)于io里的steam的抽象,Selector是nio提供的管理多個(gè)Channel的工具。nio出現(xiàn)也是因?yàn)閕o漸漸成為一些程序速度的瓶頸。
aio加了一個(gè)異步的特性。當(dāng)我們要拿數(shù)據(jù)花費(fèi)時(shí)間太長(zhǎng)的時(shí)候,我們可以考慮使用異步的io。異步就是可以理解為,讓io先處理著,我線程先去干別的事情了,你io處理完了通知我一下。aio提供的事件處理接口CompletionHandler,定義了回調(diào)函數(shù),這些函數(shù)再io完成后會(huì)被自動(dòng)的調(diào)用。
參考文章:https://www.zhihu.com/question/40930889/answer/146567853
9.HashMap實(shí)現(xiàn)原理,如何保證HashMap的線程安全?
鏈表的數(shù)組。
Map<Object, Object> map = Collections.synchronizedMap(new HashMap<>());
10.JVM內(nèi)存結(jié)構(gòu),為什么需要GC?
方法區(qū),堆,虛擬機(jī)棧,本地方法棧,程序計(jì)數(shù)器。
重點(diǎn)參考文章:JVM內(nèi)存結(jié)構(gòu)
垃圾回收可以有效的防止內(nèi)存泄露,有效的使用空閑的內(nèi)存;
引用計(jì)數(shù)法: 思路簡(jiǎn)單,執(zhí)行效率高。但是無(wú)法檢測(cè)循環(huán)引用。
可達(dá)性分析算法:
標(biāo)記清除算法
復(fù)制算法
標(biāo)記整理算法
分代收集算法
- 根搜索算法,從GCRoot出發(fā),不聯(lián)通的圖極為垃圾。作為GC Root的對(duì)象有:
a. 虛擬機(jī)棧中的引用對(duì)象(本地變量表)
b. 方法區(qū)中常量引用的對(duì)象
c. 方法區(qū)中靜態(tài)屬性引用的對(duì)象
d. 本地方法棧中引用的對(duì)象(Native對(duì)象)
重點(diǎn)參考文章:深入理解 Java 垃圾回收機(jī)制 , 一個(gè)面試官對(duì)面試問(wèn)題的分析
11.NIO模型,select/epoll的區(qū)別,多路復(fù)用的原理
select、poll、epoll之間的區(qū)別總結(jié)[整理]
12.Java中一個(gè)字符占多少個(gè)字節(jié),擴(kuò)展再問(wèn)int, long, double占多少字節(jié)
byte 1字節(jié)
short 2字節(jié)
int 4字節(jié)
long 8字節(jié)
float 4字節(jié)
double 8字節(jié)
char 2字節(jié)
boolean 1字節(jié)
13.創(chuàng)建一個(gè)類的實(shí)例都有哪些辦法?
new
clone
newInstance
14.final/finally/finalize的區(qū)別?
final 限定符,不能被繼承等
finally 配合try使用,一定會(huì)被執(zhí)行
finalize Object中的方法,被CG之前執(zhí)行,只執(zhí)行一次。
15.Session/Cookie的區(qū)別?
一個(gè)在服務(wù)器上,一個(gè)存在客戶端。
16.String/StringBuffer/StringBuilder的區(qū)別,擴(kuò)展再問(wèn)他們的實(shí)現(xiàn)?
String字符串常量
StringBuffer字符串變量(線程安全)
StringBuilder字符串變量(非線程安全)
17.Servlet的生命周期?
Web Client 向Servlet容器(Tomcat)發(fā)出Http請(qǐng)求
Servlet容器接收Web Client的請(qǐng)求
Servlet容器創(chuàng)建一個(gè)HttpRequest對(duì)象,將Web Client請(qǐng)求的信息封裝到這個(gè)對(duì)象中。
Servlet容器創(chuàng)建一個(gè)HttpResponse對(duì)象
Servlet容器調(diào)用HttpServlet對(duì)象的service方法,把HttpRequest對(duì)象與HttpResponse對(duì)象作為參數(shù)傳給 HttpServlet 對(duì)象。
HttpServlet調(diào)用HttpRequest對(duì)象的有關(guān)方法,獲取Http請(qǐng)求信息。
HttpServlet調(diào)用HttpResponse對(duì)象的有關(guān)方法,生成響應(yīng)數(shù)據(jù)。
Servlet容器把HttpServlet的響應(yīng)結(jié)果傳給Web Client。
18.如何用Java分配一段連續(xù)的1G的內(nèi)存空間?需要注意些什么?
使用數(shù)組即可分配連續(xù)1G內(nèi)存,由于分配大內(nèi)存容易出現(xiàn) OutOfMemoryError: Java heap space,因此當(dāng)需要使用這么大內(nèi)存時(shí)首先考慮優(yōu)化算法。
19.Java有自己的內(nèi)存回收機(jī)制,但為什么還存在內(nèi)存泄露的問(wèn)題呢?
內(nèi)存泄露 : 如果分配出去的內(nèi)存得不到釋放,及時(shí)回收,就會(huì)引起系統(tǒng)運(yùn)行速度下降,甚至導(dǎo)致程序癱瘓,這就是內(nèi)存泄露
stackoverflow上關(guān)于創(chuàng)建內(nèi)存泄漏的討論
資源不關(guān)閉就會(huì)導(dǎo)致內(nèi)存泄漏,比如數(shù)據(jù)庫(kù)連接,文件等
20.什么是java序列化,如何實(shí)現(xiàn)java序列化?(寫(xiě)一個(gè)實(shí)例)?
java中的序列化機(jī)制能夠?qū)⒁粋€(gè)實(shí)例對(duì)象(只序列化對(duì)象的屬性值,而不會(huì)去序列化什么所謂的方法。)的狀態(tài)信息寫(xiě)入到一個(gè)字節(jié)流中使其可以通過(guò)socket進(jìn)行傳輸、或者持久化到存儲(chǔ)數(shù)據(jù)庫(kù)或文件系統(tǒng)中;然后在需要的時(shí)候通過(guò)字節(jié)流中的信息來(lái)重構(gòu)一個(gè)相同的對(duì)象。
一般而言,要使得一個(gè)類可以序列化,只需簡(jiǎn)單實(shí)現(xiàn)java.io.Serializable接口即可。
21.String s = new String("abc");創(chuàng)建了幾個(gè) String Object?
2個(gè)。
目錄列表
一、數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)
二、Java基礎(chǔ)
三、JVM
四、多線程/并發(fā)
五、Linux使用與問(wèn)題分析排查
六、框架使用
七、數(shù)據(jù)庫(kù)相關(guān)
八、網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)編程
九、Redis等緩存系統(tǒng)/中間件/NoSQL/一致性Hash等
十、設(shè)計(jì)模式與重構(gòu)
本文是針對(duì)知乎文章《成為Java頂尖程序員,先過(guò)了下面問(wèn)題》的解答