本篇是講解關於JavaWeb崗位面試方面的一些對於Web知識的整理,當然,不只是需要知道這個方面的內容,還需要掌握其他方面的知識,我都根據自己的經歷來進行了整理,方便大家進行系統化的學習,只有多複習多研究,才能對技術有更好的掌握,才能拿到更好的offer。

下面是其他方面的知識點,歡迎大家進行瀏覽

1:Spring中獲取連線池的方式有哪些?

(1)DBCP資料來源 (2)C3P0資料來源 (3)Tomcat Jdbc Pool (4)BoneCP

(5)Druid資料來源----阿里開源

2:forward和redirect的區別有哪些?

(1)位址列顯示:前者不變,而後者會進行修改 forward是伺服器請求資源,伺服器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然後把這些內容再發給瀏覽器.瀏覽器根本不知道伺服器傳送的內容從哪裡來的,所以它的位址列還是原來的地址. redirect是服務端根據邏輯,傳送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以位址列顯示的是新的URL. (2)資料共享:前者是共享的,而後者是不能共享的 forward:轉發頁面和轉發到的頁面可以共享request裡面的資料. redirect:不能共享資料. (3)發生的方式:前者是在伺服器端,而後者是發生在客戶端 (4)運用場景:forward:一般用於使用者登陸的時候,根據角色轉發到相應的模組. redirect:一般用於使用者登出登陸時返回主頁面和跳轉到其它的網站等. (5)效率:前者效率高,而後者效率低

注意:redirect預設是302碼,包含兩次請求和兩次響應

3:Http返回碼301和302之間的區別?

共同點:都是進行重定向返回的狀態碼

不同點:301是代表永久性轉移;而302是短暫性轉移,會發生網址劫持的情況;儘量使用301而不要使用302,會發生“URL劫持”現象。

4:PreparedStatement與Statement的區別?

(1)preparedStatement是繼承的Statement介面,它們兩者都是介面; (2)preparedStatement是通過佔位符,能夠進行預編譯的,而Statement不能,其每次執行SQL語句都需要重新進行處理; (3)preparedStatement安全性更好,因為其能夠防止SQL的注入 (4)preparedStatement對於重複執行的程式碼的執行效率更快,對於批處理效率相對Statemet好 (5)PreaparedStatement程式碼的維護性和可讀性更加好

稍微補充一點額外知識:CallableStatement,其是PreparedStatement的子類,主要是用於呼叫資料庫的儲存過程;

5:JSP中靜態Include和動態Include的區別?

(1)動態include是通過<jsp:include page = "hello.jsp">,而靜態include是通過<%@ include file="hello.html"%> (2)動態的可以包含相同的變數,而靜態的是不可以包含相同變數 (3)動態的是先分別編譯每個jsp,然後再使用的時候進行的包含在一起,是先編譯再包含;而靜態的是先包含在一起,然後再進行一起編譯,是先包含,後編譯 (4)如果被包含的頁面經常更新,那麼應該使用動態包含,因為使用靜態包含,可能不會及時的進行更新; (5)靜態的include是通過偽碼實現,不會檢查檔案的改變,適用於靜態頁面;

6:JSP有哪些內建物件?作用分別是什麼?

答:一共是9個。

(1)HttpServletRequest類的request物件:代表請求物件,主要用於接受客戶端通過HTTP協議連結傳輸到伺服器端的資料 (2)HttpServletResponse類的response物件:代表響應物件,主要用於向客戶端傳送資料 (3)JspWriter類的out物件:主要用於向客戶端輸出資料,Out類的基類是JspWriter (4)HttpSession類的session物件:主要用來分別儲存每個使用者資訊和會話狀態 (5)ServletContex類的application物件:主要用於儲存所有應用系統中的公有資料,它是一個共享的內建物件,即一個容器中的多個使用者共享一個application讀寫,只要沒有關閉伺服器,application物件一直存在 (6)PageContext類的PageContext物件:管理網頁屬性,代表了頁面的上下文。PageContext物件的建立和初始化都是由容器自動完成。 (7)ServletConfig類的Config物件:程式碼片段配置物件,用於初始化Servlet的配置引數。 (8)Object類的Page物件:代表了當前正在執行的JSP頁面,也就是說,page物件代表了JSP編譯後的Servlet。page物件只能在當前的JSP範文之內使用。 (9)exception物件:處理JSP檔案執行時發生的錯誤和異常,只有在錯誤頁面裡才可以使用;

7:JSP中的基本動作指令和作用?

答:(1)jsp:include:在頁面被請求的時候引入一個檔案

(2)jsp:useBean:尋找或者例項化一個JavaBean

