大家好,我是小林。rV928資訊網(wǎng)——每日最新資訊28at.com
今天就來分享 Java 同學面試滴滴后端開發(fā)的面經(jīng),主要是問了Java+MySQL+系統(tǒng)+網(wǎng)絡+算法,都是比較經(jīng)典面試題,不算難。rV928資訊網(wǎng)——每日最新資訊28at.com
圖片rV928資訊網(wǎng)——每日最新資訊28at.com
進程五種狀態(tài)的變遷 再來詳細說明一下進程的狀態(tài)變遷:rV928資訊網(wǎng)——每日最新資訊28at.com
- _NULL -> 創(chuàng)建狀態(tài)_:一個新進程被創(chuàng)建時的第一個狀態(tài);
- _創(chuàng)建狀態(tài) -> 就緒狀態(tài)_:當進程被創(chuàng)建完成并初始化后,一切就緒準備運行時,變?yōu)榫途w狀態(tài),這個過程是很快的;
- _就緒態(tài) -> 運行狀態(tài)_:處于就緒狀態(tài)的進程被操作系統(tǒng)的進程調度器選中后,就分配給 CPU 正式運行該進程;
- _運行狀態(tài) -> 結束狀態(tài)_:當進程已經(jīng)運行完成或出錯時,會被操作系統(tǒng)作結束狀態(tài)處理;
- _運行狀態(tài) -> 就緒狀態(tài)_:處于運行狀態(tài)的進程在運行過程中,由于分配給它的運行時間片用完,操作系統(tǒng)會把該進程變?yōu)榫途w態(tài),接著從就緒態(tài)選中另外一個進程運行;
- _運行狀態(tài) -> 阻塞狀態(tài)_:當進程請求某個事件且必須等待時,例如請求 I/O 事件;
- _阻塞狀態(tài) -> 就緒狀態(tài)_:當進程要等待的事件完成時,它從阻塞狀態(tài)變到就緒狀態(tài);
你了解過哪些io模型?
- 阻塞I/O模型:應用程序發(fā)起I/O操作后會被阻塞,直到操作完成才返回結果。適用于對實時性要求不高的場景。
- 非阻塞I/O模型:應用程序發(fā)起I/O操作后立即返回,不會被阻塞,但需要不斷輪詢或者使用select/poll/epoll等系統(tǒng)調用來檢查I/O操作是否完成。適合于需要進行多路復用的場景,例如需要同時處理多個socket連接的服務器程序。
- I/O復用模型:通過select、poll、epoll等系統(tǒng)調用,應用程序可以同時等待多個I/O操作,當其中任何一個I/O操作準備就緒時,應用程序會被通知。適合于需要同時處理多個I/O操作的場景,比如高并發(fā)的服務端程序。
- 信號驅動I/O模型:應用程序發(fā)起I/O操作后,可以繼續(xù)做其他事情,當I/O操作完成時,操作系統(tǒng)會向應用程序發(fā)送信號來通知其完成。適合于需要異步I/O通知的場景,可以提高系統(tǒng)的并發(fā)能力。
- 異步I/O模型:應用程序發(fā)起I/O操作后可以立即做其他事情,當I/O操作完成時,應用程序會得到通知。異步I/O模型由操作系統(tǒng)內核完成I/O操作,應用程序只需等待通知即可。適合于需要大量并發(fā)連接和高性能的場景,能夠減少系統(tǒng)調用次數(shù),提高系統(tǒng)效率。
有了解過io多路復用嗎?
IO多路復用是一種高效的IO處理方式,它允許單個進程或線程同時監(jiān)視多個文件描述符,如網(wǎng)絡連接或文件句柄。當這些描述符中的任何一個就緒時,比如有數(shù)據(jù)可讀或可寫,多路復用機制就能夠通知應用程序進行相應的讀寫操作。這種機制的核心優(yōu)勢在于,它可以在不增加額外線程或進程的情況下,處理大量的并發(fā)連接,從而顯著地提高系統(tǒng)的并發(fā)性和響應能力。常見的IO多路復用技術包括select、poll和epoll等。這些技術各有特點,但核心思想都是通過一個線程來管理多個連接,減少系統(tǒng)資源的消耗,并提高程序運行的效率。select 實現(xiàn)多路復用的方式是,將已連接的 Socket 都放到一個文件描述符集合,然后調用 select 函數(shù)將文件描述符集合拷貝到內核里,讓內核來檢查是否有網(wǎng)絡事件產(chǎn)生,檢查的方式很粗暴,就是通過遍歷文件描述符集合的方式,當檢查到有事件產(chǎn)生后,將此 Socket 標記為可讀或可寫, 接著再把整個文件描述符集合拷貝回用戶態(tài)里,然后用戶態(tài)還需要再通過遍歷的方法找到可讀或可寫的 Socket,然后再對其處理。所以,對于 select 這種方式,需要進行 2 次「遍歷」文件描述符集合,一次是在內核態(tài)里,一個次是在用戶態(tài)里 ,而且還會發(fā)生 2 次「拷貝」文件描述符集合,先從用戶空間傳入內核空間,由內核修改后,再傳出到用戶空間中。select 使用固定長度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的個數(shù)是有限制的,在 Linux 系統(tǒng)中,由內核中的 FD_SETSIZE 限制, 默認最大值為 1024,只能監(jiān)聽 0~1023 的文件描述符。poll 不再用 BitsMap 來存儲所關注的文件描述符,取而代之用動態(tài)數(shù)組,以鏈表形式來組織,突破了 select 的文件描述符個數(shù)限制,當然還會受到系統(tǒng)文件描述符限制。但是 poll 和 select 并沒有太大的本質區(qū)別,都是使用「線性結構」存儲進程關注的 Socket 集合,因此都需要遍歷文件描述符集合來找到可讀或可寫的 Socket,時間復雜度為 O(n),而且也需要在用戶態(tài)與內核態(tài)之間拷貝文件描述符集合,這種方式隨著并發(fā)數(shù)上來,性能的損耗會呈指數(shù)級增長。poll 通過兩個方面,很好解決了 select/poll 的問題。rV928資訊網(wǎng)——每日最新資訊28at.com
- _第一點_,epoll 在內核里使用紅黑樹來跟蹤進程所有待檢測的文件描述字,把需要監(jiān)控的 socket 通過 epoll_ctl() 函數(shù)加入內核中的紅黑樹里,紅黑樹是個高效的數(shù)據(jù)結構,增刪改一般時間復雜度是 O(logn)。而 select/poll 內核里沒有類似 epoll 紅黑樹這種保存所有待檢測的 socket 的數(shù)據(jù)結構,所以 select/poll 每次操作時都傳入整個 socket 集合給內核,而 epoll 因為在內核維護了紅黑樹,可以保存所有待檢測的 socket ,所以只需要傳入一個待檢測的 socket,減少了內核和用戶空間大量的數(shù)據(jù)拷貝和內存分配。
- _第二點_, epoll 使用事件驅動的機制,內核里維護了一個鏈表來記錄就緒事件,當某個 socket 有事件發(fā)生時,通過回調函數(shù)內核會將其加入到這個就緒事件列表中,當用戶調用 epoll_wait() 函數(shù)時,只會返回有事件發(fā)生的文件描述符的個數(shù),不需要像 select/poll 那樣輪詢掃描整個 socket 集合,大大提高了檢測的效率。
從下圖你可以看到 epoll 相關的接口作用:rV928資訊網(wǎng)——每日最新資訊28at.com
圖片rV928資訊網(wǎng)——每日最新資訊28at.com
epoll 的方式即使監(jiān)聽的 Socket 數(shù)量越多的時候,效率不會大幅度降低,能夠同時監(jiān)聽的 Socket 的數(shù)目也非常的多了,上限就為系統(tǒng)定義的進程打開的最大文件描述符個數(shù)。因而,epoll 被稱為解決 C10K 問題的利器。rV928資訊網(wǎng)——每日最新資訊28at.com
計算機網(wǎng)絡
Http請求頭有哪些
下面是一個HTTP請求的請求頭:rV928資訊網(wǎng)——每日最新資訊28at.com
GET /home.html HTTP/1.1Host: developer.mozilla.orgUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflate, brReferer: https://developer.mozilla.org/testpage.htmlConnection: keep-aliveUpgrade-Insecure-Requests: 1If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMTIf-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"Cache-Control: max-age=0
常見的請求字段如下表所示:rV928資訊網(wǎng)——每日最新資訊28at.com
字段名rV928資訊網(wǎng)——每日最新資訊28at.com | 說明rV928資訊網(wǎng)——每日最新資訊28at.com | 示例rV928資訊網(wǎng)——每日最新資訊28at.com |
AcceptrV928資訊網(wǎng)——每日最新資訊28at.com | 能夠接受的回應內容類型(Content-Types)rV928資訊網(wǎng)——每日最新資訊28at.com | Accept: text/plainrV928資訊網(wǎng)——每日最新資訊28at.com |
Accept-CharsetrV928資訊網(wǎng)——每日最新資訊28at.com | 能夠接受的字符集rV928資訊網(wǎng)——每日最新資訊28at.com | Accept-Charset: utf-8rV928資訊網(wǎng)——每日最新資訊28at.com |
Accept-EncodingrV928資訊網(wǎng)——每日最新資訊28at.com | 能夠接受的編碼方式列表rV928資訊網(wǎng)——每日最新資訊28at.com | Accept-Encoding: gzip, deflaterV928資訊網(wǎng)——每日最新資訊28at.com |
AuthorizationrV928資訊網(wǎng)——每日最新資訊28at.com | 用于超文本傳輸協(xié)議的認證的認證信息rV928資訊網(wǎng)——每日最新資訊28at.com | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==rV928資訊網(wǎng)——每日最新資訊28at.com |
Cache-ControlrV928資訊網(wǎng)——每日最新資訊28at.com | 用來指定在這次的請求/響應鏈中的所有緩存機制 都必須 遵守的指令rV928資訊網(wǎng)——每日最新資訊28at.com | Cache-Control: no-cacherV928資訊網(wǎng)——每日最新資訊28at.com |
ConnectionrV928資訊網(wǎng)——每日最新資訊28at.com | 該瀏覽器想要優(yōu)先使用的連接類型rV928資訊網(wǎng)——每日最新資訊28at.com | Connection: keep-alive Connection: UpgraderV928資訊網(wǎng)——每日最新資訊28at.com |
CookierV928資訊網(wǎng)——每日最新資訊28at.com | 服務器通過 Set- Cookie (下文詳述)發(fā)送的一個 超文本傳輸協(xié)議CookierV928資訊網(wǎng)——每日最新資訊28at.com | Cookie: $Versinotallow=1; Skin=new;rV928資訊網(wǎng)——每日最新資訊28at.com |
Content-LengthrV928資訊網(wǎng)——每日最新資訊28at.com | 以 八位字節(jié)數(shù)組 (8位的字節(jié))表示的請求體的長度rV928資訊網(wǎng)——每日最新資訊28at.com | Content-Length: 348rV928資訊網(wǎng)——每日最新資訊28at.com |
Content-TyperV928資訊網(wǎng)——每日最新資訊28at.com | 請求體的 多媒體類型rV928資訊網(wǎng)——每日最新資訊28at.com | Content-Type: application/x-www-form-urlencodedrV928資訊網(wǎng)——每日最新資訊28at.com |
HostrV928資訊網(wǎng)——每日最新資訊28at.com | 服務器的域名(用于虛擬主機 ),以及服務器所監(jiān)聽的傳輸控制協(xié)議端口號rV928資訊網(wǎng)——每日最新資訊28at.com | Host: en.wikipedia.org:80 Host: en.wikipedia.orgrV928資訊網(wǎng)——每日最新資訊28at.com |
User-AgentrV928資訊網(wǎng)——每日最新資訊28at.com | 瀏覽器的瀏覽器身份標識字符串rV928資訊網(wǎng)——每日最新資訊28at.com | User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0rV928資訊網(wǎng)——每日最新資訊28at.com |
OriginrV928資訊網(wǎng)——每日最新資訊28at.com | 發(fā)起一個針對 跨來源資源共享 的請求rV928資訊網(wǎng)——每日最新資訊28at.com | Origin: http://www.example-social-network.comrV928資訊網(wǎng)——每日最新資訊28at.com |
常見的狀態(tài)碼(分類舉例說明)
圖片rV928資訊網(wǎng)——每日最新資訊28at.com
五大類 HTTP 狀態(tài)碼rV928資訊網(wǎng)——每日最新資訊28at.com
- 1xx 類狀態(tài)碼屬于提示信息,是協(xié)議處理中的一種中間狀態(tài),實際用到的比較少。
- 2xx 類狀態(tài)碼表示服務器成功處理了客戶端的請求,也是我們最愿意看到的狀態(tài)。
- 3xx 類狀態(tài)碼表示客戶端請求的資源發(fā)生了變動,需要客戶端用新的 URL 重新發(fā)送請求獲取資源,也就是重定向。
- 4xx 類狀態(tài)碼表示客戶端發(fā)送的報文有誤,服務器無法處理,也就是錯誤碼的含義。
- 5xx 類狀態(tài)碼表示客戶端請求報文正確,但是服務器處理時內部發(fā)生了錯誤,屬于服務器端的錯誤碼。
301和302有什么區(qū)別
重定向狀態(tài)碼如下,301 和 302 都會在響應頭里使用字段 Location,指明后續(xù)要跳轉的 URL,瀏覽器會自動重定向新的 URL。rV928資訊網(wǎng)——每日最新資訊28at.com
- 「301 Moved Permanently」表示永久重定向,說明請求的資源已經(jīng)不存在了,需改用新的 URL 再次訪問。
- 「302 Found」表示臨時重定向,說明請求的資源還在,但暫時需要用另一個 URL 來訪問。
重定向是指將一個URL請求轉發(fā)到另一個URL的過程。重定向的作用包括:rV928資訊網(wǎng)——每日最新資訊28at.com
- 更改URL:通過重定向,可以更改URL,使其更易于記憶、更友好或更有意義。例如,將長而復雜的URL重定向到簡潔的、易于理解的URL。
- 網(wǎng)站遷移:當網(wǎng)站進行重構、更換域名或更改URL結構時,通過重定向舊的URL到新的URL,可以讓用戶和搜索引擎正確地訪問和索引新的內容。
Java八股
常用的集合有哪些?
圖片rV928資訊網(wǎng)——每日最新資訊28at.com
List是有序的Collection,使用此接口能夠精確的控制每個元素的插入位置,用戶能根據(jù)索引訪問List中元素。常用的實現(xiàn)List的類有LinkedList,ArrayList,Vector,Stack。rV928資訊網(wǎng)——每日最新資訊28at.com
- ArrayList是容量可變的非線程安全列表,其底層使用數(shù)組實現(xiàn)。當幾何擴容時,會創(chuàng)建更大的數(shù)組,并把原數(shù)組復制到新數(shù)組。ArrayList支持對元素的快速隨機訪問,但插入與刪除速度很慢。
- LinkedList本質是一個雙向鏈表,與ArrayList相比,,其插入和刪除速度更快,但隨機訪問速度更慢。
Set不允許存在重復的元素,與List不同,set中的元素是無序的。常用的實現(xiàn)有HashSet,LinkedHashSet和TreeSet。rV928資訊網(wǎng)——每日最新資訊28at.com
- HashSet通過HashMap實現(xiàn),HashMap的Key即HashSet存儲的元素,所有Key都是用相同的Value,一個名為PRESENT的Object類型常量。使用Key保證元素唯一性,但不保證有序性。由于HashSet是HashMap實現(xiàn)的,因此線程不安全。
- LinkedHashSet繼承自HashSet,通過LinkedHashMap實現(xiàn),使用雙向鏈表維護元素插入順序。
- TreeSet通過TreeMap實現(xiàn)的,添加元素到集合時按照比較規(guī)則將其插入合適的位置,保證插入后的集合仍然有序。
Map 是一個鍵值對集合,存儲鍵、值和之間的映射。Key 無序,唯一;value 不要求有序,允許重復。Map 沒有繼承于 Collection 接口,從 Map 集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。主要實現(xiàn)有TreeMap、HashMap、HashTable、LinkedHashMap、ConcurrentHashMaprV928資訊網(wǎng)——每日最新資訊28at.com
- HashMap:JDK1.8 之前 HashMap 由數(shù)組+鏈表組成的,數(shù)組是 HashMap 的主體,鏈表則是主要為了解決哈希沖突而存在的(“拉鏈法”解決沖突),JDK1.8 以后在解決哈希沖突時有了較大的變化,當鏈表長度大于閾值(默認為 8)時,將鏈表轉化為紅黑樹,以減少搜索時間
- LinkedHashMap:LinkedHashMap 繼承自 HashMap,所以它的底層仍然是基于拉鏈式散列結構即由數(shù)組和鏈表或紅黑樹組成。另外,LinkedHashMap 在上面結構的基礎上,增加了一條雙向鏈表,使得上面的結構可以保持鍵值對的插入順序。同時通過對鏈表進行相應的操作,實現(xiàn)了訪問順序相關邏輯。
- HashTable:數(shù)組+鏈表組成的,數(shù)組是 HashMap 的主體,鏈表則是主要為了解決哈希沖突而存在的
- TreeMap:紅黑樹(自平衡的排序二叉樹)
- ConcurrentHashMap:Node數(shù)組+鏈表+紅黑樹實現(xiàn),線程安全的(jdk1.8以前Segment鎖,1.8以后volatile + CAS 或者 synchronized)
hashtable 和concurrentHashMap有什么區(qū)別
- jdk7之前的ConcurrentHashMap底層采用的是分段的數(shù)組+鏈表實現(xiàn),jdk8之后采用的是數(shù)組+鏈表/紅黑樹;
- HashTable采用的是數(shù)組+鏈表,數(shù)組是主體,鏈表是解決hash沖突存在的。
- 實現(xiàn)線程安全的方式:
- jdk8以前,ConcurrentHashMap采用分段鎖,對整個數(shù)組進行了分段分割,每一把鎖只鎖容器里的一部分數(shù)據(jù),多線程訪問不同數(shù)據(jù)段里的數(shù)據(jù),就不會存在鎖競爭,提高了并發(fā)訪問;jdk8以后,直接采用數(shù)組+鏈表/紅黑樹,并發(fā)控制使用CAS和synchronized操作,更加提高了速度。
- HashTable:所有的方法都加了鎖來保證線程安全,但是效率非常的低下,當一個線程訪問同步方法,另一個線程也訪問的時候,就會陷入阻塞或者輪詢的狀態(tài)。
Java的垃圾回收器有哪些?
- Serial 收集器,串行收集器是最古老,最穩(wěn)定以及效率高的收集器,可能會產(chǎn)生較長的停頓,只使用一個線程去回收。
- ParNew 收集器,ParNew 收集器其實就是 Serial 收集器的多線程版本。
- Parallel 收集器,Parallel Scavenge 收集器類似 ParNew 收集器,Parallel 收集器更關注系統(tǒng)的吞吐量。
- Parallel Old 收集器,Parallel Old 是 Parallel Scavenge 收集器的老年代版本,使用多線程和“標記-整理”算法
- CMS 收集器,CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。
- G1 收集器,G1 (Garbage-First)是一款面向服務器的垃圾收集器,主要針對配備多顆處理器及大容量內存的機器. 以極高概率滿足 GC 停頓時間要求的同時,還具備高吞吐量性能特征
垃圾回收的方法有哪些?
- 標記-清除算法:標記-清除算法分為“標記”和“清除”兩個階段,首先通過可達性分析,標記出所有需要回收的對象,然后統(tǒng)一回收所有被標記的對象。標記-清除算法有兩個缺陷,一個是效率問題,標記和清除的過程效率都不高,另外一個就是,清除結束后會造成大量的碎片空間。有可能會造成在申請大塊內存的時候因為沒有足夠的連續(xù)空間導致再次 GC。
- 復制算法:為了解決碎片空間的問題,出現(xiàn)了“復制算法”。復制算法的原理是,將內存分成兩塊,每次申請內存時都使用其中的一塊,當內存不夠時,將這一塊內存中所有存活的復制到另一塊上。然后將然后再把已使用的內存整個清理掉。復制算法解決了空間碎片的問題。但是也帶來了新的問題。因為每次在申請內存時,都只能使用一半的內存空間。內存利用率嚴重不足。
- 標記-整理算法:復制算法在 GC 之后存活對象較少的情況下效率比較高,但如果存活對象比較多時,會執(zhí)行較多的復制操作,效率就會下降。而老年代的對象在 GC 之后的存活率就比較高,所以就有人提出了“標記-整理算法”。標記-整理算法的“標記”過程與“標記-清除算法”的標記過程一致,但標記之后不會直接清理。而是將所有存活對象都移動到內存的一端。移動結束后直接清理掉剩余部分。
- 分代回收算法:分代收集是將內存劃分成了新生代和老年代。分配的依據(jù)是對象的生存周期,或者說經(jīng)歷過的 GC 次數(shù)。對象創(chuàng)建時,一般在新生代申請內存,當經(jīng)歷一次 GC 之后如果對還存活,那么對象的年齡 +1。當年齡超過一定值(默認是 15,可以通過參數(shù) -XX:MaxTenuringThreshold 來設定)后,如果對象還存活,那么該對象會進入老年代。
有哪些優(yōu)化java程序的辦法
調整新生代和老年代的比例、線程池、減少GC。rV928資訊網(wǎng)——每日最新資訊28at.com
mysql
mysql幾種事務隔離
SQL 標準提出了四種隔離級別來規(guī)避這些現(xiàn)象,隔離級別越高,性能效率就越低,這四個隔離級別如下:rV928資訊網(wǎng)——每日最新資訊28at.com
- 讀未提交(_read uncommitted_),指一個事務還沒提交時,它做的變更就能被其他事務看到;
- 讀提交(_read committed_),指一個事務提交之后,它做的變更才能被其他事務看到;
- 可重復讀(_repeatable read_),指一個事務執(zhí)行過程中看到的數(shù)據(jù),一直跟這個事務啟動時看到的數(shù)據(jù)是一致的,MySQL InnoDB 引擎的默認隔離級別;
- 串行化(_serializable_ );會對記錄加上讀寫鎖,在多個事務對這條記錄進行讀寫操作時,如果發(fā)生了讀寫沖突的時候,后訪問的事務必須等前一個事務執(zhí)行完成,才能繼續(xù)執(zhí)行;
按隔離水平高低排序如下:
針對不同的隔離級別,并發(fā)事務時可能發(fā)生的現(xiàn)象也會不同。
也就是說:rV928資訊網(wǎng)——每日最新資訊28at.com
- 在「讀未提交」隔離級別下,可能發(fā)生臟讀、不可重復讀和幻讀現(xiàn)象;
- 在「讀提交」隔離級別下,可能發(fā)生不可重復讀和幻讀現(xiàn)象,但是不可能發(fā)生臟讀現(xiàn)象;
- 在「可重復讀」隔離級別下,可能發(fā)生幻讀現(xiàn)象,但是不可能臟讀和不可重復讀現(xiàn)象;
- 在「串行化」隔離級別下,臟讀、不可重復讀和幻讀現(xiàn)象都不可能會發(fā)生。
臟讀和幻讀有什么區(qū)別
臟讀rV928資訊網(wǎng)——每日最新資訊28at.com
如果一個事務「讀到」了另一個「未提交事務修改過的數(shù)據(jù)」,就意味著發(fā)生了「臟讀」現(xiàn)象。rV928資訊網(wǎng)——每日最新資訊28at.com
舉個栗子。rV928資訊網(wǎng)——每日最新資訊28at.com
假設有 A 和 B 這兩個事務同時在處理,事務 A 先開始從數(shù)據(jù)庫中讀取小林的余額數(shù)據(jù),然后再執(zhí)行更新操作,如果此時事務 A 還沒有提交事務,而此時正好事務 B 也從數(shù)據(jù)庫中讀取小林的余額數(shù)據(jù),那么事務 B 讀取到的余額數(shù)據(jù)是剛才事務 A 更新后的數(shù)據(jù),即使沒有提交事務。
rV928資訊網(wǎng)——每日最新資訊28at.com
因為事務 A 是還沒提交事務的,也就是它隨時可能發(fā)生回滾操作,如果在上面這種情況事務 A 發(fā)生了回滾,那么事務 B 剛才得到的數(shù)據(jù)就是過期的數(shù)據(jù),這種現(xiàn)象就被稱為臟讀。rV928資訊網(wǎng)——每日最新資訊28at.com
幻讀rV928資訊網(wǎng)——每日最新資訊28at.com
在一個事務內多次查詢某個符合查詢條件的「記錄數(shù)量」,如果出現(xiàn)前后兩次查詢到的記錄數(shù)量不一樣的情況,就意味著發(fā)生了「幻讀」現(xiàn)象。rV928資訊網(wǎng)——每日最新資訊28at.com
舉個栗子。rV928資訊網(wǎng)——每日最新資訊28at.com
假設有 A 和 B 這兩個事務同時在處理,事務 A 先開始從數(shù)據(jù)庫查詢賬戶余額大于 100 萬的記錄,發(fā)現(xiàn)共有 5 條,然后事務 B 也按相同的搜索條件也是查詢出了 5 條記錄。rV928資訊網(wǎng)——每日最新資訊28at.com
rV928資訊網(wǎng)——每日最新資訊28at.com
接下來,事務 A 插入了一條余額超過 100 萬的賬號,并提交了事務,此時數(shù)據(jù)庫超過 100 萬余額的賬號個數(shù)就變?yōu)?6。rV928資訊網(wǎng)——每日最新資訊28at.com
然后事務 B 再次查詢賬戶余額大于 100 萬的記錄,此時查詢到的記錄數(shù)量有 6 條,發(fā)現(xiàn)和前一次讀到的記錄數(shù)量不一樣了,就感覺發(fā)生了幻覺一樣,這種現(xiàn)象就被稱為幻讀。rV928資訊網(wǎng)——每日最新資訊28at.com
算法
有序數(shù)組1-100,刪除一個數(shù),如何查找
可以通過二分查找的方式來查找并刪除一個數(shù)。rV928資訊網(wǎng)——每日最新資訊28at.com
首先,將數(shù)組從中間分成兩部分,比較中間元素和要查找的數(shù)的大小關系。如果中間元素等于要查找的數(shù),則刪除該元素并將數(shù)組整體向前移動一位。如果中間元素大于要查找的數(shù),則在左半部分繼續(xù)進行二分查找。如果中間元素小于要查找的數(shù),則在右半部分繼續(xù)進行二分查找。rV928資訊網(wǎng)——每日最新資訊28at.com
重復以上步驟,直到找到要刪除的數(shù)或者確定該數(shù)不在數(shù)組中。如果找到要刪除的數(shù),則將該數(shù)刪除并將數(shù)組整體向前移動一位。rV928資訊網(wǎng)——每日最新資訊28at.com
以下是java實現(xiàn)代碼:rV928資訊網(wǎng)——每日最新資訊28at.com
public class DeleteNumber { public static void main(String[] args) { int[] arr = new int[100]; for (int i = 0; i < 100; i++) { arr[i] = i + 1; } int target = 50; // 要刪除的數(shù) int index = binarySearch(arr, target); if(index != -1){ deleteNumber(arr, index); System.out.println("刪除成功!"); }else{ System.out.println("未找到該數(shù)!"); } } public static int binarySearch(int[] arr, int target) { int left = 0; int right = arr.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } public static void deleteNumber(int[] arr, int index) { for (int i = index; i < arr.length - 1; i++) { arr[i] = arr[i + 1]; } }}
在上面的代碼中,假設要刪除的數(shù)是50,然后調用binarySearch方法查找50的索引,如果找到則調用deleteNumber方法刪除該數(shù)。最后打印刪除成功的消息。rV928資訊網(wǎng)——每日最新資訊28at.com
本文鏈接:http://www.tebozhan.com/showinfo-26-88321-0.html落淚!滴滴一面,涼了......
聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 盤點GoLang中的三方庫:govaluate、flag、go-homedir、cast
下一篇: 解鎖 Python 超能力:十大變革性庫與框架