日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

2023 亲自经历面试的初中级java面试题(持续更新)

發(fā)布時(shí)間:2024/1/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2023 亲自经历面试的初中级java面试题(持续更新) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

面試題

  • 基礎(chǔ)題
    • 集合
      • 說(shuō)一下list,set,map的區(qū)別。
      • hashMap key是自己定義的類,有沒(méi)復(fù)寫過(guò)hashcode或者equals這些方法 ?
      • 線程安全問(wèn)題
      • List
        • ArrayList 和 LinkedList 的區(qū)別是什么?
      • Set
        • HashSet的原理(怎么保證不重復(fù))?
      • Map
        • hashMap
          • hashMap的原理(怎么存儲(chǔ)鍵值對(duì)的 /怎么put進(jìn)去的)
        • HashMap和HashTable區(qū)別
        • HashMap和HashSet的區(qū)別
        • HashMap和TreeMap的區(qū)別
        • TreeSet和HashSet區(qū)別
    • 反射
      • 什么是反射?
      • 哪里用到反射機(jī)制?
    • 線程
      • 線程和進(jìn)程的區(qū)別?
      • 守護(hù)線程是什么?
      • 創(chuàng)建線程有哪幾種方式?
      • 線程有哪些狀態(tài)?
      • sleep() 和 wait() 有什么區(qū)別?
      • 在 Java 程序中怎么保證多線程的運(yùn)行安全?
      • 線程池
        • 什么是線程池?
        • 為什么要使用線程池?
        • 線程池有什么作用?
        • 線程池都有哪幾種工作隊(duì)列
        • 悲觀鎖、樂(lè)觀鎖
          • 什么是悲觀鎖,樂(lè)觀鎖
          • 實(shí)現(xiàn)方式
        • 什么是死鎖?
        • synchronized 和 Lock 有什么區(qū)別?
    • java垃圾回收
      • GC的主要任務(wù)
      • 垃圾回收機(jī)制的主要解決問(wèn)題
        • 1、哪些內(nèi)存需要回收?如何判斷?
        • 2、什么時(shí)候回收?
        • 3、如何回收,這就牽扯到垃圾收集算法和垃圾收集器
      • 垃圾回收總結(jié):
    • JAVA8的新特性
    • String類的常用方法有哪些?
    • String,StringBuffer,StringBuilder的區(qū)別。
    • GET 和POST 的區(qū)別?
    • session與cookie的差別
    • 說(shuō)一下 session 的工作原理?
    • 如果客戶端禁止 cookie 能實(shí)現(xiàn) session 還能用嗎?
    • 用戶登錄的功能服務(wù)器需要做什么,如何保持登錄狀態(tài)?
    • 泛型是什么?
    • 靜態(tài)屬性與普通屬性的區(qū)別是什么?
    • throw 和 throws 的區(qū)別?
    • final、finally、finalize 有什么區(qū)別?
      • final
      • finally
      • finalize
    • 說(shuō)一下堆棧的區(qū)別?
    • 局部變量是存放在棧中,還是存放在堆棧中?
  • 框架
    • Spring
      • Spring是什么?
      • Spring有哪些優(yōu)點(diǎn)?
      • AOP
      • IOC
      • 什么是 ORM 框架?
      • 注解是怎么生效的?
      • Spring事務(wù)的實(shí)現(xiàn)方式和實(shí)現(xiàn)原理
      • Spring事務(wù)管理的方式有幾種?
      • spring 中的 bean 是線程安全的嗎?
      • spring 事務(wù)實(shí)現(xiàn)方式有哪些?
      • 說(shuō)出Spring 或者 Springmvc中常用的5個(gè)注解,并解釋含義
      • log4j日志級(jí)別
    • SpringBoot
      • SpringBoot是什么?
      • Spring Boot 的配置文件有哪幾種格式?它們有什么區(qū)別?
      • springboot事務(wù)是怎么去控制的 / 實(shí)現(xiàn)管理事務(wù)的?
      • Spring Boot 的核心注解是哪個(gè)?它主要由哪幾個(gè)注解組成的?
      • SpringBoot 常用注解
      • Spring Boot 注冊(cè)bean的方法
      • SpringBoot注入依賴及注解
      • Spring Boot 自動(dòng)配置原理是什么?
      • Springboot里面哪些注解屬于單例模式?
      • @Controller和@RestController的區(qū)別
      • springboot常用的starter有哪些?
    • Mybatis
      • Mybatis模糊查詢用#和$什么區(qū)別
      • 簡(jiǎn)述Mybatis提供的兩級(jí)緩存,以及緩存的查找順序
    • SpringCloud
      • springCloud是什么?
      • spring cloud 斷路器的作用是什么?
      • spring cloud 的核心組件有哪些?
    • 高并發(fā)
      • 高并發(fā)解決方案案例
  • 數(shù)據(jù)庫(kù)
    • 索引
      • 什么是索引?(為什么需要使用索引)
      • 索引具體采用的哪種數(shù)據(jù)結(jié)構(gòu)
      • 既然你提到InnoDB使用的B+ 樹(shù)的索引模型,那么你知道為什么采用B+ 樹(shù)嗎?這和Hash索引比較起來(lái)有什么優(yōu)缺點(diǎn)嗎?
    • 優(yōu)化
      • SQL語(yǔ)句優(yōu)化
      • 分庫(kù)分表
      • 讀寫分離
    • Mysql和Oracle有什么區(qū)別?
    • group by后面還可以加什么
    • MySQL
      • MySQL的事務(wù)
      • 事務(wù)的并發(fā)問(wèn)題:
      • MySQL事務(wù)隔離級(jí)別:
      • 如何做 MySQL 的性能優(yōu)化?
      • 怎么確定有沒(méi)有用到索引
    • Redis
      • Redis是什么及特點(diǎn)
      • Redis除了緩存還能做什么
      • Redis 有哪些功能?
      • 一個(gè)字符串類型的值能存儲(chǔ)最大容量是多少?
      • 最大能存多大?
      • 線程安全嗎?
      • redis 存儲(chǔ)結(jié)構(gòu)
      • redis的基本數(shù)據(jù)類型
      • 怎么理解Redis事務(wù)?
      • 什么是Redis持久化?Redis有哪幾種持久化方式?優(yōu)缺點(diǎn)是什么?
      • 什么情況下要用到緩存,什么數(shù)據(jù)適合緩存,使用緩存需要注意什么問(wèn)題?
      • 什么是緩存擊穿?怎么解決?
      • 什么是緩存穿透?怎么解決?
      • 什么是緩存雪崩?怎么解決?
      • 怎么保證緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性?
      • Redis悲觀鎖和樂(lè)觀鎖
      • Redis 怎么實(shí)現(xiàn)分布式鎖?
      • Redis 分布式鎖有什么缺陷?
      • Redis 如何做內(nèi)存優(yōu)化?
      • redis是單線程的,為什么那么快
      • Redis 一級(jí)緩存與二級(jí)緩存(不知道答案對(duì)不對(duì))
  • Nginx
    • 請(qǐng)解釋一下什么是Nginx?
    • 請(qǐng)列舉Nginx和Apache 之間的不同點(diǎn)
    • 請(qǐng)解釋Nginx如何處理HTTP請(qǐng)求
    • 請(qǐng)列舉Nginx的一些特性
    • 簡(jiǎn)述反向代理和正向代理
      • 正向代理:
      • 反向代理:
    • 使用“反向代理服務(wù)器”的優(yōu)點(diǎn)是什么?
    • nginx負(fù)載均衡的幾種常用方式
    • 解決nginx負(fù)載均衡的session共享問(wèn)題
    • 一些配置
  • 安全性
    • 攻擊
      • 注入攻擊
        • 如何避免 SQL 注入?
        • 什么是 XSS 攻擊,如何避免?
  • 設(shè)計(jì)模式
    • 說(shuō)一下你熟悉的設(shè)計(jì)模式?
      • 單例模式
      • 工廠模式
      • 觀察者模式
      • 外觀模式
      • 模版方法模式
  • tomcat
    • 默認(rèn)線程數(shù)
  • Shiro
    • 談?wù)凷hiro的工作流程
    • 權(quán)限的注解
  • Linux
    • 拷文件
    • 跳節(jié)點(diǎn)
  • 前端
    • 前端跨域怎么實(shí)現(xiàn)
    • vue2生命周期
    • vue3生命周期

基礎(chǔ)題

集合

說(shuō)一下list,set,map的區(qū)別。

List:
1.可以允許重復(fù)的對(duì)象。
2.可以插入多個(gè)null元素。
3.是一個(gè)有序容器,保持了每個(gè)元素的插入順序,輸出的順序就是插入的順序。
4.常用的實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector。ArrayList 最為流行,它提供了使用索引的隨意訪問(wèn),而 LinkedList 則對(duì)于經(jīng)常需要從 List 中添加或刪除元素的場(chǎng)合更為合適。

Set:
1.不允許重復(fù)對(duì)象
2. 無(wú)序容器,你無(wú)法保證每個(gè)元素的存儲(chǔ)順序,TreeSet通過(guò) Comparator 或者 Comparable 維護(hù)了一個(gè)排序順序。
3. 只允許一個(gè) null 元素

4.Set 接口最流行的幾個(gè)實(shí)現(xiàn)類是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 實(shí)現(xiàn)的 HashSet;TreeSet 還實(shí)現(xiàn)了 SortedSet 接口,因此 TreeSet 是一個(gè)根據(jù)其
compare() 和 compareTo() 的定義進(jìn)行排序的有序容器。

Map:
1.Map不是collection的子接口或者實(shí)現(xiàn)類。Map是一個(gè)接口。
2.Map 的 每個(gè) Entry 都持有兩個(gè)對(duì)象,也就是一個(gè)鍵一個(gè)值,Map 可能會(huì)持有相同的值對(duì)象但鍵對(duì)象必須是唯一的。
3. TreeMap 也通過(guò) Comparator 或者 Comparable 維護(hù)了一個(gè)排序順序。
4. Map 里你可以擁有隨意個(gè) null 值但最多只能有一個(gè) null 鍵。
5.Map 接口最流行的幾個(gè)實(shí)現(xiàn)類是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

hashMap key是自己定義的類,有沒(méi)復(fù)寫過(guò)hashcode或者equals這些方法 ?

線程安全問(wèn)題

ArrayList、LinkedList、HashSet、HashMap是非線程安全的
HashTable,Vector是線程安全的;
StringBuilder是非線程安全的,StringBuffer是線程安全的。

List

ArrayList
優(yōu)點(diǎn): 底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢。
缺點(diǎn): 線程不安全,效率高
LinkedList
優(yōu)點(diǎn): 底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快。
缺點(diǎn): 線程不安全,效率高
Vector
優(yōu)點(diǎn): 底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢。
缺點(diǎn): 線程安全,效率低

ArrayList 和 LinkedList 的區(qū)別是什么?

數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn):ArrayList 是動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),而 LinkedList 是雙向鏈表的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)。
隨機(jī)訪問(wèn)效率:對(duì)于隨機(jī)訪問(wèn)get和set,ArrayList覺(jué)得優(yōu)于LinkedList,因?yàn)?LinkedList 是線性的數(shù)據(jù)存儲(chǔ)方式,所以需要移動(dòng)指針從前往后依次查找。
增加和刪除效率:對(duì)于新增和刪除操作add和remove,LinkedList比較占優(yōu)勢(shì),因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。 這一點(diǎn)要看實(shí)際情況的。若只對(duì)單條數(shù)據(jù)插入或刪除,ArrayList的速度反而優(yōu)于LinkedList。但若是批量隨機(jī)的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因?yàn)锳rrayList每插入一條數(shù)據(jù),要移動(dòng)插入點(diǎn)及之后的所有數(shù)據(jù)。。
綜合來(lái)說(shuō),在需要頻繁讀取集合中的元素時(shí),更推薦使用 ArrayList,而在插入和刪除操作較多時(shí),更推薦使用 LinkedList。

Set

HashSet
底層數(shù)據(jù)結(jié)構(gòu)是哈希表。(無(wú)序,唯一)
如何來(lái)保證元素唯一性?
1.依賴兩個(gè)方法:hashCode()和equals()
LinkedHashSet
底層數(shù)據(jù)結(jié)構(gòu)是鏈表和哈希表。(FIFO插入有序,唯一)
1.由鏈表保證元素有序
2.由哈希表保證元素唯一
TreeSet
底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹(shù)。(唯一,有序)

HashSet的原理(怎么保證不重復(fù))?

HashSet保證元素不重復(fù)是通過(guò)兩部分實(shí)現(xiàn)的,第一步通過(guò)比較兩個(gè)對(duì)象的哈希碼是否相同如果相同,只能懷疑是相同對(duì)象,那么進(jìn)而就會(huì)調(diào)用equals就行二次確認(rèn),如果確認(rèn)完畢之后相同,那么就會(huì)排除第二個(gè),否則的話就會(huì)插入該元素。因此,如果要保證存入對(duì)象的內(nèi)容不同的時(shí)候就需要同時(shí)重寫hash()和equals()方法自己定義比較的規(guī)則,一定要保證相同內(nèi)容的對(duì)象的哈希碼是相同的,不同對(duì)象的哈希碼是不同的。

Map

Map接口有三個(gè)比較重要的實(shí)現(xiàn)類,分別是HashMap、TreeMap和HashTable。
TreeMap是有序的,HashMap和HashTable是無(wú)序的。
Hashtable是線程安全的,HashMap不是線程安全的。
HashMap效率較高,Hashtable效率較低。
如果對(duì)同步性或與遺留代碼的兼容性沒(méi)有任何要求,建議使用HashMap。 查看
Hashtable的源代碼 就可以發(fā)現(xiàn),除構(gòu)造函數(shù)外,Hashtable的所有 public 方
法聲明中都有 synchronized關(guān)鍵字,而HashMap的源碼中則沒(méi)有。
Hashtable不允許null值,HashMap允許null值(key和value都允許)
父類不同:Hashtable的父類是Dictionary,HashMap的父類是AbstractMap

