網(wǎng)站建設(shè)銷售培訓(xùn)語域名查詢ip138
大廠面試題分享第二期
- 如果執(zhí)行了一條命令,"select count(*)from…",使用哪個(gè)引擎更快,為什么?
- 垃圾回收器 CMS 和 G1的區(qū)別
- 介紹一下CMS和G1
- CMS(并發(fā))垃圾收集器
- G1垃圾回收器
- HTTPS和HTTP的區(qū)別主要如下:
- HTTPS 解決了 HTTP 的哪些問題?
- 主要介紹一下混合加密方式
- 非對(duì)稱加密算法
- TCP和UDP區(qū)別是什么?
- Leetcode25:K個(gè)一組翻轉(zhuǎn)鏈表
如果執(zhí)行了一條命令,“select count(*)from…”,使用哪個(gè)引擎更快,為什么?
EXPLAIN SELECT COUNT(*)FROM user;
EXPLAIN SELECT COUNT(列名) FROMuser;
EXPLAIN SELECT COUNT(1)FROM user;
執(zhí)行效果上:
- count(*)包括了所有的列,在統(tǒng)計(jì)時(shí) 不會(huì)忽略列值為null的數(shù)據(jù)。
- count(1)用1表示代碼行,在統(tǒng)計(jì)時(shí),不會(huì)忽略列值為null的數(shù)據(jù)。
- count(列名)在統(tǒng)計(jì)時(shí),會(huì)忽略列值為空的數(shù)據(jù),就是說某個(gè)字段的值為null時(shí)不統(tǒng)計(jì)。
執(zhí)行效率上:
- InnoDB引擎:count(字段)<count(1)=count(*)
- InnoDB通過遍歷最小的可用二級(jí)索引來處理select count*)語句,如果二級(jí)索引不存在,則通過掃描(主鍵索引)聚集索引來處理。
- InnoDB已同樣的方式處理count(1)和count(*)·
InnoDB中索引分為聚簇索引(主鍵索引)和非聚簇索引(非主鍵索引),聚簇索引的葉子節(jié)點(diǎn)中保存的是整行記錄,而非聚簇索引的葉子節(jié)點(diǎn)中保存的是該行記錄的主鍵的值。所以,相比之下,非聚簇索引要比聚簇索引小很多,所以MySQL會(huì)優(yōu)先選擇最小的非聚簇索引來掃表。所以,當(dāng)我們建表的時(shí)候,除了主鍵索引以外,創(chuàng)建一個(gè)非主鍵索引還是有必要的。
- MyISAM引擎:count(字段)<count(1)<= count(*)。
- MyISAM存儲(chǔ)了數(shù)據(jù)的準(zhǔn)確行數(shù),使用 count(*)會(huì)直接讀取該行數(shù),只有當(dāng)?shù)谝涣卸x為NOT NULL時(shí),count(1),才會(huì)執(zhí)行該操作,所以優(yōu)先選擇count(*)
count(列名)會(huì)遍歷整個(gè)表,但不同的是,它會(huì)先獲取列,然后判斷是否為空,然后累加,因此count(列名)性能不如前兩者。
垃圾回收器 CMS 和 G1的區(qū)別
區(qū)別一:使用的范圍不一樣:
- CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用
- G1收集器收集范圍是老年代和新生代。不需要結(jié)合其他收集器使用
區(qū)別二:STW的時(shí)間:
- CMS收集器以最小的停頓時(shí)間為目標(biāo)的收集器。
- G1收集器可預(yù)測(cè)垃圾回收區(qū) 的停頓時(shí)間(建立可預(yù)測(cè)的停頓時(shí)間模型)
區(qū)別三: 垃圾碎片
- CMS收集器是使用“標(biāo)記-清除”算法進(jìn)行的垃圾回收,容易產(chǎn)生內(nèi)存碎片·
- G1收集器使用的是“標(biāo)記-整理”算法,進(jìn)行了空間整合,沒有內(nèi)存空間碎片。
介紹一下CMS和G1
CMS(并發(fā))垃圾收集器
CMS(Concurrent-Mark-Sweep),是一款并發(fā)的、使用標(biāo)記-清除算法的垃圾回收器,該回收器是針對(duì)老年垃圾回收的。
-
CMS 收集器的關(guān)注點(diǎn)是盡可能縮短垃圾收集時(shí)用戶線程的停頓時(shí)間。停頓時(shí)間越短(低延遲) 就越適合與用戶交互的程序,良好的響應(yīng)速度能提升用戶體驗(yàn)
-
CMS 的垃圾收集算法采用 標(biāo)記-清除算法,并且也會(huì) “Stop-the-world”
-
初始標(biāo)記(Initial-Mark) 階段: 在這個(gè)階段中,程序中所有的工作線程都將會(huì)因?yàn)?“Stop-the-World” 機(jī)制而出現(xiàn)短暫的暫停,這個(gè)階段的主要任務(wù)僅僅只是標(biāo)記出 GC Roots 能直接關(guān)聯(lián)到的對(duì)象。
-
并發(fā)標(biāo)記(Concurrent-Mark) 階段: 從 GC Roots 的直接關(guān)聯(lián)對(duì)象開始遍歷整個(gè)對(duì)象圖的過程,這個(gè)過程耗時(shí)較長(zhǎng)但是不需要停頓用戶線程,可以與垃圾收集線程一起并發(fā)運(yùn)行
-
重新標(biāo)記(Remark) 階段: 由于在并發(fā)標(biāo)記階段中,程序的工作線程會(huì)和垃圾收集線程同時(shí)運(yùn)行或者交叉運(yùn)行,因此為了修正并發(fā)標(biāo)記期間,因用戶線程繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,仍然需要暫停所有工作線程
-
并發(fā)清除(Concurrent-Sweep) 階段: 此階段清理刪除掉標(biāo)記階段判斷已經(jīng)死亡的對(duì)象,釋放內(nèi)存空間。由于不需要移動(dòng)存活對(duì)象,所以這個(gè)階段也可以與用戶線程同時(shí)并發(fā)的
CMS垃圾收集器雖然減少了暫停應(yīng)用程序的運(yùn)行時(shí)間,但是它還是存在著內(nèi)存碎片問題,于是為了去除內(nèi)存碎片問題,同時(shí)有保留CMS垃圾收集器低暫停時(shí)間的優(yōu)點(diǎn),
G1垃圾回收器
G1垃圾回收器包括以下步驟:
- 初始標(biāo)記(Initial Mark):這一步主要標(biāo)記GC Roots引用的對(duì)象為存活。GCRoots是垃圾回收的起始點(diǎn),通常是活躍的對(duì)象。
- 并發(fā)標(biāo)記(Concurrent Mark):在這一階段,垃圾回收器會(huì)并發(fā)地遍歷堆中的對(duì)象圖,將初始標(biāo)記階段標(biāo)記為存活的對(duì)象引用的對(duì)象也標(biāo)記為存活。
- 最終標(biāo)記(Final Mark or Remark):此步驟會(huì)再次檢查并標(biāo)記在并發(fā)標(biāo)記階段可能被漏標(biāo)的對(duì)象,確保所有存活的對(duì)象都被正確地標(biāo)記。同時(shí),任何不再關(guān)聯(lián)的對(duì)象也會(huì)被標(biāo)記。
- 并發(fā)清理(Cleanup):這一步驟將存活的對(duì)象復(fù)制到其他Region,確保沒有內(nèi)存碎片的產(chǎn)生。G1垃圾回收器通過這種方式優(yōu)化內(nèi)存使用,并提高后續(xù)的垃圾回收效率。
G1垃圾回收器對(duì)老年代的清理策略是選擇存活度最低的區(qū)域進(jìn)行回收,這樣可以高效地回收內(nèi)存,這也是G1(Garbage first)名稱的由來。在清理階段,G1使用復(fù)制算法,確保內(nèi)存碎片的最小化。
HTTPS和HTTP的區(qū)別主要如下:
由于HTTP協(xié)議傳輸?shù)臄?shù)據(jù)是明文格式的,因此發(fā)送隱私信息時(shí)存在著安全風(fēng)險(xiǎn)。為確保數(shù)據(jù)傳輸安全性,網(wǎng)景公司推出了SSL(Secure Sockets Layer)協(xié)議,并在其基礎(chǔ)上創(chuàng)造出了HTTPS通信方式。簡(jiǎn)而言之,HTTPS是一種安全、支持加密傳輸和身份認(rèn)證功能的網(wǎng)絡(luò)通信方式,它是在SSL與HTTP結(jié)合后誕生的。
- http是超文本傳輸協(xié)議,信息是明文傳輸,存在安全風(fēng)險(xiǎn)問題,https則是在TCP和HTTP層之間加入了SSL/TLS安全協(xié)議,使得報(bào)文能夠加密傳輸
- HTTP鏈接建立相對(duì)簡(jiǎn)單,TCP三次握手之后便可進(jìn)行HTTP的報(bào)文傳輸,而HTTPS在TCP三次握手之后,還需要進(jìn)行SSL/TLS的握手過程,才可進(jìn)行加密報(bào)文傳輸
- 端口不一樣 HTTP默認(rèn)端口號(hào)80 HTTPS默認(rèn)端口到是443
- https協(xié)議需要向CA(證書權(quán)威機(jī)構(gòu)申請(qǐng)數(shù)字證書),來保證服務(wù)器的身份是可信的
HTTPS 解決了 HTTP 的哪些問題?
HTTP 由于是明文傳輸,所以安全上存在以下三個(gè)風(fēng)險(xiǎn):
- 竊聽風(fēng)險(xiǎn),比如通信鏈路上可以獲取通信內(nèi)容,用戶號(hào)容易沒
- 篡改風(fēng)險(xiǎn),比如強(qiáng)制植入垃圾廣告,視覺污染,用戶眼容易瞎。
- 冒充風(fēng)險(xiǎn),比如冒充淘寶網(wǎng)站,用戶錢容易沒,
HTTPS 是如何解決上面的三個(gè)風(fēng)險(xiǎn)的?
- 混合加密的方式實(shí)現(xiàn)信息的機(jī)密性,解決了竊聽的風(fēng)險(xiǎn)。
- 摘要算法(哈希算法)的方式來實(shí)現(xiàn)完整性,它能夠?yàn)閿?shù)據(jù)生成獨(dú)一無二的「指紋」,指紋用于校驗(yàn)數(shù)據(jù)的完整性 解決了算改的風(fēng)險(xiǎn)。
- 將服務(wù)器公鑰放入到數(shù)字證書中,解決了冒充的風(fēng)險(xiǎn)。
主要介紹一下混合加密方式
HTTPS 采用的是對(duì)稱加密和非對(duì)稱加密結(jié)合的「混合加密」方式:
在通信建立前采用非對(duì)稱加密的方式交換「會(huì)話秘鑰」,后續(xù)就不再使用非對(duì)稱加密。
在通信過程中全部使用對(duì)稱加密的「會(huì)話秘鑰」的方式加密明文數(shù)據(jù)。.采用「混合加密」的方式的原因:
- 對(duì)稱加密只使用一個(gè)密鑰,運(yùn)算速度快,密鑰必須保密,無法做到安全的密鑰交換。
- 非對(duì)稱加密使用兩個(gè)密鑰:公鑰和私鑰,公鑰可以任意分發(fā)而私鑰保密,解決了密鑰交換問題但速度慢
通過混合加密的方式可以保證信息的機(jī)密性,解決了竊聽的風(fēng)險(xiǎn)。
非對(duì)稱加密算法
非對(duì)稱加密算法中共有兩個(gè)密鑰:
- 一個(gè)是公鑰,這個(gè)是可以公開給所有人的;
- 一個(gè)是私鑰,這個(gè)必須由本人管理,不可泄露,
這兩個(gè)密鑰可以雙向加解密的,比如可以用公鑰加密內(nèi)容,然后用私鑰解密,也可以用私鑰加密內(nèi)容,公鑰解密內(nèi)容。流程的不同,意味著目的也不相同:
- 公鑰加密,私鑰解密,目的是為了保證內(nèi)容的傳輸安全,因?yàn)楸还€加密的內(nèi)容,其他人是無法解密的,只有持有私鑰的人,才能解密出實(shí)際的內(nèi)容【客戶端向服務(wù)器發(fā)送消息,但可能存在中間人偽造了一份公鑰私鑰】
- 私鑰簽名,公鑰驗(yàn)簽,目的是為了保證消息不回被冒充,因?yàn)樗借€不可泄露的,如果公鑰能正常解密出私鑰加密的內(nèi)容,就能證明這個(gè)消息是來源于持有私鑰身份的人發(fā)送的?!?font color="red">CA證書機(jī)構(gòu),確??蛻舳四玫降氖欠?wù)器的公鑰,而不是中間人的公鑰】
數(shù)字證書認(rèn)證機(jī)構(gòu)工作流程
在計(jì)算機(jī)里,這個(gè)權(quán)威的機(jī)構(gòu)就是 CA(數(shù)字證書認(rèn)證機(jī)構(gòu)),將服務(wù)器公鑰放在數(shù)字證書(由數(shù)字證書認(rèn)證機(jī)構(gòu)頒發(fā))中,只要證書是可信的,公鑰就是可信的。數(shù)字證書的工作流程如下:
TCP和UDP區(qū)別是什么?
- 連接:TCP 是面向連接的傳輸層協(xié)議,傳輸數(shù)據(jù)前先要建立連接;UDP 是不需要連接,即刻傳輸數(shù).據(jù)。
- 服務(wù)對(duì)象:TCP是一對(duì)一的兩點(diǎn)服務(wù),即一條連接只有兩個(gè)端點(diǎn)。UDP 支持一對(duì)一、一對(duì)多、多對(duì)多的交互通信
- 可靠性:TCP是可靠交付數(shù)據(jù)的,數(shù)據(jù)可以無差錯(cuò)、不丟失、不重復(fù)、按序到達(dá)。UDP 是盡最大努力交付,不保證可靠交付數(shù)據(jù)。但是我們可以基于 UDP傳輸協(xié)議實(shí)現(xiàn)一個(gè)可靠的傳輸協(xié)議,比如 QUIC協(xié)議
- 擁塞控制、流量控制:TCP 有擁塞控制和流量控制機(jī)制,保證數(shù)據(jù)傳輸?shù)陌踩?。UDP則沒有,即使網(wǎng)絡(luò)非常擁堵了,也不會(huì)影響 UDP 的發(fā)送速率。
- 首部開銷:TCP首部長(zhǎng)度較長(zhǎng),會(huì)有一定的開銷,首部在沒有使用「選項(xiàng)」字段時(shí)是 20 個(gè)字節(jié),如果使用了「選項(xiàng)!字段則會(huì)變長(zhǎng)的。UDP首部只有8個(gè)字節(jié),并且是固定不變的,開銷較小。
- 傳輸方式:TCP是流式傳輸,沒有邊界,但保證順序和可靠。UDP報(bào)文傳輸,是一個(gè)包一個(gè)包的發(fā)送,是有邊界的,但可能會(huì)丟包和亂序。
Leetcode25:K個(gè)一組翻轉(zhuǎn)鏈表
- 鏈表分區(qū)為已翻轉(zhuǎn)部分+待翻轉(zhuǎn)部分+未翻轉(zhuǎn)部分
- 每次翻轉(zhuǎn)前,要確定翻轉(zhuǎn)鏈表的范圍,這個(gè)必須通過 k 此循環(huán)來確定
- 需記錄翻轉(zhuǎn)鏈表前驅(qū)和后繼,方便翻轉(zhuǎn)完成后把已翻轉(zhuǎn)部分和未翻轉(zhuǎn)部分連接起來
- 初始需要兩個(gè)變量 pre 和 end,pre代表待翻轉(zhuǎn)鏈表的前驅(qū),end 代表待翻轉(zhuǎn)鏈表的末尾
- 經(jīng)過k此循環(huán),end 到達(dá)末尾,記錄待翻轉(zhuǎn)鏈表的后繼 next = end.next
- 翻轉(zhuǎn)鏈表,然后將三部分鏈表連接起來,然后重置 pre 和 end 指針,然后進(jìn)入下一次循環(huán)
- 特殊情況,當(dāng)翻轉(zhuǎn)部分長(zhǎng)度不足 k 時(shí),在定位end 完成后,end==null,已經(jīng)到達(dá)末尾,說明題目已完成,直接返回即可
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode dummy = new ListNode(0);dummy.next = head;//每次開始前 pre start end都在翻轉(zhuǎn)鏈表的前驅(qū)節(jié)點(diǎn)ListNode pre = dummy;ListNode start = dummy;ListNode end = dummy;while(end.next!=null){for(int i=0;i<k&&end!=null;i++) end = end.next;if(end == null) break;start = pre.next;ListNode next = end.next;end.next = null;pre.next = reverse(start);//start此時(shí)在翻轉(zhuǎn)鏈表的前驅(qū) pre和end不在start.next = next;pre = start;end = pre;}return dummy.next;}public ListNode reverse(ListNode start){ListNode dummy = new ListNode(-1);ListNode cur = dummy;while(start!=null){ListNode next = start.next;start.next = cur.next;cur.next = start; start = next;}return dummy.next;}
}