整理面試

來源於:https://mp.weixin.qq.com/s/UXjDP1xmkhBTaTObe8aH2Qhtml

1.java事件機制包括哪三個部分?分別介紹。
事件、事件監聽器、事件源java

二、爲何要使用線程池?
    首先,服務器建立和銷燬工做線程的開銷很大,若是服務器與不少客戶端通訊,而且與每一個客戶端通訊的時間很短,那麼就會在建立和銷燬線程的時候形成很大的開銷。(小而多,且頻繁的任務)mysql

        其次,活動的線程也消耗系統資源,若是線程的建立數量沒有限制,當大量的客戶鏈接服務器的時候,就會建立出大量的工做線程,他們會消耗大量的內存空間,致使系統的內存空間不足,影響服務器的使用。(不加以控制耗盡內存資源)react

        最後,若是線程的數目固定,而且每一個線程都有很長的生命週期,那麼線程切換也就是固定的,這樣就會給服務器減輕不少壓力,可是若是頻繁的建立和銷燬線程,必將致使頻繁的切換線程,使得線程之間的切換再也不遵循系統的固定切換週期,線程切換的開銷也會增大不少(維護一組固定的線程能減輕服務器壓力)nginx

三、線程池有什麼做用?
a. 重用存在的線程,減小對象建立、消亡的開銷,性能佳。
b. 可有效控制最大併發線程數,提升系統資源的使用率,同時避免過多資源競爭,避免堵塞。
c. 提供定時執行、按期執行、單線程、併發數控制等功能。c++

四、說說Java中幾種常見的線程池及使用場景。
newCachedThreadPool(彈性緩存線程池) 底層:返回ThreadPoolExecutor實例
通俗:當有新任務到來,則插入到SynchronousQueue中,因爲SynchronousQueue是同步隊列,所以會在池中尋找可用線程來執行,如有能夠線程則執行,若沒有可用線程則建立一個線程來執行該任務;若池中線程空閒時間超過指定大小,則該線程會被銷燬
適用:執行不少短時間異步的小程序或者負載較輕的服務器程序員

newFixedThreadPool 底層:返回ThreadPoolExecutor實例
通俗:建立可容納固定數量線程的池子,每隔線程的存活時間是無限的,當池子滿了就不在添加線程了;若是池中的全部線程均在繁忙狀態,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
適用:執行長期的任務,性能好不少web

newSingleThreadExecutor(單線程線程池) 底層:FinalizableDelegatedExecutorService包裝的ThreadPoolExecutor實例
通俗:建立只有一個線程的線程池,且線程的存活時間是無限的;當該線程正繁忙時,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
適用:一個任務一個任務執行的場景面試


NewScheduledThreadPool(定時器線程池): 底層:建立ScheduledThreadPoolExecutor實
通俗:建立一個固定大小的線程池,線程池內線程存活時間無限制,線程池能夠支持定時及週期性任務執行,若是全部線程均處於繁忙狀態,對於新任務會進入DelayedWorkQueue隊列中,這是一種按照超時時間排序的隊列結構
適用:週期性執行任務的場景(輪巡)redis

備註
通常若是線程池任務隊列採用LinkedBlockingQueue(無界)隊列的話,那麼不會拒絕任何任務(由於隊列大小沒有限制),這種狀況下,ThreadPoolExecutor最多僅會按照最小線程數來建立線程,也就是說線程池大小被忽略了。

若是線程池任務隊列採用ArrayBlockingQueue隊列的話,那麼ThreadPoolExecutor將會採起一個很是負責的算法,好比假定線程池的最小線程數爲4,最大爲8所用的ArrayBlockingQueue最大爲10。隨着任務到達並被放到隊列中,線程池中最多運行4個線程(即最小線程數)。即便隊列徹底填滿,也就是說有10個處於等待狀態的任務,ThreadPoolExecutor也只會利用4個線程。若是隊列已滿,而又有新任務進來,此時纔會啓動一個新線程,這裏不會由於隊列已滿而拒接該任務,相反會啓動一個新線程。新線程會運行隊列中的第一個任務,爲新來的任務騰出空間

spring 中的線程池
Spring中的ThreadPoolTaskExecutor是藉助於JDK併發包中的java.util.concurrent.ThreadPoolExecutor來實現的.

spring線程池與JDK線程池區別
spring線程池是經過JDK的線程池ThreadPoolExecutor的實現。可是具備以下兩個優勢

(1)不須要本身設置阻塞隊列

只須要設置阻塞隊列大小,不須要指定那種阻塞隊列。
(2)自動關閉線程池

經過實現DisposableBean的destroy方法

五、線程池都有哪幾種工做隊列?
無界隊列
隊列大小無限制,經常使用的爲無界的LinkedBlockingQueue,使用該隊列作爲阻塞隊列時要尤爲小心,當任務耗時較長時可能會致使大量新任務在隊列中堆積最終致使OOM

有界隊列
類是遵循FIFO原則的隊列如ArrayBlockingQueue,另外一類是優先級隊列如PriorityBlockingQueue。PriorityBlockingQueue中的優先級由任務的Comparator決定。

六、怎麼理解無界隊列和有界隊列?
有界隊列也滿,線程池執行了拒絕操做。
無界隊列
無界隊列會保持快速增加,直到耗盡系統內存。

七、線程池中的幾種重要的參數及流程說明。
corePollSize:核心線程數。 當線程池中的線程數目達到corePoolSize後,就會把到達的任務放到緩存隊列當中。
maximumPoolSize:最大線程數。代表線程中最多可以建立的線程數量
keepAliveTime:空閒的線程保留的時間。
BlockingQueue<Runnable>:阻塞隊列,存儲等待執行的任務。參數有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可選
ThreadFactory:線程工廠,用來建立線程
RejectedExecutionHandler:隊列已滿,並且任務量大於最大線程的異常處理策略。有如下取值

八、什麼是反射機制?
 * 1.在運行時判斷任意一個對象所屬的類。

 * 2.在運行時構造任意一個類的對象。

 * 3.在運行時判斷任意一個類所具備的成員變量和方法。

 * 4.在運行時調用任意一個對象的方法。
這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。

九、說說反射機制的做用。
一、反射最重要的用途就是開發各類通用框架。
一、得到Class對象 使用Class類的forName靜態方法 調用某個對象的getClass()方法
二、判斷是否爲某個類的實例 用instanceof關鍵字來判斷是否爲某個類的實例
三、建立實例 使用Class對象的newInstance()方法來建立Class對象對應類的實例。
四、獲取方法 getDeclaredMethods()
五、獲取構造器信息
六、獲取類的成員變量(字段)信息
getFiled: 訪問公有的成員變量
getDeclaredField:全部已聲明的成員變量。但不能獲得其父類的成員變量
getFileds和getDeclaredFields用法
七、調用方法 invoke()
注意: 因爲反射會額外消耗必定的系統資源 反射調用方法時能夠忽略權限檢查,所以可能會破壞封裝性而致使安全問題。

一、你怎麼理解http協議?
HTTP是Hyper Text Transfer Protocol(超文本傳輸協議) 默認端口號是80
協議中規定了客戶端應該按照什麼格式給服務器發送請求,同時也約定了服務端返回的響應結果應該是什麼格
同時 HTTP 是一種無狀態的協議,協議自己不記錄客戶端的歷史請求記錄。
參照:https://www.jianshu.com/p/b5993a20292a 講解比較詳細

十二、說說http協議的工做流程。
(1)瀏覽器分析連接所指向頁面的URL。

(2)瀏覽器向DNS服務器請求解析URL的IP地址。

(3)域名系統DNS解析出URL對應的IP地址。

(4)瀏覽器與服務器創建TCP鏈接(默認端口號80)。

(5)瀏覽器發出HTTP的GET請求報文。

(6)服務器經過HTTP響應報文把相應的文件發送給瀏覽器。