(3)jsp:setProperty:設定JavaBean的屬性

(4)jsp:getProperty:輸出某個JavaBean的屬性

(5)jsp:forward:把請求轉到一個新的頁面

(6)jsp:plugin:根據瀏覽器型別為java外掛生成object或embed標記

8:Spring的事務傳播特性和隔離級別分別是如何?

答:事務傳播特性主要是分為7類:

PROPAGATION_REQUIRED -- 支援當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。 PROPAGATION_SUPPORTS -- 支援當前事務,如果當前沒有事務,就以非事務方式執行。 PROPAGATION_MANDATORY -- 支援當前事務,如果當前沒有事務,就丟擲異常。 PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。 PROPAGATION_NOT_SUPPORTED -- 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 PROPAGATION_NEVER -- 以非事務方式執行,如果當前存在事務,則丟擲異常。 PROPAGATION_NESTED -- 如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

隔離級別主要分為4類:

1.未授權讀取(Read Uncommitted):也稱未提交讀。允許髒讀取但不允許更新丟失,如果一個事務已經開始寫資料則另外一個數據則不允許同時進行寫操作但允許其他事務讀此行資料。該隔離級別可以通過“排他寫鎖”實現。事務隔離的最低級別,僅可保證不讀取物理損壞的資料。與READ COMMITTED 隔離級相反,它允許讀取已經被其它使用者修改但尚未提交確定的資料。2. 授權讀取(Read Committed):也稱提交讀。允許不可重複讀取但不允許髒讀取。這可以通過“瞬間共享讀鎖”和“排他寫鎖”實現,讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交寫事務將會禁止其他事務訪問該行。SQL Server 預設的級別。在此隔離級下,SELECT 命令不會返回尚未提交(Committed) 的資料,也不能返回髒資料。3. 可重複讀取(Repeatable Read):禁止不可重複讀取和髒讀取。但是有時可能出現幻影資料,這可以通過“共享讀鎖”和“排他寫鎖”實現,讀取資料事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。在此隔離級下,用SELECT 命令讀取的資料在整個命令執行過程中不會被更改。此選項會影響系統的效能,非必要情況最好不用此隔離級。4. 序列(Serializable):也稱可序列讀。提供嚴格的事務隔離,它要求事務序列化執行,事務只能一個接著一個地執行,但不能併發執行。如果僅僅通過“行級鎖”是無法實現事務序列化的,必須通過其他機制保證新插入的資料不會被剛執行查詢操作事務訪問到。事務隔離的最高級別,事務之間完全隔離。如果事務在可序列讀隔離級別上執行,則可以保證任何併發重疊事務均是序列的。

溫馨提示:

(1)關於操作資料庫中出現的髒讀,不可重複讀,幻讀

髒讀:髒讀就是指當一個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外一個事務也訪問這個資料,然後使用了這個資料。不可重複讀:是指在一個事務內,多次讀同一資料。在這個事務還沒有結束時,另外一個事務也訪問該同一資料。那麼,在第一個事務中的兩次讀資料之間,由於第二個事務的修改,那麼第一個事務兩次讀到的的資料可能是不一樣的。這樣就發生了在一個事務內兩次讀到的資料是不一樣的,因此稱為是不可重複讀。

幻讀:是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼,以後就會發生操作第一個事務的使用者發現表中還有沒有修改的資料行,就好象發生了幻覺一樣。

不可重複讀的重點是修改: 同樣的條件,你讀取過的資料,再次讀取出來發現值不一樣了幻讀的重點在於新增或者刪除: 同樣的條件,第 1 次和第 2 次讀出來的記錄數不一樣

(2)問:Mysql5.6(Innodb)以後其資料庫本身是如何解決幻讀問題的?

答:首先,Innodb引擎預設的隔離級別是可重複讀,所以,它本身是能夠解決了髒讀和不可重複讀的問題,但是對於幻讀是不能夠解決的,但是,它本身又提供了一種機制來解決這種幻讀的問題,就是通過NextKey lock方式,其實就是使用一種鎖的機制;具體的過程如下:

9:Http中的request和response的頭都含有什麼欄位?

10:JavaWeb的高併發處理的一些優化方式有哪些?

答:高併發可以分為使用者量併發和資料併發

針對使用者量的併發的解決方式可以從下面的方面進行考慮:

(1)網頁靜態化(純HTML):主要是提高反應速度和提高安全性與穩定性(因為不容易被攻擊);

(2)圖片伺服器分離:主要是減輕伺服器壓力,比如jQuery中的lazyload.js就能夠實現這樣的懶載入方式

(3)ajax請求:主要是不需要頁面進行重新重新整理獲取

