1.StringBuffer與String的區別
StringBuffer是線程安全的,每次操作字符串,String會生成一個新的對象,而StringBuffer不會;StringBuilder是非線程安全的
2.線程池的作用
在程序啟動的時候就創建若干線程來響應處理,它們被稱為線程池,里面的線程叫工作線程
第一:降低資源消耗。通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。
第二:提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行。
第三:提高線程的可管理性。
常用線程池:ExecutorService 是主要的實現類,其中常用的有 Executors.newSingleThreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()。
Linux常用命令:
cd,cp,mv,rm,ps(進程),tar,cat(查看內容),chmod,vim,find,ls
3.索引:B+,B-,全文索引
Mysql的索引是一個數據結構,旨在使數據庫高效的查找數據。
常用的數據結構是B+Tree,每個葉子節點不但存放了索引鍵的相關信息還增加了指向相鄰葉子節點的指針,這樣就形成了帶有順序訪問指針的B+Tree,做這個優化的目的是提高不同區間訪問的性能。
什么時候使用索引:
##經常出現在group by,order by和distinc關鍵字后面的字段
##經常與其他表進行連接的表,在連接字段上應該建立索引
##經常出現在Where子句中的字段
##經常出現用作查詢選擇的字段
4.SpringMVC運行原理
客戶端請求提交到DispatcherServlet
由DispatcherServlet控制器查詢HandlerMapping,找到并分發到指定的Controller中。
Controller調用業務邏輯處理后,返回ModelAndView
DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖
5.Spring IOC (控制反轉,依賴注入)
Spring支持三種依賴注入方式,分別是屬性(Setter方法)注入,構造注入和接口注入。
在Spring中,那些組成應用的主體及由Spring IOC容器所管理的對象被稱之為Bean。
Spring的IOC容器通過反射的機制實例化Bean并建立Bean之間的依賴關系。
簡單地講,Bean就是由Spring IOC容器初始化、裝配及被管理的對象。
獲取Bean對象的過程,首先通過Resource加載配置文件并啟動IOC容器,然后通過getBean方法獲取bean對象,就可以調用他的方法。
6.Spring Bean的作用域:
Singleton:Spring IOC容器中只有一個共享的Bean實例,一般都是Singleton作用域。
Prototype:每一個請求,會產生一個新的Bean實例。
Request:每一次http請求會產生一個新的Bean實例。
7.一個Http請求過程
DNS域名解析 –> 發起TCP的三次握手 –> 建立TCP連接后發起http請求 –> 服務器響應http請求,瀏覽器得到html代碼 –> 瀏覽器解析html代碼,并請求html代碼中的資源(如javascript、css、圖片等) –> 瀏覽器對頁面進行渲染呈現給用戶
8.設計存儲海量數據的存儲系統
設計一個叫“中間層”的一個邏輯層,在這個層,將數據庫的海量數據抓出來,做成緩存,運行在服務器的內存中,同理,當有新的數據到來,也先做成緩存,再想辦法,持久化到數據庫中,這是一個簡單的思路。主要的步驟是負載均衡,將不同用戶的請求分發到不同的處理節點上,然后先存入緩存,定時向主數據庫更新數據。讀寫的過程采用類似樂觀鎖的機制,可以一直讀(在寫數據的時候也可以),但是每次讀的時候會有個版本的標記,如果本次讀的版本低于緩存的版本,會重新讀數據,這樣的情況并不多,可以忍受。
9.Session與Cookie
Cookie可以讓服務端跟蹤每個客戶端的訪問,但是每次客戶端的訪問都必須傳回這些Cookie,如果Cookie很多,則無形的增加了客戶端與服務端的數據傳輸量,
而Session則很好地解決了這個問題,同一個客戶端每次和服務端交互時,將數據存儲通過Session到服務端,不需要每次都傳回所有的Cookie值,而是傳回一個ID,每個客戶端第一次訪問服務器生成的唯一的ID,客戶端只要傳回這個ID就行了,這個ID通常為NAME為JSESSIONID的一個Cookie。這樣服務端就可以通過這個ID,來將存儲到服務端的KV值取出了。
10.Session和Cookie的超時問題,Cookie的安全問題
分布式Session框架
配置服務器,Zookeeper集群管理服務器可以統一管理所有服務器的配置文件
共享這些Session存儲在一個分布式緩存中,可以隨時寫入和讀取,而且性能要很好,如Memcache,Tair。
封裝一個類繼承自HttpSession,將Session存入到這個類中然后再存入分布式緩存中
由于Cookie不能跨域訪問,要實現Session同步,要同步SessionID寫到不同域名下。
11.Spring事務配置方法:
1.切點信息,用于定位實施事物切面的業務類方法
2.控制事務行為的事務屬性,這些屬性包括事物隔離級別,事務傳播行為,超時時間,回滾規則。
Spring通過aop/tx Schema 命名空間和@Transaction注解技術來進行聲明式事物配置。
12.Mybatis
每一個Mybatis的應用程序都以一個SqlSessionFactory對象的實例為核心。首先用字節流通過Resource將配置文件讀入,然后通過SqlSessionFactoryBuilder().build方法創建SqlSessionFactory,然后再通過SqlSessionFactory.openSession()方法創建一個SqlSession為每一個數據庫事務服務。
經歷了Mybatis初始化 –>創建SqlSession –>運行SQL語句,返回結果三個過程
13.HashMap與HashTable的區別。
1、HashMap是非線程安全的,HashTable是線程安全的。
2、HashMap的鍵和值都允許有null值存在,而HashTable則不行。
3、因為線程安全的問題,HashMap效率比HashTable的要高。
14.HashMap的實現機制:
維護一個每個元素是一個鏈表的數組,而且鏈表中的每個節點是一個Entry[]鍵值對的數據結構。
實現了數組+鏈表的特性,查找快,插入刪除也快。
對于每個key,他對應的數組索引下標是 int i = hash(key.hashcode)&(len-1);
每個新加入的節點放在鏈表首,然后該新加入的節點指向原鏈表首
15.HashMap,ConcurrentHashMap與LinkedHashMap的區別
ConcurrentHashMap是使用了鎖分段技術技術來保證線程安全的,鎖分段技術:首先將數據分成一段一段的存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問
ConcurrentHashMap 是在每個段(segment)中線程安全的
LinkedHashMap維護一個雙鏈表,可以將里面的數據按寫入的順序讀出
ConcurrentHashMap應用場景
1:ConcurrentHashMap的應用場景是高并發,但是并不能保證線程安全,而同步的HashMap和HashMap的是鎖住整個容器,而加鎖之后ConcurrentHashMap不需要鎖住整個容器,只需要鎖住對應的Segment就好了,所以可以保證高并發同步訪問,提升了效率。
2:可以多線程寫。
ConcurrentHashMap把HashMap分成若干個Segmenet
1.get時,不加鎖,先定位到segment然后在找到頭結點進行讀取操作。而value是volatile變量,所以可以保證在競爭條件時保證讀取最新的值,如果讀到的value是null,則可能正在修改,那么就調用ReadValueUnderLock函數,加鎖保證讀到的數據是正確的。
2.Put時會加鎖,一律添加到hash鏈的頭部。
3.Remove時也會加鎖,由于next是final類型不可改變,所以必須把刪除的節點之前的節點都復制一遍。
4.ConcurrentHashMap允許多個修改操作并發進行,其關鍵在于使用了鎖分離技術。它使用了多個鎖來控制對Hash表的不同Segment進行的修改。
ConcurrentHashMap的應用場景是高并發,但是并不能保證線程安全,而同步的HashMap和HashTable的是鎖住整個容器,而加鎖之后ConcurrentHashMap不需要鎖住整個容器,只需要鎖住對應的segment就好了,所以可以保證高并發同步訪問,提升了效率。
ConcurrentHashMap能夠保證每一次調用都是原子操作,但是并不保證多次調用之間也是原子操作。
16.死鎖的必要條件
#互斥 至少有一個資源處于非共享狀態
#占有并等待
#非搶占
#循環等待
17.解決死鎖:
第一個是死鎖預防,就是不讓上面的四個條件同時成立。
二是,合理分配資源。
三是使用銀行家算法,如果該進程請求的資源操作系統剩余量可以滿足,那么就分配。
18.進程間的通信方式
1.管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。
2.有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
3.信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
4.消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
5.信號 ( sinal ) : 信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發生。
6.共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
7.套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同機器間的進程通信。
19.Hibernate
Hibernate的一級緩存是由Session提供的,因此它只存在于Session的生命周期中,當程序調用save(),update(),saveOrUpdate()等方法 及調用查詢接口list,filter,iterate時,如Session緩存中還不存在相應的對象,Hibernate會把該對象加入到一級緩存中,當Session關閉的時候緩存也會消失。
Hibernate的一級緩存是Session所內置的,不能被卸載,也不能進行任何配置一級緩存采用的是key-value的Map方式來實現的,在緩存實體對象時,對象的主關鍵字ID是Map的key,實體對象就是對應的值。
Hibernate二級緩存:把獲得的所有數據對象根據ID放入到第二級緩存中。Hibernate二級緩存策略,是針對于ID查詢的緩存策略,刪除、更新、增加數據的時候,同時更新緩存。
20.進程和線程的區別:
進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1–n個線程。
靜態的程序文件如exe、class文件等
線程:同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。
一個程序里(進程里)面不同的執行路徑(從main方法開始)
線程和進程一樣分為五個階段:創建、就緒、運行、阻塞、終止。
多進程是指操作系統能同時運行多個任務(程序)。
多線程是指在同一程序中有多個順序流在執行。
在java中要想實現多線程,有三種手段,一種是繼續Thread類,另外一種是實現Runable接口,還有就是實現Callable接口。
wait()和sleep()的區別
sleep來自Thread類,和wait來自Object類
調用sleep()方法的過程中,線程不會釋放對象鎖。而 調用 wait 方法線程會釋放對象鎖
sleep睡眠后不出讓系統資源,wait讓出系統資源其他線程可以占用CPU
sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒
21.Override和Overload的含義以及區別
a.Overload顧名思義是重新加載,它可以表現類的多態性,可以是函數里面可以有相同的函數名但是參數名、返回值、類型不能相同;或者說可以改變參數、類型、返回值但是函數名字依然不變。
b.就是ride(重寫)的意思,在子類繼承父類的時候子類中可以定義某方法與其父類有相同的名稱和參數,當子類在調用這一函數時自動調用子類的方法,而父類相當于被覆蓋(重寫)了。
22.抽象類和接口的區別
a.一個類只能繼承單個類,但是可以實現多個接口
b.抽象類中可以有構造方法,接口中不能有構造方法
c.抽象類中的所有方法并不一定要是抽象的,你可以選擇在抽象類中實現一些基本的方法。而接口要求所有的方法都必須是抽象的
d.抽象類中可以包含靜態方法,接口中不可以
e.抽象類中可以有普通成員變量,接口中不可以
23.解析XML的幾種方式的原理與特點:DOM、SAX、PULL
a.DOM:消耗內存:先把xml文檔都讀到內存中,然后再用DOM API來訪問樹形結構,并獲取數據。這個寫起來很簡單,但是很消耗內存。要是數據過大,手機不夠牛逼,可能手機直接死機
b.SAX:解析效率高,占用內存少,基于事件驅動的:更加簡單地說就是對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數做相應動作,然后繼續同樣的掃描,直至文檔結束。
c.PULL:與 SAX 類似,也是基于事件驅動,我們可以調用它的next()方法,來獲取下一個解析事件(就是開始文檔,結束文檔,開始標簽,結束標簽),當處于某個元素時可以調用XmlPullParser的getAttributte()方法來獲取屬性的值,也可調用它的nextText()獲取本節點的值。
24.JAVA 中堆和棧的區別,說下java 的內存機制
a.基本數據類型比變量和對象的引用都是在棧分配的
b.堆內存用來存放由new創建的對象和數組
c.類變量(static修飾的變量),程序在一加載的時候就在堆中為類變量分配內存,堆中的內存地址存放在棧中
d.實例變量:當你使用java關鍵字new的時候,系統在堆中開辟并不一定是連續的空間分配給變量,是根據零散的堆內存地址,通過哈希算法換算為一長串數字以表征這個變量在堆中的”物理位置”,實例變量的生命周期–當實例變量的引用丟失后,將被GC(垃圾回收器)列入可回收“名單”中,但并不是馬上就釋放堆中內存
e.局部變量: 由聲明在某方法,或某代碼段里(比如for循環),執行到它的時候在棧中開辟內存,當局部變量一但脫離作用域,內存立即釋放
25.JAVA多態的實現原理
a.抽象的來講,多態的意思就是同一消息可以根據發送對象的不同而采用多種不同的行為方式。(發送消息就是函數調用)
b.實現的原理是動態綁定,程序調用的方法在運行期才動態綁定,追溯源碼可以發現,JVM 通過參數的自動轉型來找到合適的辦法。
26.多態
一、什么是多態
面向對象的三大特性:封裝、繼承、多態
多態的定義:指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而采用多種不同的行為方式。(發送消息就是函數調用)
實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
多態的作用:消除類型之間的耦合關系。
二、多態發生的三個必要條件
1.要有繼承
2.要有重寫
3.父類引用指向子類對像
27.Spring?概述
1.?什么是spring?
Spring?是個java企業級應用的開源開發框架。Spring主要用來開發Java應用,但是有些擴展是針對構建J2EE平臺的web應用。Spring?框架目標是簡化Java企業級應用開發,并通過POJO為基礎的編程模型促進良好的編程習慣。
2.?使用Spring框架的好處是什么?
輕量:Spring?是輕量的,基本的版本大約2MB。
控制反轉:Spring通過控制反轉實現了松散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。
面向切面的編程(AOP):Spring支持面向切面的編程,并且把應用業務邏輯和系統服務分開。
容器:Spring?包含并管理應用中對象的生命周期和配置。
MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。
事務管理:Spring?提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。
異常處理:Spring?提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate?or?JDO拋出的)轉化為一致的unchecked?異常。
3.??Spring由哪些模塊組成?
以下是Spring?框架的基本模塊:
Core?module
Bean?module
Context?module
Expression?Language?module
JDBC?module
ORM?module
OXM?module
Java?Messaging?Service(JMS)?module
Transaction?module
Web?module
Web-Servlet?module
Web-Struts?module
Web-Portlet?module
4. 核心容器(應用上下文)?模塊。
這是基本的Spring模塊,提供spring?框架的基礎功能,BeanFactory?是?任何以spring為基礎的應用的核心。Spring?框架建立在此模塊之上,它使Spring成為一個容器。
5.?BeanFactory?–?BeanFactory?實現舉例。
Bean?工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和依賴從正真的應用代碼中分離。
最常用的BeanFactory?實現是XmlBeanFactory?類。
6.?XMLBeanFactory?
最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory?,它根據XML文件中的定義加載beans。該容器從XML?文件讀取配置元數據并用它去創建一個完全配置的系統或應用。
7.?解釋AOP模塊
AOP模塊用于發給我們的Spring應用做面向切面的開發,?很多支持由AOP聯盟提供,這樣就確保了Spring和其他AOP框架的共通性。這個模塊將元數據編程引入Spring。
8.?解釋JDBC抽象和DAO模塊。
通過使用JDBC抽象和DAO模塊,保證數據庫代碼的簡潔,并能避免數據庫資源錯誤關閉導致的問題,它在各種不同的數據庫的錯誤信息之上,提供了一個統一的異常訪問層。它還利用Spring的AOP?模塊給Spring應用中的對象提供事務管理服務。
9.?解釋對象/關系映射集成模塊。
Spring?通過提供ORM模塊,支持我們在直接JDBC之上使用一個對象/關系映射映射(ORM)工具,Spring?支持集成主流的ORM框架,如Hiberate,JDO和?iBATIS?SQL?Maps。Spring的事務管理同樣支持以上所有ORM框架及JDBC。
10.??解釋WEB?模塊。
Spring的WEB模塊是構建在application?context?模塊基礎之上,提供一個適合web應用的上下文。這個模塊也包括支持多種面向web的任務,如透明地處理多個文件上傳請求和程序級請求參數的綁定到你的業務對象。它也有對Jakarta?Struts的支持。
12.??Spring配置文件
Spring配置文件是個XML?文件,這個文件包含了類信息,描述了如何配置它們,以及如何相互調用。
13.??什么是Spring?IOC?容器?
Spring?IOC?負責創建對象,管理對象(通過依賴注入(DI),裝配對象,配置對象,并且管理這些對象的整個生命周期。
14.??IOC的優點是什么?
IOC?或?依賴注入把應用的代碼量降到最低。它使應用容易測試,單元測試不再需要單例和JNDI查找機制。最小的代價和最小的侵入性使松散耦合得以實現。IOC容器支持加載服務時的餓漢式初始化和懶加載。
15.?ApplicationContext通常的實現是什么?
FileSystemXmlApplicationContext?:此容器從一個XML文件中加載beans的定義,XML?Bean?配置文件的全路徑名必須提供給它的構造函數。
ClassPathXmlApplicationContext:此容器也從一個XML文件中加載beans的定義,這里,你需要正確設置classpath因為這個容器將在classpath里找bean配置。
WebXmlApplicationContext:此容器加載一個XML文件,此文件定義了一個WEB應用的所有bean。
16.?Bean?工廠和?Application?contexts??有什么區別?
Application?contexts提供一種方法處理文本消息,一個通常的做法是加載文件資源(比如鏡像),它們可以向注冊為監聽器的bean發布事件。另外,在容器或容器內的對象上執行的那些不得不由bean工廠以程序化方式處理的操作,可以在Application?contexts中以聲明的方式處理。Application?contexts實現了MessageSource接口,該接口的實現以可插拔的方式提供獲取本地化消息的方法。
17.?一個Spring的應用看起來象什么?
一個定義了一些功能的接口。
這實現包括屬性,它的Setter , getter?方法和函數等。
Spring?AOP。
Spring?的XML?配置文件。
使用以上功能的客戶端程序。
依賴注入
18.?什么是Spring的依賴注入?
依賴注入,是IOC的一個方面,是個通常的概念,它有多種解釋。這概念是說你不用創建對象,而只需要描述它如何被創建。你不在代碼里直接組裝你的組件和服務,但是要在配置文件里描述哪些組件需要哪些服務,之后一個容器(IOC容器)負責把他們組裝起來。
19.??有哪些不同類型的IOC(依賴注入)方式?
構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實現的,該類有一系列參數,每個參數代表一個對其他類的依賴。
Setter方法注入:Setter方法注入是容器通過調用無參構造器或無參static工廠?方法實例化bean之后,調用該bean的setter方法,即實現了基于setter的依賴注入。
20.?哪種依賴注入方式你建議使用,構造器注入,還是?Setter方法注入?
你兩種依賴方式都可以使用,構造器注入和Setter方法注入。最好的解決方案是用構造器參數實現強制依賴,setter方法實現可選依賴。
Spring?Beans
21.什么是Spring?beans?
Spring?beans?是那些形成Spring應用的主干的java對象。它們被Spring?IOC容器初始化,裝配,和管理。這些beans通過容器中配置的元數據創建。比如,以XML文件中?的形式定義。
Spring?框架定義的beans都是單件beans。在bean?tag中有個屬性”singleton”,如果它被賦為TRUE,bean?就是單件,否則就是一個?prototype?bean。默認是TRUE,所以所有在Spring框架中的beans?缺省都是單件。
22.?一個?Spring?Bean?定義?包含什么?
一個Spring?Bean?的定義包含容器必知的所有配置元數據,包括如何創建一個bean,它的生命周期詳情及它的依賴。
23.?如何給Spring?容器提供配置元數據?
這里有三種重要的方法給Spring?容器提供配置元數據。
XML配置文件。
基于注解的配置。
基于java的配置。
24.?你怎樣定義類的作用域??
當定義一個?在Spring里,我們還能給這個bean聲明一個作用域。它可以通過bean?定義中的scope屬性來定義。如,當Spring要在需要的時候每次生產一個新的bean實例,bean的scope屬性被指定為prototype。另一方面,一個bean每次使用的時候必須返回同一個實例,這個bean的scope?屬性?必須設為?singleton。
25.?解釋Spring支持的幾種bean的作用域。
Spring框架支持以下五種bean的作用域:
singleton?:?bean在每個Spring?ioc?容器中只有一個實例。
prototype:一個bean的定義可以有多個實例。
request:每次http請求都會創建一個bean,該作用域僅在基于web的Spring?ApplicationContext情形下有效。
session:在一個HTTP?Session中,一個bean定義對應一個實例。該作用域僅在基于web的Spring?ApplicationContext情形下有效。
global-session:在一個全局的HTTP?Session中,一個bean定義對應一個實例。該作用域僅在基于web的Spring?ApplicationContext情形下有效。
缺省的Spring?bean?的作用域是Singleton.
26.?Spring框架中的單例bean是線程安全的嗎?
不,Spring框架中的單例bean不是線程安全的。
27.?解釋Spring框架中bean的生命周期。
Spring容器?從XML?文件中讀取bean的定義,并實例化bean。
Spring根據bean的定義填充所有的屬性。
如果bean實現了BeanNameAware?接口,Spring?傳遞bean?的ID?到?setBeanName方法。
如果Bean?實現了?BeanFactoryAware?接口,?Spring傳遞beanfactory?給setBeanFactory?方法。
如果有任何與bean相關聯的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內調用它們。
如果bean實現IntializingBean了,調用它的afterPropertySet方法,如果bean聲明了初始化方法,調用此初始化方法。
如果有BeanPostProcessors?和bean?關聯,這些bean的postProcessAfterInitialization()?方法將被調用。
如果bean實現了?DisposableBean,它將調用destroy()方法。
28.??哪些是重要的bean生命周期方法??你能重載它們嗎?
有兩個重要的bean?生命周期方法,第一個是setup?,?它是在容器加載bean的時候被調用。第二個方法是?teardown??它是在容器卸載類的時候被調用。
The?bean?標簽有兩個重要的屬性(init-method和destroy-method)。用它們你可以自己定制初始化和注銷方法。它們也有相應的注解(@PostConstruct和@PreDestroy)。
29.?什么是Spring的內部bean?
當一個bean僅被用作另一個bean的屬性時,它能被聲明為一個內部bean,為了定義inner?bean,在Spring?的?基于XML的?配置元數據中,可以在?或??元素內使用?元素,內部bean通常是匿名的,它們的Scope一般是prototype。
30.?在?Spring中如何注入一個java集合?
Spring提供以下幾種集合的配置元素:
類型用于注入一列值,允許有相同的值。
?類型用于注入一組值,不允許有相同的值。
?類型用于注入一組鍵值對,鍵和值都可以為任意類型。
類型用于注入一組鍵值對,鍵和值都只能為String類型。
31.?什么是bean裝配??
裝配,或bean?裝配是指在Spring?容器中把bean組裝到一起,前提是容器需要知道bean的依賴關系,如何通過依賴注入來把它們裝配到一起。
32.?什么是bean的自動裝配?
Spring?容器能夠自動裝配相互合作的bean,這意味著容器不需要和配置,能通過Bean工廠自動處理bean之間的協作。
33.?解釋不同方式的自動裝配?。
有五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入。
no:默認的方式是不進行自動裝配,通過顯式設置ref?屬性來進行裝配。
byName:通過參數名?自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byname,之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。
byType::通過參數類型自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byType,之后容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。
constructor:這個方式類似于byType,?但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。
autodetect:首先嘗試使用constructor來自動裝配,如果無法工作,則使用byType方式。
34.自動裝配有哪些局限性??
自動裝配的局限性是:
重寫:?你仍需用?和??配置來定義依賴,意味著總要重寫自動裝配。
基本數據類型:你不能自動裝配簡單的屬性,如基本數據類型,String字符串,和類。
模糊特性:自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配。
35.?你可以在Spring中注入一個null?和一個空字符串嗎?
可以。
Spring注解
36.?什么是基于Java的Spring注解配置??給一些注解的例子.
基于Java的配置,允許你在少量的Java注解的幫助下,進行你的大部分Spring配置而非通過XML文件。
以@Configuration?注解為例,它用來標記類可以當做一個bean的定義,被Spring IOC容器使用。另一個例子是@Bean注解,它表示此方法將要返回一個對象,作為一個bean注冊進Spring應用上下文。
37.?什么是基于注解的容器配置?
相對于XML文件,注解型的配置依賴于通過字節碼元數據裝配組件,而非尖括號的聲明。
開發者通過在相應的類,方法或屬性上使用注解的方式,直接組件類中進行配置,而不是使用xml表述bean的裝配關系。
38.?怎樣開啟注解裝配?
注解裝配在默認情況下是不開啟的,為了使用注解裝配,我們必須在Spring配置文件中配置?元素。
39.?@Required??注解
這個注解表明bean的屬性必須在配置的時候設置,通過一個bean定義的顯式的屬性值或通過自動裝配,若@Required注解的bean屬性未被設置,容器將拋出BeanInitializationException。
40.?@Autowired?注解
@Autowired?注解提供了更細粒度的控制,包括在何處以及如何完成自動裝配。它的用法和@Required一樣,修飾setter方法、構造器、屬性或者具有任意名稱和/或多個參數的PN方法。
41.?@Qualifier?注解
當有多個相同類型的bean卻只有一個需要自動裝配時,將@Qualifier?注解和@Autowire?注解結合使用以消除這種混淆,指定需要裝配的確切的bean。
Spring數據訪問
42.在Spring框架中如何更有效地使用JDBC??
使用SpringJDBC?框架,資源管理和錯誤處理的代價都會被減輕。所以開發者只需寫statements?和?queries從數據存取數據,JDBC也可以在Spring框架提供的模板類的幫助下更有效地被使用,這個模板叫JdbcTemplate?(例子見這里here)
43.?JdbcTemplate
JdbcTemplate?類提供了很多便利的方法解決諸如把數據庫數據轉變成基本數據類型或對象,執行寫好的或可調用的數據庫操作語句,提供自定義的數據錯誤處理。
44.?Spring對DAO的支持
Spring對數據訪問對象(DAO)的支持旨在簡化它和數據訪問技術如JDBC,Hibernate?or?JDO?結合使用。這使我們可以方便切換持久層。編碼時也不用擔心會捕獲每種技術特有的異常。
45. 使用Spring通過什么方式訪問Hibernate??
在Spring中有兩種方式訪問Hibernate:
控制反轉??Hibernate?Template和?Callback。
繼承?HibernateDAOSupport提供一個AOP?攔截器。
46.?Spring支持的ORM
Spring支持以下ORM:
Hibernate
iBatis
JPA?(Java?Persistence?API)
TopLink
JDO?(Java?Data?Objects)
OJB
47.如何通過HibernateDaoSupport將Spring和Hibernate結合起來?
用Spring的?SessionFactory?調用?LocalSessionFactory。集成過程分三步:
配置the?Hibernate?SessionFactory。
繼承HibernateDaoSupport實現一個DAO。
在AOP支持的事務中裝配。
48.?Spring支持的事務管理類型
Spring支持兩種類型的事務管理:
編程式事務管理:這意味你通過編程的方式管理事務,給你帶來極大的靈活性,但是難維護。
聲明式事務管理:這意味著你可以將業務代碼和事務管理分離,你只需用注解和XML配置來管理事務。
49.?Spring框架的事務管理有哪些優點?
它為不同的事務API??如?JTA,JDBC,Hibernate,JPA?和JDO,提供一個不變的編程模式。
它為編程式事務管理提供了一套簡單的API而不是一些復雜的事務API如
它支持聲明式事務管理。
它和Spring各種數據訪問抽象層很好得集成。
50.?你更傾向用那種事務管理類型?
大多數Spring框架的用戶選擇聲明式事務管理,因為它對應用代碼的影響最小,因此更符合一個無侵入的輕量級容器的思想。聲明式事務管理要優于編程式事務管理,雖然比編程式事務管理(這種方式允許你通過代碼控制事務)少了一點靈活性。
Spring面向切面編程(AOP)
51.??解釋AOP
面向切面的編程,或AOP,?是一種編程技術,允許程序模塊化橫向切割關注點,或橫切典型的責任劃分,如日志和事務管理。
52.?Aspect?切面
AOP核心就是切面,它將多個類的通用行為封裝成可重用的模塊,該模塊含有一組API提供橫切功能。比如,一個日志模塊可以被稱作日志的AOP切面。根據需求的不同,一個應用程序可以有若干切面。在Spring?AOP中,切面通過帶有@Aspect注解的類實現。
52.?在Spring?AOP?中,關注點和橫切關注的區別是什么?
關注點是應用中一個模塊的行為,一個關注點可能會被定義成一個我們想實現的一個功能。
橫切關注點是一個關注點,此關注點是整個應用都會使用的功能,并影響整個應用,比如日志,安全和數據傳輸,幾乎應用的每個模塊都需要的功能。因此這些都屬于橫切關注點。
54.?連接點
連接點代表一個應用程序的某個位置,在這個位置我們可以插入一個AOP切面,它實際上是個應用程序執行Spring?AOP的位置。
55.?通知
通知是個在方法執行前或執行后要做的動作,實際上是程序執行時要通過SpringAOP框架觸發的代碼段。
Spring切面可以應用五種類型的通知:
before:前置通知,在一個方法執行前被調用。
after:?在方法執行之后調用的通知,無論方法執行是否成功。
after-returning:?僅當方法成功完成后執行的通知。
after-throwing:?在方法拋出異常退出時執行的通知。
around:?在方法執行之前和之后調用的通知。
56.?切點
切入點是一個或一組連接點,通知將在這些位置執行。可以通過表達式或匹配的方式指明切入點。
57.?什么是引入??
引入允許我們在已存在的類中增加新的方法和屬性。
58.?什么是目標對象??
被一個或者多個切面所通知的對象。它通常是一個代理對象。也指被通知(advised)對象。
59.?什么是代理?
代理是通知目標對象后創建的對象。從客戶端的角度看,代理對象和目標對象是一樣的。
60.?有幾種不同類型的自動代理?
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadata?autoproxying
61.?什么是織入。什么是織入應用的不同點?
織入是將切面和到其他應用類型或對象連接或創建一個被通知對象的過程。
織入可以在編譯時,加載時,或運行時完成。
62.?解釋基于XML?Schema方式的切面實現。
在這種情況下,切面由常規類以及基于XML的配置實現。
63.?解釋基于注解的切面實現
在這種情況下(基于@AspectJ的實現),涉及到的切面聲明的風格與帶有java5標注的普通java類一致。
Spring?的MVC
64.?什么是Spring的MVC框架?
Spring?配備構建Web?應用的全功能MVC框架。Spring可以很便捷地和其他MVC框架集成,如Struts,Spring?的MVC框架用控制反轉把業務對象和控制邏輯清晰地隔離。它也允許以聲明的方式把請求參數和業務對象綁定。
65.?DispatcherServlet
Spring的MVC框架是圍繞DispatcherServlet來設計的,它用來處理所有的HTTP請求和響應。
66.?WebApplicationContext
WebApplicationContext?繼承了ApplicationContext??并增加了一些WEB應用必備的特有功能,它不同于一般的ApplicationContext?,因為它能處理主題,并找到被關聯的servlet。
67.?什么是Spring?MVC框架的控制器?
控制器提供一個訪問應用程序的行為,此行為通常通過服務接口實現。控制器解析用戶輸入并將其轉換為一個由視圖呈現給用戶的模型。Spring用一個非常抽象的方式實現了一個控制層,允許用戶創建多種用途的控制器。
68.?@Controller?注解
該注解表明該類扮演控制器的角色,Spring不需要你繼承任何其他控制器基類或引用Servlet?API。
69.?@RequestMapping?注解
該注解是用來映射一個URL到一個類或一個特定的方處理法上。
28.JAVA面試中問及HIBERNATE與 MYBATIS的對比
第一方面:開發速度的對比
就開發速度而言,Hibernate的真正掌握要比Mybatis來得難些。Mybatis框架相對簡單很容易上手,但也相對簡陋些。個人覺得要用好Mybatis還是首先要先理解好Hibernate。
比起兩者的開發速度,不僅僅要考慮到兩者的特性及性能,更要根據項目需求去考慮究竟哪一個更適合項目開發,比如:一個項目中用到的復雜查詢基本沒有,就是簡單的增刪改查,這樣選擇hibernate效率就很快了,因為基本的sql語句已經被封裝好了,根本不需要你去寫sql語句,這就節省了大量的時間,但是對于一個大型項目,復雜語句較多,這樣再去選擇hibernate就不是一個太好的選擇,選擇mybatis就會加快許多,而且語句的管理也比較方便。
第二方面:開發工作量的對比
Hibernate和MyBatis都有相應的代碼生成工具。可以生成簡單基本的DAO層方法。針對高級查詢,Mybatis需要手動編寫SQL語句,以及ResultMap。而Hibernate有良好的映射機制,開發者無需關心SQL的生成與結果映射,可以更專注于業務流程。
第三方面:sql優化方面
Hibernate的查詢會將表中的所有字段查詢出來,這一點會有性能消耗。Hibernate也可以自己寫SQL來指定需要查詢的字段,但這樣就破壞了Hibernate開發的簡潔性。而Mybatis的SQL是手動編寫的,所以可以按需求指定查詢的字段。
Hibernate HQL語句的調優需要將SQL打印出來,而Hibernate的SQL被很多人嫌棄因為太丑了。MyBatis的SQL是自己手動寫的所以調整方便。但Hibernate具有自己的日志統計。Mybatis本身不帶日志統計,使用Log4j進行日志記錄。
第四方面:對象管理的對比
Hibernate?是完整的對象/關系映射解決方案,它提供了對象狀態管理(state management)的功能,使開發者不再需要理會底層數據庫系統的細節。也就是說,相對于常見的?JDBC/SQL?持久層方案中需要管理?SQL?語句,Hibernate采用了更自然的面向對象的視角來持久化?Java?應用中的數據。
換句話說,使用?Hibernate?的開發者應該總是關注對象的狀態(state),不必考慮?SQL?語句的執行。這部分細節已經由?Hibernate?掌管妥當,只有開發者在進行系統性能調優的時候才需要進行了解。而MyBatis在這一塊沒有文檔說明,用戶需要對對象自己進行詳細的管理。
第五方面:緩存機制
Hibernate一級緩存是Session緩存,利用好一級緩存就需要對Session的生命周期進行管理好。建議在一個Action操作中使用一個Session。一級緩存需要對Session進行嚴格管理。
Hibernate二級緩存是SessionFactory級的緩存。?SessionFactory的緩存分為內置緩存和外置緩存。內置緩存中存放的是SessionFactory對象的一些集合屬性包含的數據(映射元素據及預定SQL語句等),對于應用程序來說,它是只讀的。外置緩存中存放的是數據庫數據的副本,其作用和一級緩存類似.二級緩存除了以內存作為存儲介質外,還可以選用硬盤等外部存儲設備。二級緩存稱為進程級緩存或SessionFactory級緩存,它可以被所有session共享,它的生命周期伴隨著SessionFactory的生命周期存在和消亡。
MyBatis?包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定制。MyBatis 3?中的緩存實現的很多改進都已經實現了,使得它更加強大而且易于配置。
默認情況下是沒有開啟緩存的,除了局部的?session?緩存,可以增強變現而且處理循環 依賴也是必須的。要開啟二級緩存,你需要在你的?SQL?映射文件中添加一行:?
字面上看就是這樣。這個簡單語句的效果如下:
映射語句文件中的所有?select?語句將會被緩存。
映射語句文件中的所有?insert,update?和?delete?語句會刷新緩存。
緩存會使用?Least Recently Used(LRU,最近最少使用的)算法來收回。
根據時間表(比如?no Flush Interval,沒有刷新間隔),?緩存不會以任何時間順序 來刷新。
緩存會存儲列表集合或對象(無論查詢方法返回什么)的?1024?個引用。
緩存會被視為是?read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而 且可以安全地被調用者修改,而不干擾其他調用者或線程所做的潛在修改。
所有的這些屬性都可以通過緩存元素的屬性來修改。
比如:
這個更高級的配置創建了一個?FIFO?緩存,并每隔?60?秒刷新,存數結果對象或列表的?512?個引用,而且返回的對象被認為是只讀的,因此在不同線程中的調用者之間修改它們會 導致沖突。可用的收回策略有,?默認的是?LRU:
LRU?–?最近最少使用的:移除最長時間不被使用的對象。
FIFO?–?先進先出:按對象進入緩存的順序來移除它們。
SOFT?–?軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。
WEAK?–?弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。
flushInterval(刷新間隔)可以被設置為任意的正整數,而且它們代表一個合理的毫秒 形式的時間段。默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新。
size(引用數目)可以被設置為任意正整數,要記住你緩存的對象數目和你運行環境的 可用內存資源數目。默認值是1024。
readOnly(只讀)屬性可以被設置為?true?或?false。只讀的緩存會給所有調用者返回緩 存對象的相同實例。因此這些對象不能被修改。這提供了很重要的性能優勢。可讀寫的緩存 會返回緩存對象的拷貝(通過序列化)?。這會慢一些,但是安全,因此默認是?false。
相同點:Hibernate和Mybatis的二級緩存除了采用系統默認的緩存機制外,都可以通過實現你自己的緩存或為其他第三方緩存方案,創建適配器來完全覆蓋緩存行為。
不同點:Hibernate的二級緩存配置在SessionFactory生成的配置文件中進行詳細配置,然后再在具體的表-對象映射中配置是那種緩存。
MyBatis的二級緩存配置都是在每個具體的表-對象映射中進行詳細配置,這樣針對不同的表可以自定義不同的緩存機制。并且Mybatis可以在命名空間中共享相同的緩存配置和實例,通過Cache-ref來實現。
兩者比較:因為Hibernate對查詢對象有著良好的管理機制,用戶無需關心SQL。所以在使用二級緩存時如果出現臟數據,系統會報出錯誤并提示。
而MyBatis在這一方面,使用二級緩存時需要特別小心。如果不能完全確定數據更新操作的波及范圍,避免Cache的盲目使用。否則,臟數據的出現會給系統的正常運行帶來很大的隱患。
第六方面:總結
對于總結,大家可以到各大java論壇去看一看
相同點:Hibernate與MyBatis都可以是通過SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory?生成Session,最后由Session來開啟執行事務和SQL語句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
Hibernate和MyBatis都支持JDBC和JTA事務處理。
MyBatis可以進行更為細致的SQL優化,可以減少查詢字段。
MyBatis容易掌握,而Hibernate門檻較高。
Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。
Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
Hibernate數據庫移植性很好,MyBatis的數據庫移植性不好,不同的數據庫需要寫不同SQL。
Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。
Hibernate功能強大,數據庫無關性好,O/R映射能力強,如果你對Hibernate相當精通,而且對Hibernate進行了適當的封裝,那么你的項目整個持久層代碼會相當簡單,需要寫的代碼很少,開發速度很快,非常爽。
Hibernate的缺點就是學習門檻不低,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡取得平衡,以及怎樣用好Hibernate方面需要你的經驗和能力都很強才行。
iBATIS入門簡單,即學即用,提供了數據庫查詢的自動對象綁定功能,而且延續了很好的SQL使用經驗,對于沒有那么高的對象模型要求的項目來說,相當完美。
iBATIS的缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層數據庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速數據庫修改。