1三、http有哪些請求提交方式?
POST、GET、HEAD、PUT 等

1四、http中的200,302,403,404,500,503都表明什麼狀態?
 200 - 服務器成功返回網頁 404 - 請求的網頁不存在 503 - 服務器超時

1五、http get和post有什麼區別?
最直觀的區別就是GET把參數包含在URL中,POST經過request body傳遞參數。 ... GET請求在URL中傳送的參數是有長度限制的,而POST麼有。 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。 GET比POST更不安全,由於參數直接暴露在URL上,因此不能用來傳遞敏感信息

1六、你怎麼理解cookie和session,有哪些不一樣點?
cookie的內容主要包括:名字,值,過時時間,路徑和域。路徑與域一塊兒構成cookie的做用範圍 若不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失

當程序須要爲某個客戶端的請求建立一個session時,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識
(稱爲session id),若是已包含則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來
使用(檢索不到,會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相
關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應
中返回給客戶端保存。

cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。 cookie不是很安全 session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能


1八、什麼是https,說說https的工做原理?
HTTPS全稱爲Hypertext Transfer Protocol over Secure Socket Layer,及以安全爲目標的HTTP通道,簡單說就是HTTP的安全版本,HTTPS的安全基礎就是TLS/SSL
原理:客戶端和服務端的交互 先經過非對稱加密進行認證,在通過對稱加密進行交互

1九、什麼是http代理服務器,有什麼用?
代理服務器大多被用來鏈接INTERNET(國際互聯網)和Local Area Network(局域網)。

2二、說說Java虛擬機的生命週期及體系結構。
當啓動一個Java程序時,一個虛擬機實例就誕生了,當程序關閉退出時,這個虛擬機實例隨之消亡。JVM實例經過main()方法來運行一個Java程序。
JVM內部有兩種線程:守護線程與非守護線程。守護線程一般是由虛擬機本身使用的,好比垃圾回收線程。當該程序全部的非守護線程都終止時,JVM實例將自動退出

2五、分佈式系統你會考慮哪些方面?
1. 服務接口的設計相當重要
2. 後臺升級要作到對用戶透明
3. 應用方設計時候須要衡量後臺服務失敗的影響

3九、爲何不把基本類型放堆中呢?
一:在方法中聲明的變量,即該變量是局部變量,每當程序調用方法時,系統都會爲該方法創建一個方法棧,其所在方法中聲明的變量就放在方法棧中,當方法結束系統會釋放方法棧,其對應在該方法中聲明的變量隨着棧的銷燬而結束
二:在類中聲明的變量是成員變量,也叫全局變量,放在堆中的(由於全局變量不會隨着某個方法執行結束而銷燬)放在堆中

4一、Java中有沒有指針的概念?
java中沒有指針。 java中有引用(reference)c/c++中有指針

4二、Java中,棧的大小經過什麼參數來設置?
JVM參數-堆分配參數總結
-Xms:設置最小堆值
-Xmx:設置最大堆值
-Xmn:設置年輕代值(設置它等於最小值和最大值相同)
-XX:NewSize:設置年輕代最小值
-XX:MaxNewSize:設置年輕代最大值
-Xss:設置線程棧值大小
-XX:PermSize:設置永久代最小值
-XX:MaxPermSize:設置永久代最大值
-XX:SuriviorRatio:設置年輕代中Eden與s0的比例
-XX:NewRatio:設置老年代與年輕代的比例。
-XX:MinHeapFreeRatio:設置堆空間最小空閒比例。當堆空間的空閒比例小於這個數值時,JVM變主動申請內存空間。
-XX:MaxHeapFreeRation:設置堆空間最大空閒比例。當堆空間的空閒比例大於這個數值時,JVM會壓縮堆空間,獲得一個較小的堆空間。
-XX:TargetSuriviorRatio:設置surivior空間使用率,當surivior空間使用率達到這個數值時,會將對應的對象送入老年代。
參見:https://blog.csdn.net/junchenbb0430/article/details/78407085 參數分配的影響

4五、講一講垃圾回收算法。
標記-清除法(Mark-Sweep) (被標記的是有引用的)
標記-清除算法是現代垃圾回收算法的思想基礎,後面提到的全部算法都是基於該算法的思想。從名字就能看出,該算法分兩個階段進行——「標記」和「清除」。首先經過根對象標記全部可達的對象,而後清除全部未被標記的不可達對象。該算法有一個比較大的缺點,就是容易產生內存碎片。過多的內存碎片對於大對象的內存分配,效率很是低(碎片最直接的問題就是會致使沒法分配大塊的內存空間)
什麼是可達?(理解爲 能找到引用)

複製算法(Copying)
複製算法基於標記-清除算法並對其產生過多內存碎片的缺點進行了優化。複製算法將內存空間分紅兩等份(以下圖的A和B),每次只使用其中的一塊,當垃圾回收的時候,將A中的可達對象複製到B中,而後清空A中的全部對象。這樣就避免了產生內存碎片的狀況,但這種算法的缺點也是顯而易見的,那就是太浪費空間。

標記整理算法
光從名字上就能看出,該算法繼承自標記-清除算法。該算法在標記和清除之間又加了一個操做——壓縮。首先將標記全部可達對象,而後將全部可達對象壓縮(或者叫移動)到內存的一端,最後將邊界之外的空間所有清空。這樣既避免了產生內存碎片,又不須要空出一塊內存空間,一箭雙鵰。

JVM中採用的並非某一種回收算法,而是多種算法組合使用,由於任何一種算法都不是完美的,都有自身的優缺點,有本身適用的場景。須要把他們放到合適的地方,這樣才能各盡其能,達到一個最好的效果

4八、講一講內存分代及生命週期。
爲何要分代?
若是說堆內存沒有區域劃分,全部新建立的對象和生命週期很長的對象放在一個區域,隨着對象愈來愈多觸發了JVM的垃圾回收機制,而每次回收都要遍歷全部的對象,這個時間成本是不可思議的,嚴重影響GC效率。

新生代
新生代中的對象存活時間短,只須要在新生代區域中頻繁進行GC,所有的新生對象都會在新生代
老年代
老年代也稱Old區。老年代的對象是由新生代中存活屢次,或者是特殊緣由(緣由有多種,後續介紹)重新生代直接轉移來的
永久代
永久代也稱Permanent區或方法區。存儲類信息、常量、靜態變量以及即時編譯器編譯後的代碼等等數據
針對HotSpot VM的實現
Minor GC:新生代GC(Minor GC):指發生在新生代的垃圾收集動做
Full GC:收集整個堆,包括young gen、old gen、perm gen
Young GC:只收集young gen的GC Old GC:只收集old gen的GC。

4九、什麼狀況下觸發垃圾回收?
1. 執行 system.gc()的時候 (其實並不會立刻進行垃圾回收,甚至不必定會執行垃圾回收)
2.老年代空間不足 永久代空間不足 new 一個大對象,新生代放不下,直接到老年代,空間不夠,觸發FullGC

怎麼避免頻繁GC
1. 不要頻繁的new 對象 2. 不要顯示的調研system.gc() 3. 不要用String+ 使用StringBuilder 4.不要使用Long Integer 儘可能使用基本類型
5.少用靜態變量 不會回收 6.能夠使用null 進行回收

若是說收集算法是內存回收的方法論,那麼垃圾收集器就是內存回收的具體實現

5五、如何進行JVM調優?有哪些方法?
JVM參數: GC的時間足夠的小 GC的次數足夠的少 發生Full GC的週期足夠的長

5六、如何理解內存泄漏問題?有哪些狀況會致使內存泄露?如何解決?
沒法被釋放的內存,累加的夠多就會內存溢出
在For循環中,咱們不斷的生成新的對象,而後將其添加到Vector對象中,以後將o引用置空。問題是當o引用被置空後,若是發生GC,咱們建立的Object對象是否可以被GC回收呢?答案是否認的。由於,GC在跟蹤代碼棧中的引用時,會發現v引用,而繼續往下跟蹤,就會發現v引用指向的內存空間中又存在指向Object對象的引用。也就是說盡管o引用已經被置空,可是Object對象仍然存在其餘的引用,是能夠被訪問到的,因此GC沒法將其釋放掉。若是在此循環以後,Object對象對程序已經沒有任何做用,那麼咱們就認爲此Java程序發生了內存泄漏

5九、爲了解決數據庫服務器的負擔,如何作數據庫的分佈?
mycat,和 Sharding

6二、講講CAP理念。
CAP原則是NOSQL數據庫的基石
分佈式系統的CAP理論:理論首先把分佈式系統中的三個特性進行了以下概括:
一致性(C):在分佈式系統中的全部數據備份,在同一時刻是否一樣的值。(等同於全部節點訪問同一份最新的數據副本)
可用性(A):在集羣中一部分節點故障後,集羣總體是否還能響應客戶端的讀寫請求。(對數據更新具有高可用性)
分區容忍性(P):以實際效果而言,分區至關於對通訊的時限要求。系統若是不能在時限內達成數據一致性,就意味着發生了分區的狀況,必須就當前操做在C和A之間作出選擇。
在分佈式系統的設計中,沒有一種設計能夠同時知足一致性,可用性,分區容錯性 3個特性
對於分佈式數據系統,分區容忍性是基本要求,不然就失去了價值

C - Consistent ,一致性A - Availability ,可用性P - Partition tolerance ,分區容錯性分佈式系統之因此叫分佈式,是由於提供服務的各個節點分佈在不一樣機器上,相互之間經過網絡交互。那麼必然存在網絡故障斷開的風險,這個網絡斷開的專業場景成爲網絡分區。

在網絡分區發生時,兩個分佈式節點之間沒法進行通訊,那麼咱們對一個節點進行的修改操做將沒法同步到另一個節點,因此數據的「一致性」將沒法知足,由於兩個分佈式節點的數據再也不保持一致。除非咱們犧牲「可用性」,也就是暫停分佈式節點服務,在網絡分區發生時,再也不提供修改數據的功能,直到網絡情況徹底恢復正常再繼續對外提供服務。或者爲了保證可用性,而犧牲數據一致性。

因此,CAP一句話就是,在網絡分區時,不能同時保證可用性和一致性。

 爲了保證分佈式中間件的可用性,大部分中間件會支持最終一致性

分佈式鎖是cp模型,redis 是ap模型

參照:https://www.cnblogs.com/duanxz/p/5229352.html 講解cap

6三、怎麼理解強一致性、單調一致性和最終一致性?
從客戶端角度,多進程併發訪問時,更新過的數據在不一樣進程如何獲取的不一樣策略,決定了不一樣的一致性。對於關係型數據庫,要求更新過的數據能被後續的訪問都能看到,這是強一致性。若是能容忍後續的部分或者所有訪問不到,則是弱一致性。若是通過一段時間後要求能訪問到更新後的數據,則是最終一致性。

6六、談一談一致性哈希算法。
是爲了解決服務器的變更形成hash結果不一致的問題,不管增長機器最終hash要一致,結果不受影響
參照:https://zhuanlan.zhihu.com/p/34985026

70、OSI有哪七層模型?TCP/IP是哪四層模型。
應用層:應用程序間溝通的層,如簡單電子郵件傳輸(SMTP)、文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等。
傳輸層:在此層中,它提供了節點間的數據傳送服務,如傳輸控制協議(TCP)、用戶數據報協議(UDP)等,TCP和UDP給數據包加入傳輸數據並把它傳輸到下一層中,這一層負責傳送數據,而且肯定數據已被送達並接收。
互連網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都可以到達目的主機(但不檢查是否被正確接收),如網際協議(IP)。
網絡接口層:對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、Serial Line等)來傳送數據。

