華爲實習生面試

華爲一面:java

一、圖的表示方式?算法

 (1)鄰接表法:鄰接表的核心思想就是針對每一個頂點設置一個鄰居表。 編程

 

 

以上面的圖爲例,這是一個有向圖,分別有頂點a, b, c, d, e, f, g, h共8個頂點。使用鄰接表就是針對這8個頂點分別構建鄰居表,從而構成一個8個鄰居表組成的結構,這個結構就是咱們這個圖的表示結構或者叫存儲結構。安全

 

a, b, c, d, e, f, g, h = range(8)服務器

N = [{b, c, d, e, f},  # a 的鄰居表網絡

     {c, e},  # b 的鄰居表併發

     {d},  # c 的鄰居表函數

     {e},  # d 的鄰居表this

     {f},  # e 的鄰居表spa

     {c, g, h},  # f 的鄰居表

     {f, h},  # g 的鄰居表

     {f, g}]  # h 的鄰居表

 

(2)鄰接矩陣:鄰接矩陣的核心思想是針對每一個頂點設置一個表,這個表包含全部頂點,經過True/False來表示是不是鄰居頂點仍是針對上面的圖,分別有頂點a, b, c, d, e, f, g, h共8個頂點。使用鄰接矩陣就是針對這8個頂點構建一個8×8的矩陣組成的結構,這個結構就是咱們這個圖的表示結構或存儲結構。

 

   a, b, c, d, e, f, g, h = range(8)

N = [[0, 1, 1, 1, 1, 1, 0, 0],  # a的鄰接狀況

     [0, 0, 1, 0, 1, 0, 0, 0],  # b 的鄰居表

     [0, 0, 0, 1, 0, 0, 0, 0],  # c 的鄰居表

     [0, 0, 0, 0, 1, 0, 0, 0],  # d 的鄰居表

     [0, 0, 0, 0, 0, 1, 0, 0],  # e 的鄰居表

     [0, 0, 1, 0, 0, 0, 1, 1],  # f 的鄰居表

     [0, 0, 0, 0, 0, 1, 0, 1],  # g 的鄰居表

     [0, 0, 0, 0, 0, 1, 1, 0]]  # h 的鄰居表

 

二、圖的遍歷方式?

一般有兩種遍歷圖的方法:深度優先遍歷和廣度優先遍歷。它們對無向圖和有向圖都適用。圖的遍歷算法是求解圖的連通性問題、拓撲排序和求關鍵路徑等算法的基礎。

1)   深度優先遍歷: 從圖中某個頂點v出發,訪問該頂點,而後依次從v的未被訪問的鄰接點出發繼續深度優先遍歷圖中的其他頂點,直至圖中全部與v有路徑相通的頂點都被訪問完爲止;若此時尚有頂點未被訪問,則選擇一個頂點做爲起始點,重複上述過程,直到全部的頂點都被訪問。深度優先遍歷是一個遞歸的過程。

 

 

 

2)  廣度優先遍歷:首先,從圖的某個頂點v出發,依次訪問與v相鄰的未被訪問的頂點,而後分別從這些頂點出發,廣度優先遍歷,直至全部的頂點都被訪問完。

如上圖中,廣度優先遍歷獲得的序列爲:

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 ->7

 

三、進程的通訊方式?

進程間通訊(IPC,InterProcess Communication)是指在不一樣進程之間傳播或交換信息。IPC的方式一般有管道(包括無名管道和命名管道)、消息隊列、信號量、共享存儲、Socket、Streams等。其中 Socket和Streams支持不一樣主機上的兩個進程IPC。

以Linux中的C語言編程爲例。

1、管道管道,一般指無名管道,是 UNIX 系統IPC最古老的形式。

    特色:它是半雙工的(即數據只能在一個方向上流動),具備固定的讀端和寫端;它只能用於具備親緣關係的進程之間的通訊(也是父子進程或者兄弟進程之間);它能夠當作是一種特殊的文件,對於它的讀寫也可使用普通的read、write 等函數;可是它不是普通的文件,並不屬於其餘任何文件系統,而且只存在於內存中。

