自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

華為進(jìn)二面了,開沖了!

開發(fā) 前端
在Spring中對(duì)于事務(wù)的傳播行為定義了七種類型分別是:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

大家好,我是小林。

華為面試流程總共是 3 輪技術(shù)面+1 輪 hr 面,在約面之前,還得先進(jìn)行機(jī)試,基本都是算法題,達(dá)到150分就算機(jī)試通過,然后就進(jìn)行后面的技術(shù)面試。

圖片圖片

華為的面試難度相比互聯(lián)網(wǎng)公司會(huì)簡(jiǎn)單一點(diǎn),不會(huì)問太深的技術(shù)原理,問的題目也不會(huì)很多,大概都是 10 -20 個(gè)問題,相比互聯(lián)網(wǎng)大廠一場(chǎng)面試動(dòng)不動(dòng)就問 30 個(gè)問題,確實(shí)壓力相對(duì)小一點(diǎn)。

今天給大家分享一位同學(xué)華為二面的面經(jīng),面試者的技術(shù)棧是Java,主要問了Spring、Java集合、并發(fā)、網(wǎng)絡(luò)、mysql 方面的問題,并且還有手撕算法的過程。

八股

Spring中的事務(wù)的隔離級(jí)別有哪些?

Sping 中的事務(wù)隔離級(jí)別有 5 種,它們分別是:

  1. DEFAULT:Spring 中默認(rèn)的事務(wù)隔離級(jí)別,以連接的數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別為準(zhǔn);
  2. READ_UNCOMMITTED:讀未提交,也叫未提交讀,該隔離級(jí)別的事務(wù)可以看到其他事務(wù)中未提交的數(shù)據(jù)。該隔離級(jí)別因?yàn)榭梢宰x取到其他事務(wù)中未提交的數(shù)據(jù),而未提交的數(shù)據(jù)可能會(huì)發(fā)生回滾,因此我們把該級(jí)別讀取到的數(shù)據(jù)稱之為臟數(shù)據(jù),把這個(gè)問題稱之為臟讀;
  3. READ_COMMITTED:讀已提交,也叫提交讀,該隔離級(jí)別的事務(wù)能讀取到已經(jīng)提交事務(wù)的數(shù)據(jù),因此它不會(huì)有臟讀問題。但由于在事務(wù)的執(zhí)行中可以讀取到其他事務(wù)提交的結(jié)果,所以在不同時(shí)間的相同 SQL 查詢中,可能會(huì)得到不同的結(jié)果,這種現(xiàn)象叫做不可重復(fù)讀;
  4. REPEATABLE_READ:可重復(fù)讀,它能確保同一事務(wù)多次查詢的結(jié)果一致。但也會(huì)有新的問題,比如此級(jí)別的事務(wù)正在執(zhí)行時(shí),另一個(gè)事務(wù)成功的插入了某條數(shù)據(jù),但因?yàn)樗看尾樵兊慕Y(jié)果都是一樣的,所以會(huì)導(dǎo)致查詢不到這條數(shù)據(jù),自己重復(fù)插入時(shí)又失敗(因?yàn)槲ㄒ患s束的原因)。明明在事務(wù)中查詢不到這條信息,但自己就是插入不進(jìn)去,這就叫幻讀 (Phantom Read);
  5. SERIALIZABLE:串行化,最高的事務(wù)隔離級(jí)別,它會(huì)強(qiáng)制事務(wù)排序,使之不會(huì)發(fā)生沖突,從而解決了臟讀、不可重復(fù)讀和幻讀問題,但因?yàn)閳?zhí)行效率低,所以真正使用的場(chǎng)景并不多。

所以,相比于 MySQL 的事務(wù)隔離級(jí)別,Spring 中多了一種 DEFAULT 的事務(wù)隔離級(jí)別。針對(duì)不同的隔離級(jí)別,并發(fā)事務(wù)時(shí)可能發(fā)生的現(xiàn)象也會(huì)不同。圖片也就是說:

  • 在「讀未提交」隔離級(jí)別下,可能發(fā)生臟讀、不可重復(fù)讀和幻讀現(xiàn)象;
  • 在「讀提交」隔離級(jí)別下,可能發(fā)生不可重復(fù)讀和幻讀現(xiàn)象,但是不可能發(fā)生臟讀現(xiàn)象;
  • 在「可重復(fù)讀」隔離級(jí)別下,可能發(fā)生幻讀現(xiàn)象,但是不可能臟讀和不可重復(fù)讀現(xiàn)象;
  • 在「串行化」隔離級(jí)別下,臟讀、不可重復(fù)讀和幻讀現(xiàn)象都不可能會(huì)發(fā)生。

