Java面試題總結


Java基礎:

1、JAVA中能創建volatile數組嗎?volatile能使得一個非原子操作變成原子操作嗎?


回答: 能,Java 中可以創建 volatile 類型數組,不過只是一個指向數組的引用,而不是整個數組。
Java 中讀取 long 類型變量不是原子的,需要分成兩步,如果一個線程正在修改該 long 變量的值,另一個線程可能只能看到該值的一半(前 32 位)。但是volatile 型的 long 或 double 變量的讀寫是原子。

2、10個線程和2個線程的同步代碼,哪個更容易寫?
回答:從寫代碼的角度來說,兩者的復雜度是相同的,因為同步代碼與線程數量是相互獨立的。但是同步策略的選擇依賴於線程的數量,因為越多的線程意味着更大的競爭,所以你需要利用同步技術,如鎖分離,這要求更復雜的代碼和專業知識。
3、什么是線程局部變量?
回答: 對於多線程資源共享的問題,同步機制采用了“以時間換空間”的方式,而ThreadLocal采用了“以空間換時間”的方式。前者僅提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程都提供了一份變量,因此可以同時訪問而互不影響。

4、我們自己寫一個容器類,然后使用for-each循環嗎?
回答:可以,你可以寫一個自己的容器類。如果你想使用 Java 中增強的循環來遍歷,你只需要實現 Iterable接口。如果你實現 Collection 接口,默認就具有該屬性。


5、說出5條IO的最佳實踐?
回答:1.使用有緩沖區的 IO 類,而不要單獨讀取字節或字符。
2.使用 NIO 和 NIO2
3.在 finally 塊中關閉流,或者使用 try-with-resource 語句。
4.使用內存映射文件獲取更快的 IO。
5.使用非阻塞式而不要使用阻塞式的IO

6、說出至少5點在Java中使用線程的最佳實踐?
回答:1.對線程命名

2.將線程和任務分離,使用線程池執行器來執行 Runnable 或 Callable。

3.使用線程池

4.如果可以,更偏向於使用 volatile 而不是 synchronized。

5.優先使用並發集合,而不是對集合進行同步。並發集合提供更好的可擴展性。

7、我能在不進行強制轉換的情況下將一個double值賦值給long類型的變量嗎?
回答:不行,因為 double 類型的范圍比 long 類型更廣,所以必須要進行強制轉換。

8、我們能在Switch中使用String嗎?
回答:在jdk 7 之前,switch 只能支持 byte、short、char、int 這幾個基本數據類型和其對應的封裝類型。switch后面的括號里面只能放int類型的值,但由於byte,short,char類型,它們會 自動 轉換為int類型(精精度小的向大的轉化),所以它們也支持。
jdk1.7后,整形,枚舉類型,boolean,字符串都可以。
jdk1.7並沒有新的指令來處理switch string,而是通過調用switch中string.hashCode,將string轉換為int從而進行判斷。

9、poll()方法和remove()方法的區別?
回答: poll() 和 remove() 都是從隊列中取出一個元素,但是 poll() 在獲取元素失敗的時候會返回空,但是 remove() 失敗的時候會拋出異常。

10、LinkedList和ArrayList的區別?
回答:1.ArrayList和LinkedList可想從名字分析,它們一個是Array(動態數組)的數據結構,一個是Link(鏈表)的數據結構,此外,它們兩個都是前者是數組隊列,相當於動態數組;后者為雙向鏈表結構,也可當作堆棧、隊列、雙端隊列對List接口的實現。

2.當隨機訪問List時(get和set操作),ArrayList比LinkedList的效率更高,因為LinkedList是線性的數據存儲方式,所以需要移動指針從前往后依次查找。

3.當對數據進行增加和刪除的操作時(add和remove操作),LinkedList比ArrayList的效率更高,因為ArrayList是數組,所以在其中進行增刪操作時,會對操作點之后所有數據的下標索引造成影響,需要進行數據的移動。

4.從利用效率來看,ArrayList自由性較低,因為它需要手動的設置固定大小的容量,但是它的使用比較方便,只需要創建,然后添加數據,通過調用下標進行使用;而LinkedList自由性較高,能夠動態的隨數據量的變化而變化,但是它不便於使用。

5.ArrayList主要控件開銷在於需要在lList列表預留一定空間;而LinkList主要控件開銷在於需要存儲結點信息以及結點指針信息。

11、hashmap的擴容問題new hashmap(19)它的長度是多少?
回答:初始長度是19,當達到默認加載因子的時候會進行擴容
12、hashtable為什么是線程安全的?
回答:Hashtable是線程安全的,其實現方式是在對應的方法上加上synchronized關鍵字,效率不高,不建議使用。目前,如果要使用線程安全的哈希表的話,推薦使用ConcurrentHashMap。

13、java異常處理怎么做?
回答:1.對代碼塊用try..catch進行異常捕獲處理;

2.在 該代碼的方法體外用throws進行拋出聲明,告知此方法的調用者這段代碼可能會出現這些異常,你需要謹慎處理。此時有兩種情況:1)如果聲明拋出的異常是非運行時異常,此方法的調用者必須顯示地用try..catch塊進行捕獲或者繼續向上層拋出異常;2)如果聲明拋出的異常是運行時異常,此方法的調用者可以選擇地進行異常捕獲處理。

3.在代碼塊用throw手動拋出一個異常對象,此時也有兩種情況,跟2中的類似:1)如果拋出的異常對象是非運行時異常,此方法的調用者必須顯示地用try..catch塊進行捕獲或者繼續向上層拋出異常;2)如果拋出的異常對象是運行時異常,此方法的調用者可以選擇地進行異常捕獲處理。

14、異常處理的作用是什么?
回答: 因為你不可能保證程序不出錯,所以使用異常處理來防止程序出錯的時候你無從下手的局面,對於調試程序和項目實際開發都是有用的

15、jvm內存的分配?
回答:1.程序計數器:線程私有,當前線程執行的字節碼的行號指示器。

2.虛擬機棧:線程私有,存放基本數據類型、對象引用和returnAddress類型。
3.本地方法棧:為虛擬機使用到的Native方法服務。
4.Java堆:線程共享,存放對象的實例,也是GC回收器管理的主要區域。
5.方法區:線程共享,存放已被虛擬機加載的類信息、常量、靜態變量、即時編譯后的代碼等數據。 
6.運行時常量池:方法區的一部分,存放編譯期生成的各種字面量和符號引用。
7.直接內存:不是虛擬機運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域,容易引起OOM異常,NIO會調用,不受Java堆大小的限制。

16、Abstract和interface區別?
回答:1.abstract class 在 Java 語言中表示的是一種繼承關系,一個類只能使用一次繼承關系。但是,一個類卻可以實現多個interface。
2.在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中一般不定義數據成員),所有的成員方法都是abstract的。
3.abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關系,interface表示的是"like-a"關系。
4.實現抽象類和接口的類必須實現其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實現方法。
5.接口中定義的變量默認是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。
6.抽象類中的變量默認是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。
7.接口中的方法默認都是 public,abstract 類型的。

