J2EE面試題(四)

65. STRUTS的應用(如STRUTS架構) 

答:Struts是採用Java Servlet/JavaServer Pages技術,開發Web應用程序的開放源碼的framework。 採用Struts能開發出基於MVC(Model-View-Controller)設計模式的應用構架。 Struts有如下的主要功能: 一.包含一個controller servlet,能將用戶的請求發送到相應的Action對象。 二.JSP自由tag庫,並且在controller servlet中提供關聯支持,幫助開發員創建交互式表單應用。 三.提供了一系列實用對象:XML處理、通過Java reflection APIs自動處理JavaBeans屬性、國際化的提示和消息。 


66. 設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。
以下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。
public class ThreadTest1 {
  private int j;
  public static void main(String args[]) {
    ThreadTest1 tt = new ThreadTest1();
    Inc inc = tt.new Inc();
    Dec dec = tt.new Dec();
    for (int i = 0; i < 2; i++) {
      Thread t = new Thread(inc);
      t.start();
      t = new Thread(dec);
      t.start();
    }
  }

  private synchronized void inc() {
    j++;
    System.out.println(Thread.currentThread().getName() + "-inc:" + j);
  }

  private synchronized void dec() {
    j--;
    System.out.println(Thread.currentThread().getName() + "-dec:" + j);
  } 

  class Inc
      implements Runnable {
    public void run() {
      for (int i = 0; i < 100; i++) {
        inc();
      }
    }
  }

  class Dec
      implements Runnable {
    public void run() {
      for (int i = 0; i < 100; i++) {
        dec();
      }
    }
  }
}


66. 說出Servlet的生命週期,並說出Servlet和CGI的區別。

Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等,當服務器決定將實例銷燬的時候調用其destroy方法。與cgi的區別在於servlet處於服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務於多個請求,並且其實例一般不會銷燬,而CGI對每個請求都產生新的進程,服務完成後就銷燬,所以效率上低於servlet。


67. STRUTS的應用( 如STRUTS架構 ) 
Struts是採用Java Servlet/JavaServer Pages技術,開發Web應用程序的開放源碼的framework。 採用Struts能開發出基於MVC(Model-View-Controller)設計模式的應用構架。 
Struts有如下的主要功能:
 一.包含一個controller servlet,能將用戶的請求發送到相應的Action對象。 二.JSP自由tag庫,並且在controller servlet中提供關聯支持,幫助開發員創建交互式表單應用。 三.提供了一系列實用對象:XML處理、通過Java reflection APIs自動處理JavaBeans屬性、國際化的提示和消息。


68. struts中的actionform有什麼好處?
struts的actionform其實不好,裏面有一堆屬性,雖然可以自動填充,但是你會發現,在很多情況下(比如你用到Hibernate)
你還要需要自動寫一個數據庫表的映射類,通常是domain.UserInfo.java,這樣就和strutsform中的屬性重複,所以他很多餘,
struts1.1版本,保留了actionform,struts1.2中已經有了新的LazyValidatorForm,但仍然保留了原有的actionform,   而在struts 2.0中已經把actionform去掉了
下面是解決方法
   a:  把actionform換成DynaActionForm ,和原來不同的是在dynaActionForm可以domain.UserInfo.java的一個實例做爲他的一個屬性這樣你就不需要在裏面寫一堆的get,set方法,只是在頁面上綁定稍有不同
   b:  把actionform換成org.apache.struts.validator.LazyValidatorForm,這樣你完全不用寫你的actionform這個類,直接在xml裏面做相應配置,當然也可以加上驗證框架
   警告:這個問題是陷阱,實際上struts的actionform很不好,非常麻煩,用久了你會發現他其實是多餘的,所以這個問題你應該說他的壞處。


69. Hibernate有哪幾種查詢數據的方式
hql查詢,sql查詢,條件查詢