osi七層結構:
應用層
表示層
會話層
傳輸層
網絡層
數據鏈路層
物理層

equals 和hashcode 若是hashcode不一樣 則不進行equals比較 重寫hashcode equals必需要重寫
== 比較地址 equals比較內容
Strin的equals重寫 原理(先進行地址比較,地址不相等就進行值(內容)的比較,值相等equals的2個對象就相等,地址相等2個對象就相等 )

四、&和&&的區別
$:只要有一個值爲0結果爲0,不然結果爲1。 $$ :都爲真纔是真

五、Collection 和 Collections的區別
一、java.util.Collection 是一個集合接口
二、java.util.Collections 是一個包裝類。它包含有各類有關集合操做的靜態多態方法。此類不能實例化,就像一個工具類,服務於Java的Collection框架。

七、String s = new String("xyz");建立了幾個String Object
答案:兩個,一個是字符串字面量"xyz"所對應的、駐留(intern)在一個全局共享的字符串常量池中的實例,另外一個是經過new String(String)建立並初始化的、內容與"xyz"相同的實例

九、short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯
// s1 = s1+1;//報錯,由於s1+1結果是int類型,等號左邊是short類型,因此要強轉

十、Java有沒有goto 沒有

Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==仍是equals()? 它們有何區別?
用equals()而不用==來區分 set裏面存放的是對象的引用,因此當兩個元素只要知足了equals()時就已經指向同一個對象,

1六、List, Set, Map是否繼承自Collection接口
答:List,Set是,Map不是。 map是本身的一個接口

20、構造器Constructor是否可被override
構造器Constructor不能被繼承,所以不能重寫Overriding,但能夠被重載Overloading。

2四、兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對
1) 對象相等則hashCode必定相等; 2) hashCode相等對象未必相等

String st1 = new String(「abc」);
答案是:在內存中建立兩個對象,一個在堆內存,一個在常量池
例子
String st1 = new String("abc");
String st2 = "abc";
System.out.println(st1 == st2);
System.out.println(st1.equals(st2));
答案:false 和 true
因爲有前面兩道提內存分析的經驗和理論,因此,我能快速得出上面的答案。==比較的st1和st2對象的內存地址,因爲st1指向的是堆內存的地址,st2看到「abc」已經在常量池存在,就不會再新建,因此st2指向了常量池的內存地址,因此==判斷結果輸出false,二者不相等。第二個equals比較,比較是兩個字符串序列是否相等,因爲就一個「abc」,因此徹底相等。

30、float型float f=3.4是否正確?
答案:不正確。
緣由:精度不許確,應該用強制類型轉換,以下所示:float f=(float)3.4 或float f = 3.4f
在java裏面,沒小數點的默認是int,有小數點的默認是 double;

3四、談談final, finally, finalize的區別
final 能夠修飾類、方法、變量。 finally 一般是用來保證代碼必定被執行的 finalize 是java.lang.Object的一個方法, 是用來保證對象在被垃圾回收以前完成特定資源的回收,如今finalize已經不被建議使用,

3八、運行時異常與通常異常有何異同
error:通常是指java虛擬機相關的問題,如系統崩潰、虛擬機出錯誤、動態連接失敗等,這種錯誤沒法恢復或不可能捕獲,將致使應用程序中

運行時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等,這些異常是不檢查異常,程序中能夠選擇捕獲處理,也能夠不處理。

4六、描述一下JVM加載class文件的原理機制?
JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現的
當Java程序須要使用某個類時,JVM會確保這個類已經被加載、鏈接(驗證、準備和解析)和初始化。類的加載是指把類的.class文件中的數據讀入到內存中,一般是建立一個字節數組讀入.class文件,而後產生與所加載類對應的Class對象
從Java 2(JDK 1.2)開始,類加載過程採起了父親委託機制

4七、排序都有哪幾種方法?請列舉

1、冒泡排序
十種排序算法總結(冒泡、插入、選擇、希爾、歸併、堆、快速,計數,桶,基數)
基本思想是:兩兩比較相鄰記錄的關鍵字,若是反序則交換 冒泡排序時間複雜度最好的狀況爲O(n),最壞的狀況是O(n^2)
7、快速排序
經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。時間複雜度爲O(nlogn)

