面試題抽答(補充)

小拾柒17發表於2020-11-14

面試題抽答

2.1.String 和 StringBuilder 的區別? ,為什麼會有這個區別?使用有什麼注意

String 和 StringBuffer、StringBuilder 的區別在於 String 宣告的是不可變的物件(final修飾),每次操作都會生成新的 String 物件,然後將指標指向新的 String 物件,而 StringBuffer、StringBuilder 可以在原有物件的基礎上進行操作,注意:在經常改變字串內容的情況下最好不要使用 String。

2.2.StringBuffer 和 StringBuilder 的區別,為什麼有那個區別?使用有什麼注意

StringBuffer (加了鎖,多執行緒使用)和 StringBuilder 最大的區別在於,StringBuffer 是執行緒安全的,而 StringBuilder 是非執行緒安全的,但 StringBuilder 的效能卻高於 StringBuffer,所以在單執行緒環境下推薦使用 StringBuilder,多執行緒環境下推薦使用 StringBuffer。

2.4.HashMap底層用到什麼哪些資料結構,為什麼會用到這些資料結構,初始長度是多少,什麼情況擴容
hashmap資料結構由陣列+連結串列組成,一個長度為16的陣列中,每個元素儲存的是一個連結串列的頭結點

什麼是Hash碰撞:(兩個輸入串的hash函式的值一樣,則稱這兩個串是一個碰撞(Collision)。既然是把任意長度的字串變成固定長度的字串,所以必有一個輸出串對應無窮多個輸入串,碰撞是必然存在的。)

處理碰撞:開放定址(Open Addressing)法和連結(Chaining)法

HashMap長度是預設的16
在容量不大於最大值的情況下,HashMap是以2倍的容量進行擴容的

2.5.HashMap和HashTable的區別,為什麼有這個區別

HashMap 和 Hashtable 有什麼區別?
儲存:HashMap 允許 key 和 value 為 null,而 Hashtable 不允許。
執行緒安全:HashMap 執行緒不安全,Hashtable 執行緒安全
推薦使用:在 Hashtable 的類註釋可以看到,Hashtable 是保留類不建議使用,推薦在單執行緒環境下使用 HashMap 替代,如果需要多執行緒使用則用 ConcurrentHashMap 替代。

HashMap和ConcurrentHashMap有什麼區別?

ConcurrentHashMap執行緒安全,hashMap執行緒不安全,
因為ConcurrentHashMap它引入了一個“分段鎖”的概念,對整個桶陣列進行了分段,把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。
2、ConcurrentHashMap在每一個分段上都用鎖進行保護,從而讓鎖的粒度更精細一些,併發效能更好,而HashMap沒有鎖機制,是執行緒不安全的
3.ConcurrentHashMap使用讀寫鎖

如何決定使用 HashMap 還是 TreeMap?
對於在 Map 中插入、刪除、定位一個元素這類操作,HashMap 是最好的選擇,因為相對而言 HashMap 的插入會更快,但如果你要對一個 key 集合進行有序的遍歷,那 TreeMap 是更好的選擇。

說一下 HashMap 的實現原理?
HashMap 基於 Hash 演算法實現的,我們通過 put(key,value)儲存,get(key)來獲取。當傳入 key 時,HashMap 會根據 key. hashCode() 計算出 hash 值,根據 hash 值將 value 儲存在 bucket 裡。當計算出的 hash 值相同時,我們稱之為 hash 衝突,HashMap 的做法是用連結串列和紅黑樹儲存相同 hash 值的 value。當 hash 衝突的個數比較少時,使用連結串列否則使用紅黑樹。

說一下 HashSet 的實現原理?
HashSet 是基於 HashMap 實現的,HashSet 底層使用 HashMap 來儲存所有元素,因此 HashSet 的實現比較簡單,相關 HashSet 的操作,基本上都是直接呼叫底層 HashMap 的相關方法來完成,HashSet 不允許重複的值。

2.3.ArryList的底層結構是什麼?初始長度是多少?擴容機制是什麼?

ArrayList初始大小為10,每次1.5倍進行擴容;它的底層是用陣列實現的,所以查詢速度相對LinkedList要快

ArrayList和LinkedList的區別,查詢誰快,修改誰快?

ArrayList的底層是用陣列實現的,所以查詢速度相對LinkedList要快

1.ArrayList使用了陣列的實現,可以認為ArrayList封裝了對內部陣列的操作,比如向陣列中新增,刪除,插入新的元素或者資料的擴充套件和重定向。

LinkedList使用了迴圈雙向連結串列資料結構,不需要維護容量的大小。與基於陣列ArrayList相比,這是兩種截然不同的實現技術,這也決定了它們將適用於完全不同的工作場景。
LinkedList連結串列由一系列 表項 連線而成。一個表項總是包含3個部分:元素內容,前驅表和後驅表

2.ArrayList 的查詢效率比較高,增刪動作的效率比較差,適用於查詢比較頻繁,增刪動作較少的元素管理的集合。
LinkedList 的查詢效率低,但是增刪效率很高。適用於增刪動作的比較頻繁,查詢次數較少的元素管理集合。

3.ArrayList ,LinkedList 都是執行緒不安全的

說一下"=="和equals方法究竟有什麼區別?

1.操作符專門用來比較兩個變數的值是否相同. 如果比較的是基本資料型別,那麼比較的是變數的值,如果比較的是引用資料型別,那麼比較的是地址值(兩個物件是否指向同一塊記憶體),要比較兩個 基本型別的資料或兩個引用變數是否相等只能用操作符

2.equals:用來比較兩個獨立物件的內容是否相同,如果沒有重寫equals方法比較的是兩個物件的地址值。 如果重寫了equals方法比較的是物件中的屬性的內容

1.講一下執行緒的幾種實現方式?
繼承thread 執行run方法
實現runnable介面和callable介面

2.執行緒池的作用,如何建立執行緒池,可以建立幾種執行緒池?
newCachedThreadPool建立一個可快取執行緒池
newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。
newScheduledThreadPool 建立一個定長執行緒池,支援定時及週期性任務執行。
newSingleThreadExecutor 建立一個單執行緒化的執行緒池