17、有沒有遇到過內存溢出,內存溢出怎么解決?
回答: 分不同情況解決,大多數情況下,此時如果代碼沒有問題的情況下,適當調整-Xmx和-Xms是可以避免的,不過一定是代碼沒有問題的前提,為什么會溢出呢,要么代碼有問題,要么訪問量太多並且每個訪問的時間太長或者數據太多,導致數據釋放不掉,因為垃圾回收器是要找到那些是垃圾才能回收,這里它不會認為這些東西是垃圾,自然不會去回收了。

18、jvm調優有哪幾種方式
回答:1.觀察內存釋放情況、集合類檢查、對象樹
2.線程監控
3.內存泄漏檢查
4.具體調優方式:

19、java中invokeAndWait和invokeLater有什么區別?
回答: 這兩個方法是Swing API 提供給Java開發者用來從當前線程而不是事件派發線程更新GUI組件用的。InvokeAndWait()同步更新GUI組件,比如一個進度條,一旦進度更新了,進度條也要做出相應改變。如果進度被多個線程跟蹤,那么就調用invokeAndWait()方法請求事件派發線程對組件進行相應更新。而invokeLater()方法是異步調用更新組件的。

20、Swing API中哪些方法是線程安全的?
回答:Swing的規則是:一旦Swing組件被具現化(realized),所有可能影響或依賴於組件狀態的代碼都應該在事件派發線程中執行。所以有這3個線程安全的方法:repaint(),revalidate(),andinvalidate()。

21、如何在Java中創建immutable對象?
回答: 1.immutable對象的狀態在創建之后就不能發生改變,任何對它的改變都應該產生一個新的對象。
2.Immutable類的所有的屬性都應該是final的。
3.對象必須被正確的創建,比如:對象引用在對象創建過程中不能泄露(leak)。
4.對象應該是final的,以此來限制子類繼承父類,以避免子類改變了父類的immutable特性。
5.如果類中包含mutable類對象,那么返回給客戶端的時候,返回該對象的一個拷貝,而不是該對象本身(該條可以歸為第一條中的一個特例)

22、Java中的readwritelock是什么?
回答: 一般而言,讀寫鎖是用來提升並發程序性能的鎖分離技術的成果。Java中的ReadWriteLock是Java 5 中新增的一個接口,一個ReadWriteLock維護一對關聯的鎖,一個用於只讀操作一個用於寫。在沒有寫線程的情況下一個讀鎖可能會同時被多個讀線程 持有。寫鎖是獨占的,你可以使用JDK中的ReentrantReadWriteLock來實現這個規則,它最多支持65535個寫鎖和65535個讀 鎖。

23、多線程中的忙循環是什么?
回答: 忙循環就是程序員用循環讓一個線程等待,不像傳統方法wait(), sleep() 或 yield() 它們都放棄了CPU控制,而忙循環不會放棄CPU,它就是在運行一個空循環。這么做的目的是為了保留CPU緩存,在多核系統中,一個等待線程醒來的時候可能會在另一個內核運行,這樣會重建緩存。為了避免重建緩存和減少等待重建的時間就可以使用它了。 

24、volatile變量和atomic變量有什么不同?
回答:volatile 變量和 atomic 變量看起來很像,但功能卻不一樣。Volatile變量可以確保先行關系,即寫操作會發生在后續的讀操作之前, 但它並不能保證原子性。例如用volatile修飾count變量那么 count++ 操作就不是原子性的。而AtomicInteger類提供的atomic方法可以讓這種操作具有原子性如getAndIncrement()方法會原子性的進行增量操作把當前值加一,其它數據類型和引用變量也可以進行相似操作。

25、如果同步塊內的線程拋出異常會發生什么?
回答: 這個問題坑了很多Java程序員,若你能想到鎖是否釋放這條線索來回答還有點希望答對。無論你的同步塊是正常還是異常退出的,里面的線程都會釋放鎖,所以對比鎖接口我更喜歡同步塊,因為它不用我花費精力去釋放鎖,該功能可以在finally block里釋放鎖實現。 

26、單例模式的雙檢鎖式是什么?
回答: 雙重檢驗鎖模式(double checked locking pattern),是一種使用同步塊加鎖的方法。程序員稱其為雙重檢查鎖,因為會有兩次檢查 instance == null,一次是在同步塊外,一次是在同步塊內。為什么在同步塊內還要再檢驗一次?因為可能會有多個線程一起進入同步塊外的 if,如果在同步塊內不進行二次檢驗的話就會生成多個實例了。

27、如何在Java中創建線程安全的singleton?
回答:
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance(){
if (instance == null) instance = new Singleton();
return instance;
}
}


28、說說jdk1.8的新特性?
回答:1.隨着大數據的興起,函數式編程在處理大數據上的優勢開始體現,引入了Lambada函數式編程
2.使用Stream徹底改變了集合使用方式:只關注結果,不關心過程
3.新的客戶端圖形化工具界面庫:JavaFX
4.良好設計的日期/時間API
5.增強的並發/並行API
6.Java與JS交互引擎 -nashorn
7.其他特性

29、gc回收機制原理?
回答:用戶Java程序運行過程中,Java虛擬機提供了另外一個系統級的線程,專門負責回收不再被使用的對象占用的內存,這一過程稱為垃圾回收。垃圾回收需要對堆內存中的對象進行標記,並對堆內存進行整理。這一過程的某些階段需要暫時終止用戶Java線程,等回收工作完成后再恢復執行。因此,頻繁地觸發虛擬機垃圾回收操作的行為會影響程序的運行效率。那么什么情況下會頻繁地出發垃圾回收操作呢?- 比如:堆內存設置過小- 再比如:程序頻繁地分配大型局部對象數組。

 

javaweb:

1、tomcat的優化方式?
回答:
Tomcat的優化我准備從三方面來說:

第一部分: 內存優化
Tomcat的默認內存配置比較低,不用說大項目,就算是小項目,並發量達到一定程度也就可能會拋出OutOfMemoryError異常,
為了解決這個問題,我們要修改JVM的一些配置,在tomcat的bin目錄下的catalina配置文件中,配置Xms和Xmx,也就是
Java虛擬機初始化時堆的最小內存和最大內存,這倆值通常會配置成一樣,這樣GC不必再為擴展內存空間而消耗性能.
除了這兩個,還可以配置XX:PermSize和XX:MaxPermSize,它們是Java虛擬機永久代大小和最大值,除了這幾個參數
還可以再根據具體需要配置其他參數。

第二部分: 配置優化
配置優化,主要有三方面:
1. Connector 優化
Connector是連接器,它負責接收客戶的請求,以及向客戶端回送響應的消息。
默認情況下Tomcat只支持200線程訪問,超過這個數量的連接將被等待甚至超時放棄,所以我們需要提高這方面的處理能力.
修改這部分配置需要修改conf下的server.xml,找到Connector 標簽項,修改protocol,默認的協議類型是BIO,也就是阻塞式I/O操作,
簡單項目及應用可以采用BIO.

第二種協議類型是NIO,它就是一種基於緩沖區是、並能提供非阻塞I/O操作的java API,它有更好的並發運行性能. NIO更適合后台需要耗時完成請求的操作

第三種協議類型是APR,它主要可以提高Tomcat對靜態文件的處理性能.
選擇哪個協議也是根據實際項目進行配置.

除了這個協議類型,還有一個非常重要的參數要改,就是maxThreads,就是當前連接器能夠處理同時請求的最大數目.這個數目也並非
越大越好,它也受操作系統等硬件制約,所以這個值要根據壓力測試后實際數據進行配置.

