最近面試遇到的Windows相關的題目

上週準備在公司內部轉崗,面了3個部門windows客戶端相關的工做,最終拿到3個Offer,主要涉及C++和Windows兩大塊內容,C++的題目基本都答上了,Windows一直都是個人弱項,在這裏記錄一下Windows相關的題目。有些答不上的問題就沒列出來,還有些問題忘了,下面的答案有些大部分是我本身的理解,有些是直接從網上copy的,有問題你們能夠討論。面試

1:GetMessage和PeekMessage的區別?windows

GetMessage:獲取消息隊列中的一個消息,存入MSG中,並從消息隊列中移除,若是消息隊列中沒有消息就會阻塞;併發

PeekMessage:查看消息,有消息,就將數據存入MSG結構中,沒有消息就返回FALSE,不會阻塞,但若是沒有更新區,能夠移除WM_PAINT消息,還能夠經過最後一個參數來決定是否從隊列中移除查看的消息;app

2:SendMessage和PostMessage的區別?怎麼跨線程發消息?怎麼跨進程發消息?SendMessage在進程間發消息要注意什麼?SendMessage能將消息發送到消息隊列嗎?PostMessage能夠在進程間發消息嗎?兩個線程互相SendMessage會出問題嗎?函數

SendMessage:將一個消息發送到指定窗口的窗口過程當中,等窗口過程執行完了再返回;高併發

PostMessage:將消息發送到指定窗口所在線程的消息隊列中,直接返回,消息是否被處理徹底不知道;優化

SendMessage直接調用窗口過程,那它是否能夠將消息發送到發送到線程的消息隊列中呢?spa

能夠啊,好比發送一個WM_PAINT消息,這是一個隊列消息,只有存在無效區域的狀況下,纔會處理WM_PAINT消息;線程

線程間SendMessage,因爲它基本就是調用指定窗口的窗口過程,當跨線程發消息的時候,沒法調用指定窗口的窗口過程,在跨線程發送;指針

消息的時候,發送線程會先掛起,由系統線程將消息發送到接收線程的另外一個隊列中,並設置QS_SENDMESSAGE標誌,當系統檢測到這個標誌後,就會處理這個隊列的消息,當這個消息被處理以後,調用SendMessage的線程就會被喚醒,就繼續執行。

SendMessage是能夠跨進程發消息的,經過FindWindow找到對方進程的窗口句柄,發一個消息過去就好了,因爲兩個進程間的內存是徹底獨立的,不能髮指針,若是要發數據,就用WM_COPYDATA。

PostMessage能夠在進程間發消息,但不能結合WM_COPYDATA使用,WM_COPYDATA經過內存映射在進程間傳遞數據,PostMessage後映射文件的句柄就無效了。

兩個線程互相SendMessage可能會致使死鎖,A線程鎖住一個資源,向B線程發一個消息,A線程掛起,這時若是B線程在處理A線程的消息須要A線程鎖住的資源,A因爲發給B的消息尚未處理完就一直不能返回,鎖也沒有打開,B線程又用不了,消息也就處理不完,結果就死鎖了。

3:Windows是怎麼實現窗口刷新的?怎麼實現窗口的當即刷新?

Update Region不爲空時,系統就會自動產生WM_PAINT消息,經過InvalidateRect和InvalidateRgn可把指定的區域加到窗口的Update Region中,經過處理WM_PAINT消息來實現窗口的刷新。 系統爲何不在調用Invalidate時發送WM_PAINT消息呢?又爲何非要等應用消息隊列爲空時才發送WM_PAINT消息呢?這是由於系統把在窗口中的繪製操做看成一種低優先級的操做,因而儘量地推後作。不過這樣也有利於提升繪製的效率:兩個WM_PAINT消息之間經過InvalidateRect和InvaliateRgn使之失效的區域就會被累加起來,而後在一個WM_PAINT消息中一次獲得更新,不只能避免屢次重複地更新同一區域,也優化了應用的更新操做。

若是窗口更新的區域不爲空,UpdateWindow函數經過發送一個WM_PAINT消息來更新指定窗口的客戶區。函數繞過應用程序的消息隊列,直接發送WM_PAINT消息給指定窗口的窗口過程,若是更新區域爲空,則不發送消息。