(4)伺服器的負載均衡:主要是減輕伺服器的壓力,這裡可以通過Nginx反向代理來進行;

(5)資料庫叢集:主要是減輕資料庫的壓力,這裡主要是通過master/slave(主從)資料庫進行;

(6)使用快取伺服器快取資料:主要是對於查詢頻繁的內容進行快取,這裡主要是通過redis進行;

針對資料併發可以從下面的方面進行考慮:

(1)對於方法採取synchronize機制

(2)通過spring的事務隔離級別:主要是用四種

(3)通過資料庫的鎖機制:表鎖和行鎖

(4)通過悲觀鎖和樂觀鎖

11:Web安全方面的知識點

答:(1)SQL注入:主要發生在登入系統的使用者名稱和密碼場景,利用SQL的拼接而導致的問題,所以,可以通過預處理命令來進行對SQL的處理;

(2)密碼安全:主要是如果密碼儲存是以明文的形式,那麼當資料洩露之後,就很容易進行使用者密碼的竊取,所以,可以通過MD5加密,或者SHA和鹽值加密;

(3)Cookie安全:主要是通過判斷本地是否有對應系統的Cookie值,從而進行修改,以達到直接登入系統的目的,所以,可以通過對Cookie值進行安全性的加密處理,再進行儲存;

(4)XSS(跨站指令碼攻擊):主要是由於編寫了指令碼內容,導致在頁面解析的時候進行指令碼語言的解析,通常發生在評論區功能,所以,可以通過字元過濾掉非法字元的形式或者轉義字元進行防範;

(4)CSRF(跨站請求偽造):攻擊可以在受害者毫不知情的情況下以受害者名義偽造請求傳送給受攻擊站點,從而在並未授權的情況下執行在許可權保護之下的操作;比如使用者訪問了一個轉賬的網頁(通過get提交),而後面又訪問了一個非法連結(而這個連結正好是指向轉賬網頁,那麼當點選之後就會發生又一次轉賬,而受害使用者卻還不知道),所以,針對這情況,可以採取HTTP referer欄位(在http請求頭裡面,有referer欄位用於判斷網頁的連結源地址),請求中新增token驗證,

(5)SYN攻擊:主要是由於tcp是一種全連線的方式,而SYN就是利用傳送大量的半連線請求,消耗CPU和系統資源,從而導致伺服器崩潰;所以,可以利用驗證碼的方式來進行預防;

12:請說說關於JDBC的基本操作流程

    1)載入(註冊)資料庫驅動(到JVM)。-------Class.forname("com.mysql.jdbc.Driver");     2)建立(獲取)資料庫連線。---------Connection con=DriverManager.getConnection(url,username,password);     3)建立(獲取)資料庫操作物件。------------Statement st = con.createStatement();     4)定義操作的SQL語句。-------------String sql = "select * from student";     5)執行資料庫操作。---------------ResultSet rst =  st.excuteQuery(sql);     6)獲取並操作結果集。 ---------while(rst.next){ 進行操作 }     7)關閉物件,回收資料庫資源(關閉結果集-->關閉資料庫操作物件-->關閉連線)。----rst.close(); st.close();con.close();

13:請說說關於SSO(單點登入)的工作原理

SSO的含義:單點登入全稱single sign on,簡稱SSO,指在多系統應用群中登入一個系統,便可在其他所有系統中得到授權而無需再次登入,包括單點登入和單點登出兩部分。

SSO的出現的原因:

(1)由於多級系統之間,如果對每個子系統都單獨登入一次,那麼這樣會導致很麻煩。

(2)由於共享cookie有很多侷限性。例如:域名難以統一,子系統技術難以統一。所以,需要一種全新的登入方式實現多系統應用群的登入--單點登入。

SSO實現原理:

登入實現原理:sso需要一個獨立的認證中心,只有認證中心能接受使用者的使用者名稱密碼等安全資訊,其他系統不提供登入入口,只接受認證中心的間接授權。間接授權通過令牌實現,sso認證中心驗證使用者的使用者名稱密碼沒問題,建立授權令牌,在接下來的跳轉過程中,授權令牌作為引數傳送給各個子系統,子系統拿到令牌,即得到了授權,可以藉此建立區域性會話,區域性會話登入方式與單系統的登入方式相同。具體過程如圖所示:

時序圖如下:

時序圖解析:

