1. 程式人生 > 實用技巧 >Java面試必會

Java面試必會

  • Bean的作用域

    • 在Spring的元素的scope屬性設定bean的作用域,用來決定bean是單例項還是多例項的
    • 預設情況下Spirng為每個在IOC容器裡宣告的bean建立唯一一個例項,整個IOC都能共享該例項,且所有getBean() 呼叫和 bean 引用都將返回這個唯一bean例項,該作用域被稱為singleton,是所有bean的預設作用域

    • bean的作用域
      • singleton:預設值。當ioc一建立就會建立bean例項,而且是單例,每次得到的都是同一個
      • prototype:原型的。當IOC一建立不再例項化該bean,每次呼叫getBean再例項化bean,而且每個例項都不同
      • request:每次請求例項化一個bean
      • session:在一次會話中共享一個bean

    事務的四大特性ACID

    1.原子性(Atomicity)

    這裡指系統只能處於操作之前或操作之後的狀態,而不是介於兩者之間的狀態。sql執行時要麼成功要麼一起失敗,不允許中間被打斷 ACID原子性的定義特徵是:能夠在錯誤時中止事務,丟棄該事務進行的所有寫入變更的能力。

    2.一致性(Consistency)

    一致性就是說,事務必須使資料庫從一個一致的狀態轉換到另一個一致的狀態。也就是說一個事務在執行前和執行後都必須處於一個一致性的狀態。

    舉個栗子,假設Gavin和Carrie的錢加起來一共是500,那麼不管他們之間如何轉賬,轉幾次賬,事務結束後兩個使用者的錢相加起來應該還得是500,這就是事務的一致性。

    3.隔離性(Isolation)

大多數資料庫都會同時被多個客戶端訪問。如果它們各自讀寫資料庫的不同部分,這是沒有問題的,但是如果它們訪問相同的資料庫記錄,則可能會遇到併發問題(競爭條件(race conditions))。 ACID意義上的隔離性意味著,同時執行的事務是相互隔離的:它們不能相互冒犯。

4.永續性(Durability)

永續性是指一個事務一旦被提交了,那麼對資料庫中的資料的改變是永久的,即便實在資料庫系統遇到故障的請胯下也不會丟失提交事務的操作。為我們提供了一個安全的地方存貯出具,而不用擔心丟失。

