貼一貼個人後端開發面試題

轉載請註明出處: 貼一貼個人後端開發面試題

本文是面試回寢室後憑記憶羅列出來的問題,大概90%的問題都在這裏面了,有幾個問題的實在是想不起來了= =,有些問題自我感受回答的很差,因此我是查了資料後從新整理了再貼上答案的。若有錯誤或不適合的,歡迎你們評論點出,謝謝!css

雖然面試的是Java實習生職位,但問題不侷限於Java語言。html

技術無關:

面試過程當中只有三個技術無關的話題:前端

  1. 自我介紹。
  2. 感受本身有什麼優缺點?
  3. 你如今有女友了嗎? = =..

這類的話題通常稍微準備一下,都不會有什麼問題。java

技術相關:

1. Spring MVC 如何接受並處理一個請求的?

首先咱們會在 web.xml中註冊一個 DispatcherServlet,並令這個 servlet接收全部的請求,項目啓動後Spring會掃描配置文件,根據配置加載和實例化類,其中掃描到的帶有 @Controller或者 @RestController註解的類則是請求要映射到的類,Spring MVC掃描裏面全部和請求映射有關的註解, 如 @RequestMapping@ResponseBody@RequestParam等。當接收到一個請求時,它會根據請求的url映射到對應的controler,並根據返回值判斷是渲染jsp頁面仍是返回普通文本,亦或是返回json。

2. AOP實現原理。

AOP是經過動態代理來實現的,有兩種經常使用的技術,一是 JDK的動態代理,二是 CGLIB,而不管是前者仍是後者,都是生成動態生成類的字節碼來實現的。 JDK的動態代理只能處理接口實現的方法,而CGLIB則沒有這個限制。由於字節碼是動態生成的,因此能夠在生成的字節碼當中,在目標方法先後插入定義好的方法的調用。

3. 註解是怎麼用的?爲何要使用註解?

當在一個類、方法或者字段上標上註解後,能夠經過 obj.getClass().isAnnotationPresent(..)來判斷一個目標是否被特定的註解標識,經過 obj.getClass().getAnnotation(..)來獲取標誌是註解,以此得到註解上的信息。使用註解能夠幫助咱們在項目的編譯期或運行時給類、方法或對象添加一個額外的信息,給編程增長了很大的靈活性。好比用 @Override來標誌這是重寫父類的方法,那麼編譯器就能夠在編譯期檢查該方法是否真的是重寫父類的方法,將錯誤扼殺在編譯器。

4. 線程有幾種狀態?生命週期是怎樣的?

線程有五種狀態: 建立就緒運行阻塞死亡
調用 start方法時,線程就會進入就緒狀態。
在線程獲得 cpu時間片時進入運行狀態。
線程調用 yield方法可讓出cpu時間回到就緒狀態。
線程運行時可能因爲 IO、調用 sleepwaitjoin方法或者 沒法得到同步鎖等緣由進入阻塞狀態。
當線程得到到等待的資源資源或者引發阻塞的條件獲得知足時(調用 notifynotifyAll),會從阻塞狀態進入就緒狀態。
當線程的 run方法執行結束或者調用 interrupt方法時,線程就進入死亡狀態。

5. Java中如何實現同步。

Java實現同步的方法有:linux

  1. 使用synchronized關鍵字爲方法或代碼塊加鎖。
  2. 使用volatile修飾變量,可是volatile不保證原子性
  3. 使用ReentrantLock或者ReentrantReadWriteLock, 這種方法比synchronized更靈活。
  4. 使用Semaphore,容許最多n個線程同時訪問資源。

6. HashMapHashtable的區別。

  1. HashMap線程不安全的,Hashtable是線程安全的。
  2. HashMap的key和value接受null,Hashtable不接受。
  3. HashMap繼承自AbstractMapHashtable繼承自Directory

7. JVM是否瞭解?

這裏我回答了最近正在看《深刻理解Java虛擬機》一書,本想着這方面的問題能答上一些的,沒想到面試官直接說
那看樣子還不是很瞭解,就不問這塊的問題了= =.. 心塞
可是我估摸着大概若是問的話會問:程序員

7.1. JVM的內存模型。

