Java開發中的問題

1.倒排索引

倒排索引(Inverted Index):倒排索引是搜索引擎數據存儲的結構與形式,是實現單詞-文檔矩陣的一種具體存儲形式。通過倒排索引,我們可以根據單詞快速的獲取包含這個單詞的文檔列表。倒排索引主要由兩個部分組成:單詞詞典和倒排文件。
2.講講redis裏面的哈希表? 

在redis中,hash數據類型存儲的數據與mysql數據庫中存儲一條記錄極爲相似,是一個string類型的field和value的映射表,它特別適合用於存儲對象,但字段值只能是字符串,不支持其他類型。
在hash類型中,一個key可以對應多個多個field,一個field對應一個value。將一個對象存儲爲hash類型的好處之一:較於每個字段都單獨存儲成string類型來說,更能節約內存。
每一個哈希可以存儲超過2的32次方-1個字段-值對。應用場景:可以用來存儲用戶的基本信息等。
3.happen-before的規則?

(1)程序順序規則:一個線程中的每個操作,happens-before於該線程中的任意後續操作。
(2)監視器鎖規則:對一個鎖的解鎖,happens-before於隨後對這個鎖的加鎖。
(3)volatile變量規則:對一個volatile域的寫,happens-before於任意後續對這個volatile域的讀。
(4)傳遞性:如果A happens-before B,且B happens-before C,那麼A happens-before C。
(5)start()規則:如果線程A執行操作ThreadB.start()(啓動線程B),那麼A線程的ThreadB.start()操作happens-before於線程B中的任意操作。
(6)Join()規則:如果線程A執行操作ThreadB.join()併成功返回,那麼線程B中的任意操作happens-before於線程A從ThreadB.join()操作成功返回。
(7)程序中斷規則:對線程interrupted()方法的調用先行於被中斷線程的代碼檢測到中斷時間的發生。
(8)對象finalize規則:一個對象的初始化完成(構造函數執行結束)先行於發生它的finalize()方法的開始。
4.volatile修飾符,synchronize鎖

(1)、volatile保證共享變量的可見性,比Synchronized的使用和執行成本更低,因爲它不會引起線程上下文的切換和調度;
(2)、一個字段被聲明城volatile類型,java的線程內存模型確保所有線程看到這個變量的值是一致的;
(3)、java中的每一個對象都可以作爲鎖,任何對象都有一個monitor與之關聯,當monitor被持有後,其對象處於鎖定狀態;
(4)、synchronized用的鎖存儲在java的對象頭裏;
(5)、javase 6 爲了減少獲得鎖和釋放鎖帶來的性能消耗,引入了偏向鎖和輕量級鎖,以及鎖的存儲結構及升級過程
5.java單例模式的實現,懶漢、餓漢?

懶漢式線程不安全,需要加上同步鎖,同步鎖影響了程序執行效率。
餓漢式天生線程安全,類加載的時候初始化一次對象,效率比懶漢式高。餓漢式:
設計思想:構造方法私有,這樣就保證了在外部是無法實例化對象的;然後先在內部定義一個靜態常量對象,再寫一個static方法來返回這個對象,這樣就保證是前後一個對象了。
區別 :餓漢式是先定義實例的 而懶漢式是先定義引用,當懶漢式第一次調用getInstance的時候 進行對象實例化操作;當然這裏考慮到多併發的情況,多個線程同時調用這個方法的時候,會出現問題,所以加上同步鎖 synchronized 來保證同一時刻只有一個線程進入方法。
6.進程與線程的區別,多進程和多線程的區別?

(1).概念 
線程:是程序執行流的最小單元,是系統獨立調度和分配CPU(獨立運行)的基本單位。 
進程:是資源分配的基本單位。一個進程包括多個線程。 

多線程:同一時刻執行多個線程。用瀏覽器一邊下載,一邊聽歌,一邊看視頻,一邊看網頁。。。 
多進程:同時執行多個程序。如,同事運行YY,QQ,以及各種瀏覽器。

併發:當有多個線程在操作時,如果系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它只能把CPU運行時間劃分成若干個時間段,再將時間 段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處於掛起狀。這種方式我們稱之爲併發(Concurrent)。
並行:當系統有一個以上CPU時,則線程的操作有可能非併發。當一個CPU執行一個線程時,另一個CPU可以執行另一個線程,兩個線程互不搶佔CPU資源,可以同時進行,這種方式我們稱之爲並行(Parallel)。
(2).區別: 
1).線程與資源分配無關,它屬於某一個進程,並與進程內的其他線程一起共享進程的資源。 
2).每個進程都有自己一套獨立的資源(數據),供其內的所有線程共享。 
3).不論是大小,開銷線程要更“輕量級” 
4).一個進程內的線程通信比進程之間的通信更快速,有效。(因爲共享變量)
7.HashMap原理,爲什麼用紅黑樹,紅黑樹的特點?