作用:第一:降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立和銷燬造成的消耗。
  第二:提高響應速度。當任務到達時,任務可以不需要等到執行緒建立就能立即執行。
  第三:提高執行緒的可管理性。

執行緒的狀態:
NEW 尚未啟動
RUNNABLE 正在執行中
BLOCKED 阻塞的(被同步鎖或者IO鎖阻塞)
WAITING 永久等待狀態
TIMED_WAITING 等待指定的時間重新被喚醒的狀態
TERMINATED 執行完成

sleep() 和 wait() 有什麼區別?
類的不同:sleep() 來自 Thread,wait() 來自 Object。
釋放鎖:sleep() 不釋放鎖;wait() 釋放鎖。
用法不同:sleep() 時間到會自動恢復;wait() 可以使用 notify()/notifyAll()直接喚醒。

notify()和 notifyAll()有什麼區別?
notifyAll()會喚醒所有的執行緒,notify()只會喚醒一個執行緒。notifyAll() 呼叫後,會將全部執行緒由等待池移到鎖池,然後參與鎖的競爭,競爭成功則繼續執行,如果不成功則留在鎖池等待鎖被釋放後再次參與競爭。而 notify()只會喚醒一個執行緒,具體喚醒哪一個執行緒由虛擬機器控制。

執行緒的 run() 和 start() 有什麼區別?
start() 方法用於啟動執行緒,run() 方法用於執行執行緒的執行時程式碼。
run() 可以重複呼叫,而 start() 只能呼叫一次

執行緒池都有哪些狀態?
RUNNING:這是最正常的狀態,接受新的任務,處理等待佇列中的任務。
SHUTDOWN:不接受新的任務提交,但是會繼續處理等待佇列中的任務。
STOP:不接受新的任務提交,不再處理等待佇列中的任務,中斷正在執行任務的執行緒。
TIDYING:所有的任務都銷燬了,workCount 為 0,執行緒池的狀態在轉換為 TIDYING 狀態時,會執行鉤子方法 terminated()。
TERMINATED:terminated()方法結束後,執行緒池的狀態就會變成這個。

執行緒池中 submit() 和 execute() 方法有什麼區別?
execute():只能執行 Runnable 型別的任務。
submit():可以執行 Runnable 和 Callable 型別的任務。
Callable 型別的任務可以獲取執行的返回值,而 Runnable 執行無返回值。

在 Java 程式中怎麼保證多執行緒的執行安全?
方法一:使用安全類,比如 Java. util. concurrent 下的類。
方法二:使用自動鎖 synchronized。
方法三:使用手動鎖 Lock。

synchronized 和 Lock 有什麼區別?
1.synchronized 可以給類、方法、程式碼塊加鎖;而 lock 只能給程式碼塊加鎖。
2.synchronized 不需要手動獲取鎖和釋放鎖,使用簡單,發生異常會自動釋放鎖,不會造成死鎖;
lock 需要自己加鎖和釋放鎖,如果使用不當沒有 unLock()去釋放鎖就會造成死鎖。
3.通過 Lock 可以知道有沒有成功獲取鎖,而 synchronized 卻無法辦到。

什麼是死鎖?
當執行緒 A 持有獨佔鎖a,並嘗試去獲取獨佔鎖 b 的同時,執行緒 B 持有獨佔鎖 b,並嘗試獲取獨佔鎖 a 的情況下,就會發生 AB 兩個執行緒由於互相持有對方需要的鎖,而發生的阻塞現象,我們稱為死鎖。

怎麼防止死鎖?
儘量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),設定超時時間,超時可以退出防止死鎖。
儘量使用 Java. util. concurrent 併發類代替自己手寫鎖。
儘量降低鎖的使用粒度,儘量不要幾個功能用同一把鎖。
儘量減少同步的程式碼塊。

Interceptor
主要作用:攔截使用者請求,進行處理,比如判斷使用者登入情況、許可權驗證,只要針對Controller請求進行處理,是通過HandlerInterceptor

Filter
主要作用:過濾字元編碼、做一些業務邏輯判斷,主要用於對使用者請求進行預處理,同時也可進行邏輯判斷。

Filter和Interceptor的區別

1、Filter是基於函式回撥(doFilter()方法)的,而Interceptor則是基於Java反射的(AOP思想)。

2、Filter依賴於Servlet容器,而Interceptor不依賴於Servlet容器。

3、Filter對幾乎所有的請求起作用,而Interceptor只能對action請求起作用。

4、Interceptor可以訪問Action的上下文,值棧裡的物件,而Filter不能。

6、Filter在過濾是隻能對request和response進行操作,而interceptor可以對request、response、handler、modelAndView、exception進行操作。

3.常用的設計模式有那些,你用過的框架中哪個地方用到了這些設計模式?
單例模式:保證被建立一次,節省系統開銷,
1.構造方法私有化,
2.在自己的類中建立一個單例項(餓漢模式是一出來就建立單例項,懶漢模式的話是需要的時候才建立單例項)
3.提供一個方法來獲取到例項物件

工廠模式:Spring IOC就是使用了工廠模式.
物件的建立交給一個工廠去建立。解耦程式碼

觀察者模式:物件之間的一對多的依賴,當一個物件改變時,它的所有的依賴者都會收到通知並自動更新

代理模式:Spring AOP就是使用的動態代理,對程式碼進行解耦,提高程式碼的維護性

模版方法模式:定義了一個演算法的骨架,而將一些步驟延遲到子類中,模版方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的步驟

狀態模式:允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類

1.Mysql的執行流程
1.客戶端和mysql伺服器建立連線
2.mysql伺服器執行查詢快取,判斷sql是否已經被執行,如果sql被命中,返回給客戶端,如果沒有命中就,將sql交給分析器
3.分析器分析sql語句功能
4.通過優化器對sql語句進行優化
5.選擇最好的優化方案之後呼叫執行器
6.執行器判斷許可權,如果沒有許可權就直接報錯,如果有許可權就呼叫mysql儲存引擎,返回介面執行的結果

資料庫索引的優缺點:

優點:
1.建立索引會的列保證了唯一性
2.建立索引增加索引速度,縮短檢索時間
3.建立索引可以加快表之間的連線
4.用來排序和分組的索引可加快排序和分組
缺點:
1.建立索引需要時間,空間成本
2.建立索引影響增刪改的效率

二:mysql的優化?為什麼要優化:處理高併發。單點故障,高可用,大資料

單機
1,建立資料庫:
資料庫儲存引擎選擇,A.選擇合適的儲存引擎,innodb,myisam,memery

三正規化:列資料不可以再分,做唯一標識的主鍵,做外來鍵進行連表查詢

和反三正規化,B.做反第三正規化(新增冗餘欄位)來優化

欄位資料型別:C.選擇最適用的欄位屬性
(瞭解)
1.char:string的java字串,長度固定
2.varchar:長度可以改變,一般使用varchar

3.tinyint:1個位元組,存狀態
4.bigint
5.int:4個位元組,10位數字

6.blod:上傳比較大的資料,存65k位元組
  longblob:可存4gb

7,dicmial:存科學計算小數,價格相關的資料

2,D.sql語句的優化
1.使用索引
索引概念:對資料庫的值進行排序的一種儲存結構,提高查詢效率(空間換時間)
索引分類:聚簇索引(主鍵索引),非聚簇索引(唯一索引,普通索引,複合索引)
建立索引的規範:
1.如果查詢的次數比較多,則使用索引
2.如果表只負責修改操作,不要建立索引,浪費空間
3.一張表不要建立過多的索引(不超過16),經常作為where groupby orderby等條件建立索引
4.不要去建立內容重複的列的索引
索引失效:
1.執行計劃:把explain加在查詢語句的前面(檢視是否通過索引查詢)(但是採用連線join代替子查詢,用union連線多個查詢語句聯合查詢,查詢速度快
2.模糊查詢,like,%在前面的時候索引會失效(不通過索引查詢,效率低)
3.函式
4.數字轉換
5.!=
6.範圍查詢
2.把多次操作轉換為一次操作
DQL(SELECT,orderby使用索引排序,groupby使用索引分組)
DDL(資料庫定義語言:INSERT、用在定義或改變表的結構,資料型別,表之間的連結和約束等初始化工作上),
DML(資料庫操作語言:UPDATE、INSERT、DELETE)
DCL(資料庫控制語言:是用來設定或更改資料庫使用者或角色許可權的語句)
or優化:兩個條件都是索引查詢,速度快,只要有一個條件不是索引查詢就不會走索引查詢
limit優化:沒有建立索引的列用limit時,查詢到需要的資料就返回,速度快

採用事務,要麼成功,要麼失敗
鎖定表,正常情況事務會鎖定庫,多個使用者查詢時需要等待,解決這種情況就鎖定表
使用外來鍵關聯查詢
避免在查詢中讓MySQL進行自動型別轉換
  
  3.定位慢查詢
  4.資料庫分表,分庫
  5.使用其他快取 

叢集
主從分離
讀寫分離

2.PreparedStatement相比Statement的好處

大多數我們都使用PreparedStatement代替Statement

1:PreparedStatement是預編譯的,比Statement速度快

2:程式碼的可讀性和可維護性
雖然用PreparedStatement來代替Statement會使程式碼多出幾行,但這樣的程式碼無論從可讀性還是可維護性上來說.都比直接用Statement的程式碼高很多檔次。

3:安全性
PreparedStatement可以防止SQL隱碼攻擊,而Statement卻不能

mysql儲存引擎

MySQL 5.7 支援的儲存引擎有 InnoDB(支援事務和外來鍵)、MyISAM(不支援事務)、Memory(存放在記憶體)、Merge、Archive、Federated、CSV、BLACKHOLE 等。

如果要提供提交、回滾和恢復的事務安全(ACID 相容)能力,並要求實現併發控制,InnoDB 是一個很好的選擇。
如果資料表主要用來插入和查詢記錄,則 MyISAM 引擎提供較高的處理效率。
如果只是臨時存放資料,資料量不大,並且不需要較高的資料安全性,可以選擇將資料儲存在記憶體的 MEMORY 引擎中,MySQL 中使用該引擎作為臨時表,存放查詢的中間結果。
如果只有 INSERT 和 SELECT 操作,可以選擇Archive 引擎,Archive 儲存引擎支援高併發的插入操作,但是本身並不是事務安全的。Archive 儲存引擎非常適合儲存歸檔資料,如記錄日誌資訊可以使用 Archive 引擎。

提示:使用哪一種引擎要根據需要靈活選擇,一個資料庫中多個表可以使用不同的引擎以滿足各種效能和實際需求。使用合適的儲存引擎將會提高整個資料庫的效能。

事務

事務是指是程式中一系列嚴密的邏輯操作,而且所有操作必須全部成功完成,否則在每個操作中所作的所有更改都會被撤消。可以通俗理解為:就是把多件事情當做一件事情來處理,好比大家同在一條船上,要活一起活,要完一起完

四個特性
1.原子性:事務不可以分割,操作這些指令時,要麼全部執行成功,要麼全部不執行。只要其中一個指令執行失敗,所有的指令都執行失敗,資料進行回滾,回到執行指令前的資料狀態

2.一致性:事務的執行使資料從一個狀態轉換為另一個狀態,但是對於整個資料的完整性保持穩定。

3.隔離性:隔離性是當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作所干擾,多個併發事務之間要相互隔離

4.永續性(Durability):當事務正確完成後,它對於資料的改變是永久性的

事務隔離級別:

1.Read uncommitted(最低階別,任何情況都無法保證。)
讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的資料
b事務修改:修改前:李四 修改後:張三 但是沒有提交事務,A讀取到的是張三。 但是B事務回滾了

2.Read committed(可避免髒讀的發生。)
讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取資料。

3.Repeatable read(可避免 髒讀、不可重複讀(針對的是修改) 的發生。)
重複讀,就是在開始讀取資料(事務開啟)時,不再允許修改操作
b事務修改:修改前:李四 修改後:張三 但是沒有提交事務,A第一次讀取到的是張三。 但是B事務回滾了,A第二次讀的就是李四

4.Serializable(可避免髒讀、不可重複讀、幻讀()的發生。) 序列化
Serializable 是最高的事務隔離級別,在該級別下,事務序列化順序執行,可以避免髒讀、不可重複讀與幻讀。但是這種事務隔離級別效率低下,比較耗資料庫效能,一般不使用

redis五種資料結構:

1.string:
set get mset mget setex setnx

2.hash
hset hget hgetall hdel hexists

3.list
lset lpush lpushx lpop rpop

4.set
SADD SINTER SMOVE SPOP

5.zset
ZADD ZCARD ZCOUNT

Redis 提供兩種持久化機制 RDB 和 AOF 機制:

1、RDBRedis DataBase)持久化方式: 是指用資料集快照的方式半持久化模式)

