面試問題記錄 三 (JavaWeb、JavaEE)

前言

這塊還是比較關鍵的,考察你對整個業務流程的熟練度吧,雖然企業級的項目沒有接觸過,但像最基本的內容必須得融會貫通,這一點我感覺自己還是處於淺層,沒有深入的去思考以及練習過,其實就像那句話,「打字速度不夠,說明你敲的程式碼不夠多」,其實有時候最原始的方法是最簡單有效的,雖然會耗大量時間,但一件事有利就有弊,所以還是加強自身程式碼熟練度。
還是那句話,如果文中有明顯錯誤,勞煩請及時糾正我,在這不勝感激!!!


一、JavaWeb

1.解釋一下Servlet以及生命周期?

答:servlet就是sun公司開發動態web程式的一門技術,通過前端請求,伺服器端進行邏輯判斷,完成對前端的響應;生命周期大致可分為三個階段,初始化階段、運行階段、銷毀階段;首先初始化階段會調用init()方法對servlet對象的初始化,二是通過調用service方法來處理和響應客戶端的請求,三是通過調用destroy方法表示伺服器資源已經被移除。而我們一般是通過繼承HttPServlet這個抽象類,因為這個類對servlet默認方法有實現而且也添加自己的方法,然後平時用的較多的就是doPost和doGet方法。

2.Cookie和Session有什麼區別以及工作原理?

答:首先Http協議是無狀態的,所以伺服器端需要確認用戶狀態時,就得有某種機制去記錄;cookie是提供給客戶端的技術,session是提供給伺服器端的技術;客戶端第一次請求伺服器端時,伺服器端會產生一個session對象,來用於保存客戶資訊,並且每個session都有唯一的sessionID與之對應,用來區分session,然後伺服器端會產生一個cookie,此時cookie中name=JSESSIONID參數,然後value值是和sessionID的值是一樣的,當伺服器端響應給客戶端的同時,將cookie發送給客戶端,然後客戶端就有一個JSESSIONID與伺服器端sessionID一一對應。當第二次請求時,伺服器端會先用客戶端的JSESSIONID去匹配session中的sessionID。cookie保存的內容較為不安全,內容是String類型的,而session中保存在伺服器這塊,較為安全,內容是object類型的。一般是瀏覽器關了後cookie就過期了,當然這也跟設置過期時間有關。

4.談一下SQL注入

答:就是對用戶輸入的數據沒有進行合法性沒有判斷,也沒有過濾,然後攻擊者可以通過特殊的字元提交,改變SQL運行的結果,實現非法操作。基本上後端都是用預編譯PreparedStatement對象,或者增加正則表達式來防止SQL注入。目前了解就這麼多。

5.說一下XSS攻擊

答:跨站腳本攻擊,不需要用戶去登錄認證,然後通過合法操作在頁面中注入腳本,然後操控用戶瀏覽器,類似SQL注入。

6.CSRF攻擊是什麼?如何避免?

答:跨站請求偽造攻擊,誘使用戶登錄認證第三方網站,然後通過用戶認證憑證繞過後台驗證,然後冒充用戶從而去達到某項操作的目的。比如盜取帳號、轉賬、發布虛假資訊。驗證碼和token都是比較用的多的防範措施。

7.doGet和doPost有什麼區別?

答:兩種方式主要針對get和post方法,而get一般用來獲取數據,因為它請求的數據會附加在URL上,而且get參數有長度限制,get請求還會保存在瀏覽器記錄中,而post方式更適合提交數據,相比get方式更加安全,因為它是將header先發過去,然後通過伺服器判斷再發送data,而且它也是放在請求體中的,雖然通過抓包可以看見,但至少比get明文傳輸的稍微安全一些。且post參數大小是無限制。


[提一些需要知道的JSP知識,個人感覺這一方面的知識還是要懂的]

JSP與Servlet的區別?

答:JSP本質上就是Servlet,JSP首先通過翻譯成servlet,然後再將servlet編譯成「.class」文件,然後其中java程式碼在伺服器端執行,最終通過out.write()方法將HTML內容發送到瀏覽器進行解析。
image

JSP內置對象

答:九大內置對象,1是request封裝客戶端請求,2是response封裝伺服器端請求,3是pageContext通過該對象可以獲得其他對象,4是session封裝用戶會話的對象,5是application封裝伺服器端運行環境的對象,6是page JSP本身對象,7是config web應用配置對象,8是out 輸出伺服器端響應的輸出流對象,9是exception封裝頁面拋出異常的對象。

