java后台面試知識點總結


  本文主要記錄在准備面試過程中遇到的一些基本知識點(持續更新)

一、Java基礎知識

  1、抽象類和接口的區別

    接口和抽象類中都可以定義變量,但是接口中定義的必須是公共的、靜態的、Final的,抽象類中的變量跟普通類中的沒有區別。從設計上來說,接口是對一系列行為的抽象,而抽象類是對事物的抽象。
    

  2、什么時候使用抽象類和接口

    ①當希望某些方法具有默認實現時。

    ②希望實現多重繼承,必須使用接口。由於Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個接口。因此你就可以使用接口來解決它。

    ③如果基本功能在不斷改變,那么就需要使用抽象類。如果不斷改變基本功能並且使用接口,那么就需要改變所有實現了該接口的類。

  3、常用集合類

    Java 集合框架主要包括兩種類型的容器,一種是集合(Collection),存儲一個元素集合,另一種是圖(Map),存儲鍵/值對映射。Collection 接口又有 3 種子類型,List、Set 和 Queue。

    ①List(有序、可重復)

        List里存放的對象是有序的,同時也是可以重復的,List關注的是索引,擁有一系列和索引相關的方法,查詢速度快。因為往list集合里插入或刪除數據時,會伴隨着后面數據的移動,所有插入刪除數據速度慢。

    ②Set(無序、不能重復)

       Set里存放的對象是無序,不能重復的,集合中的對象不按特定的方式排序,只是簡單地把對象加入集合中。

    ③Queue

      Queue用於模擬"隊列"這種數據結構(先進先出 FIFO)。新元素插入(offer)到隊列的尾部,訪問元素(poll)操作會返回隊列頭部的元素,隊列不允許隨機訪問隊列中的元素。

    ④Map(鍵值對、鍵唯一、值不唯一)

      Map集合中存儲的是鍵值對,鍵不能重復,值可以重復。根據鍵得到值,對map集合遍歷時先得到鍵的set集合,對set集合進行遍歷,得到相應的值。

  4、集合和數組的區別

    ①.數組長度在初始化時指定,意味着只能保存定長的數據。而集合可以保存數量不確定的數據。同時可以保存具有映射關系的數據(即關聯數組,鍵值對 key-value)。

    ②數組元素即可以是基本類型的值,也可以是對象。集合里只能保存對象(實際上只是保存對象的引用變量),基本數據類型的變量要轉換成對應的包裝類才能放入集合類中。

  5、反射

    程序在運行狀態中,可以根據類名動態地加載一個類,加載完類之后,在堆內存中,就生成了一個 Class 類型的對象,這個對象就包含了完整的結構信息,通過這個對象我們可以看到類的結構。

  6、static關鍵字的作用

    方便在沒有創建對象的情況下來進行調用(方法/變量)。

 

二、計算機網絡

  1、為什么連接的時候是三次握手,關閉的時候卻是四次握手? 

  答:因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

  2、為什么TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

  答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最后的ACK回復,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重復發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之后進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那么Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回復所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那么Client推斷ACK已經被成功接收,則結束TCP連接。

  3、為什么不能用兩次握手進行連接?

  答:可能會發生死鎖。考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,並發送了確認應答分組。按照兩次握手的協定,S認為連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S是否已准備好,不知道S建立什么樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認為連接還未建立成功,將忽略S發來的任何數據分組,只等待連接確認應答分組。而S在發出的分組超時后,重復發送同樣的分組。這樣就形成了死鎖。

   4、HTTP請求中,GET和POST有什么區別?

  答:GET在瀏覽器回退時是無害的,而POST會再次提交請求。GET產生的URL地址可以被Bookmark,而POST不可以。GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。GET請求只能進行url編碼,而POST支持多種編碼方式。GET請求參數會被完整保留在瀏覽器歷史記錄里,而POST中的參數不會被保留。GET請求在URL中傳送的參數是有長度限制的,而POST么有。對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。GET比POST更不安全,因為參數直接暴露在URL上,所以不能用來傳遞敏感信息。GET參數通過URL傳遞,POST放在Request body中。

  對於GET方式的請求,瀏覽器會把http header和data一並發送出去,服務器響應200(返回數據);而對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。

  5、cookie和session的區別是什么?

  答:cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。cookie是服務器在本地機器上存儲的小段文本並隨每一個請求發送至同一個服務器,是一種在客戶端保持狀態的方案。session是在服務器端生產一個session ID,並將其通過響應發送到瀏覽器,當瀏覽器第二次發送請求,會將前一次服務器響應中的Session ID放在請求中一並發送到服務器上,服務器從請求中提取出Session ID,從而識別出客戶端。

   6、常見HTTP請求方法

  7、常見HTTP響應碼

    1xx:指示信息--表示請求已接收,繼續處理。

    2xx:成功--表示請求已被成功接收、理解、接受。

    3xx:重定向--要完成請求必須進行更進一步的操作。

    4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。

    5xx:服務器端錯誤--服務器未能實現合法的請求

 

