面試:第十一章:緩存
redis的具體使用場景嗎?
1.主要應(yīng)用在門戶網(wǎng)站首頁廣告信息的緩存。因為門戶網(wǎng)站訪問量較大,將廣告緩存到redis中,可以降低數(shù)據(jù)庫訪問壓力,提高查詢性能。
2.應(yīng)用在用戶注冊驗證碼緩存。利用redis設(shè)置過期時間,當(dāng)超過指定時間后,redis清理驗證碼,使過期的驗證碼無效。
3.用在購物車模塊,用戶登陸系統(tǒng)后,添加的購物車數(shù)據(jù)需要保存到redis緩存中。
redis中對一個key進行自增或者自減操作,它是原子性的嗎?
是原子性的。一個操作的不可以再分,操作要么執(zhí)行,要么不執(zhí)行。Redis的操作之所以是原子性的,是因為Redis是單線程的。對Redis來說,執(zhí)行g(shù)et、set以及eval等API,都是一個一個的任務(wù),這些任務(wù)都會由Redis的線程去負(fù)責(zé)執(zhí)行,任務(wù)要么執(zhí)行成功,要么執(zhí)行失敗,這就是Redis的命令是原子性的原因。Redis本身提供的所有API都是原子操作,Redis中的事務(wù)其實是要保證批量操作的原子性。
數(shù)據(jù)庫創(chuàng)建表時要考慮
a、大數(shù)據(jù)字段最好剝離出單獨的表,以便影響性能
b、使用varchar,代替char,這是因為varchar會動態(tài)分配長度,char指定為20,即時你存儲字符“1”,它依然是20的長度
c、給表建立主鍵,看到好多表沒主鍵,這在查詢和索引定義上將有一定的影響
d、避免表字段運行為null,如果不知道添加什么值,建議設(shè)置默認(rèn)值,特別int類型,比如默認(rèn)值為0,在索引查詢上,效率立顯。
e、建立索引,聚集索引則意味著數(shù)據(jù)的物理存儲順序,最好在唯一的,非空的字段上建立,其它索引也不是越多越好,索引在查詢上優(yōu)勢顯著,在頻繁更新數(shù)據(jù)的字段上建立聚集索引,后果很嚴(yán)重,插入更新相當(dāng)忙。
f、組合索引和單索引的建立,要考慮查詢實際和具體模式
???????mysql中哪些情況下可以使用索引,哪些情況不能使用索引?mysql索引失效的情形有哪些?
1.一個字段的取值只有幾種的字段不要使用索引。比如性別,只有兩種可能數(shù)據(jù)。意味著索引的二叉樹級別少,多是平級。這樣的二叉樹查找無異于全表掃描。
2.頻繁更新的字段不要使用索引
3.where 子句中使用!=或<>操作符,對字段進行 null 值判斷(IS NULL /IS NOT NULL),使用 or 來連接條件,使用in 和 not in,對字段進行表達(dá)式操作,對字段進行函數(shù)操作,/ like ‘%輸入符%’等條件,不要使用索引。否則將導(dǎo)致引擎放棄使用索引而進行全表掃描
4. 不要在 where 子句中的“=”左邊進行函數(shù)(DAY(column)=…)、算術(shù)運算或其他表達(dá)式運算,否則系統(tǒng)將可能無法正確使用索引。
5.任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
6.索引并不是越多越好,索引固然可以提高相應(yīng)的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引
7.使用varchar,代替char,這是因為varchar會動態(tài)分配長度,char指定為20,即時你存儲字符“1”,它依然是20的長度
8.大數(shù)據(jù)字段最好剝離出單獨的表,以便影響性能
9.給表建立主鍵
10.經(jīng)常用到的列就最好創(chuàng)建索引
11.查詢從索引的最左前列開始并且不跳過索引中的列;
12索引列上不操作
13加了范圍會失效
14在JOIN操作中(需要從多個數(shù)據(jù)表提取數(shù)據(jù)時),MYSQL只有在主鍵和外鍵的數(shù)據(jù)類型相同時才能使用索引,否則即使建立了索引也不會使用。使用連接(JOIN)來代替子查詢(Sub-Queries)
java中的多線程在你們的這個項目當(dāng)中有哪些體現(xiàn)?
a,后臺任務(wù):如定時向大量(100W以上)的用戶發(fā)送郵件;定期更新配置文件、任務(wù)調(diào)度(如quartz),一些監(jiān)控用于定期信息采集
b, 自動作業(yè)處理:比如定期備份日志、定期備份數(shù)據(jù)庫
c, 異步處理:如發(fā)微博、記錄日志
???????Redis分布式鎖理解
獲取鎖的時候,使用setnx加鎖,并使用expire命令(this.redisTemplate.expire("max",tempTime,TimeUnit.SECONDS); )為鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。
獲取鎖的時候還設(shè)置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。
釋放鎖的時候,通過UUID判斷是不是該鎖,若是該鎖,則執(zhí)行delete進行鎖釋放。
SETEX:如果 key 已經(jīng)存在, SETEX 命令將覆寫舊值。
SETNX:若給定的 key 已經(jīng)存在,則 SETNX 不做任何動作。
???????項目添加Redis緩存后,持久化具體怎么實現(xiàn)的。
RDB:保存存儲文件到磁盤;同步時間為15分鐘,5分鐘,1分鐘一次,可能存在數(shù)據(jù)丟失問題。
AOF:保存命令文件到磁盤;安全性高,修改后立即同步或每秒同步一次。
上述兩種方式在我們的項目中都有使用到,在廣告輪播的功能中使用了redis緩存,先從redis中獲取數(shù)據(jù),無數(shù)據(jù)后從數(shù)據(jù)庫中查詢后保存到redis中
采用默認(rèn)的RDB方式,在廣告輪播的功能中使用了redis緩存,先從redis中獲取數(shù)據(jù),無數(shù)據(jù)就從數(shù)據(jù)庫中查詢后再保存到redis中
???????你有了解mysql的隔離級別嗎?mysql默認(rèn)的隔離級別是什么?
數(shù)據(jù)庫事務(wù)的隔離級別有四種,隔離級別高的數(shù)據(jù)庫的可靠性高,但并發(fā)量低,而隔離級別低的數(shù)據(jù)庫可靠性低,但并發(fā)量高,系統(tǒng)開銷小。
READ UNCIMMITTED(未提交讀)
READ COMMITTED(提交讀)
REPEATABLE READ(可重復(fù)讀)
SERIALIZABLE(可串行化)
mysql默認(rèn)的事務(wù)處理級別是'REPEATABLE-READ',也就是可重復(fù)讀。
???????項目中關(guān)于表結(jié)構(gòu)拆分,你們是業(yè)務(wù)層面的拆分還是表結(jié)構(gòu)層面的拆分?
表結(jié)構(gòu)層面的拆分。通過mycat數(shù)據(jù)庫中間件完成數(shù)據(jù)庫分表操作。
業(yè)務(wù)層面也有拆分,比如商品模塊拆分成8張表來實現(xiàn)存儲
使用MyCat分庫分表?
分庫
通過Mycat結(jié)點來管理不同服務(wù)器上的數(shù)據(jù)庫,每個表最多存500萬條記錄
分表
重直切割,水平切割
MySql提供了EXPLAIN語法用來進行查詢分析,在SQL語句前加一個"EXPLAIN"即可。mysql中的explain語法可以幫助我們改寫查詢,優(yōu)化表的結(jié)構(gòu)和索引的設(shè)置,從而最大地提高查詢效率。
???????分布式架構(gòu)session共享問題,如何在集群里邊實現(xiàn)共享。
用了CAS,所有應(yīng)用項目中如果需要登錄時在web.xml中配置過濾器做請求轉(zhuǎn)發(fā)到cas端工作原理是在cas登錄后會給瀏覽器發(fā)送一個票據(jù)(ticket),瀏覽器cookie中會緩存這個ticket,在登錄其他項目時會拿著瀏覽器的ticket轉(zhuǎn)發(fā)到cas,到cas后根據(jù)票據(jù)判斷是否登錄