事務的傳播行為

  • 一個方法執行在了一個開啟了事務的方法中,當前方法是使用原來的事務還是開啟一個新的事務

    • 7種傳播行為:

      • REQUIRED:如果有事務在執行,就在這個事務執行,否則啟動新的事務並執行
      • REQUERES_NEWS:當前方法啟動新事物並執行,如果有事務正在執行就將它掛起
      • SUPPORTS:如果有事務在執行就在這個事務內執行,否則就不執行在事務
    • NOT_SUPPORTED: 不在事務中執行,如果有執行的事務就掛起

      • MANDATORY:當前方法必須執行在事務內部,如果沒有事務就丟擲異常
    • NEVER: 當前方法不應該執行在事務中,如果有執行的事務就丟擲異常

      • NETSTED:如果有事務在執行,當前方法就在這個事務的巢狀事務內執行,否則就啟動新事務並執行。

    資料庫事務併發問題

    • 髒讀: 一個事務讀取到了另一個事務更新修改但還未提交的值
    • 不可重複讀:第一次讀和第二次讀的資料不一樣,原因是這中間有另一個事務修改了資料
    • 幻讀:一個事務讀取表中的資料,第二次讀取該表示多出了幾行資料,這中間有另一個事務向表中插入新的行

    隔離級別

    • 讀未提交:READ UNCOMMITTED:允許事務1讀取事務2未提交的資料
    • 讀已提交:READ COMMITTED:事務1只能讀取到事務2已提交的修改
    • 可重複讀:REPEATABLE READ:事務執行期間禁止其他事務對這個欄位進行更新,Mysql預設隔離級別
    • 序列化:SERIALIZABLE:確保可以多次從一個表中讀取到相同的行

    SpringMVC下解決Post和Get請求中文亂碼問題

    • 解決Post請求:修改web.xml,註冊Filter;設定CharacterEncodingFilter.class裡的encoding和forceEncoding

    攔截請求

    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    
    • 解決Get請求亂碼問題

      • 方法1:在server.xml中修改如下配置

        <connector URIEncoding="UTF-8" />
        

      SpringMVC工作流程

    • 處理模型資料方式一:將方法的返回值設定為ModelAndView

    • 方法的返回值是String,在方法的入參中傳入Map、Model或ModelMap,SpringMVC最終轉換為一個ModelAndView物件

    • 前臺傳送請求到中央控制器DispatchServlet,後者呼叫處理器對映器HandlerMapping處理得到攔截器HandlerExecutionChain(包含所有攔截器和處理器)返回給DispatchServlet
    • DispatcherServlet通過處理器介面卡HandlerAdapter呼叫相應的處理器Handler(即Controller)處理請求後返回ModelAndView給DispatcherServlet
    • DispatcharServlet通過檢視解析器(InternalResource)ViewResolver對ModelAndView進行檢視解析後得到檢視view
    • 最後DispatcharServlet呼叫view裡的render方法來渲染檢視,響應給客戶端

    SpringMVC原始碼Debug過程(分析DispatcherServlet.class)

    • 涉及的類:DispatcherServlet|View|AbstractView|InternalResourceView

    • 945:DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) // 執行轉發排程

    • 916\1101:mappedHandler = getHandler(processedRequest); // 通過處理器對映器HandlerMapping得到總處理器物件HandlerExecutionChain(包含所有攔截器和處理器)

    • 923行: HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()) // 通過處理器對映器HandlerMapping處理得到介面卡HandlerAdapter

    • 945行:mv = ha.handler(processRequest, response, mappedHandler); // 處理器執行使用者的目標方法得到modelAndView

    • 1012行:render(mv, request, response); // 通過檢視解析器(InternalResource)ViewResolver解析modelAndView進行檢視解析並返回view

    • 1225: view.render(mv.getModelInternal(), request, response); // 渲染檢視

      • (AbstractView.class)226行: renderMergedOutputModel(mergedModel, request, response); // 輸出模型資料響應給使用者
      • InternalResourceView(180行):exposeModelAsRequestAttributes(model, requestToExpose); // 暴露模型資料放到request域中
      • (AbstractView.class)374行:request.setAttribute(modelName, modelValue); // model放到request域中
    • InternalResourceView(189): RequestDispatcher rd = getRequestDispatcher(requestToExpose,dispatcher); // 獲取轉發器

    • InternalResourceView(189):rd.forward(requestToExpose, response); // 進行請求轉發

    MyBatis解決:當實體類屬性名和資料庫表中欄位名不一致

      1. 寫sql語句時起別名:select last_name lastName from S // 在資料庫表字段不分大小寫
      1. 在mybatis-config.xml開啟駝峰命名規則:

      <setting name="mapUnderscoreToCamelCase" value="true"/>

    • 在Mapper對映檔案中使用resultMap來自定義高階對映規則

    <resultMap type="/*包名*/" id="myMap">
      <id column="last_name" property="lastName"> // 將資料庫表字段與屬性名一一對應
    </resultMap>
    

    centos6/7常用服務命令service/systemctl

    • service/systemctl start/restart/stop/reload/status 服務名

    • 檢視服務命令(centos7)

      • systemctl list-unit-files
      • systemctl --type service
    • 檢視服務命令(centos6): chkconfig --list|grep xxx

    • (centos7)自啟動: systemctl enbale/disable 服務名

      • (centos6)自啟動: chkconfig --level 5 服務名 on/off

    git分支命令和實際應用

    Redis持久化

    • Redis提供兩種持久化方式:RDB(Redis Database)和AOF(Append Of File)

    • RDB: 在指定時間間隔內將記憶體中的資料集快照寫入磁碟,恢復時將快照檔案讀到記憶體,即全量儲存

      • 優點: 節省磁碟空間,恢復速度快
      • 缺點: 在到達指定的儲存點之前如果redis掛掉,將丟失上一次快照到儲存點之間所有修改。資料量龐大比較消耗效能

    • AOF:以日誌的形式記錄所有寫操作,是增量操作,只追加檔案,不修改檔案

      • 優點:丟失資料概率更低,備份機制穩健,可讀的日誌文字,通過操作AOF可以處理誤操作
      • 缺點:佔用更多磁碟空間,恢復速度慢,有更大的效能壓力,存在個別bug造成不能恢復

    15. Mysql什麼時候建索引

    • 頻繁作為查詢條件的欄位應該建立索引

    • 查詢中與其他表關聯的欄位,外來鍵關係建立索引

    • 單鍵/組合索引的選擇問題,組合索引價效比更高

    • 查詢中排序的欄位,排序欄位若通過索引去訪問將大大提高排序速度

    • 查詢中統計或者分組欄位,排序GROUP BY 比 ORDER BY 更燒效能

    • 不要建立索引:

      • 表記錄太少,經常增刪改的表或欄位
      • Where條件裡用不到的欄位不建立索引,過濾性不好(如性別,結果太多)的不適合建索引

    16.JVM垃圾回收機制,GC發生在JVM哪部分,有幾種GC,它們的演算法是什麼?

    JVM體系結構:

    • 垃圾回收機制GC發生在堆heap中,

    • GC:分代收集演算法,次數上頻繁收集Young區(Minor GC),較少收集Old區(Full GC),基本不動Perm區(永久區)

    • 四大演算法:

      • 引用計數法:一般不採用。有物件沒引用,GC就不進行垃圾回收,每次對物件賦值都要維護引用計數器,較難處理迴圈引用
      • 複製演算法Copying:年輕代Young區使用Minor GC,採用的就是複製演算法。從一片記憶體拷貝到另一片記憶體空間,因此沒有記憶體碎片,且沒有標記和清除過程,效率高,但耗費空間, 需要雙倍空間。
      • 標記清除Mark-Sweep:在Old區採用,一般由標記清除或者標記清除與標記整理的混合使用。過程:從根節點開始掃描並對存活的物件進行標記,然後掃描並回收未被標記的物件,使用free-list可以記錄區域。缺點:產生記憶體碎片,耗時。優點:無需額外空間。
      • 標記清除壓縮Mark-Sweep-Compact:採用於Old區。先進行一次標記清除的過程,然後再掃描並將存活物件滑動到一端。還可以進行多次CG後才Compact壓縮。優點:無記憶體碎片,但耗費時間.

    Redis在專案中的使用場景

    • String: Redis可存放incrby命令所計算出的訪問次數,一個IP頻繁訪問伺服器時,可能有風險
    • Hash:儲存使用者資訊:Hget(userKey,id); Hset(userKey,id,102),如果使用Get(userKey),會將所有資訊反序列化,需要進行不必要的IO
    • List:實現最新訊息的排行,還可以利用List的push() 將任務存放在list中,同時使用pop()將任務取出,redis-list可用於模擬訊息佇列,常用於電商的秒殺
    • Set:可以自動排重,比如在微博中將每個人的好友存在於集合Set中,這樣求兩個人的共同好友操作,只需要求交集即可。
    • Zset:以某一個條件為權重進行排序,例如:商品詳情的綜合排名,還可以按照價格進行排名

    Elasticsearch 和 solr

    • 都是基於Lucene搜尋伺服器基礎上開發,都是基於分詞技術構建的倒排索引的方式進行查詢
    • 在實時建立索引時,solr會產生io阻塞,es不會;在不斷動態新增資料時solr效率變低,es無影響
    • solr利用zookeeper進行分散式管理,而es自帶該功能,solr需要部署到web伺服器上,solr本質是一個動態web專案
    • solr支援更多格式資料,如xml,json,csv等,而es僅支援檔案格式
    • 單純對已有資料進行檢索時solr效率更好,而es對動態資料檢索時效率更高

    單點登入

    • 一處登入多處使用, 前提:單點登入多使用在分散式系統中

    購物車實現過程

    • 一個使用者必須對應一個購物車,單點登入一定在購物車之前
    • 新增購物車:
      • 未登入:購物車資料儲存在Redis/Cookie/local storage中
      • 已登入:Redis(Hash:hset(user:userId:cart , skuId, value))和資料庫中
    • 展示購物車:
      • 未登入:直接從cookie/Redis/local storage中獲取資料
      • 已登入:顯示redis(以前儲存的資料) + cookie(登入前儲存的購物車)中的購物車資料

    訊息佇列

    • 高併發是分散式系統中最大的特點,使用i訊息佇列可以解決非同步通訊
    • 訊息的不確定性(弊端):可以採用延遲佇列,輪詢技術來解決該問題,可以使用activemq