寫在前面:
找工做告一段落,期間經歷了不少事情,也思考了許多問題,最後也收穫了一些沉甸甸的東西 —— 成長和一些來自阿里、百度、京東(sp)、華爲等廠的Offer。好在一切又回到正軌,接下來要好好總結一番纔不枉這段經歷,遂將此過程當中筆者的一些筆試/面試心得、乾貨發表出來,與衆共享之。面試
進程和線程以及它們的區別
- 進程是對運行時程序的封裝,是系統進行資源調度和分配的的基本單位,實現了操做系統的併發;
- 線程是進程的子任務,是CPU調度和分派的基本單位,用於保證程序的 實時性,實現進程內部的併發;
- 一個程序至少有一個進程,一個進程至少有一個線程,線程依賴於進程而存在;
- 進程在執行過程當中擁有獨立的內存單元,而多個線程共享進程的內存。
進程間的通訊的幾種方式
- 管道(pipe)及命名管道(named pipe):管道可用於具備親緣關係的父子進程間的通訊,有名管道除了具備管道所具備的功能外,它還容許無親緣關係進程間的通訊;
- 信號(signal):信號是一種比較複雜的通訊方式,用於通知接收進程某個事件已經發生;
- 消息隊列:消息隊列是消息的連接表,它克服了上兩種通訊方式中信號量有限的缺點,具備寫權限得進程能夠按照必定得規則向消息隊列中添加新信息;對消息隊列有讀權限得進程則能夠從消息隊列中讀取信息;
- 共享內存:能夠說這是最有用的進程間通訊方式。它使得多個進程能夠訪問同一塊內存空間,不一樣進程能夠及時看到對方進程中對共享內存中數據得更新。這種方式須要依靠某種同步操做,如互斥鎖和信號量等;
- 信號量:主要做爲進程之間及同一種進程的不一樣線程之間得同步和互斥手段;
- 套接字:這是一種更爲通常得進程間通訊機制,它可用於網絡中不一樣機器之間的進程間通訊,應用很是普遍。
線程同步的方式
- 互斥量 Synchronized/Lock:採用互斥對象機制,只有擁有互斥對象的線程纔有訪問公共資源的權限。由於互斥對象只有一個,因此能夠保證公共資源不會被多個線程同時訪問
- 信號量 Semphare:它容許同一時刻多個線程訪問同一資源,可是須要控制同一時刻訪問此資源的最大線程數量
- 事件(信號),Wait/Notify:經過通知操做的方式來保持多線程同步,還能夠方便的實現多線程優先級的比較操做
什麼是死鎖?死鎖產生的條件?
死鎖的概念算法
在兩個或者多個併發進程中,若是每一個進程持有某種資源而又等待其它進程釋放它或它們如今保持着的資源,在未改變這種狀態以前都不能向前推動,稱這一組進程產生了死鎖。通俗的講,就是兩個或多個進程無限期的阻塞、相互等待的一種狀態。安全
死鎖產生的四個必要條件網絡
- 互斥:至少有一個資源必須屬於非共享模式,即一次只能被一個進程使用;若其餘申請使用該資源,那麼申請進程必須等到該資源被釋放爲止;
- 佔有並等待:一個進程必須佔有至少一個資源,並等待另外一個資源,而該資源爲其餘進程所佔有;
- 非搶佔:進程不能被搶佔,即資源只能被進程在完成任務後自願釋放
- 循環等待:若干進程之間造成一種頭尾相接的環形等待資源關係
死鎖的處理基本策略和經常使用方法多線程
解決死鎖的基本方法主要有 預防死鎖、避免死鎖、檢測死鎖、解除死鎖 、鴕鳥策略 等。併發
死鎖預防分佈式
死鎖預防的基本思想是 只要確保死鎖發生的四個必要條件中至少有一個不成立,就能預防死鎖的發生,具體方法包括:性能
- 打破互斥條件:容許進程同時訪問某些資源。可是,有些資源是不能被多個進程所共享的,這是由資源自己屬性所決定的,所以,這種辦法一般並沒有實用價值。
- 打破佔有並等待條件:能夠實行資源預先分配策略(進程在運行前一次性向系統申請它所須要的所有資源,若所需所有資源得不到知足,則不分配任何資源,此進程暫不運行;只有當系統能知足當前進程所需的所有資源時,才一次性將所申請資源所有分配給該線程)或者只容許進程在沒有佔用資源時才能夠申請資源(一個進程可申請一些資源並使用它們,可是在當前進程申請更多資源以前,它必須所有釋放當前所佔有的資源)。可是這種策略也存在一些缺點:在不少狀況下,沒法預知一個進程執行前所需的所有資源,由於進程是動態執行的,不可預知的;同時,會下降資源利用率,致使下降了進程的併發性。
- 打破非搶佔條件:容許進程強行從佔有者哪裏奪取某些資源。也就是說,但一個進程佔有了一部分資源,在其申請新的資源且得不到知足時,它必須釋放全部佔有的資源以便讓其它線程使用。這種預防死鎖的方式實現起來困難,會下降系統性能。
- 打破循環等待條件:實行資源有序分配策略。對全部資源排序編號,全部進程對資源的請求必須嚴格按資源序號遞增的順序提出,即只有佔用了小號資源才能申請大號資源,這樣就不回產生環路,預防死鎖的發生。
死鎖避免的基本思想操作系統
死鎖避免的基本思想是動態地檢測資源分配狀態,以確保循環等待條件不成立,從而確保系統處於安全狀態。所謂安全狀態是指:若是系統能按某個順序爲每一個進程分配資源(不超過其最大值),那麼系統狀態是安全的,換句話說就是,若是存在一個安全序列,那麼系統處於安全狀態。資源分配圖算法和銀行家算法是兩種經典的死鎖避免的算法,其能夠確保系統始終處於安全狀態。其中,資源分配圖算法應用場景爲每種資源類型只有一個實例(申請邊,分配邊,需求邊,不造成環才容許分配),而銀行家算法應用於每種資源類型能夠有多個實例的場景。線程
死鎖解除
死鎖解除的經常使用兩種方法爲進程終止和資源搶佔。**所謂進程終止是指簡單地終止一個或多個進程以打破循環等待,包括兩種方式:終止全部死鎖進程和一次只終止一個進程直到取消死鎖循環爲止;**所謂資源搶佔是指從一個或多個死鎖進程那裏搶佔一個或多個資源,此時必須考慮三個問題:
- 選擇一個犧牲品
- 回滾:回滾到安全狀態
- 飢餓(在代價因素中加上回滾次數,回滾的越多則越不可能繼續被做爲犧牲品,避免一個進程老是被回滾)
進程有哪幾種狀態?
- 就緒狀態:進程已得到除處理機之外的所需資源,等待分配處理機資源;
- 運行狀態:佔用處理機資源運行,處於此狀態的進程數小於等於CPU數;
- 阻塞狀態: 進程等待某種條件,在條件知足以前沒法執行;
線程有幾種狀態?
在 Java虛擬機 中,**線程從最初的建立到最終的消亡,要經歷若干個狀態:建立(new)、就緒(runnable/start)、運行(running)、阻塞(blocked)、等待(waiting)、時間等待(time waiting) 和 消亡(dead/terminated)。**在給定的時間點上,一個線程只能處於一種狀態,各狀態的含義以下圖所示:
線程各狀態之間的轉換以下:
分頁和分段有什麼區別(內存管理)?
段式存儲管理是一種符合用戶視角的內存分配管理方案。**在段式存儲管理中,將程序的地址空間劃分爲若干段(segment),如代碼段,數據段,堆棧段;這樣每一個進程有一個二維地址空間,相互獨立,互不干擾。**段式管理的優勢是:沒有內碎片(由於段大小可變,改變段大小來消除內碎片)。但段換入換出時,會產生外碎片(好比4k的段換5k的段,會產生1k的外碎片)
頁式存儲管理方案是一種用戶視角內存與物理內存相分離的內存分配管理方案。在頁式存儲管理中,將程序的邏輯地址劃分爲固定大小的頁(page),而物理內存劃分爲一樣大小的幀,程序加載時,能夠將任意一頁放入內存中任意一個幀,這些幀沒必要連續,從而實現了離散分離。頁式存儲管理的優勢是:沒有外碎片(由於頁的大小固定),但會產生內碎片(一個頁可能填充不滿)。
二者的不一樣點:
- 目的不一樣:分頁是因爲系統管理的須要而不是用戶的須要,它是信息的物理單位;分段的目的是爲了能更好地知足用戶的須要,它是信息的邏輯單位,它含有一組其意義相對完整的信息;
- 大小不一樣:頁的大小固定且由系統決定,而段的長度卻不固定,由其所完成的功能決定;
- 地址空間不一樣: 段向用戶提供二維地址空間;頁向用戶提供的是一維地址空間;
- 信息共享:段是信息的邏輯單位,便於存儲保護和信息的共享,頁的保護和共享受到限制;
- 內存碎片:頁式存儲管理的優勢是沒有外碎片(由於頁的大小固定),但會產生內碎片(一個頁可能填充不滿);而段式管理的優勢是沒有內碎片(由於段大小可變,改變段大小來消除內碎片)。但段換入換出時,會產生外碎片(好比4k的段換5k的段,會產生1k的外碎片)。
操做系統中進程調度策略有哪幾種?
- FCFS(先來先服務,隊列實現,非搶佔的):先請求CPU的進程先分配到CPU
- SJF(最短做業優先調度算法):平均等待時間最短,但難以知道下一個CPU區間長度
- 優先級調度算法(能夠是搶佔的,也能夠是非搶佔的):優先級越高越先分配到CPU,相同優先級先到先服務,存在的主要問題是:低優先級進程無窮等待CPU,會致使無窮阻塞或飢餓;解決方案:老化
- 時間片輪轉調度算法(可搶佔的):隊列中沒有進程被分配超過一個時間片的CPU時間,除非它是惟一可運行的進程。若是進程的CPU區間超過了一個時間片,那麼該進程就被搶佔並放回就緒隊列。
- 多級隊列調度算法:將就緒隊列分紅多個獨立的隊列,每一個隊列都有本身的調度算法,隊列之間採用固定優先級搶佔調度。其中,一個進程根據自身屬性被永久地分配到一個隊列中。
- 多級反饋隊列調度算法:與多級隊列調度算法相比,其容許進程在隊列之間移動:若進程使用過多CPU時間,那麼它會被轉移到更低的優先級隊列;在較低優先級隊列等待時間過長的進程會被轉移到更高優先級隊列,以防止飢餓發生。
說一說進程同步有哪幾種機制
原子操做、信號量機制、自旋鎖管程、會合、分佈式系統
什麼是虛擬內存?
內存的發展歷程
沒有內存抽象(單進程,除去操做系統所用的內存以外,所有給用戶程序使用) —> 有內存抽象(多進程,進程獨立的地址空間,交換技術(內存大小不可能容納下全部併發執行的進程)
)—> 連續內存分配(固定大小分區(多道程序的程度受限),可變分區(首次適應,最佳適應,最差適應),碎片) —> 不連續內存分配(分段,分頁,段頁式,虛擬內存)
虛擬內存
虛擬內存容許執行進程沒必要徹底在內存中。虛擬內存的基本思想是:每一個進程擁有獨立的地址空間,這個空間被分爲大小相等的多個塊,稱爲頁(Page),每一個頁都是一段連續的地址。這些頁被映射到物理內存,但並非全部的頁都必須在內存中才能運行程序。當程序引用到一部分在物理內存中的地址空間時,由硬件馬上進行必要的映射;當程序引用到一部分不在物理內存中的地址空間時,由操做系統負責將缺失的部分裝入物理內存並從新執行失敗的命令。這樣,**對於進程而言,邏輯上彷佛有很大的內存空間,實際上其中一部分對應物理內存上的一塊(稱爲幀,一般頁和幀大小相等),還有一些沒加載在內存中的對應在硬盤上,**以下圖所示。
注意,請求分頁系統、請求分段系統和請求段頁式系統都是針對虛擬內存的,經過請求實現內存與外存的信息置換。
由上圖能夠看出,虛擬內存實際上能夠比物理內存大。當訪問虛擬內存時,會訪問MMU(內存管理單元)去匹配對應的物理地址(好比上圖的0,1,2)。若是虛擬內存的頁並不存在於物理內存中(如上圖的3,4),會產生缺頁中斷,從磁盤中取得缺的頁放入內存,若是內存已滿,還會根據某種算法將磁盤中的頁換出。
頁面置換算法
- FIFO先進先出算法:在操做系統中常常被用到,好比做業調度(主要實現簡單,很容易想到);
- LRU(Least recently use)最近最少使用算法:根據使用時間到如今的長短來判斷;
- LFU(Least frequently use)最少使用次數算法:根據使用次數來判斷;
- OPT(Optimal replacement)最優置換算法:理論的最優,理論;就是要保證置換出去的是再也不被使用的頁,或者是在實際內存中最晚使用的算法。
虛擬內存的應用與優勢
虛擬內存很適合在多道程序設計系統中使用,許多程序的片斷同時保存在內存中。當一個程序等待它的一部分讀入內存時,能夠把CPU交給另外一個進程使用。虛擬內存的使用能夠帶來如下好處:
- 在內存中能夠保留多個進程,系統併發度提升
- 解除了用戶與內存之間的緊密約束,進程能夠比內存的所有空間還大
顛簸
顛簸本質上是指頻繁的頁調度行爲,具體來說,進程發生缺頁中斷,這時,必須置換某一頁。然而,其餘全部的頁都在使用,它置換一個頁,但又馬上再次須要這個頁。所以,會不斷產生缺頁中斷,致使整個系統的效率急劇降低,這種現象稱爲顛簸(抖動)。
內存顛簸的解決策略包括:
- 若是是由於頁面替換策略失誤,能夠修改替換算法來解決這個問題;
- 若是是由於運行的程序太多,形成程序沒法同時將全部頻繁訪問的頁面調入內存,則要下降多道程序的數量;
- 不然,還剩下兩個辦法:終止該進程或增長物理內存容量。
局部性原理
- 時間上的局部性:最近被訪問的頁在不久的未來還會被訪問;
- 空間上的局部性:內存中被訪問的頁周圍的頁也極可能被訪問。
END
喜歡的朋友記得點點贊和關注,支持下筆者,謝謝啦