記錄 redis 資料庫的所有鍵值對,在某個時間點將資料寫入一個臨時檔案,持久化

結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。

優點:

1、只有一個檔案 dump.rdb,方便持久化。

2、容災性好,一個檔案可以儲存到安全的磁碟。

3、效能最大化,
4.相對於資料集大時,比 AOF 的啟動效率更高。

缺點:

資料安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生

故障,會發生資料丟失

2、AOFAppend-only file)持久化方式: 是指所有的命令列記錄以 redis 命令請

求協議的格式完全持久化儲存)儲存為 aof 檔案。

優點:

1、資料安全,aof 持久化可以配置 appendfsync 屬性,有 always,每進行一次

命令操作就記錄到 aof 檔案中一次。

3、AOF 機制的 rewrite 模式。AOF 檔案沒被 rewrite 之前(檔案過大時會對命令

進行合併重寫),可以刪除其中的某些命令(比如誤操作的 flushall))

缺點:

1、AOF 檔案比 RDB 檔案大,且恢復速度慢。

2、資料集大的時候,比 rdb 啟動效率低。

Redis有那些淘汰策略?

設定過期時間:淘汰將要過期的,用的少的以及任意淘汰
沒有設定過期時間:淘汰用的少的,任意淘汰
不淘汰

Redis如何模擬佇列,如何模擬棧

佇列
先進先出,list形式
lpush–》rpop
rpush–》lpop


lpush–》lpop

Redis為什麼這麼快

1、完全基於記憶體,絕大部分請求是純粹的記憶體操作,非常快速。資料存在記憶體中,類似於HashMap,HashMap的優勢就是查詢和操作的時間複雜度都是O(1);

2、資料結構簡單,對資料操作也簡單,Redis中的資料結構是專門進行設計的;

3、採用單執行緒,避免了不必要的上下文切換和競爭條件,也不存在多程式或者多執行緒導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的效能消耗;

4、使用多路I/O複用模型,非阻塞IO;

5、使用底層模型不同,它們之間底層實現方式以及與客戶端之間通訊的應用協議不一樣,Redis直接自己構建了VM 機制 ,因為一般的系統呼叫系統函式的話,會浪費一定的時間去移動和請求;

快取穿透

   描述:

   快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷髮起請求,如發起為id為“-1”的資料或id為特別大不存在的資料。這時的使用者很可能是攻擊者,攻擊會導致資料庫壓力過大。

  解決方案:

介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,id<=0的直接攔截;
從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key-value對寫為key-null,快取有效時間可以設定短點,如30秒(設定太長會導致正常情況也沒法使用)。這樣可以防止攻擊使用者反覆用同一個id暴力攻擊

快取擊穿
描述:
快取擊穿是指快取中沒有但資料庫中有的資料(一般是快取時間到期),這時由於併發使用者特別多,同時讀快取沒讀到資料,又同時去資料庫去取資料,引起資料庫壓力瞬間增大,造成過大壓力

  解決方案:

設定熱點資料永遠不過期。
加互斥鎖

快取雪崩
描述:

  快取雪崩是指快取中資料大批量到過期時間,而查詢資料量巨大,引起資料庫壓力過大甚至down機。和快取擊穿不同的是,快取擊穿指併發查同一條資料,快取雪崩是不同資料都過期了,很多資料都查不到從而查資料庫。

 解決方案:

快取資料的過期時間設定隨機,防止同一時間大量資料過期現象發生。
如果快取資料庫是分散式部署,將熱點資料均勻分佈在不同搞得快取資料庫中。
設定熱點資料永遠不過期。

非關係型資料庫
MongoDB:是一個面向文件的開源NoSQL資料庫。MongoDB使用JSON之類的文件來儲存任何資料。它是用c++寫的。
Cassandra:是Facebook為收件箱搜尋開發的。Cassandra是一個用於處理大量結構化資料的分散式資料儲存系統。
Redis:是最著名的鍵值儲存。Redis是用C語言編寫的。
HBase:是谷歌為BigTable資料庫設計的分散式非關聯式資料庫。
Neo4j:稱為原生圖資料庫,因為它有效地實現了屬性圖模型,一直到儲存層。
Oracle NoSQL:實現了從使用者定義的鍵到不透明資料項的對映。

orm框架(物件關係對映)
orm框架是為了解決面物件和資料庫互不匹配的的現象的一種技術框架
通過ibatis和hibernate來完成

ibatis:將sql和Java程式碼分離,提供了將結果集自動轉化為物件實體的的功能,可以寫出複雜的sql語句
hibernate:全自動orm對映工具,可以自動生成sql語句,執行sql語句並返回結果

ibatis和hibernate相同點:
都是orm框架,不使用jdbc api就能完成資料庫的持久化操作

ibatis和hibernate不同點:
1、hibernate要比ibatis功能強大很多。因為hibernate自動生成sql語句。
2、ibatis需要我們自己在xml配置檔案中寫sql語句,hibernate我們無法直接控制該語句,我們就無法去寫特定的高效率的sql

webservice是一個SOA(面向服務的程式設計)的架構,它是不依賴於語言,不依賴於平臺,可以實現不同的語言間的相互呼叫,通過Internet進行基於Http協議的網路應用間的互動。

1、異構系統(不同語言)的整合
2、不同客戶端的整合
3、實實在在的列子:
天氣預報:可以通過實現webservice客戶端呼叫遠端天氣服務實現的。
單點登入:一個服務是所有系統的登入