4八、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別表明什麼意義?在try塊中能夠拋出異常嗎?
throws 用在方法上 throw 用在

垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收

對於GC來講,當程序員建立對象時,GC就開始監控這個對象的地址、大小以及使用狀況。一般,GC採用有向圖的方式記錄和管理堆(heap)中的全部對象。經過這種方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC肯定一些對象爲"不可達"時,GC就有責任回收這些內存空間。能夠。程序員能夠手動執行System.gc(),通知GC運行,可是Java語言規範並不保證GC必定會執行。

5四、靜態變量和實例變量的區別?
在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。
在程序運行時的區別:實例變量屬於某個對象的屬性,必須建立了實例對象,其中的實例變量纔會被分配空間,才能使用這個實例變量

5五、什麼是java序列化,如何實現java序列化?
序列化:把對象轉換爲字節序列的過程稱爲對象的序列化。 反序列化:把字節序列恢復爲對象的過程稱爲對象的反序列化。
有些信息咱們想讓他持久的保存起來,那麼這個就叫序列化。
就是把內存裏面的這些對象給變成一連串的字節(bytes)描述的過程。

60、說出一些經常使用的類,包,接口,請各舉5個
經常使用的接口 List set Map
經常使用的類: String Integer HashMap java.util.Date, stringbuffer
經常使用的包: java.io(inputstream) java.sql(date) java.lang(object) java.util (list)

多線程
四、Runnable接口和Callable接口的區別
Callable接口的call()方法能夠有返回值(經過Future接口的get()方法,不過此方法是阻塞性的),而Runnable接口的run()方法沒有返回值
Callable接口的call()方法能夠聲明拋出異常,而Runnable接口的run()方法不能夠聲明拋出異常


建立線程的2種方式,一種是直接繼承Thread,另一種就是實現Runnable接口。

  這2種方式都有一個缺陷就是:在執行完任務以後沒法獲取執行結果。

  若是須要獲取執行結果,就必須經過共享變量或者使用線程通訊的方式來達到效果,這樣使用起來就比較麻煩。

  而自從Java 1.5開始,就提供了Callable和Future,經過它們能夠在任務執行完畢以後獲得任務執行結果
九、一個線程若是出現了運行時異常會怎麼樣
若是異常沒有被捕獲該線程將會中止執行


1三、ThreadLocal有什麼用
而ThreadLocal則用於線程間的數據隔離 經過ThreadLocal的set()方法設置到線程的ThreadLocal.ThreadLocalMap裏的是是線程本身要存儲的對象,其餘線程不須要去訪問,也是訪問不到的

1七、怎麼檢測一個線程是否持有對象監視器
在java.lang.Thread中有一個方法叫holdsLock(),它返回true若是當且僅當當前線程擁有某個具體對象的鎖。

20、ReadWriteLock是什麼
讀寫鎖分爲讀鎖和寫
寫鎖和寫鎖之間須要互斥,也就是說,若是隻是讀數據,就能夠多個線程同時讀,可是若是你要寫數據,就必須互斥,使得同一時刻只有一個線程在操做。
2一、FutureTask是什麼
FutureTask可用於異步獲取執行結果或取消執行任務的場景。經過傳入Runnable或者Callable的任務給FutureTask,直接調用其run方法或者放入線程池執行,以後能夠在外部經過FutureTask的get方法異步獲取執行結果,所以,FutureTask很是適合用於耗時的計算,主線程能夠在完成本身的任務後,再去獲取結果。另外,FutureTask還能夠確保即便調用了屢次run方法,它都只會執行一次Runnable或者Callable任務,或者經過cancel取消FutureTask的執行等。

2五、不可變對象對多線程有什麼幫助
建立後狀態不能被修改的對象叫做不可變對象。不可變對象天生就是線程安全的。

2七、若是你提交任務時,線程池隊列已滿,這時會發生什麼
ThreadPoolExecutor's中的submit()方法會拋出一個RejectedExecutionException異常啦

3二、什麼是CAS
CAS(比較與交換,Compare and swap) 是一種有名的無鎖算法。無鎖編程,即不使用鎖的狀況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的狀況下實現變量的同步,因此也叫非阻塞同步


40、高併發、任務執行時間短的業務怎樣使用線程池?併發不高、任務執行時間長的業務怎樣使用線程池?併發高、業務執行時間長的業務怎樣使用線程池?
newCachedThreadPool(彈性緩存線程池) newSingleThreadExecutor(單線程線程池) newFixedThreadPool

數據庫
五、與Oracle相比,mysql有什麼優點?
oracle
性能:Oracle 性能高
缺點:
對硬件的要求很高;
價格比較昂貴;
管理維護麻煩一些;
操做比較複雜,須要技術含量較高
mysql
優勢:
體積小、速度快、整體擁有成本低,開源;
支持多種操做系統;
是開源數據庫,提供的接口支持多種語言鏈接操做
八、請簡潔描述mysql中InnoDB支持的四種事務隔離級別名稱,以及逐級之間的區別?
讀未提交(read uncommitted):能夠讀取其餘 session 未提交的髒數據。
讀已提交(read committed):容許不可重複讀取,但不容許髒讀取。提交後,其餘會話能夠看到提交的數據。
可重複讀(repeatable read):禁止不可重複讀取和髒讀取、以及幻讀(innodb 獨有)。
串行(serializable):事務只能一個接着一個地執行,但不能併發執行。事務隔離級別最高。
不一樣的隔離級別有不一樣的現象,並有不一樣的鎖定/併發機制,隔離級別越高,數據庫的併發性就越差。

3三、LIKE和REGEXP操做有什麼區別?
其中like要求整個數據都要匹配,而REGEXP只須要部分匹配便可。
也就是說,用Like,必須這個字段的全部內容知足條件,而REGEXP只須要有任何一個片斷知足便可

mysql索引採用 索引的數據結構(B Tree 、 B+Tree)
B樹
1.全部非葉子結點至多擁有兩個兒子(Left和Right);
2.全部結點存儲一個關鍵字;
3.非葉子結點的左指針指向小於其關鍵字的子樹,右指針指向大於其關鍵字的子樹;左小右大
B+Tree
B+Tree只有最下面的葉子節點纔是它的數據,每一個節點能夠多條數據,查找1是執行3次IO,查找2一樣也是執行3次IO ,MySQL查詢數據最多IO次數3-5次(固然數據量越大,樹的高度也會增加,IO也會增長)

3四、BLOB和TEXT有什麼區別?
TEXT與BLOB的主要差異就是BLOB保存二進制數據,TEXT保存字符數據。

5二、mysql裏記錄貨幣用什麼字段類型好?
貨幣在數據庫中MySQL經常使用Decimal和Numric類型表示 值做爲字符串存儲,而不是做爲二進制浮點數,以便保存那些值的小數精度
不使用float或者double的緣由:由於float和double是以二進制存儲的,因此有必定的偏差。

5四、mysql有關權限的表都有哪幾個?
user權限表:記錄容許鏈接到服務器的用戶賬號信息,裏面的權限是全局級的。
db權限表:記錄各個賬號在各個數據庫上的操做權限。
table_priv權限表:記錄數據表級的操做權限。
columns_priv權限表:記錄數據列級的操做權限。
host權限表:配合db權限表對給定主機上數據庫級操做權限做更細緻的控制。這個權限表不受GRANT和REVOKE語句的影響。

GC的三種收集方法:標記清除、標記整理、複製算法的原理與特色,分別用在什麼地方,優化收集方法的思路
第一種:標記清除 適合在老年代進行垃圾回收,好比CMS收集器就是採用該算法進行回收的。
第二種:標記整理 適合老年代進行垃圾收集
第三種:複製算法 適合新生代區進行垃圾回收
參照:https://blog.csdn.net/fateruler/article/details/81158510

