雙指針,hash表。node
l Volatile: 對於一段代碼中的變量,若是沒有加volatile關鍵字申明,那麼編譯器將會進行優化,假定該變量首次和第二次出現之間,沒有修改,直接預讀取以前的值。而加入volatile,則告訴編譯器不要進行這樣的優化,避免出現寄存器修改,使得每次都從地址中去讀取這個值。react
數組能夠處理一組數據類型相同的數據,但不容許動態定義數組的大小,在使用以前必須肯定數組的長度,而鏈表能夠動態分配。linux
從邏輯結構上看,數組必須固定長度,不能適應數據動態增減的狀況,容易溢出或內存浪費;鏈表可適應數據動態增減,且能夠方便插入、刪除。ios
從內存角度來看,數組從棧中分配空間(用new則在堆上建立),對程序員方便快速,可是自由度小;鏈表從堆中分配空間,自由度大可是申請管理比較麻煩。c++
從訪問方式類看,數組在內存中是連續的存儲,所以能夠利用下標索引進行訪問;鏈表是鏈式存儲結構,在訪問元素時候只可以經過線性方式由前到後順序的訪問,因此訪問效率比數組要低。程序員
在C++中,Struct和class同樣能包含成員函數,可以繼承和多態。區別在於算法
默認是public繼承仍是private繼承,取決於子類而不是基類。sql
即struct能夠繼承class,一樣class也能夠繼承struct,那麼默認的繼承訪問權限是看子類究竟是用的struct仍是class。以下:shell
struct A{};class B : A{}; //private繼承
struct C : B{}; //public繼承數據庫
進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源.一個線程能夠建立和撤銷另外一個線程;同一個進程中的多個線程之間能夠併發執行.
進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。
http://blog.csdn.net/gatieme/article/details/50908749
TCP提供可靠的通訊傳輸,而UDP則常被用於讓廣播和細節控制交給應用的通訊傳輸。
TCP充分實現數據傳輸時各類控制功能,能夠進行丟包的重發控制,還能夠對次序亂掉的分包進行順序控制。而這些在UDP中都沒有。此外,TCP做爲一種面向有鏈接的協議,只有在確認通訊對端存在時纔會發送數據,從而能夠控制通訊流量的浪費。TCP經過檢驗和、序列號、確認應答、重發控制、鏈接管理以及窗口控制等機制實現可靠性傳輸。
TCP用於在傳輸層有必要實現可靠性傳輸的狀況。因爲它是面向有鏈接並具有順序控制、重發控制等機制的。因此它能夠爲應用提供可靠傳輸。另外一方面,UDP主要用於那些對高速傳輸和實時性有較高要求的通訊或廣播通訊。
TCP與UDP區別總結:
一、TCP面向鏈接(如打電話要先撥號創建鏈接);UDP是無鏈接的,即發送數據以前不須要創建鏈接
二、TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付
三、TCP面向字節流,其實是TCP把數據當作一連串無結構的字節流;UDP是面向報文的。UDP沒有擁塞控制,所以網絡出現擁塞不會使源主機的發送速率下降(對實時應用頗有用,如IP電話,實時視頻會議等)
四、每一條TCP鏈接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通訊
五、TCP首部開銷20字節;UDP的首部開銷小,只有8個字節
六、TCP的邏輯通訊信道是全雙工的可靠信道,UDP則是不可靠信道
1. RUDP(Reliable UDP)
可靠用戶數據報協議(RUDP)是一種基於可靠數據協議(RDP)的簡單分組傳輸協議,用於傳輸 IP 網絡間的電話信號。RUDP 提供一組數據服務質量加強機制,如擁塞控制的改進、重發機制及淡化服務器算法等,從而在包丟失和網絡擁塞的狀況下, RTP 客戶機(實時位置)面前呈現的就是一個高質量的 RTP 流。在不干擾協議的實時特性的同時,可靠 UDP 的擁塞控制機制容許 TCP 方式下的流控制行爲。爲了與網絡 TCP 通訊量同時工做, RUDP 使用相似於 TCP 的重發機制和擁塞控制算法。
2. RTP(Real Time Protocol)
RTP,實時協議被用來爲應用程序如音頻,視頻等的實時數據的傳輸提供端到端(end to end)的網絡傳輸功能。傳輸的模型能夠是單點傳送或是多點傳送。數據傳輸被一個姐妹協議——實時控制協議(RTCP)來監控,後者容許在一個大的多點傳送網絡上監視數據傳送,而且提供最小限度的控制和識別功能。
3. UDT (UDP-based Data Transfer Protocol,簡稱UDT)
基於UDP的數據傳輸協議是一種互聯網數據傳輸協議。UDT的主要目的是支持高速廣域網上的海量數據傳輸,而互聯網上的標準數據傳輸協議TCP在高帶寬長距離網絡上性能不好。 顧名思義,UDT建於UDP之上,並引入新的擁塞控制和數據可靠性控制機制。UDT是面向鏈接的雙向的應用層協議。它同時支持可靠的數據流傳輸和部分可靠的數據報傳輸。 因爲UDT徹底在UDP上實現,它也能夠應用在除了高速數據傳輸以外的其它應用領域,例如點到點技術(P2P),防火牆穿透,多媒體數據傳輸等等。
系統調用、異常、中斷。
Ps:用戶態的程序能夠經過三種方式訪問內核態的資源:系統調用、庫函數、shell腳本。
答:能,局部會屏蔽全局。要用全局變量,須要使用"::" 。局部變量能夠與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對於有些編譯器而言,在同一個函數內能夠定義多個同名的局部變量,好比在兩個循環體內都定義一個同名的局部變量,而那個局部變量的做用域就在那個循環體內
答:extern 。能夠用引用頭文件的方式,也能夠用extern關鍵字,若是用引用頭文件方式來引用某個在頭文件中聲明的全局變理,假定你將那個變寫錯了,那麼在編譯期間會報錯,若是你用extern方式引用時,假定你犯了一樣的錯誤,那麼在編譯期間不會報錯,而在鏈接期間報錯。
使用3個指針遍歷單鏈表,逐個連接點進行反轉
所謂死鎖,是指多個進程循環等待它方佔有的資源而無限期地僵持下去的局面。eg: 進程A佔有資源R1,等待進程B佔有的資源Rr;進程B佔有資源Rr,等待進程A佔有的資源R1。並且資源R1和Rr只容許一個進程佔用,即:不容許兩個進程同時佔用。結果,兩個進程都不能繼續執行,若不採起其它措施,這種循環等待情況會無限期持續下去,就發生了進程死鎖。
計算機系統產生死鎖的根本緣由就是資源有限且操做不當。即一種緣由是系統提供的資源太少了,遠不能知足併發進程對資源的需求。另外一種緣由是因爲進程推動順序不合適引起的死鎖。
計算機系統只有同時具有如下四個條件纔會發生死鎖。
〈1〉互斥條件。即某個資源在一段時間內只能由一個進程佔有,不能同時被兩個或兩個以上的進程佔有。這種獨佔資源如CD-ROM驅動器,打印機等等,必須在佔有該資源的進程主動釋放它以後,其它進程才能佔有該資源。這是由資源自己的屬性所決定的。如獨木橋就是一種獨佔資源,兩方的人不能同時過橋。
〈2〉不可搶佔條件。進程所得到的資源在未使用完畢以前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者進程自行釋放。如過獨木橋的人不能強迫對方後退,也不能非法地將對方推下橋,必須是橋上的人本身過橋後空出橋面(即主動釋放佔有資源),對方的人才能過橋。
〈3〉佔有且申請條件。進程至少已經佔有一個資源,但又申請新的資源;因爲該資源已被另外進程佔有,此時該進程阻塞;可是,它在等待新資源之時,仍繼續佔用已佔有的資源。還以過獨木橋爲例,甲乙兩人在橋上相遇。甲走過一段橋面(即佔有了一些資源),還須要走其他的橋面(申請新的資源),但那部分橋面被乙佔有(乙走過一段橋面)。甲過不去,前進不能,又不後退;乙也處於一樣的情況。
〈4〉循環等待條件。存在一個進程等待序列{P1,P2,...,Pn},其中P1等待P2所佔有的某一資源,P2等待P3所佔有的某一源,......,而Pn等待P1所佔有的的某一資源,造成一個進程循環等待環。就像前面的過獨木橋問題,甲等待乙佔有的橋面,而乙又等待甲佔有的橋面,從而彼此循環等待。
1)打破互斥條件。容許進程同時訪問某些資源,不可取。
2)打破不可搶佔條件。容許進程強行從佔有者那裏奪取某些資源,實現困難下降性能。
3)打破佔有且申請條件。能夠實行資源預先分配策略。即進程在運行前一次性地向系統申請它所須要的所有資源。若是某個進程所需的所有資源得不到知足,則不分配任何資源,此進程暫不運行。只有當系統可以知足當前進程的所有資源需求時,才一次性地將所申請的資源所有分配給該進程。因爲運行的進程已佔有了它所需的所有資源,因此不會發生佔有資源又申請資源的現象,所以不會發生死鎖。可是,這種策略也有以下缺點:
l 在許多狀況下,一個進程在執行以前不可能知道它所須要的所有資源。這是因爲進程在執行時是動態的,不可預測的;
l 資源利用率低。不管所分資源什麼時候用到,一個進程只有在佔有所需的所有資源後才能執行。即便有些資源最後才被該進程用到一次,但該進程在生存期間卻一直佔有它們,形成長期佔着不用的情況。這顯然是一種極大的資源浪費;
l 下降了進程的併發性。由於資源有限,又加上存在浪費,能分配到所需所有資源的進程個數就必然少了。
物理地址:用於內存芯片級的單元尋址,與處理器和CPU鏈接的地址總線相對應。
邏輯地址:邏輯地址指的是機器語言指令中,用來指定一個操做數或者是一條指令的地址。
線性地址:跟邏輯地址相似,它也是一個不真實的地址,若是邏輯地址是對應的硬件平臺段式管理轉換前地址的話,那麼線性地址則對應了硬件頁式內存的轉換前地址。
類中除了定義的函數成員,還有一個成員是虛函數表指針(佔四個基本內存單元),這個指針指向一個虛函數表的起始位置,這個表會與類的定義同時出現,這個表存放着該類的虛函數指針,調用的時候能夠找到該類的虛函數表指針,經過虛函數表指針找到虛函數表,經過虛函數表的偏移找到函數的入口地址,從而找到要使用的虛函數。
父類和子類出現同名函數稱爲隱藏。父類和子類出現同名虛函數稱爲覆蓋。
特色:當咱們在父類中經過virtual修飾析構函數以後,經過父類指針指向子類對象,經過delete接父類指針就能夠釋放掉子類對象。
解決問題:經過父類指針操做子類對象的成員函數的時候是沒有問題的,但是在銷燬對象內存的時候則只是執行了父類的析構函數,子類的析構函數卻沒有執行,這會致使內存泄漏,即多態中的內存泄漏問題。
原理:若是父類當中定義了虛析構函數,那麼父類的虛函數表當中就會有一個父類的虛析構函數的入口指針,指向的是父類的虛析構函數,子類虛函數表當中也會產生一個子類的虛析構函數的入口指針,指向的是子類的虛析構函數,這個時候使用父類的指針指向子類的對象,delete接父類指針,就會經過指向的子類的對象找到子類的虛函數表指針,從而找到虛函數表,再虛函數表中找到子類的虛析構函數,從而使得子類的析構函數得以執行,子類的析構函數執行以後系統會自動執行父類的虛析構函數。這個是虛析構函數的實現原理。
class Shape { public: virtual double calcArea()//虛函數 {....} virtual double calcPerimeter()=0;//純虛函數 .... }; |
純虛函數沒有函數體,同時在定義的時候函數名後面要加「=0」。
純虛函數的實現原理:
在虛函數原理的基礎上,虛函數表中,虛函數的地址是一個有意義的值,若是是純虛函數就實實在在的寫一個0。
含有純虛函數的類被稱爲抽象類,純虛函數沒有函數體,因此抽象類不容許實例化對象,而對於一些具體的類來講,咱們要求必須實現那些要求(純虛函數),使之成爲有具體動做的類。抽象類的子類也能夠是一個抽象類。抽象類子類只有把抽象類當中的全部的純虛函數都作了實現才能夠實例化對象。
若是在抽象類當中僅含有純虛函數而不含其餘任何東西,咱們稱之爲接口類。
l 類裏聲明爲虛函數的話,這個函數是實現的,哪怕是空實現,它的做用就是爲了能讓這個函數在它的子類裏面能夠被重載,這樣的話,這樣編譯器就可使用後期綁定來達到多態了;純虛函數只是一個接口,是個函數的聲明而已,它要留到子類裏去實現。
l 虛函數在子類裏面也能夠不重載的;但純虛必須在子類去實現,這就像Java的接口同樣。一般咱們把不少函數加上virtual,是一個好的習慣,雖然犧牲了一些性能,可是增長了面向對象的多態性,由於你很難預料到父類裏面的這個函數不在子類裏面不去修改它的實現。
l 虛函數的類用於「實做繼承」,繼承接口的同時也繼承了父類的實現。固然咱們也能夠完成本身的實現。純虛函數的類用於「介面繼承」,主要用於通訊協議方面。關注的是接口的統一性,實現由子類完成。通常來講,介面類中只有純虛函數的。