shiro:
可以做認證,授權,加密,會話管理,web整合,快取支援
shiro元件:
身份驗證:authentication
授權: authorization
會話管理:sessionmanager
加密
web支援
快取
Apache shiro三大核心元件
subject(當前使用者的操作),securitymanager(管理所有的subject),realms(許可權資訊認證)

其他元件:
 sessionmanager(會話管理),cachemanager(快取管理)

Shiro工作流程(圍繞三大核心元件)

1、應用程式碼通過Subject來進行認證和授權,而Subject又委託給SecurityManager;

2.給SecurityManager注入Realms,從而讓SecurityManager能得到合法的使用者及其許可權進行判斷。

instanceof 嚴格來說是Java中的一個雙目運算子,用來測試一個物件是否為一個類的例項,用法為:

boolean result = obj instanceof Class
instanceof 運算子的 obj 運算元的型別必須是引用型別或空型別; 否則,會發生編譯時錯誤

頁面靜態化
1.使用PHP檔案讀寫功能與ob快取機制生成靜態頁面
比如某個商品的動態詳情頁地址是: http://xxx.com?goods.php?gid=112
那麼這裡我們根據這個地址讀取一次這個詳情頁的內容,然後儲存為靜態頁,下次有人訪問這個商品詳情頁動態地址時,我們可以直接把已生成好的對應靜態內容檔案輸出出來。

2.使用nosql從記憶體中讀取內容(其實這個已經不算靜態化了而是快取);

iterater介面遍歷所有的collection介面,我們可以從一個collection介面中通過迭代器方法獲取到迭代器例項,迭代器取代了java集合框架中的enumeration,迭代器允許呼叫者在迭代過程中移除元素,iterater是更加安全的,因為當前遍歷元素被更改時丟擲異常

listiteration是繼承了iteration的,提供了iteration之外的一些功能
iterrator可以遍歷list和set集合,單向遍歷
listiteration只能遍歷list,雙向遍歷

說一下linux下面的一下常用命令?
常用:
Pwd 獲取當前路徑
Cd 跳轉到目錄
Su -u 切換到管理員
Ls ls 列舉目錄
檔案操作命令:
檔案
tail 檢視
rm -rf
vi
資料夾
mkdir
rm -r

有沒有使用過雲主機?
沒有使用過,但是有所瞭解。
雲主機就是一些雲服務運營商(阿里、華為等)提供的遠端的伺服器功能,我們開發者或者企業只需按需付費就可以租用對應的伺服器。
使用ssh和sftp來進行操作

docker
安裝docker

yum install docker-ce docker-ce-cli containerd.io

  1. 啟動並加入開機啟動

systemctl start docker

systemctl enable docker

6.驗證是否安裝成功

docker version

docker run hello-world

常用命令
1.docker pull [options] NAME[:TAG]
通過此命令可以docker遠端倉庫拉取映象到本地

2.docker images [options] [REPOSITORY[:TAG]
當本地映象非常多的時候要指定檢視某一個映象

3.docker run [options] IMAGE[:TAG] [COMMAND] [ARG…]
IMAGE是映象的名字
COMMAND是執行起來的時候要執行什麼命令.
ARG表示這條命令執行需要的引數.

檢視執行的容器:
docker ps

更多關於執行的命令:
docker run --help

8080埠是否開啟
netstat -na |grep 8080
是開啟的那麼訪問 主機ip:8080 即可訪問到nginx.

2.vue中的路由攔截器的作用?
路由攔截,許可權設定
例如:當使用者沒有登入許可權的時候就會跳轉到登入頁面,用到的欄位requireAuth:true

3.axios的作用?
vue中的ajax,用於向後臺發起請求
特點:
從瀏覽器中建立XMLHttpRequests

    從node.js建立http請求

    支援Promise API

    攔截請求和響應

    轉換請求資料和響應資料

    取消請求

    自動轉換json資料

    客戶端支援防禦XSRF
promise:
    一個物件用來傳遞非同步操作的資訊
    promise的出現主要是解決地獄回撥的問題,無需多次巢狀
    本質:分離非同步資料獲取和業務
攔截器分為請求攔截器和響應攔截器
#請求攔截器
axios.interceptors.request.use(function(config){
    return config;
},function(error){
    return Promise.reject(error);
});
#響應攔截器
axios.interceptors.response.use(function(response){
    return response;
},function(error){
    return Promise.reject(error);
});

4.列舉vue的常見指令。

1.文字插值:{{}}

2.DOM屬性繫結:v-bind

3.指令繫結一個事件監聽器:v-on

4.實現表單輸入和應用狀態之間的雙向繫結:v-model

5.控制切換一個元素的顯示:v-if和v-else

6.列表渲染:v-for

vue幾種常用的指令
  答:v-for 、 v-if 、v-bind、v-on、v-show、v-else,v-model

5.列舉Http請求中常見的請求方式?
get
向特定的路徑資源發出請求,資料暴露在url中
post
向指定路徑資源提交資料進行處理請求,資料包含在請求體中
options
返回伺服器針對特定資源所支援的http請求方法,允許客戶端檢視,測試伺服器效能
head
向伺服器與get請求相一致的響應,響應體不會返回,可以不必傳輸整個響應內容
put
從客戶端向伺服器端傳送的資料取代指定的文件的內容
delete
請求伺服器刪除指定的頁面

6.對於MVVM的理解

MVVM 是 Model-View-ViewModel 的縮寫。

Model代表資料模型,在Model中定義資料修改和操作的業務邏輯。
  View 代表UI 元件,將資料模型轉化成UI 展現出來。
  ViewModel 同步View 和 Model的物件,連線Model和View。

viewmodel和model實現雙向資料繫結

jsP是Servlet技術的擴充套件,所有的jsp檔案都會被翻譯為一個繼承HttpServlet的類。也就是jsp最終也是一個Servlet.這個Servlet對外提供服務。
Servlet和JSP最主要的不同點在於JSP側重於檢視,Servlet主要用於控制邏輯。
Servlet如果要實現html的功能,必須使用Writer輸出對應的html,比較麻煩。而JSP的情況是Java和HTML可以組合成一個副檔名為.jsp的檔案,做介面展示比較方便而嵌入邏輯比較複雜。

servlet生命週期:
載入Servlet的class---->例項化Servlet----->呼叫Servlet的init完成初始化---->響應請求(Servlet的service方法)----->Servlet容器關閉時(Servlet的destory方法)

第一次接收請求,Servlet啟動時,開始載入,servlet生命週期開始。Servlet被伺服器例項化後,容器執行其init方法,請求到達時執行其service方法,service方法自動派遣執行與請求對應的doXXX方法(doGet,doPost)等,當伺服器決定將例項銷燬的時候(伺服器關閉)呼叫其destroy方法。

Servlet API中forward() 與redirect()的區別?
1、forward是伺服器端的轉向而redirect是客戶端的跳轉。
2、使用forward瀏覽器的地址不會發生改變。而redirect會發生改變。
3、Forward是一次請求中完成。而redirect是重新發起請求。
Forward是在伺服器端完成,而不用客戶端重新發起請求,效率較高

7.Vue的生命週期

1.什麼是vue生命週期?
    答: Vue 例項從建立到銷燬的過程,就是生命週期。從開始建立、初始化資料、編譯模板、掛載Dom→渲染、更新→渲染、銷燬等一系列過程,稱之為 Vue 的生命週期。

2.vue生命週期的作用是什麼?
    答:它的生命週期中有多個事件鉤子,讓我們在控制整個Vue例項的過程時更容易形成好的邏輯。

3.vue生命週期總共有幾個階段?
    答:它可以總共分為8個階段:建立前/後, 載入前/後,更新前/後,銷燬前/銷燬後。

4.第一次頁面載入會觸發哪幾個鉤子?
    答:會觸發 下面這幾個beforeCreate, created, beforeMount, mounted 。(建立前後,掛載前後)

5.DOM 渲染在 哪個週期中就已經完成?
    答:DOM 渲染在 mounted 中就已經完成了。

JavaScript 實現是由以下 3 個不同部分組成的:
核心(ECMAScript)
文件物件模型(DOM,整合js,css,html)
瀏覽器物件模型(BOM,整合js和瀏覽器)

簡單地說,ECMAScript 描述了JavaScript語言本身的相關內容。

JavaScript 是指令碼語言
JavaScript 是一種輕量級的程式語言。

JavaScript 是可插入 HTML 頁面的程式設計程式碼。

JavaScript 插入 HTML 頁面後,可由所有的現代瀏覽器執行。

為什麼要用es?
es是一個高擴充套件、開源的全文檢索和分析引擎,它可以準實時地快速儲存、搜尋、分析海量的資料

我們課程資料將來會非常多,所以採用以往的模糊查詢,模糊查詢前置配置,會放棄索引,導致課程查詢效率非常低下,而我們使用ES做一個全文索引,我們將經常查詢的課程的某些欄位,比如說課程名,描述、價格還有id這些欄位我們放入我們索引庫裡,可以提高查詢速度

es解決原生Lucene使用的不足(只是一個庫,配置及使用非常複雜),優化Lucene的呼叫方式,並實現了高可用的分散式叢集的搜尋方案

es流程
索引過程:

1) 有一系列被索引檔案