三、並發編程

  1、進程和線程

    進程(process):是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。

    線程(thread):是操作系統能夠進行運算調度的最小單位。一個進程可以由很多個線程組成,線程間共享進程的所有資源,每個線程有自己的堆棧和局部變量。一條線程指的是進程中一個單一順序的控制流,每條線程並行執行不同的任務。

    所以,線程可以理解為進程中獨立運行的子任務。多線程的好處就是可以最大限度地利用CPU的空閑時間來處理其他的任務,比如任務1是在等待遠程服務器返回數據,以便后續處理,此時就可以切換到任務2,使系統避免了不必要的等待時間,從而運行效率大大得到提升。

    ①主線程:當Java程序啟動時,一個線程立刻運行,該線程通常叫做程序的主線程。

    ②子線程:由主線程直接或間接創建的線程。

    ③守護線程:用於服務其他非守護線程的線程,典型的守護進程就是垃圾回收線程,當進程中沒有非守護線程了,則守護線程自動銷毀。

  2、生產者-消費者模式

     生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之后不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列里取,阻塞隊列就相當於一個緩沖區,平衡了生產者和消費者的處理能力。

  3、linux進程間通信的幾種方式

     ①管道;②信號量;③UNIX套接字;④信號;⑤消息隊列;⑥共享內存

 

四、數據庫

  1、關系型數據庫

    MySQL數據庫

       ①數據庫引擎:數據庫引擎定義了數據庫存儲數據的數據結構特點,主要通過指定的數據庫引擎對象來影響數據庫操作數據不同方式的效率、鎖和事務的支持、數據全文檢索的支持、數據集的緩存操作等等特性。比較常見的數據庫引擎對象主要有兩種,一種是常見的InnoDB,另一種是很多人經常提到但是很少用到的MyIASM。兩種數據庫引擎都是通過B+樹實現了數據庫中最重要的數據索引。

           • InnoDB引擎:該存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM引擎,寫的處理效率會差一些,並且會占用更多的磁盤空間以保留數據和索引。 

           • MyIASM引擎:不支持事務、也不支持外鍵,優勢是訪問速度快,對事務完整性沒有要求或者以select,insert為主的應用基本上可以用這個引擎來創建表。

      ②兩種引擎的選擇:大尺寸的數據集趨向於選擇InnoDB引擎,因為它支持事務處理和故障恢復。數據庫的大小決定了故障恢復的時間長短,InnoDB可以利用事務日志進行數據恢復,這會比較快。主鍵查詢在InnoDB引擎下也會相當快,不過需要注意的是如果主鍵太長也會導致性能問題。大批的INSERT語句(在每個INSERT語句中寫入多行,批量插入)在MyISAM下會快一些,但是UPDATE語句在InnoDB下則會更快一些,尤其是在並發量大的時候。

    索引

      索引是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息。MyIASM和Innodb都使用了B+樹這種數據結構做為索引。

      注釋:更新一個包含索引的表需要比更新一個沒有索引的表更多的時間,這是由於索引本身也需要更新。因此,理想的做法是僅僅在常常被搜索的列(以及表)上面創建索引。

   2、非關系型數據庫

     Mongodb

        它是一個內存數據庫,數據都是放在內存里面的。對數據的操作大部分都在內存中。但mongodb並不是單純的內存數據庫,mongodb的所有數據實際上是存放在硬盤上的,所有要操作的數據通過mmap的方式映射到內存某個區域內。然后,mongodb就在這塊區域里面進行數據修改,避免了零碎的硬盤操作。至於mmap上的內容flush到硬盤就是操作系統的事情了,所以,如果mongodb在內存中修改了數據后,mmap數據flush到硬盤之前,系統宕機了,數據就會丟失。

     Redis

             它就是一個不折不扣的內存數據庫。Redis通常將全部的數據存儲在內存中。當前通過兩種方式實現持久化:

        (1)使用快照,一種半持久耐用模式。不時的將數據集以異步方式從內存以RDB格式寫入硬盤。

        (2)1.1版本開始使用更安全的AOF格式替代,一種只能追加的日志類型。將數據集修改操作記錄起來。Redis能夠在后台對只可追加的記錄作修改來避免無限增長的日志。

 

   3、數據庫事務四大特性:

      ①原子性(Atomicity):原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

      ② 一致性(Consistency):一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處於一致性狀態。拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。

      ③隔離性(Isolation):隔離性是當多個用戶並發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。即要達到這么一種效果:對於任意兩個並發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在並發地執行。

      ④持久性(Durability):持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

   4、索引

     單一索引:單一索引是指索引列為一列的情況,即新建索引的語句只實施在一列上。

     復合索引:用戶可以在多個列上建立索引,這種索引叫做復合索引(組合索引)。復合索引在數據庫操作期間所需的開銷更小,可以代替多個單一索引。