九、幾種經常使用的內存調試工具:jmap、jstack、jconsole、jhat

十、類加載的幾個過程?
1)  加載:根據查找路徑找到相應的class文件,而後導入。類的加載方式分爲
隱式加載和顯示加載兩種。隱式加載指的是程序在使用new關鍵詞建立對象時,會隱式的調用類的加載器把對應的類加載到jvm中。顯示加載指的是經過直接調用class.forName()方法來把所需的類加載到jvm中。
2)  檢查:檢查夾加載的class文件的正確性。
3)  準備;給類中的靜態變量分配內存空間。
4)  解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解爲一個標示,而在直接引用直接指向內存中的地址。
5)  初始化:對靜態變量和靜態代碼塊執行初始化工做。

1三、簡述java垃圾回收機制?
只有在虛擬機空閒或者當前堆內存不足時,纔會觸發執行,掃描那些沒有被任何引用的對象,並將它們添加到要回收的集合中,進行回收。

1九、什麼是類加載器,類加載器有哪些?
引導類加載器(bootstrap class loader):它用來加載 Java 的核心庫,是用原生代碼來實現的,並不繼承自 java.lang.ClassLoader。
擴展類加載器(extensions class loader):它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄裏面查找並加載 Java 類。
系統類加載器(system class loader):它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。通常來講,Java 應用的類都是由它來完成加載的。能夠經過 ClassLoader.getSystemClassLoader()來獲取它。
除了系統提供的類加載器之外,開發人員能夠經過繼承 java.lang.ClassLoader類的方式實現本身的類加載器,以知足一些特殊的需求。
參見:https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html

20、簡述java內存分配與回收策率以及Minor GC和Major GC
新生代 GC(Minor GC):指發生在新生代的垃圾收集動做,由於 Java 對象大多都具
備朝生夕滅的特性,因此 Minor GC 很是頻繁,通常回收速度也比較快(適合採用複製算法)
老年代 GC(Major GC  / Full GC):指發生在老年代的 GC,出現了 Major GC,常常
會伴隨至少一次的 Minor GC(但非絕對的,在 ParallelScavenge 收集器的收集策略裏
就有直接進行 Major GC 的策略選擇過程) 。MajorGC 的速度通常會比 Minor GC 慢 10
倍以上。


pring Aop中四個重要概念,切點,切面,鏈接點,通知
1. 通知: 就是咱們編寫的但願Aop時執行的那個方法。咱們經過Aop但願咱們編寫的方法在目標方法執行前執行,或者執行後執行。
2. 切點:切點就是咱們咱們配置的知足咱們條件的目標方法。好比咱們規定:名字前面是select開頭的才執行咱們自定義的通知方法。那麼這些select開頭的方法就是切點。
3. 鏈接點:鏈接點能夠說是切點的全集。切點是鏈接點的子集。也能夠理解爲,鏈接點是咱們沒有定義那個select開頭規則時,知足條件的所有的方法。
4. 切面:切面是切點和通知的組合稱謂,就是變相給組合起了個名字。

spring AOP 之一:spring AOP功能介紹
參照:https://www.cnblogs.com/duanxz/p/6754606.html
aop 配置 能夠配置事物,能夠配置apsect 切面上進行通知
aop實現了 jdk的動態代理和cglib 的動態代理 2種方式 jdk的代理 實現類須要實現接口才能代理 ,cglib 能夠直接代理某個類 進行方法攔截


spring mvc 面試題答案 螞蟻金福 https://zhuanlan.zhihu.com/p/59377434

 


SpingMvc中的控制器的註解通常用那個,有沒有別的註解能夠替代
通常用@Conntroller註解,表示是表現層,不能用用別的註解代替.

八、 @RequestMapping註解用在類上面有什麼做用?
@RequestMapping 有兩種標註方式,一種是標註在類級別上,一種是標註在方法級別上。標註在方法上時,value 表示訪問該方法的 URL 地址。標註在類上時,value 至關於一個命名空間,即訪問該 Controller 下的任意方法都須要帶上這個命名空間。
參照https://www.cnblogs.com/caoyc/p/5635173.html

十一、怎麼樣在方法裏面獲得Request,或者Session?
能夠經過httpservletrequst放在方法參數上 也能夠 經過(Map)ActionContext.getContext().get("request")

springmvc 方法獲取前臺的參數 註解有
@RequestParam @PathVariable @RequestBody 返回的有@ResponseBody 表示服務器返回的時候以一種什麼樣的方式進行返回, 將內容或對象做爲 HTTP 響應正文返回,值有不少,通常設定爲json


1五、SpringMVC怎麼樣設定重定向和轉發的?
return "forward:/userHome" return "redirect:/"; 經過forward , redirect

1七、SpringMvc 用什麼對象從後臺向前臺傳遞數據的?
答:經過 ModelMap 對象,能夠在這個對象裏面用 put 方法,把對象加到裏面,前臺就能夠過 el 表達式拿到。

2一、當一個方法向 AJAX 返回特殊對象,譬如 Object,List 等,須要作什麼處理?
答:要加上@ResponseBody 註解

2二、SpringMvc 裏面攔截器是怎麼寫的?
答:有兩種寫法,一種是實現接口,另一種是繼承適配器類,而後在 SpringMvc 的配置文配置攔截器便可:<!-- 配置 SpringMvc 的攔截器 --><mvc:interceptors>

netty
1.BIO、NIO和AIO的區別?
BIO是一個鏈接一個線程。
NIO是一個請求一個線程。
AIO是一個有效請求一個線程。
Java BIO (傳統io): 同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。

Java NIO(改進後的io) : 同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。

Java AIO(NIO.2) : 異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理,

BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解。

NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持。

AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。

同步 : 本身親自出馬持銀行卡到銀行取錢(使用同步IO時,Java本身處理IO讀寫);
異步 : 委託一小弟拿銀行卡到銀行取錢,而後給你(使用異步IO時,Java將IO讀寫委託給OS處理,須要將數據緩衝區地址和大小傳給OS(銀行卡和密碼),OS須要支持異步IO操做API);
阻塞 : ATM排隊取款,你只能等待(使用阻塞IO時,Java調用會一直阻塞到讀寫完成才返回);
非阻塞 : 櫃檯取款,取個號,而後坐在椅子上作其它事,等號廣播會通知你辦理,沒到號你就不能去,你能夠不斷問大堂經理排到了沒有,大堂經理若是說還沒到你就不能去(使用非阻塞IO時,若是不能讀寫Java調用會立刻返回,當IO事件分發器會通知可讀寫時再繼續進行讀寫,不斷循環直到讀寫完成)
參照:https://blog.csdn.net/skiof007/article/details/52873421
參見:https://blog.csdn.net/anxpp/article/details/51512200 更詳細

3.Netty的特色?
Netty是一個高性能、異步事件驅動的NIO框架 Netty的全部IO操做都是異步非阻塞的
Netty的特色
(1) 使用更高效的socket底層,對epoll空輪詢引發的cpu佔用飆升在內部進行了處理,避免了直接使用NIO的陷阱,簡化了NIO的處理方式。

(2) 採用多種decoder/encoder 支持,對TCP粘包/分包進行自動化處理

(3) 可以使用接受/處理線程池,提升鏈接效率,對重連、心跳檢測的簡單支持

(4)可配置IO線程數、TCP參數, TCP接收和發送緩衝區使用直接內存代替堆內存,經過內存池的方式循環利用ByteBuf

(5) 經過引用計數器及時申請釋放再也不引用的對象,下降了GC頻率

(6)使用單線程串行化的方式,高效的Reactor線程模型

(7) 無鎖化的串行設計,採用環形數組緩衝區實現無鎖化併發編程

(8)大量使用了volitale、使用了CAS和原子類、線程安全類的使用、讀寫鎖的使用

參見:https://blog.csdn.net/baiye_xing/article/details/73136174