2) 被索引檔案經過語法分析和語言處理形成一系列詞(Term) 。

3) 經過索引建立形成詞典和反向索引表。

4) 通過索引儲存將索引寫入硬碟。

搜尋過程:

a) 使用者輸入查詢語句。

b) 對查詢語句經過語法分析和語言分析得到一系列詞(Term) 。

c) 通過語法分析得到一個查詢樹。

d) 通過索引儲存將索引讀入到記憶體。

e) 利用查詢樹搜尋索引,從而得到每個詞(Term) 的文件連結串列,對文件連結串列進行交,差,並得到結果文件。

f) 將搜尋到的結果文件對查詢的相關性進行排序。

g) 返回查詢結果給使用者。

rabbitmq流程

在最初狀態下,生產者傳送訊息的時候

(1) 生產者連線到RabbitMQ Broker , 建立一個連線( Connection) ,開啟一個通道(Channel)

(2) 生產者宣告一個交換器,並設定相關屬性,比如交換機型別、是否持久化等

(3) 生產者宣告一個佇列井設定相關屬性,比如是否排他、是否持久化、是否自動刪除等

( 4 ) 生產者通過路由鍵將交換器和佇列繫結起來

( 5 ) 生產者傳送訊息至RabbitMQ Broker,其中包含路由鍵、交換器等資訊

(6) 相應的交換器根據接收到的路由鍵查詢相匹配的佇列。

( 7 ) 如果找到,則將從生產者傳送過來的訊息存入相應的佇列中。

(8) 如果沒有找到,則根據生產者配置的屬性選擇丟棄還是回退給生產者

(9) 關閉通道。

(1 0) 關閉連線
消費者接收訊息的過程:

(1)消費者連線到RabbitMQ Broker ,建立一個連線(Connection ) ,開啟一個通道(Channel) 。

(2) 消費者向RabbitMQ Broker 請求消費相應佇列中的訊息,可能會設定相應的回撥函式,
以及做一些準備工作

(3)等待RabbitMQ Broker 回應並投遞相應佇列中的訊息, 消費者接收訊息。

(4) 消費者確認( ack) 接收到的訊息。

( 5) RabbitMQ 從佇列中刪除相應己經被確認的訊息。

( 6) 關閉通道。

( 7) 關閉連線。

rabbitmq
如何避免訊息重複消費
kafka實際上有個offset的概念,就是每個訊息寫進去,都有一個offset,代表他的序號,然後consumer消費了資料之後,每隔一段時間,會把自己消費過的訊息的offset提交一下,代表我已經消費過了,下次我重啟時,從上次消費到的offset消費

冪等性,通俗點說,就一個資料,或者一個請求,給你重複來多次時要確保對應的資料是不會改變不能出錯的。

怎麼保證訊息佇列消費的冪等性?

結合業務來思考:

(1)如果資料要寫庫,先根據唯一條件查一下,如果這資料有了,就不再插入了,更新一下

(2)如果寫redis,那沒問題了,反正每次都是set,天然冪等性