2、FIFO:也稱爲命名管道,它是一種文件類型。

    特色:FIFO能夠在無關的進程之間交換數據,與無名管道不一樣;FIFO有路徑名與之相關聯,它以一種特殊設備文件形式存在於文件系統中。

3、消息隊列:是消息的連接表,存放在內核中。一個消息隊列由一個標識符(即隊列ID)來標識。

特色:消息隊列是面向記錄的,其中的消息具備特定的格式以及特定的優先級;消息隊列獨立於發送與接收進程,進程終止時,消息隊列及其內容並不會被刪除;消息隊列能夠實現消息的隨機查詢,消息不必定要以先進先出的次序讀取,也能夠按消息的類型讀取。

4、信號量:信號量(semaphore)與已經介紹過的 IPC 結構不一樣,它是一個計數器。信號量用於實現進程間的互斥與同步,而不是用於存儲進程間通訊數據。

    特色:信號量用於進程間同步,若要在進程間傳遞數據須要結合共享內存;信號量基於操做系統的 PV 操做,程序對信號量的操做都是原子操做;每次對信號量的 PV 操做不只限於對信號量值加 1 或減 1,並且能夠加減任意正整數;支持信號量組。

5、共享內存:共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。

        特色:共享內存是最快的一種 IPC,由於進程是直接對內存進行存取;由於多個進程能夠同時操做,因此須要進行同步;信號量+共享內存一般結合在一塊兒使用,信號量用來同步對共享內存的訪問。

 

五種通信方式總結

   管道:速度慢,容量有限,只有父子進程能通信    

FIFO:任何進程間都能通信,但速度慢    

消息隊列:容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完數據的問題    

信號量:不能傳遞複雜消息,只能用來同步    

共享內存區:可以很容易控制容量,速度快,但要保持同步,好比一個進程在寫的時候,另外一個進程要注意讀寫的問題,至關於線程中的線程安全,固然,共享內存區一樣能夠用做線程間通信,不過沒這個必要,線程間原本就已經共享了同一進程內的一塊內存

 

4、java判斷可回收的垃圾對象?

1. 引用計數算法

爲對象添加一個引用計數器,當對象增長一個引用時計數器加 1,引用失效時計數器減 1。引用計數爲 0 的對象可被回收。 在兩個對象出現循環引用的狀況下,此時引用計數器永遠不爲 0,致使沒法對它們進行回收。正是由於循環引用的存在,所以 Java 虛擬機不使用引用計數算法

2. 可達性分析算法

GC Roots 爲起始點進行搜索,可達的對象都是存活的,不可達的對象可被回收。

Java 虛擬機使用該算法來判斷對象是否可被回收,GC Roots 通常包含如下內容:

      • 虛擬機棧中局部變量表中引用的對象
      • 本地方法棧中 JNI 中引用的對象
      • 方法區中類靜態屬性引用的對象
      • 方法區中的常量引用的對象

 

5、實現線程同步的方法?

1.同步方法

    即有synchronized關鍵字修飾的方法(全部訪問狀態變量的方法都必須進行同步),此時充當鎖的對象爲調用同步方法的對象。在調用該方法前,須要得到內置鎖,不然就處於阻塞狀態。

2.同步代碼塊

   即有synchronized關鍵字修飾的語句塊。鎖的粒度更細,而且充當鎖的對象不必定是this,也能夠是其它對象,使用起來更加靈活。

3.使用特殊域變量(volatile—不能保證原子性)實現線程同步

   (1).volatile關鍵字爲域變量的訪問提供了一種免鎖機制;

    (2).使用volatile修飾域至關於告訴虛擬機該域可能會被其餘線程更新;

    (3).所以每次使用該域就要從新計算,而不是使用寄存器中的值;

    (4).volatile不會提供任何原子操做,它也不能用來修飾final類型的變量;