2. 線程池
使用線程池的好處在於減少了創建銷毀線程的相關消耗,而且可以提高線程的使用效率。使用線程池就在Service標簽中配置Executor就可以了

3. Listener
還有一個影響tomcat性能的因素是內存泄漏,我們在Server標簽中配置一個JreMemoryLeakPreventionListener就可以用來預防JRE內存泄漏

第三部分: 組件優化
可以選用Tomcat Native組件,它可以讓 Tomcat使用 Apache 的 APR包來處理包括文件和網絡IO操作,從而提升性能及兼容性


2、http協議有哪些部分組成?
回答:1.請求部分:1)請求行:請求方式 路徑 協議及版本 2)請求頭:請求頭中保存的是本地瀏覽器信息的,是發送到服務器,被服務器解析的 3)請求體:請求體中存儲的是請求數據,請求方式是POST時,請求體中才有內容;

2.響應部分:1)響應行:協議及版本 狀態碼 狀態碼描述 2)響應頭:包含了服務器信息以及響應內容信息,被瀏覽器解析的 3)響應體:存儲響應數據,給一般用戶看的
3、Get和Post的區別?
回答:Get請求方式:地址欄里會顯示我們提交的數據(不安全),並且地址欄中支持提交少量數據,請求的數據存在請求行中;
Post請求方式:地址欄里不顯示我們提交的數據信息(相對安全),可以提交大量數據,請求的數據存在請求正文中。

4、cookie和session的區別?
回答:共同點:cookie和session都是用來跟蹤瀏覽器用戶身份的會話方式;

區別:cookie數據保存在客戶端,保存數據不安全且存儲數據量有限;session數據保存在服務器端,保存數據安全且存儲數據量大,session是基於cookie進行信息處理的;

5、什么是ajax,為什么要使用ajax?
回答:Ajax是一種創建交互式網頁應用的網頁開發技術;Asynchronous JavaScript and XML的縮寫;

Ajax的優勢:1.通過異步模式,提升了用戶體驗;

2.優化了瀏覽器和服務器之間的傳輸,減少不必要的數據往返,減少了寬帶占用;

3.Ajax引擎在客戶端運行,承擔了一部分本來由服務器承擔的工作,從而減少了大用戶量下的服務器負載;

Ajax的最大特點:可以實現局部刷新,在不更新整個頁面的前提下維護數據,提升用戶體驗度。

注意:ajax在實際項目開發中使用率非常高(牢固掌握)。
6、淺談你對ajax的認識?
回答:同上(第5個問題)

7、Cookie和Session以及Servlet的生命周期?
回答:1.Cookie的生命周期是累計的,從創建時,就開始計時,20分鍾后,cookie生命周期結束。

2. Session的生命周期是間隔的,從創建時,開始計時如在20分鍾,沒有訪問session,那么session生命周期被銷毀;但是,如果在20分鍾內(如在第19分鍾時)訪問過session,那么將重新計算session的生命周期。注意:關機會造成session生命周期的結束,但是對cookie沒有影響。

3.init():在Servlet的生命周期中,僅執行一次init()方法。它是在服務器裝入Servlet時執行的,負責初始化Servlet對象。可以配置服務器,以在啟動服務器或客戶機首次訪問Servlet時裝入Servlet。無論有多少客戶機訪問Servlet,都不會重復執行init()。

service():它是Servlet的核心,負責響應客戶的請求。每當一個客戶請求一個HttpServlet對象,該對象的Service()方法就要調用,而且傳遞給這個方法一個”請求”(ServletRequest)對象和一個”響應”(ServletResponse)對象作為參數。在HttpServlet中已存在Service()方法。默認的服務功能是調用與HTTP請求的方法相應的do功能。

destroy():僅執行一次,在服務器端停止且卸載Servlet時執行該方法。當Servlet對象退出生命周期時,負責釋放占用的資源。一個Servlet在運行service()方法時可能會產生其他的線程,因此需要確認在調用destroy()方法時,這些線程已經終止或完成。

8、說一下你熟悉的常用linux命令?
回答:1.列出文件列表:ls

2.創建目錄和移除目錄:mkdir rmdir

3.用於顯示文件后幾行內容:tail

4.打包:tar -xvf

5.打包並壓縮:tar -zcvf

6.查找字符串:grep

7.顯示當前所在目錄:pwd

8.創建空文件:touch

9:編輯器:vim vi

9、后台傳過的json數據前台怎么接收?
回答:在前台可以使用js代碼接收,也可以通過ajax接收,也有專門的前端框架接收

10、后台傳過來一個集合前台怎么接收?
回答:使用el表達式或者ognl表達式,或者根據實際情況從域中取數據

 

數據庫:

1、MySQL的delete與truncate區別?

回答:delete語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作為事務記錄在日志中保存以便進行回滾操作,不清空AUTO_INCREMENT記錄數;

truncate則直接將表刪除並重新建表,不會把單獨的刪除操作記錄記入日志保存,刪除行是不能恢復的,AUTO_INCREMENT將置為0,效率比delete高。

2、MySQL的存儲過程是什么?
回答:存儲過程是一組為了完成特定功能的SQL語句集,經編譯后存儲在數據庫中,用戶通過指定存儲過程的名字並給定參數(如果該存儲過程帶有參數)來調用執行它;
創建存儲過程:”pr_add”是個簡單的MySQL存儲過程,這個MySQL存儲過程有兩個int類型的輸入參數”a”,”b”,返回這兩個參數的和。

1)drop procedure if exists pr_add;

2)計算兩個數之和

create procedure pr_add( a int , b int )begin declare c int;

if a is null then set a = 0;

end if;

if a is null then set b = 0;

end if;
set c = a+b;
select c as sum ; 

3、談談你對索引的理解?
回答:索引是對數據庫中一對多個列值的排序,幫助數據庫高效獲取數據的數據結構。假如我們用類比的方法,數據庫中的索引就相當於書籍中的目錄一樣,當我們想找到書中的某個知識點,我們可以直接去目錄中找而不是在書中每頁的找,但是這也拋出了索引的一個缺點,在對數據庫修改的時候要修改索引,導致時間變多。
索引分為:普通索引,唯一索引,主鍵索引,全文索引

優點:加快檢索速度;唯一索引確保每行數據的唯一性;在使用索引的過程可以優化隱藏器,提高系統性能

缺點:插入刪除,修改,維護速度下降;占用物理和數據空間;

4、簡單描述一下數據庫的事務?
回答:應用的場景:存在並發數據訪問時才需要事務
ACID四大特性:a)原子性:整個事務中的所有操作,要么全部完成,要么全部不完成,不可能停滯在中間的某個環節。任何一項操作的失敗都會導致整個事務的失敗;

b)一致性:在事務開始之前和事務結束之后,數據庫的完整性約束沒有被破壞;

c)隔離性:並發執行的事務彼此無法看到對方的中間狀態;

d)持久性:在事務完成以后,該事務所對數據庫所操作的更改便持久的保存在數據庫之中,並不會被回滾。

問題:a)臟讀:一個事務讀取到另一個事務未提交的數據

b)不可重復讀:一個事務中兩次查詢的數據不一致 -->一個事務讀到了另一個事務,已經提交數據(update 操作)