(3)如果不是上面兩個場景,需要讓生產者傳送每條資料的時候,加一個全域性唯一的id,消費拿到了之後,先根據這個id去比如redis裡查一下,查詢之前是否消費過,如果沒有消費過,進行處理,然後這個id寫入redis。如果消費過了,就不再處理,保證不重複處理相同的訊息。

為什麼要用訊息佇列:削峰,非同步,解耦

rabbitMQ訊息可能丟失的情況:

1.傳送方發出訊息但沒有進入佇列。
2.接收者接到訊息,但處理過程出現錯誤。
3.佇列或者交換機當機。

針對上面的三種情況,rabbitMQ有三種應對措施。

publisher-confirms(傳送方確認模式)
將通道設定成confirm模式(傳送方確認模式),則所有在通道上釋出的訊息都會被指派一個唯一的ID。
一旦訊息被投遞到目的佇列後,或者訊息被寫入磁碟後(可持久化的訊息),通道會傳送一個確認給生產者(包含訊息唯一ID)。
如果RabbitMQ發生內部錯誤從而導致訊息丟失,會傳送一條nack未確認的訊息。

訊息確認機制(ACK)
當消費者獲取訊息後,會向RabbitMQ傳送回執ACK,告知訊息已經被接收。不過這種回執ACK分兩種情況:
自動ACK:訊息一旦被接收,消費者自動傳送ACK
– 如果訊息不太重要,丟失也沒有影響,那麼自動ACK會比較方便
手動ACK:訊息接收後,不會傳送ACK,需要手動呼叫
– 如果訊息非常重要,不容丟失。那麼最好在消費完成後手動ACK,否則接收訊息後就自動ACK,RabbitMQ就會把訊息從佇列中刪除。如果此時消費者當機,那麼訊息就丟失了

持久化
訊息持久化,當然前提是佇列和交換機必須持久化
RabbitMQ確保永續性訊息能從伺服器重啟中恢復的方式是,將它們寫入磁碟上的一個持久化日誌檔案,當釋出一條永續性訊息到持久交換器上時,Rabbit會在訊息提交到日誌檔案後才傳送響應。
一旦消費者從持久佇列中消費了一條持久化訊息,RabbitMQ會在持久化日誌中把這條訊息標記為等待垃圾收集。如果持久化訊息在被消費之前RabbitMQ重啟,那麼Rabbit會自動重建交換器和佇列(以及繫結),並重新發布持久化日誌檔案中的訊息到合適的佇列。

兩種微服務之間的授權方式,
一種是和使用者上下文有關的請求,通過Feign的攔截器轉發使用者請求中的Token的給下游微服務,
二種是微服務之間呼叫可能和當前使用者上下文無關,我們採用在攔截器中採用客戶端模式生成一個Token轉發給下游服務的方式,Hystrix的隔離策略:原理就是把呼叫執行緒A中的請求通過RequestContextHolder獲取到,放到新的執行緒B中的RequestContextHolder中即可

auth2的四種授權模式

密碼模式(resource owner password credentials)

授權碼模式(authorization code)

簡化模式(implicit)

客戶端模式(client credentials)

springboot註解
1)@SpringBootConfiguration // 繼承了Configuration,表示當前是註解類

2)@EnableAutoConfiguration // 開啟springboot的註解功能,springboot的四大神器之一,其藉助@import的幫助