4.使用重入鎖實現線程同步

    ReentrantLock類是可重入、互斥、實現了Lock接口的鎖,它擁有synchronized相同的併發性和內存語義,此外還多了鎖投票,定時鎖等候和中斷鎖等候。

    線程A和B都要獲取對象O的鎖定,假設A獲取了對象O鎖,B將等待A釋放對O的鎖定;

     若是使用synchronized,若是A不釋放,B將一直等下去,不能被中斷;

若是使用ReentrantLock,若是A不釋放,可使B在等待了足夠長的時間之後,中斷等待,而幹別的事情

5.使用局部變量實現線程同步

若是使用ThreadLocal管理變量,則每個使用該變量的線程都得到該變量的副本,副本之間相互獨立,這樣每個線程均可以隨意修改本身的變量副本,而不會對其餘線程產生影響。

 

6、雙向鏈表中刪除一個節點:假設須要被刪除的節點稱之爲delNode?

 

      p->prior->next=p->next;

      p->next->prior->p=p->prior;

 

7、項目介紹。。。。。blablabla

 

8、TCP三次握手

假設 A 爲客戶端,B 爲服務器端。

      • 首先 B 處於 LISTEN(監聽)狀態,等待客戶的鏈接請求。
      • A 向 B 發送鏈接請求報文,SYN=1,ACK=0,選擇一個初始的序號 x。
      • B 收到鏈接請求報文,若是贊成創建鏈接,則向 A 發送鏈接確認報文,SYN=1,ACK=1,確認號爲 x+1,同時也選擇一個初始的序號 y。
      • A 收到 B 的鏈接確認報文後,還要向 B 發出確認,確認號爲 y+1,序號爲 x+1。
      • B 收到 A 的確認後,鏈接創建。

 

 三次握手的緣由

第三次握手是爲了防止失效的鏈接請求到達服務器,讓服務器錯誤打開鏈接。

客戶端發送的鏈接請求若是在網絡中滯留,那麼就會隔很長一段時間才能收到服務器端發回的鏈接確認。客戶端等待一個超時重傳時間以後,就會從新請求鏈接。可是這個滯留的鏈接請求最後仍是會到達服務器,若是不進行三次握手,那麼服務器就會打開兩個鏈接。若是有第三次握手,客戶端會忽略服務器以後發送的對滯留鏈接請求的鏈接確認,不進行第三次握手,所以就不會再次打開鏈接。

 

9、四次揮手

 

 

 

如下描述不討論序號和確認號,由於序號和確認號的規則比較簡單。而且不討論 ACK,由於 ACK 在鏈接創建以後都爲 1。

      • A 發送鏈接釋放報文,FIN=1。
      • B 收到以後發出確認,此時 TCP 屬於半關閉狀態,B 能向 A 發送數據可是 A 不能向 B 發送數據。
      • 當 B 再也不須要鏈接時,發送鏈接釋放報文,FIN=1。
      • A 收到後發出確認,進入 TIME-WAIT 狀態,等待 2 MSL(最大報文存活時間)後釋放鏈接。
      • B 收到 A 的確認後釋放鏈接。

四次揮手的緣由

客戶端發送了 FIN 鏈接釋放報文以後,服務器收到了這個報文,就進入了 CLOSE-WAIT 狀態。這個狀態是爲了讓服務器端發送還未傳送完畢的數據,傳送完畢以後,服務器會發送 FIN 鏈接釋放報文

 

客戶端接收到服務器端的 FIN 報文後進入此狀態,此時並非直接進入 CLOSED 狀態,還須要等待一個時間計時器設置的時間 2MSL。這麼作有兩個理由:

      • 確保最後一個確認報文可以到達。若是 B 沒收到 A 發送來的確認報文,那麼就會從新發送鏈接釋放請求報文,A 等待一段時間就是爲了處理這種狀況的發生。
      • 等待一段時間是爲了讓本鏈接持續時間內所產生的全部報文都從網絡中消失,使得下一個新的鏈接不會出現舊的鏈接請求報文。

 

華爲二面

    人生理想之類的

相關文章
相關標籤/搜索