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