摘要:由于線程被無限期地阻塞,因此程序不可能正常終止。因而,紅黑樹是相對是接近平衡的二叉樹。旋轉的目的是讓樹保持紅黑樹的特性。三次握手和四次揮手面試常客為了準確無誤地把數據送達目標處,協議采用了三次握手策略。
由于作者面試過程中高度緊張,本文中只列出了自己還記得的部分題目。
經歷了漫長一個月的等待,終于在前幾天通過面試官獲悉已被螞蟻金服錄取,這期間的焦慮、痛苦自不必說,知道被錄取的那一刻,一整年的陰霾都一掃而空了。
筆者面的是阿里的Java研發工程師崗,面試流程是3輪技術面+1輪hr面。
1 意外的一面一面的時候大概是3月12號,面完等了差不多半個月才突然接到二面面試官的電話。一面可能是簡歷面,所以問題比較簡單。
ArrayList和LinkedList區別1. 是否保證線程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保證線程安全;
2. 底層數據結構: Arraylist 底層使用的是Object數組;LinkedList 底層使用的是雙向鏈表數據結構(JDK1.6之前為循環鏈表,JDK1.7取消了循環。注意雙向鏈表和雙向循環鏈表的區別,下面有介紹到!)
3. 插入和刪除是否受元素位置的影響: ① ArrayList 采用數組存儲,所以插入和刪除元素的時間復雜度受元素位置的影響。 比如:執行add(E e)方法的時候, ArrayList 會默認在將指定的元素追加到此列表的末尾,這種情況時間復雜度就是O(1)。但是如果要在指定位置 i 插入和刪除元素的話(add(int index, E element))時間復雜度就為 O(n-i)。因為在進行上述操作的時候集合中第 i 和第 i 個元素之后的(n-i)個元素都要執行向后位/向前移一位的操作。 ② LinkedList 采用鏈表存儲,所以插入,刪除元素時間復雜度不受元素位置的影響,都是近似 O(1)而數組為近似 O(n)。
4. 是否支持快速隨機訪問: LinkedList 不支持高效的隨機元素訪問,而 ArrayList 支持。快速隨機訪問就是通過元素的序號快速獲取元素對象(對應于get(int index)方法)。
5. 內存空間占用: ArrayList的空 間浪費主要體現在在list列表的結尾會預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗比ArrayList更多的空間(因為要存放直接后繼和直接前驅以及數據)。
什么情況會造成內存泄漏在Java中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點:
這些對象是可達的,即在有向圖中,存在通路可以與其相連;
這些對象是無用的,即程序以后不會再使用這些對象。
如果對象滿足這兩個條件,這些對象就可以判定為Java中的內存泄漏,這些對象不會被GC所回收,然而它卻占用內存。
什么是線程死鎖");多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由于線程被無限期地阻塞,因此程序不可能正常終止。
如下圖所示,線程 A 持有資源 2,線程 B 持有資源 1,他們同時都想申請對方的資源,所以這兩個線程就會互相等待而進入死鎖狀態。
線程死鎖示意圖
下面通過一個例子來說明線程死鎖,代碼模擬了上圖的死鎖的情況 (代碼來源于《并發編程之美》):
public class DeadLockDemo { private static Object resource1 = new Object();//資源 1 private static Object resource2 = new Object();//資源 2 public static void main(String[] args) { new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "線程 1").start(); new Thread(() -> { synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource1"); synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); } } }, "線程 2").start(); }}
Output
Thread[線程 1,5,main]get resource1Thread[線程 2,5,main]get resource2Thread[線程 1,5,main]waiting get resource2Thread[線程 2,5,main]waiting get resource1
線程 A 通過 synchronized (resource1) 獲得 resource1 的監視器鎖,然后通過Thread.sleep(1000);讓線程 A 休眠 1s 為的是讓線程 B 得到執行然后獲取到 resource2 的監視器鎖。線程 A 和線程 B 休眠結束了都開始企圖請求獲取對方的資源,然后這兩個線程就會陷入互相等待的狀態,這也就產生了死鎖。上面的例子符合產生死鎖的四個必要條件。
學過操作系統的朋友都知道產生死鎖必須具備以下四個條件:
互斥條件:該資源任意一個時刻只由一個線程占用。
請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
不剝奪條件:線程已獲得的資源在末使用完之前不能被其他線程強行剝奪,只有自己使用完畢后才釋放資源。
循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
我們只要破壞產生死鎖的四個條件中的其中一個就可以了。
破壞互斥條件
這個條件我們沒有辦法破壞,因為我們用鎖本來就是想讓他們互斥的(臨界資源需要互斥訪問)。
破壞請求與保持條件
一次性申請所有的資源。
破壞不剝奪條件
占用部分資源的線程進一步申請其他資源時,如果申請不到,可以主動釋放它占有的資源。
破壞循環等待條件
靠按序申請資源來預防。按某一順序申請資源,釋放資源則反序釋放。破壞循環等待條件。
我們對線程 2 的代碼修改成下面這樣就不會產生死鎖了。
new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "線程 2").start();
Output
Thread[線程 1,5,main]get resource1Thread[線程 1,5,main]waiting get resource2Thread[線程 1,5,main]get resource2Thread[線程 2,5,main]get resource1Thread[線程 2,5,main]waiting get resource2Thread[線程 2,5,main]get resource2Process finished with exit code 0
我們分析一下上面的代碼為什么避免了死鎖的發生");
線程 1 首先獲得到 resource1 的監視器鎖,這時候線程 2 就獲取不到了。然后線程 1 再去獲取 resource2 的監視器鎖,可以獲取到。然后線程 1 釋放了對 resource1、resource2 的監視器鎖的占用,線程 2 獲取到就可以執行了。這樣就破壞了破壞循環等待條件,因此避免了死鎖。
紅黑樹是什么");紅黑樹(Red-Black Tree,簡稱R-B Tree),它一種特殊的二叉查找樹。紅黑樹是特殊的二叉查找樹,意味著它滿足二叉查找樹的特征:任意一個節點所包含的鍵值,大于等于左孩子的鍵值,小于等于右孩子的鍵值。除了具備該特性之外,紅黑樹還包括許多額外的信息。
紅黑樹的每個節點上都有存儲位表示節點的顏色,顏色是紅(Red)或黑(Black)。紅黑樹的特性:
每個節點或者是黑色,或者是紅色。
根節點是黑色。
每個葉子節點是黑色。
如果一個節點是紅色的,則它的子節點必須是黑色的。
從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。
關于它的特性,需要注意的是:
第一,特性(3)中的葉子節點,是只為空(NIL或null)的節點。
第二,特性(5),確保沒有一條路徑會比其他路徑長出倆倍。因而,紅黑樹是相對是接近平衡的二叉樹。
img
具體實現代碼這里不貼了,要實現起來,需要包含的基本操作是添加、刪除和旋轉。在對紅黑樹進行添加或刪除后,會用到旋轉方法。旋轉的目的是讓樹保持紅黑樹的特性。旋轉包括兩種:左旋 和 右旋。
紅黑樹的應用比較廣泛,主要是用它來存儲有序的數據,它的查找、插入和刪除操作的時間復雜度是O(lgn)。
TCP 三次握手和四次揮手(面試常客)為了準確無誤地把數據送達目標處,TCP協議采用了三次握手策略。
漫畫圖解:
圖片來源:《圖解HTTP》
TCP三次握手
簡單示意圖:
TCP三次握手
客戶端–發送帶有 SYN 標志的數據包–一次握手–服務端
服務端–發送帶有 SYN/ACK 標志的數據包–二次握手–客戶端
客戶端–發送帶有帶有 ACK 標志的數據包–三次握手–服務端
三次握手的目的是建立可靠的通信信道,說到通訊,簡單來說就是數據的發送與接收,而三次握手最主要的目的就是雙方確認自己與對方的發送與接收是正常的。
第一次握手:Client 什么都不能確認;Server 確認了對方發送正常
第二次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:自己接收正常,對方發送正常
第三次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:自己發送、接收正常,對方發送、接收正常
所以三次握手就能確認雙發收發功能都正常,缺一不可。
接收端傳回發送端所發送的 SYN 是為了告訴發送端,我接收到的信息確實就是你所發送的信號了。
SYN 是 TCP/IP 建立連接時使用的握手信號。在客戶機和服務器之間建立正常的 TCP 網絡連接時,客戶機首先發出一個 SYN 消息,服務器使用 SYN-ACK 應答表示接收到了這個消息,最后客戶機再以 ACK(Acknowledgement[漢譯:確認字符 ,在數據通信傳輸中,接收站發給發送站的一種傳輸控制字符。它表示確認發來的數據已經接受無誤。 ])消息響應。這樣在客戶機和服務器之間才能建立起可靠的TCP連接,數據才可以在客戶機和服務器之間傳遞。
雙方通信無誤必須是兩者互相發送信息都無誤。傳了 SYN,證明發送方到接收方的通道沒有問題,但是接收方到發送方的通道還需要 ACK 信號來進行驗證。
TCP四次揮手
斷開一個 TCP 連接則需要“四次揮手”:
客戶端-發送一個 FIN,用來關閉客戶端到服務器的數據傳送
服務器-收到這個 FIN,它發回一 個 ACK,確認序號為收到的序號加1 。和 SYN 一樣,一個 FIN 將占用一個序號
服務器-關閉與客戶端的連接,發送一個FIN給客戶端
客戶端-發回 ACK 報文確認,并將確認序號設置為收到序號加1
任何一方都可以在數據傳送結束后發出連接釋放的通知,待對方確認后進入半關閉狀態。當另一方也沒有數據再發送的時候,則發出連接釋放通知,對方確認后就完全關閉了TCP連接。
舉個例子:A 和 B 打電話,通話即將結束后,A 說“我沒啥要說的了”,B回答“我知道了”,但是 B 可能還會有要說的話,A 不能要求 B 跟著自己的節奏結束通話,于是 B 可能又巴拉巴拉說了一通,最后 B 說“我說完了”,A 回答“知道了”,這樣通話才算結束。
上面講的比較概括,推薦一篇講的比較細致的文章:https://blog.csdn.net/qzcsu/article/details/72861891
突然的二面一面的時候大概是3月12號,面完等了差不多半個月才突然接到二面面試官的電話。
介紹項目 Storm怎么保證一致性Storm是一個分布式的流處理系統,利用anchor和ack機制保證所有tuple都被成功處理。如果tuple出錯,則可以被重傳,但是如何保證出錯的tuple只被處理一次呢?Storm提供了一套事務性組件Transaction Topology,用來解決這個問題。
Transactional Topology目前已經不再維護,由Trident來實現事務性topology,但是原理相同。
參考:https://dwz.cn/8bXRPexB
說一下 HashMap 以及它是否線程安全HashMap 基于哈希表的 Map 接口的實現。HashMap 中,null 可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。HashMap 中 hash 數組的默認大小是16,而且一定是2的指數。Hashtable、HashMap都使用了 Iterator。而由于歷史原因,Hashtable還使用了Enumeration的方式 。HashMap 實現 Iterator,支持fast-fail。
哈希表是由數組+鏈表組成的,它是通過把key值進行hash來定位對象的,這樣可以提供比線性存儲更好的性能。
img
?
HashMap不是線程安全的。
十億條淘寶購買記錄,怎么獲取出現最多的前十個這是一道典型的有限內存的海量數據處理的題目。一般這類題目的解答無非是以下幾種:
分治,hash映射,堆排序,雙層桶劃分,Bloom Filter,bitmap,數據庫索引,mapreduce等。
具體情形都有很多不同的方案。這類題目可以到網上搜索一下,了解下套路,后面就基本都會了。
平時有沒有用linux系統,怎么查看某個進程ps aux|grep java 查看java進程ps aux 查看所有進程ps –ef|grep tomcat 查看所有有關tomcat的進程ps -ef|grep --color java 高亮要查詢的關鍵字kill -9 19979 終止線程號位19979的進程
說一下 Innodb 和 MySIAM 的區別MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,但是不提供事務支持,而InnoDB提供事務支持以及外部鍵等高級數據庫功能。
InnoDB不支持FULLTEXT類型的索引。
InnoDB 中不保存表的具體行數,也就是說,執行select count(
) from table時,InnoDB要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出保存好的行數即可。注意的是,當count(
)語句包含 where條件時,兩種表的操作是一樣的。對于AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中,可以和其他字段一起建立聯合索引。
DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除。
LOAD TABLE FROM MASTER操作對InnoDB是不起作用的,解決方法是首先把InnoDB表改成MyISAM表,導入數據后再改成InnoDB表,但是對于使用的額外的InnoDB特性(例如外鍵)的表不適用。
說一下jvm內存模型,介紹一下你了解的垃圾收集器其實并沒有 jvm 內存模型的概念。應該是 Java 內存模型或者 jvm 內存結構,這里面試者一定要聽清楚問的是哪個,再回答。
可以參考:
可能是把Java內存區域講的最清楚的一篇文章
搞定 JVM 垃圾回收就是這么簡單
你說你是大數據方向的,了解哪些大數據框架作者回答了一些zookeeper、storm、HDFS、Hbase等
其他問題100個有序的整型,如何打亂順序?
如何設計一個可靠的UDP協議?
二面大概就是這些,其中storm一致性這個問題被面試官懷疑了一下,就有點緊張,其實沒答錯,所以還是要對知識掌握得更明確才行。
準備充足的三面清明節的時候例外地沒有回家掃墓,因為知道自己的弱項是操作系統和海量數據題這塊,所以想著惡補這方面的知識,不過之后的面試意外的并沒有問到這方面的內容。
介紹項目項目介紹完之后沒問太多
介紹一下HashMapHashMap真的是面試高頻題,多次面試都問到了,一定要掌握。
介紹一下并發這里可以把整個并發的體系都說下,包括volatile、synchronized、lock、樂觀悲觀鎖、鎖膨脹、鎖降級、線程池等
銀行賬戶讀寫怎么做我說了讀寫鎖以及可能出現死鎖問題
說一下關系型數據庫和非關系型數據庫的區別非關系型數據庫的優勢:
性能:NOSQL是基于鍵值對的,可以想象成表中的主鍵和值的對應關系,而且不需要經過SQL層的解析,所以性能非常高
可擴展性:同樣也是因為基于鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。
使用場景:日志、埋點、論壇、博客等
關系型數據庫的優勢:
復雜查詢:可以用SQL語句方便的在一個表以及多個表之間做非常復雜的數據查詢
事務支持:使得對于安全性能很高的數據訪問要求得以實現。
使用場景:所有有邏輯關系的數據存儲
如何訪問鏈表中間節點對于這個問題,我們首先能夠想到的就是先遍歷一遍整個的鏈表,然后計算出鏈表的長度,進而遍歷第二遍找出中間位置的數據。這種方式非常簡單。
若題目要求只能遍歷一次鏈表,那又當如何解決問題?
可以采取建立兩個指針,一個指針一次遍歷兩個節點,另一個節點一次遍歷一個節點,當快指針遍歷到空節點時,慢指針指向的位置為鏈表的中間位置,這種解決問題的方法稱為快慢指針方法。
說下進程間通信,以及各自的區別進程間通信是指在不同進程之間傳播或交換信息。方式通常有管道(包括無名管道和命名管道)、消息隊列、信號量、共享存儲、Socket、Streams等。
訪問淘寶網頁的一個具體流程,從獲取ip地址,到怎么返回相關內容先通過DNS解析到服務器地址,然后反向代理、負載均衡服務器等,尋找集群中的一臺機器來真正執行你的請求。還可以介紹CDN、頁面緩存、Cookie以及session等。
這個過程還包括三次握手、HTTP request中包含哪些內容,狀態碼等,還有OSI七層分層可以介紹。
服務器接到請求后,會執行業務邏輯,執行過程中可以按照MVC來分別介紹。
服務處理過程中是否調用其他RPC服務或者異步消息,這個過程包含服務發現與注冊,消息路由。
最后查詢數據庫,會不會經過緩存?是不是關系型數據庫?是會分庫分表還是做哪些操作?
對于數據庫,分庫分表如果數據量大的話是有必要的,一般業務根據一個分表字段進行取模進行分表,而在做數據庫操作的時候,也根據同樣的規則,決定數據的讀寫操作對應哪張表。這種也有開源的實現的,如阿里的TDDL就有這種功能。分庫分表還涉及到很多技術,比如sequence如何設置 ,如何解決熱點問題等。
最后再把處理結果封裝成response,返回給客戶端。瀏覽器再進行頁面渲染。
焦慮的hr面之所以說hr面焦慮,是因為面試前我還在看IG的半決賽(實在復習不下),接到電話的時候分外緊張,在一些點上答得很差。
遇到什么挫折這種問題主要考察面試者遇見困難是否能堅持下去,并且可以看出他的解決問題的能力。
可以簡單描述挫折,并說明自己如何克服,最終有哪些收獲。
職業規劃表明自己決心,首先自己不準備繼續求學了,必須招工作了。然后說下自己不會短期內換行業,或者換工作,自己比較喜歡,希望可以堅持幾年看自己的興趣再規劃之類的。
對阿里的認識這個比較簡答,夸就行了。
有什么崇拜的人嗎我說了詹姆斯哈登,hr小姐姐居然笑了。
這個可以說一些IT大牛。
希望去哪里就業這個問題果斷回答該公司所在的城市啊。
其他問題有什么興趣愛好,能拿得上臺表演的有嗎
記憶深刻的事情
總結提前批更多的是考察基礎知識,大公司都有自己在用的框架,你進去后基本上得重新學這些框架,所以對他們來說,基礎是否扎實才是考察的關鍵。
基礎包括: 操作系統、linxu、數據庫、數據結構、算法、java(基礎、容器、高并發、jvm)、計算機網絡等**
建議要投資知識,從寒假到現在,先后買了9個極客時間的課程、訂閱了H神的知識星球、當當買了四五本相關技術書籍…
雖然購買的課很多還來不及讀(慚愧)
當時我問一個Java群的師兄,學不下了怎么辦,他說,換種姿勢繼續學,還別說,有時候失眠的時候,我都在看極客時間或知識星球催眠自己…
要對知識做好總結,雖然以前也有記錄簡書的習慣,但是大多數時候都是寫了不發表,自己做一個記憶的作用,3月份我給自己的要求就是,對每個知識點要做到能夠有自己的理解,然后寫一篇質量較好的博客總結。
面試建議是,一定要自信,敢于表達,面試的時候我們對知識的掌握有時候很難面面俱到,把自己的思路說出來,而不是直接告訴面試官自己不懂,這也是可以加分的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7294.html
摘要:我自己總結的學習的系統知識點以及面試問題,已經開源,目前已經。面試官那你都了解里面的哪些東西呢我哈哈哈這可是我的強項,從,說到,,又說到線程池,分別說了底層實現和項目中的應用。 我自己總結的Java學習的系統知識點以及面試問題,已經開源,目前已經 35k+ Star。會一直完善下去,歡迎建議和指導,同時也歡迎Star: https://github.com/Snailclimb... ...
摘要:作者鏈接來源牛客網今天剛剛收到的電話,開心,簡單記錄一下美團的面經。當時面試官評價基礎不是很好,其他還行。的三次握手四次揮手。整體感覺美團的面試比較基礎,但是各個方面都有涉及到。 作者:icysnowgx鏈接:https://www.nowcoder.com/disc...來源:牛客網 今天剛剛收到hr的電話,開心,簡單記錄一下美團的面經。時間隔的比較久了,簡單回憶下,最后會給出我之前...
摘要:財富管理專場上,螞蟻金服微貸事業群高級前端技術專家王卓做了主題為螞蟻微貸互動營銷技術體系實踐的精彩分享。通過互動技術,最終實現拉新,留存和促活等目標。營銷技術方案對接研發平臺,通過鳳蝶系統和研發管理體系進行打通。 摘要:以數字金融新原力(The New Force of Digital Finance)為主題,螞蟻金服ATEC城市峰會于2019年1月4日上海如期舉辦。財富管理專場上,螞...
摘要:獲取的對象范圍方法獲取的是最終應用在元素上的所有屬性對象即使沒有代碼,也會把默認的祖宗八代都顯示出來而只能獲取元素屬性中的樣式。因此對于一個光禿禿的元素,方法返回對象中屬性值如果有就是據我測試不同環境結果可能有差異而就是。 花了很長時間整理的前端面試資源,喜歡請大家不要吝嗇star~ 別只收藏,點個贊,點個star再走哈~ 持續更新中……,可以關注下github 項目地址 https:...
一面(23min) 自我介紹 項目中最自豪的部分 也沒什么太自豪的,就是在移動端開發的時候不存在cookie和session,然后用redis存了一下驗證碼感覺還不錯。 講一講ArrayList和LinkedListArrayList底層實現是數組,并且每次擴容擴容1.5倍,常用在查詢較多的場景中。而LinkedList底層實現是鏈表常用在增刪比較多的場景 你說你對鎖有了解,說一說你最熟...
閱讀 3413·2021-11-25 09:43
閱讀 3468·2021-11-19 09:40
閱讀 2471·2021-10-14 09:48
閱讀 1286·2021-09-09 11:39
閱讀 1926·2019-08-30 15:54
閱讀 2826·2019-08-30 15:44
閱讀 2001·2019-08-29 13:12
閱讀 1547·2019-08-29 12:59