Spring事務(wù)的傳播行為有哪些?

在Spring中對(duì)于事務(wù)的傳播行為定義了七種類型分別是:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

支持當(dāng)前事務(wù)的:REQUIRED、SUPPORTS、MANDATORY;不支持當(dāng)前事務(wù)的:REQUIRES_NEW、NOT_SUPPORTED、NEVER,以及嵌套事務(wù) NESTED,其中 REQUIRED 是默認(rèn)的事務(wù)傳播級(jí)別。

事務(wù)傳播行為類型

說明

PROPAGATION_REQUIRED

如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。這是最常見的選擇。

PROPAGATION_SUPPORTS

支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。

PROPAGATION_MANDATORY

使用當(dāng)前的事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。

PROPAGATION_REQUIRES_NEW

新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。

PROPAGATION_NOT_SUPPORTED

以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。

PROPAGATION_NEVER

以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。

PROPAGATION_NESTED

如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類似的操作。

多態(tài)解決了什么問題?

多態(tài)是指子類可以替換父類,在實(shí)際的代碼運(yùn)行過程中,調(diào)用子類的方法實(shí)現(xiàn)。多態(tài)這種特性也需要編程語(yǔ)言提供特殊的語(yǔ)法機(jī)制來實(shí)現(xiàn),比如繼承、接口類。

多態(tài)可以提高代碼的擴(kuò)展性和復(fù)用性,是很多設(shè)計(jì)模式、設(shè)計(jì)原則、編程技巧的代碼實(shí)現(xiàn)基礎(chǔ)。比如策略模式、基于接口而非實(shí)現(xiàn)編程、依賴倒置原則、里式替換原則、利用多態(tài)去掉冗長(zhǎng)的 if-else 語(yǔ)句等等

HashMap是線程安全的嗎?

hashmap不是線程安全的,hashmap在多線程會(huì)存在下面的問題:

  • JDK 1.7 HashMap 采用數(shù)組 + 鏈表的數(shù)據(jù)結(jié)構(gòu),多線程背景下,在數(shù)組擴(kuò)容的時(shí)候,存在 Entry 鏈死循環(huán)和數(shù)據(jù)丟失問題。
  • JDK 1.8 HashMap 采用數(shù)組 + 鏈表 + 紅黑二叉樹的數(shù)據(jù)結(jié)構(gòu),優(yōu)化了 1.7 中數(shù)組擴(kuò)容的方案,解決了 Entry 鏈死循環(huán)和數(shù)據(jù)丟失問題。但是多線程背景下,put 方法存在數(shù)據(jù)覆蓋的問題。

如果要保證線程安全,可以通過這些方法來保證:

  • 多線程環(huán)境可以使用Collections.synchronizedMap同步加鎖的方式,還可以使用HashTable,但是同步的方式顯然性能不達(dá)標(biāo),而ConurrentHashMap更適合高并發(fā)場(chǎng)景使用。
  • ConcurrentHashmap在JDK1.7和1.8的版本改動(dòng)比較大,1.7使用Segment+HashEntry分段鎖的方式實(shí)現(xiàn),1.8則拋棄了Segment,改為使用CAS+synchronized+Node實(shí)現(xiàn),同樣也加入了紅黑樹,避免鏈表過長(zhǎng)導(dǎo)致性能的問題。

Java中的線程安全的集合是什么?

在 java.util 包中的線程安全的類主要 2 個(gè),其他都是非線程安全的。

  • Vector:線程安全的動(dòng)態(tài)數(shù)組,其內(nèi)部方法基本都經(jīng)過synchronized修飾,如果不需要線程安全,并不建議選擇,畢竟同步是有額外開銷的。Vector 內(nèi)部是使用對(duì)象數(shù)組來保存數(shù)據(jù),可以根據(jù)需要自動(dòng)的增加容量,當(dāng)數(shù)組已滿時(shí),會(huì)創(chuàng)建新的數(shù)組,并拷貝原有數(shù)組數(shù)據(jù)。
  • Hashtable:線程安全的哈希表,HashTable 的加鎖方法是給每個(gè)方法加上 synchronized 關(guān)鍵字,這樣鎖住的是整個(gè) Table 對(duì)象,不支持 null 鍵和值,由于同步導(dǎo)致的性能開銷,所以已經(jīng)很少被推薦使用,如果要保證線程安全的哈希表,可以用ConcurrentHashMap。

java.util.concurrent 包提供的都是線程安全的集合:

  • 并發(fā)Map:

           ConcurrentHashMap:它與 HashTable 的主要區(qū)別是二者加鎖粒度的不同,在JDK1.7,ConcurrentHashMap加的是分段鎖,也就是Segment鎖,每個(gè)Segment 含有整個(gè) table 的一部分,這樣不同分段之間的并發(fā)操作就互不影響。在JDK 1.8 ,它取消了Segment字段,直接在table元素上加鎖,實(shí)現(xiàn)對(duì)每一行進(jìn)行加鎖,進(jìn)一步減小了并發(fā)沖突的概率。對(duì)于put操作,如果Key對(duì)應(yīng)的數(shù)組元素為null,則通過CAS操作(Compare and Swap)將其設(shè)置為當(dāng)前值。如果Key對(duì)應(yīng)的數(shù)組元素(也即鏈表表頭或者樹的根元素)不為null,則對(duì)該元素使用 synchronized 關(guān)鍵字申請(qǐng)鎖,然后進(jìn)行操作。如果該 put 操作使得當(dāng)前鏈表長(zhǎng)度超過一定閾值,則將該鏈表轉(zhuǎn)換為紅黑樹,從而提高尋址效率。

           ConcurrentSkipListMap:實(shí)現(xiàn)了一個(gè)基于SkipList(跳表)算法的可排序的并發(fā)集合,SkipList是一種可以在對(duì)數(shù)預(yù)期時(shí)間內(nèi)完成搜索、插入、刪除等操作的數(shù)據(jù)結(jié)構(gòu),通過維護(hù)多個(gè)指向其他元素的“跳躍”鏈接來實(shí)現(xiàn)高效查找。

  • 并發(fā)Set:

           ConcurrentSkipListSet:是線程安全的有序的集合。底層是使用ConcurrentSkipListMap實(shí)現(xiàn)。

           CopyOnWriteArraySet:是線程安全的Set實(shí)現(xiàn),它是線程安全的無(wú)序的集合,可以將它理解成線程安全的HashSet。有意思的是,CopyOnWriteArraySet和HashSet雖然都繼承于共同的父類AbstractSet;但是,HashSet是通過“散列表”實(shí)現(xiàn)的,而CopyOnWriteArraySet則是通過“動(dòng)態(tài)數(shù)組(CopyOnWriteArrayList)”實(shí)現(xiàn)的,并不是散列表。

  • 并發(fā)List:

           CopyOnWriteArrayList:它是 ArrayList 的線程安全的變體,其中所有寫操作(add,set等)都通過對(duì)底層數(shù)組進(jìn)行全新復(fù)制來實(shí)現(xiàn),允許存儲(chǔ) null 元素。即當(dāng)對(duì)象進(jìn)行寫操作時(shí),使用了Lock鎖做同步處理,內(nèi)部拷貝了原數(shù)組,并在新數(shù)組上進(jìn)行添加操作,最后將新數(shù)組替換掉舊數(shù)組;若進(jìn)行的讀操作,則直接返回結(jié)果,操作過程中不需要進(jìn)行同步。

  • 并發(fā) Queue:

           ConcurrentLinkedQueue:是一個(gè)適用于高并發(fā)場(chǎng)景下的隊(duì)列,它通過無(wú)鎖的方式(CAS),實(shí)現(xiàn)了高并發(fā)狀態(tài)下的高性能。通常,ConcurrentLinkedQueue 的性能要好于 BlockingQueue 。

           BlockingQueue:與 ConcurrentLinkedQueue 的使用場(chǎng)景不同,BlockingQueue 的主要功能并不是在于提升高并發(fā)時(shí)的隊(duì)列性能,而在于簡(jiǎn)化多線程間的數(shù)據(jù)共享。BlockingQueue 提供一種讀寫阻塞等待的機(jī)制,即如果消費(fèi)者速度較快,則 BlockingQueue 則可能被清空,此時(shí)消費(fèi)線程再試圖從 BlockingQueue 讀取數(shù)據(jù)時(shí)就會(huì)被阻塞。反之,如果生產(chǎn)線程較快,則 BlockingQueue 可能會(huì)被裝滿,此時(shí),生產(chǎn)線程再試圖向 BlockingQueue 隊(duì)列裝入數(shù)據(jù)時(shí),便會(huì)被阻塞等待。

  • 并發(fā) Deque:

           LinkedBlockingDeque:是一個(gè)線程安全的雙端隊(duì)列實(shí)現(xiàn)。它的內(nèi)部使用鏈表結(jié)構(gòu),每一個(gè)節(jié)點(diǎn)都維護(hù)了一個(gè)前驅(qū)節(jié)點(diǎn)和一個(gè)后驅(qū)節(jié)點(diǎn)。LinkedBlockingDeque 沒有進(jìn)行讀寫鎖的分離,因此同一時(shí)間只能有一個(gè)線程對(duì)其進(jìn)行操作

           ConcurrentLinkedDeque:ConcurrentLinkedDeque是一種基于鏈接節(jié)點(diǎn)的無(wú)限并發(fā)鏈表??梢园踩夭l(fā)執(zhí)行插入、刪除和訪問操作。當(dāng)許多線程同時(shí)訪問一個(gè)公共集合時(shí),ConcurrentLinkedDeque是一個(gè)合適的選擇。

ConcurrentHashMap用了悲觀鎖還是樂觀鎖?

悲觀鎖和樂觀鎖都有用到。

添加元素時(shí)首先會(huì)判斷容器是否為空:

  • 如果為空則使用  volatile  加  CAS (樂觀鎖) 來初始化。
  • 如果容器不為空,則根據(jù)存儲(chǔ)的元素計(jì)算該位置是否為空。

           如果根據(jù)存儲(chǔ)的元素計(jì)算結(jié)果為空,則利用  CAS(樂觀鎖)  設(shè)置該節(jié)點(diǎn);

           如果根據(jù)存儲(chǔ)的元素計(jì)算結(jié)果不為空,則使用 synchronized(悲觀鎖)  ,然后,遍歷桶中的數(shù)據(jù),并替換或新增節(jié)點(diǎn)到桶中,最后再判斷是否需要轉(zhuǎn)為紅黑樹,這樣就能保證并發(fā)訪問時(shí)的線程安全了。

樂觀鎖是怎樣實(shí)現(xiàn)的?

樂觀鎖假設(shè)多個(gè)事務(wù)之間很少發(fā)生沖突,因此在讀取數(shù)據(jù)時(shí)不會(huì)加鎖,而是在更新數(shù)據(jù)時(shí)檢查數(shù)據(jù)的版本(如使用版本號(hào)或時(shí)間戳),如果版本匹配則執(zhí)行更新操作,否則認(rèn)為發(fā)生了沖突。

樂觀鎖適用于讀多寫少的場(chǎng)景,可以減少鎖的競(jìng)爭(zhēng),提高并發(fā)性能。例如,數(shù)據(jù)庫(kù)中的樂觀鎖機(jī)制可以用于處理并發(fā)更新同一行數(shù)據(jù)的情況。

樂觀鎖實(shí)現(xiàn)方式可以通過 CAS 來實(shí)現(xiàn)。

CAS叫做CompareAndSwap,比較并交換,主要是通過處理器的指令來保證操作的原子性,它包含三個(gè)操作數(shù):

  1. 變量?jī)?nèi)存地址,V表示
  2. 舊的預(yù)期值,A表示
  3. 準(zhǔn)備設(shè)置的新值,B表示

當(dāng)執(zhí)行CAS指令時(shí),只有當(dāng)V等于A時(shí),才會(huì)用B去更新V的值,否則就不會(huì)執(zhí)行更新操作。