JVM的內存一共分爲5個部分:web

  1. 程序計數器: 裏面存放着線程執行的指令。
  2. 方法區: 存放類的信息,如:類名、方法、成員變量等,也存放着常量池。
  3. 虛擬機棧: 存放着局部變量表、操做數棧、方法出口信息等方法執行所需信息。
  4. 本地方法棧: 存放程序調用native方法的信息。
  5. : 這五個部分中最大的,對象的內存分配都是在堆內存中。

7.2. 經常使用的虛擬機參數。

  1. -Xmx: 指定最大堆內存
  2. -Xms: 指定初始化堆內存大小。
  3. -Xmn: 指定年輕代內存初始內存大小,同時也是最大內存大小。
  4. -XX:NewSize: 指定年輕代內存大小。
  5. -XX:NewRatio: 指定年輕代和老年代的內存比例。
  6. -XX:MaxHeapSize: 指定程序最大內存。
  7. -XX:+PrintGC: 打印GC日誌。
  8. -XX:+PrintGCDetails: 打印詳細的GC日誌。
  9. -Xloggc: 打印GC日誌保存位置。

7.3. 垃圾回收算法。

  1. 引用計數算法:
該算法對每個對象都有一個引用計數,沒增長一次引用就+1,減小一次引用-1,在回收時將引用計數爲0的對象清理掉。這種算法簡單,可是沒法解決循環引用的問題(好比: A引用B, B也引用A,可是A和B都沒有被其它任何對象引用)。
  1. 標記-清除算法:
該算法分爲兩個階段, 第一階段遍歷找出全部須要被回收的對象,並作上標記,第二階段對清理全部被標記的對象,這種算法效率比較低,而且會產生較多的內存碎片。
  1. 標記-整理算法:
該算法的第一階段和標記-清除算法是同樣的,而第二階段它不是直接清理掉垃圾對象,並且將存活的對象往同一側移動,移動完成後清理掉另外一側全部的對象。這種算法不會產生內存碎片,可是效率低下。
  1. 複製算法:
該算法將內存分爲兩個區域,進行垃圾回收時,就將還活着的對象複製到另外一塊內存區域中,而後再將整片內存區域清空。這種算法簡單快速,並且不會產生內存碎片,可是由於將內存分紅兩塊,因此可用的內存會少不少。
  1. 分代收集算法:
將內存細分爲多個區域,不一樣區域GC的頻率,並對不一樣的區域採用適當的收集算法。如JVM將內存分爲年輕代和老年代,普通對象最開始分配在年輕代(大對象會直接分配到老年代),同一個對象在通過幾回GC後還存活着,就認爲這個對象的生命週期會比較長,將其移入老年代,GC主要發生在年輕代。

7.4 類加載機制。

Java中主要有 Bootstrap類加載器ExtClassLoaderAppClassLoader,其中 Bootstrap類加載器主要加載 JAVA_HOME/lib目錄下的類庫, ExtClassLoader加載 JAVA_HOME/lib/ext目錄下的類庫, AppClassLoader加載 classpath指向目錄下的類庫。

Java的類加載器使用雙親委派模型,除了頂層的Bootstrap類加載器外,其他的類加載器都有父類加載器,當一個類加載器要加載一個類時,它不會直接去加載,而是委託父類加載器嘗試加載,父類加載器若是沒法完成,則繼續委託其父類加載器加載,若是在期間有某一個類加載器發現已經加載過這個類,則會將已經加載的類返回,子類再也不加載。若全部的類加載器都未加載過這個類,那麼最開始嘗試加載的加載器纔會去加載這個類。使用這樣的加載機制的好處是: 對於同一個類,如: java.lang.String,能保證整個程序中都是使用的這一個類,不然若是用戶在本身的項目中也寫了一個java.lang.String類,那麼項目中將存在兩個String類,一個是java提供的String類,一個是用戶自定義的String類,不只使項目變得混亂,並且不安全。面試

8. MyBatis和Hibernate各有什麼優缺點?

我我的由於只簡單接觸過而沒有實際應用過Hibernate,因此沒能從比較好的角度來回答這個問題。redis

Hibernate的優勢是它是一個徹底的 ORM框架,使用 Hibernate能夠作到不用手寫SQL,並且無須關心使用何種數據庫,可移植性較好,當須要更變數據庫時須要作的修改不多甚至爲0。其缺點是須要根據數據庫的設計在實體進行又一次的配置,且幫程序員作了太多事,若是須要進行調優的話須要對 Hibernate有比較深的瞭解。
MyBatis的優缺點差很少和 Hibernate相反,咱們須要 手寫SQL語句和 配置結果集和實體類的映射,即便是簡單的單表操做也須要寫SQL(能夠經過 攔截器來實現CommonMapper,或者可使用生成器來生成代碼),所以 MyBatis要進行SQL調優也簡單直接。其次是 MyBatis二級緩存功能較弱,是針對 namespace的。

