面試準備

1、Spring @Resouce 和 @Autowired 對比?

二者都是用於bean的注入
區別有:①@Autowired是spring提供的註解,而@Resouce是由J2EE提供的,在javax.annotation.Resource包html

②@Autowired默認按類型裝配,若是要按照名稱裝配,須要加上@Qualifier註解,以下:java

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 
}

@Resource默認經過反射機制,按照名稱裝配,若是匹配不上則會拋出異常。也可指定type屬性進行匹配,經過類型匹配到多個或者匹配不上也會拋出異常redis

2、Redis

Redis是一個基於內存的高性能的key-value數據庫算法

優勢:spring

(1)速度快,應該數據都在內存中sql

(2)支持豐富的數據類型,有string、list、set、sorted set、hash數據庫

(3)支持事務,操做都是原子性編程

(4)可設置過時時間,可用於緩存等設計模式

一、緩存雪崩:因爲原有緩存失效(或者數據未加載到緩存中),新緩存未到期間,全部本來應該訪問緩存的請求都去查詢數據庫了,而對數據庫CPU和內存形成巨大壓力,嚴重的會形成數據庫宕機,形成系統的崩潰。數組

 

解決思路:

  • 第一,大多數系統設計者考慮用加鎖或者隊列的方式保證來保證不會有大量的線程對數據庫一次性進行讀寫,避免緩存失效時對數據庫形成太大的壓力,雖然可以在必定的程度上緩解了數據庫的壓力可是與此同時又下降了系統的吞吐量。
  • 第二,分析用戶的行爲,儘可能讓緩存失效的時間均勻分佈。
  • 第三,若是是由於某臺緩存服務器宕機,能夠考慮作主備,好比:redis主備,可是雙緩存涉及到更新事務的問題,update可能讀到髒數據,須要好好解決。

二、緩存穿透:指用戶查詢數據,在數據庫沒有,天然在緩存中也不會有。這樣就致使用戶查詢的時候,在緩存中找不到,每次都要去數據庫中查詢。

解決思路:

  • 1,若是查詢數據庫也爲空,直接設置一個默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫,這種辦法最簡單粗暴。
  • 2,根據緩存數據Key的規則。例如咱們公司是作機頂盒的,緩存數據以Mac爲Key,Mac是有規則,若是不符合規則就過濾掉,這樣能夠過濾一部分查詢。在作緩存規劃的時候,Key有必定規則的話,能夠採起這種辦法。這種辦法只能緩解一部分的壓力,過濾和系統無關的查詢,可是沒法根治。
  • 3,採用布隆過濾器,將全部可能存在的數據哈希到一個足夠大的BitSet中,不存在的數據將會被攔截掉,從而避免了對底層存儲系統的查詢壓力。關於布隆過濾器,詳情查看:基於BitSet的布隆過濾器(Bloom Filter)

三、緩存預熱:指系統上線後,將相關的緩存數據直接加載到緩存系統。這樣就能夠避免在用戶請求的時候,先查詢數據庫,而後再將數據緩存的問題!用戶直接查詢事先被預熱的緩存數據!

  • 一、直接寫個緩存刷新頁面,上線時手工操做下;
  • 二、數據量不大,能夠在項目啓動的時候自動進行加載;
  • 三、定時刷新緩存;