70. load()和get()的區別
hibernate對於load方法認爲該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,load默認支持延遲加載,在用到對象中的其他屬性數據時才查詢數據庫,但是萬一數據庫中不存在該記錄,只能拋異常ObjectNotFoundEcception;所說的load方法拋異常是指在使用該對象的數據時,數據庫中不存在該數據時拋異常,而不是在創建這個對象時。由於session中的緩存對於hibernate來說是個相當廉價的資源,所以在load時會先查一下session緩存看看該id對應的對象是否存在,不存在則創建代理(load時候之查詢一級緩存,不存在則創建代理)。get()現在一級緩存找,沒有就去二級緩存找,沒有就去數據庫找,沒有就返回null ;而對於get方法,hibernate一定要獲取到真實的數據,否則返回null。


71. spring的事務有幾種方式?談談spring事務的隔離級別和傳播行爲。
聲明事務和編程事務
隔離級別:
- DEFAULT使用數據庫默認的隔離級別
- READ_UNCOMMITTED會出現髒讀,不可重複讀和幻影讀問題
- READ_COMMITTED會出現重複讀和幻影讀
- REPEATABLE_READ會出現幻影讀
- SERIALIZABLE最安全,但是代價最大,性能影響極其嚴重
和傳播行:
- REQUIRED存在事務就融入該事務,不存在就創建事務
- SUPPORTS存在事務就融入事務,不存在則不創建事務
- MANDATORY存在事務則融入該事務,不存在,拋異常
- REQUIRES_NEW總是創建新事務
- NOT_SUPPORTED存在事務則掛起,一直執行非事務操作
- NEVER總是執行非事務,如果當前存在事務則拋異常
- NESTED嵌入式事務


72. Spring對多種ORM框架提供了很好的支持,簡單描述在Spring中使用Hibernate的方法,並結合事務管理。
getHiberanteTemplate裏面提供了save,update,delete,find等方法。
簡單說一個:如果配置了聲明式事務,當執行getHibernateTemplate的各種方法的時候,事務會

自動被加載
如果沒有配置事務,那麼以上操作不會真正的被同步到數據庫,除非配置了hibernate的

autocommit=true


73. spring的事務有幾種方式?談談spring事務的隔離級別和傳播行爲。
spring事務分兩種形式,聲明式事務和編程式事務,spring提供了一個事務的接口
PaltformTractionManager接口,針對不同的事務,spring進行了不同的實現,對hibernate事務的實現HIbernateTractionManager,對JDBC的JdbcTractionManager,DataSourceTractionManager以及JdoTractionManager。接口platformTractionManager提供了三個方法,獲取事務,提交和回滾的方法。


74. Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係)
類與類之間的關係主要體現在表與表之間的關係進行操作,它們都市對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many


75. Hibernate工作原理及爲什麼要用? 
原理: 
1.讀取並解析配置文件 
2.讀取並解析映射信息,創建SessionFactory 
3.打開Sesssion 
4.創建事務Transation 
5.持久化操作 
6.提交事務 
7.關閉Session 
8.關閉SesstionFactory 


76. 爲什麼要用Hibernate?

1. 對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。 
2. Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工作 
3. hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性。 
4. hibernate的性能非常好,因爲它是個輕量級框架。映射的靈活性很出色。它支持各種關係數據庫,從一對一到多對多的各種複雜關係。


77. Hibernate是如何延遲加載? 
》Hibernate2延遲加載實現:a)實體對象 b)集合(Collection) 
》Hibernate3 提供了屬性的延遲加載功能 
當Hibernate在查詢數據的時候,數據並沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。 


78. Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係) 
類與類之間的關係主要體現在表與表之間的關係進行操作,它們都市對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many、 

79. 說下Hibernate的緩存機制 
》 內部緩存存在Hibernate中又叫一級緩存,屬於應用事物級緩存 
》 二級緩存: 
a) 應用及緩存 
b) 分佈式緩存 
條件:數據不會被第三方修改、數據大小在可接受範圍、數據更新頻率低、同一數據被系統頻繁使用、非 關鍵數據 
c) 第三方緩存的實現 


80. Hibernate的查詢方式 
Sql、Criteria,object comptosition 
Hql: 1、 屬性查詢 2、 參數查詢、命名參數查詢 3、 關聯查詢 4、 分頁查詢5、 統計函數 