1.使用者訪問系統1的受保護資源,系統1發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數 2.sso認證中心發現使用者未登入,將使用者引導至登入頁面 3.使用者輸入使用者名稱密碼提交登入申請 4.sso認證中心校驗使用者資訊,建立使用者與sso認證中心之間的會話,稱為全域性會話,同時建立授權令牌 5.sso認證中心帶著令牌跳轉會最初的請求地址(系統1) 6.系統1拿到令牌,去sso認證中心校驗令牌是否有效 7.sso認證中心校驗令牌,返回有效,註冊系統1 8.系統1使用該令牌建立與使用者的會話,稱為區域性會話,返回受保護資源 9.使用者訪問系統2的受保護資源 10.系統2發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數 11.sso認證中心發現使用者已登入,跳轉回系統2的地址,並附上令牌 12.系統2拿到令牌,去sso認證中心校驗令牌是否有效 13.sso認證中心校驗令牌,返回有效,註冊系統2

14.系統2使用該令牌建立與使用者的區域性會話,返回受保護資源驟

登出原理:在一個子系統中登出,所有的子系統都會登出。如下圖所示:

時序圖解析:

1.使用者向系統1發起登出請求 2.系統1根據使用者與系統1建立的會話id拿到令牌,向sso認證中心發起登出請求 3.sso認證中心校驗令牌有效,銷燬全域性會話,同時取出所有用此令牌註冊的系統地址 4.sso認證中心向所有註冊系統發起登出請求 5.各註冊系統接收sso認證中心的登出請求,銷燬區域性會話 6.sso認證中心引導使用者至登入頁面

14:說說你對RPC的過程理解

答:

RPC主要的重點有:

動態代理,主要是invoke反射原理------ 對應代理層

序列化,使用Thrift的效率高 ------------對應序列化層

通訊方式,使用Netty的NIO能提高效率------對應網路層(客戶端)和通訊層(伺服器端)

服務發現,使用zookeeper可以實現

呼叫過程分析:

1、服務消費方(client)呼叫以本地呼叫方式呼叫服務;

2、client stub接收到呼叫後負責將方法、引數等組裝成能夠進行網路傳輸的訊息體;

3、client stub找到服務地址,並將訊息傳送到服務端;

4、server stub收到訊息後進行解碼;

5、server stub根據解碼結果呼叫本地的服務;

6、本地服務執行並將結果返回給server stub;

7、server stub將返回結果打包成訊息併發送至消費方;

8)client stub接收到訊息,並進行解碼;

9、服務消費方得到最終結果。

15:Tomcat的架構是如何理解的?

答:這個問題主要是考察隊Tomcat的理解,畢竟做JavaWeb對於這個是非常重要的,所以,可以從它的結構和每個部件的功能進行分析(Server,Service,Container,connector來分析)。可以通過我繪製的這個圖來理解架構:

詳細內容可以參考如下的文章:

16:Tomcat處理Http請求的過程是如何?(這個可以擴充套件到瀏覽器請求一個域名,這個過程是如何進行的,這個在我的網路總結專題中是進行了詳細分析的)

比如請求:localhost:8080//TestProject/index.jsp 1、請求被髮送到本機埠8080,被在那裡偵聽的Coyote HTTP/1.1 Connector獲得 2、Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應 3、Engine獲得請求localhost:8080//TestProject/index.jsp,匹配它所擁有的所有虛擬主機Host 4、Engine匹配到名為localhost的Host(即使匹配不到也把請求交給該Host處理,因為該Host被定義為該Engine的預設主機) 5、localhost Host獲得請求/TestProject/index.jsp,匹配它所擁有的所有Context 6、Host匹配到路徑為/TestProject的Context(如果匹配不到就把該請求交給路徑名為""的Context去處理) 7、path="/neuq"的Context獲得請求/neuq _index.jsp,在它的對映表中尋找對應的servlet 8、Context匹配到URL PATTERN為*.jsp的servlet,對應於JspServlet類 9、構造HttpServletRequest物件和HttpServletResponse物件,作為引數呼叫JspServlet的doGet或doPost方法 10、Context把執行完了之後的HttpServletResponse物件返回給Host 11、Host把HttpServletResponse物件返回給Engine 12、Engine把HttpServletResponse物件返回給Connector 13、Connector把HttpServletResponse物件返回給客戶瀏覽器注意一點:其實JSP就是一種servlet,它在內部進行的時候,就會把jsp作為servlet的程式碼進行分析。所以,針對請求jsp頁面和直接請求servlet是類似的方式的。(所以,可以延伸一個知識點jsp和servlet的相同點和共同點)

17:對Ajax瞭解嗎?說說Ajax的工作原理是什麼?