五、數據結構與算法

  1、樹

     ①B樹:B樹和平衡二叉樹稍有不同的是B樹屬於多叉樹又名平衡多路查找樹(查找路徑不只兩個),數據庫索引技術里大量使用者B樹和B+樹的數據結構。B樹相對於平衡二叉樹的不同是,每個節點包含的關鍵字增多了,特別是在B樹應用到數據庫中的時候,數據庫充分利用了磁盤塊的原理(磁盤數據存儲是采用塊的形式存儲的,每個塊的大小為4K,每次IO進行數據讀取時,同一個磁盤塊的數據可以一次性讀取出來)把節點大小限制和充分使用在磁盤塊大小范圍內;把樹的節點關鍵字增多后樹的層級比原來的二叉樹少了,減少數據查找的次數和復雜度。

     ②B+樹:B+樹是B樹的一個升級版,相對於B樹來說B+樹更充分的利用了節點的空間,讓查詢速度更加穩定,其速度完全接近於二分法查找。B+跟B樹不同B+樹的非葉子節點不保存關鍵字記錄的指針,只進行數據索引,這樣使得B+樹每個非葉子節點所能保存的關鍵字大大增加。B+樹葉子節點的關鍵字從小到大有序排列,左邊結尾數據都會保存右邊節點開始數據的指針。

     B+ 樹的優點在於

       由於B+樹在內部節點上不包含數據信息,因此在內存頁中能夠存放更多的key。 數據存放的更加緊密,具有更好的空間局部性。因此訪問葉子節點上關聯的數據也具有更好的緩存命中率。

       B+樹的葉子結點都是相鏈的,因此對整棵樹的遍歷只需要一次線性遍歷葉子結點即可。而且由於數據順序排列並且相連,所以便於區間查找和搜索。而B樹則需要進行每一層的遞歸遍歷。相鄰的元素可能在內存中不相鄰,所以緩存命中性沒有B+樹好。

     B樹的優點在於:由於B樹的每一個節點都包含key和value,因此如果經常訪問的元素離根節點較近,可能訪問速度會更快。

  2、HashMap實現原理

      HashMap的主干是一個Entry數組。Entry是HashMap的基本組成單元,每一個Entry包含一個key-value鍵值對。

    HashMap由數組+鏈表組成的,數組是HashMap的主體,鏈表則是主要為了解決哈希沖突而存在的。如果定位到的數組位置不含鏈表(當前entry的next指向null),那么對於查找,添加等操作很快,僅需一次尋址即可;如果定位到的數組包含鏈表,對於添加操作,其時間復雜度依然為O(1),因為最新的Entry會插入鏈表頭部,僅需要簡單改變引用鏈即可,而對於查找操作來講,此時就需要遍歷鏈表,然后通過key對象的equals方法逐一比對查找。

    HashMap的put過程:

