面經總結——騰訊面試題彙總(一)

1.i++是不是原子操作,++i呢?

答:i++不是原子操作,++i也不是原子操作。
原子操作是指不會被線程調度機制打斷的操作;這種操作一旦開始,就一直運行到結束,中間不會切換到另一個線程。
i++其實一共做了三次指令操作,第一次,從內存中讀取i變量的值到CPU的寄存器,第二次在寄存器中的i自增1,第三次將寄存器中的值寫入內存。這三次指令操作中任意兩次如果同時執行的話,都會造成結果的差異性。
而對於++i,在多核機器上,CPU在讀取內存時也可能同時讀到同一個值,這樣就會同一個值自增兩次,而實際上只自增了一次,所以++i也不是原子操作。

2.紅黑樹查找時間複雜度?哈希查找時間複雜度?

AVL樹和紅黑樹詳講

哈希詳講

答:紅黑樹的時間複雜度爲Olog(n);哈希查找時間複雜度爲Olog(1).

3.哈希一個字符串,輸出的結果是什麼?

4.平時如何調試代碼?簡述gdb調試的用法?

linux下gdb調試方法與技巧整理

5.簡述三次握手,三次握手之後建立的連接就可靠了嗎?

TCP連接的特點:面向連接的、可靠的、基於字節流的傳輸層通信協議。
所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示:在這裏插入圖片描述(1)第一次握手:Client將標誌位SYN置爲1,隨機產生一個值seq=x,並將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。
(2)第二次握手:Server收到數據包後由標誌位SYN=1知道Client請求建立連接,Server將標誌位SYN和ACK都置爲1,ack=x+1,隨機產生一個值seq=y,並將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態。
(3)第三次握手:Client收到確認後,檢查ack是否爲x+1,ACK是否爲1,如果正確則將標誌位ACK置爲1,ack=y+1,並將該數據包發送給Server,Server檢查ack是否爲y+1,ACK是否爲1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸數據了。

6.簡述四次揮手,TIMEWAIT狀態出現的時機和原因?

四次揮手,別名連接終止協議。其性質爲終止協議。
四次揮手即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發
在這裏插入圖片描述
第四次揮手時,Client接收到Fin後,並沒有立即進入CLOSED狀態,而是進入TIME_WAIT狀態,這是爲什麼呢?
(1)Client不能保證最後的ACK能到達Server,所以還應該觀望一段時間,護送一段時間。如果最後的ACK丟失,那麼Server顯然收不到,於是Server發起了重傳FIN的操作,此時如果Client處於CLOSED狀態,就無法重發ACK了。所以Client要等待一個2MSL的時間,這段時間就是TIME_WAIT。
因而,要實現TCP全雙工連接的正常終止,必須處理終止過程中四個分節任何一個分節的丟失情況,主動關閉連接的Server端必須維持TIME_WAIT狀態 。
2)允許老的重複分節在網絡中消逝。TCP分節可能由於路由器異常而“迷途”,在迷途期間,TCP發送端可能因確認超時而重發這個FIN包,迷途的分節在路由器修復後也會被送到最終目的地,這個遲到的迷途分節到達時可能會引起問題。在關閉“前一個連接”之後,馬上又重新建立起一個相同的IP和端口之間的“新連接”,“前一個連接”的迷途重複分組在“前一個連接”終止後到達,而被“新連接”收到了。爲了避免這個情況,TCP協議不允許處於TIME_WAIT狀態的連接啓動一個新的可用連接,因爲TIME_WAIT狀態持續2MSL,就可以保證當成功建立一個新TCP連接的時候,來自舊連接重複分組已經在網絡中消逝。

7.如何用到TCP、UDP協議?

一文了解TCP/UDP協議

TCP與UDP的區別:
1) TCP提供面向連接的傳輸,通信前要先建立連接(三次握手機制); UDP提供無連接的傳輸,通信前不需要建立連接。
2) TCP提供可靠的傳輸(有序,無差錯,不丟失,不重複); UDP提供不可靠的傳輸
3) TCP面向字節流的傳輸,因此它能將信息分割成組,並在接收端將其重組; UDP是面向數據報的傳輸,沒有分組開銷。
4) TCP提供擁塞控制和流量控制機制; UDP不提供擁塞控制和流量控制機制。

UDP應用場景
1.面向數據報方式
2.網絡數據大多爲短消息
3.擁有大量Client
4.對數據安全性無特殊要求
5.網絡負擔非常重,但對響應速度要求高

8.多線程和多進程用哪個好?什麼情況下用多線程?

線程和進程有什麼區別?
  • 進程是程序的一次執行。線程可以理解爲進程中執行的一段程序片段。
  • 進程間式獨立的,這表現在內存空間,上下文環境;線程運行在進程空間內。一般來講,進程無法突破進程邊界存取其它進程內的存儲空間;而線程由於處於進程空間內,所以同一進程所產生的線程共享在同一內存空間。
  • 同一進程中的兩段代碼不能夠同時執行,除非引入線程。
  • 線程是屬於進程的,當進程退出時該所產生的線程都會被強制退出並清除。線程佔用的資源要少於進程所佔的資源。進程和線程都可以有優先級。
  • 進程間可以通過IPC通信,但線程不可以。
何時使用多進程,何時使用多線程?
  • 對資源的管理和保護要求高,不限制開銷和效率時,使用多進程。
  • 要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多線程。

9.進程間通信方式?線程間通信方式?

進程間通信

管道(pipe):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用進程間的親緣關係通常是指父子進程關係。
命名管道(named pipe/FIFO):命名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
信號量(semophonre):信號量是一個計數器,可以用來控制多個進程隊共享資源的訪問。它常作爲一個鎖機制,防止某進程在訪問共享資源時,其他進程也訪問此資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
消息隊列(message queue):消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等缺點。
信號(sinal):信號是一種比較複雜的通信方式,用於通知接受進程某個事件已經發生。
共享內存(shared memory):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的ipc通信方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往和其他通信方式如信號量,配合使用來實現進程間的同步和通信。
套接字(socket):套接字也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同設備間的進程通信。
全雙工管道:共享內存、信號量、消息隊列、管道和命名管道只適用於本地進程間通信,套接字和全雙工管道可用於遠程通信,因此可用於網絡編程。

線程間通信

鎖機制:包括互斥鎖、條件變量、讀寫鎖
互斥鎖:提供了以排他方式防止數據結構被併發修改的方法。
讀寫鎖:允許多個線程同時共享數據,而對寫操作是互斥的。
條件變量:可以以原子的方式阻塞進程,直到某個特定條件爲真爲止。對條件的測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
信號量機制(Semaphore):包括無名進程信號量和命名線程信號量
信號機制(Signal):類似進程間的信號處理

10.文件傳輸中的斷點續傳是如何實現的?

斷點續傳的實現原理

11.I/O複用模式(LT/ET)的使用場景?

linux 中IO多路複用epoll函數的ET和LT工作模式詳解

12.講講I/O複用中的select?

I/O多路轉接之select

13.fork()後子進程和父進程的返回值分別是什麼?

答:父進程fork()之後返回值爲子進程的pid號,而子進程fork()之後的返回值爲0。

fork函數詳講
  • fork函數的特點概括起來就是“調用一次,返回兩次”,在父進程中調用一次,在父進程和子進程中各返回一次。
  • fork的另一個特性是所有由父進程打開的描述符都被複制到子進程中。父、子進程中相同編號的文件描述符在內核中指向同一個file結構體,也就是說,file結構體的引用計數要增加。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章