Windows面試題(三)

問MainFrm,CDocument和CView類之間的關係,

MainFrm爲框架類,包含應用程序外框所包含部分。CView爲視圖類,用於顯示數據的空白區域窗口。

CDocument爲文檔類。

MFC提供了文檔/視類結構,採用數據本身和顯示分離的機制。其中文檔類CDocument用於數據的存儲和加載,視類CView用於數據的顯示與修改。

 

Dialog和 ModuelDialog不同用法

1)類型不同

MoudleDialog 模態對話框,屬於壟斷對話框,例如打開對話框,點擊打開後不能再執行其他操作,會發出“嘟嘟嘟”的聲音;

      非模態對話框,屬於非壟斷對話框,利用查找對話框,點擊查找同時可以執行其他操作;

      即:非模態不壟斷;模態壟斷。

2)用法不同

      CDialog::Create :to create amodelessdialog box

      CDialog::DoModal :Call thismember function to invoke the modal dialog box andreturn the dialog-box resultwhen done

 

windows消息系統由哪幾部分構成?

答:由一下3部分組成:

1.   消息隊列:操作系統負責爲進程維護一個消息隊列,程序運行時不斷從該消息隊列中獲取消息、處理消息;

2.   消息循環:應用程序通過消息循環不斷獲取消息、處理消息。

3.   消息處理:消息循環負責將消息派發到相關的窗口上使用關聯的窗口過程函數進行處理。

 

什麼時候必須重寫拷貝構造函數?

答:當構造函數涉及到動態存儲分配空間時,要自己寫拷貝構造函數,並且要深拷貝。

 

 什麼是消息映射?

答:消息映射就是讓程序員指定MFC類(有消息處理能力的類)處理某個消息。然後由程序員完成對該處理函數的編寫,以實現消息處理功能。

 

如何定義和實現一個類的成員函數爲回調函數?

答:

所謂的回調函數,就是預先在系統的對函數進行註冊,讓系統知道這個函數的存在,以後,當某個事件發生時,再調用這個函數對事件進行響應。

定義一個類的成員函數時在該函數前加CALLBACK即將其定義爲回調函數,函數的實現和普通成員函數沒有區別

 

MFC爲何使用消息映射表而不用虛函數?

這個問題是windows開發面試中最經常問到得問題,也是很有深度的一個問題。
有兩個帖子對該問題討論的比較深刻:
http://topic.csdn.net/u/20090822/16/4cf5d189-0e5e-41ff-9ba3-c7eaf2f6da74.html
http://topic.csdn.net/u/20090316/22/8b067591-6a17-4970-b224-41ab589294b3.html
說法一:
虛函數實現佔用內存較大
      侯捷在《深入淺出MFC》中說微軟使用消息映射機制而不用虛函數,是因爲虛函數空間代價的原因。在當前MFC2.0版本發佈的時候是92年,pc的內存才幾M。一個類的虛表的大小就是虛函數的個數*一個指針的大小。
         假設windows的通用消息有200個,那麼CWnd類的虛表就有 200*4byte = 800byteCWnd類的所有派生類均copy了一份CWnd的虛表vtable,然後自己的虛函數往後加CWnd類的虛表的後頭。
         (至於有人說CWnd類的派生類能共享CWnd的虛表,這個說法不靠譜。因爲派生類自己的虛函數值加在基類的虛函數表項的最後的。如果CWnd派生了CWndChildA CWndChildB,且兩個孩子均有自己的虛函數,那麼都往CWnd類的後面加,豈不是衝突了?)。

         也就是系統內所有的CWnd類的派生類都要承受 800byte的代價。假設有100個類派生自CWnd 那麼代價就是800*100byte 也就是 80K。這在當時內存很緊張的情況下,已經是一種巨大的內存消耗了!這裏需要注意一點:vtable是和類綁定在一起的,而不是和類對象(也叫類的實例)綁定在一起的,類的實例僅增加一個指向該向類的vtable的指針而已。也就是說,如果你有100CWnd派生類,哪怕你生成了100000個派生類的實例,vtable佔用的內存也是80K
     看來在當時的環境看來,MFC沒有采用虛函數,內存的確是一個考慮。
但是放在現在看,這點內存消耗確實微不足道的!也就是說,如果現在重新設計MFC的消息機制,如果不採用虛函數,並非因爲虛函數的空間浪費問題。

結論:這個說法靠譜。

說法二:
         消息映射機制效率比虛函數效率高。
       因爲那麼多消息ID,如果找到其對應的消息處理函數,switch是不可少的!(可以hash?哦哦,的確可能,不過mfc裏面可沒這麼做?mfc裏面怎麼做的我也不清楚)