6.瞭解哪幾種序列化協議?
一、XML 二、JSON 三、Fastjson 等 參見:https://blog.csdn.net/baiye_xing/article/details/73249819

 

dubbo
四、dubbo都支持什麼協議,推薦用哪一種?
Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多種協議,可是Dubbo官網是推薦咱們使用Dubbo協議的。
五、Dubbo須要 Web 容器嗎?
dubbo服務容器是一個standalone的啓動程序,由於後臺服務不須要Tomcat或JBoss等Web容器的功能, 服務容器只是一個簡單的Main方法,
並加載一個簡單的Spring容器,用於暴露服務。 服務容器的加載內容能夠擴展,內置了spring, jetty, log4j等加載

十、Dubbo有哪幾種配置方式?
根據 DUBBO 官方文檔,配置 DUBBO 有 4 種方式,分別是:
1. XML 配置文件方式(經常使用的方式)
2. properties 配置文件方式
3. annotation 配置方式
4. API 配置方式

十一、Dubbo核心的配置有哪些?
生產者,提供者 參見:https://www.cnblogs.com/wangzhuxing/p/9735258.html

十二、在Provider 上能夠配置的 Consumer 端的屬性有哪些?
timeout group version registry

1三、Dubbo啓動時若是依賴的服務不可用會怎樣?
Dubbo缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止Spring初始化完成,以便上線時,能及早發現問題,默認check=true。不然能夠指定不檢查


1四、Dubbo推薦使用什麼序列化框架,你知道的還有哪些?
dubbo默認使用的是

Hessian序列化

1五、Dubbo默認使用的是什麼通訊框架,還有別的選擇嗎?
Dubbo使用的是netty ,reactor模式採用nio的方式通訊,主流通訊框架包括netty,mina,Grizzly


MYBATIS
二、講下MyBatis的緩存
1、mybatis和同是持久層的hibernate同樣,都存在着緩存機制,今天來講一下mybatis的緩存機制。
查詢緩存來緩存數據,從而達到提升查詢性能的要求,以提升咱們項目的效率!!
2、mybatis的緩存機制有兩級:
(1)一級緩存:一級緩存mybatsi已近爲咱們自動開啓,不用咱們手動操做,並且咱們是關閉不了的!!可是咱們能夠手動清除緩存。(SqlSession級別)
(2)二級緩存:二級緩存須要咱們手動開啓。(全局級別)

四:二級緩存

二級緩存的做用:經過度一級緩存的瞭解。推擠緩存是基於同一個SqlSesion類的實例對象的。可是,有些時候在wenb工廠中將會執行查詢操做的方法分裝在某個Service方法中,當查詢完一次後,
Service方法結束,此時SqlSession類的實例對象就會關閉,一級緩存就會被清空。此時若再次調用用Service方法查詢同一個信息,此時異界緩存就是空的,從而沒法從緩存中獲取信息!!

 所以,咱們能夠使用二級緩存,二級緩存存在與Mapper實例中,當多個SqlSession類的實例對象加載相同的mapper文件,並執行其中國的SQL配置時,他們就共享一個Mapper緩存。
當某個SqlSession類的實例對象執行了增,刪,改,等改變數據的操做時,Mapper實例都會清空其二級緩存!

簡單來講就是 多個線程執行相同的sql 會從緩存中取 ,即便不是同一個sqlsession

hibernate的查詢
有creatsqlquery(寫sql的) createquery(查詢對象的)

shiro 配置權限的方式有幾種,分別解釋一下
4種
1,在配置文件中對過濾的url進行權限的添加, 2. 在service方法上配置註解@RequiresPermissions(「user:delete」)
3. 在jsp頁面中使用標籤 <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
4.編程方式實現用戶權限控制
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
//有權限
}else{
//無權限
}
參見:https://blog.csdn.net/qq_38263083/article/details/82716702

1七、MyBatis裏面的動態Sql是怎麼設定的?用什麼語法?
MyBatis中用於實現動態SQL的元素主要有:if 、choose、 when、otherwise、trim、where、set 、foreach。

 

shiro的實現原理? 核心原理過濾器
subject:主體,能夠是用戶也能夠是程序,主體要訪問系統,系統須要對主體進行認證、受權。
securityManager:安全管理器,主體進行認證和受權都是經過securityManager進行。
authenticator:認證器,主體進行認證最終經過authenticator進行的。
authorizer:受權器,主體進行受權最終經過authorizer進行的。
sessionManager:web應用中通常是用web容器對session進行管理,shiro也提供一套session管理的方式。
SessionDao:  經過SessionDao管理session數據,針對個性化的session數據存儲須要使用sessionDao。
cache Manager:緩存管理器,主要對session和受權數據進行緩存,好比將受權數據經過cacheManager進行緩存管理,和ehcache整合對緩存數據進行管理。
realm:域,領域,至關於數據源,經過realm存取認證、受權相關數據。


spring中有spring security (原名Acegi),是一個權限框架,它和spring依賴過於緊密,沒有shiro使用簡單。
shiro不依賴於spring,shiro不只能夠實現 web應用的權限管理,還能夠實現c/s系統,分佈式系統權限管理,shiro屬於輕量框架,愈來愈多企業項目開始使用shiro。
使用shiro實現系統的權限管理,有效提升開發效率,從而下降開發成本


mybatis 使用resultmap 實現一個查詢
關聯關係
一對多:
用collection 標籤關聯

多對一:
用association 標籤關聯
參見:https://blog.csdn.net/qq_33561055/article/details/78861131

 

mapper 代理如何實現的
採用Mapper動態代理方法只須要編寫相應的Mapper接口(至關於Dao接口),那麼Mybatis框架根據接口定義建立接口的動態代理對象,代理對象的方法體同Dao接口實現類方法。
Mapper接口開發須要遵循如下規範:
一、Mapper.xml文件中的namespace與mapper接口的全類名相同。
二、Mapper接口方法名和Mapper.xml中定義的每一個statement的id相同。
三、Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同。
四、Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同。

動態代理的實現 省去了獲取sqlsession的步驟,在方法執行前進行動態執行
參見:https://blog.csdn.net/xiaokang123456kao/article/details/66476828
參見:https://blog.csdn.net/xiaokang123456kao/article/details/76228684

緩存的實現原理
?????

ConcurrentHashMap和Hashtable的區別
Hashtable和ConcurrentHashMap有什麼分別呢?它們均可以用於多線程的環境,可是當Hashtable的大小增長到必定的時候,性能會急劇降低,
由於迭代時須要被鎖定很長的時間。由於ConcurrentHashMap引入了分割(segmentation),不論它變得多麼大,僅僅須要鎖定map的某個部分,
而其它的線程不須要等到迭代完成才能訪問map。簡而言之,在迭代的過程當中,ConcurrentHashMap僅僅鎖定map的某個部分,而Hashtable則會鎖定整個map。


hashmap 線程不安全的 由於多線程環境下,使用Hashmap進行put操做會引發死循環,致使CPU利用率接近100%,因此在併發狀況下不能使用HashMap。
hashtable 每一步操做都有鎖,線程安全可是很慢性能低

HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的狀況下HashTable的效率很是低下。
由於當一個線程訪問HashTable的同步方法時,其餘線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。
如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,而且也不能使用get方法來獲取元素,因此競爭越激烈效率越低。

ConcurrentHashMap 線程安全的 利用鎖分段技術
HashTable容器在競爭激烈的併發環境下表現出效率低下的緣由,是由於全部訪問HashTable的線程都必須競爭同一把鎖,
那假如容器裏有多把鎖,每一把鎖用於鎖容器其中一部分數據,那麼當多線程訪問容器裏不一樣數據段的數據時,線程間就不會存在鎖競爭,
從而能夠有效的提升併發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術。