c)虛讀(幻讀):一個事務中兩次查詢的數據不一致 -->一個事務讀到了另一個事務,已經提交數據(insert 操作)
隔離級別:安全從低到高,性能從高到低;

a)讀未提交:也叫臟讀,是事務可以讀取其他事務未提交的數據。—>未解決任何問題

b)讀已提交:在事務未提交之前所做的修改其它事務是不可見的。—>解決臟讀問題

c)可重復讀:保證同一個事務中的多次相同的查詢的結果是一致的。—>解決臟讀,不可重復讀的問題

d)可串行化:保證讀取的范圍內沒有新的數據插入,比如事務第一次查詢得到某個范圍的數據,第二次查詢也同樣得到了相同范圍的數據,中間沒有新的數據插入到該范圍中。—>解決臟讀,不可重復讀,虛讀(幻讀)問題。


常用數據庫默認隔離級別:

MySQL:可重復讀;Oracle:讀已提交;SQLServe:讀已提交。r

5、Oracle是怎么樣分頁的?
回答:Oracle中使用rownum來進行分頁,這個是效率最好的分頁方法,hibernate也是使用rownum來進行Oracle分頁的;
select * from

(select round r,a from tabName where round <= 20)

where r > 10 

6、說說Oracle中經常使用到得函數?
回答:Length長度 、lower 小寫、upper 大寫、to_date 轉化日期、to_char 轉化字符,Ltrim 去左邊空格、substr 取字符串、add_month 增加或者減掉月份、to_number 轉變為數字
7、談談你對Oracle高水位的理解?
回答:所有的oracle段(segments,在此,為了理解方便,建議把segment作為表的一個同義詞) 都有一個在段內容納數據的上限,我們把這個上限稱為"high water mark"或HWM。這個HWM是一個標記,用來說明已經有多少沒有使用的數據塊分配給這個segment。HWM通常增長的幅度為一次5個數據塊,原則上HWM只會增大,不會縮小,即使將表中的數據全部刪除,HWM還是為原值,由於這個特點,使HWM很象一個水庫的歷史最高水位,這也就是HWM的原始含義,當然不能說一個水庫沒水了,就說該水庫的歷史最高水位為0。但是如果我們在表上使用了truncate命令,則該表的HWM會被重新置為0。
8、MySQL、Oracle、SqlServer三者之間的區別?
回答:
1. mysql
使用風險:SQL server 完全重寫代碼經歷了長期測試,需要時間來證明並十分兼容;
優點:
體積小、速度快、總體擁有成本低,開源;支持多種操作系統;是開源數據庫,提供的接口支持多種語言連接操作。

缺點:
不支持熱備份;
MySQL最大的缺點是其安全系統,主要是復雜而非標准,另外只有到調用mysqladmin來重讀用戶權限時才發生改變;
沒有一種存儲過程(Stored Procedure)語言,這是對習慣於企業級數據庫的程序員的最大限制;
MySQL的價格隨平台和安裝方式變化。Linux的MySQL如果由用戶自己或系統管理員而不是第三方安裝則是免費的,第三方案則必須付許可費。Unix或Linux 自行安裝 免費 、Unix或Linux 第三方安裝 收費;
2. oracle
優點:
開放性:Oracle 能在所有主流平台上運行(包括 windows)完全支持所有工業標准, 采用完全開放策略,使客戶選擇適合解決方案;
可伸縮性,並行性:Oracle 並行服務器通過使組結點共享同簇工作來擴展windownt能 力,提供高用性和高伸縮性簇解決方案。
安全性:獲得最高認證級別的ISO標准認證。 
性能:Oracle 性能高 保持開放平台下TPC-D和TPC-C世界記錄;
客戶端支持及應用模式:Oracle 多層次網絡計算支持多種工業標准用ODBC、JDBC、OCI 等網絡客戶連接 
使用風險:Oracle 長時間開發經驗完全向下兼容得廣泛應用地風險低 。
缺點:
對硬件的要求很高;
價格比較昂貴;
管理維護麻煩一些;
操作比較復雜,需要技術含量較高;
3. sqlserver
優點:
易用性、適合分布式組織的可伸縮性、用於決策支持的數據倉庫功能、與許多其他服 器軟件緊密關聯的集成性、良好的性價比等;
SQLServer是一個具備完全Web支持的數據庫產品,提供了對可擴展標記語言 (XML) 的核心支持以及在Internet上和防火牆外進行查詢的能力;
缺點:SQL Server 只能windows上運行,沒有絲毫開放性操作系統。
伸縮性並行性 :數據卷伸縮性有限;
安全性:沒有獲得任何安全證書。
性能 :SQL Server 多用戶時性能佳 ;
客戶端支持及應用模式: 客戶端支持及應用模式。只支持C/S模式,SQL Server C/S 結構只支持windows客戶用ADO、DAO、OLEDB、ODBC連接;

9、數據庫語句優化有哪些?


回答:1、對查詢進行優化,應盡量避免全表掃描,首先應考慮在where 及 order by 涉及的列上建立索引。
2、應盡量避免在where 字句中對字段進行null 值判斷,否則將導致引擎放棄使用索引二進行全表掃描。

3、應盡量避免在where 字句中使用or 來連接條件,否則將導致引擎放棄使用索引二進行全表掃描。

4、應盡量避免在where字句中使用!=或<>操作符,否則引擎將放棄使用索引二進行全表掃描。

5、in 和 not in 也要慎用,否則會導致全表掃描。

6、索引並不是越多越好,索引固然可以提高相應的select 的效率,但同時也降低了 insert 及 update 的效率,因為insert 或update時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常用到的列上建的索引是否有必要。

7、查詢結果不要用 * 來查詢所有字段,要明確指明結果字段。

8、根據查詢條件,簡歷索引,如果查詢條件不止一個時,使用組合索引。

9、在查詢條件表達式的左側盡量不要使用函數,否則索引失效。

10、如果有like話,盡量避免%xxx%兩側都有%的條件,單側%可以使用索引,多側不可以。

11、建立索引時字段不能有null值


10、MySQL數據庫優化有哪些?

回答:1. EXPLAIN 你的 SELECT 查詢;2. 當只要一行數據時使用 LIMIT 1;3. 使用 ENUM 而不是 VARCHAR;4. 固定長度的表會更快;5. 分庫分表


11、Oracle數據庫優化有哪些?


回答:1、調整數據結構的設計。2、調整操作系統參數。3、調整應用程序結構設計。4、調整數據庫SQL語句。5、調整服務器內存分配。6、調整硬盤I/O。

 

框架:

1、談談對spring框架的了解 ,spring有什么作用(IOC,AOP),spring的核心是什么?
回答:Spring是一個開源框架,它是為了解決企業應用開發的復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為 J2EE 應用程序開發提供集成的框架。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限於服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。簡單來說,Spring是一個分層的JavaSE/EE full-stack(一站式) 輕量級開源框架。
Spring的核心是控制反轉(IoC)和面向切面(AOP)。

  Spring的作用:1)方便解耦,簡化開發:通過Spring提供的IOC容器,我們可以將對象之間的依賴關系交由Spring進行控制,避免編碼所造成的過度程序耦合。有了Spring,用戶不必再為單例模式類、屬性文件解析等這些很多底層的需求編寫代碼,可以更專注於上層的應用。