四、緩存更新

  • (1)定時去清理過時的緩存;
  • (2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過時,過時的話就去底層系統獲得新數據並更新緩存。

五、緩存降級:當訪問量劇增、服務出現問題(如響應時間慢或不響應)或非核心服務影響到核心流程的性能時,仍然須要保證服務仍是可用的,即便是有損服務。系統能夠根據一些關鍵數據進行自動降級,也能夠配置開關實現人工降級。

  • (1)通常:好比有些服務偶爾由於網絡抖動或者服務正在上線而超時,能夠自動降級;
  • (2)警告:有些服務在一段時間內成功率有波動(如在95~100%之間),能夠自動降級或人工降級,併發送告警;
  • (3)錯誤:好比可用率低於90%,或者數據庫鏈接池被打爆了,或者訪問量忽然猛增到系統能承受的最大閥值,此時能夠根據狀況自動降級或者人工降級;
  • (4)嚴重錯誤:好比由於特殊緣由數據錯誤了,此時須要緊急人工降級。

分佈式緩存系統面臨的問題緩存一致性問題

  • 1:緩存系統與底層數據的一致性。這點在底層系統是「可讀可寫」時,寫得尤其重要
  • 2:有繼承關係的緩存之間的一致性。爲了儘可能提升緩存命中率,緩存也是分層:全局緩存,二級緩存。他們是存在繼承關係的。全局緩存能夠有二級緩存來組成。
  • 3:多個緩存副本之間的一致性。爲了保證系統的高可用性,緩存系統背後每每會接兩套存儲系統(如memcache,redis等)

緩存數據的淘汰

  • (1) 定時去清理過時的緩存。
  • (2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過時,過時的話就去底層系統獲得新數據並更新緩存。

緩存算法

  • FIFO算法:First in First out,先進先出。原則:一個數據最早進入緩存中,則應該最先淘汰掉。也就是說,當緩存滿的時候,應當把最早進入緩存的數據給淘汰掉。
  • LFU算法:Least Frequently Used,最不常用算法。
  • LRU算法:Least Recently Used,近期最少使用算法。請查看:Memcached之你真正理解LRU嗎(4)
  • LRU和LFU的區別。LFU算法是根據在一段時間裏數據項被使用的次數選擇出最少使用的數據項,即根據使用次數的差別來決定。而LRU是根據使用時間的差別來決定的

3、多線程

ThreadLocal   保證一個線程使用同一個對象

ThreadPoolExcutor  線程池建立

4、序列化和反序列化

序列化是指把對象轉換爲字節序列的過程;而反序列化是指把字節序列恢復爲對象的過程;

序列化主要的兩種用途:

1)把對象的字節序列保存到硬盤中(一般存放在一個文件中)

2)在網絡上傳送對象的字節序列

何時使用序列化:

1)對象序列化能夠實現分佈式對象,主要應用例如:RMI要利用對象序列化運行遠程主機上的服務,就像在本地機上運行對象時同樣。

2)java對象序列化不只保留一個對象的數據,並且遞歸保存對象引用的每一個對象的數據。能夠將整個對象層次寫入字節流中,能夠保存在文件中或在網絡鏈接上傳遞。利用對象序列化能夠進行對象的「深複製」,即複製對象自己及引用的對象自己。序列化一個對象可能獲得整個對象序列。

5、簡要描述下Spring的IoC和AOP

IoC就是對象的建立,依賴都有Spring及配置文件控制;而AOP就是統一的給一些相似的方法加上一樣的功能,好比日誌,事務。

IOC:控制反轉,是一種設計模式。

1)控制反轉,由傳統在程序中控制,變爲由容器控制

2)依賴注入:將互相依賴的對象分離,在Spring配置文件中描述他們的依賴關係。他們依賴關係只在使用的時候才創建。

AOP:面向切面。將系統中非核心的業務提取出來,進行單獨處理,好比事務、日誌和安全等。

實現方式:

  1. 註解
  2. xml配置

通知類型:

  • @Before:在目標方法被調用以前作加強處理,@Before只須要指定切入點表達式便可;
  • @AfterReturning:在目標方法正常完成後作加強,@AfterReturning除了指定切入點表達式後,還能夠指定一個返回值形參名returning,表明目標方法的返回值;
  • @AfterThrowing:主要用來處理程序中未處理的異常,@AfterThrowing除了指定切入點表達式後,還能夠指定一個throwing的返回值形參名,能夠經過該形參名來訪問目標方法中所拋出的異常對象;@
  • @After:在目標方法完成以後作加強,不管目標方法是否成功完成
  • @Around:環繞通知,在目標方法完成先後作加強處理,環繞通知是最重要的通知類型,像事務,日誌等都是環繞通知,

注意編程中核心是一個ProceedingJoinPoint

 1 @Component
 2 @Aspect 3 public class Operator { 4 5 @Pointcut("execution(* com.aijava.springcode.service..*.*(..))") 6 public void pointCut(){} 7 8 @Before("pointCut()") 9 public void doBefore(JoinPoint joinPoint){ 10 System.out.println("AOP Before Advice..."); 11  } 12 13 @After("pointCut()") 14 public void doAfter(JoinPoint joinPoint){ 15 System.out.println("AOP After Advice..."); 16  } 17 18 @AfterReturning(pointcut="pointCut()",returning="returnVal") 19 public void afterReturn(JoinPoint joinPoint,Object returnVal){ 20 System.out.println("AOP AfterReturning Advice:" + returnVal); 21  } 22 23 @AfterThrowing(pointcut="pointCut()",throwing="error") 24 public void afterThrowing(JoinPoint joinPoint,Throwable error){ 25 System.out.println("AOP AfterThrowing Advice..." + error); 26 System.out.println("AfterThrowing..."); 27  } 28 29 @Around("pointCut()") 30 public void around(ProceedingJoinPoint pjp){ 31 System.out.println("AOP Aronud before..."); 32 try { 33  pjp.proceed(); 34 } catch (Throwable e) { 35  e.printStackTrace(); 36  } 37 System.out.println("AOP Aronud after..."); 38  } 39 40 }