執行put方法的線程會得到鎖,只有當此線程的put方法執行結束後纔會釋放鎖,根據多線程的知識,得到鎖的線程會通知其餘試圖操做put方法的線程,並通知其餘線程出於等待狀態,
直到釋放鎖後,其餘線程纔會去從新競爭鎖。這一點保證了ConcurrentHashMap的線程安全。
線程安全的比hashtable 性能更高
參見:https://blog.csdn.net/sbq63683210/article/details/51679790


設計一個簡單權限須要幾張表
5張 user表 user-role表 role表 role-author表 author表

描述一下登陸須要哪些步驟

 


arraylist 如何擴容
初始化會被分配10個長度當超出長度後在擴容1.5倍
ArrayList是採起延遲分配對象數組大小空間的,當第一次添加元素時纔會分配10個對象空間,
當添加第11個元素的時候,會擴容1.5倍,當添加到16個元素的時候擴容爲15*1.5=22,以此類推。
當咱們在明確對象的大體數目時候提早指定初始化數組的大小是一個很是明智的選擇

hashmap 如何擴容
默認的是長度*負載因子(0.75)
當map中包含的Entry的數量大於等於threshold = loadFactor * capacity的時候,且新建的Entry恰好落在一個非空的桶上,此刻觸發擴容機制,將其容量擴大爲2倍

AOP的實現原理
spring框架對於這種編程思想的實現基於兩種動態代理模式,分別是 JDK動態代理 及 CGLIB的動態代理,這兩種動態代理的區別是 JDK動態代理須要目標對象實現接口,而 CGLIB的動態代理則不須要
動態代理模式:動態代理類的源碼是在程序運行期間,經過 JVM 反射等機制動態生成。代理類和委託類的關係是運行時才肯定的

使用 JDK 生成的動態代理的前提是目標類必須有實現的接口。但這裏又引入一個問題,若是某個類沒有實現接口,就不能使用 JDK 動態代理。因此 CGLIB 代理就是解決這個問題的。
CGLIB 是以動態生成的子類繼承目標的方式實現,在運行期動態的在內存中構建一個子類
CGLIB 使用的前提是目標類不能爲 final 修飾。由於 final 修飾的類不能被繼承。

如今,咱們能夠看看 AOP 的定義:面向切面編程,核心原理是使用動態代理模式在方法執行先後或出現異常時加入相關邏輯。

AOP 是基於動態代理模式。
AOP 是方法級別的。
AOP 能夠分離業務代碼和關注點代碼(重複代碼),在執行業務代碼時,動態的注入關注點代碼。切面就是關注點代碼造成的類。


參照:http://www.importnew.com/31318.html


數據結構:
關於樹:https://zhuanlan.zhihu.com/p/27700617

 

java io流的操做
參見:https://juejin.im/post/5af79bcc51882542ad771546
java io流中涉及的設計模式
private static final String SEPARATOR = File.separator;
File file = new File("e:" + SEPARATOR + "io" + SEPARATOR + "test.txt");
//一、得到子節輸入流
FileInputStream fileInputStream=new FileInputStream(file);
二、構造轉換流
InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream);
三、 構造緩衝字符流
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
//備註一、2兩步驟體現出了適配器模式
//2步驟體現了InputStreamReader類具備將子節輸入流轉換爲字符輸入流的功能
//二、3兩步驟體現了裝飾模式(wrapper包裝模式)

io中的適配器模式
因爲InputStream是字節流不能享受到字符流讀取字符那麼便捷的功能,所以藉助
InputStreamReader將其轉爲Reader子類,所以能夠擁有便捷操做文本文件方法。
OutputStream同理。

io中的裝飾(包裝)模式
將InputStream字節流包裝爲BufferedReader過程就裝飾的過程。一開始
InputStream只有read一個字節的方法,包裝爲Reader以後擁有read一個字符的功
能,在包裝成BufferedReader以後就擁有read一行字符串功能。OutputStream同理

 

最後說一點,咱們做爲程序員,研究問題仍是要仔細深刻一點的。當你對原理了解的有夠透徹,開發起來也就駕輕就熟了,不少開發中的問題和疑惑也就迎刃而解了,
並且在面對其餘問題的時候也可作到舉一反三。固然在開發中沒有太多的時間讓你去研究原理,開發中要以實現功能爲前提,可等項目上線的後,
你有大把的時間或者空餘的時間,你大可去刨根問底,深刻的去研究一項技術,爲以爲這對一名程序員的成長是很重要的事情。

 

1.請列舉出在JDK中幾個經常使用的設計模式?
享元模式
java.lang.Integer(其它基本類型包裝類(除去Float,Double)也如此,還有BigDecimal)
Integer.valueOf()方法
byte,short,int,long,boolean,char的包裝型在類加載到JVM時,已經緩存了制定範圍的對象引用,由於值的設定使用的是static塊或者常量。其中char的範圍爲:0~127;boolean的值爲true和false;其它默認範圍都是-127~128。其中int的上限127能夠調整,這須要調整JVM的參數。
同時利用了享元模式的還有String這個類,由於生存的每一個字符串都是不可變的。

.迭代器模式
不少集合已經使用了迭代器進行遍歷。(Iterator)

建造者模式
java.lang.StringBuilder,這是一個final類
public StringBuilder append(String str)方法,這一方法是對父類的覆寫。
類功能:用於一個不可更改的字符序列。
方法功能:根據現有字符序列和追加字符,經過系統拷貝方法System.arraycopy生成一個新的字符序列。

適配器模式
java.util.Arrays
public static List asList(T… a)方法
類功能:此類包含了大量對數組操做的方法。
方法功能:將一個引用類型的數組轉爲一個List。從而能夠使用List類的操做來操做數組對象,可是有一點要注意:就是不能使用add(),remove()操做,由於返回的list底層是基於數組的,數組結構是不能更改的。 list類就是這裏的適配器,經過這個適配器,對數組的直接操做變爲間接操做。
參見:https://blog.csdn.net/caoxiaohong1005/article/details/79961539

.在 Java 中,什麼叫觀察者設計模式(observerdesign pattern)?
發佈訂閱模式是最經常使用的一種觀察者模式的實現,而且從解耦和重用角度來看,更優於典型的觀察者模式
在發佈訂閱模式中,發佈者和訂閱者之間多了一個發佈通道;一方面從發佈者接收事件,另外一方面向訂閱者發佈事件;訂閱者須要從事件通道訂閱事件

7.在 Java 中,爲何不容許從靜態方法中訪問非靜態變量?
由於靜態方法的調用不是經過實例對象進行的,因此在靜態方法中沒有this指針,不能訪問所屬類的非靜態變量和方法,只能訪問方法體內的局部變量、本身的參數和靜態變量。
成員變量分爲實例變量和靜態變量。

10.舉例說明什麼狀況下會更傾向於使用抽象類而不是接口?
使用模板方法設計模式要使用抽象類

nginx
nginx負載均衡的算法怎麼實現的
nginx 的 upstream目前支持 4 種方式的分配

1)、輪詢(默認)
​ 每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。
2)、weight
​ 指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。
2)、ip_hash
​ 每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
3)、fair(第三方)
​ 按後端服務器的響應時間來分配請求,響應時間短的優先分配。
4)、url_hash(第三方)
nginx內置策略包含加權輪詢和ip hash
加權輪詢算法分爲先深搜索和先廣搜索,那麼nginx採用的是先深搜索算法,即將首先將請求都分給高權重的機器,直到該機器的權值降到了比其餘機器低,纔開始將請求分給下一個高權重的機器;

參見:http://dujianjian.win/2018/05/24/nginx/#nginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%9A%84%E7%AE%97%E6%B3%95%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84

 

springmvc 方法跳轉
重定向:"redirect:/url" request的做用域被改變了 就不是一個回話了
轉發: "forward:/url" request的做用域仍是同一個 仍是同一個回話參數共享
參見:https://blog.csdn.net/u013041642/article/details/72190223

spring mvc 支持以下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void。
參見:https://www.cnblogs.com/xiepeixing/p/4243801.html


