總結(jié)了面試的內(nèi)容大致來(lái)說(shuō)有以下幾點(diǎn)。spring相關(guān)以及核心東西、aop/ioc的應(yīng)用和原理、算法相關(guān)、數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)庫(kù)相關(guān)(存儲(chǔ)、原理、事務(wù))、多線程(線程間通信、鎖、并發(fā)等)、Java常用包、類的原理、中間件(Redis、zookeeper、MQ、Nginx、Dubbo等等)、負(fù)載均衡/集群..
這里就不詳細(xì)說(shuō)面試中的每個(gè)問(wèn)題了,因?yàn)樯厦媸敲嬖嚵撕芏嗉抑筮M(jìn)行了一個(gè)大概的匯總。簡(jiǎn)單的說(shuō)一下幾個(gè)當(dāng)時(shí)回答的不是很滿意的問(wèn)題吧
1、HashMap的數(shù)據(jù)結(jié)構(gòu)
我們知道數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)有數(shù)組(順序存儲(chǔ))和鏈表(鏈?zhǔn)酱鎯?chǔ))
數(shù)組存儲(chǔ)區(qū)間是連續(xù)的,占用內(nèi)存嚴(yán)重,通過(guò)下標(biāo)查找時(shí)時(shí)間復(fù)雜度為O(1),如果通過(guò)值查詢?cè)卮藭r(shí)需要遍歷整個(gè)數(shù)組,所以時(shí)間復(fù)雜度為O(n), 如果對(duì)目標(biāo)元素插入或刪除,都會(huì)導(dǎo)致后面元素的Index發(fā)生改變,所以時(shí)間復(fù)雜度也是O(n)??偨Y(jié)來(lái)看數(shù)組的特點(diǎn)為:尋址容易,插入和刪除比較困難。
相反鏈表存儲(chǔ)區(qū)間離散,占用內(nèi)存比較寬松。通過(guò)節(jié)點(diǎn)之間的引用對(duì)數(shù)據(jù)進(jìn)行處理,特點(diǎn)是:尋址難,插入和刪除簡(jiǎn)單。
這樣看來(lái)兩種數(shù)據(jù)結(jié)構(gòu)基本算是兩個(gè)極端。而HashMap就比較牛逼了,他是由數(shù)組+鏈表結(jié)構(gòu)實(shí)現(xiàn)的。順序存儲(chǔ)就是按照順序去分配內(nèi)存空間,鏈?zhǔn)酱鎯?chǔ)在內(nèi)存中離散存放。每一個(gè)元素對(duì)象都存儲(chǔ)著下一個(gè)元素對(duì)象的內(nèi)存地址。部分源碼如下所示
static class Node<K,V> implements Map.Entry<K,V> {
final int hash; // hash值,不可變
final K key; //key-value
V value; //key-value
Node<K,V> next; //下一個(gè)節(jié)點(diǎn)
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
2、HashMap和ConcurrentHashMap的區(qū)別
其實(shí)這個(gè)第一個(gè)問(wèn)題是連著問(wèn)的,我們知道HashMap是線程不安全的,并發(fā)環(huán)境下進(jìn)行put、get操作時(shí)會(huì)導(dǎo)致cpu利用率接近100%。那HashTable是線程安全的是否適用于并發(fā)和環(huán)境呢?HashTable的get/put操作都是synchronize的。那就意味著多個(gè)線程訪問(wèn)的時(shí)候,只能有一個(gè)線程去操作對(duì)象,其他線程只能阻塞。這樣就會(huì)導(dǎo)致性能很差。
這個(gè)時(shí)候就引入了ConcurrentHashMap分段鎖的概念。它會(huì)對(duì)數(shù)據(jù)進(jìn)行分段加鎖,每一段數(shù)據(jù)一個(gè)鎖,多線程訪問(wèn)對(duì)象中的不同段數(shù)據(jù)就不會(huì)發(fā)生競(jìng)爭(zhēng)鎖導(dǎo)致的阻塞現(xiàn)象了。

3、Mysql索引的數(shù)據(jù)結(jié)構(gòu)是什么?
Mysql的索引的數(shù)據(jù)結(jié)構(gòu)是樹,常用的InnoDB引擎采用的數(shù)據(jù)結(jié)構(gòu)是B+Tree
4、Mysql中插入一條數(shù)據(jù)底層做了什么?
存儲(chǔ)引擎把事務(wù)寫進(jìn)日志緩沖(log buffer),再有日志緩沖把事務(wù)刷新到事務(wù)日志中。然后引擎再把事務(wù)寫進(jìn)緩沖池(Buffer pool)。以上步驟執(zhí)行完畢整個(gè)事務(wù)就算提交完畢了。
5、MQ
MQ是一種跨系統(tǒng)傳遞數(shù)據(jù)的服務(wù),過(guò)程為異步操作。操作過(guò)程為生產(chǎn)者創(chuàng)建消息,然后再發(fā)布到代理服務(wù)器。消息包含兩部分:有效載荷(payload)和標(biāo)簽(label)。有效載荷就是你要傳輸?shù)臄?shù)據(jù),可以使任意類型,一般都是json。而標(biāo)簽則是決定誰(shuí)將獲取到這份消息。MQ會(huì)根據(jù)標(biāo)簽將消息發(fā)送給相對(duì)應(yīng)的接收方。這種通信方式是‘發(fā)后既忘’的單項(xiàng)模式,不需要知道接收者是誰(shuí)。比如在線交易系統(tǒng)為了保證數(shù)據(jù)最終一致性,在支付系統(tǒng)處理完成后會(huì)把字符的結(jié)果放到MQ中,通過(guò)訂單系統(tǒng)修改支付狀態(tài)。
MQ有兩種模式:
- 點(diǎn)對(duì)點(diǎn)模式。顧名思義每個(gè)人消息只能有一個(gè)消費(fèi)者,此過(guò)程需要接收者確認(rèn)消息接收和處理成功。
- 發(fā)布-訂閱模式
一條消息可能會(huì)有多個(gè)消費(fèi)者,消費(fèi)者需要和生產(chǎn)者之間建立一個(gè)訂閱關(guān)系。消費(fèi)者必須保持持續(xù)的運(yùn)行狀態(tài)去接受消息。除非消費(fèi)者建立了持久的訂閱
應(yīng)用程序和MQ連接成功后,會(huì)創(chuàng)建一條TCP連接,一旦TCP連接打開,通過(guò)了認(rèn)證。應(yīng)用程序就可以創(chuàng)建一條AMQP信道。信道是建立在TCP連接中的虛擬連接。每條信道都會(huì)有一個(gè)唯一ID,不管是消費(fèi)消息還是生產(chǎn)消息都是通過(guò)信道完成的。
為什么不直接通過(guò)TCP連接發(fā)送命令呢?對(duì)于操作系統(tǒng)來(lái)說(shuō)建立和消費(fèi)TCP的開銷是非常大的。高峰時(shí)期飛秒成千上萬(wàn)條MQ信息,不僅造成了連接巨大的浪費(fèi),而且操作系統(tǒng)一定時(shí)間內(nèi)創(chuàng)建的tcp連接又是有限的。其實(shí)我們可以把整個(gè)過(guò)程想象成一個(gè)一束光纖電纜就可以了。