9. MySQL平時是怎麼分析效率和進行SQL優化的?

較常使用的方法是explain SQL查看執行計劃,根據查詢計劃能夠知道是否使用了索引,是否進行來全表掃描以及查詢的順序,依此咱們能夠創建適當的索引和鏈接查詢調優。
還有一個是開啓慢查詢記錄執行時間長的SQL語句。算法

  1. 一般會在WHEREJOIN ONORDER BY使用到字段上加上索引。
  2. 避免查詢時判斷NULL,不然可能會致使全表掃描。
  3. 避免使用OR來鏈接查詢條件,不然可能致使全表掃描,能夠改用UNIONUNION ALL
  4. 避免LIKE查詢,不然可能致使全表掃描。
  5. 不使用SELECT *,只查詢必須的字段,避免加載無用數據。
  6. 能用UNION ALL的時候就不用UNIONUNION過濾重複數據要耗費更多的cpu資源。

10. MySQL除了InnoDB還有哪些引擎,有什麼區別?

由於平時都是用的 InnoDB,對其它引擎的瞭解甚少,因此這個問題沒答上= =,這裏直接貼一個連接好了。
相關連接: MySQL存儲引擎介紹

11. 如何動態改變頁面上的元素?

  1. 使用$(..).css({..})來改變元素的樣式。
  2. 使用$(..).attr(..)改變元素的屬性。
  3. 使用$(..).html(..)改變元素的html內容。
  4. 使用$(..).text(..)改變元素的文本內容。
  5. 使用$(..).remove(..)刪除元素。
  6. 使用$(..).append(..)添加元素。

12. 分頁的實現。

若是是使用 JSP等後端模板的話,通常會將須要分頁的 JSP代碼抽成一個單獨的 JSP文件,並在頁面中動態計算分頁按鈕的展現方式,在母頁中 includeJSP文件,而後在前端點擊分頁按鈕時,經過 AJAX請求下一頁的內容,服務器端將渲染後的 HTML返回給前端,前端經過 $(..).html()等方式替換展現內容。
若是是在先後端分離的項目中,通常會使用一些前端的框架,如: React.jsVue.js等,每次只向後臺請求分頁的數據,通常數據交互格式使用 JSON,並替換已有的數據,觸發頁面內容的改變。

13. 解釋一下RESTful,平時是怎麼用的

RESTful是無狀態的,採用URL+HTTP請求方法來描述資源行爲
通常在先後端分離的項目中,後端會提供REST接口給前端,其HTTP請求方法通常爲:

  1. GET : 獲取資源。
  2. POST: 更新資源。
  3. PUT: 建立資源。
  4. DELETE: 刪除資源。

其次,RESTful因爲是無狀態的,通常會採用JWTOAuth的方式來認證一個用戶,Token是保存在前端的,爲了安全性通常會配合HTTPS使用。

14. 有沒有抓過包?GET和POST格式是怎麼樣的?

HTTP請求分爲三部分: 請求行請求頭請求體:
請求行: 第一行是 METHOD URL protocal,如 GET http://abc.com HTTP/1.1
請求頭: 從第二行開始,每一行的內容都是一個請求頭參數值,直到遇到一個 空行爲止。
請求體: 請求頭和請求體中間隔着一行 空行做爲分界,請求體包含着本次請求攜帶的內容。
GET方式的請求沒有請求體,其是將參數追加到 URL後面, URL?後面的內容爲請求參數。
POST方式則三部分都有,且 POST的請求頭應當包含 Content-Type來指明請求體中內容的類型。

15. 若是是上傳文件的話又是怎樣的?後端如何處理?

上傳文件的話會設置 Content-Typemultipart/form-data,並指定 boundary的值來標識請求體中內容的分界,而在請求體中,不一樣的內容(如:文件A和文件B)之間使用 boundary的值來標識分界,而且請求體中每部份內容都會有 Content-DispositionContent-Type來指明這部份內容的類型和信息。

