線程、進程和多線程是面試過程中很容易遇到的問題,去年百度三面的時候就遇到這個問題,當時百度hr問到:線程和進程的區別是什么?你寫過多進程或者多線程的程序嗎?在你看來多線程和多進程程序那種程序比較難寫?
第一個問題很常規,但是要完全答對卻不是那么容易,現在想來,第二個問題和第三個問題實際是一個問題,因為第三個問題是驗證第二個問題是否說實話的最好的方式。另外,在今年4月6號微軟的筆試中,也考到了這第一個個問題,那么,這么方面到底會有哪些問題呢?如果要復習從哪些方面着手呢?
首先,從面試問題的角度,經過網上搜集,我認為會被問到如下問題。
1.進程和線程有什么區別?
這個一個最常見,卻最不好回答的問題,csdn上面一位博主給出的解答和另一位cnblog博主的解答稍微清晰些一些,總結起來,就是一下的幾個區別:
a.進程是資源分配的基本單位,線程是cpu調度,或者說是程序執行的最小單位。在Mac、Windows NT等采用微內核結構的操作系統中,進程的功能發生 了變化:它只是資源分配的單位,而不再是調度運行的單位。在微內核系統中,真正調度運行的基本單位是線程。因此,實現並發功能的單位是線程。
b.進程有獨立的地址空間,比如在linux下面啟動一個新的進程,系統必須分配給它獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和數據 段,這是一種非常昂貴的多任務工作方式。而運行一個進程中的線程,它們之間共享大部分數據,使用相同的地址空間,因此啟動一個線程,切換一個線 程遠比進程操作要快,花費也要小得多。當然,線程是擁有自己的局部變量和堆棧(注意不是堆)的,比如在windows中用_beginthreadex創建一個新 進程就會在調用CreateThread的同時申請一個專屬於線程的數據塊(_tiddata)。
c.線程之間的通信比較方便。統一進程下的線程共享數據(比如全局變量,靜態變量),通過這些數據來通信不僅快捷而且方便,當然如何處理好這些訪問 的同步與互斥正是編寫多線程程序的難點。而進程之間的通信只能通過進程通信的方式進行。
d.由b,可以輕易地得到結論:多進程比多線程程序要健壯。一個線程死掉整個進程就死掉了,但是在保護模式下,一個進程死掉對另一個進程沒有直接影 響。
e.線程的執行與進程是有區別的。每個獨立的線程有有自己的一個程序入口,順序執行序列和程序的出口,但是線程不能獨立執行,必須依附與程序之中, 由應用程序提供多個線程的並發控制。
2. 什么是線程安全?(2012年5月百度實習生面試)
如果多線程的程序運行結果是可預期的,而且與單線程的程序運行結果一樣,那么說明是“線程安全”的。
3. 秒殺多線程中的題目 解答
另外,這個網址里面講操作系統的知識倒是挺詳實的,還有另外一種解釋線程概念
b.多線程的幾種實現方法分別是什么?
這個貌似在java面試中會出現,我是專注於c++的,無視掉,但是不得不說,秒殺多線程面試題系列真心是個好總結
c.多線程同步與互斥有幾種實現方法?都是什么?(C++)
臨界區(CS:critical section)、事件(Event)、互斥量(Mutex)、信號量(semaphores),需要注意的是,臨界區是效率最高的,因為基本不需要其 他的開銷,二內核對象涉及到用戶態和內核態的切換,開銷較大,另外,關鍵段、互斥量具有線程所有權的概念,因此只可以用於線程之間互斥,而不能用到 同步中。只有互斥量能完美解決進程意外終止所造成的“遺棄問題”。
d.多線程同步和互斥有何異同,在什么情況下分別使用他們?舉例說明
所謂同步,表示有先有后,比較正式的解釋是“線程同步是指線程之間所具有的一種制約關系,一個線程的執行依賴另一個線程的消息,當它沒有得到另一個 線程的消息時應等待,直到消息到達時才被喚醒。”所謂互斥,比較正式的說明是“線程互斥是指對於共享的進程系統資源,在各單個線程訪問時的排它性。當 有若干個線程都要使用某一共享資源時,任何時刻最多只允許一個線程去使用,其它要使用該資源的線程必須等待,直到占用資源者釋放該資源。線程互斥 可以看成是一種特殊的線程同步。”表示不能同時訪問,也是個順序問題,所以互斥是一種特殊的同步操作。
舉個例子,設有一個全局變量global,為了保證線程安全,我們規定只有當主線程修改了global之后下一個子線程才能訪問global,這就需要同步主線程與子 線程,可用關鍵段實現。當一個子線程訪問global的時候另一個線程不能訪問global,那么就需要互斥。
e.以下多線程對int型變量x的操作,哪幾個需要進行同步:
A. x=y; B. x++; C. ++x; D. x=1;
答案是ABC,顯然,y的寫入與x讀y要同步,x++和++x都要知道x之前的值,所以也要同步。
f.多線程中棧與堆是公有的還是私有的
A:棧公有, 堆私有
B:棧公有,堆公有
C:棧私有, 堆公有
D:棧私有,堆私有
答案是C,棧一般存放局部變量,而程序員一般自己申請和釋放堆中的數據(詳見堆與棧的區別)。
g.在Windows編程中互斥量與臨界區比較類似,請分析一下二者的主要區別。
針對這個題目的話,答案主要有以下幾點:
1)互斥量是內核對象,所以它比臨界區更加耗費資源,但是它可以命名,因此可以被其它進程訪問
2)從目的是來說,臨界區是通過對多線程的串行化來訪問公共資源或一段代碼,速度快,適合控制數據訪問。
互斥量是為協調共同對一個共享資源的單獨訪問而設計的。
h.一個全局變量tally,兩個線程並發執行(代碼段都是ThreadProc),問兩個線程都結束后,tally取值范圍。
inttally = 0;//global voidThreadProc() { for(inti = 1; i <= 50; i++) tally += 1; }
當兩線程串行時,結果最大為100,當某個線程運行結束,而此時另外一個線程剛取出0,還未計算時,結果最小為50。
其它題目未完待續。。。。