static synchronize 方法鎖(類鎖) 和直接synchronize 方法鎖(對象鎖) 不衝突 互相執行各自的
對象能夠有任意個,多以與類不衝突 static 修飾的是共享的不是線程安全的


經常使用設計模式
參見:https://mp.weixin.qq.com/s/OAEtpM-h3OT_bBYgvyvE0w
觀察者模式核心是:觀察者要註冊到被觀察者裏面,一旦被觀察者變動了消息,就會通知到全部的被註冊進來的用戶,如今的註冊中心,
redis,zookeeper,都有發佈與訂閱功能,就是相似此原理


在數據庫中有兩種基本的鎖類型:排它鎖(Exclusive Locks,即X鎖)和共享鎖(Share Locks,即S鎖)。
當數據對象被加上排它鎖時,其餘的事務不能對它讀取和修改。加了共享鎖的數據對象能夠被其餘事務讀取,但不能修改。
數據庫利用這兩 種基本的鎖類型來對數據庫的事務進行併發控制。

對於UPDATE、DELETE、INSERT語句,Innodb會自動給涉及的數據集加排他鎖(X);對於普通SELECT語句,Innodb不會加任何鎖。


mysql的共享鎖(Share Lock)
Mysql會對查詢結果中的每行都加共享鎖
若是事務T對數據A加上共享鎖後,則其餘事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。
用法
SELECT 條件 from 表 LOCK IN SHARE MODE;

排他鎖(eXclusive Lock)
Mysql會對查詢結果中的每行都加排他鎖
排他鎖又稱寫鎖,若是事務T對數據A加上排他鎖後,則其餘事務不能再對A加任任何類型的封鎖。獲准排他鎖的事務既能讀數據,又能修改數據。
用法
SELECT 條件 from 表 FOR UPDATE;

innodb默認是行鎖 在更改操做自動加上行鎖,若是操做的行沒有索引那麼會自動加上表鎖 找到行以後再變行鎖

意向鎖
意向鎖
意向鎖是表級鎖,其設計目的主要是爲了在一個事務中揭示下一行將要被請求鎖的類型。InnoDB中的兩個表鎖:
意向共享鎖(IS):表示事務準備給數據行加入共享鎖,也就是說一個數據行加共享鎖前必須先取得該表的IS鎖
意向排他鎖(IX):相似上面,表示事務準備給數據行加入排他鎖,說明事務在一個數據行加排他鎖前必須先取得該表的IX鎖。
意向鎖是InnoDB自動加的,不須要用戶干預。

對於insert、update、delete,InnoDB會自動給涉及的數據加排他鎖(X);對於通常的Select語句,InnoDB不會加任何鎖,
事務能夠經過如下語句給顯示加共享鎖或排他鎖


公平鎖、非公平鎖
公平鎖(Fair):加鎖前檢查是否有排隊等待的線程,優先排隊等待的線程,先來先得。
非公平鎖(Nonfair):加鎖時不考慮排隊等待問題,直接嘗試獲取鎖,獲取不到自動到隊尾等待。(synchronize)
ReentrantLock鎖內部提供了公平鎖與分公平鎖內部類之分,默認是非公平鎖,

可重入鎖
Lock lock1 = new ReentrantLock();
可重入鎖,也叫作遞歸鎖,指的是同一線程外層函數得到鎖以後 ,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。反之不可重入鎖
使用:tryLock 避免死鎖
synchronized:可重入鎖
java.util.concurrent.locks.ReentrantLock:可重入鎖;

分段鎖
ConcurrentHashMap

樂觀鎖/悲觀鎖
悲觀鎖適合寫操做很是多的場景,樂觀鎖適合讀操做很是多的場景,不加鎖會帶來大量的性能提高。
悲觀鎖在Java中的使用,就是利用各類鎖。
樂觀鎖在Java中的使用,是無鎖編程,經常採用的是CAS算法,典型的例子就是原子類,經過CAS自旋實現原子操做的更新。


讀寫鎖:
分爲讀鎖和寫鎖,多個讀鎖不互斥,讀鎖與寫鎖互斥,這是由jvm本身控制的,你只要上好相應的鎖便可。若是你的代碼只讀數據,
能夠不少人同時讀,但不能同時寫,那就上讀鎖;若是你的代碼修改數據,
只能有一我的在寫,且不能同時讀取,那就上寫鎖。總之,讀的時候上讀鎖,寫的時候上寫鎖
參見:https://www.cnblogs.com/zzlp/p/5174745.html

CAS
使用:private static final Unsafe unsafe = Unsafe.getUnsafe();//compareAndSwapInt 簡稱cas
Compare And Swap.比較並交換.java中的同步器就是基於CAS技術實現的,爲何它能保證操做的同步性呢?由於是原子操做的一種,
因此能夠在多線程環境下來實現數據的交換操做不被打斷.
CAS缺點
1. ABA問題。由於CAS須要在操做值的時候檢查下值有沒有發生變化,若是沒有發生變化則更新,
可是若是一個值原來是A,變成了B,又變成了A,那麼使用CAS進行檢查時會發現它的值沒有發生變化,可是實際上卻變化了。
2. 循環時間長開銷大。
3. 只能保證一個共享變量的原子操做。

什麼是AQS
AQS(AbstractQueuedSynchronizer),AQS是JDK下提供的一套用於實現基於FIFO等待隊列的阻塞鎖和相關的同步器的一個同步框架
可見 CountDownLatch 是基於AQS框架來實現的一個同步器.相似的同步器在JUC下還有很多。

 

java 中的鎖:https://www.cnblogs.com/qifengshi/p/6831055.html

、getCurrentSession()與openSession()的區別?
* 採用getCurrentSession()建立的session會綁定到當前線程中,而採用openSession(),建立的session則不會
* 採用getCurrentSession()建立的session在commit或rollback時會自動關閉,而採用openSession(),建立的session必須手動關閉

事務 Spring read-only="true" 只讀事務的一些概念
應用場合:

若是你一次執行單條查詢語句,則沒有必要啓用事務支持,數據庫默認支持SQL執行期間的讀一致性;
若是你一次執行多條查詢語句,例如統計查詢,報表查詢,在這種場景下,多條查詢SQL必須保證總體的讀一致性,不然,在前條SQL查詢以後,後條SQL查詢以前,數據被其餘用戶改變,則該次總體的統計查詢將會出現讀數據不一致的狀態,此時,應該啓用事務支持。
【注意是一次執行屢次查詢來統計某些信息,這時爲了保證數據總體的一致性,要用只讀事務】


數據庫的死鎖:
死鎖的第一種狀況
一個用戶A 訪問表A(鎖住了表A),而後又訪問表B;另外一個用戶B 訪問表B(鎖住了表B),而後企圖訪問表A;這時用戶A因爲用戶B已經鎖住表B,
它必須等待用戶B釋放表B才能繼續,一樣用戶B要等用戶A釋放表A才能繼續,這就死鎖就產生了。

死鎖的第二種狀況
用戶A查詢一條紀錄,而後修改該條紀錄;這時用戶B修改該條紀錄,這時用戶A的事務裏鎖的性質由查詢的共享鎖企圖上升到獨佔鎖,
而用戶B裏的獨佔鎖因爲A 有共享鎖存在因此必須等A釋放掉共享鎖,而A因爲B的獨佔鎖而沒法上升的獨佔鎖也就不可能釋放共享鎖,因而出現了死鎖

死鎖的第三種狀況若是在事務中執行了一條不知足條件的update語句,則執行全表掃描,把行級鎖上升爲表級鎖,多個這樣的事務執行後,就很容易產生死鎖和阻塞。相似的情 況還有當表中的數據量很是龐大而索引建的過少或不合適的時候,使得常常發生全表掃描,最終應用系統會愈來愈慢,最終發生阻塞或死鎖。參見:https://uule.iteye.com/blog/2422193

相關文章
相關標籤/搜索