2)AOP編程的支持:通過Spring提供的AOP功能,方便進行面向切面的編程,許多不容易用傳統OOP實現的功能可以通過AOP輕松應付。

3)聲明式事務的支持:在Spring中,我們可以從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活地進行事務的管理,提供開發效率和質量。

4)方便程序的測試:可以用非容器依賴的編程方式進行幾乎所有的測試工作,在Spring里,測試不再是昂貴的操作,而是隨手可做的事情。例如:Spring對Junit4支持,可以通過注解方便的測試Spring程序。

5)方便集成各種優秀框架:Spring不排斥各種優秀的開源框架,相反,Spring可以降低各種框架的使用難度,Spring提供了對各種優秀框架的直接支持。

6)降低Java EE API的使用難度:Spring對很多難用的Java EE API 提供了一個薄薄的封裝層,通過Spring的簡易封裝,這些Java EE API的使用難度大為降低。
注:Spring的源碼設計精巧、結構清晰、匠心獨運,處處體現着大師對Java設計模式靈活運用以及Java技術的高深造詣。Spring框架源碼無疑是Java技術的最佳實踐范例。如果想在短時間內迅速提高自己的Java技術水平和應用開發水平,學習和研究Spring源碼將會使你收到意想不到的效果。




2、SpringMVC的常用注解,執行流程,都有哪幾種解析器,必須要返回modelAndView么,SpringMVC接收一個json數據時怎么處理的,用什么注解?
回答:SpringMVC常用注解:1)@Controller 用於標記在一個類上,使用它標記的類就是一個SpringMVC Controller對象。
2)@RequestMapping 是一個用來處理請求地址映射的注解,可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。

3)@Resource和@Autowired 兩者都是做bean的注入時使用,其實@Resource並不是Spring的注解,它的包是java.annotation.Resource,需要導入,但是Spring支持該注解的注入。@Autowired為Spring提供的注解,需要導入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

4)@PathVariable 用於將請求URL中的模板變量映射到功能處理方法的參數上,即取出uri模板中的變量作為參數。

5)@Cookie 用來獲取Cookie中的值。

6)@RequestParam 用於將請求參數區數據映射到功能處理方法的參數上。

7)@SessionAttrbutes 即將值放到session作用域中,寫在class上面;除了可以通過屬性名指定需要放到會話中的屬性外(value 屬性值),還可以通過模型屬性的對象類型指定哪些模型屬性需要放到會話中(types 屬性值)。

8)@ModelAttribute 代表的是:該Controller的所有方法在調用前,先執行此@ModelAttribute方法,可用於注解和方法參數中,可以把這個@ModelAttribute特性,應用在BaseController當中,所有的Controller繼承BaseController,即可實現在調用Controller時,先執行@ModelAttribute方法。
9)@ResponseBody 該注解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式后,寫入到Response對象的body數據區;返回數據不是html標簽的頁面,而是其他某種格式的數據時(如son、xml等)使用。
10)@RequestBody 該用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然后把相應的數據綁定到要返回的對象上;再把HttpMessageConverter返回的對象數據綁定到controller中方法的參數上。
SpringMVC的執行流程:



常用的視圖解析器:(AbstractCachingViewResolver、UrlBasedViewResolver、XmlViewResolver、BeanNameViewResolver、ResourceBundleViewResolver、FreeMarkerViewResolver、VolocityViewResolver)
必須要返回modelAndView么,SpringMVC接收一個json數據時怎么處理的,用什么注解?

不是,使用@ResponseBody把后台pojo轉換json對象,返回到頁面;@RequestBody接受前台json,把json數據自動封裝pojo。


3、Spring 依賴注入的幾種方式?
回答:Spring常用的依賴注入方式是:Setter方法注入、構造器注入、Filed注入(用於注解方式);
1)Setter方法注入:首先要配置被注入的bean,在該bean對應的類中,應該有要注入的對象屬性或者基本數據類型的屬性。

2)構造器注入:在PersonBiz類中注入PersonDAO和一個String類型的數據;在該類中,不用為PersonDAO屬性和String數據類型的屬性設置setter方法,但是需要生成該類的構造方法;在配置文件中配置該類的bean,並配置構造器,在配置構造器中用到了<constructor-arg>節點。

3)Filed注入(用於注解方式):在spring中,注入依賴對象可以采用手工裝配或自動裝配,在實際應用開發中建議使用手工裝配,因為自動裝配會產生許多未知情況,開發人員無法預見最終的裝配結果。


4、Spring設置為單例 ,那么線程安全問題怎么解決?
回答:首先了解一下在什么情況下,單例的Bean對象存在線程安全問題,當Bean對象對應的類存在可變的成員變量並且其中存在改變這個變量的線程時,多線程操作該Bean對象時會出現線程安全;產生的原因是當多線程中存在線程改變了bean對象的可變成員變量時,其他線程無法訪問該bean對象的初始狀態,從而造成數據錯亂;
解決辦法:1)在Bean對象中盡量避免定義可變的成員變量;2)在Bean對象中定義一個ThreadLocal成員變量,將需要的可變成員變量保存在ThreadLocal中。


5、 Struts2 和SpringMVC的區別 ?
回答:1)Struts2是類級別上的攔截,一個Action對應一個request上下文,SpringMVC是方法級別的攔截,一個方法對應一個request上下文;而且Struts2過濾后是去Struts2配置文件中Action,而SpringMVC過濾后是去Controller中找對應於@RequestMapping注解的uri綁定的方法,從這里看Struts2使用起來更麻煩,因為你要每個類的請求你都要配置對應的攔截器。
2)因為攔截器的原因,導致Struts2的action比較亂,因為它要定義屬性來獲取請求中參數的數據,而屬性在一個類的方法間是共享的(方法間不能獨享request、response數據),所以會有點亂;SpringMVC方法之間基本獨立,獨享request、response之間的數據。請求數據通過參數獲取,處理結果通過model Map交回給框架(方法間不共享變量)。

3)SpringMVC集成了Ajax,使用非常方便,只需要一個注解@ResponseBody就可以實現,然后直接返回響應文本即可,而Struts2攔截器集成了Ajax,在Action中處理時一般必須安裝插件或者自己寫代碼集成進去,使用起來也相對不方便。



6、Struts2可以是單例的嗎 為什么?
回答:Struts2的Action是多例模式的,也就是每次請求產生一個Action的對象,但是通過spring可以控制成單例,控制成單例的話,可以減少內存的消耗,因為可以保存action不被銷毀,但不保證這些數據在多線程的環境下不被相互影響。
7、什么是有狀態對象,什么是無狀態對象?
回答:1)有狀態對象,多線程環境下不安全,那么適合用Prototype原型模式。Prototype: 每次對bean的請求都會創建一個新的bean實例;
2)無狀態對象(Stateless Bean),就是沒有實例變量的對象,不能保存數據,是不變類,是線程安全的。


8、Spring的常用注解?
回答:@Controller:標記於一個類上面;用來注解這個bean(類)是MVC模型中的一個控制層,使分發處理器識別到該類,該類會被spring的auto-scan掃到納入管理。
@RequestMapping:標記於一個被@Controller標注的類上;標記於被@Controller標注類里面的方法上面;表示該被標注類下面所有方法的父類標注。