WM_PAINT通常在消息隊列中沒有消息的時候才處理,有時候咱們須要當即刷新窗口,那麼就須要UpdateWindow函數了,直接繞過消息循環,只要更新區域不爲空,將WM_PAINT消息直接發送到指定窗口過程便可。

Invalidate(hwnd); //將窗口設爲不可用,致使更新區域不爲空

UpdateWindow(hwnd); //當即刷新窗口 

4:Windows消息循環有哪幾個函數,各自的做用是什麼?消息循環是怎麼退出的?

while(GetMessage(&msg, NULL, 0, 0)) //獲取一個消息,成功後會放在msg中。

{      

 TranslateMessage(&msg); //消息進行必要的處理轉換。     

 DispatchMessage(&msg); //調用WinProc,將msg的各項信息傳遞給WinProc
}

當GetMessage獲取到的消息是WM_QUIT,返回的就是FALSE,while循環就退出了,消息循環也就終止了。

5:句柄是什麼?

句柄就是一個整數,Windows爲每個控件指定了一個惟一的整數,經過這個整數和相關函數操做控件。

6:Windows實現線程間同步有哪些方法?實現進程間同步又有哪些方法?讀寫鎖的實現原理是什麼?

1:volatile

2:關鍵段

3:旋轉鎖

4:讀寫鎖

5:事件對象

6:信號量

7:互斥量

只要是內核對象,就能用於進程間的同步,內核對象不屬於任何進程,由系統管理。

讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分紅讀者和寫者,讀者只對共享資源進行讀訪問,寫者則須要對共享資源進行寫操做。這種鎖相對於自旋鎖而言,能提升併發性,由於在多處理器系統中,它容許同時有多個讀者來訪問共享資源,最大可能的讀者數爲實際的邏輯CPU數。寫者是排他性的,一個讀寫鎖同時只能有一個寫者或多個讀者 (與CPU數相關),但不能同時既有讀者又有寫者。我以爲他其實就是對關鍵段和內核事件對象的封裝。寫的時候獨佔,讀的時候共享。

7:模態窗口的實現原理?模態窗口會致使崩潰嗎?

模態窗口其實就是在當前窗口調用系統的消息循環,響應用戶的操做,將相關的消息發送到對應的窗口。將父窗口設爲不可用,即不能響應用戶的操做,在關閉當前窗口的時候,將父窗口設爲可用,並退出消息循環。

可能致使窗口崩潰,模態窗口顯示的時候,除了父窗口不可用以外,其餘的窗口都是可用的,若是須要的一個資源在別的地方被釋放了,而在模態窗口中使用的時候,沒有判斷可能就會致使崩潰。

8:你瞭解沙箱,UAC相關的知識嗎?

不瞭解

9:怎麼實現線程間發消息?線程的消息隊列默認會建立嗎?

SendMessage能夠再線程間發消息,PostThreadMessage經過線程ID能夠在線程間發消息,將消息發送到指定線程的消息隊列中。線程的消息隊列默認是不會建立的,由於線程的消息隊列並非必須的。經過ResumeThread(threadHwnd);能夠建立線程的消息隊列。

10:說說Windows的內存管理,怎麼實現內存共享?

FileMapping用於將存在於磁盤的文件放進一個進程的虛擬地址空間,並在該進程的虛擬地址空間中產生一個區域用於「存放」該文件,這個空間就叫作 File View,系統並同時產生一個File Mapping Object(存放於物理內存中)用於維持這種映射關係,這樣當多個進程須要讀寫那個文件的數據時,它們的File View其實對應的都是同一個File  Mapping  Object,這樣作可節省內存和保持數據的同步性,並達到數據共享的目的。

 

第四輪面試官:若是加班嚴重你來嗎?

阿漢:不來

第四輪面試官:你肯定嗎?

阿漢:肯定

第四輪面試官:我沒有問題了,你還有什麼要問的嗎?

接下來是第五輪面試……我只是內部轉崗啊,面了五輪整整四個小時,最後哥仍是從了這個部門。

相關文章
相關標籤/搜索