Java面試題 -其他框架

1. 描述⼀下Hibernate的三個狀態?

a. transient(瞬時狀態):new出來⼀個對象,還沒被保存到數據庫中
b. persistent(持久化狀態):對象已經保存到數據庫中並且在hibernate session也存在該對象
c. detached(離線狀態):對象在數據庫中存在,hibernate session不存在

2. struts⼯作流程

在這裏插入圖片描述
1、客戶端瀏覽器發出HTTP請求。
2、根據web.xml配置,該請求被FilterDispatcher接收。
3、根據struts.xml配置,找到需要調⽤的Action類和⽅法, 並通過IoC⽅式,將值注⼊給Aciton。
4、Action調⽤業務邏輯組件處理業務邏輯,這⼀步包含表單驗證。
5、Action執⾏完畢,根據struts.xml中的配置找到對應的返回結果result,並跳轉到相應⻚⾯。
6、返回HTTP響應到客戶端瀏覽器。

3. Hibernate對⼀⼆級緩存的使⽤, Lazy-Load的理解

a. ⼀級緩存:hibernate的⼀級緩存是由session提供的,因此它只存在session的⽣命週期中。也就是說session關閉的時候該session所管理的⼀級緩存也隨之被清除。hibernate的⼀級緩存是session所內置的,默認開啓,不能被卸載,也不能進⾏任何配置。在緩存中的對象,具有持久性,session對象負責管理.⼀級緩存的優點是使⽤同⼀個session對象多次查詢
同⼀個數據對象,僅對數據庫查詢⼀次。⼀級緩存採⽤的是Key-Value的MAP⽅式來實現的。在緩存實體對象時,對象的主關鍵字ID是MAP的Key,實體對象就是對象的值。所以說⼀級緩存是以實體對象爲單位進⾏存儲的。訪問的時候使⽤的是主鍵關鍵字ID。⼀級緩存使⽤的是⾃動維護的功能。但可以通過session提供的⼿動⽅法對⼀級緩存的管理進⾏⼿動⼲預。evict()⽅法⽤於將某個對象從session的⼀級緩存中清除。clear()⽅法⽤於將session緩存中的⽅法全部清除。

b. ⼆級緩存:⼆級緩存的實現原理與⼀級緩存是⼀樣的。也是通過Key-Value的Map來實現對對象的緩存。⼆級緩存是作⽤在SessionFactory範圍內的。因此它可被所有的Session對象所共享。需要注意的是放⼊緩存中的數據不能有第三⽅的應⽤對數據進⾏修改。⼆級緩存默認關閉,需要程序員⼿動開啓,默認爲ehcache實現.

c. 懶加載:當⽤到數據的時候才向數據庫查詢,這就是hibernate的懶加載特性。延遲加載策略能避免加載應⽤程序不需要訪問的關聯對象,以提⾼應⽤程序的性能。

4. mybatis如何實現批量提交?

a. 通過標籤:

insert into sys_user_role
	( `user_id`, `role_id`) 