含義:Ajax 的全稱是AsynchronousJavaScript and XML,其中,Asynchronous 是非同步的意思。即能夠實現不重新整理整個頁面,而來進行更新頁面的部分內容。工作原理 簡單點描述:     Ajax的原理簡單來說通過XmlHttpRequest物件來向伺服器發非同步請求,從伺服器獲得資料,然後用javascript來操作DOM而更新頁面。複雜的描述:     Ajax的工作原理相當於在使用者和伺服器之間加了—箇中間層,使使用者操作與伺服器響應非同步化。並不是所有的使用者請求都提交給伺服器,像—些資料驗證和資料處理等都交給Ajax引擎自己來做, 只有確定需要從伺服器讀取新資料時再由Ajax引擎代為向伺服器提交請求。     Ajax其核心只有JavaScript、XMLHTTPRequest和DOM,在舊的互動方式中,由使用者觸發一個HTTP請求到伺服器,伺服器對其進行處理後再返回一個新的HTHL頁到客戶端, 每當伺服器處理客戶端提交的請求時,客戶都只能空閒等待,並且哪怕只是一次很小的互動、只需從伺服器端得到很簡單的一個數據,都要返回一個完整的HTML頁,而使用者每次都要浪費時間和頻寬去重新讀取整個頁面。而使用Ajax後用戶從感覺上幾乎所有的操作都會很快響應沒有頁面過載(白屏)的等待。Ajax的優勢: 1、減輕伺服器的負擔。因為Ajax的根本理念是“按需取資料”,所以最大可能在減少了冗餘請求和響影對伺服器造成的負擔; 2、無重新整理更新頁面,減少使用者實際和心理等待時間; 3、也可以把以前的一些伺服器負擔的工作轉嫁到客戶端,利於客戶端閒置的處理能力來處理,減輕伺服器和頻寬的負擔,節約空間和頻寬租用成本; 4、Ajax使WEB中的介面與應用分離(也可以說是資料與呈現分離);總結:Ajax的過程主要就是XMLHttpRequest這個物件發揮著非常重要的作用。要理解,它的建立(var xmlHttp = new XMLHttpRequest()),傳送請求(xmlHttp.open()和xmlHttp.send()方法),返回狀態碼(xmlHttp.readyState)和回撥函式的使用(xmlHttp.onreadystatechage)以及返回結果的型別(xmlHttp.responseText和xmlHttp.responseXML兩種型別)

18:請說說對於正向代理和反向代理有什麼理解?

正向代理:使用者A訪問伺服器B的時候,會先連上代理伺服器,通過代理伺服器去訪問伺服器。而使用者和代理伺服器是一個整體,因為代理伺服器是為了使用者來進行服務的,所以發生的是在客戶端。比如,我們訪問國外的連結的時候,我們通過翻牆工具和VPN的方式,其實就是一種正向代理的處理。

作用:(1)使用者A需要繞過某些障礙訪問伺服器B ,也就是翻牆(2)使用者A需要加速到達B,也就是加速器(3)快取作用,也就是使用者訪問伺服器都要通過代理伺服器,那麼別的使用者之前訪問的內容,代理伺服器可以先快取下來給其他使用者使用(4)使用者上網的管制,也就是所有使用者都只能通過代理伺服器來訪問(5)匿名訪問,也就是代理伺服器幫助使用者不讓服務發現使用者的存在,因為伺服器是不知道是代理伺服器訪問還是使用者來進行的。

反向代理:就是使用者A訪問網站的時候,訪問到的是反向代理伺服器,但是代理服務的內容其實是偷偷從伺服器B那裡搬過來的,從而實現的一種訪問。所以,對於很多的訪問量的網站,其實都是利用的一種負載均衡的形式,就常見的就是Nginx。而反向代理中,代理伺服器和伺服器本身是一個整體,代理伺服器是為了伺服器而進行的服務,這就區別了正向代理,其發生在服務端

作用:(1)保護原始伺服器(2)緩衝和負載均衡(3)內容分發CDN