81. 如何優化Hibernate? 
1.使用雙向一對多關聯,不使用單向一對多  2.靈活使用單向一對多關聯  3.不用一對一,用多對一取代  4.配置對象緩存,不使用集合緩存  5.一對多集合使用Bag,多對多集合使用Set  6. 繼承類使用顯式多態  7. 表字段要少,表關聯不要怕多,有二級緩存撐腰 


82. Struts工作機制?爲什麼要使用Struts? 
》Struts的工作流程: 
在web應用啓動時就會加載初始化ActionServlet,ActionServlet從 
struts-config.xml文件中讀取配置信息,把它們存放到各種配置對象 
當ActionServlet接收到一個客戶請求時,將執行如下流程. 
-(1)檢索和用戶請求匹配的ActionMapping實例,如果不存在,就返回請求路徑無效信息; 
-(2)如果ActionForm實例不存在,就創建一個ActionForm對象,把客戶提交的表單數據保存到ActionForm對象中; 
-(3)根據配置信息決定是否需要表單驗證.如果需要驗證,就調用ActionForm的validate()方法; 
-(4)如果ActionForm的validate()方法返回null或返回一個不包含ActionMessage的ActuibErrors對象, 就表示表單驗證成功; 
-(5)ActionServlet根據ActionMapping所包含的映射信息決定將請求轉發給哪個Action,如果相應的 Action實例不存在,就先創建這個實例,然後調用Action的execute()方法; 
-(6)Action的execute()方法返回一個ActionForward對象,ActionServlet在把客戶請求轉發給 ActionForward對象指向的JSP組件; 
-(7)ActionForward對象指向JSP組件生成動態網頁,返回給客戶; 

》爲什麼要用:

JSP、Servlet、JavaBean技術的出現給我們構建強大的企業應用系統提供了可能。但用這些技術構建的系統非常的繁亂,所以在此之上,我們需要一個規則、一個把這些技術組織起來的規則,這就是框架,Struts便應運而生。 基於Struts開發的應用由3類組件構成:控制器組件、模型組件、視圖組件 


83. Struts的validate框架是如何驗證的? 
在struts配置文件中配置具體的錯誤提示,再在FormBean中的validate()方法具體調用。 


84.  說下Struts的設計模式 
MVC模式: web應用程序啓動時就會加載並初始化ActionServler。用戶提交表單時,一個配置好的ActionForm對象被創建,並被填入表單相應的數據,ActionServler根據Struts-config.xml文件配置好的設置決定是否需要表單驗證,如果需要就調用ActionForm的Validate()驗證後選擇將請求發送到哪個Action,如果Action不存在,ActionServlet會先創建這個對象,然後調用Action的execute()方法。Execute()從ActionForm對象中獲取數據,完成業務邏輯,返回一個ActionForward對象,ActionServlet再把客戶請求轉發給ActionForward對象指定的jsp組件,ActionForward對象指定的jsp生成動態的網頁,返回給客戶。 


85. spring工作機制及爲什麼要用? 

》Spring的工作機制:

1.spring mvc請所有的請求都提交給DispatcherServlet,它會委託應用系統的其他模塊負責負責對請求進行真正的處理工作。 
2.DispatcherServlet查詢一個或多個HandlerMapping,找到處理請求的Controller. 
3.DispatcherServlet請請求提交到目標Controller 
4.Controller進行業務邏輯處理後,會返回一個ModelAndView 
5.Dispathcher查詢一個或多個ViewResolver視圖解析器,找到ModelAndView對象指定的視圖對象 
6.視圖對象負責渲染返回給客戶端。

