Java面試之技術框架

java貓發表於2019-01-03

Spring

簡介

Spring 是一種用來簡化企業級應用開發的開源框架,包括Spring Framework, Spring Data, Spring Security,Spring Boot,SpringMVC等。Spring 家族最核心的概念當屬 AOP 和 IoC,詳解見下節。其中 Spring 優點如下:

降低了元件之間的耦合性 ,實現了軟體各層之間的解耦

可以使用便捷的眾多服務,如事務管理,訊息服務等

容器提供了AOP技術,利用它很容易實現如許可權攔截,執行期監控等功能

Spring對於主流的應用框架提供了整合支援,如Hibernate、JPA等

Spring屬於低侵入式設計,程式碼的汙染極低

Spring的高度開放性,開發者可以自由選擇Spring的部分或全部

AOP和IOC

AOP(Aspect Oriented Programming,面向切面程式設計)

AOP簡單說就是在目標方法執行前後自定義一些操作,一般都是基於代理模式來實現的,Spring支援兩種代理模式,JDK原生代理和CGLib代理。AOP給程式帶來良好的擴充套件性和封裝性,可以實現業務程式碼與非業務程式碼的隔離。比如可以在不改變目的碼的前提下實現目標方法的增強:埋點業務處理、方法執行時間監控,列印日誌,許可權控制等等。

JDK動態代理是利用反射機制生成一個實現代理介面的匿名類,在呼叫具體方法前呼叫InvokeHandler來處理。只能對實現了介面的類生成代理。

CGLib動態代理是利用ASM開源包,對代理物件類的Class檔案載入進來,通過修改其位元組碼生成子類來處理。

切面(Aspect):類是對物體特徵的抽象,切面就是對橫切關注點的抽象。

切點(Pointcut):對連線點進行攔截的定義。

連線點(Joinpoint):被攔截到的點,比如方法(Spring中一般是方法)、欄位、構造器。

通知(Advice):指攔截到連線點後要執行的程式碼,通知分為前置、後置、異常、最終、環繞五類。

AOP:在執行時,動態地將程式碼切入到類的指定方法、指定位置上的程式設計思想

IoC(Inversion of Control,控制反轉)

IOC (Inversion of Control,控制反轉):物件之間的依賴關係由容器來建立。本來物件之間的關係是由開發者自己建立和維護的,在使用Spring框架後,物件之間的關係由容器來建立和維護,將開發者做的事讓容器做,這就是控制反轉。BeanFactory介面是Spring Ioc容器的核心介面

DI (Dependecy Injection,依賴注入):我們在使用Spring容器的時候,容器通過呼叫set方法或者是構造器來建立物件之間的依賴關係。注入方式有設值注入、構造注入、註解注入、介面注入(基本不用),設值注入直觀,自然;構造注入可以在構造器中決定依賴關係的順序。

控制反轉是目標,依賴注入是我們實現控制反轉的一種手段。

SpringMVC和Struts

SpringMVC執行流程如下:

客戶端向Spring容器發起一個HTTP請求。

發起的請求被前端控制器(DispatcherServlet)攔截。

查詢處理器對映(HandlerMapping)得到執行鏈,並請求相應的處理器介面卡(HandlerAdapter)。

執行處理器(Handler)並處理請求,以ModelAndView(屬性值和返回頁面)的形式返回。此處Handler即平時編寫的Controller。

前端控制器查詢檢視解析器(ViewResolver),並返回View。

成功渲染檢視則返回給客戶端,否則拋異常。

比較點SpringMVCStruts核心控制器DispatcherServletFilterDispatcher配置檔案量少(AOP)量大(Interceptor機制)RESTful API易實現(方法級別)實現費勁(類級別)處理Ajax請求@ResponseBody返回響應文字攔截器整合Ajax效能稍快稍慢

DispatcherServlet初始化流程如下:

載入配置檔案

掃描所有的相關類