19:如果資料要通過TCP連線傳輸出去要怎麼辦?(底層原理模組知識

例如,web服務對客戶端的響應資料,需要通過TCP連線傳輸給客戶端。 TCP/IP協議棧維護著兩個緩衝區:send buffer和recv buffer,它們合稱為socket buffer。需要通過TCP連線傳輸出去的資料,需要先複製到send buffer,再複製給網絡卡通過網路傳輸出去。如果通過TCP連線接收到資料,資料首先通過網絡卡進入recv buffer,再被複制到使用者空間的app buffer。 同樣,在資料複製到send buffer或從recv buffer複製到app buffer時,是CPU參與的拷貝。從send buffer複製到網絡卡或從網絡卡複製到recv buffer時,是DMA操作方式的拷貝。

如下圖所示,是通過TCP連線傳輸資料時的過程。

擴充套件知識: 當某個程序/執行緒(後文將不加區分的只認為是程序)需要某段資料時,它只能在使用者空間中屬於它自己的記憶體中訪問、修改,這段記憶體暫且稱之為app buffer(使用者緩衝區)。 假設需要的資料在磁碟上,那麼程序首先得發起相關係統呼叫,通知核心去載入磁碟上的檔案。但正常情況下,資料只能載入到核心的緩衝區,暫且稱之為kernel buffer。

20:說說關於Http請求的方式有哪些?各自特點是什麼?

1、OPTIONS 返回伺服器針對特定資源所支援的HTTP請求方法,也可以利用向web伺服器傳送‘*’的請求來測試伺服器的功能性 2、HEAD 向伺服器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以再不必傳輸整個響應內容的情況下,就可以獲取包含在響應小訊息頭中的元資訊。 3、GET 向特定的資源發出請求。注意:GET方法不應當被用於產生“副作用”的操作中,例如在WebApplication中,其中一個原因是GET可能會被網路蜘蛛等隨意訪問。Loadrunner中對應get請求函式:web_link和web_url 4、POST 向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。Loadrunner中對應POST請求函式:web_submit_data,web_submit_form 5、PUT 向指定資源位置上傳其最新內容 6、DELETE 請求伺服器刪除Request-URL所標識的資源 7、TRACE 回顯伺服器收到的請求,主要用於測試或診斷 8、CONNECT HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。 注意: 1)方法名稱是區分大小寫的,當某個請求所針對的資源不支援對應的請求方法的時候,伺服器應當返回狀態碼405(MothodNot Allowed);當伺服器不認識或者不支援對應的請求方法時,應返回狀態碼501(Not Implemented)。 2)HTTP伺服器至少應該實現GET和HEAD/POST方法,其他方法都是可選的,此外除上述方法,特定的HTTP伺服器支援擴充套件自定義的方法。

21:Http提交form表單和檔案的時候,它們之間有什麼差別?

enctype的multipart/form-data是專門用於檔案上傳的MIME格式, 不會對提交資料進行編碼,上傳的就是原始的二進位制編碼, 而form表單預設是application/x-www-form-urlencoded的格式, 不適用於檔案上傳,因為他會把form表中的資料進行編碼,空格轉換為+, 特殊字元用ASCII碼錶示.

22:Spring中獲取request物件的方法以及執行緒安全性

(1)直接在controller層方法中傳入request物件引數:通過該方法得到的request物件是不同的,是執行緒安全。

(2)自動注入::通過該方法得到的request物件是不同的,是執行緒安全。

(3)通過在controller基類中進行自動注入::通過該方法得到的request物件是不同的,是執行緒安全。

(4)手動呼叫生成::通過該方法得到的request物件是不同的,是執行緒安全。

(5)通過@ModelAttribut註解方法::通過該方法得到的request物件是相同的,是執行緒不安全

綜上所述,Controller中加引數(方法1)、自動注入(方法2和方法3)、手動呼叫(方法4)都是執行緒安全的,都可以用來獲取request物件。如果系統中request物件使用較少,則使用哪種方式均可;如果使用較多,建議使用自動注入(方法2 和方法3)來減少程式碼冗餘。如果需要在非Bean中使用request物件,既可以在上層呼叫時通過引數傳入,也可以直接在方法中通過手動呼叫(方法4)獲得。

23:請說說你平時的controller層的類是多例還是單例?(快手boss二面題)

回答:單例。

那麼既然你說單例,那麼請看下面的這個題,它能否通過變數'm'進行計算該controller的方法呼叫的次數呢?為什麼呢?

@Control
public class TestController{
	int m = 0 ; //用於記錄testMethod方法被呼叫了多少次
	@RequestMapper(value = "/test")
	public String testMethod(){
		m++;
	}
}

回答:不能,原因如下:

(1)首先,如果是單例的話, 那麼確實整個JVM中只會有一份該controller類 (2)但是,即使只有一個例項,如果遇到高併發的請求,那麼同時進行請求這個方法的時候 (3)由於這個變數“m”並不是會當值被修改之後會立刻將值同步到主存中 (4)另外,由於JVM對於java程式會存在原子性,順序性,可見性的處理,而m++操作並不是原子性操作。 (5)而這個時候,正有新的請求過來,而讀到的還是之前的變數“m”的值, (6)那麼,由於(3)和(4)的發生,導致資料不一致性,所以變數“m”的計數的值肯定是會<=實際呼叫的次數的。 (7)如果說等於的情況,那麼就是所有的請求都是順序請求,而沒有併發請求,就有可能實現。 (8)如果說小於的情況,那麼就是隻要存在併發請求,那麼就一直會出現。 (9)所以:綜合起來就是說,這樣的計數方式是不可靠的。