JSP作用域

答:四種作用域;page表示一個頁面相關的對象和屬性;request表示客戶端向伺服器發出的請求,產生的數據,臨時性的,常見於新聞這類型;session表示一次會話,就是發送請求後,產生的數據,一會還有用。比如購物車;application表示發送的請求,產生的數據,一個用戶用完別的用戶還能繼續用,全局作用域。


二、JavaEE

I.Spring

1.說一下IOC

答:IOC就是控制反轉,控制就是傳統的是由程式本身創建對象,現在交給spring容器去創建,反轉就是程式不去創建對象而是去被動的接收對象;而具體的一種實現方式就是依賴注入,注入方式的話就有構造器注入(默認無參構造,有參通過下標、參數名、類型賦值)和setter方式注入、註解方式注入;而依賴就是bean對象的創建是由容器完成的,注入就是bean對象中的屬性都由容器來注入。最終還是為了解耦合。
參考文章:《Spring:源碼解讀Spring IOC原理》//www.cnblogs.com/ITtangtang/p/3978349.html

2.說一下AOP

答:理解AOP的話,就得首先對Java的代理模式有認識;代理模式的話可以去看一下這個狂神的影片【//www.bilibili.com/video/BV1WE411d7Dv?p=17】
AOP面向切面編程,簡單說就是那些與業務無關,卻為業務模組所共同調用的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性
參考文章:《Spring3:AOP》 //www.cnblogs.com/xrq730/p/4919025.html

3.Bean的作用域

答:官方文檔作用域有六種,一是單例模式也就是單個bean定義範圍只有單個實例,二是原型模式,每次從容器中get時,就會產生新的實例,剩下的request(一次請求中存活)、session(一個session會話中存活)、application(全局存活)、websocket都在web中用到。

4.Bean的自動裝配

答:兩種裝配,一是xml中的顯式配置、java中的顯式配置、二是隱式自動裝配bean(一種是byName會自動在容器上下文中找和自己對象set方法後面值對應的bean id,即需要保證所有的bean的id唯一;一種是byType會在容器上下文中找,和自己對象屬性類型相同的bean,即需要保證所有bean的class唯一);


II.SpringMVC

1.說一下SpringMVC的流程?

答:首先URL請求會發送到前端控制器DispatcherServlet,然後DispatcherServlet尋找HandlerMapping處理器映射,通過HandlerExcution根據URL尋找處理器Handler,然後將資訊返回給DispatchServlet前端控制器,然後前端控制器去請求處理器適配器HandlerAdapter,該適配器通過給Controller去執行Handler,最後將視圖邏輯名或模型數據返回給前端控制器,然後前端控制器去調用視圖解析器去解析邏輯視圖名,然後將資訊返回給前端控制器,前端控制器再去調用具體視圖。
參考以下兩圖:
image
image


III.MyBatis

1.談一下你對MyBatis的理解?

答:MyBatis就是簡化了資料庫連接和操作,通過xml文件或註解來映射原生類型,介面和簡單的實體類,而且沒有第三方的依賴。因為以前JDBC的話,在Java中操作資料庫,首先要載入驅動,配置一些連接參數,而且數據返回結果需要一個個遍歷賦值給我們寫的POJO,當需要變更一些驅動資訊時,會消耗很大一部分時間,而且都是重複性的工作,所以MyBatis的話就簡化了開發,松解了耦合。

2. #{} 與 ${} 的區別

答:#號是可以防止SQL注入問題,因為是預編譯的,相當於jdbc中佔位符「?」;$符號是直接替換的值,不安全的。能用#{}盡量用#{}。

3.MyBatis和MyBatis-Plus有什麼區別?

答:相對於Mybatis的話,以前需要每寫一個DAO就要有一個Mapper去對應操作資料庫,而Mybatis-Plus對mybatis做了增強,也就是將平時一些常用的CRUD操作資料庫語句做了封裝,簡化了一些重複性的操作。

4.MyBatis的一級快取和二級快取是怎樣的?

答:默認情況下,一級快取開啟,也就是SQLSession級別的快取,本地快取;二級快取基於namespace級別的快取,需要手動開啟,而且MyBatis為了提高擴展性,在其中定義了cache介面,通過介面去實現二級快取。


IV.SpringBoot

1.SpringBoot與普通的SpringMVC開發的區別?