初始化所有相關類的Class例項,並將其儲存到IoC容器

自動化的依賴注入(Autowired)

初始化HandlerMapping

Spring事務

資料庫事務是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。事務滿足原子性(Atomicity)一致性(Consistency)隔離性(Isolation)永續性(Durability) 四大特性。

事務隔離級別

資料讀的三類問題:

問題解釋髒讀事務 A 讀取了事務 B 未提交的資料(發現讀到的資料是髒資料)不可重複讀事務 A 讀取了事務 B 已提交的更改資料(發現與前一次讀的不一致)幻讀事務 A 讀取了事務 B 已提交的新增資料(發現之前沒有這條資料的)

事務的四種隔離級別見下表,MySQL預設為REPEATABLE_READ

隔離級別(簡寫)含義隱患READ_UNCOMMITTED允許讀未提交髒讀、不可重複讀、幻讀READ_COMMITTED允許讀已提交不可重複讀、幻讀REPEATABLE_READ允許重複讀幻讀SERIALIZABLE序列化讀–

事務管理

Spring事務管理器的介面是PlatformTransactionManager,通過這個介面,Spring為各個平臺如JDBC(DataSourceTransactionManager)、Hibernate(HibernateTransactionManager、JpaTransactionManager)等都提供了對應的事務管理器。

事務的傳播特性

當事務方法被另一個事務方法呼叫時,必須指定事務應該如何傳播,根據如下程式碼中方法 A 有無事務,Spring定義了7種傳播行為(預設為REQUIRED):

@Transactionalvoid A(){ }@Transactionalvoid B(){A(); }

傳播行為(簡寫)含義REQUIRED如果沒有,就開啟一個事務;如果有,就加入當前事務(方法A加入到方法B)REQUIRES_NEW如果沒有,就開啟一個事務;如果有,就將當前事務掛起NESTED如果沒有,就開啟一個事務;如果有,就在當前事務中巢狀其他事務(主事務提交或回滾,子事務也會提交或回滾)SUPPORTS如果沒有,就以非事務方式執行;如果有,就使用當前事務NOT_SUPPORTED如果沒有,就以非事務方式執行;如果有,就將當前事務掛起NEVER如果沒有,就以非事務方式執行;如果有,就丟擲異常MANDATORY如果沒有,就丟擲異常;如果有,就使用當前事務

Spring Boot

Spring Boot來自於 Spring 大家族,是一套全新的框架,它預設幫我們進行了很多配置,整合了大量常用的第三方庫(例如 Jackson、JDBC、MongoDB、Redis、Mail 等),這些第三方庫幾乎都可以開箱即用。Spring Boot可以幫助我們快速搭建一個專案,從而讓開發者能夠更加專注於業務邏輯。

Spring擴充套件

實現BeanPostProcess介面在Bean生成前後進行操作。

實現BeanFactoryPostProcessor介面配置Bean元屬性。

實現FactoryBean介面定製個性化的Bean。

MyBatis

MyBatis是一款優秀的持久層框架,它幾乎避免了所有的JDBC程式碼和手動設定引數以及獲取結果集,它可以使用XML或註解來將介面和POJO對映成資料庫中的記錄。

MyBatis與Spring整合的時候Spring提供了全域性唯一的SqlSessionTemplate,SqlSessionTemplate 實現了SqlSession介面,那麼如何保證多個執行緒呼叫同一個dao時拿到的SqlSession不會錯亂呢?這個時候就用到了ThreadLocal,SqlSessionUtils.getSqlSession()會首先檢視當前執行緒資源map有無SqlSession,有則返回無則新建然後返回,這樣就能保證一條業務始終用的是同一個資料庫連線,也就能正確處理資料庫事務。

MyBatis和Hibernate

比較點MyBatisHibernate特點半自動(手寫SQL)全自動(根據對映生成SQL)SQL直接優化方便複雜資料庫移植性弱強快取機制欠缺更優日誌系統欠缺完整

