2020Java實習必看面試兩百題解析 (下)

愛學習的小肥豬發表於2020-04-07

JVM 15
Q1:類的載入機制是什麼?
答:類載入到記憶體中主要有5個階段,分別為①載入:將Class檔案讀取到執行時資料區的方法區內,在堆中建立Class物件,並封裝類在方法區的資料結構的過程。②驗證:主要用於確保Class檔案符合當前虛擬機器的要求,保障虛擬機器自身的安全,只有通過驗證的Class檔案才能被JVM載入。③準備:主要工作是在方法區中為類變數分配記憶體空間並設定類中變數的初始值。④解析:將常量池中的符號引用替換為直接引用。⑤初始化:主要通過執行類構造器的<client>方法為類進行初始化,該方法是在編譯階段由編譯器自動收集類中靜態語句塊和變數的賦值操作組成的。JVM規定,只有在父類的<client>方法都執行成功後,子類的方法才可以被執行。在一個類中既沒有靜態變數賦值操作也沒有靜態語句塊時,編譯器不會為該類生成<client>方法。

Q2:有哪些類載入器,類載入器的載入模型是什麼,有什麼好處?
答:①主要有啟動類載入器,負責載入JAVA_HOME/lib中的類庫;擴充套件類載入器,負責載入JAVA_HOME/lib/ext中的類庫;應用程式類載入器,也稱系統類載入器,負責載入使用者類路徑上指定的類庫;也可以自定義類載入器。②類載入器之間的層次關係叫做雙親委派模型,要求除了頂層的啟動類載入器外其餘的類載入器都應當有自己的父類載入器。一個類收到類載入請求後會層層找父類載入器去嘗試載入,因此所有的載入請求最終都會被傳送到頂層的啟動類載入器,只有當父類載入器反饋自己無法完成載入時子載入器才會嘗試自己去載入。③雙親委派模型的好處是保障類載入的唯一性和安全性,例如載入rt.jar包中的java.lang.Object,無論哪一個類載入最終都會委託給啟動類載入器,這樣就保證了類載入的唯一性。如果存在包名和類名都相同的兩個類,那麼該類就無法被載入。

Q3:簡述JVM的記憶體區域
答:JVM的記憶體區域分為執行緒私有區域(程式計數器、虛擬機器棧、本地方法區)、執行緒共享區域(堆、方法區)和直接記憶體。①程式計數器是一塊很小的記憶體空間,用於儲存當前執行緒執行位元組碼檔案的行號指示器。②虛擬機器棧是描述Java方法執行過程的記憶體模型,幀棧中儲存了區域性變數表,運算元棧,動態連結,方法出口等資訊。③本地方法棧,和虛擬機器棧作用類似,區別是虛擬機器棧為Java方法服務,本地方法棧為Native方法服務。④JVM執行過程中建立的物件和生成的資料都儲存在堆中,堆是被執行緒共享的記憶體區域,也是垃圾回收最主要的記憶體區域。⑤方法區用來儲存常量,靜態變數、類資訊、即時編譯器編譯後的機器碼、執行時常量池等資料。

Q4:哪些情況下類不會初始化?
答:①常量在編譯時會存放在使用該常量的類的常量池,該過程不要呼叫常量所在的類,不會初始化。②子類引用父類的靜態變數時,子類不會初始化,只有父類會初始化。③定義物件陣列,不會觸發該類的初始化。④在使用類名獲取Class物件時不會觸發類的初始化。⑤在使用Class.forName()載入指定的類時,可以通過initialize引數設定是否需要初始化。⑥在使用ClassLoader預設的loadClass方法載入類時不會觸發該類的初始化。

Q5:哪些情況下類會初始化?
答:①建立類的例項。②訪問某個類或介面的靜態變數,或對該靜態變數賦值。③呼叫類的靜態方法。④初始化一個類的子類時(初始化子類,父類必須先初始化)。⑤JVM啟動時被標為啟動類的類。⑥使用反射進行方法呼叫時。

Q6:談談JVM的執行時記憶體
答:JVM的執行時記憶體也叫做JVM堆,從GC角度更將其分為新生代,老年代和永久代。
其中新生代預設佔1/3堆空間,老年代預設佔2/3堆空間,永久代佔非常少的堆空間。
新生代又分為Eden區、ServivorFrom區和ServivorTo區,Eden區預設佔8/10新生代空間,ServivorFrom區和ServivorTo區預設分別佔1/10新生代空間。

Q7:談談新生代是怎麼分割槽的
答:①JVM新建立的物件(除了大物件外)會被存放在新生代,預設佔1/3堆記憶體空間。由於JVM會頻繁建立物件,所以新生代會頻繁觸發MinorGC進行垃圾回收。②新生代又分為Eden區,ServivorFrom區和ServivorTo區。③Eden區:Java新建立的物件首先會被存放在Eden區,如果新建立的物件屬於大物件,則直接將其分配到老年代。大物件的定義和具體的JVM版本、堆大小和垃圾回收策略有關,一般為2KB~128KB,可通過-XX:PretenureSizeThreshold設定其大小。在Eden區的記憶體空間不足時會觸發MinorGC,對新生代進行一次垃圾回收。②ServivorTo區:保留上一次MinorGC時的倖存者。③ServivorFrom區:將上一次MinorGC時的倖存者作為這一次MinorGC的被掃描者。

Q8:談談新生代的垃圾回收機制
答:新生代的GC過程叫做MinorGC,採用複製演算法實現,具體過程如下:
①把在Eden區和ServivorFrom區中存活的物件複製到ServivorTo區,如果某物件的年齡達到老年代的標準,則將其複製到老年代,同時把這些物件的年齡加1。如果ServivorTo區的記憶體空間不夠,則也直接將其複製到老年代。如果物件屬於大物件,則也直接複製到老年代。②清空Eden區和ServivorFrom區中的物件。③將ServivorFrom區和ServivorTo區互換,原來的ServivorTo區成為下一次GC時的ServivorFrom區。

Q9:談談老年代的垃圾回收機制
答:①老年代主要存放有長生命週期的物件和大物件,老年代的GC叫MajorGC。②在老年代,物件比較穩定,MajorGC不會頻繁觸發。在進行MajorGC前,JVM會進行一次MinorGC,過後仍然出現老年代空間不足或無法找到足夠大的連續記憶體空間分配給新建立的大物件時,會觸發MajorGC進行垃圾回收,釋放JVM的記憶體空間。③MajorGC採用標記清除演算法,該演算法首先會掃描所有物件並標記存活的物件,然後回收未被標記的物件,並釋放記憶體空間。因為要先掃描老年代的所有物件再回收,所以MajorGC的時間較長。容易產生記憶體碎片,在老年代沒有記憶體空間可分配時,會出現記憶體溢位異常。

Q10:談一談永久代
答:①永久代指記憶體的永久儲存區域,主要存放Class和Meta(後設資料)的資訊。Class在類載入時被放入永久代。②永久代和老年代、新生代不同,GC不會在程式執行期間對永久代的記憶體進行清理,這也導致了永久代的記憶體會隨著載入的Class檔案的增加而增加,在載入的Class檔案過多時會出現記憶體溢位異常,比如Tomcat引用jar檔案過多導致JVM記憶體不足而無法啟動。③在JDK1.8中,永久代已經被後設資料區取代。後設資料區的作用和永久代類似,二者最大的區別在於:後設資料區並沒有使用虛擬機器的記憶體,而是直接使用作業系統的本地記憶體。因此元空間的大小不受JVM記憶體的限制,只和作業系統的記憶體有關。④在JDK1.8中,JVM將類的後設資料放入本地記憶體中,將常量池和類的靜態常量放入Java堆中,這樣JVM能夠載入多少後設資料資訊就不再由JVM的最大可用記憶體空間決定,而由作業系統的實際可用記憶體空間決定。

Q11:如何確定物件是否是垃圾?
答:①Java採用引用計數法和可達性分析來確定物件是否應該被回收。引用計數法容易產生迴圈引用的問題,可達性分析通過根搜尋演算法實現。根搜尋演算法以一系列GC Roots的點作為起點向下搜尋,在一個物件到任何GC Roots都沒有引用鏈相連時,說明其已經死亡。根搜尋演算法主要針對棧中的引用、方法區的靜態引用和JNI中的引用展開分析。②引用計數法:在Java中如果要操作物件,就必須先獲取該物件的引用,因此可以通過引用計數法來判斷一個物件是否可以被回收。在為物件新增一個引用時,引用計數加1;在為物件刪除一個引用時,引用計數減1;如果一個物件的引用計數為0,則表示此刻該物件沒有被引用,可以被回收。引用計數法容易產生迴圈引用問題,迴圈引用指兩個物件相互引用,導致它們的引用一直存在,而不能被回收。③可達性分析:為了解決引用計數法的迴圈引用問題,Java還採用了可達性分析來判斷物件是否可以被回收。具體做法是首先定義一些GC Roots物件,然後以這些GC Roots物件作為起點向下搜尋,如果在GC Roots和一個物件之間沒有可達路徑,則稱該物件是不可達的。不可達物件要經過至少兩次標記才能判斷其是否可被回收,如果兩次標記後該物件仍然不可達,則將被垃圾回收器回收。

Q12:有哪些GC演算法?分別有什麼特點?
答:①標記清除演算法:標記出所有需要回收的物件,然後清除可回收的物件。效率較低,並且因為在清除後沒有重新整理可用的記憶體空間,如果記憶體中可被回收的小物件居多,會引起記憶體碎片化問題。②複製演算法:將可用記憶體分為區域1和區域2,將新生成的物件放在區域1,在區域1滿後對區域1進行一次標記,將標記後仍然存活的物件複製到區域2,然後清除區域1。效率較高並且易於實現,解決了記憶體碎片化的問題,缺點是浪費了大量記憶體,同時在系統中存在長生命週期物件時會在兩區域間來回複製影響系統效率。③標記清除演算法:結合了標記清除演算法和複製演算法的優點,標記過程和標記清除演算法一樣,標記後將存活的物件移動到一端,清理另一端。④分代收集演算法:根據物件不同型別把記憶體劃分為不同區域,把堆劃分為新生代和老年代。由於新生代的物件生命週期較短,主要採用複製演算法。將新生代劃分為一塊較大的Eden區和兩塊較小的Survivor區,Servivor區又分為ServivorTo和ServivorFrom區。JVM在執行過程中主要使用Eden和SurvivorFrom區,進行垃圾回收時將這個兩個區域存活的物件複製到SurvivorTo區並清除這兩個區域。老年代主要儲存長生命週期的大物件,因此採用標記清除或標記整理演算法。

Q13:有哪些垃圾回收器?各自有什麼特點?
答:①Serial:單執行緒,基於複製演算法,JVM執行在Client時預設的新生代垃圾收集器。②ParNew:Serial的多執行緒實現,基於複製演算法,JVM執行在Server時預設 的新生代垃圾收集器。③Paraller Scavenge:多執行緒,基於複製演算法,以吞吐量最大化為目標,允許較長時間的STW換取吞吐量。④Serial Old:單執行緒,基於標記整理演算法,是JVM執行在Client模式下預設的老年代垃圾回收器,可和Serial搭配使用。⑤Parall Old:多執行緒,基於標記整理演算法,優先考慮系統的吞吐量。⑥CMS:多執行緒,基於標記清除演算法,為老年代設計,追求最短停頓時間。主要有四個步驟:初始標記、併發標記、重新標記、併發清除。⑥G1:將堆記憶體分為幾個大小固定的獨立區域,在後臺維護了一個優先列表,根據允許的收集時間回收垃圾收集價值最大的區域。相比CMS不會產生記憶體碎片,並且可精確控制停頓時間。分為四個階段:初始標記、併發標記、最終標記、篩選回收。

Q14:Java中有哪些引用型別?
答:①強引用,最常見的引用型別,把一個物件指向一個引用變數時就是強引用。強引用的物件一定為可達性狀態,所以不會被垃圾回收,是記憶體洩漏的主要原因。②軟引用,通過SoftReference實現,如果一個物件只有軟引用,當記憶體空間不足時將被回收。③弱引用,通過WeakReference實現,如果一個物件只有弱引用,在垃圾回收過程中一定會被回收。④虛引用,通過PhantomReference實現,虛引用和引用佇列聯合使用,主要用來跟蹤物件的垃圾回收過程。

Q15:JVM有哪些記憶體回收與回收策略?
答:①物件優先在Eden區分配:大多數情況下物件在新生代Eden區分配,當Eden區沒有足夠空間時,虛擬機器將發起一次MinorGC。②大物件直接進入老年代:大物件是指需要大量連續記憶體空間的Java物件,如很長的字串及陣列。虛擬機器提供了一個引數-XX:PretenureSizeThreshold,大於該值的物件會直接進入老年代,防止它在新生代之間來回複製。③長期存活的物件進入老年代:虛擬機器給每個物件定義了一個年齡計數器,若物件在Eden區出生、經過第一次MinorGC後仍存活且能被Survivor容納,將被移到Survivor區並且物件年齡設為1。每經過一次MinorGC,年齡就加1。預設在年齡增加到15時晉升到老年代,可通過-XX:MaxTenuringThreshold設定晉升老年代的年齡閾值。④動態物件年齡判定:如果在Survivor空間中相同年齡所有物件大小超過了該空間的一半,大於等於該年齡的物件就可以直接進入老年代而不用等到達到閾值。⑤空間分配擔保:發生MinorGC前,先判斷老年代最大可用連續空間是否大於新生代所有物件的總空間,如果成立那麼MinorGC是安全的。如果不成立會檢視HandlePromotionFailure是否允許擔保,如果允許會冒險進行MinorGC,否則改為一次FullGC。

反射與註解 3
Q1:簡述反射的基本概念,優缺點和使用場景。
答:①在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法,對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為Java的反射機制。② 優點是執行時動態獲取類的全部資訊,缺點是破壞了類的封裝性,泛型的約束性。③是框架的核心靈魂,動態代理設計模式採用了反射機制,還有 Spring、Hibernate 等框架也大量使用到了反射機制。