修改為正確的方法有如下幾種:

(1)在變數“m”的定義時,新增static和volatile關鍵字。 原因:因為新增static關鍵字,可以讓該變數儲存在常量池中,而且由於java程式的原子性,順序性,可見性,所以可以利用volatile關鍵字進行修飾,這樣可以讓修改後的值立即被同步到主存,但是要保證對於變數“m”的操作必須是原子性操作,然而m++並不是原子性操作,所以,單獨這樣的方式是不行的,還需要與方法(2)結合。 (2)在testMethod方法加入關鍵字synchronized 原因:通過這個可以把該方法設定為同步方法,所以對於併發請求的時候,會進行“排隊請求”,這樣就能解決併發處理。 (3)在testMethod方法中,將m++方法放入到同步程式碼塊中,synchronized(TestController.class){m++} 原因:這個比同步方法好,因為這樣減少不必要的同步消耗。 (4)利用JDK中的同步原子類AtomicInteger定義變數m 原因:通過這個類的物件,那麼進行的就是同步安全的原子操作(內部是通過CAS實現),所以這樣就可以達到併發原子操作 (5)利用面向切面程式設計中的AOP來進行controller方法的切入。 原因:就類似我們進行日誌和事務的處理方式一樣,這樣才實現方法呼叫次數的處理,相對前面會麻煩一點。

24:Spring中的事務管理有哪幾種方式?