HashMap中的值都是key,value對吧,其實這裏的存儲與上面的很像,key會被映射成數據所在的地址,而value就在以這個地址爲頭的鏈表中,這種數據結構在獲取的時候就很快。但這裏存在的問題就是如果hash桶較小,數據量較大,就會導致鏈表非常的長。比如說上面的長爲11的空間我要放1000個數,無論Hash函數如何精妙,後面跟的鏈表都會非常的長,這樣Hash表的優勢就不復存在了,反而傾向於線性檢索。好了,紅黑樹閃亮登場。
紅黑樹也叫自平衡二叉查找樹或者平衡二叉B樹,
時間複雜度爲O(log n)
高度h <= log2(n+1)
性質1. 節點是紅色或黑色。  性質2. 根節點是黑色。  性質3 每個葉節點(NIL節點,空節點)是黑色的。
性質4 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
性質5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
8.快排時間空間複雜度,最好最壞的情況,優化方案?

平均情況和最好的情況的空間複雜度:O(log2n)
最壞情況的空間複雜度:O(n)
優化1:當待排序序列的長度分割到一定大小後,使用插入排序
優化2:在一次分割結束後,可以把與Key相等的元素聚在一起,繼續下次分割時,不用再對與key相等元素分割
優化3:優化遞歸操作
9.TCP的擁塞控制,具體過程是怎麼樣的?UDP有擁塞控制嗎?如何解決?

TCP 擁塞控制的目標是最大化利用網絡上瓶頸鍊路的帶寬。
TCP 全稱爲傳輸控制協議。這種協議可以提供面向連接的、可靠的、點到點的通信,所謂可靠,在於 TCP 建立連接時雙方需要互相確認,類似打電話,在專業術語中稱爲 3 次握手。
UDP 全稱爲用戶數據報協議,它可以提供非連接的不可靠的點到多點的通信,所謂不可靠,在於 UDP 每一次發送數據需要綁定 IP 和端口號,但是對於已經發送出去的數據來說並不去確認,也不需要類似 TCP 的三次握手的過程,由於沒有了這個過程,所以其傳輸效率較之 TCP 來說要高許多。
(1)、在傳輸層可採用:重傳策略、亂序緩存策略、確認策略、流控制策略和確定超時策略。
(2)、在網絡層可採用:子網內部的虛電路與數據報策略、分組排隊和服務策略、分組丟棄策略、路由算法和分組生存管理。
(3)、在數據鏈路層可採用:重傳策略、亂序緩存策略、確認策略和流控制策略
Reno
Reno 被許多教材(例如:《計算機網絡——自頂向下的方法》)所介紹,適用於低延時、低帶寬的網絡,它將擁塞控制的過程分爲四個階段:慢啓動、擁塞避免、快重傳和快恢復。
BBR 算法不將出現丟包或時延增加作爲擁塞的信號,而是認爲當網絡上的數據包總量大於瓶頸鍊路帶寬和時延的乘積時纔出現了擁塞,所以 BBR 也稱爲基於擁塞的擁塞控制算法(Congestion-Based Congestion Control),其適用網絡爲高帶寬、高時延、有一定丟包率的長肥網絡,可以有效降低傳輸時延,並保證較高的吞吐量。
目前有非常多的 TCP 的擁塞控制協議,例如:
基於丟包的擁塞控制:將丟包視爲出現擁塞,採取緩慢探測的方式,逐漸增大擁塞窗口,當出現丟包時,將擁塞窗口減小,如 Reno、Cubic 等。
基於時延的擁塞控制:將時延增加視爲出現擁塞,延時增加時增大擁塞窗口,延時減小時減小擁塞窗口,如 Vegas、FastTCP 等。
基於鏈路容量的擁塞控制:實時測量網絡帶寬和時延,認爲網絡上報文總量大於帶寬時延乘積時出現了擁塞,如 BBR。
基於學習的擁塞控制:沒有特定的擁塞信號,而是藉助評價函數,基於訓練數據,使用機器學習的方法形成一個控制策略,如 Remy。
從使用的角度來說,我們應該根據自身的實際情況來選擇自己機器的擁塞控制協議(而不是跟風 BBR),同時對於擁塞控制原理的掌握(尤其是掌握 Reno 的控制機理和幾個重要階段)可以加強對於網絡發包機制的瞭解,在排查問題或面對面試的時候有更好的表現。
此外,擁塞控制只是 TCP 相關考點中的一個部分,還有許多的常見的高頻考點可以順帶去看看,例如:
OSI 模型是什麼?
有哪些協議是基於 TCP 的,哪些是基於 UDP 的?
爲什麼建立連接需要三次握手,而斷開連接需要四次握手?
TCP首部長度,有哪些字段?
三次握手過程中有哪些不安全性?
補充:UDP主要特點:傳輸的是用戶數據報協議。
(1).UDP是無連接的,即發送數據之前不需要建立連接。
(2).UDP 使用盡最大努力交付,即不保證可靠交付,同時也不使用擁塞控制。
(3).UDP是面向報文的。UDP沒有擁塞控制,很適合多媒體通信的要求。
(4).UDP支持一對一、一對多、多對一和多對多的交互通信。
(5).UDP的首部開銷小,只有 8個字節。
發送方 UDP對應用程序交下來的報文,在添加首部後就向下交付 IP層。UDP  對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界。應用層交給 UDP多長的報文,UDP就照樣發送,即一次發送一個報文。接收方 UDP對 IP  層交上來的 UDP 用戶數據報,在去除首部後就原封不動地交付上層的應用進程,一次交付一個完整的報文。
應用程序必須選擇合適大小的報文。
10.講講了解的垃圾回收算法和回收器,什麼時候執行STOP THE WORLD?