@Service:用於標注業務層組件上;標注與業務層組件上表示定義一個bean,自動根據所標注的組件名稱實例化一個首字母為小寫的bean。

@Resource:標注於字段上或者setter方法上,@Resource默認按ByName進行自動裝配;用來自動裝配Bean,激活一個命名資源的依賴注入,@Resource屬性name可以定義被自動裝配Bean的名稱。

@Autowired:與@Resource的用法和作用基本一致;@Resource屬於J2EE,@Autowired屬於Spring;@Autowired是根據類型(ByType)進行自動裝配的;@Autowired沒有name屬性,如果要按名稱進行裝配,需要配合@Qualifier使用。

@Repository:是用戶標注數據訪問層組件(DAO層);實現DAO訪問,將類識別為Bean,同時它將所標注的類中拋出的數據訪問異常封裝為Spring的數據訪問異常類型。

@Component:泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注;和前面@Service、@Repository、@Controller一樣,只是它們比@Component更細化。

9、報表用的什么生成圖表?
回答:1)JFreeChart :.jfree.org/jfreechart/
2)ECharts:

3) jCharts:.sourceforge.net/

4)DynamicReports:.dynamicreports.org/

5)JChartLib:http://sourceforge.net/projects/jchartlib/

6)SWTChart:.swtchart.org/

以上JAVA常用的生成圖表工具。



10、Spring 是如何管理事務的?
回答:Spring的事務機制包括聲明式事務和編程式事務;編程式事務管理(Spring推薦使用TransactionTemplate,實際開發中使用聲明式事務較多);聲明式事務管理(將我們從復雜的事務處理中解脫出來,獲取連接,關閉連接,事務提交、回滾、異常處理等這些操作都不用我們處理了,Spring都會幫我們處理;使用了AOP面向切面編程實現的,本質就是在目標方法執行前后進行攔截。在目標方法執行前加入或創建一個事務,在執行方法執行后,根據實際情況選擇提交或是回滾事務。)
Spring事務管理主要包括3個接口,Spring的事務主要由它們三個共同完成的。

1)PlatformTransactionManager:事務管理器(主要用於平台相關事務的管理),主要有三個方法(commit 事務提交;rollback 事務回滾;getTransaction 獲取事務狀態);

2)TransactionDefinition:事務定義信息(用來定義事務相關的屬性,給事務管理器PlatformTransactionManager使用),主要有四個方法(getIsolationLevel 獲取隔離級別、getPropagationBehavior 獲取傳播行為、getTimeout 獲取超時時間、isReadOnly 是否只讀);

3)TransactionStatus:事務具體運行狀態(事務管理過程中,每個時間點事務的狀態信息)。

聲明式事務:優點(不需要在業務邏輯代碼中編寫事務相關代碼,只需要在配置文件配置或使用注解(@Transaction),這種方式沒有入侵性);
缺點(聲明式事務的最細粒度作用於方法上,如果像代碼塊也有事務需求,只能變通下,將代碼塊變為方法)。

11、簡單說說你知道的spring的底層?
回答:1)Spring對Bean進行實例化(相當於程序中的new Xx())
2)Spring將值和Bean的引用注入進Bean對應的屬性中
3)如果Bean實現了BeanNameAware接口,Spring將Bean的ID傳遞給setBeanName()方法(實現BeanNameAware清主要是為了通過Bean的引用來獲得Bean的ID,一般業務中是很少有用到Bean的ID的)
4)如果Bean實現了BeanFactoryAware接口,Spring將調用setBeanDactory(BeanFactory bf)方法並把BeanFactory容器實例作為參數傳入。(實現BeanFactoryAware 主要目的是為了獲取Spring容器,如Bean通過Spring容器發布事件等)
5)如果Bean實現了ApplicationContextAwaer接口,Spring容器將調用setApplicationContext(ApplicationContext ctx)方法,把y應用上下文作為參數傳入.(作用與BeanFactory類似都是為了獲取Spring容器,不同的是Spring容器在調用setApplicationContext方法時會把它自己作為setApplicationContext 的參數傳入,而Spring容器在調用setBeanDactory前需要程序員自己指定(注入)setBeanDactory里的參數BeanFactory )
6)如果Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessBeforeInitialization(預初始化)方法(作用是在Bean實例創建成功后對進行增強處理,如對Bean進行修改,增加某個功能)
7)如果Bean實現了InitializingBean接口,Spring將調用它們的afterPropertiesSet方法,作用與在配置文件中對Bean使用init-method聲明初始化的作用一樣,都是在Bean的全部屬性設置成功后執行的初始化方法。
8)如果Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessAfterInitialization(后初始化)方法(作用與6的一樣,只不過6是在Bean初始化前執行的,而這個是在Bean初始化后執行的,時機不同)
9)經過以上的工作后,Bean將一直駐留在應用上下文中給應用使用,直到應用上下文被銷毀
10)如果Bean實現了DispostbleBean接口,Spring將調用它的destory方法,作用與在配置文件中對Bean使用destory-method屬性的作用一樣,都是在Bean實例銷毀前執行的方法。

12、說說solr的底層 ?
回答:1) 索引過程:(1、有一系列被索引文件;2、被索引文件經過語法分析和語言處理形成一系列詞(Term);3、經過索引創建形成詞典和反向索引表;4、通過索引存儲將索引寫入硬盤。)
2)搜索過程:(1、用戶輸入查詢語句;2、 對查詢語句經過語法分析和語言分析得到一系列詞(Term);3、通過語法分析得到一個查詢樹;4、通過索引存儲將索引讀入到內存;5、利用查詢樹搜索索引,從而得到每個詞(Term)的文檔鏈表,對文檔鏈表進行交,差,並得到結果文檔;6、將搜索到的結果文檔對查詢的相關性進行排序;7、返回查詢結果給用戶。)
源碼實現:




13、Solr如何搭建,簡單介紹一下,你用的什么版本?
回答:solr-4.10.3搭建:1)下載solr-4.10.3版本,JDK需要1.7及以上版本;2)解壓solr-4.10.3;3)創建solr工程;4)部署到tomcat容器;5)新建solrCore,在此目錄下新建core2文件夾;6)查詢數據表數據;7)java通過solr查詢數據庫表。
詳細過程參考:


14、Mybatis和hibernate的區別?
回答:mybatis:1)入門簡單,即學即用,提供數據庫查詢的自動對象綁定功能,而且延續了很好的SQL使用經驗,對於沒有那么高的對象模型要求的項目來說,相當完美;
2)可以進行更為細致的SQL優化,可以減少查詢字段;

3)缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層數據庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速數據庫修改;

4)二級緩存機制不佳。

hibernate:1)功能強大,數據庫無關性好,O/R映射能力強,如果你對Hibernate相當精通,而且對Hibernate進行了適當的封裝,那么你的項目整個持久層代碼會相當簡單,需要寫的代碼很少,開發速度很快,非常爽;

2)有更好的二級緩存機制,可以使用第三方緩存;

3)缺點就是學習門檻不低,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何取得平衡,以及怎樣用好Hibernate方面需要你的經驗和能力都很強才行。