答:SpringMVC是基於servlet的一個MVC框架主要解決WEB開發的問題,通過xml配置統一開發前端視圖和後端邏輯,提供一種輕度耦合的方式來開發web應用;SpringBoot專註於微服務方面的介面開發,和前端解耦,同時也解決了Spring配置的複雜,簡化了SpringMVC的開發流程;從而提供一種與Spring框架緊密結合用於提升開發者體驗的工具,同時它也集成了大量的第三方庫配置。
具體的理解可自行網上搜索文章查閱,還是感覺只有在項目中才能更加的去理解這一部分的知識,所以平時還是要多做一些demo來梳理自己的對開發技術的理解

2.SpringBoot的核心註解有哪些?

答:目前是知道@SpringBootApplication複合註解,因為它包含了SpringBootConfiguration(標註當前類是配置類)、EnableAutoConfiguration(根據我們添加的jar組件來完成默認配置,比如mvc的配置和tomcat)、ComponentScan(掃描當前包以及子包中被Component、Controller、Service、Repository註解標記的類並納入Spring容器進行管理);@Controller表示這個類是個控制類,@RequestMapping一般是使用Rest風格,比如@GetMapping、@PostMapping等等;@CrossOrigin解決跨域訪問問題;@AutoWired是Spring的自動裝配;(其實像後面的這些註解都是Spring和SpringMVC中的,嚴格意義上來講我覺得也不算SpringBoot的,只有像第一個複合註解才是比較核心的,目前也是了解這麼多,還需後期不斷深入的學習理解

3.SpringBoot的自動裝配原理是怎樣的?

答:這個點我感覺自己把握也不是很好,所以找了點一些內容
狂神筆記內容:

//表示這是一個配置類,和以前編寫的配置文件一樣,也可以給容器中添加組件;
@Configuration 

//啟動指定類的ConfigurationProperties功能;
  //進入這個HttpProperties查看,將配置文件中對應的值和HttpProperties綁定起來;
  //並把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class}) 

//Spring底層@Conditional註解
  //根據不同的條件判斷,如果滿足指定的條件,整個配置類裡面的配置就會生效;
  //這裡的意思就是判斷當前應用是否是web應用,如果是,當前配置類生效
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

//判斷當前項目有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器;
@ConditionalOnClass({CharacterEncodingFilter.class})

//判斷配置文件中是否存在某個配置:spring.http.encoding.enabled;
  //如果不存在,判斷也是成立的
  //即使我們配置文件中不配置pring.http.encoding.enabled=true,也是默認生效的;
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

public class HttpEncodingAutoConfiguration {
    //他已經和SpringBoot的配置文件映射了
    private final Encoding properties;
    //只有一個有參構造器的情況下,參數的值就會從容器中拿
    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }
    
    //給容器中添加一個組件,這個組件的某些值需要從properties中獲取
    @Bean
    @ConditionalOnMissingBean //判斷容器沒有這個組件?
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }
    //。。。。。。。
}



 一句話總結 :根據當前不同的條件判斷,決定這個配置類是否生效!
 一但這個配置類生效;這個配置類就會給容器中添加各種組件; 
 
 這些組件的屬性是從對應的 properties 類中獲取的,這些類裡面的每一個屬性又是和配置文件綁定的; 
 所有在配置文件中能配置的屬性都是在 xxxxProperties 類中封裝著; 
 配置文件能配置什麼就可以參照某個功能對應的這個屬性類 


//從配置文件中獲取指定的值和bean的屬性進行綁定
@ConfigurationProperties(prefix = "spring.http") 
public class HttpProperties {
    // .....
}



精髓

1、SpringBoot 啟動會載入大量的自動配置類

2、我們看我們需要的功能有沒有在 SpringBoot 默認寫好的自動配置類當中;

3、我們再來看這個自動配置類中到底配置了哪些組件;(只要我們要用的組件存在在其中,我們就不需要再手動配置了)

4、給容器中自動配置類添加組件的時候,會從 properties 類中獲取某些屬性。我們只需要在配置文件中指定這些屬性的值即可;

xxxxAutoConfigurartion:自動配置類;給容器中添加組件

xxxxProperties: 封裝配置文件中相關屬性;

參考文章:《這樣講 SpringBoot 自動配置原理,你應該能明白了吧》《SpringBoot自動配置原理
本人無打廣告嫌疑!!!!


三、JVM

1.說說JVM記憶體結構?

答:ProcessOn上找的一張圖,看標註應該是尚矽谷的圖,感覺這個圖還是能初步認識JVM。
image
還有三張圖鏈接放這,自行查看,感覺還是解釋的比較全面。
JVM記憶體模型完整版【//www.processon.com/view/5ea7a1b9e401fd21c196eb17?fromnew=1
JVM相關知識//www.processon.com/view/5ec5d7c60791290fe0768668?fromnew=1
JVM【//www.processon.com/view/5c749debe4b0f9fba6921d15?fromnew=1