通知執行的優先級

進入目標方法時,先織入Around,再織入Before,退出目標方法時,先織入Around,再織入AfterReturning,最後才織入After。

注意:Spring AOP的環繞通知會影響到AfterThrowing通知的運行,不要同時使用!同時使用也沒啥意義。

原文:https://blog.csdn.net/chinacr07/article/details/78817449 

6、說一下轉發(forward)和重定向(redirect)的區別

  轉發(forward)
重定向(redirect)
地址欄 不變 改成重定向的地址
數據共享 能夠共享轉發前request的數據 不能共享request的數據
運用 通常用於用戶登陸後轉發到相應模塊 通常用於用戶註銷後回到首頁和跳轉到其餘網站等
效率

 

 

 

 

 

7、java虛擬機內存的堆、棧、方法區

堆:線程共享,存放數組和實例化對象(GC主要在這裏進行垃圾回收)jdk8後把運行時常量池、靜態變量也移到堆區進行存儲

虛擬機棧:線程私有,隨線程建立而建立,存放基本數據類型變量和引用等(操做數棧、方法出口等信息)

本地方法棧:線程私有,與虛擬機用到native方法相關,(JNI)

方法區:常量池

程序計數器:JVM支持多個線程同時運行,每一個線程都有本身的程序計數器,運行JVM方法會保存當前指令的地址。(PS:線程執行過程當中並非一口氣完成的,執行到一半中止後,下次繼續執行時,經過程序計數器就能夠知道該從什麼地方開始執行)

8、HashMap和HashTable

 

HashMap HashTable
非線程安全 線程安全
鍵值容許爲null 不容許爲null
containsValue/containsKey contains
繼承自Dictionary類 是Map接口的實現

9、cookie和session 的區別有哪些?

cookie session
數據存放在客戶端 數據存放在服務器
經過http協議實現的           -
不安全(存放在瀏覽器) 相對安全
            - 可能影響服務器性能
常規信息可放在cookie 重要信息如登陸信息等,放在session

 10、事務的實現方式

(1)編程式事務管理。咱們須要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理。
(2)基於xml配置, 聲明式事務管理(TransactionProxyFactoryBean)
(3)基於註解, @Transactional 的聲明式事務管理
(4)基於Aspectj AOP配置事務

11、java 調用靜態方法和構造函數和靜態塊執行的前後順序

 1 public class ExA {  
 2     static {  
 3         System.out.println("父類--靜態代碼塊");  
 4     }  
 5    
 6     public ExA() {  
 7         System.out.println("父類--構造函數");  
 8     }  
 9    
10     {  
11         System.out.println("父類--非靜態代碼塊");  
12     }  
13    
14     public static void main(String[] args) {  
15         new ExB();  
16     }  
17 }  
18    
19 class ExB extends ExA {  
20     static {  
21         System.out.println("子類--靜態代碼塊");  
22     }  
23     {  
24         System.out.println("子類--非靜態代碼塊");  
25     }  
26    
27     public ExB() {  
28         System.out.println("子類--構造函數");  
29     }  
30 }  
31  
32 執行結果 
33 ===== 
34 父類--靜態代碼塊 
35 子類--靜態代碼塊 
36 父類--非靜態代碼塊 
37 父類--構造函數 
38 子類--非靜態代碼塊 
39 子類--構造函數

12、java中的sleep()和wait()的區別

sleep()是Thread類中的方法,而wait是Object類提供的方法;

調用sleep()方法的時候,線程不會釋放對象鎖;

調用wait()方法的時候,線程會釋放對象鎖,只有對此對象調用notify()方法後,才獲取對象鎖進入運行狀態

原文:https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

十3、sql優化 

(一)、索引

如下狀況不會命中索引:

  1. 使用 !=或<>
  2. 使用 is nul / is not null (解決方案:設置默認值,好比設置默認0)
  3. 使用 or ( 解決方案:使用union all鏈接兩次查詢結果)
  4. 使用 like %xxxx
  5. 使用 in / not in (解決方案:使用between 或者 exist)
  6. 使用 自定義參數 @xxx (解決方案:強制使用索引,如:select id from t with(index(索引名)) where num=@num)
  7. 使用 函數,如:select id from t where substring(name,1,3)='abc'  /   select id from t where datediff(day,createdate,'2005-11-30')=0
  8. 使用 數學運算 如:select id from t where num/2=100
  9. 若是該索引是複合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使用,而且應儘量的讓字段順序與索引順序相一致。
相關文章
相關標籤/搜索