values
<foreach collection="roleIdList" item="item" index="index" separator=","> 
	(  #{userId}, #{item} )
</foreach>

b. 通過ExecutorType.BATCH:
在這裏插入圖片描述

5. session機制?

  1. session是服務器的⽣成,並傳⾄客戶端瀏覽器,後續請求,都會通過URL重寫傳⾄服務器進⾏session⽐較.
  2. session是基於cookie
  3. session可以保存⽤戶信息,但cookie如果瀏覽器被禁⽤,則⽆法保存⽤戶信息
  4. 如果瀏覽器禁⽤會話cookie,則每次請求都⽆法將第⼀次請求獲得的sessionId傳⾄後臺服務器.所以每次請求刷新⻚⾯服務器都會⽣成新的sessionid給到瀏覽器
  5. 因HTTP協議爲⽆狀態的協議(⼀旦數據交互完畢,客戶端和服務端的連接就會關閉,再次交換數據時需要建⽴新的連接),需要通過session或者cookie保存和跟蹤⽤戶信息
  6. sessionID放在瀏覽器客戶端cookie,其它信息放在服務器內存中,也可以做持久化管理memcached、redis中;

6. Struts2表單重複提交問題(token攔截器)

  1. 訪問⻚⾯前保存token(服務器後臺⽣成的⼀串序列時間串放到session中),並傳⾄前臺jsp⻚⾯中的隱藏域

  2. 提交時驗證token,將前臺的隱藏的token傳⾄後臺進⾏驗證是否⼀致,提交隨機⽣成新的token,可以防⽌重複提交;

7.Shiro

定義:
apache shiro是java的⼀個安全框架,簡單易⽤,基本功能有:認證、授權、加密、會話管理、與Web集成、緩存等。Shiro不會去維護⽤戶、維護權限;這些需要我們⾃⼰去設計/提供;然後通過相應的接⼝注⼊給Shiro即可(五張表)。

功能點:
在這裏插入圖片描述
Authentication:身份認證/登錄,驗證⽤戶是不是擁有相應的身份;
Authorization:授權,即權限驗證,驗證某個已認證的⽤戶是否擁有某個權限;即判斷⽤戶是否能做事情,常⻅的如:驗證某個⽤戶是否擁有某個⻆⾊。或者細粒度的驗證某個⽤戶對某個資源是否具有某個權限;
Session Manager:會話管理,即⽤戶登錄後就是⼀次會話,在沒有退出之前,它的所有信息都在會話中;會話可以是普通JavaSE環境的,也可以是如Web環境的;
Cryptography:加密,保護數據的安全性,如密碼加密存儲到數據庫,⽽不是明⽂存儲;
Web Support:Web⽀持,可以⾮常容易的集成到Web環境;
Caching:緩存,⽐如⽤戶登錄後,其⽤戶信息、擁有的⻆⾊/權限不必每次去查,這樣可以提⾼效率;
Concurrency:shiro⽀持多線程應⽤的併發驗證,即如在⼀個線程中開啓另⼀個線程,能把權限⾃動傳播過去;
Testing:提供測試⽀持;
Run As:允許⼀個⽤戶假裝爲另⼀個⽤戶(如果他們允許)的身份進⾏訪問;
Remember Me:記住我,這個是⾮常常⻅的功能,即⼀次登錄後,下次再來的話不⽤登錄了。

⼯作流程:

  1. 應⽤代碼通過Subject(主體,代表當前”⽤戶")來進⾏認證和授權,⽽Subject⼜委託給SecurityManager(安全管理器,shiro核⼼);
  2. 我們需要給Shiro的SecurityManager注⼊Realm(域,Shiro從Realm獲取安全數據(如⽤戶、⻆⾊、權限)),從⽽讓SecurityManager能得到合法的⽤戶及其權限進⾏判斷。

8. Tomcat Filter過濾器責任鏈模式,過濾器攔截器區別?

責任鏈模式

  • 將⼀個事件處理流程分派到⼀組執⾏對象上去,這⼀組執⾏對象形成⼀個鏈式結構,事件處理請求在這⼀組執⾏對象上進⾏傳遞。

過濾器和攔截器

  1. 過濾器filter:是在java web中,你傳⼊的request,response提前過濾掉⼀些信息,或者提前設置⼀些參數,然後再傳⼊servlet或者struts的 action進⾏業務邏輯,⽐如過濾掉⾮法url(不是login.do的地址請求,如果⽤戶沒有登陸都過濾掉),或者在傳⼊servlet或者 struts的action前統⼀設置字符集,或者去除掉⼀些⾮法字符;
  2. 攔截器interceptor:是在⾯向切⾯編程的就是在你的service或者⼀個⽅法,前調⽤⼀個⽅法,或者在⽅法後調⽤⼀個⽅法⽐如動態代理就是攔截器的簡單實現,在你調⽤⽅法前打印出字符串(或者做其它業務邏輯的操作),也可以在你調⽤⽅法後打印出字符串,甚⾄在你拋出異常的時候做業務邏輯的操作。攔截是AOP的⼀種實現策略;

區別:

a. 攔截器是基於java的反射機制的,⽽過濾器是基於函數回調。
b. 攔截器不依賴於servlet容器,過濾器依賴與servlet容器。
c. 攔截器只能對action請求起作⽤,⽽過濾器則可以對⼏乎所有的請求起作⽤。
d. 攔截器可以訪問action上下⽂、值棧⾥的對象,⽽過濾器不能訪問。
e. 在action的⽣命週期中,攔截器可以多次被調⽤,⽽過濾器只能在容器初始化時被調⽤⼀次。

9. Git與Svn的區別

1、Git是分佈式的,⽽Svn不是;
2、GIT把內容按元數據⽅式存儲,⽽SVN是按⽂件
3、分⽀不同:git分⽀切換很⽅便;svn分⽀就是版本庫的另外⼀個⽬錄;
4、GIT沒有⼀個全局的版本號,⽽svn有,SVN的版本號實際是任何⼀個相應時間的源代碼快照。
5、GIT的內容完整性要優於SVN(GIT的內容存儲使⽤的是SHA-1哈希算法。這能確保代碼內容的完整性,確保在遇到磁盤故障和⽹絡問題時降低對版本庫的破壞。)

10. Git命令底層原理:

1.git init:使⽤git init初始化⼀個新的⽬錄時,會⽣成⼀個.git的⽬錄,該⽬錄即爲本地倉庫。⼀個新初始化的本地倉庫是這樣的:
在這裏插入圖片描述

  • description⽤於GitWeb程序
  • config配置特定於該倉庫的設置(還記得git config的三個配置級別麼)
  • hooks放置客戶端或服務端的hook腳本
  • HEAD傳說中的HEAD指針,指明當前處於哪個分⽀
  • objectsGit對象存儲⽬錄
  • refsGit引⽤存儲⽬錄
  • branches放置分⽀引⽤的⽬錄

其中description、config和hooks這些不在討論中,後⽂會直接忽略。

git add:Git commit之前先要通過git add添加⽂件:
在這裏插入圖片描述
可以看到,多了⼀個index⽂件。並且在objects⽬錄下多了⼀個9f的⽬錄,其中多了⼀個
4d96d5b00d98959ea9960f069585ce42b1349a⽂件。其實9f4d96d5b00d98959ea9960f069585ce42b1349a就是⼀個Git對象,稱爲blob對象。

git commit:
在這裏插入圖片描述

11. JSP的執⾏過程:

  1. 客戶端發出請求。
  2. Web容器將JSP轉譯成Servlet源代碼。
  3. Web容器將產⽣的源代碼進⾏編譯。
  4. Web容器加載編譯後的代碼並執⾏。
  5. 把執⾏結果響應⾄客戶端。

12. ZK⾼可⽤

  • ZooKeeper 運⾏期間,集羣中⾄少有過半的機器保存了最新數據。集羣超過半數的機器能夠正常⼯作,集羣就能夠對外提供服務。

13. zookeeper有什麼功能,選舉算法如何進⾏?

選舉算法 (Fast Leader(領導者選舉)選舉算法):

  1. server啓動時默認選舉⾃⼰,並向整個集羣⼴播
  2. 收到消息時,通過3層判斷:選舉輪數,zxid,server id⼤⼩判斷是否同意對⽅,如果同意,則修改⾃⼰的選票,並向集羣⼴播
  3. QuorumCnxManager負責IO處理,每2個server建⽴⼀個連接,只允許id⼤的server連id⼩的server,每個server啓動單獨的讀寫線程處理,使⽤阻塞IO
  4. 默認超過半數機器同意時,則選舉成功,修改⾃身狀態爲LEADING或FOLLOWING
  5. Obserer機器不參與選舉

原理:

  • 選舉結果的影響權重關係是:⾸先看數據id,數據id⼤者勝出;其次再判斷leader id,leader id⼤者勝出。

舉例:

假設有五臺服務器組成的zookeeper集羣,它們的id從1-5,同時它們都是最新啓動的,也就是沒有歷史數據,在存放數據量這⼀點上,都是⼀樣的.假設這些服務器依序啓動,來看看會發⽣什麼?

  1. 服務器1啓動,此時只有它⼀臺服務器啓動了,它發出去的報沒有任何響應,所以它的選舉狀態⼀直是LOOKING狀態;
  2. 服務器2啓動,它與最開始啓動的服務器1進⾏通信,互相交換⾃⼰的選舉結果,由於兩者都沒有歷史數據,所以id值較⼤的服務器2勝出,但是由於沒有達到超過半數以上的服務器都同意選舉它(這個例⼦中的半數以上是3),所以服務器1,2還是繼續保持LOOKING狀態.
  3. 服務器3啓動,根據前⾯的理論分析,服務器3成爲服務器1,2,3中的⽼⼤,⽽與上⾯不同的是,此時有三臺服務器選舉了它,所以它成爲了這次選舉的leader.
  4. 服務器4啓動,根據前⾯的分析,理論上服務器4應該是服務器1,2,3,4中最⼤的,但是由於前⾯已經有半數以上的服務器選舉了服務器3,所以它只能接收當⼩弟的命了.
  5. 服務器5啓動,同4⼀樣,當⼩弟.

4、zookeeper管理員指南:

  • 集羣中過半存活即可⽤,故集羣選擇奇數臺機器;

14. RPC、RMI、MQ、SOAP

RPC:遠程過程調⽤協議,採⽤C/S模式,分佈式跨語⾔平臺,更多⽤於同步調⽤,⽐如Web Service(SOAP);

RMI:遠程⽅法調⽤,依賴於java遠程消息交換協議,要求服務端與客戶端都爲java編寫;每個⽅法都具有⽅法簽名,只有簽名匹配纔可以調⽤,返回值是基本類型和對象;

MQ:隊列,更多⽤於異步傳輸;

SOAP:最主要的⼯作是使⽤標準的XML描述了RPC的請求信息(URI/類/⽅法/參數/返回值)。理論上,SOAP就是⼀段xml,你可以通過http,smtp等發送它(複製到軟盤上,叫快遞公司送去也⾏?),同樣SOAP也是跨語⾔的。

15. Netty⾼性能

  1. NIO異步⾮阻塞通信
  2. “零拷⻉”
  3. 內存池ByteBuf
  4. Netty提供了多種內存管理策略,通過在啓動輔助類中配置相關參數,可以實現差異化的定製。
  5. ⾼效的Reactor線程模型:Reactor單線程(多線程、主從)模型,指的是所有的IO操作都在同⼀個NIO線程上⾯完成
  6. 爲了儘可能提升性能,Netty採⽤了串⾏⽆鎖化設計,在IO線程內部進⾏串⾏操作,避免多線程競爭導致的性能下降。表⾯上看,串⾏化設計似乎CPU利⽤率不⾼,併發程度不夠。但是,通過調整NIO線程池的線程參數,可以同時啓動多個串⾏化的線程並⾏運⾏,這種局部⽆鎖化的串⾏線程設計相⽐⼀個隊列-多個⼯作線程模型性能更優。
  7. ⾼效的序列化框架。
  8. 靈活的TCP參數配置能⼒:合理設置TCP參數在某些場景下對於性能的提升可以起到顯著的效果,例如SO_RCVBUF和SO_SNDBUF。如果設置不當,對性能的影響是⾮常⼤的。

⾼效的併發編程:Netty的⾼效併發編程主要體現在如下⼏點:

  • volatile的⼤量、正確使⽤;
  • CAS和原⼦類的⼴泛使⽤;
  • 線程安全容器的使⽤;
  • 通過讀寫鎖提升併發性能。

16. 如何保證服務的冪等性?

概念:接⼝的冪等性實際上就是接⼝可重複調⽤,在調⽤⽅多次調⽤的情況下,接⼝最終得到的結果是⼀致的。有些接⼝可以天然的實現冪等性,⽐如查詢接⼝,對於查詢來說,你查詢⼀次和兩次,對於系統來說,沒有任何影響,查出的結果也是⼀樣。

GET冪等:值得注意,冪等性指的是作⽤於結果⽽⾮資源本身。怎麼理解呢?例如,這個HTTP GET⽅法可能會每次得到不同的返回內容,但並不影響資源。

POST⾮冪等:因爲它會對資源本身產⽣影響,每次調⽤都會有新的資源產⽣,因此不滿⾜冪等性。

如何保證冪等性

  1. 全局唯⼀id:如果使⽤全局唯⼀ID,就是根據業務的操作和內容⽣成⼀個全局ID,在執⾏操作前先根據這個全局唯⼀ID是否存在,來判斷這個操作是否已經執⾏。如果不存在則把全局ID,存儲到存儲系統中,⽐如數據庫、redis等。如果存在則表示該⽅法已經執⾏。從⼯程的⻆度來說,使⽤全局ID做冪等可以作爲⼀個業務的基礎的微服務存在,在很多的微服務中都會⽤到這樣的服務,在每個微服務中都完成這樣的功能,會存在⼯作量重複。另外打造⼀個⾼可靠的冪等服務還需要考慮很多問題,⽐如⼀臺機器雖然把全局ID先寫⼊了存儲,但是在寫⼊之後掛了,這就需要引⼊全局ID的超時機制。使⽤全局唯⼀ID是⼀個通⽤⽅案,可以⽀持插⼊、更新、刪除業務操作。但是這個⽅案看起來很美但是實現起來⽐較麻煩,下⾯的⽅案適⽤於特定的場景,但是實現起來⽐較簡單。

  2. 去重表:這種⽅法適⽤於在業務中有唯⼀標的插⼊場景中,⽐如在以上的⽀付場景中,如果⼀個訂單隻會⽀付⼀次,所以訂單ID可以作爲唯⼀標識。這時,我們就可以建⼀張去重表,並且把唯⼀標識作爲唯⼀索引,在我們實現時,把創建⽀付單據和寫⼊去重表,放在⼀個事務中,如果重複創建,數據庫會拋出唯⼀約束異常,操作就會回滾。

  3. 插⼊或更新:這種⽅法插⼊並且有唯⼀索引的情況,⽐如我們要關聯商品品類,其中商品的ID和品類的ID可以構成唯⼀索引,並且在數據表中也增加了唯⼀索引。這時就可以使⽤InsertOrUpdate操作。在mysql數據庫中如下:在這裏插入圖片描述

  4. 多版本控制:這種⽅法適合在更新的場景中,⽐如我們要更新商品的名字,這時我們就可以在更新的接⼝中增加⼀個版本號,來做冪等:在這裏插入圖片描述在實現時可以如下:在這裏插入圖片描述

  5. 、狀態機控制:這種⽅法適合在有狀態機流轉的情況下,⽐如就會訂單的創建和付款,訂單的付款肯定是在之前,這時我們可以通過在設計狀態字段時,使⽤int類型,並且通過值類型的⼤⼩來做冪等,⽐如訂單的創建爲0,付款成功爲100。付款失敗爲99在做狀態機更新時,我們就這可以這樣控制:在這裏插入圖片描述

17. zookeeper⼯作原理?

定義:zookeeper是⼀種爲分佈式應⽤所設計的⾼可⽤、⾼性能且⼀致的開源協調服務,它提供了⼀項基本服務:分佈式鎖服務。後來摸索出了其他使⽤⽅法:配置維護、組服務、分佈式消息隊列、分佈式通知/協調等。

特點:

  1. 能夠⽤在⼤型分佈式系統中;
  2. 具有⼀致性、可⽤性、容錯性,不會因爲⼀個節點的錯誤⽽崩潰;

⽤途:(⽤戶⼤型分佈式系統,作協調服務⻆⾊)

  1. 分佈式鎖應⽤:通過對集羣進⾏master選舉,來解決分佈式系統中的單點故障(⼀主n從,主掛全掛)。
  2. 協調服務;
  3. 註冊中⼼;

術語:

  • 數據結構Znode:zookeeper數據採⽤樹形層次結構,和標準⽂件系統⾮常相似,樹中每個節點被稱爲Znode;
  • 通知機制Watcher:zookeeper可以爲所有的讀操作(exists()、getChilden()及getData())設置watch,watch事件是⼀次性出發器,當watch的對象狀態發⽣改變時,將會觸發次對象上watch所對應的事件。watch事件將被異步的發送給客戶端,並且zookeeper爲watch機制提供了有序的⼀致性保證。

基本流程:(分佈式鎖應⽤場景)

  1. 傳統的⼀主n從分佈式系統,容易發⽣單點故障,傳統解決⽅式是增加⼀個備⽤節點,定期給主節點發送Ping包,主節點回復ack,但是如果⽹絡原因ack丟失,那麼會出現兩個主節點,造成數據混亂。
  2. zookeeper的引⼊可以管理兩個主節點,其中掛了⼀個,會將另外⼀個作爲新的主節點,掛的節點回來時擔任備⽤節點;

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

18. cap理論

概念:⼀個分佈式系統最多隻能同時滿⾜⼀致性(Consistency)、可⽤性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。

  • ⼀致性:更新操作成功並返回客戶端完成後,所有節點在同⼀時間的數據完全⼀致,所以,⼀致性,說的就是數據⼀致性。
  • 可⽤性:服務⼀直可⽤,⽽且是正常響應時間。
  • 分區容錯性:分佈式系統在遇到某節點或⽹絡分區故障的時候,仍然能夠對外提供滿⾜⼀致性和可⽤性的服務。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章