MFC中採用的是消息映射的機制,而沒有用虛函數的機制,因爲消息有很多,如果用虛函數機制,需要給每個消息定義一個虛函數,在分派消息時,程序需要逐一判斷是哪一個消息,找到合適的分支後再調用相應的虛函數;而通常情況下,應用程序不需要響應太多的消息,消息映射方式只需要判斷程序想要響應的這些消息即可,所以開銷小。 

         也就是說,MFC採用了消息映射而沒有采用虛函數,是從對消息的響應機制來考慮的。 消息映射,就可以僅實現自己感興趣的消息,這樣switch時就可以快一點。
      不過話又說回來,對一個非自己感興趣的系統消息來了以後,就需要遍歷消息網,層層的向基類查找直到找到對應的消息處理函數!這本身也很浪費時間!也許這種情況比較少見吧,否則的話,消息映射的消息響應時間並不比虛函數來的快!因爲虛函數最多隻需一次遍歷,而且,如果可以採用hash技術,更快!
如果說,大多數消息都是系統的消息,那麼消息映射的迭代查找消息函數的方式並不比虛函數的switch來的快!
         PS:這裏有一篇對比消息映射機制和虛函數機制效率的簡單模擬實驗
         http://blog.csdn.net/hjsunj/archive/2008/01/10/2034314.aspx 

結論,該說法不靠譜!

說法三:
         爲了未來的可擴展性。兼容新的系統級的消息。
      我不是很清楚MS設計消息映射的初衷,但是感覺它着眼點更側重於增加新消息很容易,而不是節省內存。 
如果我們使用虛函數機制實現,恐怕對於每個可能的消息我們都必須在基類中定義一個虛函數,而其首要的困難就是你無法猜測未來會出現什麼消息,也無法確定需要定義什麼樣函數原型的虛函數。而使用消息映射,解決這個問題則相對容易,因爲這將由未來的程序設計者決定他們的消息該如何處理。
     對於系統的新增消息,消息映射支持起來較方便。虛函數想要支持就需要改動基類添加虛函數。
對於自定義的消息,無論消息映射和虛函數都可以很好的支持。
那麼虛函數方式如何支持自定義消息?
    自定義消息是不需要加到基類的。基類可以加個虛函數,OnMessage(xxx), 然後有自定義消息的類實現之,用switch轉換成相應虛函數調用,不是自己的消息再傳給基類。
結論:這個說法靠譜。

 

sendMessage與postMessage區別?

不同點:sendMessage發送完畢以後需要等待處理完才返回;而postMessage發送消息後立即返回。

Do not post the WM_QUIT message usingPostMessage; use thePostQuitMessage function.

postMessage將消息放置到消息隊列中,不等待線程處理消息就立即返回。

sendMessage發送指定的消息到窗口,並會調用窗口過程,直到窗口過程處理完畢後才返回。

 

TCP的重發機制是怎麼實現的?

       1.滑動窗口機制,確立收發的邊界,能讓發送方知道已經發送了多少(已確認)、尚未確認的字節數、尚待發送的字節數;讓接收方知道(已經確認收到的字節數)。

       2.選擇重傳,用於對傳輸出錯的序列進行重傳。

TCP和UDP的區別?

       1TCP面向連接(三次握手機制),通信前需要先建立連接;UDP面向無連接,通信前不需要建立連接;

       2TCP保障可靠傳輸(按序、無差錯、不丟失、不重複);UDP不保障可靠傳輸,使用最大努力交付;

       3TCP面向字節流的傳輸,UDP面向數據報的傳輸。

 

TCP爲什麼不是兩次連接?而是三次握手?

如果AB兩個進程通信,如果僅是兩次連接。可能出現的一種情況就是:A發送完請報文以後,由於網絡情況不好,出現了網絡擁塞,即B延時很長時間後收到報文,即此時A將此報文認定爲失效的報文。B收到報文後,會向A發起連接。此時兩次握手完畢,B會認爲已經建立了連接可以通信,B會一直等到A發送的連接請求,而A對失效的報文回覆自然不會處理。依次會陷入B忙等的僵局,造成資源的浪費。

connect方法會阻塞,請問有什麼方法可以避免其長時間阻塞?

可以考慮採用異步傳輸機制,同步傳輸與異步傳輸的主要區別在於同步傳輸中,如果調用recvfrom後會一致阻塞運行,從而導致調用線程暫停運行;異步傳輸機制則不然,會立即返回。

網絡編程中設計併發服務器,使用多進程與多線程,請問有什麼區別?

答案一:

1,進程:子進程是父進程的複製品。子進程獲得父進程數據空間、堆和棧的複製品。

2,線程:相對與進程而言,線程是一個更加接近與執行體的概念,它可以與同進程的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。兩者都可以提高程序的併發度,提高程序運行效率和響應時間。

線程和進程在使用上各有優缺點:線程執行開銷小,但不利於資源管理和保護;而進程正相反。同時,線程適合於在SMP機器上運行,而進程則可以跨機器遷移。

答案二:

根本區別就一點:用多進程每個進程有自己的地址空間(address space),線程則共享地址空間。所有其它區別都是由此而來的:

