一面參考這篇文章:螞蟻金服JAVA後端面試題及答案之一面css
二面html
2二、你有什麼問題想問個人嗎?前端
一、自我介紹、工做經歷、技術棧java
二、項目中你學到了什麼技術?react
三、微服務劃分的粒度?git
四、微服務的高可用怎麼保證的?web
負載均衡與反向代理,隔離,限流,降級,超時與重試,回滾,壓力測試與應急預案面試
五、經常使用的負載均衡,該怎麼用,你能說下嗎?算法
一、http重定向sql
當http代理(好比瀏覽器)向web服務器請求某個URL後,web服務器能夠經過http響應頭信息中的Location標記來返回一個新的URL。這意味着HTTP代理須要繼續請求這個新的URL,完成自動跳轉。
二、DNS負載均衡
DNS 負責提供域名解析服務,當訪問某個站點時,實際上首先須要經過該站點域名的DNS服務器來獲取域名指向的IP地址,在這一過程當中,DNS服務器完成了域名到IP地址的映射,一樣,這樣映射也能夠是一對多的,這時候,DNS服務器便充當了負載均衡調度器,它就像http重定向轉換策略同樣,將用戶的請求分散到多臺服務器上,可是它的實現機制徹底不一樣。
三、反向代理負載均衡
這個確定你們都有所接觸,由於幾乎全部主流的Web服務器都熱衷於支持基於反向代理的負載均衡。它的核心工做就是轉發HTTP請求。
相比前面的HTTP重定向和DNS解析,反向代理的調度器扮演的是用戶和實際服務器中間人的角色:
一、任何對於實際服務器的HTTP請求都必須通過調度器
二、調度器必須等待實際服務器的HTTP響應,並將它反饋給用戶(前兩種方式不須要通過調度反饋,是實際服務器直接發送給用戶)
四、IP負載均衡(LVS-NAT)
由於反向代理服務器工做在HTTP層,其自己的開銷就已經嚴重製約了可擴展性,從而也限制了它的性能極限。那可否在HTTP層面如下實現負載均衡呢?
NAT服務器:它工做在傳輸層,它能夠修改發送來的IP數據包,將數據包的目標地址修改成實際服務器地址
五、直接路由(LVS-DR)
NAT是工做在網絡分層模型的傳輸層(第四層),而直接路由是工做在數據鏈路層(第二層),貌似更6些。它經過修改數據包的目標MAC地址(沒有修改目標IP),將數據包轉發到實際服務器上,不一樣的是,實際服務器的響應數據包將直接發送給客戶羰,而不通過調度器
六、IP隧道(LVS-TUN)
基於IP隧道的請求轉發機制:將調度器收到的IP數據包封裝在一個新的IP數據包中,轉交給實際服務器,而後實際服務器的響應數據包能夠直接到達用戶端。目前Linux大多支持,能夠用LVS來實現,稱爲LVS-TUN,與LVS-DR不一樣的是,實際服務器能夠和調度器不在同一個WANt網段,調度器經過 IP隧道技術來轉發請求到實際服務器,因此實際服務器也必須擁有合法的IP地址。
整體來講,LVS-DR和LVS-TUN都適合響應和請求不對稱的Web服務器,如何從它們中作出選擇,取決於你的網絡部署須要,由於LVS-TUN能夠將實際服務器根據須要部署在不一樣的地域,而且根據就近訪問的原則來轉移請求,因此有相似這種需求的,就應該選擇LVS-TUN。
六、網關可以爲後端服務帶來哪些好處?
後端服務器能夠專心處理業務請求,節省了大量鏈接管理的開銷
七、Spring Bean 的生命週期
八、xml 中配置的 init、destroy 方法怎麼能夠作到調用具體的方法?
九、反射的機制
你們都知道,要讓Java程序可以運行,那麼就得讓Java類要被Java虛擬機加載。Java類若是不被Java虛擬機加載,是不能正常運行的。如今咱們運行的全部的程序都是在編譯期的時候就已經知道了你所須要的那個類的已經被加載了。
Java的反射機制是在編譯並不肯定是哪一個類被加載了,而是在程序運行的時候才加載、探知、自審。使用在編譯期並不知道的類。這樣的特色就是反射
反射機制經過void setAccessible(boolean flag)方法能夠獲得一個類的private的方法和屬性,使用這些private的方法和屬性
十、Object 類中的方法
1,構造函數
2,hashCode和equale函數用來判斷對象是否相同,
3,wait(),wait(long),wait(long,int),notify(),notifyAll()
4,toString()和getClass,
5,clone()
6,finalize()用於在垃圾回收
十一、hashcode 和 equals 方法經常使用地方
十二、對象比較是否相同
equals一般用來比較兩個對象的內容是否相等,==用來比較兩個對象的地址是否相等
1三、hashmap put 方法存放的時候怎麼判斷是不是重複的
先比較key的hashCode,再比較相等或equals的,因此重寫hashCode()和equals()方法便可實現添加劇復元素。
1四、Object toString 方法經常使用的地方,爲何要重寫該方法
經常使用在對象模型類
由於假如User是一個用戶的對象,若是User.toString();結果是不正常的,由於User對象中可能有多個屬性,如年齡,姓名等,這個toString後沒法知道具體的是那個屬性轉換爲字符串
1五、Set 和 List 區別?
Set(集):集合中的對象不按特定方式排序,而且沒有重複對象。它的有些實現類能對集合中的對象按特定方式排序。
List(列表):集合中的對象按索引位置排序,能夠有重複對象,容許按照對象在集合中的索引位置檢索對象。
1六、ArrayList 和 LinkedList 區別
ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構
ArrayList 繼承AbstractList
LinkedList 繼承AbstractSequentialList
ArrayList 採用的是數組形式來保存對象的,這種方式將對象放在連續的位置中,因此最大的缺點就是插入刪除時很是麻煩
LinkedList 採用的將對象存放在獨立的空間中,並且在每一個空間中還保存下一個連接的索引 可是缺點就是查找很是麻煩 要叢第一個索引開始
1七、若是存取相同的數據,ArrayList 和 LinkedList 誰佔用空間更大?
對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針
對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據,若要從數組中刪除或插入某一個對象,須要移動後段的數組元素,從而會從新調整索引順序,調整索引順序會消耗必定的時間,相反,LinkedList是使用鏈表實現的,若要從鏈表中刪除或插入某一個對象,只須要改變先後對象的引用便可
1八、Set 存的順序是有序的嗎?
無序
Set是Map的一個馬甲,主要邏輯都交給Map實現
1九、常見 Set 的實現有哪些?
HashSet
LinkedHashSet
TreeSet
20、TreeSet 對存入對數據有什麼要求呢?
TreeSet集合是用來對象元素進行排序的,一樣他也能夠保證元素的惟一
2一、HashSet 的底層實現呢?
2二、TreeSet 底層源碼有看過嗎?
TreeSet的底層實現是TreeMap
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
2三、HashSet 是否是線程安全的?爲何不是線程安全的?
說白了,HashSet就是限制了功能的HashMap,因此瞭解HashMap的實現原理
2四、Java 中有哪些線程安全的 Map?
Concurrenthashmap
2五、Concurrenthashmap 是怎麼作到線程安全的?
ConcurrentHashMap的大部分操做和HashMap是相同的,例如初始化,擴容和鏈表向紅黑樹的轉變等。可是,在ConcurrentHashMap中,大量使用了U.compareAndSwapXXX
的方法,這個方法是利用一個CAS算法實現無鎖化的修改值的操做,他能夠大大下降鎖代理的性能消耗。這個算法的基本思想就是不斷地去比較當前內存中的變量值與你指定的
一個變量值是否相等,若是相等,則接受你指定的修改的值,不然拒絕你的操做。由於當前線程中的值已經不是最新的值,你的修改極可能會覆蓋掉其餘線程修改的結果。這一
點與樂觀鎖,SVN的思想是比較相似的。
同時,在ConcurrentHashMap中還定義了三個原子操做,用於對指定位置的節點進行操做。這三種原子操做被普遍的使用在ConcurrentHashMap的get和put等方法中,
正是這些原子操做保證了ConcurrentHashMap的線程安全。
在ConcurrentHashMap沒有出現之前,jdk使用hashtable來實現線程安全,可是hashtable是將整個hash表鎖住,因此效率很低下。
ConcurrentHashMap將數據分別放到多個Segment中,默認16個,每個Segment中又包含了多個HashEntry列表數組,
對於一個key,須要通過三次hash操做,才能最終定位這個元素的位置,這三次hash分別爲:
對於一個key,先進行一次hash操做,獲得hash值h1,也即h1 = hash1(key);
將獲得的h1的高几位進行第二次hash,獲得hash值h2,也即h2 = hash2(h1高几位),經過h2可以肯定該元素的放在哪一個Segment;
將獲得的h1進行第三次hash,獲得hash值h3,也即h3 = hash3(h1),經過h3可以肯定該元素放置在哪一個HashEntry。
每個Segment都擁有一個鎖,當進行寫操做時,只須要鎖定一個Segment,而其它Segment中的數據是能夠訪問的。
2六、HashTable 你瞭解過嗎?
Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的註釋中有說明
Hashtable是線程安全的,
Hashtable是線程安全的,它的每一個方法中都加入了Synchronize方法,效率比較低
Hashtable默認的初始大小爲11,以後每次擴充,容量變爲原來的2n+1。
Hashtable在計算元素的位置時須要進行一次除法運算,而除法運算是比較耗時的。
2七、如何保證線程安全問題?
2八、synchronized、lock
synchronized是java中的一個關鍵字,也就是說是Java語言內置的特性
若是一個代碼塊被synchronized修飾了,當一個線程獲取了對應的鎖,並執行該代碼塊時,其餘線程便只能一直等待,等待獲取鎖的線程釋放鎖,而這裏獲取鎖的線程釋放鎖只會有兩種狀況:
1)獲取鎖的線程執行完了該代碼塊,而後線程釋放對鎖的佔有;
2)線程執行發生異常,此時JVM會讓線程自動釋放鎖
那麼若是這個獲取鎖的線程因爲要等待IO或者其餘緣由(好比調用sleep方法)被阻塞了,可是又沒有釋放鎖,其餘線程便只能乾巴巴地等待,試想一下,這多麼影響程序執行效率。
所以就須要有一種機制能夠不讓等待的線程一直無期限地等待下去(好比只等待必定的時間或者可以響應中斷),經過Lock就能夠辦到
再舉個例子:當有多個線程讀寫文件時,讀操做和寫操做會發生衝突現象,寫操做和寫操做會發生衝突現象,可是讀操做和讀操做不會發生衝突現象。
可是採用synchronized關鍵字來實現同步的話,就會致使一個問題:
若是多個線程都只是進行讀操做,因此當一個線程在進行讀操做時,其餘線程只能等待沒法進行讀操做。
所以就須要一種機制來使得多個線程都只是進行讀操做時,線程之間不會發生衝突,經過Lock就能夠辦到。
另外,經過Lock能夠知道線程有沒有成功獲取到鎖。這個是synchronized沒法辦到的
2九、volatile 的原子性問題?爲何 i++ 這種不支持原子性?從計算機原理的設計來說下不能保證原子性的緣由
30、happens before 原理
3一、cas 操做
java.util.concurrent包中藉助CAS實現了區別於synchronized同步鎖的一種樂觀鎖
cas是比較並交換算法
CAS有3個操做數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改成B,不然什麼都不作
JDK提供了AtomicReference類來保證引用對象之間的原子性,就能夠把多個變量放在一個對象裏來進行CAS操做。
3二、lock 和 synchronized 的區別?
1)Lock是一個接口,而synchronized是Java中的關鍵字,synchronized是內置的語言實現;
2)synchronized在發生異常時,會自動釋放線程佔有的鎖,所以不會致使死鎖現象發生;而Lock在發生異常時,若是沒有主動經過unLock()去釋放鎖,則極可能形成死鎖現象,所以使用Lock時須要在finally塊中釋放鎖;
3)Lock可讓等待鎖的線程響應中斷,而synchronized卻不行,使用synchronized時,等待的線程會一直等待下去,不可以響應中斷;
4)經過Lock能夠知道有沒有成功獲取鎖,而synchronized卻沒法辦到。
5)Lock能夠提升多個線程進行讀操做的效率。
在性能上來講,若是競爭資源不激烈,二者的性能是差很少的,而當競爭資源很是激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優於synchronized。因此說,在具體使用時要根據適當狀況選擇。
類別
synchronized
Lock
存在層次
Java的關鍵字,在jvm層面上
是一個類
鎖的釋放
一、以獲取鎖的線程執行完同步代碼,釋放鎖 二、線程執行發生異常,jvm會讓線程釋放鎖
在finally中必須釋放鎖,否則容易形成線程死鎖
鎖的獲取
假設A線程得到鎖,B線程等待。若是A線程阻塞,B線程會一直等待
分狀況而定,Lock有多個鎖獲取的方式,具體下面會說道,大體就是能夠嘗試得到鎖,線程能夠不用一直等待
鎖狀態
沒法判斷
能夠判斷
鎖類型
可重入 不可中斷 非公平
可重入 可判斷 可公平(二者皆可)
性能
少許同步
大量同步
3三、公平鎖和非公平鎖
公平和非公平鎖的隊列都基於鎖內部維護的一個雙向鏈表,表結點Node的值就是每個請求當前鎖的線程。公平鎖則在於每次都是依次從隊首取值
非公平鎖在等待鎖的過程當中, 若是有任意新的線程妄圖獲取鎖,都是有很大的概率直接獲取到鎖的
(在ReentrantLock中很明顯能夠看到其中同步包括兩種,分別是公平的FairSync和非公平的NonfairSync。公平鎖的做用就是嚴格按照線程啓動的順序來執行的,不容許其餘線程插隊執行的;而非公平鎖是容許插隊的。
默認狀況下ReentrantLock是經過非公平鎖來進行同步的,包括synchronized關鍵字都是如此,由於這樣性能會更好。由於從線程進入了RUNNABLE狀態,能夠執行開始,到實際線程執行是要比較久的時間的。並且,在一個鎖釋放以後,其餘的線程會須要從新來獲取鎖。其中經歷了持有鎖的線程釋放鎖,其餘線程從掛起恢復到RUNNABLE狀態,其餘線程請求鎖,得到鎖,線程執行,這一系列步驟。若是這個時候,存在一個線程直接請求鎖,可能就避開掛起到恢復RUNNABLE狀態的這段消耗,因此性能更優化)
3四、Java 讀寫鎖
3五、讀寫鎖設計主要解決什麼問題?
多線程,
讀操做能夠共享,寫操做是排他的,讀能夠有多個在讀,寫只有惟一個在寫,同時寫的時候不容許讀
解決了讀和讀能夠同時進行,讀和寫不能同時進行,寫和寫不能同時進行
3六、你項目除了寫 Java 代碼,還有前端代碼,那你知道前端有哪些框架嗎?
Vue layer react element
3七、MySQL 分頁查詢語句
LIMIT [offset,] rows
offset指定要返回的第一行的偏移量,rows第二個指定返回行的最大數目
3八、MySQL 事務特性和隔離級別
1、事務的基本要素(ACID)
一、原子性(Atomicity):事務開始後全部操做,要麼所有作完,要麼所有不作,不可能停滯在中間環節。事務執行過程當中出錯,會回滾到事務開始前的狀態,全部的操做就像沒有發生同樣。也就是說事務是一個不可分割的總體,就像化學中學過的原子,是物質構成的基本單位。
二、一致性(Consistency):事務開始前和結束後,數據庫的完整性約束沒有被破壞 。好比A向B轉帳,不可能A扣了錢,B卻沒收到。
三、隔離性(Isolation):同一時間,只容許一個事務請求同一數據,不一樣的事務之間彼此沒有任何干擾。好比A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉帳。
四、持久性(Durability):事務完成後,事務對數據庫的全部更新將被保存到數據庫,不能回滾。
2、事務的併發問題
一、髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據
二、不可重複讀:事務 A 屢次讀取同一數據,事務 B 在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果 不一致。
三、幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。
MySQL事務隔離級別
事務隔離級別
髒讀
不可重複讀
幻讀
讀未提交(read-uncommitted)
是
是
是
不可重複讀(read-committed)
否
是
是
可重複讀(repeatable-read)
否
否
是
串行化(serializable)
否
否
否
3九、不可重複讀會出如今什麼場景?
40、sql having 的使用場景
若是須要對組函數的結果做爲條件,那麼不能使用where子句,必須使用having子句
4一、前端瀏覽器地址的一個 http 請求到後端整個流程是怎麼樣?
可以說下嗎?
域名解析 --> 發起TCP的3次握手 --> 創建TCP鏈接後發起http請求 -->服務器響應http請求,瀏覽器獲得html代碼 -->瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給用戶
4二、http 默認端口,https 默認端口
HTTP協議代理服務器經常使用端口號:80/8080/3128/8081/9080
HTTPS服務器,默認的端口號爲443/tcp 443/udp
4三、DNS 你知道是幹嗎的嗎?
DNS是指:域名服務器(Domain Name Server)。在Internet上域名與IP地址之間是一一對應的,域名雖然便於人們記憶,但機器之間只能互相認識IP地址,它們之間的轉換工做稱爲域名解析,域名解析須要由專門的域名解析服務器來完成,DNS就是進行域名解析的服務器
4四、大家開發用的 ide 是啥?你能說下 idea 的經常使用幾個快捷鍵吧?
4五、代碼版本管理大家用的是啥?
4六、git rebase 和 merge 有什麼區別?
4七、大家公司加班多嗎?
一面參考這篇文章:螞蟻金服JAVA後端面試題及答案之一面
歡迎工做一到五年的Java工程師朋友們加入Java高級架構:867581223
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!