2.為什麼用雙親委派機制,它是什麼?

答:首先當某一個類載入器載入「.class」文件的時候,會把任務交給上級類載入器,進行遞歸操作,也就是當上級類載入器都沒有載入,當前載入器才會去載入這個類;就比如:先從BootStrapClassLoader根載入器找,找不到則在ExtClassLoder擴展載入器找,如果還找不到,才會在當前AppClassLoader應用程式載入器找(一般是執行main方法)。雙親委派機制,它防止了去載入同一個「.class」文件,而且保證了核心「.class」文件被篡改,這樣保證了Class執行安全。
image
image


最後

關於這塊的知識,感覺還是注重實踐,因為許多概念上的東西,不通過自己去敲,去練的話,對這方面處於一種只知皮毛的狀態;其實我感覺我個人也是在表面上漂著,沒有去靜下心來去認真的思考過一個問題而且也沒有認真的去看過JDK的源碼;一路走來,感覺就是沒真正的扎進去,通過幾次簡單的面試其實就能感覺到自己在 哪些方面的缺失,可以幫助自己找到更多的缺點。

那在這我也想總結一下自己的學習方式:對某塊東西的認識先從影片看起,因為我感覺影片還是快的,影片和書各有各的好處吧,我感覺影片可以快速入門,而且中間出現的錯誤也會有個影響;看完影片的話,像JavaEE方面的知識點,個人覺得看官方文檔來的比較快,比較有權威一點,畢竟網上的文章太多了,或者也可以通過某些人整理的簡化的官方文檔,再去了解真正的官方文檔。最後還是就是動手,個人感覺自己動的手太少了,所以對一些東西的理解不是很深;然後在一段時間內去總結一下自己學的東西,必須要總結,這樣可以提高自己的邏輯以及以後查閱起來自己學的知識點方便一些,可以簡單記錄,也可以詳細記錄,但一般我感覺能讓幾個月之後的自己看到自己寫的東西可以瞬間想起來整個思路的話就其實很好。

剩下的就是關於微服務這塊的知識,個人感覺這塊知識單單從平時的demo學習的話,理解其實比較淺,還是覺得應該在實習的時候去真正接觸項目的時候,再來去深入的學習一下這方面的知識,雖然現在很卷,但是實習的話,面試官也不會對分散式微服務問的太多,最多問一下一些基礎。當然可能畢業後,問的點比較多了。

也祝看到此篇隨筆的小夥伴,面試順利,成功拿到心儀Offer!!!


題外話

最近,也是偶然間看到了一個影片,叫《經濟機器是怎樣運行的》,感覺像我這樣的經濟小白很有啟蒙作用!影片的話B站有,可以直接搜。(放個有字幕的影片鏈接地址:經濟機器是怎樣運行的 Ray Dalio(字幕)

人物介紹
雷·達利奧(英語:Raymond Dalio,1949年8月8日)出生於紐約,現居康乃狄克州費爾菲爾德縣,是美國的著名對沖基金經理、慈善家。瑞·達利奧是橋水基金公司的創始人兼首席執行官,而橋水基金於2013年被列為全世界最大的避險基金公司 [2][3]。達利奧於2017出版了關於企業管理金融經濟學的著作《原則》。根據彭博社報導,截至2019年1月,他是世界上最富有的100個人中的第79位[4]
早年生活
瑞·達利奧出生在一個義大利裔家庭,他的父親是一位音樂家。12歲時在林克斯高爾夫球場打工並受到那些僱主的耳濡目染下開始把賺來的錢拿來炒股。買進了人生第一支股票東北航空公司(Northeast Airlines)。而購買東北航空股票的原因是因為東北航空股價較低,瑞・逹利奧當時以為買的股數越多賺的錢也越多。最後結果是幸運的,成功賺了兩倍的錢,但其實是因為東北航空在即將破產之際被收購,才不至讓初買股票的瑞・逹利奧血本無歸。以後瑞·達利奧先後就讀於長島大學哈佛大學,並取得金融學本科學位和工商管理碩士學位。

如果有興趣的話可以去了解一下,感覺還是很有意思的,下面是MBA智庫中的介紹
鏈接//wiki.mbalib.com/wiki/%E7%91%9E%E8%BE%BE%E5%88%A9%E6%AC%A7

Tags: