2023年12月21日
提問(不按時間順序):
1, 使用linux epoll模型,水平觸發模式(level-triggered);當socket可寫時,會不停的觸發socket可寫的事件,如何處理?
2, 從socket讀資料時,socket快取裡的資料,可能超過使用者快取的長度,如何處理?例如,socket快取有8kb的資料,而你的快取只有2kb空間。
3, 向socket傳送資料時, 可能只傳送了使用者快取裡的一半,如何處理?例如,需要向socket傳送8kb資料,返回值只有2kb傳送成功。
4, c++的虛函式是怎麼實現的?
5, c++的虛函式有什麼作用?
6, 非阻塞connect()如何實現?
7, sizeof()問題
class a
class b
sizeof(a), sizeof(b) 分別是多少?
8, 實現字串比較函式 strcmp(char *src, char * sub)
9, 實現記憶體拷貝函式 strcpy(void*dst, char * src, size_t len)
10,條件變數的如何使用? 你使用的執行緒函式是什麼?
11, deamon程序如何實現?
12, http和cgi是什麼?
13, tcp的三次握手, time_wait和close_wait狀態是什麼?
因為第7題之後的屬於客觀題,不打算在此寫答案。 朋友們如有好的答案也歡迎跟貼。
本人在此寫出自己對前6個問題的回答:
1, 使用linux epoll模型,水平觸發模式(level-triggered);當socket可寫時,會不停的觸發socket可寫的事件,如何處理?
第一種最普通的方式:
當需要向socket寫資料時,將該socket加入到epoll模型(epoll_ctl);等待可寫事件。
接收到socket可寫事件後,呼叫write()或send()傳送資料。
當資料全部寫完後, 將socket描述符移出epoll模型。
這種方式的缺點是: 即使傳送很少的資料,也要將socket加入、移出epoll模型。有一定的操作代價。
第二種方式,(是本人的改進方案, 叫做directly-write)
向socket寫資料時,不將socket加入到epoll模型;而是直接呼叫send()傳送;只有當或send()返回錯誤碼eagain(系統快取滿),才將socket加入到epoll模型,等待可寫事件後,再傳送資料。
全部資料傳送完畢,再移出epoll模型。
這種方案的優點:當使用者資料比較少時,不需要epool的事件處理。
在高壓力的情況下,效能怎麼樣呢?
對一次性直接寫成功、失敗的次數進行統計。如果成功次數遠大於失敗的次數, 說明效能良好。(如果失敗次數遠大於成功的次數,則關閉這種直接寫的操作,改用第一種方案。同時在日誌裡記錄警告):在我自己的應用系統中,實驗結果資料證明該方案的效能良好。
事實上,網路資料可分為兩種到達/傳送情況:
一是分散的資料報,例如每間隔40ms左右,傳送/接收3-5個 mtu(或更小,這樣就沒超過預設的8k系統快取)。二是連續的資料報,例如每間隔1s左右,連續傳送/接收20個 mtu(或更多)。
回來查了資料,發現以下兩種方式:
第三種方式:
使用edge-triggered(邊沿觸發),這樣socket有可寫事件,只會觸發一次。
可以在應用層做好標記,以避免頻繁的呼叫epoll_ctl(epoll_ctl_add,epoll_ctl_mod)。這種方式是epoll的 man 手冊裡推薦的方式,效能最高。但如果處理不當容易出錯,事件驅動停止。
第四種方式:
在epoll_ctl()使用epolloneshot標誌,當事件觸發以後,socket會被禁止再次觸發。需要再次呼叫epoll_ctl(epoll_ctl_mod),才會接收下一次事件。 這種方式可以禁止socket可寫事件,應該也會同時禁止可讀事件。會帶來不便,同時並沒有效能優勢,因為epoll_ctl()有一定的操作代價。
2, 從socket讀資料時,socket快取裡的資料,可能超過使用者快取的長度,如果處理?
可以呼叫realloc(),擴大原有的快取塊尺寸。但是臨時申請記憶體的有一定效能損失。
這種情況要看接收快取的方式。
第一種方式:
使用100k的大接收快取為例。
如果要等待資料,並進行解析。可能發生快取不夠的情況。此時只能擴充快取,或先處理100k的資料,再接收新的資料。
第二種方式:
使用快取佇列,分成8k大小的佇列。
不存在接收快取不夠的情況。 除非使用者解析已出錯,使用資料接收、使用脫勾。
這種方式的代價是,可能需要將快取佇列再次拷貝、拼接成一塊大的快取,再進行解析。 而在本人的系統中,只需要將socket接收的資料再次原樣分發給客戶, 所以這種方案是最佳方案。
3, 向socket傳送資料時, 可能只傳送了使用者快取裡的一半,然後失敗,如何處理?
記錄快取的偏移量。下一次socket寫事件時,再從偏移的位置接著傳送。
那個面試官居然對這個問題問了我兩次, 看來我解釋的不夠清晰。。。。。。 鬱悶。
4, c++的虛函式是怎麼實現的?
使用虛函式表。
回來查下資料: c++物件使用虛表,如果是基類的例項,對應位置存放的是基類的函式指標;如果是繼承類,對應位置存放的是繼承類的函式指標(如果在繼承類有實現)。所以,當使用基類指標呼叫物件方法時,也會根據具體的例項,呼叫到繼承類的方法。
5, c++的虛函式有什麼作用?
虛函式作用是實現多型,很多人都能理解這一點。但卻不會回答下面這一點。
更重要的,虛函式其實是實現封裝,使得使用者不需要關心實現的細節。在很多設計模式中都是這樣用法,例如factory、bridge、strategy模式。 前兩天在書上剛好看到這個問題,但在面試的時候卻沒想起來。
個人覺得這個問題可以很好的區分c++的理解水平。
6, 非阻塞connect()如何實現?
將socket設定成non-blocking,操作方法同非阻塞read()、write()。
面試官是在聽到我介紹之後,才問我這個問題。可惜還是問我兩遍。
這次面試, 總的來說準備不夠充足, 所以這次機會沒有青睞我!
也有其它一些問題:
對於一般的面試提問,總是想很簡要的回答完。因為對方可能本來就很清楚,所以自己就想一兩句話說完。但是有時候這樣行不通。需要適當的回答清晰、完整一些。
對tcp/udp的問題本來是很熟悉的,但因為長時間沒複習,忘的差不多了。
以前已經對rtsp進行了仔細的學習。 http、sip屬於同一類協議。而我卻回答不了http的問題。努力學習啊................
有些問題要問我兩遍,說明我的表達確實不夠清晰。有的問題可能面試官自己並不清晰,所以除了表達清晰之外,完全有必要適當的回答稍完整些。否則很難讓人滿意。
精神狀態不太好,思維有些慢了。 因為總是睡的晚。
接下來打算繼續研究 lighttpd原始碼,這樣對我自己的水平提高會有很大幫助。
機會總是青睞有準備的人! 期待下次。
from: 3/24/5407394.aspx
騰訊公司後台伺服器經典面試題
2010年12月21日 提問 不按時間順序 1,使用linux epoll模型,水平觸發模式 level triggered 當socket可寫時,會不停的觸發socket可寫的事件,如何處理?2,從socket讀資料時,socket快取裡的資料,可能超過使用者快取的長度,如何處理?例如,socke...
騰訊公司後台伺服器經典面試題 2023年5月
這次面試,總的來說準備不夠充足,所以這次機會沒有青睞我!也有其它一些問題 1,對於一般的面試提問,總是想很簡要的回答完。因為對方可能本來就很清楚,所以自己就想一兩句話說完。但是有時候這樣行不通。需要適當的回答清晰 完整一些。2,對tcp udp的問題本來是很熟悉的,但因為長時間沒複習,忘的差不多了。...
後台伺服器經典面試題
1,使用linux epoll模型,水平觸發模式 level triggered 當socket可寫時,會不停的觸發socket可寫的事件,如何處理?2,從socket讀資料時,socket快取裡的資料,可能超過使用者快取的長度,如何處理?例如,socket快取有8kb的資料,而你的快取只有2kb空...