Q2:獲取Class物件有哪幾種方式?能通過Class物件獲取類的哪些資訊?
答:①通過類名.class②通過物件.getClass()③通過Class.forName(類的全限名);④可以通過Class物件獲取類的成員變數,方法或構造器。帶declared的獲取方法可以獲取到類的一個或全部成員變數,方法,構造器,不帶declared的方法只能獲取到類的public修飾的成員變數、方法或構造器,包括父類public修飾的成員變數、方法或構造器。

Q3:註解是什麼,元註解是什麼,有什麼作用?
答:①註解是一種標記,可以使類或介面附加額外的資訊,是幫助編譯器和JVM完成一些特定功能的。②元註解就是自定義註解的註解,包括@Target:用來約束註解的位置,值是ElementType列舉類,包括METHOD方法、VARIABLE變數、TYPE類/介面、PARAMETER方法引數、CONSTRUCTORS構造器和LOACL_VARIABLE區域性變數;@Rentention:用來約束註解的生命週期,值是RetentionPolicy列舉類,包括:SOURCE原始碼、CLASS位元組碼和RUNTIME執行時;@Documented:表明這個註解應該被javadoc工具記錄;@Inherited:表面某個被標註的型別是被繼承的。

IO流 5
Q1:簡單說說File物件表示的是什麼?File類有哪些常用方法?
答:①File物件表示的是作業系統上的檔案或目錄。②獲取:getAbsolutePath() 獲取絕對路徑;getPath() 獲取檔案定義時使用的路徑;getName() 獲取檔名,帶字尾;length() 返回檔案長度,單位是位元組。③判斷:exists() 判斷File物件表示的檔案或目錄是否存在;isDirectory() 判斷是否是目錄; isFile() 判斷是否是檔案。④建立和刪除:createNewFile() 不存在時建立新檔案;delete() 刪除檔案,目錄(非空目錄不能刪除);mkdir() 建立一級目錄;mkdirs() 建立多級目錄,推薦使用;⑤遍歷:list 獲取當前目錄下所有一級檔名稱到一個字串陣列並返回;listFiles 獲取當前目錄下所有一級File物件到File陣列返回。

Q2:英文、數字和中文字元在檔案中分別佔多大的空間?
答:①英文和數字在任何編碼中都佔1個位元組。②中文字元在GBK編碼下佔2個位元組,在UTF-8編碼下佔3個位元組。

Q3:簡述傳統IO有哪些分類?
答:①按流的方向:輸出流:把記憶體中的資料寫出到磁碟檔案或網路介質中;輸入流:把磁碟檔案或網路介質中的資料讀取到記憶體中。②按流的內容:位元組流:流中資料的最小單位是位元組;字元流:流中資料的最小單位是字元(針對文字內容)。頂層的抽象類包括InputStream、OutputStream、Reader、Writer,它們都實現了Closeable介面。③緩衝流(BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter):自帶一個8KB大小的緩衝池,可以將位元組/字元流為緩衝位元組/緩衝字元流。④字元轉換流(InputStreamReader/OutputStreamWriter):可以將對應的位元組流轉換為字元流。⑤列印流:PrintStream,方便快速列印資料,引數是什麼就列印什麼。

Q4:簡述BIO、NIO、AIO的區別和原理
答:①BIO是同步阻塞的,資料的讀寫會阻塞在一個執行緒中,適用於連線數目比較小且固定的架構,對伺服器資源要求高,JDK1.4前的唯一選擇。②NIO是同步非阻塞的,通過Selector監聽Channel上事件的變化,在Channel上有資料發生變化時通知該執行緒進行讀寫操作。適用於連線數目比較多且連線比較短的架構,如聊天伺服器,從 JDK1.4開始支援。③AIO是非同步非阻塞的,非同步是指服務端執行緒接收到客戶端管道後就交給底層處理IO通訊,自己可以做其他事情。適用於連線數目比較多且連線比較長的架構,從JDK1.7開始支援。

Q5:序列化和反序列化是什麼,有什麼要求?
答:①Java在JVM執行時被建立、更新和消耗,當JVM退出時,物件也會隨之銷燬。可以通過Java序列化實現持久化儲存,儲存物件及其狀態資訊到位元組陣列中。②反序列化就是再將位元組陣列中儲存的資訊轉換回Java物件。③要求類必須實現序列化介面,並且序列化和反序列化必須保持序列化的ID一致。④靜態變數和被transient修飾的變數不會被序列化。

JavaWeb 19
Q1:HTTP有哪些特點
答:①HTTP是基於TCP/IP協議的。②HTTP使用的預設埠號是80。③HTTP是基於請求/響應模型的,一次請求對應一次響應。④HTTP是無狀態的,每次請求之間相互獨立,不能互動資料。⑤HTTP1.0每一次請求響應都會建立新的連線,HTTP1.1會複用連線。

Q2:HTTP請求資料的資料格式是什麼?
答:①請求行,包括了請求方式、請求url、請求協議/版本。HTTP協議有7種請求方式,常用的有2種。GET方式,請求引數在請求行中,在url後、 請求的url長度有限制的、不太安全;POST方式,請求引數在請求體中、請求的url長度沒有限制的、相對安全。②請求頭,是客戶端瀏覽器告訴伺服器的一些資訊,常見的請求頭例如User-Agent,告訴伺服器使用的瀏覽器版本資訊,可以在伺服器端獲取該頭的資訊,解決瀏覽器的相容性問題。Referer,可以告訴伺服器,當前請求從哪裡來,可以防盜鏈或者進行統計資料。③請求空行,用於分割POST請求的請求頭和請求體的。④請求體(正文),封裝POST請求訊息的請求引數的。

Q3:轉發和重定向的區別?
答:①轉發的特點: 轉發位址列路徑不變、 轉發只能訪問當前伺服器下的資源、轉發是一次請求,可以使用request物件來共享資料。②重定向的特點:位址列發生變化、重定向可以訪問其他站點(伺服器)的資源、重定向是兩次請求,不能使用request物件來共享資料。

Q4:講一講Cookie
答:①Cookie是客戶端會話技術,將資料儲存到客戶端。②建立Cookie物件,繫結資料:new Cookie(String name, String value);傳送Cookie物件:response.addCookie(Cookie cookie),一次可以傳送多個Cookie;獲取Cookie,拿到資料:request.getCookies()。③瀏覽器對於單個cookie 的大小有限制(4kb) 以及對同一個域名下的總cookie數量也有限制(20個),cookie一般用於存出少量的不太敏感的資料,在不登入的情況下,完成伺服器對客戶端的身份識別。

Q5:Cookie的生命週期?
答:①預設情況下,當瀏覽器關閉後,Cookie資料被銷燬。②如果想要持久化儲存,可以使用setMaxAge(int seconds)。正數:將Cookie資料寫到硬碟的檔案中,持久化儲存,並指定cookie存活時間,時間到後,cookie檔案自動失效。負數:預設值。零:刪除cookie資訊。

Q6:Cookie可以儲存中文資料嗎?
答:①在tomcat 8 之前cookie中不能直接儲存中文資料,需要將中文資料轉碼—一般採用URL編碼(%E3)。②在tomcat 8 之後,cookie支援中文資料,特殊字元還是不支援,建議使用URL編碼儲存,URL解碼解析。

Q7:Cookie的共享範圍是什麼?
答:①假設在一個tomcat伺服器中,部署了多個web專案,那麼在這些web專案中cookie預設情況下不能共享。通過setPath(String path)設定cookie的獲取範圍,預設情況下,設定為當前的虛擬目錄,如果要共享,則可以將path設定為/。②不同的tomcat伺服器間cookie共享問題:通過setDomain(String path)設定一級域名,如果一級域名相同,那麼多個伺服器之間cookie可以共享。例如setDomain(".baidu.com"),那麼tieba.baidu.com和news.baidu.com中cookie可以共享。

Q8:講一講Session
答:①Session是伺服器端會話技術,在一次會話的多次請求間共享資料,將資料儲存在伺服器端的物件中。②獲取HttpSession物件:request.getSession();使用HttpSession物件:Object getAttribute(String name)、void setAttribute(String name, Object value)、void removeAttribute(String name)。③Session的實現是依賴於Cookie的,伺服器是通過cookie中的JESSIONID判斷session是否是同一個的。

Q9:Session的生命週期?當客戶端關閉後,伺服器不關閉,兩次獲取session是否為同一個?客戶端不關閉,伺服器關閉後,兩次獲取的session是同一個嗎?
答:①伺服器關閉、session物件呼叫invalidate() 時銷燬,session預設失效時間 30分鐘。②在預設情況下,當客戶端關閉服務端不關閉時,兩次獲取session值不是同一個。③如果需要相同,則可以建立Cookie,鍵為JSESSIONID,設定最大存活時間,讓cookie持久化儲存。④客戶端不關閉,服務端關閉,兩次獲取的session值也不是同一個。但是要確保資料不丟失。tomcat自動完成以下工作。session的鈍化: 在伺服器正常關閉之前,將session物件序列化到硬碟上。session的活化: 在伺服器啟動後,將session檔案轉化為記憶體中的session物件即可。但是IDEA不支援這種操作,因為每次用IDEA重啟tomcat時會自動刪除catalina_base中work目錄(程式動態生成的檔案),這樣在關閉tomcat時生成的session序列化檔案也會被刪除。

Q10:Session的特點,和Cookie有什麼區別?
答:①Session用於儲存一次會話的多次請求的資料,存在伺服器端。session可以儲存任意型別,任意大小的資料。②Session儲存資料在伺服器端,Cookie儲存資料在客戶端。
Session沒有儲存資料的大小限制,Cookie有資料大小限制。Session儲存資料是安全的,使用Cookie儲存資料相對於使用Session來說不安全。

Q11:EL是什麼?
答:①EL指Expression Language 表示式語言。②EL表示式的作用是替換和簡化jsp頁面中java程式碼的編寫。③EL表示式的語法是:${表示式}。④JSP預設支援EL表示式,如果要忽略EL表示式,設定JSP中page指令中的isELIgnored="true"忽略當前jsp頁面中所有的el表示式,也可以通過\${表示式} 忽略當前這個EL表示式。

Q12:JSTL是什麼?
答:①JSTL指JavaServer Pages Tag Library JSP標準標籤庫,是由Apache組織提供的開源的免費的JSP標籤。②JSTL的作用是簡化和替換jsp頁面上的Java程式碼。③使用時首先需要匯入JSTL相關jar包,並引入標籤庫: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>。

Q13:JSP定義Java程式碼有哪些方式?
答:①<% 程式碼 %>是JSP頁面中Java程式碼片段的容器,將頁面轉換為servlet類時,會將內容插入到servlet類的jspService()方法中,同時從JSP生成servlet。②<%! 程式碼 %>用於為JSP頁面宣告全域性的方法和變數。在JSP檔案中,必須先宣告這些變數和方法然後才能使用它們。在頁面轉換中,宣告的方法和變數成為JSP頁面的servlet類中的類成員宣告。語法③<%= 程式碼 %>用於將轉換為String的Java表示式的值插入到返回給客戶端的響應中。

Q14:JSP的內建物件有哪些?
答:①pageContext,真實型別是PageContext,可以在當前頁面共享資料,還可以獲取其他八個內建物件。②page,真實型別是Object,指當前頁面(Servlet)的物件this。③request,真實型別是HttpServletRequest,封裝客戶端的請求。④response,真實型別是HttpServletResponse,封裝服務端對客戶端的響應。⑤session,真實型別是HttpSession,封裝會話資料資訊。⑥out,真實型別是JspWriter,字元輸出流物件,可以將資料輸出到頁面上,和response.getWriter()類似。response.getWriter()和out的區別:在tomcat伺服器真正給客戶端做出響應之前,會先找response緩衝區資料,再找out緩衝區資料。response.getWriter().write()資料輸出永遠在out.write()之前。⑦config,真實型別是ServletConfig,是Servlet的配置物件。⑧exception,真實型別是Throwable,封裝頁面丟擲異常的物件。⑨application,真實型別是ServletContext,封裝伺服器執行環境的物件。

Q15:過濾器是什麼?如何使用?
答:①當訪問伺服器的資源時,過濾器可以將請求攔截下來,完成一些特殊的功能。②需要實現Filter介面,使用註解方式可以在類名上加上註解@WebFilter("攔截路徑"),使用XML的方式可以配置web.xml中的filter和filter-mapping標籤,設定過濾器類和攔截路徑。

Q16:過濾器的執行流程和生命週期是什麼?
答:①執行流程:執行過濾器,執行放行後的資源,回來執行過濾器放行程式碼下邊的程式碼。②生命週期:init:在伺服器啟動後,會建立Filter物件,然後呼叫init方法。只執行一次,一般用於載入資源。doFilter:在每一次請求被攔截資源時執行,會執行多次。destroy:在伺服器關閉後,Filter物件被銷燬,如果伺服器是正常關閉,則會執行destroy方法。只執行一次。一般用於釋放資源。

