typora-root-url: …\Software\Typora\Picture
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
事務的傳播行為
- 一個方法運作在了一個開啟了事務的方法中,目前方法是使用原來的事務還是開啟一個新的事務
- 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工作流程
- 方法1:在server.xml中修改如下配置
- 處理模型資料方式一:将方法的傳回值設定為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
-
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