1。速度:線程產生的速度快,線程間的通訊快、切換快等,因爲他們在同一個地址空間內。

2。資源利用率:線程的資源利用率比較好也是因爲他們在同一個地址空間內。

3。同步問題:線程使用公共變量/內存時需要使用同步機制還是因爲他們在同一個地址空間內。等等

 

Windows編程的知識點,如消息機制,一個自定義消息如何實現。

       自定義消息共分爲3步驟:

1  自定義消息:#defineWM_MYMSGWM_USER+1

2  在頭文件中聲明函數      afx_msg voidonMyMsg();

3) 在消息映射中添加對應關係:

//BEGIN_MESSAGE_MAP(CDefMsgDemoDlg,CDialog)//END_MESSAGE_MAP()

ON_MESSAGE(WM_MYMSG,onMyMsg)

4)定義函數void onMyMsg();

核心即:函數原型、關聯消息與消息響應函數的宏、函數實現。

 

SNMP協議

       簡單網絡管理協議——應用層協議.

       包括5種數據包:Get-Request;Get-Next-Request;Set-Request, Get-Response; Trap;

RAW套接字

       廣泛應用於高級網絡編程,如SNIFFER、拒絕服務、IP欺騙都是通過原始套接字實現的。

 

窗口創建的步驟:

1)設計窗口類(填充結構體)à2)註冊窗口類RegisterClassà3)創建窗口;4)顯示ShowWindow&更新窗口UpdateWindowà4)循環獲取消息GetMessage(){翻譯(轉換)TranslateMessage消息、處理消息DispathMessage(將消息交付給窗口過程進行處理)}

 

當觸發按鈕以後發生了什麼?

       1)比如點擊鼠標左鍵後,操作系統首先會感知到該事件;2)操作系統將事件其轉化爲消息;3)操作系統將消息投遞到對應程序(線程)的消息隊列中;4)應用程序(線程)從消息隊列中通過GetMessage獲取消息,並通過DispathMessge將消息交付給操作系統;5)操作系統通過設計窗口類時指定的窗口過程對對消息進行處理。

 

你平時是如何調試程序的?(引申)當一個程序在自己機器上運行正常,但是在其他機器上程序運行崩潰,如何查找原因?

斷點調試:

值:查看變量(Variables)、表達式、內存(Memory)、寄存器(Register)的值。

進程控制:VC允許被中斷的程序繼續運行、單步運行和運行到指定光標處,分別對應快捷鍵F5F10/F11CTRL+F10

其他調試手段:系統提供一系列特殊的函數或者宏來處理Debug版本相關的信息TRACEASSERTVERIFyCtrl+B打開斷點設置。

運行崩潰,如何查找原因? [提示後],可以通過打印語句來發現錯誤!

 

線程、窗口、消息隊列三者之間的關係?

MSDN上如是說:

Thethread to which the message is posted musthave created a message queue,or elsethe call to PostThreadMessagefails.  

並提供瞭如下兩種解決方法:

CallPostThreadMessage.If it fails, call theSleep function and call PostThreadMessageagain. Repeat  until PostThreadMessage  succeeds. 

【面試官】說:一個線程對應一個或多個窗口(創建的關係),同時一個線程對應了一個消息隊列。

【總結如下】:
1.MFC程序框架裏面,CWinThread專門負責線程創建的,它可以創建用戶界面線程,及工作者線程。其中用戶界面線程是包含消息隊列的,而工作者線程是不包含消息隊列的。即【一句話】:用戶界面線程對應一個消息隊列。
2.CWinThread類和CWnd類都派生自CCmdTarget,而CDialog對話框類、視圖類CView都派生自CWnd
【深入淺出MFC裏一句話】:不是每一個窗口都產生一個線程(因爲要付出昂貴的線程切換代價)。即,深入理解之:一個線程可以對應多個窗口。主線程可以創建出其所要的全部窗口。
【結論】一個UI線程就1組消息隊列集合,一個線程可以創建多個窗口。

 

OSI 7層模型是什麼? 每層有哪些協議?  

應用層 FTPTelnetSMTPHTTPRIPNFSDNS 表示層 示例:加密,ASCII 會話層 示例:RPCSQL 傳輸層 示例:TCPUDPSPX 

網絡層 示例:IP協議、ICMP協議、ARP協議、RARP協議  數據鏈路層 示例:ATMFDDI 物理層 示例:Rj45802.3 

 

請寫出下列服務使用的默認端口POP3、SMTP、FTP、MSN、DNS、SQL  

端口:21   服務:FTP  

端口:22   服務:SSH  端口:23   服務:Telnet  端口:25   服務:SMTP  端口:80   服務:HTTP  

端口:110   服務:Post Office Protocol -Version3 (pop3) 端口:569     服務:Membership MSN  端口14331434  服務:SQL 

DNS協議運行在UDP之上,使用端口號53

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章