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)
- 在Spring的
大多數資料庫都會同時被多個客戶端訪問。如果它們各自讀寫資料庫的不同部分,這是沒有問題的,但是如果它們訪問相同的資料庫記錄,則可能會遇到併發問題(競爭條件(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解決:當實體類屬性名和資料庫表中欄位名不一致
-
- 寫sql語句時起別名:select last_name lastName from S // 在資料庫表字段不分大小寫
-
- 在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
- (centos6)自啟動:
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