Statement和PreparedStatement的區別

/***PreparedStatement extends Statement***///Statement用法sql1 =”select * from tbl_user where username=`”+ u +”` and password=`”+ p +”`”;statement = conn.createStatement(); result1 = statement.executeQuery(sql1); //PrepareStatement用法sql2 =”select * from tbl_user where username=? and password=?”; prepareStatement = conn.prepareStatement(sql2); pstmt.setString(1, u); pstmt.setString(2, p); result2 = prepareStatement.executeQuery();

比較點StatementPreparedStatement用途執行靜態SQL語句並返回結果執行已預編譯SQL語句並返回結果可讀性低(字串拼接)高(Set方法設值)效率低(字串拼接)高(佔位符)安全性低(SQL隱碼攻擊)高

訊息佇列

訊息佇列中介軟體是分散式系統中重要的元件,主要主要解決應用耦合、非同步訊息、流量削鋒等問題,具有非同步性、可靠性(儲存到本地硬碟)、鬆耦合、分散式的特性。

主要特點是非同步處理

主要目的是減少請求響應時間、解耦

主要使用場景是將比較耗時且不需同步返回結果的操作當做訊息存入佇列

流量削峰的一種解決方案

MQ推送模式改為定時或者批量拉取模式

訊息接收方實現批量處理等方式

RabbitMQ

RabbitMQ 是一個由 ErLang 開發的AMQP的開源實現。

交換機(Exchange)的功能主要是接收訊息並且轉發到繫結的佇列,交換機不儲存訊息,交換機本質是一張路由查詢表

Direct:繫結時設定一個路由鍵,訊息的路由鍵匹配才會被投送到佇列中。

Topic:根據模糊匹配轉發訊息(最靈活)。

Headers:設定頭部引數型別的交換機。

Fanout:轉發訊息到所有繫結佇列,訊息廣播的模式。

路由鍵(routing_key)在訊息中,而繫結鍵(binding_key)作用於交換機和佇列之間。當訊息中的路由鍵和繫結鍵對應上的時候,交換機就知道將該訊息存入哪個佇列。

分散式

分散式:一個業務分拆多個子業務,部署在不同的伺服器上(廚師和配菜師的關係)

叢集:同一個業務,部署在多個伺服器上(兩個廚師的關係)

微服務

微服務架構風格是一種使用一套小服務來開發單個應用的方式,每個服務執行在自己的程式中,並使用輕量級機制通訊(通常是HTTP API),這些服務能夠通過自動化部署機制來獨立部署、可以使用不同的程式語言實現、可以使用不同的資料儲存技術,並保持最低限度的集中式管理。

時下熱門的微服務開發框架有:Spring Cloud、Dubbo

RESTful

URL定位資源,HTTP動詞描述操作

GET:讀取資源

POST:建立資源

PUT:更新資源

DELETE:刪除資源

使用PUT方式更新時,必須傳送資源所有的屬性

Nginx

反向代理

正向代理:隱藏真實的請求客戶端,服務端不知道真實的客戶端是誰,正向代理伺服器會代替客戶端向伺服器傳送請求。正向代理代理的物件是客戶端

反向代理:隱藏真實的響應服務端,客戶端不知道真實的服務端是誰,反向代理伺服器會把請求轉發到真實的伺服器。反向代理代理的物件是服務端

10086總機就是一種反向代理,客戶不知道真正提供服務人的是誰。

負載均衡

四層負載均衡:工作在OSI模型的傳輸層,它在接收到客戶端的流量以後通過修改資料包的地址資訊將流量轉發到應用伺服器,因此四層負載均衡的主要工作就是轉發

七層負載均衡:工作在OSI模型的應用層,七層負載均衡在接到客戶端的流量以後,還需要一個完整的TCP/IP協議棧與客戶端建立一條完整的連線,並將應用層的請求流量解析出來,再按照排程演算法選擇一個應用伺服器,並與應用伺服器建立另外一條連線將請求傳送過去,因此七層負載均衡的主要工作就是代理

