Java两年工作经验面试
Java兩年工作經(jīng)驗(yàn)面試題目和心得
- 一、ArrayList和LinkedList的區(qū)別?
- 二、ArrayList的底層擴(kuò)容機(jī)制是如何實(shí)現(xiàn)的?
- 三、spring的aop底層實(shí)現(xiàn)方式有哪些?
- 四、HashMap的底層實(shí)現(xiàn)原理?
- 4.1 HashMap的幾個(gè)重要知識(shí)點(diǎn)
- 4.2 JDK7與JDK8的HashMap區(qū)別
- 4.3 HashMap的容量與擴(kuò)容機(jī)制
- 五、MySQL的事務(wù)隔離級(jí)別有哪些?
一、ArrayList和LinkedList的區(qū)別?
ArrayList是基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,LinkedList是基于鏈表的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,對(duì)于隨機(jī)訪問(wèn),ArrayList的get和set查詢效率要高一些,因?yàn)槭峭ㄟ^(guò)索引去定位進(jìn)行訪問(wèn)的,而LinkedList是通過(guò)指針一步一步的移動(dòng)(遍歷)來(lái)實(shí)現(xiàn),而對(duì)于新增和刪除,LinkedList效率要高,只需要對(duì)指針進(jìn)行修改即可,而ArrayList需要西東數(shù)據(jù)來(lái)填補(bǔ)被刪除的元素。
兩者空間復(fù)雜度對(duì)比:
ArrayList 是線性表(數(shù)組)
get() 直接讀取第幾個(gè)下標(biāo),復(fù)雜度 O(1)
add(E) 添加元素,直接在后面添加,復(fù)雜度O(1)
add(index, E) 添加元素,在第幾個(gè)元素后面插入,后面的元素需要向后移動(dòng),復(fù)雜度O(n)
remove()刪除元素,后面的元素需要逐個(gè)移動(dòng),復(fù)雜度O(n)
LinkedList 是鏈表的操作
get() 獲取第幾個(gè)元素,依次遍歷,復(fù)雜度O(n)
add(E) 添加到末尾,復(fù)雜度O(1)
add(index, E) 添加第幾個(gè)元素后,需要先查找到第幾個(gè)元素,直接指針指向操作,復(fù)雜度O(n)
remove()刪除元素,直接指針指向操作,復(fù)雜度O(1)
二、ArrayList的底層擴(kuò)容機(jī)制是如何實(shí)現(xiàn)的?
首先初始化一個(gè)ArrayList數(shù)組,長(zhǎng)度個(gè)數(shù)為0,當(dāng)往里添加一個(gè)元素時(shí),默認(rèn)擴(kuò)容的容量大小為10,接著做一個(gè)if的判斷,判斷數(shù)組的長(zhǎng)度和默認(rèn)容量的大小,如果比10要小,則容量為10;如果比10要大,則進(jìn)行1.5倍的擴(kuò)容。
為什么是1.5倍呢?
k=1.5時(shí),就能充分利用前面已經(jīng)釋放的空間。
為什么是1.5,而不是1.2,1.25,1.8或者1.75?
因?yàn)?.5 可以充分利用移位操作,減少浮點(diǎn)數(shù)或者運(yùn)算時(shí)間和運(yùn)算次數(shù)。
三、spring的aop底層實(shí)現(xiàn)方式有哪些?
1.xml配置文件中配置aop相關(guān)的標(biāo)簽
2.通過(guò)注解方式來(lái)配置aop的功能,@Aspect
(1)Aspect(切面):通常是一個(gè)類,里面可以定義切入點(diǎn)和通知
(2)JointPoint(連接點(diǎn)):程序執(zhí)行過(guò)程中明確的點(diǎn),一般是方法的調(diào)用
(3)Advice(通知):AOP在特定的切入點(diǎn)上執(zhí)行的增強(qiáng)處理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入點(diǎn)):就是帶有通知的連接點(diǎn),在程序中主要體現(xiàn)為書(shū)寫(xiě)切入點(diǎn)表達(dá)式
四、HashMap的底層實(shí)現(xiàn)原理?
4.1 HashMap的幾個(gè)重要知識(shí)點(diǎn)
HashMap是無(wú)序且不安全的哈希數(shù)據(jù)結(jié)構(gòu)。
HashMap 是以key–value對(duì)的形式存儲(chǔ)的,key值是唯一的(可以為null),一個(gè)key只能對(duì)應(yīng)著一個(gè)value,但是value是可以重復(fù)的。
HashMap 如果再次添加相同的key值,它會(huì)覆蓋key值所對(duì)應(yīng)的內(nèi)容,這也是與HashSet不同的一點(diǎn),Set通過(guò)add添加相同的對(duì)象,不會(huì)再添加到Set中去。
HashMap 提供了get方法,通過(guò)key值取對(duì)應(yīng)的value值,但是HashSet只能通過(guò)迭代器Iterator來(lái)遍歷數(shù)據(jù),找對(duì)象。
4.2 JDK7與JDK8的HashMap區(qū)別
既然講HashMap,那就不得不說(shuō)一下JDK7與JDK8(及jdk8以后)的HashMap有什么區(qū)別:
jdk8中添加了紅黑樹(shù),當(dāng)鏈表長(zhǎng)度大于等于8的時(shí)候鏈表會(huì)變成紅黑樹(shù)
鏈表新節(jié)點(diǎn)插入鏈表的順序不同(jdk7是插入頭結(jié)點(diǎn),jdk8因?yàn)橐焰湵碜優(yōu)榧t 黑樹(shù)所以采用插入尾節(jié)點(diǎn))
hash算法簡(jiǎn)化 ( jdk8 )
resize的邏輯修改(jdk7會(huì)出現(xiàn)死循環(huán),jdk8不會(huì))
4.3 HashMap的容量與擴(kuò)容機(jī)制
1.HashMap的默認(rèn)負(fù)載因子
面試的時(shí)候,面試官經(jīng)常會(huì)問(wèn)道一個(gè)問(wèn)題:為什么HashMap的默認(rèn)負(fù)載因子是0.75,而不是0.5或者是整數(shù)1呢?答案有兩種:
閾值(threshold) = 負(fù)載因子(loadFactor) x 容量(capacity) 根據(jù)HashMap的擴(kuò)容機(jī)制,他會(huì)保證容量(capacity)的值永遠(yuǎn)都是2的冪 為了保證負(fù)載因子x容量的結(jié)果是一個(gè)整數(shù),這個(gè)值是0.75(4/3)比較合理,因?yàn)檫@個(gè)數(shù)和任何2的次冪乘積結(jié)果都是整數(shù)。
理論上來(lái)講,負(fù)載因子越大,導(dǎo)致哈希沖突的概率也就越大,負(fù)載因子越小,費(fèi)的空間也就越大,這是一個(gè)無(wú)法避免的利弊關(guān)系,所以通過(guò)一個(gè)簡(jiǎn)單的數(shù)學(xué)推理,可以測(cè)算出這個(gè)數(shù)值在0.75左右是比較合理的
2.HashMap的擴(kuò)容機(jī)制
寫(xiě)數(shù)據(jù)之后會(huì)可能觸發(fā)擴(kuò)容,HashMap結(jié)構(gòu)內(nèi),我記得有一個(gè)記錄當(dāng)前數(shù)據(jù)量的字段,這個(gè)數(shù)據(jù)量字段到達(dá)擴(kuò)容閾值的話,它就會(huì)觸發(fā)擴(kuò)容的操作
問(wèn)題又來(lái)了,為什么計(jì)算擴(kuò)容后容量要采用位移運(yùn)算呢,怎么不直接乘以2呢?這個(gè)問(wèn)題就比較簡(jiǎn)單了,因?yàn)閏pu畢竟它不支持乘法運(yùn)算,所有的乘法運(yùn)算它最終都是再指令層面轉(zhuǎn)化為了加法實(shí)現(xiàn)的,這樣效率很低,如果用位運(yùn)算的話對(duì)cpu來(lái)說(shuō)就非常的簡(jiǎn)潔高效。
3.HashMap中散列表數(shù)組初始長(zhǎng)度
老問(wèn)題又來(lái)了,為啥HashMap中初始化大小為什么是16呢?
二進(jìn)制的按位運(yùn)算,那為什么不是8,4呢? 因?yàn)槭?或者4的話很容易導(dǎo)致map擴(kuò)容影響性能,如果分配的太大的話又會(huì)浪費(fèi)資源,所以就使用16作為初始大小。
五、MySQL的事務(wù)隔離級(jí)別有哪些?
讀未提交、讀提交、可重復(fù)度、串行化,性能依次往下越來(lái)越差
總結(jié)
以上是生活随笔為你收集整理的Java两年工作经验面试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 艾默生DCS(ModbusTCP)与西门
- 下一篇: 慕课网_《Java实现邮箱验证》学习总结