3)@ComponentScan(excludeFilters = { // 掃描路徑設定(具體使用待確認)

為什麼要使用 spring?
spring 提供 ioc 技術,容器會幫你管理依賴的物件,從而不需要自己建立和管理依賴物件了,更輕鬆的實現了程式的解耦。
spring 提供了事務支援,使得事務操作變的更加方便。
spring 提供了面向切片程式設計,這樣可以更方便的處理某一類的問題。

spring ioc :控制反轉,指的是當前物件對內部成員的控制權交給其他(類,第三方容器)來管理
spring aop : 面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術

spring的事務傳播機制:
1.如果有事務,支援該事務,如果沒有事務
1.開啟一個事務
2.執行非事務
3.沒有可活動的事務,丟擲異常
2.總是開啟一個事務,掛起已經存在的事務
3.非事務執行
1.把所有的事務掛起
2.如果有可以活動的事務就丟擲異常
4.如果有可以活動的事務,可以進行巢狀,如果沒有事務就開啟事務

spring註解
1.宣告bean的註解

@Component 和spring做關聯,交給spring管理
@Service 在業務邏輯層使用(service層)

@Repository 在資料訪問層使用(dao層)

@Controller 在展現層使用,控制器的宣告(C)
2.注入bean的註解

@Autowired:由Spring提供

@Resource:由JSR-250提供

3.spring 自動裝配 bean 方式?
no:預設值,表示沒有自動裝配,應使用顯式 bean 引用進行裝配。
byName:它根據 bean 的名稱注入物件依賴項。
byType:它根據型別注入物件依賴項。
autodetect:容器先通過建構函式使用 autowire 裝配,如果不行,則通過 byType 自動裝配

4.spring 事務實現方式
宣告式事務:宣告式事務也有兩種實現方式,xml 配置檔案的方式和註解方式(在類上新增 @Transaction 註解)。
編碼方式:提供編碼的形式管理和維護事務。

5.spring 支援 5 種作用域
singleton:spring ioc 容器中只存在一個 bean 例項,以單例模式存在,是系統預設值;
prototype:每次呼叫 bean 時都會建立一個新的示例,頻繁建立和銷燬 bean 會帶來很大的效能開銷。

Web 環境下的作用域:
request:每次 http 請求都會建立一個 bean;
session:同一個 http session 共享一個 bean 例項;
global-session:globalsession 提供一個全域性性的 http session。用於 portlet 容器,因為每個 portlet 有單獨的 session

6.spring 有哪些主要模組?
spring core:框架的最基礎部分,提供 ioc 和依賴注入特性。
spring context:構建於 core 封裝包基礎上的 context 封裝包,提供了一種框架式的物件訪問方法。
spring dao: 提供了JDBC的抽象層。
spring aop:提供了面向切面的程式設計實現
spring Web:提供了針對 Web 開發的整合特性。
spring Web mvc:spring 中的 mvc 封裝包提供了Model-View-Controller(MVC)的實現。

7.spring 常用的注入方式
setter 屬性注入
構造方法注入
註解方式注入

8.spring建立Bean的三種方式
第一種方式:使用預設建構函式建立
在spring的配置檔案中使用bean標籤,配以id和class屬性之後,且沒有其他屬性和標籤時
採用的就是預設建構函式建立bean物件,此時如果類中沒有預設建構函式,則物件無法建立
第二種方式: 使用普通工廠中的方法建立物件(使用某個類中的方法建立物件,並存入spring容器)

    第三種方式:使用工廠中的靜態方法建立物件(使用某個類中的靜態方法建立物件,並存入spring容器)

mybatis

mybatis是一個持久層框架
它封裝了jdbc操作的很多細節,使開發者只需要關注sql語句本身,不需要關注註冊驅動,建立連線等繁雜過程,實現了對結果集的封裝。
MyBatis可以使用XML或者註解進行對映和配置,通過將引數對映到配置的SQL,然後解析為執行的SQL語句,查詢後將結果集對映成java物件返回,可以編寫動態sql等

常用標籤,註解
@Insert : 插入sql , 和xml insert sql語法完全一樣@Select : 查詢sql, 和xml select sql語法完全一樣
@Update : 更新sql, 和xml update sql語法完全一樣
@Delete : 刪除sql, 和xml delete sql語法完全一樣
@Param : 入參
@Results : 設定結果集合
@Result : 結果
@ResultMap : 引用結果集合
@SelectKey : 獲取最新插入id
@where
@if
@choose

說一下 MyBatis 的一級快取和二級快取?
一級快取:基於 PerpetualCache 的 HashMap 本地快取,它的生命週期是和 SQLSession 一致的,在有多個 SQLSession 或者分散式的環境中資料庫操作,可能會出現髒資料。當 Session flush 或 close 之後,該 Session 中的所有 Cache 就將清空,預設一級快取是開啟的。

二級快取:也是基於 PerpetualCache 的 HashMap 本地快取,不同在於其儲存作用域為 Mapper 級別的,如果多個SQLSession之間需要共享快取,則需要使用到二級快取,並且二級快取可自定義儲存源,如 Ehcache。預設不開啟二級快取,要開啟二級快取,使用二級快取屬性類需要實現 Serializable 序列化介面(可用來儲存物件的狀態)。
開啟二級快取資料查詢流程:二級快取 -> 一級快取 -> 資料庫。
快取更新機制:當某一個作用域(一級快取 Session/二級快取 Mapper)進行了C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。

MyBatis-plus是一款MyBatis的增強工具,在MyBatis 的基礎上只做增強不做改變
1)依賴少:僅僅依賴 Mybatis 以及 Mybatis-Spring 。

2)損耗小:啟動即會自動注入基本 CURD,效能基本無損耗,直接物件導向操作 。

3)預防Sql注入:內建 Sql 注入剝離器,有效預防Sql注入攻擊 。

4)支援程式碼生成:採用程式碼或者 Maven 外掛可快速生成 Mapper 、 Model 、 Service 、 Controller 層程式碼(生成自定義檔案,避免開發重複程式碼),支援模板引擎、有超多自定義配置等

5)內建分頁外掛:基於 Mybatis 物理分頁,開發者無需關心具體操作,配置好外掛之後,寫分頁等同於普通List查詢。

註解
@TableField
描述:欄位註解(非主鍵)
@TableId
描述:主鍵註解
@TableName
描述:表名註解

spring,springboot,springMVC的區別?

springboot整合了spring和springMVC,springMVC只是spring處理web層的一個模組

spring 的 ioc 和 aop ioc 提供了依賴注入的容器 aop 解決了面向橫切面的程式設計 然後在此兩者的基礎上實現了其他延伸產品的高階功能
Spring MVC 呢是基於 Servlet 的一個 MVC 框架 主要解決 WEB 開發的問題
因為 Spring 的配置太複雜了 各種 XML JavaConfig hin 麻煩 於是推出了 Spring boot 約定優於配置 簡化了 spring 的配置流程.

動態代理的實現:
java動態代理其實是一種設計模式,是Spring AOP 的核心技術。通俗的解釋就是往沒有耦合關係但卻需要經過同樣步驟處理的程式碼里加上這些“同樣步驟”

1.JDK代理使用的是反射機制實現aop的動態代理,CGLIB代理使用位元組碼處理框架asm,通過修改位元組碼生成子類。所以jdk動態代理的方式建立代理物件效率較高,執行效率較低,cglib建立效率較低,執行效率高;
2.JDK動態代理機制是委託機制,具體說動態實現介面類,在動態生成的實現類裡面委託hanlder去呼叫原始實現類方法,CGLIB則使用的繼承機制,具體說被代理類和代理類是繼承關係,所以代理類是可以賦值給被代理類的,如果被代理類有介面,那麼代理類也可以賦值給介面。

執行緒安全: 指多個執行緒在執行同一段程式碼的時候採用加鎖機制,使每次的執行結果和單執行緒執行的結果都是一樣的,不存在執行程式時出現意外結果。

執行緒不安全: 是指不提供加鎖機制保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料。

Feign,Feign整合了Ribbon是一種負載均衡的HTTP客戶端, 使用Feign呼叫API就像呼叫本地方法一樣,從避免了呼叫目標微服務時,需要不斷的解析/封裝json 資料的繁瑣。Ribbon+eureka是面向微服務程式設計,而Feign是面向介面程式設計。

springcloud五大元件
eureka,註冊中心
feign,服務之間的呼叫
rabbin,負載均衡
hystrix,熔斷
zuul閘道器

為什麼用註冊中心進行服務註冊和發現
如果我們沒有用註冊中心,服務之間通過IP和埠進行聯絡,當我們的服務崩潰了的時候,換個ip和埠時需要改我們的程式碼,麻煩,但是有了註冊中心之後,我們把服務註冊到註冊中心,並取名,當服務崩潰的時候我們只需要通過名字去匹配服務(已經註冊到eureka儲存了),不需要再書寫我們的程式碼

相關文章