6、SpringBoot
SpringBoot常用的starter有哪些?
spring-boot-starter:核心啟動(dòng)器
sprint-boot-starter-web:使用Spring MVC構(gòu)建Web(包括RESTful)應(yīng)用程序的入門者。使用Tomcat作為默認(rèn)嵌入式容器
spring-boot-starter-data-jpa****:數(shù)據(jù)庫(kù)支持
spring-boot-starter-data-elasticsearch:springboot支持elasticsearch
mybatis-spring-boot-starter:集成mybatis
spring-boot-starter-data-redis:redis的支持
spring-boot-starter-logging:日志模塊
SpringBoot有哪些常用注解:
@RestController:用于標(biāo)注控制層組件(如struts中的action),等同于@Controller + @ResponseBody。
@Configuration:指出該類是 Bean 配置的信息源,相當(dāng)于XML中的<beans></beans>,一般加在主類上。
@RequestMapping:RequestMapping是一個(gè)用來(lái)處理請(qǐng)求地址映射的注解,可用于類或方法上
@EnableAutoConfiguration:讓 Spring Boot 根據(jù)應(yīng)用所聲明的依賴來(lái)對(duì) Spring 框架進(jìn)行自動(dòng)配置,一般加在主類上。
@ComponentScan:組件掃描。個(gè)人理解相當(dāng)于<context:component-scan>,如果掃描到有@Component @Controller @Service等這些注解的類,則把這些類注冊(cè)為bean
等等就不一一舉例了
運(yùn)行SpringBoot的方式:
- 打包放到容器中啟動(dòng)
- Main方法啟動(dòng)
- Maven、Gradle插件啟動(dòng)
還有問(wèn)到了配置文件.properties和.yml的有些書寫格式、以及啟動(dòng)原理、加載順序等..
7、總結(jié)
面試過(guò)程中,面試官主要圍繞著簡(jiǎn)歷中項(xiàng)目經(jīng)驗(yàn)用到的技術(shù)去考察面試者。此次面試發(fā)現(xiàn)了很多不足,以后工作中對(duì)于常用的東西不光要知其然,更要知其所以然。對(duì)于有些比較基礎(chǔ)的東西,當(dāng)面試官問(wèn)到底層原理的時(shí)候,回答起來(lái)就不是很流暢。其次有的面試官還會(huì)問(wèn)某些場(chǎng)景某些問(wèn)題的解決方案。如果大家有面試了,可以提前在招聘網(wǎng)站看看這個(gè)公司的技術(shù)棧,提前做點(diǎn)準(zhǔn)備,有些基礎(chǔ)的東西往往是最容易忽略的點(diǎn)。
歡迎大家加入粉絲交流群:963944895,免費(fèi)分享Spring框架、Mybatis框架SpringBoot框架、SpringMVC框架、SpringCloud微服務(wù)、Dubbo框架、Redis緩存、RabbitMq消息、JVM調(diào)優(yōu)、Tomcat容器、MySQL數(shù)據(jù)庫(kù)教學(xué)視頻及架構(gòu)學(xué)習(xí)思維導(dǎo)圖
寫在最后:
既然看到這里了,覺得筆者寫的還不錯(cuò)的就點(diǎn)個(gè)贊,加個(gè)關(guān)注唄!點(diǎn)關(guān)注,不迷路,持續(xù)更新?。?!
如需Java架構(gòu)資料,點(diǎn)關(guān)注,發(fā)簡(jiǎn)信給我即可,先到先得!