設計模式

設計模式的六大原則

單一職責原則:一個類只負責一個功能領域中的相應職責。

開閉原則:一個軟體實體應當對擴充套件開放,對修改關閉。

里氏替換原則:所有引用父類的地方必須能透明地使用其子類的物件。

依賴倒置原則:抽象不應該依賴於細節,細節應當依賴於抽象。(要針對介面程式設計,而不是針對實現程式設計)。

介面隔離原則:使用多個專門的介面,而不使用單一的總介面。

迪米特法則:一個軟體實體應當儘可能少地與其他實體發生相互作用。

單例、工廠、觀察者、介面卡、責任鏈

單例模式:一個類負責建立自己的物件,同時確保只有單個物件被建立,並提供一種訪問其唯一物件的方式。

工廠模式:在建立物件時不暴露建立邏輯,並通過使用一個共同的介面來指向新建立的物件。

觀察者模式:定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。

介面卡模式:負責加入獨立的或不相容的介面功能的類,使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

責任鏈模式:為請求建立了一個接收者物件的鏈,沿著這條鏈傳遞請求,直到有物件處理它為止,對請求的傳送者和接收者進行解耦。

寫出生產者消費者模式

生產者生產資料到緩衝區中,消費者從緩衝區中取資料。如果緩衝區已經滿了,則生產者執行緒阻塞;如果緩衝區為空,那麼消費者執行緒阻塞。

publicclassProducerAndConsumer{ staticBlockingQueueresourceQueue =newLinkedBlockingQueue(10); public static void main(String[] args) {Producerp =newProducer();//生產者Consumerc1 =newConsumer();//消費者1Consumerc2 =newConsumer();//消費者2Consumerc3 =newConsumer();//消費者3p.start(); c1.start(); c2.start(); c3.start(); }}/**

* 資源

*/classResource{ int id; publicResource(int id) {this.id = id; }}/**

* 生產者

*/classProducerextendsThread{ int p =1;@Overridepublic void run() {while(true) {try{Resourceresource =newResource(p++);System.out.println(“生產資源”+ resource.id);ProducerAndConsumer.resourceQueue.put(resource); }catch(InterruptedExceptione) { e.printStackTrace(); } } }}/**

* 消費者

*/classConsumerextendsThread{@Overridepublic void run() {while(true) {try{System.out.println(“消費資源”+  ((Resource)ProducerAndConsumer.resourceQueue.take()).id); }catch(InterruptedExceptione) { e.printStackTrace(); } } }}

高內聚、低耦合

耦合性:也稱塊間聯絡。指軟體各模組之間相互聯絡緊密程度的一種度量。模組之間聯絡越緊密,則其耦合性就越強。模組間耦合高低取決於模組間介面的複雜性、呼叫的方式及傳遞的資訊。

內聚性:也稱塊內聯絡。指軟體模組內部各元素彼此結合緊密程度的一種度量。模組內各元素(語名之間、程式段之間)聯絡越緊密,則其內聚性就越高。

高內聚、低耦合的系統具有更好的重用性,維護性,擴充套件性,可以更高效的完成系統的維護開發,持續的支援業務的發展,而不會成為業務發展的障礙

最後提供一個小福利,對於想要跳槽 換工作的可以加群:960439918,點選連結加入群聊【java高階架構交流群】:https://jq.qq.com/?_wv=1027&k=5fozFzF可以領取免費的架構師學習資料;瞭解最新的學習動態;瞭解最新的阿里、京東招聘資訊;獲取更多的面試資料。

1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,

需要突破技術瓶頸的。2、在公司待久了,過得很安逸,

但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的。

3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,

常用設計思想,常用java開發框架掌握熟練的。

4、覺得自己很牛B,一般需求都能搞定。

但是所學的知識點沒有系統化,很難在技術領域繼續突破的。


相關文章