》爲什麼用: 
{AOP 讓開發人員可以創建非行爲性的關注點,稱爲橫切關注點,並將它們插入到應用程序代碼中。使用 AOP 後,公共服務 (比 如日誌、持久性、事務等)就可以分解成方面並應用到域對象上,同時不會增加域對象的對象模型的複雜性。 
IOC 允許創建一個可以構造對象的應用環境,然後向這些對象傳遞它們的協作對象。正如單詞 倒置 所表明的,IOC 就像反 過來的 JNDI。沒有使用一堆抽象工廠、服務定位器、單元素(singleton)和直接構造(straight construction),每一個對象都是用其協作對象構造的。因此是由容器管理協作對象(collaborator)。 Spring即使一個AOP框架,也是一IOC容器。 Spring 最好的地方是它有助於您替換對象。有了 Spring,只要用 JavaBean 屬性和配置文件加入依賴性(協作對象)。然後可以很容易地在需要時替換具有類似接口的協作對象。}


86.什麼是Spring Framework?
Spring Framework(簡稱Spring)是根據Rod Johnson著名的《Expert One-on-One J2EE Design and Development》而開發的J2EE應用程序框架。目前主要根據Rod Johnson和Juergen Hoeller而進行開發的,目前發佈的最新版爲1.1.4。 Spring是J2EE應用程序框架,不過,更嚴格地講它是針對Bean的生命週期進行管理的輕量級容器(Lightweight container),可以單獨利用Spring構築應用程序,也可以和Struts,Webwork,Tapestry等衆多Web應用程序框架組合使用,並且可以與Swing等桌面應用程序API組合。所以Spring並不僅僅只能應用在J2EE中,也可以應用在桌面應用及小應用程序中。針對Spring開發的組件不需要任何外部庫。


87. 使用Spring有什麼好處?
(1)Spring能有效地組織你的中間層對象。
(2)Spring能消除在許多工程中常見的對Singleton的過多使用。
(3)Spring能消除各種各樣自定義格式的屬性文件的需要,使配置信息一元化。
(4)Spring能夠幫助我們真正意義上實現針對接口編程。
(5)在Spring應用中的大多數業務對象沒有依賴於Spring。
(6)使用Spring構建的應用程序易於單元測試。
(7)Spring支持JDBC和O/R Mapping產品(Hibernate)
(8)MVC Web框架,提供一種清晰,無侵略性的MVC實現方式。
(9)JNDI抽象層,便於改變實現細節,可以方便地在遠程服務和本地服務間切換。
(10)簡化訪問數據庫時的例外處理。
(11)Spring能使用AOP提供聲明性事務管理,可以不直接操作JTA也能夠對事務進行管理。
(12)提供了JavaMail或其他郵件系統的支持。


88. 什麼是輕量(Lightweight)級容器?
Spring的開發者可以避免使用重量級容器開發EJB時的缺點:
(1)帶有侵略性的API。(代碼依賴於EJB)
(2)對容器的依賴。(代碼不能在EJB容器之外工作)
(3)提供固定的一組機能,不具有配置能力。
(4)不同的產品,部署過程不同,不易通用。
(5)啓動時間長。


89. 什麼是AOP,請解釋一下:

在軟件業,AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。


90. 什麼是IOC,請解釋一下

》什麼是IOC

IoC就是Inversion of Control,控制反轉。在Java開發中,IoC意味着將你設計好的類交給系統去控制,而不是在你的類內部控制。這稱爲控制反轉。

本人理解:就是把原本你自己製造,使用的對象,現在交由別人製造,而通過構造函數,setter方法或方法(這裏指使用這個對象的方法)參數的方式傳給你,由你使用。

下面我們以幾個例子來說明什麼是IoC


假設我們要設計一個Girl和一個Boy類,其中Girl有kiss方法,即Girl想要Kiss一個Boy。那麼,我們的問題是,Girl如何能夠認識這個Boy?

 

在我們中國,常見的MM與GG的認識方式有以下幾種

1 青梅竹馬; 2 親友介紹; 3 父母包辦

那麼哪一種纔是最好呢?

青梅竹馬:Girl從小就知道自己的Boy。

 

代碼:
public class Girl { 
    void kiss(){
       Boy boy = new Boy();
    }
}


然而從開始就創建的Boy缺點就是無法在更換。並且要負責Boy的整個生命週期。如果我們的Girl想要換一個怎麼辦?(筆者嚴重不支持Girl經常更換Boy)