Q17:過濾器攔截路徑都有哪些方式?
答:①具體資源路徑:,例如/index.jsp ,只有訪問index.jsp資源時,過濾器才會被執行。②攔截目錄:例如/user/*,當訪問/user下的所有資源時,過濾器都會被執行。③通過字尾名攔截:例如*.jsp, 當訪問所有字尾名為jsp資源時,過濾器都會被執行。④攔截所有資源:使用/*,訪問所有資源時過濾器都會執行。

Q18:AJAX是什麼?
答:①Ajax 是一種在無需重新載入整個網頁的情況下,能夠更新部分網頁的技術。②通過在後臺與伺服器進行少量資料交換,Ajax 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。③傳統的網頁(不使用 Ajax)如果需要更新內容,必須過載整個網頁頁面,使用Ajax技術可以提升使用者的體驗。

Q19:JSON是什麼?如何把Java物件轉為JSON?如何把JSON轉回Java物件?
答:①JSON指JavaScript Object Notation JavaScript物件表示法。②JSON現在多用於儲存和交換文字資訊的語法,進行資料的傳輸。③JSON的優勢是想比XML來說佔用空間更小、運算元據更快,更易解析。④將Java物件轉為JSON時,需要先匯入jackson的相關jar包,建立Jackson核心物件 ObjectMapper,之後呼叫ObjectMapper的writeValue(引數,obj)進行轉換,如果引數是File型別,可以將obj物件轉換為JSON字串,並儲存到指定的檔案中;如果引數是Writer型別,可以將obj物件轉換為JSON字串,並將json資料填充到字元輸出流中;如果引數是OutputStream型別,可以將obj物件轉換為JSON字串,並將JSON資料填充到位元組輸出流中。⑤將JSON轉會Java物件時使用readValue的方法,引數為要轉回的Java物件的Class位元組碼物件。

JavaEE 29
Spring 7
Q1:Spring的IOC和DI是什麼?
答:①IOC即控制反轉,簡單來說就是把物件的控制權委託給spring框架,作用是降低程式碼的耦合度。②DI即依賴注入,是IOC的一種具體實現方式。假設一個Car類需要Engine的物件,那麼一般需要new一個Engine,利用IOC就是隻需要定義一個私有的Engine引用變數,容器會在執行時建立一個Engine的例項物件並將引用自動注入給變數。

Q2:簡述Spring中bean物件的生命週期
答:①Spring對bean進行例項化。②Spring將值和bean的引用注入到其對應的屬性中。③呼叫BeanNameAware的setBeanName方法。④呼叫BeanFactoryAware的setBeanFactory方法。⑤呼叫AppicationContxtAware的setApplicationContext方法。⑥呼叫BeanPostProcessor的post-ProcessBeforeInitialization方法。⑦呼叫InitializingBean的after-PropertiesSet方法。如果bean使用init-method宣告瞭自定義初始化方法,該方法也會被呼叫。⑧呼叫BeanPostProcessor的post-ProcessAfterInitialization方法。⑨使用bean。⑩呼叫DisposableBean的destroy方法,如果bean使用destroy-method宣告瞭自定義銷燬方法,該方法也會被呼叫。

Q3:簡述bean的作用範圍
答:通過scope指定bean的作用範圍,有①singleton:單例的,每次容器返回的物件是同一個。②prototype :多例的,每次返回的物件是新建立的例項。③request:僅作用於HttpRequest,每次Http請求都會建立一個新的bean。④session:僅作用於HttpSession,不同的Session使用不同的例項,相同的Session使用同一個例項。⑤global session :僅作用於HttpSession,所有的Session使用同一個例項。

Q4:BeanFactory和FactoryBean,ApplicationContext的區別?
答:①BeanFactory是一個Factory介面,是用來管理bean的IOC容器或物件工廠,較為古老,不支援spring的一些外掛。BeanFactory使用了延遲載入,適合多例模式。②FactoryBean是一個Bean介面,是一個可以生產或者裝飾物件的工廠Bean,可以通過實現該介面自定義的例項化Bean的邏輯。③ApplicationConext是BeanFactory的子介面,擴充套件了其功能,ApplicationContext是立即載入,適合單例模式。一般推薦使用ApplicationContext。

Q5:使用XML配置有哪些建立Bean物件的方式?
答:①通過預設無參構造器。使用bean標籤,只使用id和class屬性,如果沒有無參構造器會報錯。②使用靜態工廠,通過bean標籤中的class指明靜態工廠,factory-method指明靜態工廠方法。③使用例項工廠,通過bean標籤中的factory-bean指明例項工廠,factory-method指明例項工廠方法。

Q6:依賴注入可以注入哪些資料型別?有哪些注入方式?
答:①可以注入的資料型別有基本資料型別、String、Bean、以及集合等複雜資料型別。②有三種注入方式,第一種是通過構造器注入,通過constructor-arg標籤實現,缺點是即使不需要該屬性也必須注入;第二種是通過Set方法注入,通過property標籤實現,優點是建立物件時沒有明確限制,缺點是某個成員變數必須有值,在獲取物件時set方法可能還沒有執行;第三種是通過註解注入,利用@Autowired自動按型別注入,如果有多個匹配則按照指定bean的id查詢,查詢不到會報錯;@Qualifier在自動按照型別注入的基礎之上,再按照 Bean 的 id 注入,給成員變數注入時必須搭配@Autowired,給方法注入時可單獨使用;@Resource直接按照 Bean 的 id 注入;@Value用於注入基本資料型別和String。

Q7:有哪些配置Bean的註解,各有什麼區別?
答:①@Component,把當前類物件存入spring容器中,相當於在 xml 中配置一個 bean。value屬性指定 bean 的 id,如果不指定 value 屬性,預設 id 是當前類的類名,首字母小寫。②@Service,一般用於業務層。③@Controller:一般用於表現層。④@Repository:一般用於持久層。⑤@Controller @Service @Repository都是針對@Component的衍生註解,作用及屬性都是一模一樣的,只是提供了更加明確的語義化。

Spring Aop 4
Q1:Spring Aop的基本原理是什麼?
答:Aop即面向切面程式設計,簡單地說就是將程式碼中重複的部分抽取出來,在需要執行的時候使用動態代理的技術,在不修改原始碼的基礎上對方法進行增強。優點是可以減少程式碼的冗餘,提高開發效率,維護方便。Spring會根據類是否實現了介面來判斷動態代理的方式,如果實現了介面會使用JDK的動態代理,核心是InvocationHandler介面和Proxy類,如果沒有實現介面會使用cglib的動態代理,cglib是在執行時動態生成某個類的子類,如果某一個類被標記為final,是不能使用cglib動態代理的。

Q2:簡單解釋一下AOP的相關術語
答:①Joinpoint(連線點):指那些被攔截到的點,在 spring 中這些點指的是方法,因為 spring 只支援方法型別的連線點。例如業務層實現類中的方法都是連線點。②Pointcut(切入點):指我們要對哪些 Joinpoint 進行攔截的定義。例如業務層實現類中被增強的方法都是切入點,切入點一定是連線點,但連線點不一定是切入點。③Advice(通知/增強):指攔截到 Joinpoint 之後所要做的事情。④Introduction(引介):引介是一種特殊的通知,在不修改類程式碼的前提下可以在執行期為類動態地新增一些方法或 Field。⑤Weaving(織入):是指把增強應用到目標物件來建立新的代理物件的過程。spring 採用動態代理織入,而 AspectJ 採用編譯期織入和類裝載期織入。⑥Proxy(代理):一個類被 AOP 織入增強後,就產生一個結果代理類。⑦Target(目標):代理的目標物件。⑧Aspect(切面):是切入點和通知(引介)的結合。

Q3:Spring Aop有哪些相關注解?
答:@Before前置通知,@AfterThrowing異常通知,@AfterReturning後置通知,@After最終通知,@Around環繞通知。最終通知會在後置通知之前執行,為解決此問題一般使用環繞通知。

Q4:如何使用XML方式配置AOP?
答:①aop:config用於宣告開始 aop 的配置。②aop:aspect用於配置切面。屬性:id給切面提供一個唯一標識。ref引用配置好的通知類 bean 的 id。③aop:pointcut用於配置切入點表示式,就是指定對哪些類的哪些方法進行增強。屬性:expression用於定義切入點表示式,id用於給切入點表示式提供一個唯一標識。④aop:before用於配置前置通知,在切入點方法執行之前執行;aop:after-returning用於配置後置通知,在切入點方法正常執行之後執行,它和異常通知只能有一個執行;aop:after-throwing用於配置異常通知,在切入點方法執行產生異常後執行;aop:after用於配置最終通知,無論切入點方法執行時是否有異常,它都會在其後面執行。

Spring MVC 15
Q1:SpringMVC的作用是什麼?MVC的含義分別是什麼?
答:①springMVC是一種基於Java實現的mvc設計模型的請求驅動型別的輕量級Web層框架,作用包括:引數繫結(獲取請求引數)、呼叫業務層 、進行請求響應。②mvc全名是model view controller模型檢視控制器,model指資料模型,JavaBean的類,用來封裝資料;view指jsp,html等用來展示資料給使用者的介面;controller是整個流程的控制器,用來接收使用者請求以及進行資料校驗等功能。

Q2:要搭建一個最基礎的SpringMVC環境,你是如何配置的?
答:①在pom.xml中匯入以下jar包:org.springframework下的spring-context)、spring-web、spring-webmvc、javax.servlet下的servlet-api、javax.servlet.jsp下的jsp-api以及測試用的junit包。②建立一個springmvc.xml的springconfig配置檔案,開啟包掃描,註冊檢視解析器,配置檢視的字首和字尾。③在web.xml中配置核心控制器,servlet和servlet-mapping的對映等。

Q3:SpringMVC的基礎響應流程是怎樣的?
答:①瀏覽器傳送請求,被 DispatherServlet 捕獲,該 Servlet 並不處理請求,而是把請求轉發出去(控制器類),轉發的路徑是根據請求 URL,匹配@RequestMapping 中的內容②根據執行方法的返回值和檢視解析器(InternalResourceViewResolver),去指定的目錄下查詢指定名稱的檢視檔案,Tomcat伺服器渲染頁面,做出響應。

Q4:SpringMVC響應流程中會涉及到哪些元件?
答:①DispatcherServlet:前端控制器,使用者請求到達前端控制器,它就相當於 mvc 模式中的 c,dispatcherServlet 是整個流程控制的中心,由它呼叫其它元件處理使用者的請求,dispatcherServlet 的存在降低了元件之間的耦合性。②HandlerMapping:處理器對映器,負責根據使用者請求找到 Handler 即處理器,SpringMVC 提供了不同的對映器實現不同的對映方式,例如:配置檔案方式,實現介面方式,註解方式等。③Handler:處理器,它就是我們開發中要編寫的具體業務控制器。由 DispatcherServlet 把使用者請求轉發到 Handler。由Handler 對具體的使用者請求進行處理。④HandlAdapter:處理器介面卡,
通過 HandlerAdapter 對處理器進行執行,這是介面卡模式的應用,通過擴充套件介面卡可以對更多型別的處理器進行執行⑤View Resolver:檢視解析器,負責將處理結果生成 View 檢視,View Resolver 首先根據邏輯檢視名解析成物理檢視名,即具體的頁面地址,再生成 View 檢視物件,最後對 View 進行渲染將處理結果通過頁面展示給使用者。⑥View:檢視,SpringMVC 提供了很多 View 檢視型別的支援,包括:jstlView、freemarkerView、pdfView等。最常用的檢視就是 jsp。一般情況下需要通過頁面標籤或頁面模版技術將模型資料通過頁面展示給使用者,需要由程式設計師根據業務需求開發具體的頁面。

Q5:講一講@RequestMapping註解
答:①作用:建立請求url和處理方法之間的對應關係。②作用位置:類,請求url的第一級訪問目錄,如果不寫相當於根目錄,需要以/開頭;方法,請求url的第二級訪問目錄,可以不以/開頭。③屬性:value/path,繫結路徑,支援多個路徑,一般只配置一個路徑;method 指定訪問方式,可配置多個允許的訪問方式,預設任何方法都支援,例如POST、GET等。

Q6:SpringMVC的引數繫結支援哪些型別,分別有哪些要求?
答:①基本資料型別和String,要求請求引數的引數名必須和控制器中方法的形參名一致,例如請求引數為name,控制器方法的形參也必須為name。②可以是Java物件,要求請求屬性必須和對應的Java類中的成員變數名一致,例如input標籤的name屬性值為id,類中也必須有id這一個成員變數。也可以是Java物件中的List或Map集合。

Q7:如何解決請求引數中文亂碼問題?
答:在web.xml中配置一個過濾器,配置一個filter標籤,使用org.springframework.web.filter包下的CharacterEncodingFilter類實現,將<init-param>中的<param-name>設定為encoding,對應的<param-value>設定為UTF-8即可。然後配置對應的fiter-mapping標籤,fiter-name和之前的一樣,<url-pattern>設定為/*,表示對所有檢視都進行編碼過濾。

Q8:SpringMVC支援哪些Servlet物件作為控制器方法的引數?
答:一共有9個,包括①HttpServletRequest,指客戶端的請求。②HttpServletResponse,指伺服器端的響應。③HttpSession,Java平臺對session機制的實現規範。④Principal,此介面表示主體的抽象概念,它可以用來表示任何實體,例如,個人、公司或登入id。⑤Locale,用於國際化操作的類。⑥InputStream,位元組輸入流。⑦OutputStream,位元組輸出流。⑧Reader,字元輸入流。⑨Writer,字元輸出流。

Q9:SpringMVC的常用註解有哪些?
答:①@RequestParam:作用是將請求引數和控制器中方法形參繫結(請求引數名和形參名不再要求相同)。屬性包括:name/value,當和請求引數名一致可省略;required指定請求引數是否必填項;defaultValue是未提供請求引數時的預設值。②@RequestBody:作用是用於獲取請求體的內容,直接使用得到的是key=value形式的字串,把獲取的json資料轉換成pojo物件(get方式不可用)。③@RequestBody:作用是將控制器中方法返回的物件通過適當的轉換器轉換為指定的格式之後進行響應,通常用來返回JSON資料或者是XML。④@PathVariable:作用是繫結url中的佔位符,例如請求url中/delete/{id},{id}就是url佔位符。url支援佔位符是spring3.0後加入的,是springmvc支援rest風格url的一個重要標誌。屬性包括name/value 指定url中佔位符名稱;required指定是否必須提供佔位符。⑤@RequestHeader:作用是獲取指定請求頭的值。屬性:value代表請求頭的名稱。⑥@CookieValue:作用是用於把指定 cookie 名稱的值傳入控制器方法引數。屬性包括value:指定 cookie 的名稱。required:是否必須有此 cookie。⑦@ModelAttribute:是 SpringMVC4.3 版本以後加入的,它可以修飾方法和引數,出現在方法上表示當前方法會在控制器的方法執行之前先執行。它可以修飾沒有返回值的方法,也可以修飾有具體返回值的方法。出現在引數上,獲取指定的資料給引數賦值。屬性value用於獲取資料的 key。key 可以是 POJO 的屬性名稱,也可以是 map 結構的 key。

Q10:響應資料的格式有哪些?
答:①字串,控制器中的方法返回字串可以指定邏輯檢視名,通過檢視解析器解析為物理檢視地址,例如返回"success"時可解析為success.jsp頁面。②返回值為空,預設訪問檢視解析器字首+requestmapping路徑+檢視解析器字尾的檢視。③ModelandView,可以通過setViewName()方法設定檢視名實現指定檢視的跳轉。

Q11:SpringMVC中如何實現轉發和重定向,有什麼區別?
答:①前提是控制器方法返回值型別必須是String型別。②轉發到頁面return"forward:+絕對地址"。轉發到控制器其他方法:return的是"forward:+類上requestmapping的地址+方法上requestmapping的地址"。③重定向到頁面:return的是"redirect:+絕對地址",注意不能重定向訪問WEB-INF下的資源。重定向到控制器其他方法:return的是"redirect:+類上requestmapping的地址+方法上requestmapping的地址"。重定向到外部連結:return的是"redirect:+連結地址(http://www.qq.com)"。④轉發和重定向的區別是轉發只是一次請求,重定向是兩次請求;轉發位址列不變,重定向位址列將改變;轉發只能到內部資源,重定向可以到內部或外部資源;轉發可以到WEB-INF下資源,重定向不可以。

Q12:SpringMVC實現簡單檔案上傳有哪些要求?
答:①瀏覽器端要求:表單提交方式為post(get有檔案大小限制)。提供檔案上傳框對應的標籤:<input type="file">。表單的entype屬性必須為multipart/form-data。②伺服器端要求:使用**request.getInputStream()**獲取資料。springmvc底層封裝了commons-fileupload檔案上傳工具包。

Q13:SpringMVC的異常處理流程是什麼?
答:Dao層發生的異常會向上丟擲到Service層、Service層的異常會向上丟擲到Controller層,Controller層的異常會繼續向上丟擲到SpringMVC的前端控制器,由前端控制器將異常交給SpringMVC的異常處理器進行處理。如果是自定義的異常處理器,需要實現HandlerExceptionResolver介面,並使用@Component註解配置或在對應的springconfig配置檔案中註冊。

Q14:SpringMVC中的攔截器和攔截器鏈是什麼,和過濾器有什麼區別?
答:①Spring MVC 的攔截器用於對處理器進行預處理和後處理,使用者可以自己定義一些攔截器來實現特定的功能。攔截器鏈就是將攔截器按一定的順序聯結成一條鏈,在訪問被攔截的方法或欄位時,攔截器鏈中的攔截器就會按其之前定義的順序被呼叫。②它和過濾器的區別是:過濾器是 servlet 規範中的一部分,任何 java web 工程都可以使用,攔截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用;過濾器在 url-pattern 中配置了/*之後,可以對所有要訪問的資源攔截,攔截器它是隻會攔截訪問的控制器方法,如果訪問的是 jsp、html、css、image 或者 js 是不會進行攔截的;它也是 AOP 思想的具體應用,如果要想自定義攔截器, 要求必須實現HandlerInterceptor 介面。

Q15:攔截器有哪些常用方法,各自有什麼特點?
答:①preHandle:按攔截器定義順序呼叫,只要配置了都會呼叫。如果程式設計師決定該攔截器對請求進行攔截處理後還要呼叫其他的攔截器,或者是業務處理器去進行處理,則返回 true,如果不需要再呼叫其他的元件去處理請求,則返回 false。②postHandle:
按攔截器定義逆序呼叫,在攔截器鏈內所有攔截器返回成功時呼叫。在業務處理器處理完請求後,但是 DispatcherServlet 向客戶端返回響應前被呼叫, 在該方法中對使用者請求 request 進行處理。③afterCompletion:按攔截器定義逆序呼叫,只有 preHandle 返回 true時才呼叫。在 DispatcherServlet 完全處理完請求後被呼叫,可以在該方法中進行一些資源清理的操作。

Mybatis 3
Q1:延遲載入是什麼?Mybatis支援嗎?
答:①Mybatis支援延遲載入。實際開發過程中很多時候我們並不需要總是在載入某些資訊時就一定要載入其關聯資訊,例如在載入使用者資訊時不是使用者關聯的賬戶資訊不是必需的,此時就可以採用延遲載入。②延遲載入就是在需要用到資料時才進行載入,不需要用到資料時就不載入資料。延遲載入也稱懶載入。③好處:先從單表查詢,需要時再從關聯表去關聯查詢,大大提高資料庫效能,因為查詢單表要比關聯查詢多張錶速度要快。④壞處:因為只有當需要用到資料時,才會進行資料庫查詢,這樣在大批量資料查詢時,因為查詢工作也要消耗時間,所以可能造成使用者等待時間變長,造成使用者體驗下降。

Q2:講一講Mybatis的快取
答:Mybatis的快取分為:①一級快取:指的是Mybatis中SqlSession物件的快取,當我們執行完查詢結果後,查詢的結果會同時存入到SqlSession為我們提供的一塊區域中,該區域的結構是一個Map,當我們再次查詢同樣資料時,Mybatis會先去SqlSession中查詢是否有,有的話直接拿出來用。當SqlSession物件消失時,Mybatis的一級快取也就消失了。一級快取是 SqlSession 範圍的快取,當呼叫 SqlSession 的修改,新增,刪除,commit(),close()等方法時,就會清空一級快取。②二級快取:二級快取是 mapper 對映級別的快取,多個 SqlSession 去操作同一個 Mapper 對映的 sql 語句,多個SqlSession 可以共用二級快取,二級快取是跨 SqlSession 的。

Q3:如何開啟Mybatis的二級快取?
答:①在springconfig配置檔案中,將setting標籤的cacheEnabled值設定為true(預設值為true,所以這一步可省略)。②配置相關的 Mapper 對映檔案,使用<cache>標籤表示當前這個 mapper 對映將使用二級快取。③配置 statement 上面的 useCache 屬性,設定 useCache=”true”代表當前這個 statement 要使用二級快取,如果不使用二級快取可以設定為 false。針對每次查詢都需要最新的資料 sql,要設定成 useCache=false,禁用二級快取。④如果是使用註解的方式,可以省略第二步,只需要在dao層介面上加上註解@CacheNamespace(blocking=true)。

資料庫 47
MySQL 21
Q1:MySQL主要有哪些儲存引擎,分別適合哪些應用場景?
答:主要有①MyISAM,是5.5版本之前的預設儲存引擎,支援表級鎖,不支援事務和外來鍵,併發效率較低,讀取資料快,更新資料慢。適合以讀操作為主,並且對併發性要求較低的應用。②InnoDB,MySQL目前的預設儲存引擎,支援行級鎖、事務和外來鍵,併發效率好。適合對事務的完整性和併發性、資料的準確性要求比較高,增刪操作多的應用。③Memory,所有的資料都儲存在記憶體中,訪問速度快,一旦服務關閉資料將丟失。適合更新不太頻繁的資料量小的表用來快速得到訪問結果。④Archive、Federated等。

Q2:索引是什麼?
答:MySQL官方對索引的定義為:索引(index)是幫助MySQL高效獲取資料的資料結構(有序)。在資料之外,資料庫系統還維護者滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料, 這樣就可以在這些資料結構上實現高階查詢演算法,這種資料結構就是索引。

Q3:索引的優缺點有哪些?
答:①優勢:提高資料檢索的效率,降低資料庫的IO成本。通過索引列對資料進行排序,降低資料排序的成本,降低CPU的消耗。②劣勢:實際上索引也是一張表,該表中儲存了主鍵與索引欄位,並指向實體類的記錄,所以索引列也是要佔用空間的。 雖然索引大大提高了查詢效率,同時卻也降低更新表的速度,如對錶進行INSERT、UPDATE、DELETE。因為更新表時,MySQL 不僅要儲存資料,還要儲存一下索引檔案每次更新新增了索引列的欄位,都會調整因為更新所帶來的鍵值變化後的索引資訊。

Q4:MySQL支援哪幾種索引?
答:①BTREE 索引 : 最常見的索引型別,大部分索引都支援 B 樹索引。②HASH 索引:只有Memory引擎支援 , 使用場景簡單 。③R-tree 索引(空間索引):空間索引是MyISAM引擎的一個特殊索引型別,主要用於地理空間資料型別,通常使用較少,不做特別介紹。④Full-text (全文索引) :全文索引也是MyISAM的一個特殊索引型別,主要用於全文索引,InnoDB從Mysql5.6版本開始支援全文索引。

Q5:B+樹是什麼和B樹有什麼區別?
答:①BTree又叫多路平衡搜尋樹,一顆m叉的BTree特性如下: 樹中每個節點最多包含m個孩子。 除根節點與葉子節點外,每個節點至少有[ceil(m/2)]個孩子。若根節點不是葉子節點,則至少有兩個孩子。所有的葉子節點都在同一層。每個非葉子節點由n個key與n+1個指標組成,其中[ceil(m/2)-1] <= n <= m-1。②B+Tree為BTree的變種,B+Tree與BTree的區別為: n叉B+Tree最多含有n個key,而BTree最多含有n-1個key。 B+Tree的葉子節點儲存所有的key資訊,依key大小順序排列。所有的非葉子節點都可以看作是key的索引部分。③由於B+Tree只有葉子節點儲存key資訊,查詢任何key都要從root走到葉子。所以B+Tree的查詢效率更加穩定。

Q6:MySQL的索引對B+樹做了哪些優化?
答:MySql索引資料結構對經典的B+Tree進行了優化。在原B+Tree的基礎上,增加一個指向相鄰葉子節點的連結串列指標,就形成了帶有順序指標的B+Tree,提高區間訪問的效能。

Q7:索引有哪些分類?
答:①單值索引 :即一個索引只包含單個列,一個表可以有多個單列索引。②唯一索引 :索引列的值必須唯一,但允許有空值。③複合索引 :即一個索引包含多個列。

Q8:資料庫的索引建立有哪些設計原則?
答:①對查詢頻次較高,資料量較大的表建立索引。②限制索引數量:對於增刪改操作較多的表,如果索引過多將需要很高的維護代價,降低操作效率,增加操作耗時。③利用最左字首:如果索引欄位值過長,會降低索引的執行效率。④刪除不常用索引。⑤使用唯一索引,區分度越高,效率越高。⑤使用短索引,如果索引值很長則佔用磁碟變大,會影響效。⑥為常作為查詢條件、經常需要排序、分組和聯合操作的欄位建立索引。⑦儘量擴充套件現有索引,聯合索引的效率高於多個獨立索引。

Q9:索引在什麼情況下會失效?
答:①複合索引未使用最左列索引時或跳躍使用時失效,例如以name,age和sex欄位建立索引,只使用age和sex或只使用name和sex時索引失效。②在索引上進行運算或函式操作時索引失效。③數字字元沒有加單引號索引失效,因為MySQL查詢優化器會自動進行型別轉換。④LIKE以%開頭的查詢索引失效,%在前時執行計劃更傾向於使用全表掃描。⑤OR的前後沒有同時使用索引時索引失效。⑥當全表掃描比使用索引速度更快時會使用全表掃描。

Q10:簡述資料庫三大正規化
答:①第一正規化:如果每列都是不可再分的最小資料單元,則滿足第一正規化。例如address:中國北京可拆分為兩列,countyr:中國,city:北京。②第二正規化:在第一正規化的基礎上,規定表中的非主鍵列不存在對主鍵的部分依賴,即第二正規化要求每個表只描述一件事情。例如訂單表:訂單編號、產品編號、訂單日期、產品價格可拆分為訂單表:訂單編號、訂單日期和產品表:產品編號、產品價格。③第三正規化:滿足第一和第二正規化,並且表中的列不存在對非主鍵列的傳遞依賴。例如訂單表:訂單編號、訂單日期、使用者編號、使用者姓名可優化為訂單表:訂單編號、訂單日期、使用者姓名。

Q11:MySQL資料庫的隔離級別有哪些?分別有什麼特點?
答:①未提交讀,一個事務會讀取到另一個事務沒有提交的資料,存在髒讀、不可重複讀、幻讀的問題。②已提交讀,一個事務可以讀取到另一個事務已經提交的資料,解決了幻讀的問題,存在不可重複讀、幻讀的問題。③可重複讀,MySQL預設的隔離級別,在一次事務中讀取同一個資料結果是一樣的,解決了不可重複讀的問題,存在幻讀問題。④可序列化,每次讀都需要獲得表級共享鎖,讀寫互相阻塞,效率低,解決了幻讀問題。

Q12:讀取資料庫時可能出現哪些問題?
答:①髒讀,一個事務中會讀取到另一個事務中還沒有提交的資料,如果另一事務最終回滾了資料,那麼所讀取到的資料就是無效的。②不可重複讀,一個事務中可以讀取到另一個事務中已經提交的資料,在同一次事務中對同一資料讀取的結果可能不同。③幻讀,一個事務在讀取資料時,當另一個事務在表中插入了一些新資料時再次讀取表時會多出幾行,如同出現了幻覺。

Q13:簡述事務的ACID屬性
答:①Atomicity表示原子性,事務中的所有操作都是不可分割的原子單位,要麼全部成功,要麼全部失敗。②Consistency表示一致性,無論正常執行還是異常退出,事務執行前後資料的完整性必須保持一致,比如轉賬前後雙方的總金額是不變的。③Isolation表示隔離性,併發操作中不同事務是互相隔離的,之間不會互相影響。④Durability表示永續性,事務操作完成後資料就會被持久化修改到永久儲存中。

Q14:簡述主從複製的基本原理
答:①主從複製是指一臺伺服器充當主資料庫伺服器,另外一臺或多臺伺服器充當從資料庫伺服器,主伺服器中的資料自動複製到從伺服器中。對於多級複製,資料庫伺服器既可充當主機也可充當從機。②MySQL主從複製的基礎是主伺服器對資料庫修改二進位制記錄,從伺服器通過主伺服器的二進位制日誌自動執行更新。

Q15:MySQL有哪些鎖?
答:①按操作型別可以分為讀鎖(共享鎖S)和寫鎖(排它鎖X)。讀鎖:對同一份資料,多個讀操作可以同時進行而不會互相影響。寫鎖:當前操作沒有完成之前,會阻塞其他讀鎖和寫鎖。②按操作粒度分為行鎖、表鎖、頁鎖。行鎖指對某行資料加鎖,是一種排它鎖。表鎖指對當前操作的整張表加鎖,實現簡單,資源消耗較少。③頁鎖的鎖定粒度介於行鎖和表鎖之間,一次鎖定相鄰的一組記錄。

Q16:檢視是什麼?和普通的表有什麼區別?
答:①檢視(View)是一種虛擬存在的表。檢視並不在資料庫中實際存在,行和列資料來自定義檢視的查詢中使用的表,並且是在使用檢視時動態生成的。通俗的講,檢視就是一條SELECT語句執行後返回的結果集。所以我們在建立檢視的時候,主要的工作就落在建立這條SQL查詢語句上。②檢視相對於普通的表的優勢主要包括以下幾項:簡單:使用檢視的使用者完全不需要關心後面對應的表的結構、關聯條件和篩選條件,對使用者來說已經是過濾好的複合條件的結果集。安全:使用檢視的使用者只能訪問他們被允許查詢的結果集,對錶的許可權管理並不能限制到某個行某個列,但是通過檢視就可以簡單的實現。資料獨立:一旦檢視的結構確定了,可以遮蔽表結構變化對使用者的影響,源表增加列對檢視沒有影響;源表修改列名,則可以通過修改檢視來解決,不會造成對訪問者的影響。

Q17:儲存過程和函式是什麼?有什麼區別?
答:①儲存過程和函式是 事先經過編譯並儲存在資料庫中的一段 SQL 語句的集合,呼叫儲存過程和函式可以簡化應用開發人員的很多工作,減少資料在資料庫和應用伺服器之間的傳輸,對於提高資料處理的效率是有好處的。        ②兩者的區別在於函式必須有返回值,而儲存過程沒有返回值。

Q18:觸發器是什麼?
答:①觸發器是與表有關的資料庫物件,指在 insert/update/delete 之前或之後,觸發並執行觸發器中定義的SQL語句集合。觸發器的這種特性可以協助應用在資料庫端確保資料的完整性 , 日誌記錄 , 資料校驗等操作 。②使用別名 OLD 和 NEW 來引用觸發器中發生變化的記錄內容,這與其他的資料庫是相似的。現在觸發器還只支援行級觸發,不支援語句級觸發。

Q19:瞭解MySQL的體系結構嗎?
答:① 連線層:最上層是一些客戶端和連結服務,包含本地sock 通訊和大多數基於客戶端/服務端工具實現的類似於 TCP/IP的通訊。主要完成一些類似於連線處理、授權認證、及相關的安全方案。在該層上引入了執行緒池的概念,為通過認證安全接入的客戶端提供執行緒。同樣在該層上可以實現基於SSL的安全連結。伺服器也會為安全接入的每個客戶端驗證它所具有的操作許可權。②服務層:第二層架構主要完成大多數的核心服務功能,如SQL介面,並完成快取的查詢,SQL的分析和優化,部分內建函式的執行。所有跨儲存引擎的功能也在這一層實現,如 過程、函式等。在該層,伺服器會解析查詢並建立相應的內部解析樹,並對其完成相應的優化如確定表的查詢的順序,是否利用索引等, 最後生成相應的執行操作。如果是select語句,伺服器還會查詢內部的快取,如果快取空間足夠大,這樣在解決大量讀操作的環境中能夠很好的提升系統的效能。③ 引擎層:儲存引擎層, 儲存引擎真正的負責了MySQL中資料的儲存和提取,伺服器通過API和儲存引擎進行通訊。不同的儲存引擎具有不同的功能,這樣我們可以根據自己的需要,來選取合適的儲存引擎。④儲存層:資料儲存層, 主要是將資料儲存在檔案系統之上,並完成與儲存引擎的互動。

Q20:儲存引擎應當怎樣進行選擇?
答:①在選擇儲存引擎時,應該根據應用系統的特點選擇合適的儲存引擎。對於複雜的應用系統,還可以根據實際情況選擇多種儲存引擎進行組合。以下是幾種常用的儲存引擎的使用環境。②InnoDB : 是Mysql的預設儲存引擎,用於事務處理應用程式,支援外來鍵。如果應用對事務的完整性有比較高的要求,在併發條件下要求資料的一致性,資料操作除了插入和查詢意外,還包含很多的更新、刪除操作,那麼InnoDB儲存引擎是比較合適的選擇。InnoDB儲存引擎除了有效的降低由於刪除和更新導致的鎖定, 還可以確保事務的完整提交和回滾,對於類似於計費系統或者財務系統等對資料準確性要求比較高的系統,InnoDB是最合適的選擇。③MyISAM : 如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性、併發性要求不是很高,那麼選擇這個儲存引擎是非常合適的。④MEMORY:將所有資料儲存在RAM中,在需要快速定位記錄和其他類似資料環境下,可以提供幾塊的訪問。MEMORY的缺陷就是對錶的大小有限制,太大的表無法快取在記憶體中,其次是要確保表的資料可以恢復,資料庫異常終止後表中的資料是可以恢復的。MEMORY表通常用於更新不太頻繁的小表,用以快速得到訪問結果。⑤MERGE:用於將一系列等同的MyISAM表以邏輯方式組合在一起,並作為一個物件引用他們。MERGE表的優點在於可以突破對單個MyISAM表的大小限制,並且通過將不同的表分佈在多個磁碟上,可以有效的改善MERGE表的訪問效率。這對於儲存諸如資料倉儲等VLDB環境十分合適。

Q21:優化SQL的步驟瞭解嗎?
答:①檢視SQL執行頻率。②定位低效率執行SQL。可以通過以下兩種方式:慢查詢日誌 : 通過慢查詢日誌定位那些執行效率較低的 SQL 語句。show processlist : 慢查詢日誌在查詢結束以後才記錄,所以在應用反映執行效率出現問題的時候查詢慢查詢日誌並不能定位問題,可以使用show processlist命令檢視當前MySQL在進行的執行緒,包括執行緒的狀態、是否鎖表等,可以實時地檢視 SQL 的執行情況,同時對一些鎖表操作進行優化。③通過以上步驟查詢到效率低的 SQL 語句後,可以通過 EXPLAIN或者 DESC命令獲取 MySQL如何執行 SELECT 語句的資訊,包括在 SELECT 語句執行過程中表如何連線和連線的順序。④Mysql從5.0.37版本開始增加了對 show profiles 和 show profile 語句的支援。show profiles 能夠在做SQL優化時幫助我們瞭解時間都耗費到哪裡了。⑤MySQL5.6提供了對SQL的跟蹤trace, 通過trace檔案能夠進一步瞭解為什麼優化器選擇A計劃, 而不是選擇B計劃。開啟trace , 設定格式為 JSON,並設定trace最大能夠使用的記憶體大小,避免解析過程中因為預設記憶體過小而不能夠完整展示。

JDBC 10
Q1:瞭解JDBC嗎?
答:①JDBC(Java Database Connectivity)是一個獨立於特定資料庫管理系統、通用的SQL資料庫存取和操作的公共介面(一組API),定義了用來訪問資料庫的標準Java類庫(java.sql,javax.sql),使用這些類庫可以以一種標準的方法方便地訪問資料庫資源。
②JDBC為訪問不同的資料庫提供了統一的途徑,為開發者遮蔽了一些細節問題。③JDBC的目標是使Java程式設計師使用JDBC可以連線任何提供了JDBC驅動程式的資料庫系統,這樣就使得程式設計師無需對特定的資料庫系統的特點有過多的瞭解,從而大大簡化和加快了開發過程。

Q2:JDBC的操作步驟?
答:①匯入相應的jar包。②載入、註冊sql驅動。③獲取Connection連線物件。④建立Statement物件並執行SQL語句。⑤使用ResultSet物件獲取查詢結果集。⑥依次關閉ResultSet、Statement、Connection物件。

Q3:Statement和PrepatedStatement的區別是什麼?
答:①Statement:用於執行靜態 SQL 語句並返回它所生成結果的物件。②PrepatedStatement:SQL 語句被預編譯並儲存在此物件中,可以使用此物件多次高效地執行該語句。③使用Statement運算元據表存在弊端:存在拼串操作,繁瑣;存在SQL隱碼攻擊問題。④PreparedStatement程式碼的可讀性和可維護性更強,能實現更高效的批量操作。DBServer會對預編譯語句提供效能優化。因為預編譯語句有可能被重複呼叫,所以語句在被DBServer的編譯器編譯後的執行程式碼被快取下來,那麼下次呼叫時只要是相同的預編譯語句就不需要編譯,只要將引數直接傳入編譯過的語句執行程式碼中就會得到執行。在statement語句中,每執行一次都要對傳入的語句編譯一次。⑤PreparedStatement 可以防止 SQL 注入,還可以操作Blob類資料。

Q4:ResultSet物件儲存的是什麼?
答:①PreparedStatement 的 executeQuery()方法,查詢結果是一個ResultSet 物件,
ResultSet 物件以邏輯表格的形式封裝了執行資料庫操作的結果集,ResultSet 介面由資料庫廠商提供實現。②ResultSet 返回的實際上就是一張資料表,有一個指標指向資料表的第一條記錄的前面。③ResultSet 物件維護了一個指向當前資料行的遊標,初始的時候,遊標在第一行之前,可以通過 ResultSet 物件的next()方法移動到下一行。呼叫 next()方法檢測下一行是否存在。若存在,該方法返回true,且指標下移,相當於Iterator物件的 hasNext() 和 next()方法的結合體。可以通過呼叫對應的getXxx()獲取每一列的值。

Q5:ResultSetMetaData物件儲存的是什麼?
答:①可用於獲取關於 ResultSet 物件中列的型別和屬性資訊的物件。②通過呼叫ResultSet物件的getMetaData()方法獲得ResultSetMetaData物件,getColumnName(int column):獲取指定列的名稱,getColumnLabel(int column):獲取指定列的別名
,getColumnCount():返回當前 ResultSet 物件中的列數。

Q6:JDBC要釋放的資源有哪些,釋放的順序是什麼?
答:①釋放ResultSet, Statement,Connection。②資料庫連線(Connection)是非常稀有的資源,用完後必須馬上釋放,如果Connection不能及時正確的關閉將導致系統問題。Connection的使用原則是儘量晚建立,儘量早的釋放。③可以在finally中釋放資源,保證及時其他程式碼出現異常,資源也一定能被釋放。

Q7:資料庫連線池是什麼?它的工作原理是怎樣的?
答:①傳統開發模式存在的問題:普通的JDBC資料庫連線使用 DriverManager 來獲取,每次向資料庫建立連線的時候都要將 Connection 載入到記憶體中,資料庫的連線資源並沒有得到很好的重複利用。若在高併發情況下,頻繁進行資料庫連線操作將佔用很多的系統資源,嚴重的甚至會造成伺服器的崩潰。對於每一次資料庫連線,使用完後都得斷開。否則,如果程式出現異常而未能關閉,將會導致資料庫系統中的記憶體洩漏,最終將導致重啟資料庫。不能控制被建立的連線物件數,系統資源會被毫無顧及的分配出去,如連線過多,也可能導致記憶體洩漏,伺服器崩潰。②為解決傳統開發中的資料庫連線問題,可以採用資料庫連線池技術。基本思想:就是為資料庫連線建立一個“緩衝池”。預先在緩衝池中放入一定數量的連線,當需要建立資料庫連線時,只需從“緩衝池”中取出一個,使用完畢之後再放回去。資料庫連線池負責分配、管理和釋放資料庫連線,它允許應用程式重複使用一個現有的資料庫連線,而不是重新建立一個。③資料庫連線池在初始化時將建立一定數量的資料庫連線放到連線池中,這些資料庫連線的數量是由最小資料庫連線數來設定的。無論這些資料庫連線是否被使用,連線池都將一直保證至少擁有這麼多的連線數量。連線池的最大資料庫連線數量限定了這個連線池能佔有的最大連線數,當應用程式向連線池請求的連線數超過最大連線數量時,這些請求將被加入到等待佇列中。

Q8:資料庫連線池有哪些優點?
答:①資源重用:由於資料庫連線得以重用,避免了頻繁建立,釋放連線引起的大量效能開銷。在減少系統消耗的基礎上,另一方面也增加了系統執行環境的平穩性。② 更快的系統反應速度:資料庫連線池在初始化過程中,往往已經建立了若干資料庫連線置於連線池中備用。此時連線的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連線,避免了資料庫連線初始化和釋放過程的時間開銷,從而減少了系統的響應時間。當資料庫訪問結束後,程式還是像以前一樣關閉資料庫連線:conn.close(); 但conn.close()並沒有關閉資料庫的物理連線,它僅僅把資料庫連線釋放,歸還給了資料庫連線池。
③ 新的資源分配手段:對於多應用共享同一資料庫的系統而言,可在應用層通過資料庫連線池的配置,實現某一應用最大可用資料庫連線數的限制,避免某一應用獨佔所有的資料庫資源。④ 統一的連線管理,避免資料庫連線洩漏:在較為完善的資料庫連線池實現中,可根據預先的佔用超時設定,強制回收被佔用連線,從而避免了常規資料庫連線操作中可能出現的資源洩露。

Q9:資料庫連線池有哪些分類?
答:①JDBC 的資料庫連線池使用 javax.sql.DataSource 來表示,DataSource 只是一個介面,該介面通常由伺服器(Weblogic, WebSphere, Tomcat)提供實現,也有一些開源組織提供實現。②DBCP 是Apache提供的資料庫連線池。tomcat 伺服器自帶dbcp資料庫連線池。速度相對c3p0較快,但因自身存在BUG,Hibernate3已不再提供支援。③C3P0 是一個開源組織提供的一個資料庫連線池,速度相對較慢,穩定性還可以。hibernate官方推薦使用。④Druid 是阿里提供的資料庫連線池,集合了DBCP 、C3P0 、Proxool 的優點。

Q10:資料來源DataSource和資料庫連線Connection有什麼區別?
答:①DataSource 通常被稱為資料來源,它包含連線池和連線池管理兩個部分,習慣上也經常把 DataSource 稱為連線池。DataSource用來取代DriverManager來獲取Connection,獲取速度快,同時可以大幅度提高資料庫訪問速度。②資料來源和資料庫連線不同,資料來源無需建立多個,它是產生資料庫連線的工廠,因此整個應用只需要一個資料來源即可。

Redis 16
Q1:什麼是NoSQL?列舉幾個你知道的NoSQL資料庫。
答:①許多網站在海量使用者訪問的高併發情況下出現崩潰問題,根本原因是關係型資料庫。關係型資料庫有效能瓶頸:磁碟IO效能低下、擴充套件瓶頸:資料關係複雜,擴充套件性差,不便於大規模叢集。②NoSQL即Not-Only SQL,泛指非關係型資料庫,作為關係型資料庫的補充,降低了磁碟IO次數——使用記憶體儲存、去除資料間關係——不儲存關係,僅儲存資料。③NoSQL的特徵:特徵:可擴容,可伸縮;大資料量下高效能;靈活的資料模型;高可用。④常見的NoSQL資料庫:Redis、memcache、HBase、MongoDB。

Q2:簡單講講Redis的含義
答:①Redis (REmote DIctionary Server) 是用 C 語言開發的一個開源的高效能鍵值對(key-value)資料庫。②Redis資料庫中的資料間沒有必然的關聯關係,內部採用單執行緒機制進行工作,效能比較高,支援持久化儲存。③支援多種資料型別,包括字串型別 string、列表型別 list、雜湊型別 hash、集合型別 set、有序集合型別 sorted_set。

Q3:Redis有哪些應用場景?
答:①為熱點資料加速查詢(主要場景),如熱點商品、熱點新聞、熱點資訊、推廣類等高訪問量資訊等。②應用於任務佇列,如秒殺、搶購、購票排隊等。③即時資訊查詢,如排行榜、各類網站訪問統計、公交到站資訊、線上人數資訊(聊天室、網站)、裝置訊號等。④時效性資訊控制,如驗證碼控制、投票控制等。⑤分散式資料共享,如分散式叢集架構中的 session 分離以及訊息佇列、分散式鎖等。

Q4:簡述string型別的基本操作和注意事項
答:①儲存的資料:單個資料,最簡單常用的資料儲存型別。儲存資料的格式:一個儲存空間儲存一個資料。儲存內容:通常使用字串,如果字串以整數的形式展示,可以作為數字操作使用。②新增/修改資料:set key value、獲取資料:get key、刪除資料:del key、新增/修改多個資料:mset key1 value1 key2 value2 ...、獲取多個資料:mget key1 key2 …、獲取資料字元個數(字串長度):strlen key、追加資訊到原始資訊後部(如果原始資訊存在就追加,否則新建):append key value。③string在redis內部儲存預設就是一個字串,當遇到增減類操作incr,decr時會轉成數值型進行計算。redis所有的操作都是原子性的,採用單執行緒處理所有業務,命令是一個一個執行的,因此無需考慮併發 帶來的資料影響。注意:按數值進行操作的資料,如果原始資料不能轉成數值,或超越了redis 數值上限範圍(java中long型資料最大值,Long.MAX_VALUE)將報錯。

Q5:簡述hash型別的基本操作和注意事項
答:①儲存需求:對一系列儲存的資料進行編組,方便管理,一般儲存物件資訊。儲存結構:一個儲存空間儲存多個鍵值對資料。底層使用雜湊表結構實現資料儲存。②如果field數量較少,儲存結構優化為類陣列結構;如果field數量較多,儲存結構使用HashMap結構。③新增/修改資料:hset key field value、獲取資料:hget key field,hgetall key、 刪除資料:hdel key field1 [field2]、新增/修改多個資料:hmset key field1 value1 field2 value2 …、 獲取多個資料:hmget key field1 field2 …、獲取雜湊表中欄位的數量:hlen key、獲取雜湊表中是否存在指定的欄位:hexists key field。③hash型別下的value只能儲存字串,不允許儲存其他資料型別,不存在巢狀現象。如果資料未獲取到, 對應的值為(nil)。每個 hash 可以儲存 2^32 - 1 個鍵值對。hash型別十分貼近物件的資料儲存形式,並且可以靈活新增刪除物件屬性。但hash設計初衷不是為了儲存大量物件而設計的,不可濫用,更不可以將hash作為物件列表使用。hgetall 操作可以獲取全部屬性,如果內部field過多,遍歷整體資料效率就很會低,有可能成為資料訪問瓶頸。

Q6:簡述list型別的基本操作和注意事項
答:①儲存需求:儲存多個資料,並對資料進入儲存空間的順序進行區分。儲存結構:一個儲存空間儲存多個資料,且通過資料可以體現進入順序。儲存多個資料,底層使用雙向連結串列儲存結構實現。②新增/修改資料:lpush key value1 [value2] …,rpush key value1 [value2] …、獲取資料:lrange key start stop,lindex key index,llen key、獲取並移除資料:lpop key,rpop key。獲取資料時可以設定等待時間,list為空時等待獲取。移除指定資料:lrem key count value。③list中儲存的資料都是string型別的,資料總容量是有限的,最多2^32- 1 個元素(4294967295)。list具有索引的概念,但是運算元據時通常以佇列的形式進行入隊出隊操作,或以棧的形式進行入棧出棧操作。獲取全部資料操作結束索引設定為-1。list可以對資料進行分頁操作,通常第一頁的資訊來自於list,第2頁及更多的資訊通過資料庫的形式載入。

Q7:簡述set型別的基本操作和注意事項
答:①儲存需求:儲存大量的資料,在查詢方面提供更高的效率。儲存結構:能夠儲存大量的資料,高效的內部儲存機制,便於查詢。與hash儲存結構完全相同,僅儲存鍵,不儲存值(nil),並且值是不允許重複的。②新增資料:sadd key member1 [member2]、獲取全部資料:smembers key、刪除資料:srem key member1 [member2]、獲取集合資料總量:scard key、判斷集合中是否包含指定資料:sismember key member。③set 型別不允許資料重複,如果新增的資料在 set 中已經存在,將只保留一份。set 雖然與hash的儲存結構相同,但是無法啟用hash中儲存值的空間。

Q8:簡述sorted-set型別的相關操作和注意事項
答:①儲存需求:資料排序有利於資料的有效展示,需要提供一種可以根據自身特徵進行排序的方式。儲存結構:新的儲存模型,可以儲存可排序的資料,在set的儲存結構基礎上新增可排序欄位。②新增資料:zadd key score1 member1 [score2 member2]、獲取全部資料:zrange key start stop [WITHSCORES],zrevrange key start stop [WITHSCORES]、刪除資料:zrem key member [member ...]。③score儲存的資料儲存空間是64位,超過該範圍的話score儲存的資料也可以是一個雙精度的double值,但可能會丟失精度,使用時候要慎重。sorted_set 底層儲存還是基於set結構的,因此資料不能重複,如果重複新增相同的資料,score值將被反覆覆蓋,保留最後一次修改的結果。

Q9:Key有哪些通用指令?
答:①刪除指定key:del key、獲取key是否存在:exists key、獲取key的型別:type key。②為指定key設定有效期:expire key seconds 單位秒,pexpire key milliseconds 單位毫秒、獲取key的有效時間:ttl key 如果key不存在或key失效顯示-2,沒設定有效期或永久性顯示-1,單位秒、pttl key以毫秒為單位、切換key從時效性轉換為永久性:persist key。③查詢key:keys pattern。查詢模式規則:* 匹配任意數量的任意符號,? 配合一個任意符號,[] 匹配一個指定符號。④為key改名:rename key newkey、renamenx key newkey新名不存在時才可使用。

Q10:Redis如何解決key的重複問題?資料庫有哪些基本操作?
答:①redis為每個服務提供有16個資料庫,編號從0到15。每個資料庫之間的資料相互獨立。②切換資料庫:select index、退出:quit、測試連通:ping、輸出資訊:echo message。③移動到其他資料庫:move key db 、資料個數:dbsize 、清除該資料庫:flushdb 、清除所有資料庫:flushall 。

Q11:Jedis是什麼?
答:①Jedis是一種利用Java語言連線redis的服務,需要依賴redis.clients下的jedis包。②通過new Jedis(String address,int port)建立一個操作redis資料庫的物件,第一個引數是字串類的ip地址,第二個引數是int型別的埠號。③之後通過Jedis類例項物件呼叫相關API實現對redis資料庫的操作。

Q12:新聞網站會出現熱點新聞,熱點新聞最大的特徵是時效性,如何自動控制熱點新聞的時效性?
答:redis 可以控制資料的生命週期,通過資料是否失效控制業務行為,適用於所有具有時效性限定控制的操作,使用String資料結構,通過setex key seconds value 可以設定資料有效的生命週期,有效時間以秒為單位,也可以通過psetex key milliseconds value設定資料的有效時間,有效時間以毫秒為單位。

Q13:你會如何設計與實現電商網站購物車?
答:①可以使用redis資料庫,以客戶id作為key,每位客戶建立一個hash儲存結構儲存對應的購物車資訊。②將商品編號作為field,購買數量作為value進行儲存。③新增商品:追加全新的field與value。④瀏覽:遍歷hash。⑤更改數量:自增/自減,設定value值。⑥刪除商品:直接刪除field。⑦清空購物車:直接刪除key。⑧當前僅僅是將資料儲存到了redis中,並沒有起到加速的作用,商品資訊還需要二次查詢資料庫,將每條購物車中的商品記錄儲存成兩條field,field1專用於儲存購買數量,命名格式:商品id:nums 數值;field2專用於儲存購物車中顯示的資訊,包含文字描述,圖片地址,所屬商家資訊等,命名格式:商品id:info json資料 。

Q14:雙11活動日,銷售手機充值卡的商家對移動、聯通、電信的30元、50元、100元商品推出搶購活動,每種商品搶購上限1000張,你會怎麼解決?
答:①使用redis的hash資料結構,以商家id作為key、將參與搶購的商品id作為field、將參與搶購的商品數量作為對應的value。②搶購時使用降值的方式控制產品數量,通過hincrby key field increment實現對指定key的field值實現值的更新操作,例如hincrby CMCC card30:nums -10實現對移動的30元商品數量實現-10操作。

Q15:微信朋友圈點贊,要求按照點贊順序顯示點贊好友資訊,如果取消點贊,移除對應好友資訊,你會怎麼實現?
答:redis 可以應用於具有操作先後順序的資料控制,可以使用list資料結構實現,點贊時使用rpush key value從右新增實現順序顯示功能,取消點贊通過lrem key count value從list左邊開始移除指定資料。

Q16:每位使用者首次使用今日頭條時會設定3項愛好的內容,但是後期為了增加使用者的活躍度、興趣點,必須讓使用者對其他資訊類別逐漸產生興趣,增加客戶留存度,如何實現?
答:①可以利用redis資料庫的set資料結構完成,系統分析出各個分類的最新或最熱點資訊條目並組織成set集合,隨機挑選其中部分資訊,配合使用者關注資訊分類中的熱點資訊組織成展示的全資訊集合。②通過srandmember key [count]隨機獲取集合中指定數量的資料,通過spop key [count]隨機獲取集合中的某個資料並將該資料移出集合。

設計模式 29
Q1:設計模式是什麼?
答:設計模式是經過高度抽象化的在程式設計中可以被反覆使用的程式碼設計經驗的總結。正確使用設計模式能提高程式碼的可讀性、可重用性和可靠性,編寫符合設計模式規範的程式碼不但有利於自身系統的穩定、可靠,還有利於外部系統的對接。在使用了良好設計模式的系統工程中,無論是對滿足當前的需求還是對適應未來的需求,無論是對自身系統間模組的對接還是對外部系統的對接,都有很大幫助。

Q2:設計模式有哪些原則?
答:①單一職責原則:單一職責原則又稱單一功能原則,它規定一個類只有一個職責。如果有多個職責(功能)設計在一個類中,這個類就違反了單一職責原則。②開閉原則:
開閉原則規定軟體中的物件(類、模組、函式等)對擴充套件開放,對修改封閉,這意味著一個實體允許在不改變其原始碼的前提下改變其行為,該特性在產品化的環境下是特別有價值的,在這種環境下,改變原始碼需要經過程式碼審查,單元測試等過程以確保產品的使用質量。遵循這個原則的程式碼在擴充套件時並不發生改變,因此不需要經歷上述過程。③里氏代換原則:里氏代換原則是對開閉原則的補充,規定了在任意父類可以出現的地方,子類都一定可以出現。實現開閉原則的關鍵就是抽象化,父類與子類的繼承關係就是抽象化的具體表現,所以里氏代換原則是對實現抽象化的具體步驟的規範。④依賴倒轉原則:依賴倒轉原則指程式要依賴於抽象(Java中的抽象類和介面),而不依賴於具體的實現(Java中的實現類)。簡單地說,就是要求對抽象進行程式設計,不要求對實現進行程式設計,這就降低了使用者與實現模組之間的耦合度。⑤介面隔離原則:介面隔離原則是指通過將不同的功能定義在不同的介面中來實現介面的隔離,這樣就避免了其他類在依賴該介面(介面上定義的功能)時依賴其不需要的介面,可減少介面之間依賴的冗餘性和複雜性。
⑥合成/聚合複用原則:合成/聚合複用原則指通過在一個新的物件中引入(注入)已有的物件以達到類的功能複用和擴充套件的目的。它的設計原則是要儘量使用合成或聚合而不要使用繼承來擴充套件類的功能。⑦迪米特法則:迪米特法則指一個物件儘可能少地與其他物件發生相互作用,即一個物件對其他物件應該有儘可能少的瞭解或依賴。其核心思想在於降低模組之間的耦合度,提高模組的內聚性。迪米特法則規定每個模組對其它模組都要有儘可能少的瞭解和依賴,因此很容易使系統模組之間的功能獨立,這使得各個模組的獨立執行變得更加簡單,同時使得各個模組之間的組合變得更加容易。

Q3:設計模式有哪些分類?
答:①建立型模式:提供了多種優雅建立物件的方法,包括工廠模式、抽象工廠模式、單例模式、建造者模式、原型模式。②結構型模式:通過類和介面之間的繼承和引用實現建立複雜結構物件的功能,包括介面卡模式、橋接模式、組合模式、裝飾器模式、外觀模式、享元模式、代理模式。③行為型模式:通過類之間不同的通訊方式實現不同的行為方式,包括責任鏈模式、命令模式、直譯器模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態模式、策略模式、模板模式、訪問者模式。

Q4:簡述工廠模式
答:①工廠模式是最常見的設計模式,該模式屬於建立型模式,它提供了一種簡單、快速、高效而安全地建立物件的方式。②工廠模式在介面中定義了建立物件的方法,而將具體的建立物件的過程在子類中實現,使用者只需通過介面建立需要的物件即可,不用關注物件的具體建立過程。同時,不同的子類可根據需求靈活實現建立物件的不同方法。③通俗地講,工廠模式的本質就是用工廠方法代替new操作建立一種例項化物件的方式,以便提供一種方便地建立有同種型別介面地產品的複雜物件。

Q5:簡述抽象工廠模式
答:①抽象工廠模式在工廠模式上新增了一個建立不同工廠的抽象介面(抽象類或介面實現),該介面可叫做超級工廠。在使用過程中,我們首先通過抽象介面建立出不同的工廠物件,然後根據不同的工廠物件建立不同的物件。②在同一個廠商有多個維度的產品時,如果使用工廠模式,則勢必會存在多個獨立的工廠,這樣的話設計和物理世界是不對應的。正確的做法是通過抽象工廠模式來實現,我們可以將抽象工廠類比成廠商,將通過抽象工廠建立出來的工廠類比成不同產品的生產線,在需要生產產品時根據抽象工廠生產。

Q6:講一講單例模式
答:①單例模式是保證系統例項唯一性的重要手段。單例模式首先通過將類的例項化方法私有化來防止程式通過其他方式建立該類的例項,然後通過提供一個全域性唯一獲取該類例項的方法幫助使用者獲取類的例項,使用者只需也只能通過呼叫該方法獲取類的例項。②單例模式的設計保證了一個類在整個系統中同一時刻只有一個例項存在,主要被用於一個全域性類的物件在多個地方被使用並且物件的狀態是全域性變化的場景下。同時單例模式為系統資源的優化提供了很好的思路,頻繁建立或銷燬物件都會增加系統的資源消耗,而單例模式保障了整個系統只有一個物件能被使用,很好地節約了資源。③單例模式的實現很簡單,每次在獲取物件前都判斷系統是否已經有這個單例物件,有則返回,無則建立。需要注意的是,單例模型的類構造器是私有的,只能由自身建立和銷燬物件,不允許除了該類的其他程式使用new關鍵字建立物件及破壞單例模式。

Q7:懶漢模式執行緒安全嗎?
答:①懶漢模式是執行緒不安全的,在需要時才會建立例項物件。②可以通過加synchronized鎖實現執行緒安全的懶漢模式。③可以在加鎖的基礎上使用volatile關鍵字和雙重校驗鎖進一步提升懶漢模式的執行緒安全性。

Q8:講一講建造者模式
答:①建造者模式使用多個簡單的物件建立一個複雜的物件,用於將一個複雜的構建與其表示分離,使得同樣的構建過程可以建立不同的表示,然後通過一個Builder類(該Builder類是獨立於其他物件的)建立最終的物件。②建造者模式主要用於解決軟體系統中複雜物件的建立問題,比如有些複雜物件的建立需要通過各部分的子物件用一定的演算法構成,在需求變化時這些複雜物件將面臨很大的改變,不利於系統穩定。但是使用建造者模式能將它們各部分的演算法包裝起來,在需求變化後只需調整各個演算法的組合方式和順序,能極大提供系統穩定性。建造者模式常被用於一些基本部件不會變而其組合經常變化的應用場景下。③建造者模式與工廠模式的最大區別是,建造者模式更關注產品的組合方式和裝配順序,而工廠模式關注產品的生產本身。④建造者模式在設計時有以下幾種角色:Builder 建立一個複雜產品物件的抽象介面、ConcreteBuilder Builder介面的實現類,用於定義複雜產品各個部件的裝配流程、Director 構造一個使用Builder介面的物件、Product 表示被構造的複雜物件,ConcreteBuilder定義了該複雜物件的裝配流程,而Product定義了該複雜物件的結構和內部表示。

Q9:講一講原型模式
答:①原型模式指通過呼叫原型例項的Clone方法或其他手段來建立物件。②原型模式屬於建立型設計模式,它以當前物件為原型來建立另一個新的物件,而無需知道建立的細節。原型模式在Java中通常使用Clone技術實現,在JavaScript中通常使用物件的原型屬性實現。原型模式的Java實現很簡單,只需要原型類實現Cloneable介面並重寫clone方法即可。

Q10:淺複製和深複製的區別?
答:Java中的複製分為淺複製和深複製。①淺複製:Java中的淺複製是通過實現Cloneable介面並重寫clone方法實現。在淺複製的過程中,物件的基本資料型別的變數值會重新被複制和建立,而引用資料型別仍指向原物件的引用,也就是說淺複製不復制物件的引用資料型別。②深複製:在深複製的過程中,不論是基本資料型別還是引用資料型別,都會被重新複製和建立。簡而言之,深複製徹底複製了物件的資料,淺複製的複製不徹底(忽略了引用資料型別)。

Q11:講一講介面卡模式
答:①介面卡模式通過定義一個介面卡類作為兩個不相容的介面之間的橋樑,將一個類的介面轉換成使用者期望的另一個介面,使得兩個或多個原本不相容的介面可以基於介面卡類一起工作。②介面卡模式主要通過介面卡類實現各個介面之間的相容,該類通過依賴注入或者繼承實現各個介面的功能並對外統一提供服務。在介面卡模式的實現中有三種角色:source、targetable、adapter。sourc是待適配的類,targetable是目標介面,adapter是介面卡。我們在具體應用中通過adapter將source的功能擴充套件到targetable,以實現介面的相容。介面卡的實現主要分為三類:類介面卡模式、物件介面卡模式、介面介面卡模式。

Q12:講一講裝飾者模式
答:①裝飾者模式指在無需改變原有類及類的繼承關係的情況下,動態擴充套件一個類的功能。它通過裝飾者來包裹真實的物件,並動態地向物件新增或者撤銷功能。②裝飾者模式包括Source和Decorator兩種角色,source是被裝飾者,decorator是裝飾者。裝飾者模式通過裝飾者可以為被裝飾者Source動態地新增一些功能。

Q13:講一講代理模式
答:①代理模式指為物件提供一種通過代理的方式來訪問並控制該物件行為的方法。在客戶端不適合或者不能夠直接引用一個物件時,可以通過該物件的代理物件實現對該物件的訪問,可以將該代理物件理解為客戶端和目標物件之間的中介者。②在代理模式下有兩種角色,一種是被代理者,一種是代理(Proxy),在被代理者需要做一項工作時,不用自己做而是交給代理做。以企業招聘為例,不用自己去市場找,可以通過代理去找。

Q14:講一講外觀模式
答:①外觀模式也叫做門面模式,通過一個門面向客戶端提供一個訪問系統的統一介面,客戶端無需關心和知曉系統內部各子模組(系統)之間的複雜關係,其主要目的是降低訪問擁有多個子系統的複雜系統的難度,簡化客戶端與其之間的介面。外觀模式將子系統中的功能抽象成一個統一的介面,客戶端通過這個介面訪問系統,使得系統使用起來更加容易。②簡單來說外觀模式就是將多個子系統及其之間的複雜關係和呼叫流程封裝到一個統一的介面或類中以對外提供服務,這種模式設計三種角色:子系統角色:實現了子系統的功能;門面角色:外觀模式的核心, 熟悉各子系統的功能和呼叫關係並根據客戶端的需求封裝統一的方法來對外提供服務;客戶角色:通過呼叫門面來完成業務功能。

Q15:講一講橋接模式
答:①橋接模式通過將抽象及其實現解耦,使二者可以根據需求獨立變化。這種型別的設計模式屬於結構型模式,通過定義一個抽象和實現之間的橋接者來達到解耦的目的。②橋接模型主要用於解決在需求多變的情況下使用繼承造成類爆炸的問題,擴充套件起來不夠靈活。可以通過橋接模式將抽象部分與實現部分分離,使其能夠獨立變化而相互之間的功能不受影響。具體的做法是通過定義一個橋接介面,使得實體類的功能獨立於介面實現類,降低他們之間的耦合度。

Q16:你知道哪些應用使用了橋接模式嗎?
答:JDBC和DriverManager就使用了橋接模式,JDBC在連線資料庫時,在各個資料庫之間切換而不需要修改程式碼,因為JDBC提供了統一的介面,每個資料庫都提供了各自的實現,通過一個叫做資料庫驅動的程式來橋接即可。

Q17:講一講組合模式
答:①組合模式又叫做部分整體模式,主要用於實現部分和整體操作的一致性。組合模式常根據樹形結構來表示部分及整體之間的關係,使得使用者對單個物件和組合物件的操作具有一致性。②組合模式通過特定的資料結構簡化了部分和整體之間的關係,使得客戶端可以像處理單個元素一樣來處理整體的資料集,而無需關心單個元素和整體資料集之間的內部複雜結構。

Q18:講一講享元模式
答:①享元模式主要通過物件的複用減少物件建立的次數和數量,減少系統記憶體的使用和降低系統負載。享元模式屬於結構型模型,在系統需要一個物件時享元模式首先在系統中查詢並嘗試重用現有的物件,如果未找到匹配物件則建立新物件並將其快取在系統中。②享元模式主要用於避免在有大量物件時頻繁建立和銷燬物件造成系統資源的浪費,把其中共同的部分抽象出來,如果有相同的業務請求則直接返回記憶體中已有的物件。

Q19:講一講策略模式
答:①策略模式為同一個行為定義了不同策略,為每種策略實現了不同方法。使用者使用時系統根據不同的策略自動切換不同的方法實現策略的改變。同一策略下的不同方法是對同一功能的不同實現,因此在使用時可相互替換而不影響使用者的使用。②策略模式的實現是在介面中定義不同的策略,在實現類中完成了對不同策略下具體行為的實現,並將使用者的策略狀態儲存在上下文中來完成策略的儲存和狀態的改變。

Q20:講一講模板方法模式
答:①模板方法模式定義了一個演算法框架,並通過繼承的方式將演算法的實現延遲到子類中,使得子類可以在不改變演算法框架及其流程的前提下重新定義該演算法在某些特定環節的實現,是一種類行為型模式。②該模式在抽象類中定義了演算法的結構並實現了公共部分演算法,在子類中實現可變的部分並根據不同的業務需求實現不同的擴充套件。模板方法模式的優點在於其父類(抽象類)中定義了演算法的框架以及保障演算法的穩定性,同時在父類中實現了演算法公共部分的方法保證程式碼的複用,將部分演算法延遲到子類實現,因此子類可以通過繼承擴充套件或重新定義演算法的功能而不影響穩定性,符合開閉原則。③抽象類:定義演算法框架,由基本方法和模板方法組成。基本方法定義了演算法有哪些環節,模板方法定義了演算法各個環節執行的流程。具體子類:對在抽象類中定義的演算法根據需求進行不同的實現。

Q21:講一講觀察者模式
答:①觀察者模式指在被觀察者的狀態發生變化時,系統基於事件驅動理論將其狀態通知到訂閱其狀態的觀察者物件中,以完成狀態的修改和事件傳播。觀察者模式是一種物件行為模式,觀察者和被觀察者之間的關係屬於抽象耦合關係,主要優點是觀察者與被觀察者之間建立了一套事件觸發機制,以降低二者之間的耦合度。②觀察者模式的主要角色如下:抽象主題Subject:持有訂閱了該主題的觀察者物件的集合,同時提供了增加刪除觀察者物件的方法和主題狀態變化後的通知方法。具體主題Concrete Subject:實現了抽象主題的通知方法,在主題內部狀態發生變化時,呼叫該方法通知訂閱了主題狀態的觀察者物件。抽象觀察者Observer:觀察者的抽象類或介面,定義了主題狀態變化時需要呼叫的方法。具體觀察者 Concrete Observer:抽象觀察者的實現類,在收到主題狀態變化的資訊後執行具體觸發機制。

Q22:講一講迭代器模式
答:①迭代器模式提供了順序訪問集合物件中的各種元素,而不暴露該物件內部結構的方法。Java中的集合就是典型的迭代器模式,比如HashMap,當遍歷HashMap時,需要迭代器不停地獲取Next元素就可以迴圈遍歷集合中所有元素。②迭代器模式將遍歷集合中所有元素地操作封裝成一個迭代器類,目的是在不暴露集合物件內部結構地情況下,對外提供統一訪問集合內部資料的方法。迭代器的實現一般包括一個迭代器,用於執行具體的遍歷操作,以及一個Collection,用於儲存具體的資料。

Q23:講一講責任鏈模式
答:①責任鏈模式用於避免請求傳送者與多個請求處理者耦合在一起,讓所有請求的處理者持有下一個物件的引用,從而將請求串聯成一條鏈,在有請求發生時,可將請求沿著這條鏈傳遞,直到遇到該物件的處理器。②該模式下使用者只需將請求傳送到責任鏈上即可,無需關心請求的處理細節和傳遞過程,所以責任鏈模式優雅地將請求的傳送和處理進行了解耦。責任鏈模式常用於Web模式。③責任鏈模式包含以下三種角色:Handler介面:規定責任鏈上要執行的具體方法。AbstractHandler抽象類:持有Handler例項並通過get/set方法將各個具體的業務Handler串聯成一個責任鏈,客戶端上的請求在責任鏈上執行。業務Handler:使用者根據具體的業務需求實現的業務邏輯。

Q24:講一講命令模式
答:①命令模式將請求封裝為命令基於事件驅動非同步執行,以實現命令的傳送者和命令的執行者之間的解耦,提高命令傳送執行的效率和靈活度。②命令模式主要包含以下角色:
抽象命令類:執行命令的介面,定義執行命令的抽象方法。具體命令類:抽象命令類的實現類,持有接收者物件,並在收到命令後呼叫命令執行者的方法action()實現命令的呼叫和執行。命令執行者:命令的具體執行者,定義了命令執行的具體方法action()。命令呼叫者:接收客戶端的命令並非同步執行。

Q25:講一講備忘錄模式
答:①備忘錄模式又叫做快照模式,該模式將當前物件的內部狀態儲存到備忘錄中,以便在需要時能將物件的狀態恢復到原先儲存的狀態。備忘錄模式提供了一種儲存和恢復狀態的機制,常用於快照的記錄和狀態的儲存,在系統發生鼓掌或資料發生不一致時能夠方便地將資料恢復到某個歷史狀態。②備忘錄的核心是設計備忘錄類及用於管理備忘錄的管理者類,主要角色如下:發起人Originator:記錄當前時刻的內部狀態,定義建立備忘錄和回覆備忘錄資料的方法。備忘錄Memento:負責儲存物件的內部狀態。狀態管理者Storage:對備忘錄的歷史狀態進行儲存,定義了儲存和獲取備忘錄狀態的功能。注意備忘錄只能被儲存或恢復,不能進行修改。

Q26:講一講狀態模式
答:①狀態模式指給物件定義不同的狀態,併為不同的狀態定義不同的行為,在物件的狀態發生變換時自動切換狀態的行為。狀態模式是一種物件行為型模式,它將物件的不同行為封裝到不同的狀態中,遵循單一職責原則。②具體角色如下:環境: 也叫做上下文,用於維護物件當前的狀態,並在物件狀態發生變化時觸發物件行為的變化。抽象狀態:定義介面,用於定義物件中不同狀態對應行為。具體狀態:抽象狀態的實現類

Q27:講一講訪問者模式
答:①訪問者模式指將資料結構和資料的操作分離開來,使其在不改變資料結構的前提下動態新增作用於這些元素的操作。訪問者模式通過定義不同的訪問者實現對資料的不同操作,因此在需要給資料新增新的操作時只需為其定義一個新的訪問者即可。②訪問者模式是一種物件行為型模式,主要特點是將資料結構和作用於結構上的操作解耦,使得集合的操作可自由地演化而不影響其資料結構,它適用於資料結構穩定但操作多變的系統中。③主要角色如下:抽象訪問者:定義了一個訪問元素的介面,為每類元素都定義了一個訪問操作,該操作中的引數型別對應被訪問元素的資料型別。具體訪問者:抽象訪問者的實現類,實現了不同訪問者訪問元素後具體行為。抽象元素:定義了訪問該元素的入口方法,不同訪問者型別代表不同訪問者。具體元素:實現抽象元素定義的入口方法,根據訪問者的不同型別實現不同邏輯業務。

Q28:講一講中介者模式
答:①中介者模式指物件和物件之間不直接互動,而是通過一個名為中介者的角色來實現,使原有物件之間的關係變得鬆散,且可以通過定義不同的中介者來改變它們之間的互動。②主要包含以下角色:抽象中介者:中介者介面,定義了註冊同事物件方法和轉發同時物件資訊的方法。具體中介者:中介者介面的實現類,定義了一個集合儲存同事物件,協調各同事角色之間的互動關係。抽象同事類:定義同事的介面類,持有中介者物件,並定義同事物件互動的抽象方法,同時實現同事類的公共方法和功能。具體同事類:抽象同事的實現類,在需要與其他同事物件互動時,通過中介者物件來完成。

Q29:講一講直譯器模式
答:①直譯器模式給定一種語言,並定義該語言的語法表示,然後設計一個直譯器來解釋語言的語法,這種模式常被用於SQL解析、符號處理引擎等。②直譯器模式包含以下主要角色:抽象表示式:定義直譯器的介面,約定直譯器所包含的操作。終結符表示式:抽象表示式的子類,用來定義語法中和終結符有關的操作,語法中的每一個終結符都應有一個與之對應的終結表示式。非終結符表示式:抽象表示式的子類,用來定義語法中和非終結符有關的操作,語法中的每條規則都有一個非終結符表示式與之對應。環境:定義各個直譯器需要的共享資料或公共功能。

計算機網路 7
Q1:說一說OSI網路模型
答:網路的七層架構從下到上主要包括物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層。①物理層:物理層主要定義物理裝置標準,主要作用是傳輸位元流,具體做法是在傳送端將1、0轉化為電流強弱來進行傳輸,在到達目的地之後再將電流強弱轉化為1、0,也就是我們常說的模數轉換與數模轉換,這一層的資料叫做位元。②資料鏈路層:資料鏈路層主要用於對資料包中的MAC地址進行解析和封裝。這一層的資料叫做幀,在這一層工作的裝置是網路卡、網橋、交換機。③網路層:網路層主要用於對資料包中的IP地址進行封裝和解析,這一層的資料叫做資料包。在這一層工作的裝置有路由器、交換機、防火牆等。④傳輸層:傳輸層定義了傳輸資料的協議和埠號,主要用於資料的分段、傳輸和重組。在這一層工作的協議有TCP和UDP等。TCP是傳輸控制協議,傳輸效率低,可靠性強,用於傳輸對可靠性要求高,資料量大的資料,比如支付寶轉賬業務;UDP是使用者資料包協議,用於傳輸可靠性要求不高,資料量小的資料,例如抖音等視訊服務。⑤會話層:會話層在傳輸層的基礎上建立連線和管理會話,具體包括登陸驗證、斷點續傳、資料粘包與分包等。在裝置之間需要互相識別的可以是IP,也可以是MAC或者主機名。⑥表示層:表示層主要對接收的資料進行解釋、加密、解密、壓縮、解壓縮等,即把計算機能夠識別的內容轉換成人能夠識別的內容(圖片、聲音、文字等)。⑦應用層:基於網路構建具體應用,例如FTP上傳檔案下載服務、Telnet服務、HTTP服務、DNS服務、SNMP郵件服務等。

Q2:說一說TCP/IP的網路模型
答:TCP/IP不是指TCP和IP這兩個協議的合稱,而是指因特網的整個TCP/IP協議簇。從協議分層模型方面來講,TCP/IP由4個層次組成:網路介面層、網路層、傳輸層和應用層。①網路介面層:定義了主機間網路連通的協議,具體包括Echernet、FDDI、ATM等通訊協議。②網路層:主要用於資料的傳輸、路由及地址的解析,以保障主機可以把資料傳送給任何網路上的目標。資料經過網路傳輸,傳送的順序和到達的順序可能發生變化。在網路層使用IP協議和ARP地址解析協議。③傳輸層:使源端和目的端的機器上的對等實體可以基於會話相互通訊。在這一層定義了兩個端到端的協議TCP和UDP。TCP是面向連線的協議,提供可靠的報文傳輸和對上層應用的連線服務,除了基本的資料傳輸,它還有可靠性保證、流量控制、多路複用、優先權和安全性控制等功能。UDP是面向無連線的不可靠傳輸的協議,主要用於不需要TCP的排序和流量控制等功能的應用程式。④應用層:負責具體應用層協議的定義,包括Telnet虛擬終端協議、FTP檔案傳輸協議、SMTP簡單電子郵件傳輸協議、DNS域名解析服務、NNTP網上新聞傳輸協議和HTTP超文字傳輸協議等。

Q3:簡述TCP的三次握手過程,為什麼不是兩次或四次?
答:①服務端建立傳輸控制塊TCB,進入LISTEN狀態,準備接收客戶端的請求。客戶端同樣先建立TCB,然後當準備建立連線時向服務端傳送連線請求報文(SYN=1,seq=x),然後進入SYN-SENT狀態。②服務端收到後向客戶端傳送確認報文(SYN=1,ACK=1,ack=x+1,seq=y),進入SYN-RCVD狀態。③客戶端接收到確認後,再向服務端傳送一個確認報文(ACK=1,ack=y+1,seq=x+1),然後進入ESTABLISHED狀態,服務端接收後也進入ESTABLISHED狀態。
④不是兩次的原因是為了避免無效的連線請求突然傳送到服務端,而此時客戶端已關閉,服務端誤以為客戶端將要傳送資料會白白浪費資源。⑤不是四次的原因是將服務端的SYN和ACK報文拆分成兩次傳送和一次的效果是相同的,沒有意義。

Q4:簡述TCP的四次握手過程,為什麼不是三次?
答:①當客戶端準備關閉連線時,向服務端傳送連線終止報文(FIN=1,seq=u),進入FIN-WAIT-1狀態。②服務端接收後向客戶端傳送確認報文(ACK=1,ack=u+1,seq=v),進入CLOSE-WAIT狀態,客戶端收到後進入FIN-WAIT-2狀態,此時TCP連線處於半關閉狀態。③當服務端也傳送完全部資料準備斷開連線時,向客戶傳送連線終止報文(FIN=1,ACK=1,ack=u+1,seq=w),進入LAST-ACK狀態。④客戶端接收到該報文後,傳送一個確認報文(ACK=w+1,ack=1,seq=u+1),進入TIME-WAIT狀態,然後等待2MSL時間後關閉。服務端收到後關閉,時間將略早於客戶端。⑤不是三次的原因第一是為了保證客戶端傳送的最後一個報文可以到達服務端,如果該報文丟失那麼服務端會超時重傳之前的FIN+ACK報文,客戶端可以在2MSL內收到,第二是防止已失效的報文傳送到客戶端,在2MSL後客戶端在本連線時間內發出的所有報文都將從網路中消失。

Q5:簡述HTTP的傳輸流程
答:①地址解析:地址解析通過域名系統DNS解析伺服器域名從而獲得主機的IP地址。例如客戶端的瀏覽器請求http://localhost:8080/index.html,則可分析出:協議名HTTP、主機名localhost、埠8080、物件路徑/index.html。②封裝HTTP資料包:解析協議名、主機名、埠、物件路徑等並結合本機自己的資訊封裝成一個HTTP請求資料包。③封裝TCP包:將HTTP請求資料包進一步封裝成TCP資料包。④建立TCP連線:基於TCP的三次握手機制建立TCP連線。⑤客戶端傳送請求:在建立連線後,客戶端傳送一個請求給伺服器。⑥伺服器響應:伺服器在接收到請求後,結合業務邏輯進行資料處理,然後向客戶端返回相應的響應資訊。在響應資訊中包含狀態行、協議版本號、成功或錯誤的程式碼、訊息體等內容。⑦伺服器關閉TCP連線:伺服器在向瀏覽器傳送請求響應資料後關閉TCP連線。但如果瀏覽器或者伺服器在訊息頭加入了Connection:keep-alive,則TCP連線在請求響應資料後仍然保持連線狀態,在下一次請求中瀏覽器可以繼續使用相同的連線傳送請求。採用keep-alive不但減少了請求響應的時間,還節約了網路頻寬和系統資源。

Q6:HTTPS是什麼?
答:HTTPS是以安全為目標的HTTP通道,它在HTTP中加入SSL層以提高資料傳輸的安全性。HTTP被用於在Web瀏覽器和網站伺服器之間傳遞資訊,但以明文方式傳送內容,不提供任何方式的資料加密,如果攻擊者擷取了Web瀏覽器和網站伺服器之間的傳輸報文,就可以直接讀懂其中的資訊,因此HTTP不適合傳輸一些敏感資訊,比如身份證號碼、密碼等。為了資料傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證照來驗證伺服器的身份,並對瀏覽器和伺服器之間的通訊進行資料加密,以保障資料傳輸的安全性,其埠一般是443。

Q7:簡述HTTPS的加密流程
答:①發起請求:客戶端在通過TCP和伺服器建立連線之後(443埠),發出一個請求證照的訊息給伺服器,在該請求訊息裡包含自己可實現的演算法列表和其他需要的訊息。②證照返回:服務端在收到訊息後回應客戶端並返回證照,在證照中包含伺服器資訊、域名、申請證照的公司、公鑰、資料加密演算法等。③證照驗證:客戶端在收到證照後,判斷證照籤發機構是否正確,並使用該簽發機構的公鑰確認簽名是否有效,客戶端還會確認在證照中列出的域名就是它正在連線的域名。如果客戶端確認證照有效,則生成對稱金鑰,並使用公鑰將對稱金鑰加密。④金鑰交換:客戶端將加密後的對稱金鑰傳送給伺服器,伺服器在接收到對稱金鑰後使用私鑰解密。⑤資料傳輸:經過上述步驟,客戶端和伺服器就完成了金鑰對的交換,在之後的資料傳輸過程中,客戶端和服務端就可以基於對稱加密(加密和解密使用相同金鑰的加密演算法)對資料加密後在網路上傳輸,保證了網路資料傳輸的安全性。

作業系統 2
Q1:程式和執行緒有什麼區別?
答:①程式是一個具有獨立功能的程式關於某個資料集合的一次執行活動,是系統進行資源分配和排程的一個獨立單位。②執行緒是一種輕量級的程式,是一個基本的CPU執行單元也是程式執行流的最小單元。執行緒是程式中的一個實體,是被系統獨立排程和分配的基本單位,執行緒不擁有系統資源,只擁有一點執行必備的資源,但可與其他同屬一個程式的執行緒共享程式擁有的全部資源。③引入程式的目的是為了更好地使多道程式併發執行,提高系統資源利用率和吞吐量,增加併發程度。引入執行緒地目的使為了減小程式在併發執行時的開銷,提高系統的併發能力。④堆是執行緒共享的,棧是執行緒私有的。

Q2:死鎖產生的原因和解決方法?
答:①死鎖是多個程式競爭共享資源而造成互相等待的僵局,若無外力作用這些程式都將無法向前推進。②死鎖產生的原因是非剝奪資源的競爭和程式的不恰當推進順序。③預防死鎖:破壞互斥條件、破壞不剝奪條件、破壞請求和保持條件、破壞迴圈等待條件。④預防死鎖:安全狀態:能找到一個分配資源的序列讓所有程式都順序完成。銀行家演算法:採用預分配策略檢查分配完成時系統是否處於安全狀態。⑤檢測死鎖:利用死鎖定理化簡資源分配圖檢測死鎖的存在。⑥解除死鎖:資源剝奪法:掛起某些死鎖程式並搶奪它的資源,以便其他執行緒繼續推進。撤銷程式法:強制撤銷部分、甚至全部程式並搶奪其資源,以便讓其他程式繼續推進。程式回退法:讓一個或多個程式回退到足以避免死鎖的地步。
 

相關文章