多線程面試題

多線程在筆試面試中經常出現,下面列出一些公司的多線程筆試面試題。首先是一些概念性的問答題,這些是多線程的基礎知識,經常出現在面試中的第一輪面試(我參加2011年騰訊研究院實習生招聘時就被問到了幾個概念性題目)。然後是一些選擇題,這些一般在筆試時出現,雖然不是太難,但如果在選擇題上花費大多時間無疑會對後面的編程題造成影響,因此必須迅速的解決掉。最後是綜合題即難一些的問答題或是編程題。這種題目當然是最難解決了,要麼會引來面試官的追問,要麼就很容易考慮不周全,因此解決這類題目時一定要考慮全面和細緻。

下面就來看看這三類題目吧。

   一。概念性問答題

   第一題:線程的基本概念、線程的基本狀態及狀態之間的關係?

概念:線程是進程中執行運算的最小單位,是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以併發執行。

    好處 :

(1)易於調度。

               (2)提高併發性。通過線程可方便有效地實現併發性。進程可創建多個線程來執行同一程序的不同部分。

               (3)開銷少。創建線程比創建進程要快,所需開銷很少。。

               (4)利於充分發揮多處理器的功能。通過創建多線程進程,每個線程在一個處理器上運行,從而實現應用程序的併發性,使每個處理器都得到充分運行。

狀態:運行、阻塞、掛起阻塞、就緒、掛起就緒

    狀態之間的轉換:準備就緒的進程,被CPU調度執行,變成運行態;

                                 運行中的進程,進行I/O請求或者不能得到所請求的資源,變成阻塞態;

                                 運行中的進程,進程執行完畢(或時間片已到),變成就緒態;

                                 將阻塞態的進程掛起,變成掛起阻塞態,當導致進程阻塞的I/O操作在用戶重啓進程前完成(稱之爲喚醒),掛起阻塞態變成掛起就緒態,當用戶在I/O操作結束之前重啓進程,掛起阻塞態變成阻塞態;

                                 將就緒(或運行)中的進程掛起,變成掛起就緒態,當該進程恢復之後,掛起就緒態變成就緒態;                

    第二題:線程與進程的區別?

   這個題目問到的概率相當大,計算機專業考研中也常常考到。要想全部答出比較難。

進程和線程的關係:

    (1)一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。

    (2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。

    (3)處理機分給線程,即真正在處理機上運行的是線程。

    (4)線程在執行過程中,需要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。線程是指進程內的一個執行單元,也是進程內的可調度實體.

進程與線程的區別:

    (1)調度:線程作爲調度和分配的基本單位,進程作爲擁有資源的基本單位

    (2)併發性:不僅進程之間可以併發執行,同一個進程的多個線程之間也可併發執行

    (3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬於進程的資源.

    (4)系統開銷:在創建或撤消進程時,由於系統都要爲之分配和回收資源,導致系統的開銷明顯大於創建或撤消線程時的開銷。

   第三題:多線程有幾種實現方法,都是什麼?

C++中多線程實現方法:

windows下通過api CreateThread,linux下則常用pthread庫,這些都是最底層的實現,最新的C++11標準裏增加了std::thread多線程庫,使用第三方庫的話就更多了,比如boost的thread等等,不推薦使用vc自家的_beginthread,尤其有跨平臺需求的時候。

Java中實現多線程的方法:

 1. 繼承 Thread 類
    2. 實現 Runnable 接口再 new Thread(YourRunnableOjbect) 推薦

   第四題:多線程同步和互斥有幾種實現方法,都是什麼?

   2011年迅雷校園招聘時的一面和二面都被問到這個題目,回答的好將會給面試成績加不少分。

   線程間的同步方法大體可分爲兩類:用戶模式和內核模式。顧名思義,內核模式就是指利用系統內核對象的單一性來進行同步,使用時需要切換內核態與用戶態,而用戶模式就是不需要切換到內核態,只在用戶態完成操作。
用戶模式下的方法有:原子操作(例如一個單一的全局變量),臨界區。內核模式下的方法有:事件,信號量,互斥量。

   第五題:多線程同步和互斥有何異同,在什麼情況下分別使用他們?舉例說明。

當有多個線程的時候,經常需要去同步這些線程以訪問同一個數據或資源。例如,假設有一個程序,其中一個線程用於把文件讀到內存,而另一個線程用於統計文件中的字符數。當然,在把整個文件調入內存之前,統計它的計數是沒有意義的。但是,由於每個操作都有自己的線程,操作系統會把兩個線程當作是互不相干的任務分別執行,這樣就可能在沒有把整個文件裝入內存時統計字數。爲解決此問題,你必須使兩個線程同步工作。

      所謂同步,是指散步在不同進程之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先後次序來運行,這種先後次序依賴於要完成的特定的任務。如果用對資源的訪問來定義的話,同步是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。

        所謂互斥,是指散佈在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其它進程就不能運行它們之中的任一程序片段,只能等到該進程運行完這個程序片段後纔可以運行。如果用對資源的訪問來定義的話,互斥某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。

     第六題:進程間通信的方式?

    (1)管道(pipe)及有名管道(named pipe):管道可用於具有親緣關係的父子進程間的通信,有名管道除了具有管道所具有的功能外,它還允許無親緣關係進程間的通信。

    (2)信號(signal):信號是在軟件層次上對中斷機制的一種模擬,它是比較複雜的通信方式,用於通知進程有某事件發生,一個進程收到一個信號與處理器收到一箇中斷請求效果上可以說是一致的。

    (3)消息隊列(message queue):消息隊列是消息的鏈接表,它克服了上兩種通信方式中信號量有限的缺點,具有寫權限得進程可以按照一定得規則向消息隊列中添加新信息;對消息隊列有讀權限得進程則可以從消息隊列中讀取信息。

    (4)共享內存(shared memory):可以說這是最有用的進程間通信方式。它使得多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數據得更新。這種方式需要依靠某種同步操作,如互斥鎖和信號量等。

    (5)信號量(semaphore):主要作爲進程之間及同一種進程的不同線程之間得同步和互斥手段。

    (6)套接字(socket):這是一種更爲一般得進程間通信機制,它可用於網絡中不同機器之間的進程間通信,應用非常廣泛。

二。選擇題

   第一題(百度筆試題):

   以下多線程對int型變量x的操作,哪幾個不需要進行同步:

    A.x=y;      B. x++;    C.++x;    D. x=1;

  答案參見:http://blog.csdn.net/jjj19891128/article/details/24392229

    第二題(阿里巴巴筆試題)

   多線程中棧與堆是公有的還是私有的

    A:棧公有, 堆私有

    B:棧公有,堆公有

    C:棧私有, 堆公有D:棧私有,堆私有

一般來說棧是私有的

堆是共有的

但是你可以爲特定的線程創建私有的堆

堆和棧的區別如下:

堆很靈活,但是不安全。對於對象,我們要動態地創建、銷燬,不能說後創建的對象沒有銷燬,先前創建的對象就不能銷燬,那樣的話我們的程序就寸步難行,所以Java中用堆來存儲對象。而一旦堆中的對象被銷燬,我們繼續引用這個對象的話,就會出現著名的 NullPointerException,這就是堆的缺點——錯誤的引用邏輯只有在運行時纔會被發現。

棧不靈活,但是很嚴格,是安全的,易於管理。因爲只要上面的引用沒有銷燬,下面引用就一定還在,所以,在棧中,上面引用永遠可以通過下面引用來查找對象,同時如果確認某一區間的內容會一起存在、一起銷燬,也可以上下互相引用。在大部分程序中,都是先定義的變量、引用先進棧,後定義的後進棧,同時,區塊內部的變量、引用在進入區塊時壓棧,區塊結束時出棧,理解了這種機制,我們就可以很方便地理解各種編程語言的作用域的概念了,同時這也是棧的優點——錯誤的引用邏輯在編譯時就可以被發現。

總之,就是變量和對象的引用存儲在棧區中,而對象在存儲在堆中

三。綜合題

   第一題(臺灣某殺毒軟件公司面試題):

   Windows編程中互斥量與臨界區比較類似,請分析一下二者的主要區別。

        兩者都可以用於同一進程中不同子線程對資源的互斥訪問。

        互斥量是內核對象,因此還可以用於不同進程中子線程對資源的互斥訪問。

        互斥量可以很好的解決由於線程意外終止資源無法釋放的問題。

    第二題:

   一個全局變量tally,兩個線程併發執行(代碼段都是ThreadProc),問兩個線程都結束後,tally取值範圍。

    inttally = 0;//glable

    voidThreadProc()

    {

    forint i = 1; i <= 50;i++

    tally += 1;

    }

 答:[50,100]

   第三題(某培訓機構的練習題):

   子線程循環 10次,接着主線程循環 100次,接着又回到子線程循環 10次,接着再回到主線程又循環 100次,如此循環50次,試寫出代碼。

   第四題(迅雷筆試題):

   編寫一個程序,開啓3個線程,這3個線程的ID分別爲ABC,每個線程將自己的ID在屏幕上打印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC…依次遞推。

   第五題(Google面試題)

   有四個線程1234.線程1的功能就是輸出1,線程2的功能就是輸出2,以此類推……現在有四個文件ABCD.初始都爲空。現要讓四個文件呈如下格式:

    A:1 2 3 4 1 2

    B:2 3 4 1 2 3

    C:3 4 1 2 3 4

    D:4 1 2 3 4 1

   請設計程序。

   下面的第六題與第七題也是在考研中或是程序員和軟件設計師認證考試中的熱門試題。

   第六題

   生產者消費者問題

   這是一個非常經典的多線程題目,題目大意如下:有一個生產者在生產產品,這些產品將提供給若干個消費者去消費,爲了使生產者和消費者能併發執行,在兩者之間設置一個有多個緩衝區的緩衝池,生產者將它生產的產品放入一個緩衝區中,消費者可以從緩衝區中取走產品進行消費,所有生產者和消費者都是異步方式運行的,但它們必須保持同步,即不允許消費者到一個空的緩衝區中取產品,也不允許生產者向一個已經裝滿產品且尚未被取走的緩衝區中投放產品。

   第七題

   讀者寫者問題

   這也是一個非常經典的多線程題目,題目大意如下:有一個寫者很多讀者,多個讀者可以同時讀文件,但寫者在寫文件時不允許有讀者在讀文件,同樣有讀者讀時寫者也不能寫。

   多線程相關題目就列舉到此,如果各位有多線程方面的筆試面試題,歡迎提供給我,我將及時補上。謝謝大家。


參考文章:http://blog.csdn.net/dazhong159/article/details/7948327

一個牛逼的鏈接:http://blog.csdn.net/morewindows/article/details/7392749
程序解答:http://blog.csdn.net/lanyan822/article/details/7587972
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章