2020畢業後我所經歷的面試【面試系列】 面試題四

kay三石發表於2020-11-12

1.快速排序的實現,

通過一個陣列劃分為若干個子陣列,然後通過遞迴呼叫自身為每一個子陣列進行快速排序,設定關鍵字比關鍵字大的設定為一組,比關鍵字小的放為一組,設定陣列最右端的資料為關鍵字。謹記:快速排序和氣泡排序一樣都需要兩兩交換。

	/**
	 * 快速排序:通過一個陣列劃分為若干個子陣列,然後通過遞迴呼叫自身為每一個子陣列進行快速排序
	 * 設定關鍵字比關鍵字大的設定為一組,比關鍵字小的放為一組,設定陣列最右端的資料為關鍵字
	 * @param arry
	 */
	public static void quicklySort(long[] arry,int left,int right){
		if (right-left<=0) {
			return;
		}else{
			//這裡使用遞迴迪呼叫的方式
			
			//設定point:關鍵字
			long point=arry[right];
			//獲取切點
			int partition=partition(arry, left, right, point);
			//對左面的子陣列進行快速排序
			quicklySort(arry, left, partition-1);
			//對右面的子陣列進行快速排序
			quicklySort(arry, partition+1, right);
			
		}
		
		
	}
	/**
	 * 為快速排序劃分陣列
	 * @param arry
	 * @param left
	 * @param right
	 * @param point
	 */
	public static int partition(long[] arry,int left,int right,long point){
		int leftPtr=left-1;//左指標
		int rightPtr=right+1;//右指標
		//保證左邊的陣列比右面的小
		while(true){
			//迴圈:將比關鍵字小的留在左端
			while(leftPtr <rightPtr && arry[++leftPtr]<point);
			//迴圈:將比關鍵字大的留在右端
			while(rightPtr >leftPtr && arry[--rightPtr]>point);
			if (leftPtr>=rightPtr) {
				break; 
			}else {
				long temp=arry[leftPtr];
				arry[leftPtr]=arry[rightPtr];
				arry[rightPtr]=temp;
			}
		}
		//將關鍵字和當前的所指的leftPtr所指的進行交換
		long temp=arry[leftPtr];
		arry[leftPtr]=arry[right];
		arry[right]=temp;
		return leftPtr;
	}

順便看下幾個排序的複雜度。

2.快速排序的優點

3.快速排序的複雜度

4.TCP與UDP的區別:

  • TCP是面向連線的;UDP是無連線的,即傳送資料之前不需要建立連線。
  • TCP提供可靠的服務。通過TCP連線傳輸的資料,無差錯,不丟失,不重複,且按序到達;UDP儘量保證到達,不保證可靠互動。
  • TCP是面向位元組流,實際tcp連線傳送的資料可看成一連串的無結構的位元組流;UDP是面向報文的,UDP沒有阻塞控制,因此網路出現擁堵不會使得源主機傳送效率降低(實時應用有用)
  • 每條TCP連線只能點對點,UDP支援一對一,一對多,多對多的互動通訊。
  • TCP首部開銷20位元組;UDP的首部開銷小,只有8個位元組
  • TCP的邏輯通訊通道是雙全工的可靠的通道,UDP則是不可靠通道。

5.TCP三次握手四次揮手的原理

  • 第一次握手:建立連線,客戶端傳送sync包(sync=x)到伺服器,並進入SYN_SENT狀態等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers) 。。 首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶資料,但要消耗掉一個序號。
  • 第二次握手:伺服器收到客戶端的Syn包,必須確認客戶的SYN(ack=x+1) 同時自己也傳送一個SYN包(syn=y),即SYN+ACK包,此時伺服器進入SYN_RECV狀態; 在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y
  • 第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送去人包ACK(ack=y+1)傳送完畢後,客戶端和服務端進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。 確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始為seq=x,第二個報文段所以要+1),ACK報文段可以攜帶資料,不攜帶資料則不消耗序號。

6.TCP為何不設定為四次握手 為什麼連線的時候是三次握手,關閉的時候卻是四次握手?

因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都傳送完了,我才能傳送FIN報文,因此不能一起傳送。故需要四步握手。

7.TCP如果設定兩次握手可以嗎

3次握手完成兩個重要的功能,既要雙方做好傳送資料的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。

   現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作為例子,考慮計算機S和C之間的通訊,假定C給S傳送一個連線請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認為連線已經成功地建立了,可以開始傳送資料分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連線請求分組。在這種情況下,C認為連線還未建立成功,將忽略S發來的任何資料分 組,只等待連線確認應答分組。而S在發出的分組超時後,重複傳送同樣的分組。這樣就形成了死鎖

8.Hash表的實現原理

9.Hash表的碰撞衝突如何解決,

10.如果建立了連線,但是客戶端突然出現故障了怎麼辦?

TCP還設有一個保活計時器,客戶端如果出現故障,伺服器不能一直等下去,白白浪費資源。伺服器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設定為2小時,若兩小時還沒有收到客戶端的任何資料,伺服器就會傳送一個探測報文段,以後每隔75秒傳送一次。若一連傳送10個探測報文仍然沒反應,伺服器就認為客戶端出了故障,接著就關閉連線。

面試反思:這家對計算機網路,以及演算法要求比較高特別是網路傳輸。

相關文章