後端的話使用ServletFileUpload來解析請求,得到FileItemList,遍歷Item,而後經過Item得到輸入流,從輸入流中讀取上傳文件的數據,再構建FileOutputStream輸出到磁盤中保存。
若是使用Spring MVC,則能夠在接收請求的方法中接收CommonsMultipartFile,並使用transferTo方法保存到磁盤中。

16. AJAX實現原理。

這個也沒答上來,平時都是使用jQuery封裝的AJAX或者其餘AJAX框架。

AJAX是利用瀏覽器的AJAX引擎來實現的異步請求,經過 XMLHttpRequest對象來發送請求,由AJAX引擎向服務器發送和接收響應,再回調給用戶處理,達到不阻塞用戶界面和無刷新的目的。
資料來源: AJAX工做原理及其優缺點

17. Linux下怎麼查找一個文件?

若是是查找二進制文件,可使用 whereis
若是是查找命令,可使用 which
若是是其餘文件,可使用 find命令(其實什麼均可以找), -name指定搜索的名稱或者匹配串, -maxdepth指定搜索的深度。
也可使用 locate命令查找,可是最新變更的文件可能會找不到,由於該命令其實是搜索數據庫,該數據庫天天自動更新,能夠手動執行 updatedb更新。

18. Linux怎麼查找一個進程?

使用 ps命令能夠查看進程狀態, ps -ef查看全部進程,配合 grep命令能夠進行篩選, 如查看 tomcat進程的命令是: ps -ef | grep tomcat

19. Linux下只知道文件所在目錄和內容,如何查找文件?

這題沒也沒答上= =

使用 grep命令能夠實現:
grep -rn /path/to/target/dir -e "pattern"
-r: 遞歸
-n: 顯示行數
-w: 徹底匹配
例子: grep -rn. -e "ERROR"
輸出: ./面試:143:輸出: ./面試:144:上面的命令搜索當前目錄及其子目錄中的文件,並輸出含有ERROR內容的行
詳細答案及來源: How to find all files containing specific text on Linux?

20. Redis你用它來作什麼?

Redis在我接觸過的項目中主要作了兩件事:

  1. 緩存
  2. 存儲須要計算的信息

Redis也能夠用來作消息訂閱隊列等。

21. Redis若是運行過程當中崩潰了怎麼辦。

這個問題我估摸着面試官想問的是Redis的數據保障的方法,否則崩潰了除了重啓還能怎麼辦?

Redis有提供數據持久化的功能,一種是 快照,一種是 AOF
快照是在某一個時間點將全部數據寫入到磁盤中, AOF是將被執行的命令複製到硬盤中, 快照的文件體積要比 AOF的文件體積小。前者在 恢復時速度比後者快,可是由於是 間隔持久化,因此會有必定量的 數據丟失。後者由於是 實時寫入的,因此數據的完整性比較好,若是丟失的話通常也就丟失一秒的數據。

其次須要作主從複製,這樣一份數據能夠保存在多臺服務器上,且能夠避免Redis崩潰到重啓完成這段時間內沒法提供正常服務,同時從服務器能夠分擔主服務器的讀壓力。

22. Redis集羣。

沒配置過因此沒答上= =

相關鏈接: Redis集羣教程

23. 剩下的問題都是偏向我的的,沒有什麼通用性的回答,大概問了我:

  1. 前一家公司實習的時候主要作什麼?
  2. 講一下作過的項目?
  3. 項目中有沒有遇到什麼難點?怎麼解決的?
  4. 有沒有作過什麼有亮點的東西?

其中在問題3根據個人回答,繼續將狀況複雜化讓我給出解決方案,一步一步問。

最後

最後. 若是不是熟悉的技術真的不要往簡歷上寫= = 我由於在項目須要,學習過Android,可是項目完成後就
沒碰過了(近一年),把對Android有必定的瞭解寫上簡歷,結果問了三個問題就答不上了= =

雖然最終拿到了offer,可是由於各方面緣由,最後仍是放棄了,在此也提醒一下,秋招千萬不要錯過= =,拖到這個時候,好的實習的真很差找(成都)。

學習技術不能知其然而不知其因此然,往後不只會持續更新面試內容,同時本專欄會持續發佈Java數據庫Linux算法等方面的學習文章。歡迎關注。

最後,若有錯誤或不適合的,請你們評論點出,共同進步,謝謝!

相關文章
相關標籤/搜索