Java的面試題

1.結合項目談談你對MVC的理解
MVC是model-view-control的簡稱.也就是模型-視圖-控制器.mvc是一種設計模式,它強制性的吧應用程序的輸入,處理,輸出分開.MVC中模型.視圖,控制器分別承擔正不同的任務.
視圖:視圖是用戶看到並與之交互的界面.視圖向用戶顯示相關的數據,並接受用戶的輸出.視圖不進行任何業務邏輯處理
模型:表示業務數據和業務處理,相當JavaBean.一個模型能爲多個視圖提供數據,這提供了應用程序的重用性.
控制器:當用戶單機web頁面中的提交按鈕是,控制器接收請求並調用相應的模型去處理請求.然後根據處理結構調用相應的視圖來顯示處理的過程的結構
MVC的處理過程:首先控制器接收用戶的請求,調用相應的模型來進行業務處理,並返回數據給控制器.控制器調用相應的視圖來顯示處理的結構.並通過視圖呈現給用戶.如果在項目中對應MVC的haul;View對用項目中的JSP.controler對應action.model對應service+dao層的業務邏輯和持久層的操作

2.項目中爲什麼使用ssh(三大框架的有點)
- springmvc是因爲struts基於mvc模式的,很好的將應用程序進行了分層,使開發者更關注業務邏輯的實現
- Hivernate:是因爲Hibernate爲java應用提供了一個易用的、搞效率的對象關係映射框架。hibernate是個輕量級的持久層框架,功能豐富
- Spring基於IOC(控制反轉)和AOP框架多層J2ee系統的框架

3.爲何使用spring
spring是一個輕量級的控制反轉(IOC),面向切面(AOP),面向接口,事物管理,包容促進其他框架;是系統中用到的其他框假的耦合程度大大降地,擴展性強,簡單易用好管理..

4.Spring在項目中如何充當粘合劑
在項目中利用spring的ioc(控制反轉或依賴注入),明確的定義組件接口(UserDao),開發者可以獨立開發各個組件,然後根據組件間的依賴關係組裝(UserControl依賴UserService,UserService依賴UserDao)運行,很好的吧SpringMVC和hibernate結合起來;
spring的事物管理吧hibernate對數據庫的操作進行了事物配置

5.描述在系統中如何使用了spring的事物控制
spring事物包括編程和聲明式事務.在系統中使用了聲明式的事務管理是用spring的AOP來實現的;配置了只讀事物和回滾事物,當出現錯誤後進行事物回滾操作.在項目中通過aop切入事物daoservice層,這樣能是以業務邏輯操作包括幾個數據操作都控制在一個事務中.

6.Hibernate工作原理以及什麼要用?
原理:

  • 讀取並解析配置文件
  • 讀取並解析映射信息,創建SessionFactory
  • 打開Session
  • 創建事物Transaction
  • 持久化操作
  • 提交事物
  • 關閉Session
  • 關閉SessionFactory
    爲什麼要用
    1.對JDBC訪問數據庫代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼.
    2.hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現.他很大程度上簡化DAO層的編碼工作.
    3.Hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性
    4.Hibernate的性能非常好,因爲他是一個輕量級框架.映射的靈活性很出色.他支持各種關係型數據庫,從一到多對對的各種複雜的關係

Hibernate在系統中使用的優化策略
Hibernate對數據的緩存包括兩個級:一級緩存,在session的級別上進行,主要是對象的緩存,一起id爲鍵保存對象,在Session的生命期間存在;二級緩存,在SessionFactory的的級別上進行,有對象緩存和查詢緩存,查詢緩存一查詢條件爲鍵保存查詢結果,在SessionFactory的生命期間存在,默認地,Hibernate只啓用一級緩存

Hibernate與mybatis的比較
Hibernate與mybatis相比較,mybatis更爲輕便、靈活,容易掌握。mybatis可以把sql語句從java代碼中分離了出來,放在了配置文件中書寫,大大降低裏java代碼與SQL語句的耦合度,更容易對sql語句操作,重要的是mybatis還可以書寫動態的sql語句,但mybatis也存在一些缺陷,比如mybatis本身的緩存機制沒有hibernate那麼完善,hibernate除了本身有良好的緩存機制,還可以使用第三方緩存。Hibernate較完整的封裝了JDBC,但學起來要比mybatis更困難一些。Hibernate的DAO層開發比MyBatis簡單,對對象的維護和緩存要比MyBatis好。

談一下攔截器和過濾器的區別
- 攔截器是基於JAVA反射機制的,而過濾器是基於函數回調的
- 過濾器只能對Action請求起作用(action中的方法),而過濾器可以對幾乎所有的請求起作用(css JSP JS)
- 過濾器依賴servlet容器,二攔截器不依賴Servlet容器

SessionFactory是線程安全嗎?Session是線程安全嗎?兩個線程能共享一個Session嗎?
SessionFactory對應Hibernate的一個數據存儲的概念,它的線程是安全的,可以被多個線程併發並訪問.SessionFactory一般只會在啓動時候創建.對於對應的程序,最好是將SessionFactory通過單例的模式進行封裝以便訪問

Session是一個輕量級非線程安全的對象 (線程之間不能共享session),它表示與數據庫進行交互的一個工作單元.Session是由SessionFactory創建的,在任務完成之後被關閉.Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫連接(也就是在需要的時候纔會獲取)。爲了避免創建太多的session,可以使用TreadLocal來獲取當前的session,無論你調用多少次getCurrentSession()方法,返回的都是同一個session。

Session的load和get方法的區別
如果沒有找到符合條件的記錄,get方法返回null值,而load方法會拋出異常
get方法直接返回實體類對象,load方法返回實體類對象的代理
對於load()方法,hibernate認爲該數據在數據庫中一定存在,可以放心的使用代理來實現延遲加載,如果沒有數據,就會拋出異常,而通過get()方法去取數據,是可以不存在的。

Session加載實體對象的過程
Session在調用數據查詢工鞥呢之前,首先會緩衝中進行查詢,在一級緩存中,通過實體類型和主鍵進行查詢.如果一級緩存查詢中且數據狀態合法,則直接返回
如果一級緩存沒有命中,接下來Session會在當前NonExists記錄(相當於一個查詢黑名單,如果出現重複的無效查詢可以迅速判斷,從而提升性能)中進行查詢,如果NonExists中存在同樣的查詢條件,則返回null;
對於load方法,如果一級緩存查詢失敗,則查詢二級緩存,如果二級緩存命中則直接返回
如果之前的查詢都未命中,則發出sql語句,如果查詢未發現對應的記錄,則此次查詢添加到Session的NonExists中加以記錄,並返回null;
根據映射配置和SQL語句,的帶ResultSet,並創建對應的實體對象
將對象納入Session(一級緩存)管理
執行攔截器的onload方法(如果有對應的攔截器);
將數據對象納入二級緩存;
返回數據對象。

Query接口的list方法和iterate方法有什麼區別?
①list()方法返回的每個對象都是完整的(對象中的每個屬性都被表中的字段填充上了),list方法無法利用緩存,它對一級緩存只寫不讀;

②iterate方法可以充分利用一級緩存,它所返回的對象中僅包含了主鍵值(標識符),只有當你對iterator中的對象進行操作時,Hibernate纔會向數據庫再次發送SQL語句來獲取該對象的屬性值;

②list方法不會引起N+1查詢問題,而iterate方法會引起N+1查詢問題。

Hibernate如何實現分頁查詢
通過Hibernate實現分頁查詢,開發人眼只需要提供HOL語句,查詢起始行數(setFirstResult()方法)和最大查詢行數(setMaxResult()),並調用Query接口的list()方法,Hibernate會自動生成分頁查詢的SQL語句

servlet的執行流程
客戶端發出http的請求,web服務器請求轉發到servlet容器,servlet容器解析url並根據werb.xml找到相應的servlet,並將request和response對象傳遞給找到servlet,servlet根據request就可以知道是誰發出的請求,請求信息及其他信息,當servlet處理完業務邏輯後會將信息放入到response並響應到客戶端。

springMVC執行流程
springMVC流程是由dispatchservlet爲核心的分層控制框架.首先客戶端發出一個請求web服務器解析請求url並去匹配dispatchservlet的映射url,,如果匹配上就將這個請求放入到dispatchservlet,dispatchservlet根據mapping映射配置去尋找相對應的handel,然後把處理權交給找到的handel,handel封裝了處理業務邏輯的代碼,當handel處理完後會返回一個邏輯視圖modelandview給dispatchservlet,此時的modelandview是一個邏輯視圖不是一個正式視圖,所以dispatchservlet會通過viewresource視圖資源去解析modelandview,然後將解析後的參數放到view中返回到客戶端並展現。

多線程
a)一個進程是一個獨立的運行環境,可以看做是一個程序,而線程可以看做是進程的一個任務,比如QQ是一個進程,而一個QQ窗口是一個線程。

b)在多線程程序中,多線程併發可以提高程序的效率,cpu不會因爲某個線程等待資源而進入空閒狀態,它會把資源讓給其他的線程。

c)用戶線程就是我們開發程序是創建的線程,而守護線程爲系統線程,如JVM虛擬中的GC

d)線程的優先級別:每一個線程都有優先級別,有限級別高的可以先獲取CPU資源使該線程從就緒狀態轉爲運行狀態。也可以自定義線程的有限級別

e)死鎖:至少兩個以上線程爭取兩個以上cpu資源,避免死鎖就避免使用嵌套鎖,只需要在他們需要同步的地方加鎖和避免無限等待

Spring的IOC和AOP
a) IOC:Spring是開源框架,使用框架可以使我們減少工作量,提高工作效率並且它是分層結構,即相對應的層處理對應的業務邏輯,減少代碼的耦合度。而spring的核心是IOC控制反轉和AOP面向切面編程。IOC控制反轉主要強調的是程序之間的關係是由容器控制的,容器控制對象,控制了對外部資源的獲取。而反轉即爲,在傳統的編程中都是由我們創建對象獲取依賴對象,而在IOC中是容器幫我們創建對象並注入依賴對象,正是容器幫我們查找和注入對象,對象是被獲取,所以叫反轉。

b) AOP:面向切面編程,主要是管理系統層的業務,比如日誌,權限,事物等。AOP是將封裝好的對象剖開,找出其中對多個對象產生影響的公共行爲,並將其封裝爲一個可重用的模塊,這個模塊被命名爲切面(aspect),切面將那些與業務邏輯無關,卻被業務模塊共同調用的邏輯提取並封裝起來,減少了系統中的重複代碼,降低了模塊間的耦合度,同時提高了系統的可維護性。

Hibernate的核心思想
Hibernate的核心思想是ROM對象關係映射機制.它是將表與表之間的操作映射成對象與對象之間的操作。也就是從數據庫中提取的信息會自動按照你設置的映射要求封裝成特定的對象。所以hibernate就是通過將數據表實體類的映射,使得對對象的修改對應數據行的修改。

mybatis
數據庫優化
a) 選擇合適的字段,比如郵箱字段可以設爲char(6),儘量把字段設置爲notnull,這樣查詢的時候數據庫就不需要比較null值
b) 使用關聯查詢( left join on)查詢代替子查詢

c) 使用union聯合查詢手動創建臨時表

d) 開啓事物,當數據庫執行多條語句出現錯誤時,事物會回滾,可以維護數據庫的完整性

e) 使用外鍵,事物可以維護數據的完整性但是它卻不能保證數據的關聯性,使用外鍵可以保證數據的關聯性

f) 使用索引,索引是提高數據庫性能的常用方法,它可以令數據庫服務器以比沒有索引快的多的速度檢索特定的行,特別是對於max,min,order by查詢時,效果更明顯

g) 優化的查詢語句,絕大多數情況下,使用索引可以提高查詢的速度,但如果sql語句使用不恰當的話,索引無法發揮它的特性。

Tomcat服務器優化(內存,併發連接數,緩存)
a) 內存優化:主要是對Tomcat啓動參數進行優化,我們可以在Tomcat啓動腳本中修改它的最大內存數等等。

b) 線程數優化:Tomcat的併發連接參數,主要在Tomcat配置文件中server.xml中配置,比如修改最小空閒連接線程數,用於提高系統處理性能等等。

c) 優化緩存:打開壓縮功能,修改參數,比如壓縮的輸出內容大小默認爲2KB,可以適當的修改。

類加載過程
遇到一個新的類時,首先會到方法區去找class文件,如果沒有找到就會去硬盤中找class文件,找到後會返回,將class文件加載到方法區中,在類加載的時候,靜態成員變量會被分配到方法區的靜態區域,非靜態成員變量分配到非靜態區域,然後開始給靜態成員變量初始化,賦默認值,賦完默認值後,會根據靜態成員變量書寫的位置賦顯示值,然後執行靜態代碼。當所有的靜態代碼執行完,類加載纔算完成

對象的創建
a) 遇到一個新類時,會進行類的加載,定位到class文件

b) 對所有靜態成員變量初始化,靜態代碼塊也會執行,而且只在類加載的時候執行一次

c) New 對象時,jvm會在堆中分配一個足夠大的存儲空間

d) 存儲空間清空,爲所有的變量賦默認值,所有的對象引用賦值爲null

e) 根據書寫的位置給字段一些初始化操作

f) 調用構造器方法(沒有繼承)

MyBatis編程步驟
1.創建SqlSessionFactory
2.通過SqlSessionFactory創建SqlSession
3.通過sqlsession執行數據庫操作
4.調用session.commit()提交事物
5.調用session.close()關閉會話

進程間通信的方式?
(1)管道(pipe)及有名管道(named pipe):管道可用於具有親緣關係的父子進程間的通信,有名管道除了具有管道所具有的功能外,它還允許無親緣關係進程間的通信。

(2)信號(signal):信號是在軟件層次上對中斷機制的一種模擬,它是比較複雜的通信方式,用於通知進程有某事件發生,一個進程收到一個信號與處理器收到一箇中斷請求效果上可以說是一致的。

(3)消息隊列(message queue):消息隊列是消息的鏈接表,它克服了上兩種通信方式中信號量有限的缺點,具有寫權限得進程可以按照一定得規則向消息隊列中添加新信息;對消息隊列有讀權限得進程則可以從消息隊列中讀取信息。

(4)共享內存(shared memory):可以說這是最有用的進程間通信方式。它使得多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數據得更新。這種方式需要依靠某種同步操作,如互斥鎖和信號量等。

(5)信號量(semaphore):主要作爲進程之間及同一種進程的不同線程之間得同步和互斥手段。

(6)套接字(socket):這是一種更爲一般得進程間通信機制,它可用於網絡中不同機器之間的進程間通信,應用非常廣泛。

線程的基本概念、線程的基本狀態及狀態之間的關係?
線程是進程中執行運算的最小單位,是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以併發執行。

產生 就緒 運行 消亡 阻塞

守護線程: 只要當前JVM中尚有任何一個非守護線程沒有結束,守護線程就全部工作 thread.setDaemon(true)

線程的優先級(1–>10(最重要))

推薦使用implemenets Runnable
保留了繼承權
適合多個相同的程序代碼去處同一個資源
增加了程序的健壯性,代碼可以被多個線程共享.代碼和數據獨立

線程與進程的區別?
(1)一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。
(2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。
(3)處理機分給線程,即真正在處理機上運行的是線程。
(4)線程在執行過程中,需要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。線程是指進程內的一個執行單元,也是進程內的可調度實體.

線程間的同步方法大體可分爲兩類:用戶模式和內核模式。顧名思義,內核模式就是指利用系統內核對象的單一性來進行同步,使用時需要切換內核態與用戶態,而用戶模式就是不需要切換到內核態,只在用戶態完成操作。
用戶模式下的方法有:原子操作(例如一個單一的全局變量),臨界區。內核模式下的方法有:事件,信號量,互斥量

多線程同步和互斥有何異同,在什麼情況下分別使用他們?
所謂同步,是指散步在不同進程之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先後次序來運行,這種先後次序依賴於要完成的特定的任務。如果用對資源的訪問來定義的話,同步是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。

所謂互斥,是指散佈在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其它進程就不能運行它們之中的任一程序片段,只能等到該進程運行完這個程序片段後纔可以運行。如果用對資源的訪問來定義的話,互斥某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。

Java多線程中調用wait() 和 sleep()方法有什麼不同?
Java程序中wait 和 sleep都會造成某種形式的暫停,它們可以滿足不同的需要。wait()方法用於線程間通信,如果等待條件爲真且其它線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放CPU資源或者讓當前線程停止執行一段時間,但不會釋放鎖。

“==”和equals方法有什麼區別?
==操作符專門用來比較兩個變量的值是否相等,也就是用於比較變量所對應的內存中所存儲的數值是否相同,要比較兩個基本類型的數據或兩個引用變量是否相等,只能用==操作符。

quals方法是用於比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的

.抽象類和接口的區別?
 抽象方法必須用abstract關鍵字進行修飾。如果一個類含有抽象方法,則稱這個類爲抽象類,抽象類必須在類前用abstract關鍵字修飾。
 1)抽象方法必須爲public或者protected(因爲如果爲private,則不能被子類繼承,子類便無法實現該方法),缺省情況下默認爲public。

  2)抽象類不能用來創建對象;

  3)如果一個類繼承於一個抽象類,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義爲爲abstract類。

區別?
1.語法層面上的區別

  1)抽象類可以提供成員方法的實現細節,而接口中只能存在public abstract 方法;

  2)抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;

  3)接口中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;

  4)一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。

解釋Nginx如何處理HTTP請求
Nginx使用反應器模式。主事件循環等待操作系統發出準備事件的信號,這樣數據就可以從套接字讀取,在該實例中讀取到緩衝區並進行處理。單個線程可以提供數萬個併發連接。

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