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

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

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