親友介紹:由中間人負責提供Boy來見面

 

 

代碼:
public class Girl {
    void kiss(){
       Boy boy = BoyFactory.createBoy();     
    }
}


親友介紹,固然是好。如果不滿意,儘管另外換一個好了。但是,親友BoyFactory經常是以Singleton的形式出現,不然就是,存在於 Globals,無處不在,無處不能。實在是太繁瑣了一點,不夠靈活。我爲什麼一定要這個親友摻和進來呢?爲什麼一定要付給她介紹費呢?萬一最好的朋友愛上了我的男朋友呢?

 

父母包辦:一切交給父母,自己不用費吹灰之力,只需要等着Kiss就好了。

 


代碼:
public class Girl {
    void kiss(Boy boy){
       // kiss boy 
      boy.kiss();
    }
}

 

Well,這是對Girl最好的方法,只要想辦法賄賂了Girl的父母,並把Boy交給他。那麼我們就可以輕鬆的和Girl來Kiss了。看來幾千年傳統的父母之命還真是有用哦。至少Boy和Girl不用自己瞎忙乎了。

這就是IOC,將對象的創建和獲取提取到外部。由外部容器提供需要的組件。

 

我們知道好萊塢原則:“Do not call us, we will call you.” 意思就是,You, girlie, do not call the boy. We will feed you a boy。

 

我們還應該知道依賴倒轉原則即 Dependence Inversion Princinple,DIP


Eric Gamma說,要面向抽象編程。面向接口編程是面向對象的核心。

組件應該分爲兩部分,即

Service, 所提供功能的聲明

Implementation, Service的實現

好處是:多實現可以任意切換,防止 “everything depends on everything” 問題.即具體依賴於具體。

所以,我們的Boy應該是實現Kissable接口。這樣一旦Girl不想kiss可惡的Boy的話,還可以kiss可愛的kitten和慈祥的grandmother。

 


》IOC的type

IoC的Type指的是Girl得到Boy的幾種不同方式。我們逐一來說明。

IOC type 0:不用IOC

代碼:
public class Girl implements Servicable {

    private Kissable kissable;

    public Girl() {
        kissable = new Boy();
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}


Girl自己建立自己的Boy,很難更換,很難共享給別人,只能單獨使用,並負責完全的生命週期。

IOC type 1,先看代碼:

代碼:
public class Girl implements Servicable {

    Kissable kissable;

    public void service(ServiceManager mgr) {
        kissable = (Kissable) mgr.lookup(“kissable”);
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}


這種情況出現於Avalon Framework。一個組件實現了Servicable接口,就必須實現service方法,並傳入一個ServiceManager。其中會含有需要的其它組件。只需要在service方法中初始化需要的Boy。

另外,J2EE中從Context取得對象也屬於type 1。


它依賴於配置文件

代碼:
<container>
    <component name=“kissable“ class=“Boy">             
       <configuration> … </configuration>
    </component>

    <component name=“girl" class=“Girl" />
</container>


IOC type 2:

代碼:
public class Girl {

    private Kissable kissable;

    public void setKissable(Kissable kissable) {
        this.kissable = kissable;
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}


Type 2出現於Spring Framework,是通過JavaBean的set方法來將需要的Boy傳遞給Girl。它必須依賴於配置文件。

代碼:
<beans>
    <bean id=“boy" class=“Boy"/>
    <bean id=“girl“ class=“Girl">
        <property name=“kissable">
           <ref bean=“boy"/>
        </property>
    </bean>
</beans>


IOC type 3:

代碼:
public class Girl {

    private Kissable kissable;

    public Girl(Kissable kissable) {
        this.kissable = kissable;
    }

    public void kissYourKissable() {
        kissable.kiss();
    }

}


這就是PicoContainer的組件 。通過構造函數傳遞Boy給Girl
代碼:

PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy.class);
container.registerComponentImplementation(Girl.class);
Girl girl = (Girl) container.getComponentInstance(Girl.class);
girl.kissYourKissable();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章