hashMap

hashMap比較好的一些問(wèn)題https://www.cnblogs.com/heqiyoujing/p/11143298.html

hashMap的原理(怎么存儲(chǔ)鍵值對(duì)的 /怎么put進(jìn)去的)

第一種(簡(jiǎn)單):
HashMap 基于 Hash 算法實(shí)現(xiàn)的,我們通過(guò) put(key,value)存儲(chǔ),get(key)來(lái)獲取。當(dāng)傳入 key 時(shí),HashMap 會(huì)根據(jù) key. hashCode() 計(jì)算出 hash 值,根據(jù) hash 值將 value 保存在 bucket 里。下一次key傳入時(shí),同樣計(jì)算hash值,并用equals比較。當(dāng)計(jì)算出的 hash 值相同時(shí),我們稱之為 hash 沖突,HashMap 的做法是用鏈表和紅黑樹(shù)存儲(chǔ)相同 hash 值的 value。當(dāng) hash 沖突的個(gè)數(shù)比較少時(shí)使用鏈表,否則使用紅黑樹(shù)。

第二種(這種聽(tīng)著比較牛):
調(diào)用哈希函數(shù)獲取Key對(duì)應(yīng)的hash值,再計(jì)算其數(shù)組下標(biāo);
如果沒(méi)有出現(xiàn)哈希沖突,則直接放入數(shù)組;如果出現(xiàn)哈希沖突,則以鏈表的方式放在鏈表后面;
如果鏈表長(zhǎng)度超過(guò)閥值( TREEIFY THRESHOLD==8),就把鏈表轉(zhuǎn)成紅黑樹(shù),鏈表長(zhǎng)度低于6,就把紅黑樹(shù)轉(zhuǎn)回鏈表;
如果結(jié)點(diǎn)的key已經(jīng)存在,則替換其value即可;
如果集合中的鍵值對(duì)大于12,調(diào)用resize方法進(jìn)行數(shù)組擴(kuò)容。”

HashMap和HashTable區(qū)別

(1)線程安全性不同
HashMap是線程不安全的,HashTable是線程安全的,其中的方法是Synchronize的,在多線程并發(fā)的情況下,可以直接使用HashTable,但是使用HashMap時(shí)必須自己增加同步處理。
(2)是否提供contains方法
HashMap只有containsValue和containsKey方法;HashTable有contains、containsKey和containsValue三個(gè)方法,其中contains和containsValue方法功能相同。
(3)key和value是否允許null值
Hashtable中,key和value都不允許出現(xiàn)null值。HashMap中,null可以作為鍵,這樣的鍵只有一個(gè);可以有一個(gè)或多個(gè)鍵所對(duì)應(yīng)的值為null。
(4)數(shù)組初始化和擴(kuò)容機(jī)制
HashTable在不指定容量的情況下的默認(rèn)容量為11,而HashMap為16,Hashtable不要求底層數(shù)組的容量一定要為2的整數(shù)次冪,而HashMap則要求一定為2的整數(shù)次冪。
Hashtable擴(kuò)容時(shí),將容量變?yōu)樵瓉?lái)的2倍加1,而HashMap擴(kuò)容時(shí),將容量變?yōu)樵瓉?lái)的2倍。

HashMap和HashSet的區(qū)別

HashMap和TreeMap的區(qū)別

HashMap:數(shù)組方式存儲(chǔ)key/value,線程非安全,允許null作為key和value,key不可以重復(fù),value允許重復(fù),不保證元素迭代順序是按照插入時(shí)的順序,key的hash值是先計(jì)算key的hashcode值,然后再進(jìn)行計(jì)算,每次容量擴(kuò)容會(huì)重新計(jì)算所以key的hash值,會(huì)消耗資源,要求key必須重寫equals和hashcode方法

TreeMap:基于紅黑二叉樹(shù)的NavigableMap的實(shí)現(xiàn),線程非安全,不允許null,key不可以重復(fù),value允許重復(fù),存入TreeMap的元素應(yīng)當(dāng)實(shí)現(xiàn)Comparable接口或者實(shí)現(xiàn)Comparator接口,會(huì)按照排序后的順序迭代元素,兩個(gè)相比較的key不得拋出classCastException。主要用于存入元素的時(shí)候?qū)υ剡M(jìn)行自動(dòng)排序,迭代輸出的時(shí)候就按排序順序輸出

TreeSet和HashSet區(qū)別

HashSet是采用hash表來(lái)實(shí)現(xiàn)的。其中的元素沒(méi)有按順序排列,add()、remove()以及contains()等方法都是復(fù)雜度為O(1)的方法。
TreeSet是采用樹(shù)結(jié)構(gòu)實(shí)現(xiàn)(紅黑樹(shù)算法)。元素是按順序進(jìn)行排列,但是add()、remove()以及contains()等方法都是復(fù)雜度為O(log (n))的方法。它還提供了一些方法來(lái)處理排序的set,如first(), last(), headSet(), tailSet()等等。

反射

什么是反射?

反射就是程序運(yùn)行期間jvm會(huì)洞悉任意一個(gè)類的屬性和方法,對(duì)任意一個(gè)對(duì)象都能夠訪問(wèn)它的屬性和方法。依靠此機(jī)制,可以動(dòng)態(tài)的創(chuàng)建一個(gè)類的對(duì)象和調(diào)用對(duì)象的方法
優(yōu)點(diǎn):增加靈活性,可以在運(yùn)行時(shí)動(dòng)態(tài)獲取對(duì)象
缺點(diǎn):效率低,破壞封裝,通過(guò)發(fā)射可以訪問(wèn)類的私有方法,不安全

哪里用到反射機(jī)制?

1.JDBC中,利用反射動(dòng)態(tài)加載了數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序。
2.Web服務(wù)器中利用反射調(diào)用了Sevlet的服務(wù)方法。
3.Eclispe等開(kāi)發(fā)工具利用反射動(dòng)態(tài)刨析對(duì)象的類型與結(jié)構(gòu),動(dòng)態(tài)提示對(duì)象的屬性和方法。
4.很多框架都用到反射機(jī)制,注入屬性,調(diào)用方法,如Spring。

線程

線程和進(jìn)程的區(qū)別?

一個(gè)程序下至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程下至少有一個(gè)線程,一個(gè)進(jìn)程下也可以有多個(gè)線程來(lái)增加程序的執(zhí)行速度。

守護(hù)線程是什么?

守護(hù)線程是運(yùn)行在后臺(tái)的一種特殊線程。它獨(dú)立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。在 Java 中垃圾回收線程就是特殊的守護(hù)線程。

創(chuàng)建線程有哪幾種方式?

繼承 Thread 重新 run 方法;
實(shí)現(xiàn) Runnable 接口;
實(shí)現(xiàn) Callable 接口。

線程有哪些狀態(tài)?

NEW 尚未啟動(dòng)
RUNNABLE 正在執(zhí)行中
BLOCKED 阻塞的(被同步鎖或者IO鎖阻塞)
WAITING 永久等待狀態(tài)
TIMED_WAITING 等待指定的時(shí)間重新被喚醒的狀態(tài)
TERMINATED 執(zhí)行完成

sleep() 和 wait() 有什么區(qū)別?

類的不同:sleep() 來(lái)自 Thread,wait() 來(lái)自 Object。
釋放鎖:sleep() 不釋放鎖;wait() 釋放鎖。
用法不同:sleep() 時(shí)間到會(huì)自動(dòng)恢復(fù);wait() 可以使用 notify()/notifyAll()直接喚醒。

在 Java 程序中怎么保證多線程的運(yùn)行安全?

方法一:使用安全類,比如 Java. util. concurrent 下的類。比如:ConCurrentHashMap
方法二:使用自動(dòng)鎖 synchronized。
方法三:使用手動(dòng)鎖 Lock。

線程池

什么是線程池?

線程池就是事先將線程放到一個(gè)容器中,當(dāng)使用線程的時(shí)候,不用再去new出一個(gè)線程,直接從線程池取出來(lái)就可以了

為什么要使用線程池?

創(chuàng)建線程和銷毀線程的花銷是比較大的,這些時(shí)間有可能比處理業(yè)務(wù)的時(shí)間還要長(zhǎng)。這樣頻繁的創(chuàng)建線程和銷毀線程,再加上業(yè)務(wù)工作線程,消耗系統(tǒng)資源的時(shí)間,可能導(dǎo)致系統(tǒng)資源不足。(我們可以把創(chuàng)建和銷毀的線程的過(guò)程去掉)

線程池有什么作用?

1、提高效率 創(chuàng)建好一定數(shù)量的線程放在池中,等需要使用的時(shí)候就從池中拿一個(gè),這要比需要的時(shí)候創(chuàng)建一個(gè)線程對(duì)象要快的多。
2、方便管理 可以編寫線程池管理代碼對(duì)池中的線程同一進(jìn)行管理,比如說(shuō)啟動(dòng)時(shí)有該程序創(chuàng)建100個(gè)線程,每當(dāng)有請(qǐng)求的時(shí)候,就分配一個(gè)線程去工作,如果剛好并發(fā)有101個(gè)請(qǐng)求,那多出的這一個(gè)請(qǐng)求可以排隊(duì)等候,避免因無(wú)休止的創(chuàng)建線程導(dǎo)致系統(tǒng)崩潰。

線程池都有哪幾種工作隊(duì)列

1、ArrayBlockingQueue
是一個(gè)基于數(shù)組結(jié)構(gòu)的有界阻塞隊(duì)列,此隊(duì)列按 FIFO(先進(jìn)先出)原則對(duì)元素進(jìn)行排序。
2、LinkedBlockingQueue
一個(gè)基于鏈表結(jié)構(gòu)的阻塞隊(duì)列,此隊(duì)列按FIFO (先進(jìn)先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。靜態(tài)工廠方法Executors.newFixedThreadPool()使用了這個(gè)隊(duì)列
3、SynchronousQueue
一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列。每個(gè)插入操作必須等到另一個(gè)線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài),吞吐量通常要高于LinkedBlockingQueue,靜態(tài)工廠方法Executors.newCachedThreadPool使用了這個(gè)隊(duì)列。
4、PriorityBlockingQueue
一個(gè)具有優(yōu)先級(jí)的無(wú)限阻塞隊(duì)列

悲觀鎖、樂(lè)觀鎖

什么是悲觀鎖,樂(lè)觀鎖

樂(lè)觀鎖和悲觀鎖是兩種思想,用于解決并發(fā)場(chǎng)景下的數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題。
樂(lè)觀鎖:樂(lè)觀鎖在操作數(shù)據(jù)時(shí)非常樂(lè)觀,認(rèn)為別人不會(huì)同時(shí)修改數(shù)據(jù)。因此樂(lè)觀鎖不會(huì)上鎖,只是在執(zhí)行更新的時(shí)候判斷一下在此期間別人是否修改了數(shù)據(jù):如果別人修改了數(shù)據(jù)則放棄操作,否則執(zhí)行操作。
悲觀鎖:悲觀鎖在操作數(shù)據(jù)時(shí)比較悲觀,認(rèn)為別人會(huì)同時(shí)修改數(shù)據(jù)。因此操作數(shù)據(jù)時(shí)直接把數(shù)據(jù)鎖住,直到操作完成后才會(huì)釋放鎖;上鎖期間其他人不能修改數(shù)據(jù)。

實(shí)現(xiàn)方式

悲觀鎖的實(shí)現(xiàn)方式是加鎖,加鎖既可以是對(duì)代碼塊加鎖(如Java的synchronized關(guān)鍵字),也可以是對(duì)數(shù)據(jù)加鎖(如MySQL中的排它鎖)。
樂(lè)觀鎖的實(shí)現(xiàn)方式:
CAS(Compare and Swap)比較并交換,是一種樂(lè)觀鎖的實(shí)現(xiàn),是用非阻塞算法來(lái)代替鎖定,其中 java.util.concurrent 包下的 AtomicInteger 就是借助 CAS 來(lái)實(shí)現(xiàn)的。
但 CAS 也不是沒(méi)有任何副作用,比如著名的 ABA 問(wèn)題就是 CAS 引起的。

什么是死鎖?

當(dāng)線程 A 持有獨(dú)占鎖a,并嘗試去獲取獨(dú)占鎖 b 的同時(shí),線程 B 持有獨(dú)占鎖 b,并嘗試獲取獨(dú)占鎖 a 的情況下,就會(huì)發(fā)生 AB 兩個(gè)線程由于互相持有對(duì)方需要的鎖,而發(fā)生的阻塞現(xiàn)象,我們稱為死鎖。
避免死鎖最簡(jiǎn)單的方法就是阻塞循環(huán)等待條件,將系統(tǒng)中所有資源設(shè)置標(biāo)志位、排序,規(guī)定所有的進(jìn)程申請(qǐng)資源必須以一定的順序(升序或者降序)做操作來(lái)避免死鎖

synchronized 和 Lock 有什么區(qū)別?

54.synchronized 可以給類、方法、代碼塊加鎖;而 lock 只能給代碼塊加鎖。
synchronized 不需要手動(dòng)獲取鎖和釋放鎖,使用簡(jiǎn)單,發(fā)生異常會(huì)自動(dòng)釋放鎖,不會(huì)造成死鎖;而 lock 需要自己加鎖和釋放鎖,如果使用不當(dāng)沒(méi)有 unLock()去釋放鎖就會(huì)造成死鎖。
通過(guò) Lock 可以知道有沒(méi)有成功獲取鎖,而 synchronized 卻無(wú)法辦到。

java垃圾回收

GC的主要任務(wù)

1.分配內(nèi)存
2.確保被引用對(duì)象的內(nèi)存不被錯(cuò)誤的回收
3.回收不再被引用的對(duì)象的內(nèi)存空間

垃圾回收機(jī)制的主要解決問(wèn)題

1、哪些內(nèi)存需要回收?如何判斷?

垃圾收集器會(huì)對(duì)堆進(jìn)行回收前,確定對(duì)象中哪些是“存活”,哪些是“死亡”(不可能再被任何途徑使用的對(duì)象)

判斷方法:
1、引用計(jì)數(shù)算法(不推薦)
每當(dāng)一個(gè)地方引用它時(shí),計(jì)數(shù)器+1;引用失效時(shí),計(jì)數(shù)器-1;計(jì)數(shù)值=0——不可能再被引用。
查看運(yùn)行結(jié)果,會(huì)發(fā)現(xiàn)并沒(méi)有因?yàn)閮蓚€(gè)對(duì)象互相引用就沒(méi)有回收,因此引用計(jì)數(shù)算法很難解決對(duì)象之間相互矛盾循環(huán)引用的問(wèn)題
2、可達(dá)性分析算法(推薦)
當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連,即不可達(dá)時(shí),則證明此對(duì)象時(shí)不可用的。
舉例:一顆樹(shù)有很多丫枝,其中一個(gè)分支斷了,跟樹(shù)上沒(méi)有任何聯(lián)系,那就說(shuō)明這個(gè)分支沒(méi)有用了,就可以當(dāng)垃圾回收去燒了。

2、什么時(shí)候回收?

1、會(huì)在cpu空閑的時(shí)候自動(dòng)進(jìn)行回收
2、在堆內(nèi)存存儲(chǔ)滿了之后
3、主動(dòng)調(diào)用System.gc()后嘗試進(jìn)行回收

3、如何回收,這就牽扯到垃圾收集算法和垃圾收集器

1)標(biāo)記—清除算法

這是最基礎(chǔ)的一種算法,分為兩個(gè)步驟,第一個(gè)步驟就是標(biāo)記,也就是標(biāo)記處所有需要回收的對(duì)象,標(biāo)記完成后就進(jìn)行統(tǒng)一的回收掉哪些帶有標(biāo)記的對(duì)象。這種算法優(yōu)點(diǎn)是簡(jiǎn)單,缺點(diǎn)是效率問(wèn)題,還有一個(gè)最大的缺點(diǎn)是空間問(wèn)題,標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,當(dāng)程序在以后的運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí)無(wú)法找到足夠的連續(xù)內(nèi)存而造成內(nèi)存空間浪費(fèi)。

兩個(gè)階段:標(biāo)記清除
不足:效率問(wèn)題;空間問(wèn)題(會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片)

2)復(fù)制算法

復(fù)制將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對(duì)象復(fù)制到另外一塊上面,然后再把已使用過(guò)的內(nèi)存空間一次清理掉。這樣使得每次都是對(duì)其中的一塊進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)也就不用考慮內(nèi)存碎片等復(fù)雜情況。只是這種算法的代價(jià)是將內(nèi)存縮小為原來(lái)的一半。

不足:將內(nèi)存縮小為了原來(lái)的一半

3)標(biāo)記—整理算法

標(biāo)記整理算法與標(biāo)記清除算法很相似,但最顯著的區(qū)別是:標(biāo)記清除算法僅對(duì)不存活的對(duì)象進(jìn)行處理,剩余存活對(duì)象不做任何處理,造成內(nèi)存碎片;而標(biāo)記整理算法不僅對(duì)不存活對(duì)象進(jìn)行處理清除,還對(duì)剩余的存活對(duì)象進(jìn)行整理,重新整理,因此其不會(huì)產(chǎn)生內(nèi)存碎片。

兩個(gè)階段:標(biāo)記清除
(讓存活的對(duì)象都向一端移動(dòng)

3)分代收集算法

分代收集算法是一種比較智能的算法,也是現(xiàn)在jvm使用最多的一種算法,他本身其實(shí)不是一個(gè)新的算法,而是他會(huì)在具體的場(chǎng)景自動(dòng)選擇以上三種算法進(jìn)行垃圾對(duì)象回收。
那么現(xiàn)在的重點(diǎn)就是分代收集算法中說(shuō)的自動(dòng)根據(jù)具體場(chǎng)景進(jìn)行選擇。這個(gè)具體場(chǎng)景到底是什么場(chǎng)景。

場(chǎng)景其實(shí)指的是針對(duì)jvm的哪一個(gè)區(qū)域,1.7之前jvm把內(nèi)存分為三個(gè)區(qū)域:新生代,老年代,永久代
JVM會(huì)將堆內(nèi)存分為兩個(gè)區(qū)域,一個(gè)新生代,一個(gè)老年代。
新生代:就是創(chuàng)建和使用完之后立馬就要被回收的對(duì)象放在里面
老年代:把一些會(huì)長(zhǎng)期存活的對(duì)象放在里面。
永久代:用于存放一些靜態(tài)文件,如Java類、方法等
了解過(guò)場(chǎng)景之后再結(jié)合分代收集算法得出結(jié)論:
1、在新生代中,每次垃圾收集時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,只有少量存活,那就選用復(fù)制算法。只需要付出少量存活對(duì)象的復(fù)制成本就可以完成收集。
2、老年代中因?yàn)閷?duì)象存活率高、沒(méi)有額外空間對(duì)他進(jìn)行分配擔(dān)保,就必須用標(biāo)記-清除或者標(biāo)記-整理。

垃圾回收總結(jié):

JAVA8的新特性

Lambda 表達(dá)式 ? Lambda 允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞到方法中)。

方法引用 ? 方法引用提供了非常有用的語(yǔ)法,可以直接引用已有Java類或?qū)ο?#xff08;實(shí)例)的方法或構(gòu)造器。與lambda聯(lián)合使用,方法引用可以使語(yǔ)言的構(gòu)造更緊湊簡(jiǎn)潔,減少冗余代碼。

默認(rèn)方法 ? 默認(rèn)方法就是一個(gè)在接口里面有了一個(gè)實(shí)現(xiàn)的方法。

新工具 ? 新的編譯工具,如:Nashorn引擎 jjs、 類依賴分析器jdeps。

Stream API ?新添加的Stream API(java.util.stream) 把真正的函數(shù)式編程風(fēng)格引入到Java中。

Date Time API ? 加強(qiáng)對(duì)日期與時(shí)間的處理。

Optional 類 ? Optional 類已經(jīng)成為 Java 8 類庫(kù)的一部分,用來(lái)解決空指針異常。

Nashorn, JavaScript 引擎 ? Java 8提供了一個(gè)新的Nashorn javascript引擎,它允許我們?cè)贘VM上運(yùn)行特定的javascript應(yīng)用。

String類的常用方法有哪些?

答:https://zhidao.baidu.com/question/232452768.html

String,StringBuffer,StringBuilder的區(qū)別。

第一種回答
答:1)如果操作少量的數(shù)據(jù)用String(查看源碼得知,String類的聲明是:public
final,改變它的值相當(dāng)于創(chuàng)建一個(gè)新的字符串)

2)單線程下操作大量的數(shù)據(jù)用StringBuilder

3)多線程下操作大量的數(shù)據(jù)用StringBuffer

https://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html

第二種回答
(1)StringBuffer 與 StringBuilder 中的方法和功能完全是等價(jià)的,
(2)只是StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進(jìn)行修飾,因此是線程安全的,而 StringBuilder 沒(méi)有這個(gè)修飾,可以被認(rèn)為是線程不安全的。
(3)在單線程程序下,StringBuilder效率更快,因?yàn)樗恍枰渔i,不具備多線程安全而StringBuffer則每次都需要判斷鎖,效率相對(duì)更低

GET 和POST 的區(qū)別?

GET 請(qǐng)求的數(shù)據(jù)會(huì)附在URL 之后(就是把數(shù)據(jù)放置在 HTTP 協(xié)議頭中),以?分割URL 和傳輸數(shù)據(jù),參數(shù)之間以&相連,如:login.action?name=zhagnsan&password=123456。POST 把提交的數(shù)據(jù)則放置在是 HTTP 包的包體中。

session與cookie的差別

Cookie實(shí)際上是一小段的文本信息。客戶端請(qǐng)求服務(wù)器,如果服務(wù)器需要記錄該用戶狀態(tài),就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie。客戶端瀏覽器會(huì)把Cookie保存起來(lái)。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí),瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie,以此來(lái)辨認(rèn)用戶狀態(tài)。服務(wù)器還可以根據(jù)需要修改Cookie的內(nèi)容。
Session 是存儲(chǔ)在 web 服務(wù)器端的一塊信息。session 對(duì)象存儲(chǔ)特定用戶會(huì)話所需的屬性及配置信息。當(dāng)用戶在應(yīng)用程序的 Web 頁(yè)之間跳轉(zhuǎn)時(shí),存儲(chǔ)在 Session 對(duì)象中的變量將不會(huì)丟失,而是在整個(gè)用戶會(huì)話中一直存在下去。
Cookie 和session 的不同點(diǎn):
(1)無(wú)論客戶端做怎樣的設(shè)置,session 都能夠正常工作。當(dāng)客戶端禁用 cookie 時(shí)將無(wú)法使用 cookie。
(2)在存儲(chǔ)的數(shù)據(jù)量方面:session 能夠存儲(chǔ)任意的java 對(duì)象,cookie 只能存儲(chǔ) String 類型的對(duì)象。
(3)cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上

說(shuō)一下 session 的工作原理?

session 的工作原理是客戶端登錄完成之后,服務(wù)器會(huì)創(chuàng)建對(duì)應(yīng)的 session,session 創(chuàng)建完之后,會(huì)把 session 的 id 發(fā)送給客戶端,客戶端再存儲(chǔ)到瀏覽器中。這樣客戶端每次訪問(wèn)服務(wù)器時(shí),都會(huì)帶著 sessionid,服務(wù)器拿到 sessionid 之后,在內(nèi)存找到與之對(duì)應(yīng)的 session 這樣就可以正常工作了。

如果客戶端禁止 cookie 能實(shí)現(xiàn) session 還能用嗎?

可以用
一般默認(rèn)情況下,在會(huì)話中,服務(wù)器存儲(chǔ) session 的 sessionid 是通過(guò) cookie 存到瀏覽器里。
如果瀏覽器禁用了 cookie,瀏覽器請(qǐng)求服務(wù)器無(wú)法攜帶 sessionid,服務(wù)器無(wú)法識(shí)別請(qǐng)求中的用戶身份,session失效。
但是可以通過(guò)其他方法在禁用 cookie 的情況下,可以繼續(xù)使用session。
1、通過(guò)url重寫,把 sessionid 作為參數(shù)追加的原 url 中,后續(xù)的瀏覽器與服務(wù)器交互中攜帶 sessionid 參數(shù)。
2、服務(wù)器的返回?cái)?shù)據(jù)中包含 sessionid,瀏覽器發(fā)送請(qǐng)求時(shí),攜帶 sessionid 參數(shù)。
3、通過(guò) Http 協(xié)議其他 header 字段,服務(wù)器每次返回時(shí)設(shè)置該 header 字段信息,瀏覽器中 js 讀取該 header 字段,請(qǐng)求服務(wù)器時(shí),js設(shè)置攜帶該 header 字段。

用戶登錄的功能服務(wù)器需要做什么,如何保持登錄狀態(tài)?

第一種,cookie和session的配合使用

實(shí)現(xiàn)原理:當(dāng)用戶請(qǐng)求頁(yè)面,一般需要先登錄,用戶第一次輸入用戶名和密碼之后,前臺(tái)發(fā)送post請(qǐng)求,后臺(tái)獲取用戶信息,通過(guò)查詢數(shù)據(jù)庫(kù)來(lái)驗(yàn)證用戶信息是否正確,如果驗(yàn)證通過(guò),則會(huì)開(kāi)辟一塊session空間來(lái)儲(chǔ)存用戶數(shù)據(jù),并且同時(shí)生成一個(gè)cookie字符串,由后臺(tái)返回給前臺(tái),前臺(tái)接收后,會(huì)把這個(gè)cookie字符串儲(chǔ)存到瀏覽器的cookie空間中,這個(gè)cookie就相當(dāng)于一把鑰匙,可以打開(kāi)后臺(tái)存儲(chǔ)對(duì)應(yīng)用戶信息的鎖,當(dāng)用戶下一次請(qǐng)求的時(shí)候,客戶端便會(huì)自動(dòng)攜帶這個(gè)cookie去請(qǐng)求服務(wù)器,服務(wù)器識(shí)別后,就會(huì)讀取session中的用戶信息,這樣用戶就可以直接訪問(wèn),就不需要再輸入用戶名密碼來(lái)驗(yàn)證身份了。
優(yōu)缺點(diǎn):
優(yōu)點(diǎn)是:提升了用戶體驗(yàn),cookie和session的結(jié)合使用,比直接在客戶端保存用戶信息要相對(duì)安全;缺點(diǎn)是:當(dāng)服務(wù)器向?yàn)g覽器傳送cookie的時(shí)候,很容易被劫持,并不是絕對(duì)的安全,還有一點(diǎn)就是,在大型的項(xiàng)目中,服務(wù)器往往不只一臺(tái),如果第一次請(qǐng)求,用戶信息被保存在了服務(wù)器1的session空間中,但是第二次請(qǐng)求被分流到了服務(wù)器2,這樣就獲取不到用戶信息了,依然要重新登錄,所以又引出了另一種方法:token來(lái)實(shí)現(xiàn)。

第二種,使用token安全令牌

實(shí)現(xiàn)原理:當(dāng)用戶請(qǐng)求頁(yè)面,輸入用戶信息,服務(wù)端經(jīng)過(guò)驗(yàn)證后,會(huì)生成一個(gè)token安全令牌(隨機(jī)字符串),并返回給客戶端,當(dāng)客戶端發(fā)送下一次請(qǐng)求的時(shí)候,直接攜帶這個(gè)token,服務(wù)端識(shí)別后,就可以直接訪問(wèn)頁(yè)面,不需要再次登錄了
優(yōu)點(diǎn):token只是以字符串的形式存在,不要服務(wù)器再開(kāi)辟空間,并且相對(duì)更安全,即使在傳輸?shù)倪^(guò)程中被劫持,別人也并不能破解內(nèi)容,并且減少了服務(wù)器壓力,減少頻繁的查詢數(shù)據(jù)庫(kù)。

泛型是什么?

就是一種不確定的輸出類型,只有需要在使用這個(gè)類的時(shí)候才能夠確定出來(lái)
泛型的好處:

  • 省略了強(qiáng)轉(zhuǎn)的代碼。2. 可以把運(yùn)行時(shí)的問(wèn)題提前到編譯時(shí)期。
  • 靜態(tài)屬性與普通屬性的區(qū)別是什么?

    靜態(tài)屬性 程序一加載時(shí) 就初始化,只有一份
    實(shí)例屬性 需要實(shí)例化后 才加載

    throw 和 throws 的區(qū)別?

    throw:是真實(shí)拋出一個(gè)異常。
    throws:是聲明可能會(huì)拋出一個(gè)異常。

    final、finally、finalize 有什么區(qū)別?

    final

    final關(guān)鍵字主要用在三個(gè)地方:變量、方法、類;
    final修飾的變量是常量不能被修改;
    final修飾的方法是私有(private)不可被調(diào)用;
    final修飾的類不能被繼承,類中的所有成員方法都被指定為final方法;

    finally

    finally:是 try{} catch{} finally{} 最后一部分,表示不論發(fā)生任何情況都會(huì)執(zhí)行,finally 部分可以省略,但如果 finally 部分存在,則一定會(huì)執(zhí)行 finally 里面的代碼。

    finalize

    finalize: 是 Object 類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法。

    說(shuō)一下堆棧的區(qū)別?

    功能方面:堆是用來(lái)存放對(duì)象的,棧是用來(lái)執(zhí)行程序的。
    共享性:堆是線程共享的,棧是線程私有的。
    空間大小:堆大小遠(yuǎn)遠(yuǎn)大于棧。

    局部變量是存放在棧中,還是存放在堆棧中?

    局部變量存放在棧中。
    程序bai運(yùn)行中有兩個(gè)存儲(chǔ)空間可用du,一個(gè)是棧,是zhi歸屬于進(jìn)程本身的,另外一個(gè)是堆,所有dao進(jìn)程共用的。
    局部變量在聲明周期為函數(shù)內(nèi)部,其存儲(chǔ)空間位于棧中。當(dāng)進(jìn)入函數(shù)時(shí),會(huì)對(duì)根據(jù)局部變量需求,在棧上申請(qǐng)一段內(nèi)存空間,供局部變量使用。當(dāng)局部變量生命周期結(jié)束后,在棧上釋放。
    由于進(jìn)程的棧空間是有限的,所以要避免申請(qǐng)占用空間過(guò)大的局部變量,以及避免函數(shù)嵌套層數(shù)過(guò)多。這些都可能引起棧空間不夠?qū)е鲁绦虮罎ⅰ?/p>

    框架

    Spring

    spring的15個(gè)經(jīng)典面試題:https://www.cnblogs.com/yanggb/p/11004887.html

    Spring是什么?

    Spring 是一個(gè)開(kāi)源框架,為簡(jiǎn)化企業(yè)級(jí)應(yīng)用開(kāi)發(fā)而生,目標(biāo)是使得Java EE應(yīng)用程序的開(kāi)發(fā)更加簡(jiǎn)捷,

    Spring有哪些優(yōu)點(diǎn)?

    輕量級(jí):Spring在大小和透明性方面絕對(duì)屬于輕量級(jí)的,基礎(chǔ)版本的Spring框架大約只有2MB。
    控制反轉(zhuǎn)(IOC):Spring使用控制反轉(zhuǎn)技術(shù)實(shí)現(xiàn)了松耦合。依賴被注入到對(duì)象,而不是創(chuàng)建或?qū)ふ乙蕾噷?duì)象。
    面向切面編程(AOP): Spring支持面向切面編程,同時(shí)把應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)的服務(wù)分離開(kāi)來(lái)。
    容器:Spring包含并管理應(yīng)用程序?qū)ο蟮呐渲眉吧芷凇?br /> MVC框架:Spring的web框架是一個(gè)設(shè)計(jì)優(yōu)良的web MVC框架,很好的取代了一些web框架。
    事務(wù)管理:Spring對(duì)下至本地業(yè)務(wù)上至全局業(yè)務(wù)(JAT)提供了統(tǒng)一的事務(wù)管理接口。
    異常處理:Spring提供一個(gè)方便的API將特定技術(shù)的異常(由JDBC, Hibernate, 或JDO拋出)轉(zhuǎn)化為一致的、Unchecked異常。

    AOP

    AOP(面向切面編程)能夠將那些與業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可擴(kuò)展性和可維護(hù)性。
    用于:事務(wù)處理、日志管理、權(quán)限控制

    IOC

    IOC(控制反轉(zhuǎn))是一種設(shè)計(jì)思想,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由給Spring框架來(lái)管理。IOC在其他語(yǔ)言中也有應(yīng)用,并非Spring特有。IOC容器是Spring用來(lái)實(shí)現(xiàn)IOC的載體,IOC容器實(shí)際上就是一個(gè)Map(key,value),Map中存放的是各種對(duì)象。
    將對(duì)象之間的相互依賴關(guān)系交給IOC容器來(lái)管理,并由IOC容器完成對(duì)象的注入。這樣可以很大程度上簡(jiǎn)化應(yīng)用的開(kāi)發(fā),把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來(lái)。IOC容器就像是一個(gè)工廠一樣,當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)對(duì)象的時(shí)候,只需要配置好配置文件/注解即可,完全不用考慮對(duì)象是如何被創(chuàng)建出來(lái)的。在實(shí)際項(xiàng)目中一個(gè)Service類可能由幾百甚至上千個(gè)類作為它的底層,假如我們需要實(shí)例化這個(gè)Service,可能要每次都搞清楚這個(gè)Service所有底層類的構(gòu)造函數(shù),這可能會(huì)把人逼瘋。如果利用IOC的話,你只需要配置好,然后在需要的地方引用就行了,大大增加了項(xiàng)目的可維護(hù)性且降低了開(kāi)發(fā)難度。
    也可理解為工廠模式+反射,不過(guò)工廠模式的對(duì)象生成是提前在工廠類中定死的,IOC更加靈活

    什么是 ORM 框架?

    ORM(Object Relation Mapping)對(duì)象關(guān)系映射,是把數(shù)據(jù)庫(kù)中的關(guān)系數(shù)據(jù)映射成為程序中的對(duì)象。
    使用 ORM 的優(yōu)點(diǎn):提高了開(kāi)發(fā)效率降低了開(kāi)發(fā)成本、開(kāi)發(fā)更簡(jiǎn)單更對(duì)象化、可移植更強(qiáng)。

    注解是怎么生效的?

    Spring會(huì)掃描所有的類包,反射獲取到類里面的注解,對(duì)注解進(jìn)行邏輯判斷,獲取到進(jìn)行分析,不同的注解有不同的邏輯

    Spring事務(wù)的實(shí)現(xiàn)方式和實(shí)現(xiàn)原理

    Spring事務(wù)的本質(zhì)其實(shí)就是數(shù)據(jù)庫(kù)對(duì)事務(wù)的支持,沒(méi)有數(shù)據(jù)庫(kù)的事務(wù)支持,spring是無(wú)法提供事務(wù)功能的。真正的數(shù)據(jù)庫(kù)層的事務(wù)提交和回滾是通過(guò)binlog或者redo log實(shí)現(xiàn)的。
    基于 @Transactional 的聲明式事務(wù)管理

    Spring事務(wù)管理的方式有幾種?

    1.編程式事務(wù):在代碼中硬編碼(不推薦使用)。
    2.聲明式事務(wù):在配置文件中配置(推薦使用),分為基于XML的聲明式事務(wù)和基于注解的聲明式事務(wù)。
    聲明式事務(wù)管理建立在AOP之上的。其本質(zhì)是通過(guò)AOP功能,對(duì)方法前后進(jìn)行攔截,將事務(wù)處理的功能編織到攔截的方法中,也就是在目標(biāo)方法開(kāi)始之前加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。

    spring 中的 bean 是線程安全的嗎?

    spring 中的 bean 默認(rèn)是單例模式,Spring容器本身并沒(méi)有提供線程安全的策略,因此是否線程安全完全取決于Bean本身的特性

    spring 事務(wù)實(shí)現(xiàn)方式有哪些?

    1.基于 xml 配置文件的方式
    2.注解方式(在類上添加 @Transaction 注解)

    說(shuō)出Spring 或者 Springmvc中常用的5個(gè)注解,并解釋含義

    log4j日志級(jí)別

    DEBUG:輸出調(diào)試信息;指出細(xì)粒度信息事件對(duì)調(diào)試應(yīng)用程序是非常有幫助的。
    INFO: 輸出提示信息;消息在粗粒度級(jí)別上突出強(qiáng)調(diào)應(yīng)用程序的運(yùn)行過(guò)程。
    WARN: 輸出警告信息;表明會(huì)出現(xiàn)潛在錯(cuò)誤的情形。
    ERROR:輸出錯(cuò)誤信息;指出雖然發(fā)生錯(cuò)誤事件,但仍然不影響系統(tǒng)的繼續(xù)運(yùn)行。
    FATAL:輸出致命錯(cuò)誤;指出每個(gè)嚴(yán)重的錯(cuò)誤事件將會(huì)導(dǎo)致應(yīng)用程序的退出。
    ALL level:打開(kāi)所有日志記錄開(kāi)關(guān);是最低等級(jí)的,用于打開(kāi)所有日志記錄。
    OFF level:關(guān)閉所有日志記錄開(kāi)關(guān);是最高等級(jí)的,用于關(guān)閉所有日志記錄。

    按照范圍從小到大排序:OFF level > FATAL > ERROR > WARN > INFO > DEBUG > ALL
    level;范圍大的會(huì)包含范圍小的,例如日志設(shè)置為INFO級(jí)別的話則FATAL、ERROR、WARN、INFO的日志開(kāi)關(guān)都是打開(kāi)的,而DEBUG的日志開(kāi)關(guān)將是關(guān)閉的。

    Log4j建議只使用四個(gè)級(jí)別,優(yōu)先級(jí)從高到低分別是 ERROR、WARN、INFO、DEBUG。

    SpringBoot

    SpringBoot是什么?

    簡(jiǎn)單版:
    用來(lái)簡(jiǎn)化spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程
    使用特定的方式來(lái)進(jìn)行配置(properties或yml文件)
    main方法運(yùn)行
    嵌入的Tomcat 無(wú)需部署war文件
    簡(jiǎn)化maven配置
    自動(dòng)配置spring添加對(duì)應(yīng)功能starter自動(dòng)化配置
    spring boot來(lái)簡(jiǎn)化spring應(yīng)用開(kāi)發(fā),約定大于配置,去繁從簡(jiǎn),just run就能創(chuàng)建一個(gè)獨(dú)立的,產(chǎn)品級(jí)別的應(yīng)用

    復(fù)雜版(改):
    Spring Boot 是 Spring 開(kāi)源組織下的子項(xiàng)目,是 Spring 組件一站式解決方案,主要是簡(jiǎn)化了使用 Spring 的難度,簡(jiǎn)省了繁重的配置,提供了各種啟動(dòng)器,開(kāi)發(fā)者能快速上手。
    1、獨(dú)立運(yùn)行
    Spring Boot而且內(nèi)嵌了各種servlet容器,Tomcat、Jetty等,現(xiàn)在不再需要打成war包部署到容器中,Spring Boot只要打成一個(gè)可執(zhí)行的jar包就能獨(dú)立運(yùn)行,所有的依賴包都在一個(gè)jar包內(nèi)。
    2、簡(jiǎn)化配置
    spring-boot-starter-web啟動(dòng)器自動(dòng)依賴其他組件,簡(jiǎn)少了maven的配置。除此之外,還提供了各種啟動(dòng)器,開(kāi)發(fā)者能快速上手。
    3、自動(dòng)配置
    Spring Boot能根據(jù)當(dāng)前類路徑下的類、jar包來(lái)自動(dòng)配置bean,如添加一個(gè)spring-boot-starter-web啟動(dòng)器就能擁有web的功能,無(wú)需其他配置。
    4、無(wú)代碼生成和XML配置
    Spring Boot配置過(guò)程中無(wú)代碼生成,也無(wú)需XML配置文件就能完成所有配置工作,這一切都是借助于條件注解完成的,這也是Spring4.x的核心功能之一。
    5、應(yīng)用監(jiān)控
    Spring Boot提供一系列端點(diǎn)可以監(jiān)控服務(wù)及應(yīng)用,做健康檢測(cè)。

    Spring Boot 的配置文件有哪幾種格式?它們有什么區(qū)別?

    .properties 和 .yml,它們的區(qū)別主要是書寫格式不同。

    springboot事務(wù)是怎么去控制的 / 實(shí)現(xiàn)管理事務(wù)的?

    我們以前沒(méi)有spring的時(shí)候,都是手動(dòng)報(bào)錯(cuò)就rollback的,現(xiàn)在有了spring,底層實(shí)現(xiàn)是用了aop 創(chuàng)建代理對(duì)象,就可以產(chǎn)生事務(wù)了

    Spring Boot 的核心注解是哪個(gè)?它主要由哪幾個(gè)注解組成的?

    啟動(dòng)類上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要組合包含了以下 3 個(gè)注解:
    @SpringBootConfiguration:組合了 @Configuration 注解,實(shí)現(xiàn)配置文件的功能。
    @EnableAutoConfiguration:打開(kāi)自動(dòng)配置的功能,也可以關(guān)閉某個(gè)自動(dòng)配置的選項(xiàng),如關(guān)閉數(shù)據(jù)源自動(dòng)配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
    @ComponentScan:Spring組件包名掃描。

    SpringBoot 常用注解

    1.@RestController 和 @RequestMapping 注解
    2.@SpringBootApplication
    3.@ResponseBody @RequestParam
    4.@AutoWired
    5.@PathVariable

    Spring Boot 注冊(cè)bean的方法

    @ComponentScan
    @Bean
    @Import

    SpringBoot注入依賴及注解

    常用注解
    @Service用于標(biāo)注業(yè)務(wù)層組件
    @Controller用于標(biāo)注控制層組件
    @Repository用于標(biāo)注數(shù)據(jù)庫(kù)訪問(wèn)Dao組件
    @Component泛指組件,當(dāng)組件不好歸類的時(shí)候,我們可以使用這個(gè)注解進(jìn)行標(biāo)注
    @Autowired,自動(dòng)注入,自動(dòng)從spring的上下文找到合適的bean來(lái)注入
    @RestController,Spring4之后新加入的注解,原來(lái)返回json需要@ResponseBody和@Controller配合,將調(diào)用的結(jié)果直接返回給調(diào)用者。
    @Value:注入Spring boot application.properties配置的屬性的值。
    @RequestMapping:提供路由信息,負(fù)責(zé)URL到Controller中的具體函數(shù)的映射。@RequestMapping(“/path”)表示該控制器處理所有“/path”的UR L請(qǐng)求。RequestMapping是一個(gè)用來(lái)處理請(qǐng)求地址映射的注解,可用于類或方法上。
    @GetMapping是一個(gè)組合注解,是@RequestMapping(method = RequestMethod.GET)的縮寫。該注解將HTTP Get 映射到 特定的處理方法上。
    同理PostMapping也是一個(gè)組合注解,是@RequestMapping(method = RequestMethod.POST)的縮寫。
    @PathVariable:獲取url中的數(shù)據(jù)。
    @ComponentScan 組件掃描,發(fā)現(xiàn)和組裝一些Bean。
    @EnableAutoConfiguration自動(dòng)配置。
    @SpringBootApplication:申明讓spring boot自動(dòng)給程序進(jìn)行必要的配置,這個(gè)配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三個(gè)配置。
    @Data 自動(dòng)生成setter、getter方法
    @Import:用來(lái)導(dǎo)入其他配置類。
    @ImportResource:用來(lái)加載xml配置文件。
    @Bean:放在方法的上面,而不是類,意思是產(chǎn)生一個(gè)bean,并交給spring管理。
    @Inject:等價(jià)于默認(rèn)的@Autowired,只是沒(méi)有required屬性;

    Spring Boot 自動(dòng)配置原理是什么?

    注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自動(dòng)配置的核心,首先它得是一個(gè)配置文件,其次根據(jù)類路徑下是否有這個(gè)類去自動(dòng)配置。

    Springboot里面哪些注解屬于單例模式?

    @AutoWired

    @Controller和@RestController的區(qū)別

    springboot常用的starter有哪些?

    1.spring-boot-starter-web (嵌入tomcat和web開(kāi)發(fā)需要servlet與jsp支持)
    2.spring-boot-starter-data-jpa (數(shù)據(jù)庫(kù)支持)
    3.spring-boot-starter-data-redis (redis數(shù)據(jù)庫(kù)支持)
    4.spring-boot-starter-data-solr (solr搜索應(yīng)用框架支持)
    5.mybatis-spring-boot-starter (第三方的mybatis集成starter)

    Mybatis

    Mybatis模糊查詢用#和$什么區(qū)別

    簡(jiǎn)述Mybatis提供的兩級(jí)緩存,以及緩存的查找順序

    參考:https://juejin.cn/post/6926161053743218695

    一級(jí)緩存是SqlSession級(jí)別的緩存。在操作數(shù)據(jù)庫(kù)時(shí)需要構(gòu)造sqlSession對(duì)象,底層實(shí)際上是在對(duì)象中有一個(gè)數(shù)據(jù)結(jié)構(gòu)(HashMap)用于存儲(chǔ)緩存數(shù)據(jù)。不同的sqlSession之間的緩存數(shù)據(jù)區(qū)域(HashMap)是互相不影響的。
    二級(jí)緩存是mapper級(jí)別的緩存,多個(gè)SqlSession去操作同一個(gè)Mapper的sql語(yǔ)句,多個(gè)SqlSession可以共用二級(jí)緩存,二級(jí)緩存是跨SqlSession的。

    緩存的查找順序:二級(jí)緩存 => 一級(jí)緩存 => 數(shù)據(jù)庫(kù)

    一級(jí)緩存是SqlSession級(jí)別的
    一級(jí)緩存默認(rèn)開(kāi)啟
    一級(jí)緩存在底層update方法也就是刪除 新增 更新 時(shí)候會(huì)清除一級(jí)緩存;
    一級(jí)緩存在查詢的時(shí)候會(huì)先從緩存中查詢,沒(méi)查到去查db,然后再放入本地一級(jí)緩存;
    一級(jí)緩存之前會(huì)先從二級(jí)緩存查,沒(méi)查到再去一級(jí)查,一級(jí)沒(méi)查到再去db查;

    SpringCloud

    springCloud是什么?

    SpringCloud是基于SpringBoot的一套實(shí)現(xiàn)微服務(wù)的框架。它提供了微服務(wù)開(kāi)發(fā)所需的配置管理、服務(wù)發(fā)現(xiàn)、斷路器、智能路由、微代理、控制總線、全局鎖、決策競(jìng)選、分布式會(huì)話和集群狀態(tài)管理等組件。最重要的是,跟SpringBoot框架一起使用的話,會(huì)讓你開(kāi)發(fā)微服務(wù)架構(gòu)的云服務(wù)非常方便。

    SpringCloud五大核心組件:
    服務(wù)注冊(cè)發(fā)現(xiàn)-Netflix Eureka
    配置中心 - spring cloud config
    負(fù)載均衡-Netflix Ribbon
    斷路器 - Netflix Hystrix
    路由(網(wǎng)關(guān)) - Netflix Zuul

    spring cloud 斷路器的作用是什么?

    在分布式架構(gòu)中,斷路器模式的作用也是類似的,當(dāng)某個(gè)服務(wù)單元發(fā)生故障(類似用電器發(fā)生短路)之后,通過(guò)斷路器的故障監(jiān)控(類似熔斷保險(xiǎn)絲),向調(diào)用方返回一個(gè)錯(cuò)誤響應(yīng),而不是長(zhǎng)時(shí)間的等待。這樣就不會(huì)使得線程因調(diào)用故障服務(wù)被長(zhǎng)時(shí)間占用不釋放,避免了故障在分布式系統(tǒng)中的蔓延。

    spring cloud 的核心組件有哪些?

    Eureka:服務(wù)注冊(cè)于發(fā)現(xiàn)。
    Feign:(負(fù)載均衡)一個(gè)輕量級(jí)Restful的HTTP服務(wù)客戶端,Feign內(nèi)置了Ribbon,用來(lái)做客戶端負(fù)載均衡,去調(diào)用服務(wù)注冊(cè)中心的服務(wù)。Feign的使用方式是:使用Feign的注解定義接口,調(diào)用這個(gè)接口,就可以調(diào)用服務(wù)注冊(cè)中心的服務(wù)
    Hystrix:提供線程池,不同的服務(wù)走不同的線程池,實(shí)現(xiàn)了不同服務(wù)調(diào)用的隔離,避免了服務(wù)雪崩的問(wèn)題。
    Zuul:網(wǎng)關(guān)管理,由 Zuul 網(wǎng)關(guān)轉(zhuǎn)發(fā)請(qǐng)求給對(duì)應(yīng)的服務(wù)。

    高并發(fā)

    高并發(fā)解決方案案例

    常用的高并發(fā)處理的思路與手段

    從服務(wù)端視角看高并發(fā)

    服務(wù)端處理請(qǐng)求需要耗費(fèi)服務(wù)端的資源,比如能同時(shí)開(kāi)啟的進(jìn)程數(shù)、能同時(shí)運(yùn)行的線程數(shù)、網(wǎng)絡(luò)連接數(shù)、cpu、I/O、內(nèi)存等等,由于服務(wù)端資源是有限的,那么服務(wù)端能同時(shí)處理的請(qǐng)求也是有限的。高并發(fā)問(wèn)題的本質(zhì)就是:資源的有限性

    高并發(fā)帶來(lái)的問(wèn)題
    服務(wù)端的處理和響應(yīng)會(huì)越來(lái)越慢,甚至?xí)G棄部分請(qǐng)求不予處理,更嚴(yán)重的會(huì)導(dǎo)致服務(wù)端崩潰。

    高并發(fā)處理的基本思路
    1)從客戶端看

    • 盡量減少請(qǐng)求數(shù)量,比如:依靠客戶端自身的緩存或處理能力
    • 盡量減少對(duì)服務(wù)端資源的不必要耗費(fèi),比如:重復(fù)使用某些資源,如連接池客戶端處理的基本原則就是:能不訪問(wèn)服務(wù)端就不要訪問(wèn)

    2)從服務(wù)端看

    • 增加資源供給,比如:更大的網(wǎng)絡(luò)帶寬,使用更高配置的服務(wù)器,使用高性能的Web服務(wù)器,使用高性能的數(shù)據(jù)庫(kù)
    • 請(qǐng)求分流,比如:使用集群,分布式的系統(tǒng)架構(gòu)
    • 應(yīng)用優(yōu)化,比如:使用更高效的編程語(yǔ)言,優(yōu)化處理業(yè)務(wù)邏輯的算法,優(yōu)化訪問(wèn)數(shù)據(jù)庫(kù)的SQL

    基本原則:分而治之,并提高單個(gè)請(qǐng)求的處理速度

    高并發(fā)處理的基本手段

    1)客戶端發(fā)出請(qǐng)求層面,常見(jiàn)的手段有:

    • 盡量利用瀏覽器的緩存功能,減少訪問(wèn)服務(wù)端,比如:js、css、圖片等
    • 可以考慮使用壓縮傳輸?shù)墓δ?#xff0c;減少網(wǎng)絡(luò)流量,也會(huì)提高傳輸速度
    • 考慮使用異步請(qǐng)求,分批獲取數(shù)據(jù)

    2)前端接收客戶端請(qǐng)求層面,常見(jiàn)的手段有:

    • 動(dòng)靜分離,部分靜態(tài)資源可以直接從Nginx返回
    • 按請(qǐng)求的不同,分發(fā)到不同的后端進(jìn)行處理,比如:負(fù)載均衡、業(yè)務(wù)拆分訪問(wèn)等
    • 前面再加上一層來(lái)做多個(gè)Nginx的負(fù)載均衡,比如:LVS、F5等
    • 還可以在更前面使用CDN服務(wù)
    • 還可以對(duì)動(dòng)態(tài)內(nèi)容進(jìn)行緩存,盡量減少訪問(wèn)后端服務(wù)

    3)Web服務(wù)器層面,常見(jiàn)的手段有:

    • 使用最新的JVM,并進(jìn)行配置優(yōu)化
    • 對(duì)Web服務(wù)器進(jìn)行配置優(yōu)化,比如:調(diào)整內(nèi)存數(shù)量、線程數(shù)量等
    • 提供多個(gè)能提供相同服務(wù)的Web服務(wù)器,以實(shí)現(xiàn)負(fù)載均衡
    • 仔細(xì)規(guī)劃Web服務(wù)器上部署的應(yīng)用規(guī)模
    • 對(duì)Web服務(wù)器進(jìn)行集群

    4)Web應(yīng)用層面,常見(jiàn)的手段有:

    • 動(dòng)態(tài)內(nèi)容靜態(tài)化
    • Java開(kāi)發(fā)優(yōu)化
    • 優(yōu)化處理業(yè)務(wù)邏輯的算法
    • 合理高效的利用緩存
    • 優(yōu)化訪問(wèn)數(shù)據(jù)庫(kù)的Sql,可以考慮利用存儲(chǔ)過(guò)程等數(shù)據(jù)庫(kù)的能力
    • 合理使用多線程,加快業(yè)務(wù)處理
    • 部分業(yè)務(wù)可以考慮內(nèi)存數(shù)據(jù)庫(kù),或者是進(jìn)行純內(nèi)存處理
    • 盡量避免遠(yuǎn)程調(diào)用、大量I/O等耗時(shí)的操作
    • 合理規(guī)劃事務(wù)等較為耗資源的操作
    • 合理使用異步處理
    • 對(duì)部分業(yè)務(wù)考慮采用預(yù)處理或者預(yù)計(jì)算的方式,減少實(shí)時(shí)計(jì)算量
    • 內(nèi)部系統(tǒng)間的業(yè)務(wù)盡量直接調(diào)用、直接處理,減少WebService、工作流等

    5)數(shù)據(jù)庫(kù)層面,常見(jiàn)的手段有:

    • 合理選擇數(shù)據(jù)庫(kù)的引擎,比如Mysql的InnoDB與MyISAM引擎
    • 進(jìn)行配置優(yōu)化
    • 可以考慮使用存儲(chǔ)過(guò)程來(lái)處理復(fù)雜的數(shù)據(jù)邏輯
    • 數(shù)據(jù)庫(kù)集群,進(jìn)行讀寫分離
    • 合理設(shè)計(jì)數(shù)據(jù)庫(kù)的表結(jié)構(gòu)、索引等
    • 分庫(kù)、分表,降低單庫(kù)、單表的數(shù)據(jù)量

    數(shù)據(jù)庫(kù)

    索引

    比較好的面試題 https://www.cnblogs.com/williamjie/p/11187470.html

    什么是索引?(為什么需要使用索引)

    【簡(jiǎn)單】:
    索引其實(shí)是一種數(shù)據(jù)結(jié)構(gòu),能夠幫助我們快速的檢索數(shù)據(jù)庫(kù)中的數(shù)據(jù)

    【復(fù)雜】:
    MySQL官方對(duì)索引的定義為:索引(Index)是幫助 MySQL 高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。
    打個(gè)比方,如果合理的設(shè)計(jì)且使用索引的MySQL是一輛蘭博基尼的話,那么沒(méi)有設(shè)計(jì)和使用索引的MySQL就是一個(gè)人力三輪車。
    索引分單列索引和組合索引。單列索引,即一個(gè)索引只包含單個(gè)列,一個(gè)表可以有多個(gè)單列索引,但這不是組合索引。組合索引,即一個(gè)索引包含多個(gè)列。
    創(chuàng)建索引時(shí),你需要確保該索引是應(yīng)用在 SQL 查詢語(yǔ)句的條件(一般作為 WHERE 子句的條件)。
    實(shí)際上,索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄。
    上面都在說(shuō)使用索引的好處,但過(guò)多的使用索引將會(huì)造成濫用。因此索引也會(huì)有它的缺點(diǎn):雖然索引大大提高了查詢速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
    建立索引會(huì)占用磁盤空間的索引文件。

    索引具體采用的哪種數(shù)據(jù)結(jié)構(gòu)

    常見(jiàn)的MySQL主要有兩種結(jié)構(gòu):Hash索引和B+ Tree索引,我們使用的是InnoDB引擎,默認(rèn)的是B+樹(shù)

    既然你提到InnoDB使用的B+ 樹(shù)的索引模型,那么你知道為什么采用B+ 樹(shù)嗎?這和Hash索引比較起來(lái)有什么優(yōu)缺點(diǎn)嗎?

    因?yàn)镠ash索引底層是哈希表,哈希表是一種以key-value存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu),所以多個(gè)數(shù)據(jù)在存儲(chǔ)關(guān)系上是完全沒(méi)有任何順序關(guān)系的,所以,對(duì)于區(qū)間查詢是無(wú)法直接通過(guò)索引查詢的,就需要全表掃描。所以,哈希索引只適用于等值查詢的場(chǎng)景。而B(niǎo)+ 樹(shù)是一種多路平衡查詢樹(shù),所以他的節(jié)點(diǎn)是天然有序的(左子節(jié)點(diǎn)小于父節(jié)點(diǎn)、父節(jié)點(diǎn)小于右子節(jié)點(diǎn)),所以對(duì)于范圍查詢的時(shí)候不需要做全表掃描

    優(yōu)化

    SQL語(yǔ)句優(yōu)化

  • 不要把 select 子句寫成 select *
  • 謹(jǐn)慎使用模糊查詢
  • 對(duì) order by 排序的字段設(shè)置索引,可以大大加快數(shù)據(jù)庫(kù)執(zhí)行的速度
  • 少用 is null 和 is not null
  • 盡量少用 != 運(yùn)算符
  • 盡量少用 or 運(yùn)算符,因?yàn)檫壿嫽蜻\(yùn)算符也會(huì)讓數(shù)據(jù)庫(kù)跳過(guò)索引
  • 盡量少用 in 和 not in 運(yùn)算符,原因和 or 運(yùn)算符一樣,都屬于邏輯或關(guān)系
  • 避免條件語(yǔ)句中的數(shù)據(jù)類型轉(zhuǎn)換
  • 在表達(dá)式左側(cè)使用運(yùn)算符和函數(shù)都會(huì)讓索引失效
  • 分庫(kù)分表

    1)分庫(kù)分表,如何對(duì)數(shù)據(jù)庫(kù)如何進(jìn)行垂直拆分或水平拆分的,用什么中間件?
    綜上,現(xiàn)在其實(shí)建議考量的,就是 Sharding-jdbc 和 Mycat,這兩個(gè)都可以去考慮使用。
    Sharding-jdbc 這種 client 層方案的優(yōu)點(diǎn)在于不用部署,運(yùn)維成本低,不需要代理層的二次轉(zhuǎn)發(fā)請(qǐng)求,性能很高,但是如果遇到升級(jí)啥的需要各個(gè)系統(tǒng)都重新升級(jí)版本再發(fā)布,各個(gè)系統(tǒng)都需要耦合 Sharding-jdbc 的依賴;
    Mycat 這種 proxy 層方案的缺點(diǎn)在于需要部署,自己運(yùn)維一套中間件,運(yùn)維成本高,但是好處在于對(duì)于各個(gè)項(xiàng)目是透明的,如果遇到升級(jí)之類的都是自己中間件那里搞就行了。

    2)分庫(kù)分表之后,id 主鍵如何處理?、、
    ----snowflake 雪花算法 (id work)

    3)從未分庫(kù)分表動(dòng)態(tài)切換到分庫(kù)分表上?

    a、停機(jī)遷移,寫個(gè)公告凌晨升級(jí)(半夜) --> 寫個(gè)工具從0點(diǎn)開(kāi)始讀寫數(shù)據(jù),4點(diǎn)伸個(gè)懶腰下班,爽

    b、雙寫遷移方案

    讀寫分離

    前提:讀并發(fā)大
    就是寫一個(gè)主庫(kù),但是主庫(kù)掛多個(gè)從庫(kù),然后從多個(gè)從庫(kù)來(lái)讀,那不就可以支撐更高的讀并發(fā)壓力了嗎?
    ? 主庫(kù)將變更寫入 binlog 日志,然后從庫(kù)連接到主庫(kù)之后,從庫(kù)有一個(gè) IO 線程,將主庫(kù)的 binlog 日志拷貝到自己本地,寫入一個(gè) relay 中繼日志中。接著從庫(kù)中有一個(gè) SQL 線程會(huì)從中繼日志讀取 binlog,然后執(zhí)行 binlog 日志中的內(nèi)容,也就是在自己本地再次執(zhí)行一遍 SQL,這樣就可以保證自己跟主庫(kù)的數(shù)據(jù)是一樣的。

    Mysql和Oracle有什么區(qū)別?

    1.Oracle收費(fèi),Mysql免費(fèi)

    2.單引號(hào)的處理
    Mysql里可以用雙引號(hào)包起字符串,Oracle里只可以用單引號(hào)包起字符串。在插入和修改字符串前必須做單引號(hào)的替換:把所有出現(xiàn)的一個(gè)單引號(hào)替換成兩個(gè)單引號(hào)。

    3.自動(dòng)增長(zhǎng)的數(shù)據(jù)類型處理
    Mysql是一個(gè)自動(dòng)增長(zhǎng)的數(shù)據(jù)類型,插入數(shù)據(jù)的時(shí)候,不需要管理,它自己會(huì)自動(dòng)增長(zhǎng),Oracle不支持自動(dòng)增長(zhǎng)的數(shù)據(jù)類型,通過(guò)建立一個(gè)自動(dòng)增長(zhǎng)的序列號(hào)來(lái)完成自動(dòng)增長(zhǎng)。

    4.事物提交方式
    oracle默認(rèn)不自動(dòng)提交,需要用戶手動(dòng)提交。
    Mysql默認(rèn)是自動(dòng)提交。不支持事物。
    Mysql默認(rèn)自動(dòng)提交,也就是你提交一個(gè)query,他就直接執(zhí)行,我們可以通過(guò)
    set autocommit=0 禁止自動(dòng)提交
    set autocommit=1 開(kāi)啟自動(dòng)提交

    group by后面還可以加什么

    group by 對(duì)應(yīng)的列如果如果需要加條件,一般用having。

    MySQL

    MySQL的事務(wù)

    事務(wù)的基本要素(ACID):
    1、原子性(Atomicity):
    事務(wù)開(kāi)始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環(huán)節(jié)。事務(wù)執(zhí)行過(guò)程中出錯(cuò),會(huì)回滾到事務(wù)開(kāi)始前的狀態(tài),所有的操作就像沒(méi)有發(fā)生一樣。也就是說(shuō)事務(wù)是一個(gè)不可分割的整體,就像化學(xué)中學(xué)過(guò)的原子,是物質(zhì)構(gòu)成的基本單位
    2、一致性(Consistency):
    事務(wù)開(kāi)始前和結(jié)束后,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞 。比如A向B轉(zhuǎn)賬,不可能A扣了錢,B卻沒(méi)收到。
    3、隔離性(Isolation):
    同一時(shí)間,只允許一個(gè)事務(wù)請(qǐng)求同一數(shù)據(jù),不同的事務(wù)之間彼此沒(méi)有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過(guò)程結(jié)束前,B不能向這張卡轉(zhuǎn)賬。
    4、持久性(Durability):
    事務(wù)完成后,事務(wù)對(duì)數(shù)據(jù)庫(kù)的所有更新將被保存到數(shù)據(jù)庫(kù),不能回滾。

    事務(wù)的并發(fā)問(wèn)題:

    臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)
    不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過(guò)程中,對(duì)數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致
    幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫(kù)中所有學(xué)生的成績(jī)從具體分?jǐn)?shù)改為ABCDE等級(jí),但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒(méi)有改過(guò)來(lái),就好像發(fā)生了幻覺(jué)一樣,這就叫幻讀。
    小結(jié):
    不可重復(fù)讀的和幻讀很容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除。解決不可重復(fù)讀的問(wèn)題只需鎖住滿足條件的行,解決幻讀需要鎖表

    MySQL事務(wù)隔離級(jí)別:

    四種:未提交讀、已提交讀、可重復(fù)讀、可串行化,
    默認(rèn)是 可重復(fù)讀

    如何做 MySQL 的性能優(yōu)化?

  • 不要把 select 子句寫成 select *
  • 謹(jǐn)慎使用模糊查詢
  • 對(duì) order by 排序的字段設(shè)置索引,可以大大加快數(shù)據(jù)庫(kù)執(zhí)行的速度
  • 少用 is null 和 is not null
  • 盡量少用 != 運(yùn)算符
  • 盡量少用 or 運(yùn)算符,因?yàn)檫壿嫽蜻\(yùn)算符也會(huì)讓數(shù)據(jù)庫(kù)跳過(guò)索引
  • 盡量少用 in 和 not in 運(yùn)算符,原因和 or 運(yùn)算符一樣,都屬于邏輯或關(guān)系
  • 避免條件語(yǔ)句中的數(shù)據(jù)類型轉(zhuǎn)換
  • 在表達(dá)式左側(cè)使用運(yùn)算符和函數(shù)都會(huì)讓索引失效
  • 怎么確定有沒(méi)有用到索引

    使用方法,在select語(yǔ)句前加上explain就可以了:
    如:
    explain select surname,first_name from a,b where a.id=b.id
    細(xì)節(jié):https://www.cnblogs.com/the-fool/p/11113996.html

    Redis

    Redis是什么及特點(diǎn)

    Redis是一個(gè)內(nèi)存型緩存數(shù)據(jù)庫(kù)
    特點(diǎn):
    key/value型數(shù)據(jù)庫(kù)
    支持豐富的數(shù)據(jù)類型(String,List,Set,ZSet,Hash)
    支持持久化,內(nèi)存數(shù)據(jù),持久化到硬盤中
    是單進(jìn)程,單線程,所以是線程安全
    可實(shí)現(xiàn)分布式鎖

    Redis除了緩存還能做什么

    比如:用戶登錄session,網(wǎng)頁(yè)緩存,日志系統(tǒng),搜索引擎,消息隊(duì)列、持久化、發(fā)布訂閱系統(tǒng)、計(jì)時(shí)器、計(jì)數(shù)器(瀏覽量!)

    Redis 有哪些功能?

    數(shù)據(jù)緩存功能
    分布式鎖的功能
    支持?jǐn)?shù)據(jù)持久化
    支持事務(wù)
    支持消息隊(duì)列

    一個(gè)字符串類型的值能存儲(chǔ)最大容量是多少?

    512M

    最大能存多大?

    官方說(shuō)單例能處理key:2.5億個(gè)

    線程安全嗎?

    Redis是個(gè)單線程程序,所以它是線程安全的。

    redis 存儲(chǔ)結(jié)構(gòu)

    key-value

    redis的基本數(shù)據(jù)類型

    string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。”

    怎么理解Redis事務(wù)?

    事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化、按順序地執(zhí)行。事務(wù)在執(zhí)行的過(guò)程中,不會(huì)被其他客戶端發(fā)送來(lái)的命令請(qǐng)求所打斷。
    事務(wù)是一個(gè)原子操作:事務(wù)中的命令要么全部被執(zhí)行,要么全部都不執(zhí)行。

    什么是Redis持久化?Redis有哪幾種持久化方式?優(yōu)缺點(diǎn)是什么?

    持久化就是把內(nèi)存的數(shù)據(jù)寫到磁盤中去,防止服務(wù)宕機(jī)了內(nèi)存數(shù)據(jù)丟失。
    RDB(Redis Database):指定的時(shí)間間隔能對(duì)你的數(shù)據(jù)進(jìn)行快照存儲(chǔ)。
    AOF(Append Only File):每一個(gè)收到的寫命令都通過(guò)write函數(shù)追加到文件中。

    什么情況下要用到緩存,什么數(shù)據(jù)適合緩存,使用緩存需要注意什么問(wèn)題?

    熱點(diǎn)數(shù)據(jù),不變化的數(shù)據(jù)(如省市區(qū),分類),登錄用戶的token也可以用緩存,需要注意緩存和數(shù)據(jù)庫(kù)的一致性,緩存擊穿,緩存穿透,雪崩問(wèn)題

    什么是緩存擊穿?怎么解決?

    相較于緩存穿透,緩存擊穿的目的性更強(qiáng),一個(gè)存在的key,在緩存過(guò)期的一刻,同時(shí)有大量的請(qǐng)求,這些請(qǐng)求都會(huì)擊穿到DB,造成瞬時(shí)DB請(qǐng)求量大、壓力驟增。這就是緩存被擊穿,只是針對(duì)其中某個(gè)key的緩存不可用而導(dǎo)致?lián)舸?#xff0c;但是其他的key依然可以使用緩存響應(yīng)。
    比如熱搜排行上,一個(gè)熱點(diǎn)新聞被同時(shí)大量訪問(wèn)就可能導(dǎo)致緩存擊穿。

  • 設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期
  • 加互斥鎖(分布式鎖)
    在訪問(wèn)key之前,采用SETNX(set if not exists)來(lái)設(shè)置另一個(gè)短期key來(lái)鎖住當(dāng)前key的訪問(wèn),訪問(wèn)結(jié)束再刪除該短期key。保證同時(shí)刻只有一個(gè)線程訪問(wèn)。這樣對(duì)鎖的要求就十分高。
  • 什么是緩存穿透?怎么解決?

    緩存穿透:
    緩存穿透的概念很簡(jiǎn)單,用戶想要查詢一個(gè)數(shù)據(jù),發(fā)現(xiàn)redis內(nèi)存數(shù)據(jù)庫(kù)沒(méi)有,也就是緩存沒(méi)有命中,于是向持久層數(shù)據(jù)庫(kù)查詢。發(fā)現(xiàn)也沒(méi)有,于是本次查詢失敗。當(dāng)用戶很多的時(shí)候,緩存都沒(méi)有命中(秒殺!),于是都去請(qǐng)求了持久層數(shù)據(jù)庫(kù)。這會(huì)給持久層數(shù)據(jù)庫(kù)造成很大的壓力,這時(shí)候就相當(dāng)于出現(xiàn)了緩存穿透。洪水攻擊。數(shù)據(jù)庫(kù)也查不到就沒(méi)有緩存,就會(huì)一直與數(shù)據(jù)庫(kù)訪問(wèn)。

    解決方案:

  • 布隆過(guò)濾器
    對(duì)所有可能查詢的參數(shù)以Hash的形式存儲(chǔ),以便快速確定是否存在這個(gè)值,在控制層先進(jìn)行攔截校驗(yàn),校驗(yàn)不通過(guò)直接打回,減輕了存儲(chǔ)系統(tǒng)的壓力。
  • 緩存空對(duì)象
    一次請(qǐng)求若在緩存和數(shù)據(jù)庫(kù)中都沒(méi)找到,就在緩存中方一個(gè)空對(duì)象用于處理后續(xù)這個(gè)請(qǐng)求。
  • 什么是緩存雪崩?怎么解決?

    大量的key設(shè)置了相同的過(guò)期時(shí)間,導(dǎo)致在緩存在同一時(shí)刻全部失效,造成瞬時(shí)DB請(qǐng)求量大、壓力驟增,引起雪崩。

    解決方案:

  • redis高可用
    這個(gè)思想的含義是,既然redis有可能掛掉,那我多增設(shè)幾臺(tái)redis,這樣一臺(tái)掛掉之后其他的還可以繼續(xù)工作,其實(shí)就是搭建的集群
  • 限流降級(jí)
    這個(gè)解決方案的思想是,在緩存失效后,通過(guò)加鎖或者隊(duì)列來(lái)控制讀數(shù)據(jù)庫(kù)寫緩存的線程數(shù)量。比如對(duì)某個(gè)key只允許一個(gè)線程查詢數(shù)據(jù)和寫緩存,其他線程等待。
  • 數(shù)據(jù)預(yù)熱
    數(shù)據(jù)加熱的含義就是在正式部署之前,我先把可能的數(shù)據(jù)先預(yù)先訪問(wèn)一遍,這樣部分可能大量訪問(wèn)的數(shù)據(jù)就會(huì)加載到緩存中。在即將發(fā)生大并發(fā)訪問(wèn)前手動(dòng)觸發(fā)加載緩存不同的key,設(shè)置不同的過(guò)期時(shí)間,讓緩存失效的時(shí)間點(diǎn)盡量均勻。
  • 怎么保證緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性?

    合理設(shè)置緩存的過(guò)期時(shí)間。
    新增、更改、刪除數(shù)據(jù)庫(kù)操作時(shí)同步更新 Redis,可以使用事物機(jī)制來(lái)保證數(shù)據(jù)的一致性。

    Redis悲觀鎖和樂(lè)觀鎖

    悲觀鎖:
    執(zhí)行操作前假設(shè)當(dāng)前的操作肯定(或有很大幾率)會(huì)被打斷(悲觀)。基于這個(gè)假設(shè),我們?cè)谧霾僮髑熬蜁?huì)把相關(guān)資源鎖定,不允許自己執(zhí)行期間有其他操作干擾。
    Redis不支持悲觀鎖。Redis作為緩存服務(wù)器使用時(shí),以操作為主,很少寫操作,相應(yīng)的操作被打斷的幾率較少。不采用悲觀鎖是為了防止降低性能。

    樂(lè)觀鎖:
    執(zhí)行操作前假設(shè)當(dāng)前操作不會(huì)被打斷(樂(lè)觀)。基于這個(gè)假設(shè),我們?cè)谧霾僮髑安粫?huì)鎖定資源,萬(wàn)一發(fā)生了其他操作的干擾,那么本次操作將被放棄。

    Redis 怎么實(shí)現(xiàn)分布式鎖?

    Redis 分布式鎖其實(shí)就是在系統(tǒng)里面占一個(gè)“坑”,其他程序也要占“坑”的時(shí)候,占用成功了就可以繼續(xù)執(zhí)行,失敗了就只能放棄或稍后重試。
    占坑一般使用 setnx(set if not exists)指令,只允許被一個(gè)程序占有,使用完調(diào)用 del 釋放鎖。

    Redis 分布式鎖有什么缺陷?

    Redis 分布式鎖不能解決超時(shí)的問(wèn)題,分布式鎖有一個(gè)超時(shí)時(shí)間,程序的執(zhí)行如果超出了鎖的超時(shí)時(shí)間就會(huì)出現(xiàn)問(wèn)題。

    Redis 如何做內(nèi)存優(yōu)化?

    盡量使用 Redis 的散列表,把相關(guān)的信息放到散列表里面存儲(chǔ),而不是把每個(gè)字段單獨(dú)存儲(chǔ),這樣可以有效的減少內(nèi)存使用。比如將 Web 系統(tǒng)的用戶對(duì)象,應(yīng)該放到散列表里面再整體存儲(chǔ)到 Redis,而不是把用戶的姓名、年齡、密碼、郵箱等字段分別設(shè)置 key 進(jìn)行存儲(chǔ)。

    redis是單線程的,為什么那么快

    1)完全基于內(nèi)存,絕大部分請(qǐng)求是純粹的內(nèi)存操作,非常快速。數(shù)據(jù)存在內(nèi)存中,類似于HashMap,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)
    2)數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單,對(duì)數(shù)據(jù)操作也簡(jiǎn)單,Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進(jìn)行設(shè)計(jì)的
    3)采用單線程,避免了不必要的上下文切換和競(jìng)爭(zhēng)條件,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU,不用去考慮各種鎖的問(wèn)題,不存在加鎖釋放鎖操作,沒(méi)有因?yàn)榭赡艹霈F(xiàn)死鎖而導(dǎo)致的性能消耗
    4)使用多路I/O復(fù)用模型,非阻塞IO
    5)使用底層模型不同,它們之間底層實(shí)現(xiàn)方式以及與客戶端之間通信的應(yīng)用協(xié)議不一樣,Redis直接自己構(gòu)建了VM 機(jī)制 ,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請(qǐng)求

    Redis 一級(jí)緩存與二級(jí)緩存(不知道答案對(duì)不對(duì))

    緩存為了減輕數(shù)據(jù)庫(kù)訪問(wèn)量;
    一級(jí)比二級(jí)多了一級(jí)
    一級(jí)緩存請(qǐng)求內(nèi)存,沒(méi)有的話在請(qǐng)求數(shù)據(jù)庫(kù);
    二級(jí)緩存請(qǐng)求內(nèi)存,沒(méi)有在請(qǐng)求二級(jí)緩存區(qū),沒(méi)有在請(qǐng)求數(shù)據(jù)庫(kù);
    Hibernate 二級(jí)緩存需要添加配置文件
    redis 自帶二級(jí)緩存
    因?yàn)閿?shù)據(jù)庫(kù)去進(jìn)行IO操作(增刪更新)都需要像(唱片)的刻度一樣,動(dòng)刻度,非常慢,
    所以需要緩存減輕數(shù)據(jù)庫(kù)訪問(wèn)量達(dá)到什么減輕數(shù)據(jù)庫(kù)壓力等等作用;

    在看看別人的標(biāo)準(zhǔn)答案:
    hibernate一級(jí)緩存和二級(jí)緩存的區(qū)別: https://blog.csdn.net/defonds/article/details/2308972
    MyBatis緩存分為一級(jí)緩存和二級(jí)緩存:https://blog.csdn.net/u014756827/article/details/52754750

    Nginx

    比較好的文章(內(nèi)含教程視頻):https://blog.csdn.net/m0_49558851/article/details/107786372

    請(qǐng)解釋一下什么是Nginx?

    Nginx—Ngine X,是一款免費(fèi)的、自由的、開(kāi)源的、高性能HTTP服務(wù)器和反向代理服務(wù)器;也是一個(gè)IMAP、POP3、SMTP代理服務(wù)器;Nginx以其高性能、穩(wěn)定性、豐富的功能、簡(jiǎn)單的配置和低資源消耗而聞名。
    也就是說(shuō)Nginx本身就可以托管網(wǎng)站(類似于Tomcat一樣),進(jìn)行Http服務(wù)處理,也可以作為反向代理服務(wù)器 、負(fù)載均衡器和HTTP緩存。
    Nginx 解決了服務(wù)器的C10K(就是在一秒之內(nèi)連接客戶端的數(shù)目為10k即1萬(wàn))問(wèn)題。它的設(shè)計(jì)不像傳統(tǒng)的服務(wù)器那樣使用線程處理請(qǐng)求,而是一個(gè)更加高級(jí)的機(jī)制—事件驅(qū)動(dòng)機(jī)制,是一種異步事件驅(qū)動(dòng)結(jié)構(gòu)。

    請(qǐng)列舉Nginx和Apache 之間的不同點(diǎn)

    請(qǐng)解釋Nginx如何處理HTTP請(qǐng)求

    Nginx 是一個(gè)高性能的 Web 服務(wù)器,能夠同時(shí)處理大量的并發(fā)請(qǐng)求。它結(jié)合多進(jìn)程機(jī)制和異步機(jī)制 ,異步機(jī)制使用的是異步非阻塞方式 ,接下來(lái)就給大家介紹一下 Nginx 的多線程機(jī)制和異步非阻塞機(jī)制 。

    1、多進(jìn)程機(jī)制
    服務(wù)器每當(dāng)收到一個(gè)客戶端時(shí),就有 服務(wù)器主進(jìn)程 ( master process )生成一個(gè) 子進(jìn)程( worker process )出來(lái)和客戶端建立連接進(jìn)行交互,直到連接斷開(kāi),該子進(jìn)程就結(jié)束了。
    使用進(jìn)程的好處是各個(gè)進(jìn)程之間相互獨(dú)立,不需要加鎖,減少了使用鎖對(duì)性能造成影響,同時(shí)降低編程的復(fù)雜度,降低開(kāi)發(fā)成本。其次,采用獨(dú)立的進(jìn)程,可以讓進(jìn)程互相之間不會(huì)影響 ,如果一個(gè)進(jìn)程發(fā)生異常退出時(shí),其它進(jìn)程正常工作, master 進(jìn)程則很快啟動(dòng)新的 worker 進(jìn)程,確保服務(wù)不會(huì)中斷,從而將風(fēng)險(xiǎn)降到最低。
    缺點(diǎn)是操作系統(tǒng)生成一個(gè)子進(jìn)程需要進(jìn)行 內(nèi)存復(fù)制等操作,在資源和時(shí)間上會(huì)產(chǎn)生一定的開(kāi)銷。當(dāng)有大量請(qǐng)求時(shí),會(huì)導(dǎo)致系統(tǒng)性能下降 。

    2、異步非阻塞機(jī)制

    每個(gè)工作進(jìn)程 使用 異步非阻塞方式 ,可以處理 多個(gè)客戶端請(qǐng)求 。

    當(dāng)某個(gè) 工作進(jìn)程 接收到客戶端的請(qǐng)求以后,調(diào)用 IO 進(jìn)行處理,如果不能立即得到結(jié)果,就去 處理其他請(qǐng)求 (即為 非阻塞 );而 客戶端
    在此期間也 無(wú)需等待響應(yīng) ,可以去處理其他事情(即為 異步 )。

    當(dāng) IO 返回時(shí),就會(huì)通知此 工作進(jìn)程 ;該進(jìn)程得到通知,暫時(shí) 掛起 當(dāng)前處理的事務(wù)去 響應(yīng)客戶端請(qǐng)求 。

    請(qǐng)列舉Nginx的一些特性

    跨平臺(tái):可以在大多數(shù)Unix like 系統(tǒng)編譯運(yùn)行。而且也有Windows的移植版本。

    配置異常簡(jiǎn)單:非常的簡(jiǎn)單,易上手。

    非阻塞、高并發(fā)連接:數(shù)據(jù)復(fù)制時(shí),磁盤I/O的第一階段是非阻塞的。官方測(cè)試能支持5萬(wàn)并發(fā)連接,實(shí)際生產(chǎn)中能跑2~3萬(wàn)并發(fā)連接數(shù)(得益于Nginx采用了最新的epoll事件處理模型(消息隊(duì)列)。

    Nginx代理和后端Web服務(wù)器間無(wú)需長(zhǎng)連接;

    Nginx接收用戶請(qǐng)求是異步的,即先將用戶請(qǐng)求全部接收下來(lái),再一次性發(fā)送到后端Web服務(wù)器,極大減輕后端Web服務(wù)器的壓力。

    發(fā)送響應(yīng)報(bào)文時(shí),是邊接收來(lái)自后端Web服務(wù)器的數(shù)據(jù),邊發(fā)送給客戶端。

    網(wǎng)絡(luò)依賴性低,理論上只要能夠ping通就可以實(shí)施負(fù)載均衡,而且可以有效區(qū)分內(nèi)網(wǎng)、外網(wǎng)流量。

    支持內(nèi)置服務(wù)器檢測(cè)。Nginx能夠根據(jù)應(yīng)用服務(wù)器處理頁(yè)面返回的狀態(tài)碼、超時(shí)信息等檢測(cè)服務(wù)器是否出現(xiàn)故障,并及時(shí)返回錯(cuò)誤的請(qǐng)求重新提交到其它節(jié)點(diǎn)上。

    此外還有內(nèi)存消耗小、成本低廉(比F5硬件負(fù)載均衡器廉價(jià)太多)、節(jié)省帶寬、穩(wěn)定性高等特點(diǎn)。

    簡(jiǎn)述反向代理和正向代理

    正向代理:

    對(duì)于目標(biāo)服務(wù)器來(lái)講,感受不到真實(shí)的客戶端,與它通信的是代理客戶端,如kexueguge的軟件就是一個(gè)正向代理

    舉個(gè)正向代理的例子,我(客戶端)沒(méi)有綠碼出不了門,但是朋友(代理)有,我(客戶端)讓朋友(代理)去超市買瓶水,而對(duì)于超市(服務(wù)器)來(lái)講,他們感知不到我(客戶端)的存在,這就是正向代理。

    反向代理:

    我們將請(qǐng)求發(fā)送到服務(wù)器,然后服務(wù)器對(duì)我們的請(qǐng)求進(jìn)行轉(zhuǎn)發(fā),我們只需要和代理服務(wù)器進(jìn)行通信就好

    舉個(gè)反向代理例子,我(客戶端)讓朋友(代理)去給我買瓶水,并沒(méi)有說(shuō)去哪里買,反正朋友(代理)買回來(lái)了,對(duì)于我(客戶端)來(lái)講,我(客戶端)感知不到超市(服務(wù)器)的存在,這就是反向代理。

    使用“反向代理服務(wù)器”的優(yōu)點(diǎn)是什么?

    反向代理服務(wù)器可以隱藏源服務(wù)器的存在和特征。它充當(dāng)互聯(lián)網(wǎng)云和web服務(wù)器之間的中間層。這對(duì)于安全方面來(lái)說(shuō)是很好的,特別是當(dāng)您使用web托管服務(wù)時(shí)。

    nginx負(fù)載均衡的幾種常用方式

    1、輪詢(默認(rèn))
    2、weight 權(quán)重
    3、ip_hash指令

    解決nginx負(fù)載均衡的session共享問(wèn)題

    1、不使用session,換用cookie
    2、session存在數(shù)據(jù)庫(kù)(MySQL等)中
    3、session存在memcache或者redis中
    4、nginx中的ip_hash技術(shù)

    一些配置

    # upstream 節(jié)點(diǎn)群 upstream backend {server backend1.example.com weight=5;server backend2.example.com:8080;server unix:/tmp/backend3;server backup1.example.com:8080 backup;server backup2.example.com:8080 backup; }server { #轉(zhuǎn)發(fā)location / {# 節(jié)點(diǎn)地址proxy_pass http://backend;} }

    安全性

    攻擊

    注入攻擊

    如何避免 SQL 注入?

    使用預(yù)處理 PreparedStatement。
    使用正則表達(dá)式過(guò)濾掉字符中的特殊字符。

    什么是 XSS 攻擊,如何避免?

    XSS 攻擊:即跨站腳本攻擊,它是 Web 程序中常見(jiàn)的漏洞。原理是攻擊者往 Web 頁(yè)面里插入惡意的腳本代碼(css 代碼、Javascript 代碼等),當(dāng)用戶瀏覽該頁(yè)面時(shí),嵌入其中的腳本代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的目的,如盜取用戶 cookie、破壞頁(yè)面結(jié)構(gòu)、重定向到其他網(wǎng)站等。
    預(yù)防 XSS 的核心是必須對(duì)輸入的數(shù)據(jù)做過(guò)濾處理。

    設(shè)計(jì)模式

    說(shuō)一下你熟悉的設(shè)計(jì)模式?

    單例模式

    構(gòu)造參數(shù)私有化,外部不能調(diào)用,提供一個(gè)static的接口保證被創(chuàng)建一次

    簡(jiǎn)單的懶漢式

    public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

    比較完整的版本(雙重校驗(yàn)鎖+不允許指令重排):
    關(guān)鍵詞:
    鎖:synchronized
    指令重排:volatile

    public class Lazy {private Lazy(){System.out.println(Thread.currentThread().getName() + "已被創(chuàng)建!");}//所以我們要加volatile關(guān)鍵字告訴jvm它是易變的 不要優(yōu)化策略而進(jìn)行指令重排private static volatile Lazy instance;public static Lazy getInstance(){if(instance == null) {synchronized (Lazy.class) {if (instance == null) {instance = new Lazy();//這不是一個(gè)原子型操作/*** 1.分配內(nèi)存空間* 2.執(zhí)行構(gòu)造方法* 3.引用變量指向內(nèi)存空間* 虛擬機(jī)jvm執(zhí)行時(shí),可能會(huì)產(chǎn)生指令重排的現(xiàn)象 類似 132 的順序* 這將導(dǎo)致并發(fā)場(chǎng)景下的另一線程想要獲取實(shí)例時(shí),* 鎖之前的判空就會(huì)認(rèn)為不為空了* 則會(huì)返回 指向未知內(nèi)存的引用(因?yàn)閷?shí)際上未執(zhí)行構(gòu)造方法)*/}}}return instance;} }

    詳細(xì):https://www.runoob.com/design-pattern/singleton-pattern.html

    工廠模式

    工廠設(shè)計(jì)模式,顧名思義,就是用來(lái)生產(chǎn)對(duì)象的,在java中,萬(wàn)物皆對(duì)象,這些對(duì)象都需要?jiǎng)?chuàng)建,如果創(chuàng)建的時(shí)候直接new該對(duì)象,就會(huì)對(duì)該對(duì)象耦合嚴(yán)重,假如我們要更換對(duì)象,所有new對(duì)象的地方都需要修改一遍,這顯然違背了軟件設(shè)計(jì)的開(kāi)閉原則,如果我們使用工廠來(lái)生產(chǎn)對(duì)象,我們就只和工廠打交道就可以了,徹底和對(duì)象解耦,如果要更換對(duì)象,直接在工廠里更換該對(duì)象即可,達(dá)到了與對(duì)象解耦的目的;所以說(shuō),工廠模式最大的優(yōu)點(diǎn)就是:解耦

    觀察者模式

    定義了對(duì)象之間的一對(duì)多的依賴,這樣一來(lái),當(dāng)一個(gè)對(duì)象改變時(shí),它的所有的依賴者都會(huì)收到通知并自動(dòng)更新。

    外觀模式

    提供一個(gè)統(tǒng)一的接口,用來(lái)訪問(wèn)子系統(tǒng)中的一群接口,外觀定義了一個(gè)高層的接口,讓子系統(tǒng)更容易使用。

    模版方法模式

    定義了一個(gè)算法的骨架,而將一些步驟延遲到子類中,模版方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法的步驟。
    狀態(tài)模式:允許對(duì)象在內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)好像修改了它的類。

    tomcat

    默認(rèn)線程數(shù)

    150

    Shiro

    談?wù)凷hiro的工作流程

    別人的答案:

    首先shiro工作流程中又三個(gè)重要的組件,分別是Subject,SecurityManager,以及Realm。
    先來(lái)介紹Subject,即為主體也就相當(dāng)于目前操作系統(tǒng)的用戶直觀來(lái)說(shuō)就相當(dāng)于目前登錄的用戶。這里Subject主要是用來(lái)檢測(cè)用戶的登錄,登錄完之后就主要將工作交給SecurityManager來(lái)完成
    其次就是SecurityManager主要來(lái)檢測(cè)目前的用戶Subject的一系列的安全操作,比如說(shuō)當(dāng)前用戶所具備的權(quán)限,以及該用戶的角色是哪一層級(jí)的,在用戶執(zhí)行一系列操作的時(shí)候進(jìn)行授權(quán),避免越權(quán)的操作。
    之后就是Realm,他主要就是負(fù)責(zé)與數(shù)據(jù)庫(kù)交互,就比如說(shuō)SecurityManager來(lái)檢測(cè)用戶的權(quán)限是,就需要Realm從數(shù)據(jù)庫(kù)中取出該用戶的權(quán)限以及角色信息,之后才能方便SecurityManager來(lái)進(jìn)行授權(quán)的操作。

    我自己練習(xí)的項(xiàng)目是這樣的:

    啟動(dòng)項(xiàng)目的時(shí)候,首先會(huì) 配置SecurityManager的生命周期處理器,然后注冊(cè)自己寫的授權(quán)和認(rèn)證,配置shiro攔截器,并開(kāi)啟注解功能
    登錄的時(shí)候,先判斷該用戶是否生成過(guò)token,來(lái)進(jìn)行保存或者更新token。
    發(fā)送請(qǐng)求的時(shí)候,首先會(huì)攔截除option外所有的請(qǐng)求,進(jìn)行token的非空驗(yàn)證,如果token是空的,則返回錯(cuò)誤信息,如果不是空的,則驗(yàn)證token的有效性,如果無(wú)效,則返回錯(cuò)誤信息,有效的話進(jìn)行權(quán)限驗(yàn)證。先給用戶添加角色和權(quán)限(授權(quán))再進(jìn)行驗(yàn)證,無(wú)權(quán)限返回對(duì)應(yīng)異常,有權(quán)限進(jìn)入對(duì)應(yīng)接口

    權(quán)限的注解

    @RequiresPermissions //例子: @RequiresPermissions({"save"})

    Linux

    拷文件

    跳節(jié)點(diǎn)

    前端

    前端跨域怎么實(shí)現(xiàn)

    1.通過(guò)jsonp跨域
    2.跨域資源共享(CORS)
    3.nodejs中間件代理跨域
    4.nginx反向代理中設(shè)置proxy_cookie_domain

    vue2生命周期

    實(shí)例創(chuàng)建前后

    dom元素掛載前后

    組件數(shù)據(jù)更新前后

    組件卸載前后

    vue3生命周期

    setup函數(shù)

    頁(yè)面掛載前后

    數(shù)據(jù)更新前后

    卸載前后

    頁(yè)面報(bào)錯(cuò)函數(shù)

    新增兩個(gè) 廢棄兩個(gè)

    總結(jié)

    以上是生活随笔為你收集整理的2023 亲自经历面试的初中级java面试题(持续更新)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 成人一级片视频 | 黄色在线播放 | 免费看黄色av | 丝袜老师办公室里做好紧好爽 | 日韩中文字幕亚洲精品欧美 | 在线欧美日韩 | 黑人vs日本人ⅹxxxhd | 最新中文av | 九一网站在线观看 | 日本一级片在线播放 | 国产精品亚洲欧美在线播放 | 激情亚洲视频 | 国产精品福利一区 | 国产一级片麻豆 | 日韩一区二区三区久久 | 亚洲欧美国产精品 | 国产免费一区二区三区四区五区 | www.sesehu.com| 91玉足脚交嫩脚丫在线播放 | 国产一区二区黄色 | 国产精品亚洲五月天丁香 | 成人免费观看a | 涩av| 国产二级片 | 国产综合一区二区 | 午夜av网| 欧美骚视频 | 中文字幕国内自拍 | 久久这里只精品 | 一本色道久久亚洲综合精品蜜桃 | 美女伊人网| 2021狠狠干| 五月天色婷婷综合 | 欧美激情图区 | 日本高清在线观看 | 欧美综合在线观看 | 精品一区二区不卡 | 91超薄肉色丝袜交足高跟凉鞋 | 春草| 九九色播| 日本www黄 | 国产一区二区三区播放 | 一级裸体视频 | 午夜伦理在线观看 | 日韩成人片 | 国产高清视频免费 | 美女视频黄色 | 免费看一级 | 一区二区免费视频 | 精品爆乳一区二区三区 | 潮喷失禁大喷水无码 | 国产午夜福利视频在线观看 | 国产资源久久 | 一个色综合网 | 天天操天天插天天干 | av久久久| 青青草国产 | 男人舔女人下部高潮全视频 | av免费大片| 国产69精品麻豆 | 玖草影院| 久久综合久色欧美综合狠狠 | 国产精品一区在线播放 | 国产日本视频 | 色婷婷综合久久久久中文字幕 | 看了让人下面流水的视频 | 人成免费 | 亚洲欧美日韩国产一区 | 不卡av免费观看 | 美女a视频 | 搡国产老太xxx网站 高h喷汁呻吟3p | 天天干狠狠插 | 国产又粗又大又黄 | 久久精品国产亚洲av成人 | 理论视频在线观看 | 国产一区2| 中文字幕国产一区二区 | 99热99这里只有精品 | 日韩av中文在线观看 | 色综合久久久无码中文字幕波多 | 亚洲欧美日韩在线一区二区 | 欧美性视频在线 | 国产精品自产拍高潮在线观看 | 99久久99久久精品国产片 | 三区在线 | 精品国产午夜 | 青青草原国产在线 | 日韩精品你懂的 | 精品国产成人亚洲午夜福利 | 精品久久九九 | 看污片网站 | 在线观看的黄色网址 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | 大尺度电影在线 | 伊人久久一区二区三区 | 欧美另类videossexo高潮 | 四虎com| 亚洲精品9999 | 国产精品一二区 |