15、對於hibernate3,4,5有什么了解,其中的特性是什么?
回答:hibernate4中的新特性基於hibernate3中的改變:1)數據庫方言的設置(在3.3版本中連接MySQL數據庫只需要指明MySQLDialect即可。在4.1版本中可以指出MySQL5Dialect)
2)buildSessionFactory(4.1版本中buildSessionFactory()已經被buildSessionFactory(ServiceRegistry ServiceRegistry)取代)
3)annotation(4.1版本中推薦使用annotation配置,所以在引進jar包時把requested里面的包全部引進來就已經包含了annotation必須包了)
4)事務,hibernateTemplate(hibernate4已經完全可以實現事務了與spring3.1中的hibernatedao,hibernateTemplate等有沖突,所以spring3.1里已經不提供hibernatedaosupport,hibernateTemplate)
5)自動建表(hibernate4.1已經可以自動建表,所以開發時只需要自己開發類然后配置好久OK)
hibernate5的新特性:1)明確了關聯關系映射;2)明確Hibernate檢索優化;3)明確Hibernate緩存機制;4)明確Hibernate對事務並發控制的管理;5)明確Hibernate注解開發。


16、SpringMVC的底層是基於什么實現的?
回答:Spring MVC是基於servlet功能實現的,通過實現Servlet接口的DispatcherServlet來封裝其核心功能實現,通過將請求分派給處理程序,同時帶有可配置的處理程序映射、視圖解析、本地語言、主題解析以及上傳下載文件支持。

17、請羅列出您所理解的微服務架構應具有的關鍵組件及關鍵指標?
回答:1)負載平衡:Linkerd提供了多種負載均衡算法,它們使用實時性能指標來分配負載並減少整個應用程序的尾部延遲。
2)熔斷:Linkerd包含自動熔斷,將停止將流量發送到被認為不健康的實例,從而使他們有機會恢復並避免連鎖反應故障。
3)服務發現:Linkerd 與各種服務發現后端集成,通過刪除特定的(ad-hoc)服務發現實現來幫助您降低代碼的復雜性。
4)動態請求路由:Linkerd 啟用動態請求路由和重新路由,允許您使用最少量的配置來設置分段服務(staging service),金絲雀(canaries),藍綠部署(blue-green deploy),跨DC故障切換和黑暗流量(dark traffic)。
5)重試次數和截止日期:Linkerd可以在某些故障時自動重試請求,並且可以在指定的時間段之后讓請求超時。
6)TLS:Linkerd可以配置為使用TLS發送和接收請求,您可以使用它來加密跨主機邊界的通信,而不用修改現有的應用程序代碼。
7)HTTP代理集成:Linkerd可以作為HTTP代理,幾乎所有現代HTTP客戶端都廣泛支持,使其易於集成到現有應用程序中。
8)透明代理:您可以在主機上使用iptables規則,設置通過Linkerd的透明代理。
9)gRPC:Linkerd支持HTTP/2和TLS,允許它路由gRPC請求,支持高級RPC機制,如雙向流,流程控制和結構化數據負載。
10)分布式跟蹤:Linkerd支持分布式跟蹤和度量儀器,可以提供跨越所有服務的統一的可觀察性。
11)儀器儀表:Linkerd支持分布式跟蹤和度量儀器,可以提供跨越所有服務的統一的可觀察性。

18、hibernate的二級緩存有什么用?
回答:因為應用程序訪問數據庫,讀寫數據的代價非常高,而利用持久層的緩存可以減少應用程序與數據庫之間的交互,即把訪問過的數據保存到緩存中,應用程序再次訪問已經訪問過的數據,這些數據就可以從緩存中獲取,而不必再從數據庫中獲取。同時如果數據庫中的數據被修改或者刪除,那么是該數據所對應的緩存數據,也會被同步修改或刪除,進而保持緩存數據的一致性。

19、介紹一下mybatis?
回答:1)入門簡單,即學即用,提供數據庫查詢的自動對象綁定功能,而且延續了很好的SQL使用經驗,對於沒有那么高的對象模型要求的項目來說,相當完美;

2)二級緩存機制不佳。

3)可以進行更為細致的SQL優化,可以減少查詢字段;

4)缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層數據庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速數據庫修改;




20、 Shiro的原理?
回答:shiro是apache的一個開源框架,是一個權限管理的框架,實現用戶認證,用戶授權。spring中有spring security(原名Acegi),是一個權限框架,它和spring依賴過於緊密,沒有shiro使用簡單。shiro不依賴與spring,shiro不僅可以實現web應用的權限管理,還可以實現c/s系統,分布式系統權限管理,shiro屬於輕量級框架,越來越多的企業項目使用shiro。使用shiro實現系統的權限管理,有效提高開發效率,從而降低開發成本。
shiro架構有3個主要概念:Subject、SecurityManager、Realms。


1)Subject,正如我們在教程中所說,Subject其實代表的就是當前正在執行操作的用戶,只不過因為“User”一般指代人,但是一個“Subject”可以是人,也可以是任何的第三方系統,服務賬號等任何其他正在和當前系統交互的第三方軟件系統。
所有的Subject實例都被綁定到一個SecurityManager,如果你和一個Subject交互,所有的交互動作都會被轉換成Subject與SecurityManager的交互。

2)SecurityManager。SecurityManager是Shiro的核心,他主要用於協調Shiro內部各種安全組件,不過我們一般不用太關心SecurityManager,對於應用程序開發者來說,主要還是使用Subject的API來處理各種安全驗證邏輯。
3)Realm,這是用於連接Shiro和客戶系統的用戶數據的橋梁。一旦Shiro真正需要訪問各種安全相關的數據(比如使用用戶賬戶來做用戶身份驗證以及權限驗證)時,他總是通過調用系統配置的各種Realm來讀取數據。

正因為如此,Realm往往被看做是安全領域的DAO,他封裝了數據源連接相關的細節,將數據以Shiro需要的格式提供給Shiro。當我們配置Shiro的時候,我們至少需要配置一個Realm來提供用戶驗證和權限控制方面的數據。我們可能會給SecurityManager配置多個Realm,但是不管怎樣,我們至少需要配置一個。
Shiro提供了幾種開箱即用的Realm來訪問安全數據源,比如LDAP、關系數據庫、基於ini的安全配置文件等等,如果默認提供的這幾種Realm無法滿足你的需求,那么你也可以編寫自己的定制化的Realm插件。
和其他內部組件一樣,SecurityManager決定了在Shiro中如何使用Realm來讀取身份和權限方面的數據,然后組裝成Subject實例。


shiro詳細架構:




21、Webservice是什么,怎么用 ?
回答:從表面上看,WebService就是一個應用程序,它向外界暴露出一個能夠通過Web進行調用的API。這就是說,你能夠用編程的方法通過Web調用來實現某個功能的應用程序。從深層次上看,Web Service是一種新的Web應用程序分支,它們是自包含、自描述、模塊化的應用,可以在網絡(通常為Web)中被描述、發布、查找以及通過Web來調用;Web Service便是基於網絡的、分布式的模塊化組件,它執行特定的任務,遵守具體的技術規范,這些規范使得Web Service能與其他兼容的組件進行互操作。它可以使用標准的互聯網協議,像超文本傳輸協議HTTP和XML,將功能體現在互聯網和企業內部網上。WebService平台是一套標准,它定義了應用程序如何在Web上實現互操作性。你可以用你喜歡的任何語言,在你喜歡的任何平台上寫Web Service;WebService 為Internet 上的組件服務•通過網絡提供,以URL 定位方法調用•以Internet技術為基礎•未來的分散式應用程序。