目前所有的新生代gc都是需要STW的:Serial:單線程STW,複製算法
ParNew:多線程並行STW,複製算法
Parallel Scavange:多線程並行STW,吞吐量優先,複製算法
Serial old:標記-整理
parallel old:標記-整理
cms:標記清除算法
垃圾回收算法:
引用計數:一個對象被引用計數器加一,取消引用計數器減一,引用計數器爲0才能被回收。優點:簡單。缺點:不能解決循環引用的問題,比如A引用B,B引用A,但是這兩個對象沒有被其他任何對象引用,屬於垃圾對象,卻不能回收;每次引用都會附件一個加減法,影響性能。
標記清除法:分爲兩個階段:標記階段和清除階段。標記階段通過根節點標記所有可達對象,清除階段清除所有不可達對象。缺點:因爲清除不可達對象之後剩餘的內存不連續,會產生大量內存碎片,不利於大對象的分配。
複製算法:將內存空間分成相同的兩塊,每次只是用其中的一塊,垃圾回收時,將正在使用的內存中的存活對象複製到另外一塊空間,然後清除正在使用的內存空間中的所有對象,這種回收算法適用於新生代垃圾回收。優點:垃圾回收對象比較多時需要複製的對象恨少,性能較好;不會存在內存碎片。缺點:將系統內存摺半。
標記壓縮算法:是一種老年代回收算法,在標記清除的基礎上做了一些優化,首先從根節點開始標記所有不可達的對象,然後將所有可達的對象移動到內存的一端,最後清除所有不可達的對象。優點:不用將內存分爲兩塊;不會產生內存碎片。
分代算法:新生代使用複製算法,老生帶使用標記清除算法或者標記壓縮算法。幾乎所有的垃圾回收期都區分新生代和老生帶。
分區算法:將整個堆空間分成很多個連續的不同的小空間,每個小空間獨立使用,獨立回收。爲了更好的控制gc停頓時間,可以根據目標停頓時間合理地回收若干個小區間,而不是整個堆空間,從而減少gc停頓時間。
11.瞭解Go語言嗎?

2007年,受夠了C++煎熬的Google首席軟件工程師Rob Pike糾集Robert Griesemer和Ken Thompson兩位牛人,決定創造一種新語言來取代C++, 這就是Golang。出現在21世紀的GO語言,雖然不能如願對C++取而代之,但是其近C的執行性能和近解析型語言的開發效率以及近乎於完美的編譯速度,已經風靡全球。特別是在雲項目中,大部分都使用了Golang來開發,不得不說,Golang早已深入人心。而對於一個沒有歷史負擔的新項目,Golang或許就是個不二的選擇。

被稱爲GO語言之父的Rob Pike說,你是否同意GO語言,取決於你是認可少就是多,還是少就是少(Less is more or less is less)。Rob Pike以一種非常樸素的方式,概括了GO語言的整個設計哲學–將簡單、實用體現得淋漓盡致。

很多人將GO語言稱爲21世紀的C語言,因爲GO不僅擁有C的簡潔和性能,而且還很好的提供了21世紀互聯網環境下服務端開發的各種實用特性,讓開發者在語言級別就可以方便的得到自己想要的東西。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章