對於Spring中的事務的,有這三API介面需要特別清晰的明白:事務管理器(PlatformTransactionManager),TransactionDefinition介面定義事務隔離級別(五種)和傳播行為(七種),以及TransactionStatus介面(主要是可以用於判斷事務是否執行完成和是否有儲存點) (1)程式設計式事務管理(不經常使用

該方式主要是通過手動編碼進行的事務管理,所以稱為程式設計式事務管理。其通過在spring配置檔案中,注入事務管理器以及事務管理模板transactionTemplate,再將需要進行事務管理的方法程式碼塊進行transactionTemplate執行execute()方法,從而實現事務管理。

(2)宣告式事務管理(該方式的第二種和第三種使用最多

第一種方式:基於TransactionProxyFactoryBean的方式。該方法主要是通過動態代理機制進行實現。該方式不經常使用,因為要針對每一個需要事務管理的類都配置一個代理類去管理,很顯然,這需要代理的類多了,配置檔案內容就多了。

第二種方式:基於AspectJ的XML配置。主要是通過在spring中的xml中,利用AOP的機制原理進行配置事務切面,從而實現事務的管理操作。通過這種方式的開發,可以在xml中很清晰的看到具體的事務管理配置內容。

第三種方式:基於註解的配置。主要是通過在spring中的xml中,配置事務註解的配置。然後在需要進行事務管理的類或者方法上面使用@transactional註解進行設定相關的傳播特性和隔離級別以及異常回滾型別等。通過這種方式的開發,配置少,便於我們進行相應的方法和類的控制,但是需要我們對類和方法進行修改。

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource" />
</bean>
 <!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="txManager" />

25:請說說SpringMVC的執行流程

(1)使用者通過瀏覽器向伺服器傳送請求,請求被DispatchServlet捕獲; (2)DispachServlet對請求的URL進行解析,得到請求資源識別符號(URI),然後根據URI呼叫HandMapping將請求對映到處理器HandlerExcutionChain;如果無法對映,那麼就表示該請求是一個無效請求,而不進行後續處理,進行相應錯誤碼的返回, (3)DispatchServlet根據獲得Handler選擇一個合適的HandlerAdapater介面卡處理; (4)Handler對資料處理完成以後將返回一個ModelAndView()物件給DispatchServlet; (5)Handler返回的ModelAndView()只是一個邏輯檢視並不是一個正式的檢視,DispathServlet通過ViewResolver試圖解析器將邏輯檢視轉化為真正的檢視View。 (6)DispatchServlet通過model解析出ModelAndView()中的引數進行解析最終展現出完整的view並返回給客戶端。

26:說說Spring中用到了哪些經典的設計模式

(1)單例模式:對於spring容器中的bean,預設都是採取單例模式,但是也可以通過修改bean的protoy來進行修改。 (2)工廠模式:這個主要就是在建立bean的時候,根據傳入的類引數來進行建立不同的bean(其實內部就是用map進行儲存),這個最明顯的就是BeanFacoty (3)模板模式:為了減少程式碼的重複,所以在比如JpaTemplate,RestTemplate,JmsTemplate就是採取這種模式的思想。 (4)代理模式:最明顯的就是在AOP程式設計中,如果代理類實現了介面,那麼就採取JDK的動態代理,否則就使用CGLIB代理。

27:請說說在Web應用中,對於SimpleDateFormat物件如何實現執行緒安全?

(1)每次使用的時候,都在方法進行重新建立一個新的物件。這種方法會產生多個物件,增加了負擔,但其實正常情況下,影響並不是很大。 (2)通過同步程式碼塊

public class DateCommonUtils{
      private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
      public static String formatDate(Date date)throws ParseException{
          synchronized(sdf){
              return sdf.format(date);
          }  
      }
      
     public static Date parse(String strDate) throws ParseException{
         synchronized(sdf){
             return sdf.parse(strDate);
         }
     } 
 }

(3)通過threadlocal物件

public class DateCommonUtils {
      private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
          @Override
          protected DateFormat initialValue() {
              return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          }
     };
      public static Date parse(String dateStr) throws ParseException {
          return threadLocal.get().parse(dateStr);
     }
     public static String format(Date date) {
         return threadLocal.get().format(date);
     }
 }

(4)使用其他的日期處理物件,比如jdk1.8中的localtime等等。

28:攔截器和過濾器的區別有哪些?

(1)攔截器是基於java的反射機制的,而過濾器是基於函式回撥。 (2)攔截器不依賴與servlet容器,過濾器依賴與servlet容器。 (3)攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。 (4)攔截器可以訪問action上下文、值棧裡的物件,而過濾器不能訪問。 (5)在action的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。 (6)攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裡注入一個service,可以呼叫業務邏輯。

29:Struts2中有哪些常用結果型別?各自的用處是什麼?

(1)dispatcher:預設的請求轉發的結果型別,Action轉發給JSP (2)chain:Action轉發到另外一個Action(同一次請求) (3)redirect:重定向,重定向到一個路徑資訊,路徑資訊沒有限制(不在一個請求)Action重定向到JSP (4)dedircAction:Action重定向到另一個Action (5)stream:將原始資料作為流傳遞迴瀏覽器,該結果型別對下載圖片和內容很有好處。 (6)freemarker:呈現freemarker模板 (7)plaintext:返回普通文字內容

30:Hibernate中的get和load查詢有什麼區別?

(1)get是立即載入,而load是懶載入 (2)get是先查詢一級快取,再查詢二級快取,再進行資料庫的查詢。而load是先查詢一級快取,如果沒有找到,就建立一個代理物件,等需要的時候去查詢二級快取和資料庫 (3)get如果沒有找到,則返回的是null,而load如果沒有找到,則返回異常 (4)當我們使用session。load()方法進行載入一個物件時,此時並不會發出sql語句,當前得到的這個物件其實是一個代理物件,這個代理物件只儲存了實體物件的id值,只有當我們要使用這個物件,得到其他屬性時,這個時候才會發出sql語句,從資料庫去查詢我們的物件。相對於load的延遲載入方式,get就直接多了,當我們使用session.get()方法來得到一個物件時,不管我們使用不使用這個物件,此時都會發出sql語句去從資料庫中查詢出來。

31:請說說Quartz是否有用過?裡面的核心物件有哪些?作用分別是什麼?

Quartz是一個定時排程的框架,使用起來非常簡單,功能也非常強大,適合對於有規律的任務進行排程執行。 核心的物件主要有: (1)Scheduler:待辦一個排程容器,一個排程容器中可以註冊多個JobDetail和Trigger。當Trigger與JobDetail組合,就可以被Scheduler容器排程了。 (2)Trigger:代表一個排程引數的配置,也就是設定什麼時候進行排程處理 (3)JobDeatil:表示一個具體的可執行的排程程式,Job是這個可執行程式排程程式所要執行的內容,另外JobDetail還包含了這個任務排程的方案和策略。其實就是設定需要進行處理的引數 (4)Job:表示一個任務,即就是要進行的操作

32:在Spring中獲取request物件的方法以及執行緒安全性分析?(Web)

33:禁止Cookie是否還能夠登入系統?是否還能夠作業系統中的功能模組?(58到家二面)

(1)能夠:因為在登入的時候,並沒有採取和cookie相關的內容,進行登入主要是採取使用者名稱和密碼的匹配關係,只是在登入之後,會存在返回給瀏覽器一個cookie的值。 (2)不能夠。因為系統判定是誰登入系統的話,主要是通過cookie中的SESSINID進行判斷的。如果現在禁止了cookie,那麼就會存在一個問題,系統無法得到sessionID,無法判斷獲取當前登入人是誰,那麼這樣就會導致系統混亂。所以,是無法作業系統的模組。  

34: