Java實(shí)習(xí)打卡8道面試題
1、什么是雪花算法,簡(jiǎn)單介紹一下?
文章參考:帶你入門(mén)java雪花算法原理
雪花算法是 Twitter 開(kāi)源的分布式 ID 生成算法。是由 64bit
的 long
類(lèi)型,生成的全局 ID,引入了 時(shí)間戳和 ID保持自增 的屬性。
64bit
分為四個(gè)部分:
- 第一個(gè)部分是
1bit
,沒(méi)有實(shí)際意義。 - 第二個(gè)部分是
41bit
,由時(shí)間戳組成。 - 第三個(gè)部分是
10bit
,工作機(jī)器 ID,里面分為兩個(gè)部分,5 個(gè) bit 是的是機(jī)房號(hào),代表最多有 2^5 即 32 個(gè)機(jī)房,5 個(gè) bit 是指機(jī)器的ID,代表最多有 2^5 個(gè)機(jī)器,即 32 個(gè)機(jī)器。 - 第四部分是
12bit
,代表是同一個(gè)毫秒類(lèi)產(chǎn)生不同的 ID,區(qū)分同一個(gè)毫秒內(nèi)產(chǎn)生的ID.
總的來(lái)說(shuō)就是一個(gè)機(jī)房,一臺(tái)機(jī)器,在同一號(hào)毫秒時(shí)產(chǎn)生的 ID,可能在同一秒鐘產(chǎn)生不同的 ID,最后 12bit 序列號(hào)可以區(qū)分在同一秒鐘的不同 ID。
雪花算法保證:
- 所生成的 ID 按時(shí)間遞增。
- 整個(gè)分布式系統(tǒng)不會(huì)有重復(fù)的 ID。
2、請(qǐng)你分析一下紅黑樹(shù)的左右旋轉(zhuǎn)流程?
直接上圖,生動(dòng)形象:
就以左旋為例,首先當(dāng)前節(jié)點(diǎn)(N)所在位置被它的右子節(jié)點(diǎn)(R)替代,N 的左子樹(shù)仍然是它的左子節(jié)點(diǎn)(L),但是 R 節(jié)點(diǎn)此時(shí)將它的左子節(jié)點(diǎn)(RL)交給 N,使其成為 N 的右子節(jié)點(diǎn),R 的右子節(jié)點(diǎn)還是原來(lái)的右子節(jié)點(diǎn)(RR)。
紅黑樹(shù)的完整文章,參考往期博客:HashMap底層紅黑樹(shù)實(shí)現(xiàn)(自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的紅黑樹(shù))
3、什么是DNS污染和DSN劫持?
什么是DNS劫持?
- DNS 劫持:就是指 DNS 服務(wù)器被劫持了,通過(guò)某些手段取得某域名的解析記錄控制權(quán),進(jìn)而修改此域名的解析結(jié)果,導(dǎo)致對(duì)該域名的訪問(wèn)由原IP地址轉(zhuǎn)入到修改后的指定IP,其結(jié)果就是對(duì)特定的網(wǎng)址不能訪問(wèn)或訪問(wèn)的是假網(wǎng)址,從而實(shí)現(xiàn)竊取資料或者破壞原有正常服務(wù)的目的。DNS 劫持通過(guò)篡改 DNS 服務(wù)器上的數(shù)據(jù)返回給用戶一個(gè)錯(cuò)誤的查詢結(jié)果來(lái)實(shí)現(xiàn)的。
- DNS 劫持癥狀:在某些地區(qū)的用戶在成功連接寬帶后,首次打開(kāi)任何頁(yè)面都指向 ISP 提供的 “電信互聯(lián)星空”、“網(wǎng)通黃頁(yè)廣告” 等內(nèi)容頁(yè)面。還有就是曾經(jīng)出現(xiàn)過(guò)用戶訪問(wèn) Google 域名的時(shí)候出現(xiàn)了百度的網(wǎng)站。這些都屬于 DNS 劫持。
什么是DNS污染?
- DNS 污染:是一種讓一般用戶由于得到虛假目標(biāo)主機(jī) IP 而不能與其通信的方法,是一種 DNS 緩存投毒攻擊(DNS cache poisoning)。
- 其工作方式是:由于通常的 DNS 查詢沒(méi)有任何認(rèn)證機(jī)制,而且 DNS 查詢通?;诘?UDP 是無(wú)連接不可靠的協(xié)議,因此 DNS 的查詢非常容易被篡改,通過(guò)對(duì) UDP 端口 53 上的 DNS 查詢進(jìn)行入侵檢測(cè),一經(jīng)發(fā)現(xiàn)與關(guān)鍵詞相匹配的請(qǐng)求則立即偽裝成目標(biāo)域名的解析服務(wù)器(NS,Name Server)給查詢者返回虛假結(jié)果。
- DNS污染則是發(fā)生在用戶請(qǐng)求的第一步上,直接從協(xié)議上對(duì)用戶的DNS請(qǐng)求進(jìn)行干擾。
- DNS污染癥狀:目前一些被禁止訪問(wèn)的網(wǎng)站很多就是通過(guò) DNS 污染來(lái)實(shí)現(xiàn)的,例如 YouTube、Facebook 等網(wǎng)站。
二者的解決方案:
對(duì)于DNS劫持,可以采用使用國(guó)外免費(fèi)公用的DNS服務(wù)器解決。例如 OpenDNS(208.67.222.222)或 GoogleDNS(8.8.8.8)。
對(duì)于DNS污染,可以說(shuō),個(gè)人用戶很難單單靠設(shè)置解決,通??梢允褂?VPN 或者域名遠(yuǎn)程解析的方法解決,但這大多需要購(gòu)買(mǎi)付費(fèi)的 VPN 或 SSH 等,也可以通過(guò)修改 Hosts 的方法,手動(dòng)設(shè)置域名正確的 IP 地址。
總結(jié):
- DNS 劫持,就是指用戶訪問(wèn)一個(gè)被標(biāo)記的地址時(shí),DNS 服務(wù)器故意將此地址指向一個(gè)錯(cuò)誤的IP地址的行為。范例,網(wǎng)通、電信、鐵通的某些用戶有時(shí)候會(huì)發(fā)現(xiàn)自己打算訪問(wèn)一個(gè)地址,卻被轉(zhuǎn)向了各種推送廣告等網(wǎng)站,這就是DNS劫持。
- DNS 污染,指的是用戶訪問(wèn)一個(gè)地址,國(guó)內(nèi)的服務(wù)器(非DNS)監(jiān)控到用戶訪問(wèn)的已經(jīng)被標(biāo)記地址時(shí),服務(wù)器偽裝成DNS服務(wù)器向用戶發(fā)回錯(cuò)誤的地址的行為。范例,訪問(wèn) Youtube、Facebook 之類(lèi)網(wǎng)站等出現(xiàn)的狀況。
4、說(shuō)一說(shuō)操作系統(tǒng)的虛擬內(nèi)存?
4.1、虛擬內(nèi)存介紹,什么是虛擬內(nèi)存?
這個(gè)在我們平時(shí)使用電腦特別是 Windows 系統(tǒng)的時(shí)候太常見(jiàn)了。很多時(shí)候我們使用點(diǎn)開(kāi)了很多占內(nèi)存的軟件,這些軟件占用的內(nèi)存可能已經(jīng)遠(yuǎn)遠(yuǎn)超出了我們電腦本身具有的物理內(nèi)存。
為什么可以這樣呢? 正是因?yàn)?虛擬內(nèi)存 的存在,通過(guò) 虛擬內(nèi)存 可以讓程序可以擁有超過(guò)系統(tǒng)物理內(nèi)存大小的可用內(nèi)存空間。
另外,虛擬內(nèi)存為每個(gè)進(jìn)程提供了一個(gè)一致的、私有的地址空間,它讓每個(gè)進(jìn)程產(chǎn)生了一種自己在獨(dú)享主存的錯(cuò)覺(jué)(每個(gè)進(jìn)程擁有一片連續(xù)完整的內(nèi)存空間)。這樣會(huì)更加有效地管理內(nèi)存并減少出錯(cuò)。
虛擬內(nèi)存是計(jì)算機(jī)系統(tǒng)內(nèi)存管理的一種技術(shù),我們可以手動(dòng)設(shè)置自己電腦的虛擬內(nèi)存。不要單純認(rèn)為虛擬內(nèi)存只是“使用硬盤(pán)空間來(lái)擴(kuò)展內(nèi)存“的技術(shù)。虛擬內(nèi)存的重要意義是它定義了一個(gè)連續(xù)的虛擬地址空間,并且 把內(nèi)存擴(kuò)展到硬盤(pán)空間。
4.2、什么是局部性原理?
局部性原理是虛擬內(nèi)存技術(shù)的基礎(chǔ),正是因?yàn)槌绦蜻\(yùn)行具有局部性原理,才可以只裝入部分程序到內(nèi)存就開(kāi)始運(yùn)行。
早在 1968 年的時(shí)候,就有人指出我們的程序在執(zhí)行的時(shí)候往往呈現(xiàn)局部性規(guī)律,也就是說(shuō)在某個(gè)較短的時(shí)間段內(nèi),程序執(zhí)行局限于某一小部分,程序訪問(wèn)的存儲(chǔ)空間也局限于某個(gè)區(qū)域。
局部性原理表現(xiàn)在以下兩個(gè)方面:
- 時(shí)間局部性 :如果程序中的某條指令一旦執(zhí)行,不久以后該指令可能再次執(zhí)行;如果某數(shù)據(jù)被訪問(wèn)過(guò),不久以后該數(shù)據(jù)可能再次被訪問(wèn)。產(chǎn)生時(shí)間局部性的典型原因,是由于在程序中存在著大量的循環(huán)操作。
- 空間局部性 :一旦程序訪問(wèn)了某個(gè)存儲(chǔ)單元,在不久之后,其附近的存儲(chǔ)單元也將被訪問(wèn),即程序在一段時(shí)間內(nèi)所訪問(wèn)的地址,可能集中在一定的范圍之內(nèi),這是因?yàn)橹噶钔ǔJ琼樞虼娣拧㈨樞驁?zhí)行的,數(shù)據(jù)也一般是以向量、數(shù)組、表等形式簇聚存儲(chǔ)的。
時(shí)間局部性是通過(guò)將近來(lái)使用的指令和數(shù)據(jù)保存到高速緩存存儲(chǔ)器中,并使用高速緩存的層次結(jié)構(gòu)實(shí)現(xiàn)??臻g局部性通常是使用較大的高速緩存,并將預(yù)取機(jī)制集成到高速緩存控制邏輯中實(shí)現(xiàn)。虛擬內(nèi)存技術(shù)實(shí)際上就是建立了 “內(nèi)存一外存”的兩級(jí)存儲(chǔ)器的結(jié)構(gòu),利用局部性原理實(shí)現(xiàn)髙速緩存。
4.3、虛擬存儲(chǔ)器(虛擬內(nèi)存)
基于局部性原理,在程序裝入時(shí),可以將程序的一部分裝入內(nèi)存,而將其他部分留在外存,就可以啟動(dòng)程序執(zhí)行。由于外存往往比內(nèi)存大很多,所以我們運(yùn)行的軟件的內(nèi)存大小實(shí)際上是可以比計(jì)算機(jī)系統(tǒng)實(shí)際的內(nèi)存大小大的。
**在程序執(zhí)行過(guò)程中,當(dāng)所訪問(wèn)的信息不在內(nèi)存時(shí),由操作系統(tǒng)將所需要的部分調(diào)入內(nèi)存,然后繼續(xù)執(zhí)行程序。另一方面,操作系統(tǒng)將內(nèi)存中暫時(shí)不使用的內(nèi)容換到外存上,從而騰出空間存放將要調(diào)入內(nèi)存的信息。**這樣,計(jì)算機(jī)好像為用戶提供了一個(gè)比實(shí)際內(nèi)存大的多的存儲(chǔ)器——虛擬存儲(chǔ)器。
實(shí)際上,我覺(jué)得虛擬內(nèi)存同樣是一種時(shí)間換空間的策略,你用 CPU 的計(jì)算時(shí)間,頁(yè)的調(diào)入調(diào)出花費(fèi)的時(shí)間,換來(lái)了一個(gè)虛擬的更大的空間來(lái)支持程序的運(yùn)行。不得不感嘆,程序世界幾乎不是時(shí)間換空間就是空間換時(shí)間。
4.4、虛擬內(nèi)存技術(shù)實(shí)現(xiàn)
虛擬內(nèi)存的實(shí)現(xiàn)需要建立在離散分配的內(nèi)存管理方式的基礎(chǔ)上。 虛擬內(nèi)存的實(shí)現(xiàn)有以下三種方式:
請(qǐng)求分頁(yè)存儲(chǔ)管理 :建立在分頁(yè)管理之上,為了支持虛擬存儲(chǔ)器功能而增加了請(qǐng)求調(diào)頁(yè)功能和頁(yè)面置換功能。請(qǐng)求分頁(yè)是目前最常用的一種實(shí)現(xiàn)虛擬存儲(chǔ)器的方法。請(qǐng)求分頁(yè)存儲(chǔ)管理系統(tǒng)中,在作業(yè)開(kāi)始運(yùn)行之前,僅裝入當(dāng)前要執(zhí)行的部分段即可運(yùn)行。假如在作業(yè)運(yùn)行的過(guò)程中發(fā)現(xiàn)要訪問(wèn)的頁(yè)面不在內(nèi)存,則由處理器通知操作系統(tǒng)按照對(duì)應(yīng)的頁(yè)面置換算法將相應(yīng)的頁(yè)面調(diào)入到主存,同時(shí)操作系統(tǒng)也可以將暫時(shí)不用的頁(yè)面置換到外存中。
請(qǐng)求分段存儲(chǔ)管理 :建立在分段存儲(chǔ)管理之上,增加了請(qǐng)求調(diào)段功能、分段置換功能。請(qǐng)求分段儲(chǔ)存管理方式就如同請(qǐng)求分頁(yè)儲(chǔ)存管理方式一樣,在作業(yè)開(kāi)始運(yùn)行之前,僅裝入當(dāng)前要執(zhí)行的部分段即可運(yùn)行;在執(zhí)行過(guò)程中,可使用請(qǐng)求調(diào)入中斷動(dòng)態(tài)裝入要訪問(wèn)但又不在內(nèi)存的程序段;當(dāng)內(nèi)存空間已滿,而又需要裝入新的段時(shí),根據(jù)置換功能適當(dāng)調(diào)出某個(gè)段,以便騰出空間而裝入新的段。
請(qǐng)求段頁(yè)式存儲(chǔ)管理
這里多說(shuō)一下?很多人容易搞混請(qǐng)求分頁(yè)與分頁(yè)存儲(chǔ)管理,兩者有何不同呢?
請(qǐng)求分頁(yè)存儲(chǔ)管理建立在分頁(yè)管理之上。他們的根本區(qū)別是是否將程序全部所需的全部地址空間都裝入主存,這也是請(qǐng)求分頁(yè)存儲(chǔ)管理可以提供虛擬內(nèi)存的原因,我們?cè)谏厦嬉呀?jīng)分析過(guò)了。
它們之間的根本區(qū)別在于是否將一作業(yè)的全部地址空間同時(shí)裝入主存。請(qǐng)求分頁(yè)存儲(chǔ)管理不要求將作業(yè)全部地址空間同時(shí)裝入主存。基于這一點(diǎn),請(qǐng)求分頁(yè)存儲(chǔ)管理可以提供虛存,而分頁(yè)存儲(chǔ)管理卻不能提供虛存。
不管是上面那種實(shí)現(xiàn)方式,我們一般都需要:
- 一定容量的內(nèi)存和外存:在載入程序的時(shí)候,只需要將程序的一部分裝入內(nèi)存,而將其他部分留在外存,然后程序就可以執(zhí)行了;
- 缺頁(yè)中斷:如果需執(zhí)行的指令或訪問(wèn)的數(shù)據(jù)尚未在內(nèi)存(稱為缺頁(yè)或缺段),則由處理器通知操作系統(tǒng)將相應(yīng)的頁(yè)面或段調(diào)入到內(nèi)存,然后繼續(xù)執(zhí)行程序;
- 虛擬地址空間 :邏輯地址到物理地址的變換。
4.5、頁(yè)面置換算法
地址映射過(guò)程中,若在頁(yè)面中發(fā)現(xiàn)所要訪問(wèn)的頁(yè)面不在內(nèi)存中,則發(fā)生缺頁(yè)中斷 。
注:缺頁(yè)中斷 就是要訪問(wèn)的頁(yè)不在主存,需要操作系統(tǒng)將其調(diào)入主存后再進(jìn)行訪問(wèn)。 在這個(gè)時(shí)候,被內(nèi)存映射的文件實(shí)際上成了一個(gè)分頁(yè)交換文件。
當(dāng)發(fā)生缺頁(yè)中斷時(shí),如果當(dāng)前內(nèi)存中并沒(méi)有空閑的頁(yè)面,操作系統(tǒng)就必須在內(nèi)存選擇一個(gè)頁(yè)面將其移出內(nèi)存,以便為即將調(diào)入的頁(yè)面讓出空間。用來(lái)選擇淘汰哪一頁(yè)的規(guī)則叫做頁(yè)面置換算法,我們可以把頁(yè)面置換算法看成是淘汰頁(yè)面的規(guī)則。
- OPT 頁(yè)面置換算法(最佳頁(yè)面置換算法) :最佳(Optimal, OPT)置換算法所選擇的被淘汰頁(yè)面將是以后永不使用的,或者是在最長(zhǎng)時(shí)間內(nèi)不再被訪問(wèn)的頁(yè)面,這樣可以保證獲得最低的缺頁(yè)率。但由于人們目前無(wú)法預(yù)知進(jìn)程在內(nèi)存下的若千頁(yè)面中哪個(gè)是未來(lái)最長(zhǎng)時(shí)間內(nèi)不再被訪問(wèn)的,因而該算法無(wú)法實(shí)現(xiàn)。一般作為衡量其他置換算法的方法。
- FIFO(First In First Out) 頁(yè)面置換算法(先進(jìn)先出頁(yè)面置換算法) : 總是淘汰最先進(jìn)入內(nèi)存的頁(yè)面,即選擇在內(nèi)存中駐留時(shí)間最久的頁(yè)面進(jìn)行淘汰。
- LRU (Least Currently Used)頁(yè)面置換算法(最近最久未使用頁(yè)面置換算法) :LRU算法賦予每個(gè)頁(yè)面一個(gè)訪問(wèn)字段,用來(lái)記錄一個(gè)頁(yè)面自上次被訪問(wèn)以來(lái)所經(jīng)歷的時(shí)間 T,當(dāng)須淘汰一個(gè)頁(yè)面時(shí),選擇現(xiàn)有頁(yè)面中其 T 值最大的,即最近最久未使用的頁(yè)面予以淘汰。
- LFU (Least Frequently Used)頁(yè)面置換算法(最少使用頁(yè)面置換算法) : 該置換算法選擇在之前時(shí)期使用最少的頁(yè)面作為淘汰頁(yè)。
5、StringBuilder.append(“xxx”); 后創(chuàng)建新對(duì)象嗎?
答案是,沒(méi)有創(chuàng)建新對(duì)象:
因?yàn)?StringBuilder
,和 String
不同,它的 char[]
數(shù)組沒(méi)有被 final
修飾,所以它可以在添加新char
字符時(shí),根據(jù)字符數(shù)組容量,進(jìn)行動(dòng)態(tài)擴(kuò)容,而不需要新創(chuàng)建一個(gè) StringBuilder
對(duì)象!
如圖所示:
StringBuilder.append()
方法如下代碼所示:
// java.lang.StringBuilder 類(lèi)中 @Override public StringBuilder append(String str) { // 調(diào)用父類(lèi) AbstractStringBuilder 的append(String str) 方法 super.append(str); return this; } // java.lang.AbstractStringBuilder 類(lèi)中(有興趣可以自己點(diǎn)進(jìn)去閱讀該類(lèi)的源碼,還是很有收獲的,這里只作簡(jiǎn)述?。? public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); // 其成員屬性value[]數(shù)組擴(kuò)容,類(lèi)似于ArrayList 的擴(kuò)容 // 擴(kuò)容算法:int newCapacity = (value.length << 1) + 2; // 注意容量有上限:MAX_ARRAY_SIZE ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
注: 同理,StringBuffer
也是一樣的!
6、哈希沖突的幾種解決方案,各個(gè)優(yōu)缺點(diǎn)?
6.1、開(kāi)放定址法
這種方法也稱再散列法,其基本思想是:當(dāng)關(guān)鍵字 key 的哈希地址 p=H(key)
出現(xiàn)沖突時(shí),以 p 為基礎(chǔ),產(chǎn)生另一個(gè)哈希地址 p1,如果 p1 仍然沖突,再以 p 為基礎(chǔ),產(chǎn)生另一個(gè)哈希地址 p2,…,直到找出一個(gè)不沖突的哈希地址pi ,將相應(yīng)元素存入其中。這種方法有一個(gè)通用的再散列函數(shù)形式:
Hi=(H(key)+di)% m i=1,2,…,n
其中 H(key)
為哈希函數(shù),m
為表長(zhǎng),di
稱為增量序列。增量序列的取值方式不同,相應(yīng)的再散列方式也不同。主要有以下三種:
① 線性探測(cè)再散列
dii = 1,2,3,…,m-1
這種方法的特點(diǎn)是:沖突發(fā)生時(shí),順序查看表中下一單元,直到找出一個(gè)空單元或查遍全表。ThreadLocal 解決 hash 沖突就采用這種方法!
② 二次探測(cè)再散列
di = 12,-12,22,-22,…,k2,-k2 ( k<=m/2 )(2為2次方)
這種方法的特點(diǎn)是:沖突發(fā)生時(shí),在表的左右進(jìn)行跳躍式探測(cè),比較靈活。
③ 偽隨機(jī)探測(cè)再散列
di = 偽隨機(jī)數(shù)序列
具體實(shí)現(xiàn)時(shí),應(yīng)建立一個(gè)偽隨機(jī)數(shù)發(fā)生器,(如i=(i+p) % m),并給定一個(gè)隨機(jī)數(shù)做起點(diǎn)。
例如,已知哈希表長(zhǎng)度m=11,哈希函數(shù)為:H(key)= key % 11,則 H(47)=3,H(26)=4,H(60)=5,假設(shè)下一個(gè)關(guān)鍵字為69,則H(69)=3,與47沖突。
如果用線性探測(cè)再散列處理沖突,下一個(gè)哈希地址為 H1=(3 + 1)% 11 = 4,仍然沖突,再找下一個(gè)哈希地址為 H2=(3 + 2)% 11 = 5,還是沖突,繼續(xù)找下一個(gè)哈希地址為 H3=(3 + 3)% 11 = 6,此時(shí)不再?zèng)_突,將69填入5號(hào)單元。
如果用二次探測(cè)再散列處理沖突,下一個(gè)哈希地址為 H1=(3 + 12)% 11 = 4,仍然沖突,再找下一個(gè)哈希地址為 H2=(3 - 12)% 11 = 2,此時(shí)不再?zèng)_突,將69填入2號(hào)單元。
如果用偽隨機(jī)探測(cè)再散列處理沖突,且偽隨機(jī)數(shù)序列為:2,5,9,………,則下一個(gè)哈希地址為 H1=(3 + 2)% 11 = 5,仍然沖突,再找下一個(gè)哈希地址為 H2=(3 + 5)% 11 = 8,此時(shí)不再?zèng)_突,將69填入8號(hào)單元。
6.2、再哈希法(再散列法)
這種方法是同時(shí)構(gòu)造多個(gè)不同的哈希函數(shù):
Hi=RH1(key) i=1,2,…,k
當(dāng)哈希地址Hi=RH1(key)
發(fā)生沖突時(shí),再計(jì)算 Hi=RH2(key)……,
直到?jīng)_突不再產(chǎn)生。這種方法不易產(chǎn)生聚集,但增加了計(jì)算時(shí)間。
6.3、鏈地址法(拉鏈法)
這種方法的基本思想是將所有哈希地址為i的元素構(gòu)成一個(gè)稱為同義詞鏈的單鏈表,并將單鏈表的頭指針存在哈希表的第i個(gè)單元中,因而查找、插入和刪除主要在同義詞鏈中進(jìn)行。鏈地址法適用于經(jīng)常進(jìn)行插入和刪除的情況。
HashMap 解決 hash 沖突就采用的這種方式!
7、使用java如何對(duì)一個(gè)大的文本文件內(nèi)容進(jìn)行去重?
一般可能會(huì)想到一次將文本內(nèi)容讀取到內(nèi)存中,用 HashSet 對(duì)內(nèi)容去重,但是很不幸這個(gè)過(guò)程 jvm 會(huì)內(nèi)存溢出,無(wú)奈,只能另想辦法,首先將這個(gè)大文件中的內(nèi)容讀取出來(lái),對(duì)每行 String 的 hashCode 取模取正整數(shù),可用取模結(jié)果作為文件名,將相同模數(shù)的行寫(xiě)入同一個(gè)文件,再單獨(dú)對(duì)每個(gè)小文件進(jìn)行去重,最后再合并。
8、MySQL如何優(yōu)化慢查詢?
首先可以通過(guò) explain
命令查看 SQL 執(zhí)行狀態(tài),如果是沒(méi)有加索引,則需要添加索引后再進(jìn)行查詢。如果已經(jīng)加了索引,但是表中數(shù)據(jù)量過(guò)多,這時(shí)候可以考慮水平分表,或者通過(guò) limit 限制一次查詢的記錄總數(shù)。如果已經(jīng)加了索引,表中數(shù)據(jù)量較少,但是表字段多,大字段檢索效率慢,這時(shí)候可以考慮垂直分表!
總結(jié)
本篇文章的內(nèi)容就到這了,希望大家可以多多關(guān)注腳本之家的其他精彩內(nèi)容!
相關(guān)文章
EasyExcel實(shí)現(xiàn)讀寫(xiě)Excel文件的示例代碼
EasyExcel是阿里巴巴開(kāi)源的一個(gè)excel處理框架,以使用簡(jiǎn)單、節(jié)省內(nèi)存著稱。它可以在盡可能節(jié)約內(nèi)存的情況下支持讀寫(xiě)百M(fèi)的Excel,所以本文就將利用它實(shí)現(xiàn)讀寫(xiě)Excel文件,感興趣的可以了解一下2022-08-08springboot+Vue實(shí)現(xiàn)分頁(yè)的示例代碼
本文主要介紹了springboot+Vue實(shí)現(xiàn)分頁(yè)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06Spring Cloud Sleuth整合zipkin過(guò)程解析
這篇文章主要介紹了Spring Cloud Sleuth整合zipkin過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12關(guān)于nacos無(wú)法正常下線問(wèn)題記錄
這篇文章主要介紹了關(guān)于nacos無(wú)法正常下線問(wèn)題記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Java?SpringMVC實(shí)現(xiàn)自定義攔截器
這篇文章主要為大家詳細(xì)介紹了SpringMVC實(shí)現(xiàn)自定義攔截器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03java寫(xiě)入zip文件后無(wú)法進(jìn)行刪除的問(wèn)題及解決
這篇文章主要介紹了java寫(xiě)入zip文件后無(wú)法進(jìn)行刪除的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06idea 無(wú)法創(chuàng)建Scala class 選項(xiàng)的原因分析及解決辦法匯總
這篇文章主要介紹了idea 無(wú)法創(chuàng)建Scala class 選項(xiàng)的解決辦法匯總,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Java BigDecimal類(lèi)的使用和注意事項(xiàng)
這篇文章主要講解Java中BigDecimal類(lèi)的用法,并簡(jiǎn)單介紹一些注意事項(xiàng),希望能給大家做一個(gè)參考。2016-06-06eclipse實(shí)現(xiàn)可認(rèn)證的DH密鑰交換協(xié)議
這篇文章主要介紹了eclipse實(shí)現(xiàn)可認(rèn)證的DH密鑰交換協(xié)議,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06解決Java中OutOfMemoryError的問(wèn)題
這篇文章主要介紹了解決Java中OutOfMemoryError的三種方法,需要的朋友可以參考下2015-09-09