六、JVM

   1、四種GC算法:

    ①引用技術算法:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的對象就是不可能再被使用的。

    ②根搜索算法:由於引用計數算法的缺陷,所以JVM一般會采用一種新的算法,叫做根搜索算法。它的處理方式就是,設立若干種根對象,當任何一個根對象到某一個對象均不可達時,則認為這個對象是可以被回收的。

       ③標記清除算法:標記-清除算法將垃圾回收分為兩個階段:標記階段和清除階段。一種可行的實現是,在標記階段,首先通過根節點,標記所有從根節點開始的可達對象。因此,未被標記的對象就是未被引用的垃圾對象;然后,在清除階段,清除所有未被標記

     的對象。

        標記:標記的過程其實就是,遍歷所有的GC Roots,然后將所有GC Roots可達的對象標記為存活的對象。

        清除:清除的過程將遍歷堆中所有的對象,將沒有標記的對象全部清除掉。

    ④復制算法:將原有的內存空間分為兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中的存活對象復制到未使用的內存塊中,之后,清除正在使用的內存塊中的所有對象,交換兩個內存的角色,完成垃圾回收。

   2、雙親委托機制

    工作過程:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委托給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳送到頂層的啟動類加載器中,只有當父類加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需要加載的類)時,子加載器才會嘗試自己去加載。
    好處:能夠有效確保一個類的全局唯一性,當程序中出現多個限定名相同的類時,類加載器在執行加載時,始終只會加載其中的某一個類。

  3、類加載過程

    類加載器:是Java運行時環境(Java Runtime Environment)的一部分,負責動態加載Java類到Java虛擬機的內存空間中(通過一個類的全限定名來獲取描述此類的二進制字節流)。從Java虛擬機的角度來講,只存在兩種不同的類加載器:一種是啟動類加載器(Bootstrap ClassLoader),這個類加載器使用C++語言實現,是虛擬機自身的一部分;另一種就是所有其他的類加載器,這些類加載器都由Java語言實現,獨立於虛擬機外部,並且全都繼承自抽象類java.lang.ClassLoader。

    類加載過程包括加載、驗證、准備、解析和初始化五個階段。

    加載:類加載階段就是由類加載器負責根據一個類的全限定名來讀取此類的二進制字節流到JVM內部,並存儲在運行時內存區的方法區,然后將其轉換為一個與目標類型對應的java.lang.Class對象實例,這個Class對象在日后就會作為方法區中該類的各種數據的訪問入口。

      驗證:驗證類數據信息是否符合JVM規范,是否是一個有效的字節碼文件,驗證內容涵蓋了類數據信息的格式驗證、語義分析、操作驗證等。

      准備:為類中的所有靜態變量分配內存空間,並為其設置一個初始值(由於還沒有產生對象,實例變量不在此操作范圍內)被final修飾的靜態變量,會直接賦予原值。

      解析:是將常量池中的符號引用轉化為直接引用的過程,這個過程的執行時間是不確定的,靜態綁定是在初始化之前進行解析,如果有動態綁定的話,它會在初始化后進行解析。

    初始化:將一個類中所有被static關鍵字標識的代碼統一執行一遍,如果執行的是靜態變量,那么就會使用用戶指定的值覆蓋之前在准備階段設置的初始值;如果執行的是static代碼塊,那么在初始化階段,JVM就會執行static代碼塊中定義的所有操作。

 

七、操作系統

  1、mmap

    mmap將一個文件或者其它對象映射進內存,實現文件磁盤地址和進程虛擬地址空間中一段虛擬地址的一一對映關系。實現這樣的映射關系后,進程就可以采用指針的方式讀寫操作這一段內存,而系統會自動回寫臟頁面到對應的文件磁盤上,即完成了對文件的操作而不必再調用read,write等系統調用函數。這種機制只需要從文件到用戶空間再從用戶空間到文件兩次拷貝,相比較在用戶空間、內核空間和文件之間四次拷貝數據,效率更高。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會清零。

 

 


 



    

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM