標籤:java web 面試題 servlet
Servlet是一個介面,介面中有5個方法:init、service、destroy、getServletInfo、getServletConfig。對於Servlet來說,生命週期就是init,service,destroy三步,其中service可能會調用多次。
GenericServlet實現了Servlet介面,它只是通用的Servlet,和協議無關。
HttpServlet繼承了GernericServlet,增加了doGet、doPost等方法,需要開發人員去複寫,預設動作是報錯。在service方法中還檢測了LastModify,看情況返回304 Not Modified。
我們日常生活中所說的Servlet一般是指HttpServlet。因此Servlet完整的生命週期是init、service、doGet/doPost、destroy。init方法是在Servlet被執行個體化之後調用的,service方法是在請求到達之後調用的。
Servlet和CGI的區別。Servlet一個執行個體可以服務多個請求,每個請求使用一個單獨的線程,一般Web容器中會使用線程池技術,所以每個請求的額外開銷非常少。而CGI每個請求需要啟動一個單獨的進程。進程的開銷比線程要大很多,因此Servlet效能更加優越。
Servlet不是安全執行緒的,它沒有多線程保護機制。在Servlet中,每個請求都會有一個專門的線程進行處理。如果多個請求同時到來,那麼同一個Servlet對象中的service方法會被這些線程同時調用。為了保護多線程的安全,可以讓Servlet類實現SingleThreadModel介面。這種方法一次只能處理一個請求,因此效能很差。不過也有Web容器會建立對象池,也就是每個線程一個Servlet對象,這樣效能稍微好一點。如果需要更好的效能,還需要手動加入代碼同步塊。如果允許的話,使用ThreadLocal來定義變數。Java面試題經常會問到“Servlet是否安全執行緒?”其實這種描述容易給新手造成誤解,“什嗎?大名鼎鼎的Servlet居然也有安全問題?”個人認為更加明確一點的描述應該是“你在實現Servlet中的service方法時,要不要考慮多線程的問題?為什嗎?”