Http1.0和2.0的區(qū)別是什么?

  • 協(xié)議版本:Http/1.0 是較早的版本,采用文本格式進(jìn)行通信,雖然支持長(zhǎng)連接,但是默認(rèn)是使用短連接。從 http/1.1版本開始,默認(rèn)是用了長(zhǎng)連接,Http/2.0 是較新的版本,引入了二進(jìn)制格式,以及多路復(fù)用等新特性。
  • 性能:Http/1.0 每次請(qǐng)求只能響應(yīng)一個(gè)資源,多個(gè)資源需要多次請(qǐng)求,存在隊(duì)頭阻塞問題。Http/2.0 支持多路復(fù)用,可以在單個(gè)連接上同時(shí)傳輸多個(gè)請(qǐng)求和響應(yīng),提高性能。
  • 頭部壓縮:Http/1.0 每次請(qǐng)求和響應(yīng)都需要攜帶完整的頭部信息,存在較大的開銷。Http/2.0 引入了頭部壓縮機(jī)制,減少了重復(fù)頭部信息的傳輸,提高了效率。
  • 服務(wù)器推送:Http/1.0 需要等待客戶端請(qǐng)求后才能發(fā)送響應(yīng),無(wú)法主動(dòng)推送資源。Http/2.0 支持服務(wù)器推送,服務(wù)器可以在客戶端請(qǐng)求之前將相關(guān)資源推送給客戶端,減少等待時(shí)間。

MySQL中的bin log的作用是什么?

binlog 是 MySQL 的 Server 層實(shí)現(xiàn)的日志,用于備份恢復(fù)、主從復(fù)制。

binlog 有 3 種格式類型,分別是 STATEMENT(默認(rèn)格式)、ROW、 MIXED,區(qū)別如下:

  • STATEMENT:每一條修改數(shù)據(jù)的 SQL 都會(huì)被記錄到 binlog 中(相當(dāng)于記錄了邏輯操作,所以針對(duì)這種格式, binlog 可以稱為邏輯日志),主從復(fù)制中 slave 端再根據(jù) SQL 語(yǔ)句重現(xiàn)。但 STATEMENT 有動(dòng)態(tài)函數(shù)的問題,比如你用了 uuid 或者 now 這些函數(shù),你在主庫(kù)上執(zhí)行的結(jié)果并不是你在從庫(kù)執(zhí)行的結(jié)果,這種隨時(shí)在變的函數(shù)會(huì)導(dǎo)致復(fù)制的數(shù)據(jù)不一致;
  • ROW:記錄行數(shù)據(jù)最終被修改成什么樣了(這種格式的日志,就不能稱為邏輯日志了),不會(huì)出現(xiàn) STATEMENT 下動(dòng)態(tài)函數(shù)的問題。但 ROW 的缺點(diǎn)是每行數(shù)據(jù)的變化結(jié)果都會(huì)被記錄,比如執(zhí)行批量 update 語(yǔ)句,更新多少行數(shù)據(jù)就會(huì)產(chǎn)生多少條記錄,使 binlog 文件過大,而在 STATEMENT 格式下只會(huì)記錄一個(gè) update 語(yǔ)句而已;
  • MIXED:包含了 STATEMENT 和 ROW 模式,它會(huì)根據(jù)不同的情況自動(dòng)使用 ROW 模式和 STATEMENT 模式;

算法

  • 一個(gè)二叉樹,給一個(gè)target,找出大于這個(gè)樹中的節(jié)點(diǎn)的最大深度。
責(zé)任編輯:武曉燕 來源: 小林coding
相關(guān)推薦

2022-06-02 10:54:16

BrokerRocketMQ

2023-11-03 08:10:49

ThreadLoca內(nèi)存泄露

2010-08-09 14:18:53

路由器telnet

2021-11-11 11:30:11

GET圖片Java

2025-04-09 11:15:00

服務(wù)熔斷服務(wù)降分布式系統(tǒng)

2022-03-14 11:05:01

RocketMQRedis緩存

2010-07-12 14:01:43

機(jī)房漫畫連載

2021-04-25 09:58:48

mmapJava面試

2021-03-17 15:54:32

IO零拷貝方式

2023-12-13 08:11:36

2020-03-13 17:59:06

OA二開CIO觀點(diǎn)

2021-12-26 21:49:19

微信面試參數(shù)

2023-10-06 15:29:07

MySQL數(shù)據(jù)庫(kù)更新

2024-06-27 12:26:32

2015-12-17 13:50:43

存儲(chǔ)華為

2009-08-14 16:57:58

高端EV服務(wù)器證書中國(guó)市場(chǎng)上網(wǎng)安全通道

2013-01-09 17:57:11

曹開彬

2017-06-29 11:00:49

2023-04-27 14:39:57

騰訊C++后端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)