第一步:創建一個Java項目
  第二步:創建一個類,加入Webservice注解
@WebService是jdk提供的一個注解,它位於javax.jws.*這個包中。
  第三步:創建一個方法
  第四步:在main方法中調用jdk提供的發布服務的方法
    通過EndPoint(端點服務)發布一個webService。
Endpoint也是jdk提供的一個專門用於發布服務的類,它的publish方法接收兩個參數,一個是本地的服務地址,二是提供服務的類。它位於javax.xml.ws.*包中。
static Endpoint.publish(String address, Object implementor) 在給定地址處針對指定的實現者對象創建並發布端點。
stop方法用於停止服務。
EndPoint發布完成服務以后,將會獨立的線程運行。所以,publish
之后的代碼,可以正常執行



22、solr存數據是不是要創建索引?
回答:要創建,存數據之前需要創建標簽並設置屬性,需要創建的索引必須在Schema里面有。

 

redis:

1、什么是Redis?


回答:Redis是一個基於內存的高性能key-value數據庫;
應用場景:1)會話緩存(Session Cache) 2)全頁緩存(FPC)3)隊列 4)排行榜/計數器 5)發布/訂閱

2、使用Redis有哪些好處?


回答:1)速度快,因為數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1);
2)支持豐富的數據類型,支持string,list,set,sorted set,hash;

3)支持事務,操作都是原子性,所謂的原子性就是對數據的更改要么全部執行,要么全部不執行;

4)豐富的特性:可用於緩存,消息,按key設置過期時間,過期后將會自動刪除;

3、Redis的特點?


回答:Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據flush到硬盤上進行保存。因為是純內存操作,Redis的性能非常出色,每秒可以處理超過10萬次讀寫操作,是已知性能最快的Key-Value DB.
Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像memcached只能保存1MB的數據,另外Redis也可以對存入的Key-Value設置expire時間。

Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上。

4、為什么Redis需要把所有數據放到內存中?


回答:Redis為了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特征。如果不將數據放在內存中,磁盤I/O速度會嚴重影響redis的性能。如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。


5、Redis常見的性能問題怎么解決?


回答:1) Master最好不要做任何持久化工作,如RDB內存快照和AOF日志文件;
2)如果數據比較重要,某個Slave開啟AOF備份數據,策略設置為每秒同步一次;

3) 為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個局域網內;
4)盡量避免在壓力很大的主庫上增加從庫;

5)主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3…;

這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

6、Redis與memcached有什么區別?


回答:1) memcached所有的值均是簡單的字符串,redis作為其替代者,支持更為豐富的數據類型;
2) redis的速度比memcached快很多;
3) redis可以持久化其數據;


7、Redis有哪些數據結構?


回答:常用的五種數據結構(string、list、set、hash、zset)

1)string :可以是字符串,整數或者浮點數,對整個字符串或者字符串中的一部分執行操作,對整個整數或者浮點執行自增(increment)或者自減(decrement)操作。

2)list:一個鏈表,鏈表上的每個節點都包含了一個字符串,蟲鏈表的兩端推入或者彈出元素,根據偏移量對鏈表進行修剪(trim),讀取單個或者多個元素,根據值查找或者移除元素。

3)set:包含字符串的無序收集器(unordered collection)、並且被包含的每個字符串都是獨一無二的。添加,獲取,移除單個元素,檢查一個元素是否存在於集合中,計算交集,並集,差集,從集合里面隨機獲取元素。

4)hash:包含鍵值對無序散列表,添加,獲取,移除當鍵值對,獲取所有鍵值對。

5)zset :字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定。添加,獲取,刪除單個元素,根據分值范圍(range)或者成員來獲取元素。

8、Redis持久化方案區別以及優缺點?


回答:redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。
RDB方式:是一種快照式的持久化方法,將某一時刻的數據持久化到磁盤中。

1)redis在進行數據持久化的過程中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,才會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時來進行備份,因為快照文件總是完整可用的。
2)對於RDB方式,redis會單獨創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操作的,這樣就確保了redis極高的性能。
3)如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
AOF方式:是將執行過的寫指令記錄下來,在數據恢復時按照叢前到后的順序再將指令執行一遍。
1)AOF命令以redis協議追加保存每次寫的操作到文件末尾.Redis還能對AOF文件進行后台重寫,使得AOF文件的體積不至於過大.默認的AOF持久化策略是每秒鍾fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),因為在這種情況下,redis仍然可以保持很好的處理性能,即使redis故障,也只會丟失最近1秒鍾的數據。
2)如果在追加日志時,恰好遇到磁盤空間滿、inode滿或斷電等情況導致日志寫入不完整,也沒有關系,redis提供了redis-check-aof工具,可以用來進行日志修復。
3)因為采用了追加方式,如果不做任何處理的話,AOF文件會變得越來越大,為此,redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,redis就會啟動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。舉個例子或許更形象,假如我們調用了100次INCR指令,在AOF文件中就要存儲100條指令,但這明顯是很低效的,完全可以把這100條指令合並成一條SET指令,這就是重寫機制的原理。
4)在進行AOF重寫時,仍然是采用先寫臨時文件,全部完成后再替換的流程,所以斷電、磁盤滿等問題都不會影響AOF文件的可用性。

9、如何來維護集群之間的關系,或者說集群之間如何建立連接?


回答:1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
2)節點的fail是通過集群中超過半數的節點檢測失效時才生效.
3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可
4)redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->value

10、Redis如何存取實體?


回答:存儲的時候需要將實體序列化,然后就可以當字符串一樣存儲,取數據時也一樣,取出來的數據需要反序列化。


11、Redis保留時間多久?


回答:如果未設置則一直存在,除非服務停掉且沒有保存到磁盤。如果已手動或自動保存過,則再次啟動服務還會存在。
EXPIRE <KEY> <TTL> : 將鍵的生存時間設為 ttl 秒
PEXPIRE <KEY> <TTL> :將鍵的生存時間設為 ttl 毫秒
EXPIREAT <KEY> <timestamp> :將鍵的過期時間設為 timestamp 所指定的秒數時間戳
PEXPIREAT <KEY> <timestamp>: 將鍵的過期時間設為 timestamp 所指定的毫秒數時間戳.


12、Redis掛掉后怎么辦?介紹Redis是怎么實現高可用的?


回答:主要取決於,你是把redis作為緩存還是nosql,如果是緩存那丟了也無所謂,從別的地方恢復重建就行了,如果是nosql的話,redis是有snapshot和aof的機制來保證數據持久化的。
高可用實現流程:


13、Redis有事務嗎,簡單的說一下?


回答:1) 開啟:以MULTI開始一個事務
2) 入隊:將多個命令入隊到事務中,找到這些命令並不會立即執行,而是放到等待執行事務隊列里面
3) 執行:由EXEC命令觸發事務
三個特性:單獨的隔離操作:事務的所有命令都會序列化、按順序地實行
沒有隔離級別的概念:事務提交前任何指令都不會被實際執行
不保證原子性:redis同一個事務中如果有一條命令執行失敗,其后的命令仍然會被執行,不回滾


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM