站長工具seo下載推客平臺
文章目錄
- 一、線程
- 1.什么是進(jìn)程,線程,彼此有什么區(qū)別?
- 2.多進(jìn)程、多線程的優(yōu)缺點(diǎn)
- 3.什么時候用進(jìn)程,什么時候用線程
- 4.多進(jìn)程、多線程同步(通訊)的方法
- 5.父進(jìn)程、子進(jìn)程的關(guān)系以及區(qū)別
- 6.什么是進(jìn)程上下文、中斷上下文
- 7.一個進(jìn)程可以創(chuàng)建多少線程,和什么有關(guān)
- 8.什么是線程同步和互斥
- 9.進(jìn)程的空間模型
- 10.進(jìn)程線程的狀態(tài)轉(zhuǎn)換圖 什么時候阻塞,什么時候就緒
- 11.線程同步與阻塞的關(guān)系?同步一定阻塞嗎?阻塞一定同步嗎?
- 12.并發(fā),同步,異步,互斥,阻塞,非阻塞的理解
- 13.孤兒進(jìn)程、僵尸進(jìn)程、守護(hù)進(jìn)程的概念
- 14.正確處理僵尸進(jìn)程的方法
- 15.如何創(chuàng)建守護(hù)進(jìn)程
- 二、C/C++高頻面試題
- 1.new和malloc的區(qū)別
- 2.malloc的底層實現(xiàn)
- 3.在1G內(nèi)存的計算機(jī)中能否malloc(1.2G)?為什么?
- 4.指針與引用的相同和區(qū)別;如何相互轉(zhuǎn)換?
- 5.C語言檢索內(nèi)存情況 內(nèi)存分配的方式
- 6. extern”C” 的作用???
- 7.頭文件聲明時加extern定義時不要加 因為extern可以多次聲明,但只有一個定義????
- 8.函數(shù)參數(shù)壓棧順序,即關(guān)于__stdcall和__cdecl調(diào)用方式的理解???
- 9.重寫memcpy()函數(shù)需要注意哪些問題??
- 10.數(shù)組到底存放在哪里???
- 11.struct和class的區(qū)別 ?????
- 12. char和int之間的轉(zhuǎn)換;???
- 13. static的用法(定義和用途)?????
- 14.const常量和#define的區(qū)別(編譯階段、安全性、內(nèi)存占用等) ????
- 15.c/c++中變量的作用域?????
- 16.volatile作用和用法 ?????
- 17.有常量指針 指針常量 常量引用 沒有 引用常量???
- 18.c++中類型轉(zhuǎn)換機(jī)制?各適用什么環(huán)境?dynamic_cast轉(zhuǎn)換失敗時,會出現(xiàn)什么情況????
- 19.char、short、int、long、float、double、struct的大小
- 三、繼承、多態(tài)相關(guān)面試題
- 1.繼承和虛繼承 ?????
- 2.多態(tài)的類,內(nèi)存布局是怎么樣的 ?????
- 3.被隱藏的基類函數(shù)如何調(diào)用或者子類調(diào)用父類的同名函數(shù)和父類成員變量 ?????
- 4.多態(tài)實現(xiàn)的三個條件、實現(xiàn)的原理 ?????
- 5.對拷貝構(gòu)造函數(shù) 深淺拷貝 的理解 拷貝構(gòu)造函數(shù)作用及用途?什么時候需要自定義拷貝構(gòu)造函數(shù)????
- 6.析構(gòu)函數(shù)可以拋出異常嗎?為什么不能拋出異常?除了資源泄露,還有其他需考慮的因素嗎????
- 7.什么情況下會調(diào)用拷貝構(gòu)造函數(shù)(三種情況)???
- 8.析構(gòu)函數(shù)一般寫成虛函數(shù)的原因?????
- 9.構(gòu)造函數(shù)為什么一般不定義為虛函數(shù)?????
- 10.什么是純虛函數(shù)?????
- 11.靜態(tài)綁定和動態(tài)綁定的介紹????
- 12.C++所有的構(gòu)造函數(shù) ???
- 13.重寫、重載、覆蓋的區(qū)別?????
- 14.成員初始化列表的概念,為什么用成員初始化列表會快一些(性能優(yōu)勢)?????
- 15.如何避免編譯器進(jìn)行的隱式類型轉(zhuǎn)換;(explicit)????
- 四、網(wǎng)絡(luò)編程
- 1.TCP、UDP的區(qū)別 ?????
- 2.TCP、UDP的優(yōu)缺點(diǎn)???
- 3.TCP UDP適用場景???
- 4.TCP為什么是可靠連接????
- 5.典型網(wǎng)絡(luò)模型,簡單說說有哪些;???
- 6.Http1.1和Http1.0的區(qū)別???
- 7.URI(統(tǒng)一資源標(biāo)識符)和URL(統(tǒng)一資源定位符)之間的區(qū)別??
- 8.什么是三次握手?????
- 9.為什么三次握手中客戶端還要發(fā)送一次確認(rèn)呢?可以二次握手嗎?????
- 10.為什么服務(wù)端易受到SYN攻擊?????
- 11.什么是四次揮手?????
- 12.為什么客戶端最后還要等待2MSL?????
- 13.為什么建立連接是三次握手,關(guān)閉連接確是四次揮手呢?????
- 五、常見算法
- 1.各種排序算法的時間空間復(fù)雜度、穩(wěn)定性?????
- 2.各種排序算法什么時候有最好情況、最壞情況(尤其是快排) ????
- 3.冒泡排序????
- 4.選擇排序????
- 5.插入排序????
- 6.希爾排序????
- 7.歸并排序????
- 8.快速排序?????
- 9.快排的partition函數(shù)與歸并的Merge函數(shù)???
- 10. vector list異同?????
- 11. vector內(nèi)存是怎么增長的vector的底層實現(xiàn)????
- 12.幾種模板插入的時間復(fù)雜度 ?????
- 13. vector和deque的比較????
- 14.為什么stl里面有sort函數(shù)list里面還要再定義一個sort???
- 15. STL底層數(shù)據(jù)結(jié)構(gòu)實現(xiàn)????
- 16.利用迭代器刪除元素會發(fā)生什么?????
- 17. map是如何實現(xiàn)的,查找效率是多少?????
- 六、Linux操作系統(tǒng)
- 1. Linux內(nèi)核的組成??
- 2.用戶空間與內(nèi)核通信方式有哪些??????
- 3.系統(tǒng)調(diào)用read()/write(),內(nèi)核具體做了哪些事情??
- 4.系統(tǒng)調(diào)用的作用?????
- 5.內(nèi)核態(tài),用戶態(tài)的區(qū)別?????
- 6. bootloader內(nèi)核 根文件的關(guān)系????
- 7. Bootloader多數(shù)有兩個階段的啟動過程:???
- 8. linux的內(nèi)核是由bootloader裝載到內(nèi)存中的????
- 9.為什么需要BootLoader????
- 10. Linux內(nèi)核同步方式總結(jié)????
- 11.為什么自旋鎖不能睡眠 而在擁有信號量時就可以?????
- 12. linux下檢查內(nèi)存狀態(tài)的命令???
- 13.大小端的區(qū)別以及各自的優(yōu)點(diǎn),哪種時候用?????
- 14. 一個程序從開始運(yùn)行到結(jié)束的完整過程(四個過程)?????
- 15.什么是堆,棧,內(nèi)存泄漏和內(nèi)存溢出?????
- 16.硬鏈接與軟鏈接的區(qū)別;?????
- 17.虛擬內(nèi)存,虛擬地址與物理地址的轉(zhuǎn)換????
- 18.計算機(jī)中,32bit與64bit有什么區(qū)別???
- 19.中斷和異常的區(qū)別?????
- 20.中斷怎么發(fā)生,中斷處理大概流程????
- 21. Linux 操作系統(tǒng)掛起、休眠、關(guān)機(jī)相關(guān)命令??
- 22.數(shù)據(jù)庫為什么要建立索引,以及索引的缺點(diǎn)??
- 23.堆和棧的區(qū)別?????
- 24.死鎖的原因、條件 創(chuàng)建一個死鎖,以及如何預(yù)防?????
- 單片機(jī)
- 1 CPU 內(nèi)存 虛擬內(nèi)存 磁盤/硬盤 的關(guān)系???
- 2 CPU內(nèi)部結(jié)構(gòu)????
- 3 ARM結(jié)構(gòu)處理器簡析 ??
- 4波特率是什么,為什么雙方波特率要相同,高低波特率有什么區(qū)別;????
- 5.arm和dsp有什么區(qū)別??
- 6 ROM RAM的概念淺析???
- 7 IO口工作方式:上拉輸入 下拉輸入 推挽輸出 開漏輸出????
- 8扇區(qū) 塊 頁 簇的概念????
- 9簡述處理器在讀內(nèi)存的過程中,CPU核、cache、MMU如何協(xié)同工作?畫出CPU核、cache、MMU、內(nèi)存之間的關(guān)系示意圖加以說明??
- 10請說明總線接口USRT、I2C、USB的異同點(diǎn)(串/并、速度、全/半雙工、總線拓?fù)涞?#xff09;?????
- 11什么是異步串口和同步串口?????
- 12 I2C時序圖?????
一、線程
1.什么是進(jìn)程,線程,彼此有什么區(qū)別?
概念:
進(jìn)程:是并發(fā)執(zhí)行的程序在執(zhí)行過程中分配和管理資源的基本單位。
線程:處理器任務(wù)的基本單位。線程也被稱為輕量級進(jìn)程。
協(xié)程:是一種比線程更加輕量級的存在。C++ 20的協(xié)程是一個特殊函數(shù)。只是這個函數(shù)具有掛起和恢復(fù)的能力,可以被掛起(掛起后調(diào)用代碼繼續(xù)向后執(zhí)行),而后可以繼續(xù)恢復(fù)其執(zhí)行。
區(qū)別:
地址空間:進(jìn)程之間是獨(dú)立的地址空間,線程共享本進(jìn)程的地址空間。
健壯性:一個進(jìn)程崩潰后,在保護(hù)模式下不會對其他進(jìn)程產(chǎn)生影響,但是一個線程崩潰整個進(jìn)程都死掉。
執(zhí)行過程或者切換時:進(jìn)程執(zhí)行開銷大。線程執(zhí)行開銷小。
最小單位: 進(jìn)程是管理資源的基本單位。線程是處理器調(diào)度的基本單位
2.多進(jìn)程、多線程的優(yōu)缺點(diǎn)
3.什么時候用進(jìn)程,什么時候用線程
進(jìn)程與線程的選擇取決以下幾點(diǎn):
- 需要頻繁創(chuàng)建銷毀的優(yōu)先使用線程;因為對進(jìn)程來說創(chuàng)建和銷毀一個進(jìn)程代價是很大的。
- 線程的切換速度快,所以在需要大量計算,切換頻繁時用線程,還有耗時的操作使用線程可提高應(yīng)用程序的響應(yīng)
- 因為對CPU系統(tǒng)的效率使用上線程更占優(yōu),所以可能要發(fā)展到多機(jī)分布的用進(jìn)程,多核分布用線程;
- 并行操作時使用線程,如C/S架構(gòu)的服務(wù)器端并發(fā)線程響應(yīng)用戶的請求;
- 需要更穩(wěn)定安全時,適合選擇進(jìn)程;需要速度時,選擇線程更好。
4.多進(jìn)程、多線程同步(通訊)的方法
多進(jìn)程、多線程同步(通訊)的方法
進(jìn)程間通訊:
- 管道( pipe):管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動,而且只能在具有親緣關(guān)系的進(jìn)程間使用。進(jìn)程的親緣關(guān)系通常是指父子進(jìn)程關(guān)系
- 有名管道 (named pipeline) :有名管道也是半雙工的通信方式,但是它允許無親緣關(guān)系進(jìn)程間的通信。
- 信號量( semaphore):信號量是一個計數(shù)器,可以用來控制多個進(jìn)程對共享資源的訪問。它常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問共享資源時,其他進(jìn)程也訪問該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
- 消息隊列( message queue):消息隊列是由消息的鏈表,存放在內(nèi)核中并由消息隊列標(biāo)識符標(biāo)識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。
- 信號 ( signal ) :信號是一種比較復(fù)雜的通信方式,用于通知接收進(jìn)程某個事件已經(jīng)發(fā)生。
- 共享內(nèi)存( shared memory):共享內(nèi)存就是映射一段能被其他進(jìn)程所訪問的內(nèi)存,這段共享內(nèi)存由一個進(jìn)程創(chuàng)建,但多個進(jìn)程都可以訪問。共享內(nèi)存是最快的 IPC方式,它是針對其他進(jìn)程間通信方式運(yùn)行效率低而專門設(shè)計的。它往往與其他通信機(jī)制,如信號量,配合使用,來實現(xiàn)進(jìn)程間的同步和通信。
- 套接字(socket ) :套接口也是一種進(jìn)程間通信機(jī)制,與其他通信機(jī)制不同的是,它可用于不同及其間的進(jìn)程通信。
線程通訊:
- 互斥鎖:提供了以排他方式防止數(shù)據(jù)結(jié)構(gòu)被并發(fā)修改的方法。
- 讀寫鎖:允許多個線程同時讀共享數(shù)據(jù),而對寫操作是互斥的。
- 條件變量:可以以原子的方式阻塞進(jìn)程,直到某個特定條件為真為止。對條件的測試是在互斥鎖的保護(hù)下進(jìn)行的。條件變量始終與互斥鎖一起使用。
- 信號量機(jī)制(Semaphore):包括無名線程信號量和命名線程信號量。 信號機(jī)制(Signal):類似進(jìn)程間的信號處理。
5.父進(jìn)程、子進(jìn)程的關(guān)系以及區(qū)別
父子不同處: 1.進(jìn)程ID 2.fork返回值 3.父進(jìn)程ID 4.進(jìn)程運(yùn)行時間 5.鬧鐘(定時器) 6.未決信號集
父子進(jìn)程間遵循讀時共享寫時復(fù)制的原則。
6.什么是進(jìn)程上下文、中斷上下文
處理器總處于以下三種狀態(tài)之一:
1、內(nèi)核態(tài),運(yùn)行于進(jìn)程上下文,內(nèi)核代表進(jìn)程運(yùn)行于內(nèi)核空間;
2、內(nèi)核態(tài),運(yùn)行于中斷上下文,內(nèi)核代表硬件運(yùn)行于內(nèi)核空間;
3、用戶態(tài),運(yùn)行于用戶空間。
什么是中斷上下文?
當(dāng)執(zhí)行一個中斷處理函數(shù)時,內(nèi)核處于中斷上下文。
所謂的“ 中斷上下文”,其實也可以看作就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的一些其他環(huán)境(主要是當(dāng)前被打斷執(zhí)行的進(jìn)程環(huán)境)。
中斷上下文:
(1)中斷上文:硬件通過中斷觸發(fā)信號,導(dǎo)致內(nèi)核調(diào)用中斷處理程序,進(jìn)入內(nèi)核空間。這個過程中,硬件的一些變量和參數(shù)也要傳遞給內(nèi)核,內(nèi)核通過這些參數(shù)進(jìn)行中斷處理。中斷上文可以看作就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的一些其他環(huán)境(主要是當(dāng)前被中斷的進(jìn)程環(huán)境。
(2)中斷下文:執(zhí)行在內(nèi)核空間的中斷服務(wù)程序。
什么是進(jìn)程上下文?
用戶空間的應(yīng)用程序,通過系統(tǒng)調(diào)用,進(jìn)入內(nèi)核空間。這個時候用戶空間的進(jìn)程要傳遞 很多變量、參數(shù)的值給內(nèi)核,內(nèi)核態(tài)運(yùn)行的時候也要保存用戶進(jìn)程的一些寄存 器值、變量等。所謂的“進(jìn)程上下文”,可以看作是用戶進(jìn)程傳遞給內(nèi)核的這些參數(shù)以及內(nèi)核要保存的那一整套的變量和寄存器值和當(dāng)時的環(huán)境等。
進(jìn)程上下文:
(1)進(jìn)程上文:其是指進(jìn)程由用戶態(tài)切換到內(nèi)核態(tài)是需要保存用戶態(tài)時cpu寄存器中的值,進(jìn)程狀態(tài)以及堆棧上的內(nèi)容,即保存當(dāng)前進(jìn)程的進(jìn)程上下文,以便再次執(zhí)行該進(jìn)程時,能夠恢復(fù)切換時的狀態(tài),繼續(xù)執(zhí)行。
(2)進(jìn)程下文:其是指切換到內(nèi)核態(tài)后執(zhí)行的程序,即進(jìn)程運(yùn)行在內(nèi)核空間的部分。
7.一個進(jìn)程可以創(chuàng)建多少線程,和什么有關(guān)
理論上,一個進(jìn)程可用虛擬空間是2G,默認(rèn)情況下,線程的棧的大小是1MB,所以理論上最多只能創(chuàng)建2048個線程。如果要創(chuàng)建多于2048的話,必須修改編譯器的設(shè)置。
一個進(jìn)程可以創(chuàng)建的線程數(shù)由可用虛擬空間和線程的棧的大小共同決定,只要虛擬空間足夠,那么新線程的建立就會成功。如果需要創(chuàng)建超過2K以上的線程,減小你線程棧的大小就可以實現(xiàn)了。
8.什么是線程同步和互斥
線程同步:每個線程之間按預(yù)定的先后次序進(jìn)行運(yùn)行,協(xié)同、協(xié)助、互相配合??梢岳斫獬伞澳阏f完,我再做”。有了線程同步,每個線程才不是自己做自己的事情,而是協(xié)同完成某件大事。
線程互斥:當(dāng)有若干個線程訪問同一塊資源時,規(guī)定同一時間只有一個線程可以得到訪問權(quán),其它線程需要等占用資源者釋放該資源才可以申請訪問。線程互斥可以看成是一種特殊的線程同步。
9.進(jìn)程的空間模型
1、常量區(qū)
2、全局變量區(qū)
3、靜態(tài)變量區(qū)
4、代碼區(qū)
兩個動態(tài)區(qū)域,這就是
堆和棧。
10.進(jìn)程線程的狀態(tài)轉(zhuǎn)換圖 什么時候阻塞,什么時候就緒
創(chuàng)建態(tài)、終止態(tài)、就緒態(tài)、運(yùn)行態(tài)、阻塞態(tài)。
11.線程同步與阻塞的關(guān)系?同步一定阻塞嗎?阻塞一定同步嗎?
同步是個過程,阻塞是線程的一種狀態(tài)。多個線程操作共享變量時可能會出現(xiàn)競爭。這時需要同步來防止兩個以上的線程同時進(jìn)入臨界區(qū),在這個過程中,后進(jìn)入臨界區(qū)的線程將阻塞,等待先進(jìn)入的線程走出臨界區(qū)。
線程同步不一定發(fā)生阻塞,線程同步的時候,需要協(xié)調(diào)推進(jìn)速度,互相等待和互相喚醒會發(fā)生阻塞。
12.并發(fā),同步,異步,互斥,阻塞,非阻塞的理解
并發(fā)(concurrency):在操作系統(tǒng)中,是指一個時間段中有幾個程序都處于已啟動運(yùn)行到運(yùn)行完畢之間,且這幾個程序都是在同一個處理機(jī)上運(yùn)行。其中兩種并發(fā)關(guān)系分別是同步和互斥。
1.互斥:是指某一資源同時只允許一個訪問者對其進(jìn)行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的?! ?br /> 2.同步:是指在互斥的基礎(chǔ)上(大多數(shù)情況),通過其它機(jī)制實現(xiàn)訪問者對資源的有序訪問。在大多數(shù)情況下,同步已經(jīng)實現(xiàn)了互斥,特別是所有寫入資源的情況必定是互斥的。少數(shù)情況是指可以允許多個訪問者同時訪問資源。
異步(asynchronous):異步和同步是相對的,同步就是順序執(zhí)行,執(zhí)行完一個再執(zhí)行下一個,需要等待、協(xié)調(diào)運(yùn)行。異步就是彼此獨(dú)立,在等待某事件的過程中繼續(xù)做自己的事,不需要等待這一事件完成后再工作。線程就是實現(xiàn)異步的一個方式。異步是讓調(diào)用方法的主線程不需要同步等待另一線程的完成,從而可以讓主線程干其它的事情。
阻塞和非阻塞是針對于進(jìn)程在訪問數(shù)據(jù)的時候,根據(jù)IO操作的就緒狀態(tài)來采取的不同方式,說白了是一種讀取或者寫入操作函數(shù)的實現(xiàn)方式。阻塞方式下讀取或者寫入函數(shù)將一直等待,而非阻塞方式下,讀取或者寫入函數(shù)會立即返回一個狀態(tài)值。
一般來說IO模型可以分為:同步阻塞,同步非阻塞,異步阻塞,異步非阻塞。
同步阻塞IO :用戶進(jìn)程在發(fā)起一個IO操作以后,必須等待IO操作的完成,只有當(dāng)真正完成了IO操作以后,用戶進(jìn)程才能運(yùn)行。
同步非阻塞IO :用戶進(jìn)程發(fā)起一個IO操作以后可返回做其它事情, 但是用戶進(jìn)程需要時不時的詢問 IO操作是否就緒,這就要求用戶進(jìn)程不停的去詢問,從而引入不必要的CPU資源浪費(fèi)。應(yīng)用發(fā)起一個IO操作以后,使用阻塞select系統(tǒng)調(diào)用 來等待 I/O可用的通知。 select 調(diào)用非常有趣的是它可以用來為多個IO描述符提供通知,而不僅僅為一個描述符提供通知。
異步阻塞IO :應(yīng)用發(fā)起一個IO操作以后,不等待內(nèi)核IO操作的完成, 等內(nèi)核完成IO操作以后會通知應(yīng)用程序,這其實就是同步和異步最關(guān)鍵的區(qū)別同步必須等待或者主動的去詢問IO是否完成。
異步非阻塞IO :用戶進(jìn)程只需要發(fā)起一個IO操作然后立即返回, 等IO操作真正的完成以后,應(yīng)用程序會得到IO操作完成的通知, 此時用戶進(jìn)程只需要對數(shù)據(jù)進(jìn)行處理就好了,不需要進(jìn)行實際的IO讀寫操作因為真正的IO讀取或者寫入操作已經(jīng)由內(nèi)核完成了。
同步與異步是對應(yīng)的,它們是線程之間的關(guān)系,兩個線程之間要么是同步的,要么是異步的。
阻塞與非阻塞是對同一個線程來說的,在某個時刻,線程要么處于阻塞,要么處于非阻塞。
阻塞是使用同步機(jī)制的結(jié)果,非阻塞則是使用異步機(jī)制的結(jié)果。
13.孤兒進(jìn)程、僵尸進(jìn)程、守護(hù)進(jìn)程的概念
一個父進(jìn)程退出,而它的一個或多個子進(jìn)程還在運(yùn)行,那么那些子進(jìn)程將成為孤兒進(jìn)程。孤兒進(jìn)程將被init進(jìn)程所收養(yǎng),并由init進(jìn)程對它們完成狀態(tài)收集工作。
一個進(jìn)程使用fork創(chuàng)建子進(jìn)程,如果子進(jìn)程退出,而父進(jìn)程并沒有調(diào)用wait或waitpid獲取子進(jìn)程的狀態(tài)信息,那么子進(jìn)程的進(jìn)程描述符仍然保存在系統(tǒng)中。這種進(jìn)程稱之為僵尸進(jìn)程。
Linux Daemon(守護(hù)進(jìn)程)是運(yùn)行在后臺的一種特殊進(jìn)程。它獨(dú)立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。
14.正確處理僵尸進(jìn)程的方法
1.子進(jìn)程退出時向父進(jìn)程發(fā)送SIGCHILD信號,父進(jìn)程處理SIGCHILD信號。在信號處理函數(shù)中調(diào)用wait進(jìn)行處理僵尸進(jìn)程。
2.把父進(jìn)程殺掉。父進(jìn)程死后,僵尸進(jìn)程成為"孤兒進(jìn)程",過繼給進(jìn)程init,init始終會負(fù)責(zé)清理僵尸進(jìn)程。它產(chǎn)生的所有僵尸進(jìn)程也跟著消失。
fork兩次,父進(jìn)程fork一個子進(jìn)程,然后繼續(xù)工作,子進(jìn)程fork一 個孫進(jìn)程后退出,那么孫進(jìn)程被init接管,孫進(jìn)程結(jié)束后,init會回收。不過子進(jìn)程的回收 還要自己做。
兩次fork的原理是將子進(jìn)程成為孤兒進(jìn)程,從而其的父進(jìn)程變?yōu)閕nit進(jìn)程,通過init進(jìn)程可以處理僵尸進(jìn)程。
15.如何創(chuàng)建守護(hù)進(jìn)程
1、fork()創(chuàng)建子進(jìn)程,父進(jìn)程exit()退出;
2、在子進(jìn)程調(diào)用setsid()創(chuàng)建新會話;
3、再次 fork() 一個子進(jìn)程,父進(jìn)程exit退出;
4、在子進(jìn)程中調(diào)用chdir()讓根目錄“/”成為子進(jìn)程的工作目錄;
5、在子進(jìn)程中調(diào)用umask()重設(shè)文件權(quán)限掩碼為0;
6、在子進(jìn)程中close()不需要的文件描述符;
7、守護(hù)進(jìn)程退出處理
二、C/C++高頻面試題
1.new和malloc的區(qū)別
-
malloc和free是庫函數(shù),而new和delete是C++操作符;
-
new自己計算需要的空間大小,比如’int * a = new,malloc需要指定大小,例如’int * a = malloc(sizeof(int))’;
-
new在動態(tài)分配內(nèi)存的時候可以初始化對象,調(diào)用其構(gòu)造函數(shù),delete在釋放內(nèi)存時調(diào)用對象的析構(gòu)函數(shù)。而malloc只分配一段給定大小的內(nèi)存,并返回該內(nèi)存首地址指針,如果失敗,返回NULL。
-
new是C++操作符,是關(guān)鍵字,而operate new是C++庫函數(shù)
-
opeartor new /operator delete可以重載,而malloc不行
-
new可以調(diào)用malloc來實現(xiàn),但是malloc不能調(diào)用new來實現(xiàn)
-
對于數(shù)據(jù)C++定義new[]專門進(jìn)行動態(tài)數(shù)組分配,用delete[]進(jìn)行銷毀。new[]會一次分配內(nèi)存,然后多次調(diào)用構(gòu)造函數(shù);delete[]會先多次調(diào)用析構(gòu)函數(shù),然后一次性釋放。
分配數(shù)組不同之處
int char* pa = new char[100];
int char* pb = malloc(sizeof(char) * 100); -
malloc能夠直觀地重新分配內(nèi)存
使用malloc分配的內(nèi)存后,如果在使用過程中發(fā)現(xiàn)內(nèi)存不足,可以使用realloc函數(shù)進(jìn)行內(nèi)存重新分配實現(xiàn)內(nèi)存的擴(kuò)充。realloc先判斷當(dāng)前的指針?biāo)竷?nèi)存是否有足夠的連續(xù)空間,如果有,原地擴(kuò)大可分配的內(nèi)存地址,并且返回原來的地址指針;如果空間不夠,先按照新指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來的內(nèi)存區(qū)域。
new沒有這樣直觀的配套設(shè)施來擴(kuò)充內(nèi)存。
2.malloc的底層實現(xiàn)
malloc()工作機(jī)制
malloc函數(shù)的實質(zhì)體現(xiàn)在,它有一個將可用的內(nèi)存塊連接為一個長長的列表的所謂空閑鏈表。調(diào)用malloc函數(shù)時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。調(diào)用free函數(shù)時,它將用戶釋放的內(nèi)存塊連接到空閑鏈上。到最后,空閑鏈會被切成很多的小內(nèi)存片段,如果這時用戶申請一個大的內(nèi)存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。于是,malloc函數(shù)請求延時,并開始在空閑鏈上翻箱倒柜地檢查各內(nèi)存片段,對它們進(jìn)行整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊。
3.在1G內(nèi)存的計算機(jī)中能否malloc(1.2G)?為什么?
是有可能申請1.2G的內(nèi)存的。
回答這個問題前需要知道m(xù)alloc的作用和原理,應(yīng)用程序通過malloc函數(shù)可以向程序的虛擬空間申請一塊虛擬地址空間,與物理內(nèi)存沒有直接關(guān)系,得到的是在虛擬地址空間中的地址,之后程序運(yùn)行所提供的物理內(nèi)存是由操作系統(tǒng)完成的。
4.指針與引用的相同和區(qū)別;如何相互轉(zhuǎn)換?
- 都是地址的概念,指針指向某一內(nèi)存、它的內(nèi)容是所指內(nèi)存的地址;引用則是某塊內(nèi)存的別名。
- 從內(nèi)存分配上看:兩者都占內(nèi)存,程序為指針會分配內(nèi)存,一般是4個字節(jié);而引用的本質(zhì)是指針常量,指向?qū)ο蟛荒茏?#xff0c;但指向?qū)ο蟮闹悼梢宰儭烧叨际堑刂犯拍?#xff0c;所以本身都會占用內(nèi)存。
- 指針轉(zhuǎn)引用:把指針用*就可以轉(zhuǎn)換成對象,可以用在引用參數(shù)當(dāng)中。
- 引用轉(zhuǎn)指針:把引用類型的對象用&取地址就獲得指針了。
5.C語言檢索內(nèi)存情況 內(nèi)存分配的方式
內(nèi)存分配方式:
- 從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運(yùn)行期間都存在。例如全局變量,static變量。
- 在棧上創(chuàng)建。在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
- 從堆上分配,亦稱動態(tài)內(nèi)存分配。程序在運(yùn)行的時候用malloc或new申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時用free或delete釋 放內(nèi)存。動態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會出現(xiàn)內(nèi)存泄漏,頻繁地分配和釋放不同大 小的堆空間將會產(chǎn)生堆內(nèi)碎塊。
程序的內(nèi)存空間:
- 棧區(qū)(stack):由編譯器自動分配釋放,存放為運(yùn)行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回數(shù)據(jù)、返回地址。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
- 堆區(qū)(heap):一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時可能由OS回收。分配方式類似于鏈表。
- 全局區(qū)(靜態(tài)區(qū))(static):存放全局變量、靜態(tài)數(shù)據(jù)、常量。程序結(jié)束后由系統(tǒng)釋放。
- 文字常量區(qū):常量字符串就是放在這里的。程序結(jié)束后由系統(tǒng)釋放。
- 程序代碼區(qū):存放函數(shù)體(類成員函數(shù)和全局函數(shù))的二進(jìn)制代碼。
6. extern”C” 的作用???
extern “C”的作用是告訴C++編譯器用C規(guī)則編譯指定的代碼(除函數(shù)重載外,extern “C”不影響C++其他特性)。
7.頭文件聲明時加extern定義時不要加 因為extern可以多次聲明,但只有一個定義????
8.函數(shù)參數(shù)壓棧順序,即關(guān)于__stdcall和__cdecl調(diào)用方式的理解???
__stdcall和__cdecl都是函數(shù)調(diào)用約定關(guān)鍵字。
__stdcall:參數(shù)由右向左壓入堆棧;堆棧由函數(shù)本身清理。
__cdecl:參數(shù)也是由右向左壓入堆棧;但堆棧由調(diào)用者清理
9.重寫memcpy()函數(shù)需要注意哪些問題??
10.數(shù)組到底存放在哪里???
1.數(shù)組就是一片地址連續(xù)且空間大小一致的存儲空間 (但是每個空間存的還是其他數(shù)據(jù)的地址)
2.數(shù)組存在于堆內(nèi)存中,但凡在堆中存儲的數(shù)據(jù)都稱之為 對象(但凡在堆內(nèi)存中創(chuàng)建的對象都會有默認(rèn)初始值)
11.struct和class的區(qū)別 ?????
- 默認(rèn)的繼承訪問權(quán)。class默認(rèn)的是private,strcut默認(rèn)的是public。
- 默認(rèn)訪問權(quán)限:struct作為數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)體,它默認(rèn)的數(shù)據(jù)訪問控制是public的,而class作為對象的實現(xiàn)體,它默認(rèn)的成員變量訪問控制是private的。
- 3.“class”這個關(guān)鍵字還用于定義模板參數(shù),就像“typename”。但關(guān)鍵字“struct”不用于定義模板參數(shù)
- class和struct在使用大括號{ }上的區(qū)別
關(guān)于使用大括號初始化
1.)class和struct如果定義了構(gòu)造函數(shù)的話,都不能用大括號進(jìn)行初始化
2.)如果沒有定義構(gòu)造函數(shù),struct可以用大括號初始化。
3.)如果沒有定義構(gòu)造函數(shù),且所有成員變量全是public的話,class可以用大括號初始化
12. char和int之間的轉(zhuǎn)換;???
1.1、char轉(zhuǎn)int:
char a = '1';
int b = a - '0'; // b = 1;
1.2、int轉(zhuǎn)char:
int a = 1;
char b = a + '0'; // b = '1';
13. static的用法(定義和用途)?????
- 在全局變量前,加上關(guān)鍵字static,該變量就被定義成為一個靜態(tài)全局變量。該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存;靜態(tài)全局變量在聲明它的整個文件都是可見的,而在文件之外是不可見的;未經(jīng)初始化的靜態(tài)全局變量會被程序自動初始化為0
- 在局部變量前,加上關(guān)鍵字static,該變量就被定義成為一個靜態(tài)局部變量。
? 該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存;
? 靜態(tài)局部變量在程序執(zhí)行到該對象的聲明處時被首次初始化,即以后的函數(shù)調(diào)用不再進(jìn)行初始化;
? 靜態(tài)局部變量一般在聲明處初始化,如果沒有顯式初始化,會被程序自動初始化為0;
? 它始終駐留在全局?jǐn)?shù)據(jù)區(qū),直到程序運(yùn)行結(jié)束。但其作用域為局部作用域,當(dāng)定義它的函數(shù)或語句塊結(jié)束時,其作用域隨之結(jié)束; - 在函數(shù)的返回類型前加上static關(guān)鍵字,函數(shù)即被定義為靜態(tài)函數(shù)。靜態(tài)函數(shù)與普通函數(shù)不同,它只能在聲明它的文件當(dāng)中可見,不能被其它文件使用。
- 靜態(tài)數(shù)據(jù)成員
在類內(nèi)數(shù)據(jù)成員的聲明前加上關(guān)鍵字static,該數(shù)據(jù)成員就是類內(nèi)的靜態(tài)數(shù)據(jù)成員。
? 靜態(tài)數(shù)據(jù)成員是該類的所有對象所共有的
? 靜態(tài)數(shù)據(jù)成員存儲在全局?jǐn)?shù)據(jù)區(qū)。 - 與靜態(tài)數(shù)據(jù)成員一樣,我們也可以創(chuàng)建一個靜態(tài)成員函數(shù),它為類的全部服務(wù)而不是為某一個類的具體對象服務(wù)。
14.const常量和#define的區(qū)別(編譯階段、安全性、內(nèi)存占用等) ????
- define是在編譯的預(yù)處理階段起作用,而const是在 編譯、運(yùn)行的時候起作用。
- const 定義的常數(shù)是變量 也帶類型,#define 定義的只是個常數(shù) 不帶類型。
- define只是簡單的字符串替換,沒有類型檢查。而const有對應(yīng)的數(shù)據(jù)類型,是要進(jìn)行判斷的,可以避免一些低級的錯誤。
- const常量可以進(jìn)行調(diào)試的,define是不能進(jìn)行調(diào)試的,因為在預(yù)編譯階段就已經(jīng)替換掉了
- define可以用來防止頭文件重復(fù)引用,而const不能
- const不足的地方,是與生俱來的,const不能重定義,而#define可以通過#undef取消某個符號的定義,再重新定義。
15.c/c++中變量的作用域?????
16.volatile作用和用法 ?????
首先volatile修飾的變量,作用在編譯階段,影響編譯出的結(jié)果,其修飾的變量是隨時可能被修改的,volatile告訴編譯器,這個變量是重要人物,不要偷懶的去走捷徑,每次認(rèn)認(rèn)真真的去從內(nèi)存拿值。
一般說來,volatile用在如下的幾個地方:
- 中斷服務(wù)程序中修改的供其它程序檢測的變量需要加 volatile;
- 多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志應(yīng)該加 volatile;
- 存儲器映射的硬件寄存器通常也要加 volatile 說明,因為每次對它的讀寫都可能由不同意義;
17.有常量指針 指針常量 常量引用 沒有 引用常量???
- 常量指針(const int* p)常量指針本質(zhì)上是一個指針,是一個指向“常量”的指針,即不能通過指針改變指向?qū)ο蟮闹?#xff08;不能解除引用),但可以更改指向
- 常量引用(const int& a)本質(zhì)上是一個引用,對常量的引用,不能通過引用改變綁定對象的值
- 指針常量(int* const p)指針常量本質(zhì)上是一個常量,const是修飾p的,即指針的值自身是一個常量,不可改變,始終指向一個地址,在創(chuàng)建的同時必須進(jìn)行初始化
18.c++中類型轉(zhuǎn)換機(jī)制?各適用什么環(huán)境?dynamic_cast轉(zhuǎn)換失敗時,會出現(xiàn)什么情況????
http://t.csdn.cn/wBwuS
若對指針進(jìn)行dynamic_cast,失敗返回nullptr,成功返回正常cast后的對象指針
19.char、short、int、long、float、double、struct的大小
結(jié)構(gòu)體大小等于最后一個成員的偏移量加上最后一個成員的大小。
偏移量指的是結(jié)構(gòu)體變量中成員的地址和結(jié)構(gòu)體變量地址的差。
1、結(jié)構(gòu)體變量中成員的偏移量必須是成員大小的整數(shù)倍(0被認(rèn)為是任何數(shù)的整數(shù)倍)
2、結(jié)構(gòu)體大小必須是所有成員大小的整數(shù)倍。
三、繼承、多態(tài)相關(guān)面試題
1.繼承和虛繼承 ?????
虛繼承的目的是讓某個類做出聲明,承諾愿意共享它的基類。其中,這個被共享的基類就稱為虛基類(Virtual Base Class),本例中的 A 就是一個虛基類。在這種機(jī)制下,不論虛基類在繼承體系中出現(xiàn)了多少次,在派生類中都只包含一份虛基類的成員。
2.多態(tài)的類,內(nèi)存布局是怎么樣的 ?????
https://blog.csdn.net/yuupengsun/article/details/104136210
和類中的數(shù)據(jù)有關(guān),和函數(shù)無關(guān),若是有虛函數(shù),內(nèi)存加上虛指針的大小
3.被隱藏的基類函數(shù)如何調(diào)用或者子類調(diào)用父類的同名函數(shù)和父類成員變量 ?????
4.多態(tài)實現(xiàn)的三個條件、實現(xiàn)的原理 ?????
1.繼承,2.虛函數(shù)重寫,3.父類指針或引用指向子類對象
5.對拷貝構(gòu)造函數(shù) 深淺拷貝 的理解 拷貝構(gòu)造函數(shù)作用及用途?什么時候需要自定義拷貝構(gòu)造函數(shù)????
拷貝構(gòu)造函數(shù)一般用于以下三種情況:
1.當(dāng)用類的一個對象去初始化該類的另外一個對象時。
2.如果函數(shù)的形參是類的對象,調(diào)用函數(shù)時,是值傳遞。(引用傳遞并不調(diào)用拷貝構(gòu)造函數(shù))
3.如果函數(shù)的返回值是類的對象,函數(shù)執(zhí)行完成時會返回調(diào)用者時。
如果是淺拷貝,那么只會拷貝指針b=a,它們都指向D內(nèi)存區(qū)域。如果是深拷貝,不僅拷貝指針b=a,還會申請一塊新的內(nèi)存空間E,原來的a指向D,新的b指向E。
當(dāng)類存在指針類成員變量時,默認(rèn)拷貝構(gòu)造函數(shù)是淺拷貝,會導(dǎo)致二次析構(gòu)問題,所以要自定義拷貝構(gòu)造函數(shù)。
6.析構(gòu)函數(shù)可以拋出異常嗎?為什么不能拋出異常?除了資源泄露,還有其他需考慮的因素嗎????
1)如果析構(gòu)函數(shù)拋出異常,則異常點(diǎn)之后的程序不會執(zhí)行,如果析構(gòu)函數(shù)在異常點(diǎn)之后執(zhí)行了某些必要的動作比如釋放某些資源,則這些動作不會執(zhí)行,會造成諸如資源泄漏的問題。
2)通常異常發(fā)生時,c++的機(jī)制會調(diào)用已經(jīng)構(gòu)造對象的析構(gòu)函數(shù)來釋放資源,此時若析構(gòu)函數(shù)本身也拋出異常,則前一個異常尚未處理,又有新的異常,會造成程序崩潰的問題。
7.什么情況下會調(diào)用拷貝構(gòu)造函數(shù)(三種情況)???
1.當(dāng)用類的一個對象去初始化該類的另外一個對象時。
2.如果函數(shù)的形參是類的對象,調(diào)用函數(shù)時,是值傳遞。(引用傳遞并不調(diào)用拷貝構(gòu)造函數(shù))
3.如果函數(shù)的返回值是類的對象,函數(shù)執(zhí)行完成時會返回調(diào)用者時。
8.析構(gòu)函數(shù)一般寫成虛函數(shù)的原因?????
在派生類中申請的資源就不會得到釋放,就會造成內(nèi)存泄漏
9.構(gòu)造函數(shù)為什么一般不定義為虛函數(shù)?????
存儲空間角度:虛函數(shù)對應(yīng)一個vtable,vtable存儲于對象的內(nèi)存空間
若構(gòu)造函數(shù)是虛的,則需要通過 vtable來調(diào)用,若對象還未實例化,即內(nèi)存空間還沒有,無法找到vtable
使用角度:虛函數(shù)主要用于在信息不全的情況下,能使重載的函數(shù)得到對應(yīng)的調(diào)用。
構(gòu)造函數(shù)本身就是要初始化實例,那使用虛函數(shù)就沒有實際意義
從實際含義上看,在調(diào)用構(gòu)造函數(shù)時還不能確定對象的真實類型(因為子類會調(diào)父類的構(gòu)造函數(shù));而且構(gòu)造函數(shù)的作用是提供初始化,在對象生命期只執(zhí)行一次,不是對象的動態(tài)行為,也沒有太大的必要成為虛函數(shù)
10.什么是純虛函數(shù)?????
純虛函數(shù)只有函數(shù)的名字而不具備函數(shù)的功能,不能被調(diào)用。在虛函數(shù)后面添加 =0 ,虛函數(shù)就成為純虛函數(shù)
- 虛函數(shù)定義形式:成員函數(shù)前添加 virtual 關(guān)鍵字,純虛函數(shù)在虛函數(shù)后添加 =0 ;
- 含有純虛函數(shù)的類,稱為抽象類;只含有虛函數(shù)的類,不能稱為抽象類。
- 虛函數(shù)既可以直接使用,也可以被子類重載實現(xiàn)后,以多態(tài)的形式調(diào)用;而純虛函數(shù)必須被子類重載實現(xiàn),才能以多態(tài)的形式調(diào)用,因為純虛函數(shù)在基類中只有聲明。
- 無論虛函數(shù)還是純虛函數(shù),定義中都不能有 static 關(guān)鍵字。因為 static關(guān)鍵字修飾的內(nèi)容在編譯前就要確定,而虛函數(shù)、純虛函數(shù)是在運(yùn)行時動態(tài)綁定的。
11.靜態(tài)綁定和動態(tài)綁定的介紹????
靜態(tài)類型:對象在聲明時采用的類型,在編譯期既已確定;
動態(tài)類型:通常是指一個指針或引用目前所指對象的類型,是在運(yùn)行期決定的;
靜態(tài)綁定:綁定的是靜態(tài)類型,所對應(yīng)的函數(shù)或?qū)傩砸蕾囉趯ο蟮撵o態(tài)類型,發(fā)生在編譯期;
動態(tài)綁定:綁定的是動態(tài)類型,所對應(yīng)的函數(shù)或?qū)傩砸蕾囉趯ο蟮膭討B(tài)類型,發(fā)生在運(yùn)行期;
12.C++所有的構(gòu)造函數(shù) ???
C++中的構(gòu)造函數(shù)可以分為4類:
(1)默認(rèn)構(gòu)造函數(shù)。以Student類為例,默認(rèn)構(gòu)造函數(shù)的原型為
Student();//沒有參數(shù)
(2)初始化構(gòu)造函數(shù)
Student(int num,int age);//有參數(shù)
(3)復(fù)制(拷貝)構(gòu)造函數(shù)
Student(Student&);//形參是本類對象的引用
(4)轉(zhuǎn)換構(gòu)造函數(shù)
Student(int r) ;//形參時其他類型變量,且只有一個形參
13.重寫、重載、覆蓋的區(qū)別?????
Overload(重載):重載是指不同的函數(shù)使用相同的函數(shù)名,但是函數(shù)的參數(shù)個數(shù)或類型(參數(shù)列表不同)。調(diào)用的時候根據(jù)函數(shù)的參數(shù)來區(qū)別不同的函數(shù)。有以下特征:
(1)相同的范圍(在同一個類中);
(2)函數(shù)名字相同;
(3)參數(shù)不同;
(4)virtual關(guān)鍵字可有可無;
Override(覆蓋):是指派生類函數(shù)覆蓋基類函數(shù),有以下特征:
(1)不同的范圍(分別位于派生類與基類);
(2)函數(shù)名字相同;
(3)參數(shù)相同;
(4)基類函數(shù)必須有virtual關(guān)鍵字
Overwrite(重寫):是值在派生類中重新對基類中的虛函數(shù)重新實現(xiàn)。即函數(shù)名和參數(shù)都一樣,只是函數(shù)的實現(xiàn)體不一樣
覆蓋就是重寫
14.成員初始化列表的概念,為什么用成員初始化列表會快一些(性能優(yōu)勢)?????
如果有些成員是類,那么在進(jìn)入構(gòu)造函數(shù)之前,會先調(diào)用一次默認(rèn)構(gòu)造函數(shù),進(jìn)入構(gòu)造函數(shù)后所做的事其實是一次賦值操作(對象已存在),所以如果是在構(gòu)造函數(shù)體內(nèi)進(jìn)行賦值的話,等于是一次默認(rèn)構(gòu)造加一次賦值,而初始化列表只做一次賦值操作。
15.如何避免編譯器進(jìn)行的隱式類型轉(zhuǎn)換;(explicit)????
將構(gòu)造函數(shù)聲明為explicit,來防止隱式類型轉(zhuǎn)換。
explicit關(guān)鍵字只能用于類內(nèi)部的構(gòu)造函數(shù)聲明上,而不能用在類外部的函數(shù)定義上。
四、網(wǎng)絡(luò)編程
1.TCP、UDP的區(qū)別 ?????
2.TCP、UDP的優(yōu)缺點(diǎn)???
3.TCP UDP適用場景???
UDP 常用于以下幾個方面:
1.包總量較少的通信(DNS、SNMP等);
2.視頻、音頻等多媒體通信(即時通信);
3.限定于 LAN 等特定網(wǎng)絡(luò)中的應(yīng)用通信;
4.廣播通信(廣播、多播)
4.TCP為什么是可靠連接????
- 檢驗和:通過檢驗和的方式,接收端可以檢測出來數(shù)據(jù)是否有差錯和異常,假如有差錯就會直接丟棄TCP 段,重新發(fā)送。
- 序列號/確認(rèn)應(yīng)答機(jī)制過程如下:
發(fā)送端每次發(fā)送數(shù)據(jù)時,TCP就給每個數(shù)據(jù)包分配一個序列號并且在一個特定的時間內(nèi)等待接收端對分配的這個序列號進(jìn)行確認(rèn),如果發(fā)送端在一個特定時間內(nèi)沒有收到接收端的確認(rèn),則發(fā)送端會重傳此數(shù)據(jù)包。
接收端利用序列號對接收的數(shù)據(jù)進(jìn)行確認(rèn),以便檢測對方發(fā)送的數(shù)據(jù)是否有丟失或者亂序等,接收端一旦收到已經(jīng)順序化的數(shù)據(jù),它就將這些數(shù)據(jù)按正確的順序重組成數(shù)據(jù)流并傳遞到高層進(jìn)行處理。 - 超時重傳原理
TCP協(xié)議要求在發(fā)送端每發(fā)送一個報文段,就啟動一個定時器并等待確認(rèn)信息;接收端成功接收新數(shù)據(jù)后返回確認(rèn)信息。若在定時器超時前數(shù)據(jù)未能被確認(rèn),TCP就認(rèn)為報文段中的數(shù)據(jù)已丟失或損壞,需要對報文段中的數(shù)據(jù)重新組織和重傳。
5.典型網(wǎng)絡(luò)模型,簡單說說有哪些;???
網(wǎng)絡(luò)模型一般是指OSI七層參考模型和TCP/IP四層參考模型。
OSI分層(7層):物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會話層、表示層、應(yīng)用層。
TCP/IP分層(4層):網(wǎng)絡(luò)接口層、網(wǎng)際層、運(yùn)輸層、應(yīng)用層。
網(wǎng)絡(luò)層:IP協(xié)議、ICMP協(xié)議、ARP協(xié)議、RARP協(xié)議。
傳輸層:UDP協(xié)議、TCP協(xié)議。
應(yīng)用層:FTP(文件傳送協(xié)議)、Telnet(遠(yuǎn)程登錄協(xié)議)、DNS(域名解析協(xié)議)、SMTP(郵件傳送協(xié)議),POP3協(xié)議(郵局協(xié)議),HTTP協(xié)議。
6.Http1.1和Http1.0的區(qū)別???
7.URI(統(tǒng)一資源標(biāo)識符)和URL(統(tǒng)一資源定位符)之間的區(qū)別??
8.什么是三次握手?????
三次握手的目的是建立可靠的通信通道,說到通信,簡單來說就是數(shù)據(jù)的發(fā)生與接收,而三次握手最主要的目的就是雙方確認(rèn)自己與對方的發(fā)送與接收是否正常
第一次握手:Client什么都不能確認(rèn),Server確認(rèn)了對方發(fā)送正常,自己接收正常
第二次握手:Client確認(rèn)了:自己發(fā)送、接收正常,對方發(fā)送正常、接收正常;Server確認(rèn)了:對方發(fā)送正常,自己接收正常
第三次握手:Client確認(rèn)了:自己發(fā)送、接收正常,對方發(fā)送正常接收正常;Server 確認(rèn)了:對方發(fā)送正常,接收正常,自己發(fā)送正常,接收正常。
9.為什么三次握手中客戶端還要發(fā)送一次確認(rèn)呢?可以二次握手嗎?????
下面解釋明明兩次就可以建立連接的為什么還要加第三次的確認(rèn)。
如果發(fā)送兩次就可以建立連接話,那么只要客戶端發(fā)送一個連接請求,服務(wù)端接收到并發(fā)送了確認(rèn),就會建立一個連接。
可能出現(xiàn)的問題:如果一個連接請求在網(wǎng)絡(luò)中跑的慢,超時了,這時客戶端會從發(fā)請求,但是這個跑的慢的請求最后還是跑到了,然后服務(wù)端就接收了兩個連接請求,然后全部回應(yīng)就會創(chuàng)建兩個連接,浪費(fèi)資源!
如果加了第三次客戶端確認(rèn),客戶端在接受到一個服務(wù)端連接確認(rèn)請求后,后面再接收到的連接確認(rèn)請求就可以拋棄不管了。
10.為什么服務(wù)端易受到SYN攻擊?????
服務(wù)端的資源分配是在二次握手時分配的,而客戶端的資源是在三次握手時分配的。
SYN攻擊,即客戶端在短時間內(nèi)偽造大量不存在的IP地址,并向SERVER端不斷的發(fā)送SYN包,SERVER收到請求即回復(fù)確認(rèn),并等待客戶端的確認(rèn),由于源地址不存在,因此SERVER需要不斷的重發(fā)直到超時。
這些偽造的SYN包長時間占用未連接隊列,導(dǎo)致正常的SYN請求因為隊列滿而丟棄,因為網(wǎng)絡(luò)擁塞。
一般服務(wù)端會重試5次。
分類: 嵌入式100題
11.什么是四次揮手?????
第一次揮手: Client端發(fā)起揮手請求,向Server端發(fā)送標(biāo)志位是FIN報文段,設(shè)置序列號seq,此時,Client端進(jìn)入FIN_WAIT_1狀態(tài),這表示Client端沒有數(shù)據(jù)要發(fā)送給Server端了。
第二次分手:Server端收到了Client端發(fā)送的FIN報文段,向Client端返回一個標(biāo)志位是ACK的報文段,ack設(shè)為seq加1,Client端進(jìn)入FIN_WAIT_2狀態(tài),Server端告訴Client端,我確認(rèn)并同意你的關(guān)閉請求。
第三次分手: Server端向Client端發(fā)送標(biāo)志位是FIN的報文段,請求關(guān)閉連接,同時Client端進(jìn)入LAST_ACK狀態(tài)。
第四次分手 : Client端收到Server端發(fā)送的FIN報文段,向Server端發(fā)送標(biāo)志位是ACK的報文段,然后Client端進(jìn)入TIME_WAIT狀態(tài)。Server端收到Client端的ACK報文段以后,就關(guān)閉連接。此時,Client端等待2MSL的時間后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,Client端也可以關(guān)閉連接了
12.為什么客戶端最后還要等待2MSL?????
TIME_WAIT狀態(tài)的時長設(shè)置為2MSL的主要原因:
確保被動關(guān)閉TCP連接的一端能收到第四次揮手的ACK
避免上一次TCP連接的數(shù)據(jù)包影響到下一次的TCP連接。
13.為什么建立連接是三次握手,關(guān)閉連接確是四次揮手呢?????
建立連接時因為當(dāng)Server端收到Client端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文。其中ACK報文是用來應(yīng)答的,SYN報文是用來同步的。所以建立連接只需要三次握手。
由于TCP協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的運(yùn)輸層通信協(xié)議,TCP是全雙工模式。這就意味著,關(guān)閉連接時,當(dāng)Client端發(fā)出FIN報文段時,只是表示Client端告訴Server端數(shù)據(jù)已經(jīng)發(fā)送完畢了。當(dāng)Server端收到FIN報文并返回ACK報文段,表示它已經(jīng)知道Client端沒有數(shù)據(jù)發(fā)送了,但是Server端還是可以發(fā)送數(shù)據(jù)到Client端的,所以Server很可能并不會立即關(guān)閉SOCKET,直到Server端把數(shù)據(jù)也發(fā)送完畢。當(dāng)Server端也發(fā)送了FIN報文段時,這個時候就表示Server端也沒有數(shù)據(jù)要發(fā)送了,就會告訴Client端,我也沒有數(shù)據(jù)要發(fā)送了,之后彼此就 會愉快的中斷這次TCP連接。
五、常見算法
1.各種排序算法的時間空間復(fù)雜度、穩(wěn)定性?????
2.各種排序算法什么時候有最好情況、最壞情況(尤其是快排) ????
3.冒泡排序????
https://www.runoob.com/w3cnote/bubble-sort.html
4.選擇排序????
5.插入排序????
6.希爾排序????
7.歸并排序????
8.快速排序?????
9.快排的partition函數(shù)與歸并的Merge函數(shù)???
void Merge(vector<int> &Array, int front, int mid, int end) {// preconditions:// Array[front...mid] is sorted// Array[mid+1 ... end] is sorted// Copy Array[front ... mid] to LeftSubArray// Copy Array[mid+1 ... end] to RightSubArrayvector<int> LeftSubArray(Array.begin() + front, Array.begin() + mid + 1);vector<int> RightSubArray(Array.begin() + mid + 1, Array.begin() + end + 1);int idxLeft = 0, idxRight = 0;LeftSubArray.insert(LeftSubArray.end(), numeric_limits<int>::max());RightSubArray.insert(RightSubArray.end(), numeric_limits<int>::max());// Pick min of LeftSubArray[idxLeft] and RightSubArray[idxRight], and put into Array[i]for (int i = front; i <= end; i++) {if (LeftSubArray[idxLeft] < RightSubArray[idxRight]) {Array[i] = LeftSubArray[idxLeft];idxLeft++;} else {Array[i] = RightSubArray[idxRight];idxRight++;}}
}void MergeSort(vector<int> &Array, int front, int end) {if (front >= end)return;int mid = (front + end) / 2;MergeSort(Array, front, mid);MergeSort(Array, mid + 1, end);Merge(Array, front, mid, end);
}
template <typename T>
void quick_sort_recursive(T arr[], int start, int end) {if (start >= end)return;T mid = arr[end];int left = start, right = end - 1;while (left < right) { //在整個范圍內(nèi)搜尋比樞紐元值小或大的元素,然后將左側(cè)元素與右側(cè)元素交換while (arr[left] < mid && left < right) //試圖在左側(cè)找到一個比樞紐元更大的元素left++;while (arr[right] >= mid && left < right) //試圖在右側(cè)找到一個比樞紐元更小的元素right--;std::swap(arr[left], arr[right]); //交換元素}if (arr[left] >= arr[end])std::swap(arr[left], arr[end]);elseleft++;quick_sort_recursive(arr, start, left - 1);quick_sort_recursive(arr, left + 1, end);
}
template <typename T> //整數(shù)或浮點(diǎn)數(shù)皆可使用,若要使用物件(class)時必須設(shè)定"小於"(<)、"大於"(>)、"不小於"(>=)的運(yùn)算子功能
void quick_sort(T arr[], int len) {quick_sort_recursive(arr, 0, len - 1);
}
10. vector list異同?????
- vector底層實現(xiàn)是數(shù)組;list是雙向鏈表。
- vector支持隨機(jī)訪問,list不支持。
- vector是順序內(nèi)存,list不是。
- vector在中間節(jié)點(diǎn)進(jìn)行插入刪除會導(dǎo)致內(nèi)存拷貝,list不會。
- vector一次性分配好內(nèi)存,不夠時才進(jìn)行2倍擴(kuò)容;list每次插入新節(jié)點(diǎn)都會進(jìn)行內(nèi)存申請。
- vector隨機(jī)訪問性能好,插入刪除性能差;list隨機(jī)訪問性能差,插入刪除性能好。
11. vector內(nèi)存是怎么增長的vector的底層實現(xiàn)????
vector是按照2倍方式擴(kuò)容的,擴(kuò)容需要經(jīng)過以下步驟:
開辟新空間
拷貝元素
釋放舊空間
使用新空間
12.幾種模板插入的時間復(fù)雜度 ?????
13. vector和deque的比較????
-
兩端都能快速安插和刪除元素,這些操作可以在分期攤還的常數(shù)時間(amortized constant time)內(nèi)完成。
-
元素的存取和迭代器的動作比vector稍慢。
-
迭代器需要在不同區(qū)塊間跳轉(zhuǎn),所以它非一般指針。
-
因為deque使用不止一塊內(nèi)存(而vector必須使用一塊連續(xù)內(nèi)存),所以deque的max_size()可能更大。
-
不支持對容量和內(nèi)存重新分配時機(jī)的控制。不過deque的內(nèi)存重分配優(yōu)于vector,因為其內(nèi)部結(jié)構(gòu)顯示,deque不必在內(nèi)存重分配時復(fù)制所有元素。
-
除了頭尾兩端,在任何地方安插或刪除元素,都將導(dǎo)致指向deque元素的所有pointers、references、iterators失效。
-
deque的內(nèi)存區(qū)塊不再被使用時,會自動被釋放。deque的內(nèi)存大小是可自動縮減的。
-
deque與vector組織內(nèi)存的方式不一樣。在底層,deque按“頁”(page)或“塊”(chunk)來分配存儲器,每頁包含固定數(shù)目的元素。而vector只分配一塊連續(xù)的內(nèi)存。例如,一個10M字節(jié)的vector使用的是一整塊10M字節(jié)的內(nèi)存,而deque可以使用一串更小的內(nèi)存塊,比如10塊1M的內(nèi)存。所以不能將deque的地址(如&deque[0])傳遞給傳統(tǒng)的C API,因為deque內(nèi)部所使用的內(nèi)存不一定會連續(xù)。
deque的下述特性與vector差不多:
-
在中部安插、刪除元素的速度較慢。
-
迭代器屬于random access iterator(隨機(jī)存取迭代器)。
14.為什么stl里面有sort函數(shù)list里面還要再定義一個sort???
雖然STL中提供了標(biāo)準(zhǔn)的sort函數(shù),但是它只適用于隨機(jī)存取的容器,而顯然list并不是這樣的容器,因此list提供了專用的鏈表排序函數(shù),雖然同樣名為sort,但是這個sort函數(shù)是list類的成員函數(shù)。
15. STL底層數(shù)據(jù)結(jié)構(gòu)實現(xiàn)????
C++ STL 的實現(xiàn):
1.vector 底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組 ,支持快速隨機(jī)訪問
2.list 底層數(shù)據(jù)結(jié)構(gòu)為雙向鏈表,支持快速增刪
3.deque 底層數(shù)據(jù)結(jié)構(gòu)為一個中央控制器和多個緩沖區(qū),詳細(xì)見STL源碼剖析P146,支持首尾(中間不能)快速增刪,也支持隨機(jī)訪問
deque是一個雙端隊列(double-ended queue),也是在堆中保存內(nèi)容的.它的保存形式如下:
[堆1] --> [堆2] -->[堆3] --> …
每個堆保存好幾個元素,然后堆和堆之間有指針指向,看起來像是list和vector的結(jié)合品.
4.stack 底層一般用list或deque實現(xiàn),封閉頭部即可,不用vector的原因應(yīng)該是容量大小有限制,擴(kuò)容耗時
5.queue 底層一般用list或deque實現(xiàn),封閉頭部即可,不用vector的原因應(yīng)該是容量大小有限制,擴(kuò)容耗時
(stack和queue其實是適配器,而不叫容器,因為是對容器的再封裝)
6.priority_queue 的底層數(shù)據(jù)結(jié)構(gòu)一般為vector為底層容器,堆heap為處理規(guī)則來管理底層容器實現(xiàn)
7.set 底層數(shù)據(jù)結(jié)構(gòu)為紅黑樹,有序,不重復(fù)
8.multiset 底層數(shù)據(jù)結(jié)構(gòu)為紅黑樹,有序,可重復(fù)
9.map 底層數(shù)據(jù)結(jié)構(gòu)為紅黑樹,有序,不重復(fù)
10.multimap 底層數(shù)據(jù)結(jié)構(gòu)為紅黑樹,有序,可重復(fù)
11.hash_set 底層數(shù)據(jù)結(jié)構(gòu)為hash表,無序,不重復(fù)
12.hash_multiset 底層數(shù)據(jù)結(jié)構(gòu)為hash表,無序,可重復(fù)
13.hash_map 底層數(shù)據(jù)結(jié)構(gòu)為hash表,無序,不重復(fù)
14.hash_multimap 底層數(shù)據(jù)結(jié)構(gòu)為hash表,無序,可重復(fù)
16.利用迭代器刪除元素會發(fā)生什么?????
(1)對于關(guān)聯(lián)容器(如map,set,multimap,multiset),刪除當(dāng)前的iterator,僅僅會使當(dāng)前的iterator失效,只要在erase時,遞增當(dāng)前的iterator即可。這是因為map之類的容器,使用了紅黑樹來實現(xiàn),插入,刪除一個結(jié)點(diǎn)不會對其他結(jié)點(diǎn)造成影響。
(2)對于序列式容器(如vector,deque,list等),刪除當(dāng)前的iterator會使后面所有元素的iterator都失效。這是因為vector,deque使用了連續(xù)分配的內(nèi)存,刪除一個元素導(dǎo)致后面所有的元素會向前移動一個位置。不過erase方法可以返回下一個有效的iterator。
17. map是如何實現(xiàn)的,查找效率是多少?????
C++ STL中的map用紅黑樹實現(xiàn),搜索效率是O(lgN)
六、Linux操作系統(tǒng)
1. Linux內(nèi)核的組成??
Linux內(nèi)核主要由五個子系統(tǒng)組成:
進(jìn)程調(diào)度,內(nèi)存管理,虛擬文件系統(tǒng),網(wǎng)絡(luò)接口,進(jìn)程間通信。
2.用戶空間與內(nèi)核通信方式有哪些??????
系統(tǒng)調(diào)用,提供特定的用戶空間與內(nèi)核空間的信息傳遞。
信號,內(nèi)核空間出現(xiàn)一些異常時候會發(fā)送信號給進(jìn)程,如SIGSEGV、SIGILL、SIGPIPE等。
/proc,proc可以讀取內(nèi)核空間的信息并且設(shè)置部分屬性的值,需要循環(huán)檢測。
文件,可以通過指定文件的讀寫操作來實現(xiàn)通信,但是流程不夠?qū)崟r,需要循環(huán)檢測來實現(xiàn)。
netlink,類似socket通信方式,可以讀寫大量的數(shù)據(jù),實現(xiàn)稍微復(fù)雜。
ioctl,可以實現(xiàn)數(shù)據(jù)量比較少時候的通信。
3.系統(tǒng)調(diào)用read()/write(),內(nèi)核具體做了哪些事情??
用戶空間read()–>內(nèi)核空間sys_read()–>scull_fops.read–>scull_read();
該過程分為兩個部分:用戶空間的處理和核心空間的處理。在用戶空間中通過 0x80 中斷的方式將控制權(quán)交給內(nèi)核處理,內(nèi)核接管后,經(jīng)過6個層次的處理最后將請求交給磁盤,由磁盤完成最終的數(shù)據(jù)拷貝操作。在這個過程中,調(diào)用了一系列的內(nèi)核函數(shù)。
4.系統(tǒng)調(diào)用的作用?????
(1) 系統(tǒng)調(diào)用可以為用戶空間提供訪問硬件資源的統(tǒng)一接口,以至于應(yīng)用程序不必去關(guān) 注具體的硬件訪問操作。
比如,讀寫文件時,應(yīng)用程序不用去管磁盤類型,甚至于不用關(guān)心是哪種文件系統(tǒng)。
(2) 系統(tǒng)調(diào)用可以對系統(tǒng)進(jìn)行保護(hù),保證系統(tǒng)的穩(wěn)定和安全。系統(tǒng)調(diào)用的存在規(guī)定了用 戶進(jìn)程進(jìn)入內(nèi)核的具體方式,
換句話說,用戶訪問內(nèi)核的路徑是事先規(guī)定好的,只能從規(guī)定位置進(jìn)入內(nèi)核,而不準(zhǔn)許肆意跳入內(nèi)核。有了這樣的進(jìn)
入內(nèi)核的統(tǒng)一訪問路徑限制才能保證 內(nèi)核的安全。
5.內(nèi)核態(tài),用戶態(tài)的區(qū)別?????
用戶空間就是用戶進(jìn)程所在的內(nèi)存區(qū)域,相對的,系統(tǒng)空間就是操作系統(tǒng)占據(jù)的內(nèi)存區(qū)域。用戶進(jìn)程和系統(tǒng)進(jìn)程的所有數(shù)據(jù)都在內(nèi)存中。
開機(jī)加電,系統(tǒng)啟動后,就對物理內(nèi)存進(jìn)行了劃分。
當(dāng)一個任務(wù)(進(jìn)程)執(zhí)行系統(tǒng)調(diào)用而陷入內(nèi)核代碼中執(zhí)行時,我們就稱進(jìn)程處于內(nèi)核運(yùn)行態(tài)(或簡稱為內(nèi)核態(tài))。 此時處理器處于特權(quán)級最高的(0級)內(nèi)核代碼中執(zhí)行。 當(dāng)進(jìn)程處于內(nèi)核態(tài)時,執(zhí)行的內(nèi)核代碼會使用當(dāng)前進(jìn)程的內(nèi)核棧。 每個進(jìn)程都有自己的內(nèi)核棧。 當(dāng)進(jìn)程在執(zhí)行用戶自己的代碼時,則稱其處于用戶運(yùn)行態(tài)(用戶態(tài))。
6. bootloader內(nèi)核 根文件的關(guān)系????
7. Bootloader多數(shù)有兩個階段的啟動過程:???
8. linux的內(nèi)核是由bootloader裝載到內(nèi)存中的????
linux的內(nèi)核的確是由bootloader裝載到內(nèi)存中的。 linux的bootloader有2個部分組成:bootstrap和uboot。
9.為什么需要BootLoader????
10. Linux內(nèi)核同步方式總結(jié)????
原子操作
信號量(semaphore)
讀寫信號量(rw_semaphore)
Spinlock
Mutex
BKL(Big Kernel Lock,只包含在2.4內(nèi)核中,不講)
Rwlock
brlock(只包含在2.4內(nèi)核中,不講)
RCU(只包含在2.6內(nèi)核及以后的版本中)
seqlock(只包含在2.6內(nèi)核及以后的版本中)
11.為什么自旋鎖不能睡眠 而在擁有信號量時就可以?????
12. linux下檢查內(nèi)存狀態(tài)的命令???
13.大小端的區(qū)別以及各自的優(yōu)點(diǎn),哪種時候用?????
大端序(Big-Endian)將數(shù)據(jù)的低位字節(jié)存放在內(nèi)存的高位地址,高位字節(jié)存放在低位地址。這種排列方式與數(shù)據(jù)用字節(jié)表示時的書寫順序一致,符合人類的閱讀習(xí)慣。
小端序(Little-Endian),將一個多位數(shù)的低位放在較小的地址處,高位放在較大的地址處,則稱小端序。小端序與人類的閱讀習(xí)慣相反,但更符合計算機(jī)讀取內(nèi)存的方式,因為CPU讀取內(nèi)存中的數(shù)據(jù)時,是從低地址向高地址方向進(jìn)行讀取的。
小端模式 :強(qiáng)制轉(zhuǎn)換數(shù)據(jù)不需要調(diào)整字節(jié)內(nèi)容,1、2、4字節(jié)的存儲方式一樣。
大端模式 :符號位的判定固定為第一個字節(jié),容易判斷正負(fù)。
14. 一個程序從開始運(yùn)行到結(jié)束的完整過程(四個過程)?????
預(yù)處理:.i文件。在預(yù)編譯的過程中,主要處理源代碼中的預(yù)處理指令,引入頭文件,去除注釋,處理所有的條件編譯指令,宏的替換,添加行號,保留所有的編譯器指令。當(dāng)進(jìn)行預(yù)編譯以后的文件中將不再存在宏,所有的宏都已經(jīng)被替代。
編譯:.s文件。在預(yù)處理結(jié)束后,進(jìn)行的是編譯。編譯過程所進(jìn)行的是對預(yù)處理后的文件進(jìn)行語法分析,詞法分析,語義分析,符號匯總,然后生成匯編代碼。
匯編:.o文件。匯編過程將匯編代碼轉(zhuǎn)成二進(jìn)制文件,二進(jìn)制文件就可以讓機(jī)器來讀取。每一條匯編語句都會產(chǎn)生一句機(jī)器語言。這個階段會形成符號表,并給這些符號分配虛擬地址。
鏈接:鏈接程序的主要工作就是將有關(guān)的目標(biāo)文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標(biāo)文件成為一個能夠被操作系統(tǒng)裝入執(zhí)行的統(tǒng)一整體
15.什么是堆,棧,內(nèi)存泄漏和內(nèi)存溢出?????
堆(heap):是由malloc之類函數(shù)分配的空間所在地。地址是由低向高增長的。
棧(stack):是自動分配變量,以及函數(shù)調(diào)用的時候所使用的一些空間。地址是由高向低減少的。
內(nèi)存溢出(out of memory):通俗理解就是內(nèi)存不夠,通常在運(yùn)行大型軟件或游戲時,軟件或游戲所需要的內(nèi)存遠(yuǎn)遠(yuǎn)超出了你主機(jī)內(nèi)安裝的內(nèi)存所承受大小,就叫內(nèi)存溢出。
內(nèi)存泄漏(Memory Leak):是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。
16.硬鏈接與軟鏈接的區(qū)別;?????
1.軟鏈接是存放另一個文件的路徑的形式存在。
2.軟鏈接可以 跨文件系統(tǒng) ,硬鏈接不可以。
3.軟鏈接可以對一個不存在的文件名進(jìn)行鏈接,硬鏈接必須要有源文件。
4.軟鏈接可以對目錄進(jìn)行鏈接。
17.虛擬內(nèi)存,虛擬地址與物理地址的轉(zhuǎn)換????
虛擬內(nèi)存,借助于地址轉(zhuǎn)換,操作系統(tǒng)可以給應(yīng)用程序一種假象,獨(dú)占整個計算機(jī)內(nèi)存,可以使用超過實際物理大小的內(nèi)存,應(yīng)用程序之間互不干擾。
進(jìn)程隔離,地址轉(zhuǎn)換可以用來構(gòu)建沙盒(SandBoxes)技術(shù),讓第三方代碼在沙盒中運(yùn)行,限制其對內(nèi)存的訪問,從而避免操作系統(tǒng)內(nèi)核和應(yīng)用程序受到病毒或者惡意代碼的攻擊。
進(jìn)程間通信,地址轉(zhuǎn)換可以將不同進(jìn)程空間的地址映射到同一段物理內(nèi)存,從而實現(xiàn)進(jìn)程間通信。
共享代碼段,動態(tài)加載so庫可以在多個程序?qū)嵗g進(jìn)行共享。
程序初始化,使用地址轉(zhuǎn)換技術(shù)可以讓應(yīng)用程序只加載部分代碼和數(shù)據(jù)就可以運(yùn)行(內(nèi)核在后臺繼續(xù)加載剩余部分),若執(zhí)行到未加載部分,則發(fā)生中斷掛起應(yīng)用程序,待內(nèi)核將剩余部分加載到內(nèi)存后再恢復(fù)應(yīng)用程序的執(zhí)行。
緩存管理,內(nèi)核通過合理安排程序所在的內(nèi)存位置來提高緩存效率。
內(nèi)存映射文件,將文件內(nèi)容映射到應(yīng)用程序地址空間,這樣一來,文件的內(nèi)容就可以被應(yīng)用程序直接訪問。
內(nèi)存的兩種視角
虛擬地址,進(jìn)程看到的內(nèi)存地址稱為虛擬地址,他們不對應(yīng)任何物理實體,每個進(jìn)程有自己的地址空間。
物理地址,內(nèi)存系統(tǒng)看到的地址稱為物理地址,他們用實際的地址去查找和存儲內(nèi)容。
虛擬尋址的方法。CPU生成一個虛擬地址(VA),然后MMU(Memory Management Unit 內(nèi)存管理單元) 將虛擬地址翻譯成實際的物理地址,然后再進(jìn)行物理尋址。
虛擬內(nèi)存是計算機(jī)系統(tǒng)中的一種技術(shù),它通過將物理內(nèi)存和磁盤空間結(jié)合起來,為每個進(jìn)程提供了一個統(tǒng)一的連續(xù)地址空間。在虛擬內(nèi)存中,使用虛擬地址來訪問內(nèi)存,而不是直接使用物理地址。虛擬地址需要通過地址轉(zhuǎn)換機(jī)制轉(zhuǎn)換為對應(yīng)的物理地址,以實現(xiàn)內(nèi)存的訪問。
18.計算機(jī)中,32bit與64bit有什么區(qū)別???
對于電腦CPU來說,64位和32位就是CPU一次出來數(shù)據(jù)的能力,32位就是32bit即一次可以處理4個字節(jié)的數(shù)據(jù);64位就是64bit即一次可以處理8個字節(jié)。
32位的系統(tǒng)許多支持4G的內(nèi)存,而64位則可以支持上百G的內(nèi)存。
19.中斷和異常的區(qū)別?????
中斷和異常
相同點(diǎn):都是CPU對系統(tǒng)發(fā)生的某個事情做出的一種反應(yīng)。
區(qū)別:中斷由外因引起,異常由CPU本身原因引起。
把中斷分為外中斷和內(nèi)中斷。
外中斷——就是我們指的中斷——是指由于外部設(shè)備事件所引起的中斷,如通常的磁盤中斷、打印機(jī)中斷等;
內(nèi)中斷——就是異常——是指由于 CPU 內(nèi)部事件所引起的中斷,如程序出錯(非法指令、地址越界)。內(nèi)中斷(trap)也被譯為“捕獲”或“陷入”。
異常是由于執(zhí)行了現(xiàn)行指令所引起的。由于系統(tǒng)調(diào)用引起的中斷屬于異常。
中斷則是由于系統(tǒng)中某事件引起的,該事件與現(xiàn)行指令無關(guān)。
20.中斷怎么發(fā)生,中斷處理大概流程????
21. Linux 操作系統(tǒng)掛起、休眠、關(guān)機(jī)相關(guān)命令??
Linux 操作系統(tǒng)掛起、休眠、關(guān)機(jī)相關(guān)命令
立刻關(guān)機(jī):
shutdown -h now
shutdown -h 0
定時/延時關(guān)機(jī):
shutdown -h 10:00
shutdown -h +30 //單位為分鐘
重啟:
reboot
待機(jī)/掛起:
sudo pm-suspend
sudo pm-suspend-hybrid
echo “mem” > /sys/power/state
sudo hibernate-ram
休眠:
sudo pm-hibernate
echo “disk” > /sys/power/state
sudo hibernate-disk
22.數(shù)據(jù)庫為什么要建立索引,以及索引的缺點(diǎn)??
23.堆和棧的區(qū)別?????
(1)管理方式不同。棧由操作系統(tǒng)自動分配釋放,無需我們手動控制;堆的申請和釋放工作由程序員控制,容易產(chǎn)生內(nèi)存泄漏;
(2)空間大小不同。每個進(jìn)程擁有的棧的大小要遠(yuǎn)遠(yuǎn)小于堆的大小。理論上,程序員可申請的堆大小為虛擬內(nèi)存的大小,進(jìn)程棧的大小 64bits 的 Windows 默認(rèn) 1MB,64bits 的 Linux 默認(rèn) 10MB;
(3)生長方向不同。堆的生長方向向上,內(nèi)存地址由低到高;棧的生長方向向下,內(nèi)存地址由高到低。
(4)分配方式不同。堆都是動態(tài)分配的。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是由操作系統(tǒng)完成的,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由操作系統(tǒng)進(jìn)行釋放,無需我們手工實現(xiàn)。
(5)分配效率不同。棧由操作系統(tǒng)自動分配,會在硬件層級對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是由C/C++提供的庫函數(shù)或運(yùn)算符來完成申請與管理,實現(xiàn)機(jī)制較為復(fù)雜,頻繁的內(nèi)存申請容易產(chǎn)生內(nèi)存碎片。顯然,堆的效率比棧要低得多。
(6)存放內(nèi)容不同。棧存放的內(nèi)容,函數(shù)返回地址、相關(guān)參數(shù)、局部變量和寄存器內(nèi)容等。當(dāng)主函數(shù)調(diào)用另外一個函數(shù)的時候,要對當(dāng)前函數(shù)執(zhí)行斷點(diǎn)進(jìn)行保存,需要使用棧來實現(xiàn),首先入棧的是主函數(shù)下一條語句的地址,即擴(kuò)展指針寄存器的內(nèi)容(EIP),然后是當(dāng)前棧幀的底部地址,即擴(kuò)展基址指針寄存器內(nèi)容(EBP),再然后是被調(diào)函數(shù)的實參等,一般情況下是按照從右向左的順序入棧,之后是被調(diào)函數(shù)的局部變量,注意靜態(tài)變量是存放在數(shù)據(jù)段或者BSS段,是不入棧的。出棧的順序正好相反,最終棧頂指向主函數(shù)下一條語句的地址,主程序又從該地址開始執(zhí)行。堆,一般情況堆頂使用一個字節(jié)的空間來存放堆的大小,而堆中具體存放內(nèi)容是由程序員來填充的。
從以上可以看到,堆和棧相比,由于大量malloc()/free()或new/delete的使用,容易造成大量的內(nèi)存碎片,并且可能引發(fā)用戶態(tài)和核心態(tài)的切換,效率較低。棧相比于堆,在程序中應(yīng)用較為廣泛,最常見的是函數(shù)的調(diào)用過程由棧來實現(xiàn),函數(shù)返回地址、EBP、實參和局部變量都采用棧的方式存放。雖然棧有眾多的好處,但是由于和堆相比不是那么靈活,有時候分配大量的內(nèi)存空間,主要還是用堆。
無論是堆還是棧,在內(nèi)存使用時都要防止非法越界,越界導(dǎo)致的非法內(nèi)存訪問可能會摧毀程序的堆、棧數(shù)據(jù),輕則導(dǎo)致程序運(yùn)行處于不確定狀態(tài),獲取不到預(yù)期結(jié)果,重則導(dǎo)致程序異常崩潰,這些都是我們編程時與內(nèi)存打交道時應(yīng)該注意的問題。
24.死鎖的原因、條件 創(chuàng)建一個死鎖,以及如何預(yù)防?????
產(chǎn)生死鎖的原因(兩個):
由競爭資源引起死鎖:多個進(jìn)程,共享資源,資源不足,競爭資源。
進(jìn)程推進(jìn)順序不當(dāng)引起死鎖:進(jìn)程運(yùn)行過程中,請求和釋放資源的順序不當(dāng),而導(dǎo)致進(jìn)程死鎖。
產(chǎn)生死鎖的四個必要條件:
① 互斥條件——進(jìn)程要求對所分配的資源進(jìn)行排它性控制,即在一段時間內(nèi)某資源僅為一進(jìn)程所占有。
② 請求和保持條件——當(dāng)進(jìn)程因請求資源而阻塞時,對已獲得的資源保持不放。
③ 不剝奪條件——進(jìn)程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。
④ 環(huán)路等待條件——在發(fā)生死鎖時必然存在一個“進(jìn)程—資源”的環(huán)形鏈。
解決死鎖的基本方法(四種):
① 預(yù)防死鎖——通過設(shè)置某些限制條件,以破壞產(chǎn)生死鎖的四個必要條件中的一個或幾個,來防止發(fā)生死鎖。
② 避免死鎖——在資源的動態(tài)分配過程中,使用某種方法去防止系統(tǒng)進(jìn)入不安全狀態(tài),從而避免了死鎖的發(fā)生。
③ 檢測死鎖——檢測死鎖方法允許系統(tǒng)運(yùn)行過程中發(fā)生死鎖。但通過系統(tǒng)所設(shè)置的檢測機(jī)構(gòu),可以及時檢測出死鎖的發(fā)生,并精確地確定與死鎖有關(guān)的進(jìn)程和資源,然后采取適當(dāng)措施,從系統(tǒng)中消除所發(fā)生的死鎖。
④ 解除死鎖——解除死鎖是與檢測死鎖相配套的一種設(shè)施,用于將進(jìn)程從死鎖狀態(tài)下解脫出來。常用的方法是撤銷或者掛起一些進(jìn)程,以便于釋放出一些資源,再將它分配給已經(jīng)處于阻塞的進(jìn)程,使其轉(zhuǎn)換為就緒狀態(tài)可以繼續(xù)運(yùn)行。解決死鎖的基本方法(四種):
① 預(yù)防死鎖——通過設(shè)置某些限制條件,以破壞產(chǎn)生死鎖的四個必要條件中的一個或幾個,來防止發(fā)生死鎖。
② 避免死鎖——在資源的動態(tài)分配過程中,使用某種方法去防止系統(tǒng)進(jìn)入不安全狀態(tài),從而避免了死鎖的發(fā)生。
③ 檢測死鎖——檢測死鎖方法允許系統(tǒng)運(yùn)行過程中發(fā)生死鎖。但通過系統(tǒng)所設(shè)置的檢測機(jī)構(gòu),可以及時檢測出死鎖的發(fā)生,并精確地確定與死鎖有關(guān)的進(jìn)程和資源,然后采取適當(dāng)措施,從系統(tǒng)中消除所發(fā)生的死鎖。
④ 解除死鎖——解除死鎖是與檢測死鎖相配套的一種設(shè)施,用于將進(jìn)程從死鎖狀態(tài)下解脫出來。常用的方法是撤銷或者掛起一些進(jìn)程,以便于釋放出一些資源,再將它分配給已經(jīng)處于阻塞的進(jìn)程,使其轉(zhuǎn)換為就緒狀態(tài)可以繼續(xù)運(yùn)行。
單片機(jī)
1 CPU 內(nèi)存 虛擬內(nèi)存 磁盤/硬盤 的關(guān)系???
-
CPU從內(nèi)存或緩存中取出指令,放入指令寄存器,并對指令譯碼分解成 系統(tǒng)指令的執(zhí)行。
-
內(nèi)存(即物理 內(nèi)存,是相對于硬盤這個“外存”而言)作為硬盤和CPU的“中轉(zhuǎn)站”,對電腦運(yùn)行速度有較大影響。
-
當(dāng)運(yùn)行數(shù)據(jù)超出物理內(nèi)存容納限度的時候,部分?jǐn)?shù)據(jù)就會自行“溢出”,虛擬內(nèi)存運(yùn)行的程序或 不使用的數(shù)據(jù)存放到這部分空間之中,等待需要的時候方便及時調(diào)用。
-
由于內(nèi)存是帶電存儲的(一旦斷電數(shù)據(jù)就會消失),而且容量有限,有了硬盤
2 CPU內(nèi)部結(jié)構(gòu)????
3 ARM結(jié)構(gòu)處理器簡析 ??
4波特率是什么,為什么雙方波特率要相同,高低波特率有什么區(qū)別;????
波特率是指數(shù)據(jù)傳送時,每秒傳送數(shù)據(jù)二進(jìn)制代碼的位數(shù),它的單位是位/秒(b/s)。1波特就是一位每秒。
5.arm和dsp有什么區(qū)別??
ARM具有比較強(qiáng)的事務(wù)管理功能,可以用來跑界面以及應(yīng)用程序等,其優(yōu)勢主要體現(xiàn)在控制方面,它的速度和數(shù)據(jù)處理能力一般,但是外圍接口比較豐富,標(biāo)準(zhǔn)化和通用性做的很好,而且在功耗等方面做得也比較好,所以適合用在一些消費(fèi)電子品方面;
而DSP主要是用來計算的,比如進(jìn)行加密解密、調(diào)制解調(diào)等,優(yōu)勢是強(qiáng)大的數(shù)據(jù)處理能力和較高的運(yùn)行速度。由于其在控制算法等方面很擅長,所以適合用在對控制要求比較高的場合,比如軍用導(dǎo)航、電機(jī)伺服驅(qū)動等方面。
如果只是著眼于嵌入式應(yīng)用的話,嵌入式CPU和DSP的區(qū)別應(yīng)該只在于一個偏重控制一個偏重運(yùn)算了。
DSP的優(yōu)勢主要是速度,它可以在一個指令周期中同時完成一次乘法和一次加法,這非常適合快速傅立葉變換的需求。DSP有專門的指令集,主要是專門針對通訊和多媒體處理的;而ARM使用的是RISC指令集(當(dāng)然ARM的E系列也支持DSP指令集)是通用處理用的。
6 ROM RAM的概念淺析???
- 只讀存儲器(Read Only Memory,ROM)。ROM所存數(shù)據(jù),一般是裝入整機(jī)前事先寫好的,整機(jī)工作過程中只能讀出,而不像隨機(jī)存儲器那樣能快速地、方便地加以改寫。ROM所存數(shù)據(jù)穩(wěn)定,斷電后所存數(shù)據(jù)也不會改變。
- 隨機(jī)存取存儲器(Random Access Memory,RAM)又稱作“隨機(jī)存儲器”,是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲器,也叫主存(內(nèi)存)。它可以隨時讀寫,而且速度很快,通常作為操作系統(tǒng)或其他正在運(yùn)行中的程序的臨時數(shù)據(jù)存儲媒介。當(dāng)電源關(guān)閉時RAM不能保留數(shù)據(jù)。如果需要保存數(shù)據(jù),就必須把它們寫入一個長期的存儲設(shè)備中(例如硬盤)。RAM和ROM相比,兩者的最大區(qū)別是RAM在斷電以后保存在上面的數(shù)據(jù)會自動消失,而ROM不會自動消失,可以長時間斷電保存。
7 IO口工作方式:上拉輸入 下拉輸入 推挽輸出 開漏輸出????
-
浮空輸入 :當(dāng)IO口沒有接輸入的時候,此時的電平會是一個不確定的值,也就是我們所說的浮空。電平會處于一個跳變的狀態(tài),一會高,一會低。只有輸入了一個高/低電平才會確定下來。
-
上拉輸入 :在沒有信號輸入的時候,此時的電平就是VDD的電平,此時讀取到的電平就是高電平。如果輸入了一個高電平,VDD和O點(diǎn)(最上面的圖中的O點(diǎn))之間就幾乎沒有電勢差,此時O點(diǎn)的電平就仍然是高電平,讀取到的電平就是高電平。當(dāng)輸入信號是一個低電平的時候,此時O點(diǎn)的電平的電平就會變成低電平,那么VDD和O點(diǎn)之間形成了電勢差,但是因為上拉電阻的存在,所以不會出現(xiàn)一個大電流。此時單片機(jī)讀取到的一個電平就是一個低電平。上拉輸入的好處就是輸入的電平不會上下浮動而導(dǎo)致輸入信號不穩(wěn)定,在沒有信號輸入的情況下可以穩(wěn)定在高電平。
-
下拉輸入 : 在沒有信號輸入的時候,根據(jù)電路知識,電平就是VSS的電平,此時讀取到的電平就是低電平。此時輸入的電平如果是一個低電平,就沒有辦法和之前的情況進(jìn)行區(qū)分。但如果輸入的是一個高電平,O點(diǎn)和VSS之間同樣形成了電勢差,O點(diǎn)的電平會變成外部的高電平,那么單片機(jī)得到的就是一個高電平信號。
下拉輸入的好處就是輸入的電平不會上下浮動而導(dǎo)致輸入信號不穩(wěn)定,在沒有信號輸入的情況下可以穩(wěn)定在低電平。 -
模擬輸入 : 模擬輸入需要走的路徑如圖所示。首先得知道,模擬輸出走的這一條路徑,是我們需要對一個模擬信號進(jìn)行讀取。
在我們使用單片機(jī)的時候,我們有時候需要用AD采集到IO口上面的真實電壓。這就有了我們所需要的模擬輸入。為了讓外部的電壓真實的讀取到單片機(jī)的AD模塊,我們既不能閉合上拉和下拉的開關(guān),也不能讓信號經(jīng)過施密特觸發(fā)器。
優(yōu)勢:可以讓AD讀取電壓。還可以在低功耗模式下運(yùn)行,實現(xiàn)省電的作用。 -
開漏輸出
我們可以把這一個MOS管當(dāng)成一個三極管,對于圖中所示的這種三極管我們可以簡單的理解成一個水龍頭,左側(cè)就是一個水龍頭開關(guān),當(dāng)給一個高電平的時候, O點(diǎn)和GND就會導(dǎo)通。(O點(diǎn)的輸出就是一種反向器的輸出,也就是O點(diǎn)的電平會和左側(cè)MOS的柵極(三極管的基極)相反)
所以說,開漏輸出就很好理解了。當(dāng)我們給一個低電平的時候,MOS管關(guān)閉,此時輸出的電壓就是一個浮空,即不確定的電壓。如果給一個高電平,那么MOS管導(dǎo)通,相當(dāng)于IO口與VSS相連,此處就輸出了一個低電平電壓。
優(yōu)勢①
雖然我們可以看到開漏輸出是沒有辦法在內(nèi)部輸出一個高電平,但是這一個看似是缺點(diǎn)。其實實際上是一種優(yōu)點(diǎn)。我們可以得到,當(dāng)給一個低電平的時候,MOS管沒有導(dǎo)通,此時電壓不確定導(dǎo)致無法輸出高電平,但是一旦我們在外部增加一個上拉,那么這一個缺點(diǎn)就會被有效避免。并且,因為是我們自己設(shè)計一個上拉,這個上拉的電壓是由我們自己確定,這樣我們就可以根據(jù)外部電路需要多少V的高電平來給這一個上拉的電壓,可以更好的適應(yīng)更多情況。如下圖,我們可以給定任意的VDD電壓,來適應(yīng)我們實際所需要的情況。
優(yōu)勢②
開漏輸出的實質(zhì)其實就是一個OD門(OD:漏極輸出(Open Drain))。而在數(shù)電中,OD門有一個非常重要的特性就是可以實現(xiàn)線與的功能,簡單來說,就是在像IIC這樣的總線協(xié)議中,只要有一個給低電平,那么總線都會被拉低。 -
推挽輸出 :推挽輸出就是可以需要利用兩個不同的MOS管來實現(xiàn)輸出。P-MOS和N-MOS是不同的控制方式,當(dāng)給一個高電平的時候,N-MOS不導(dǎo)通,P-MOS導(dǎo)通,此時IO口接通在VDD,此時輸出的是高電平。當(dāng)給一個低電平的時候,N-MOS導(dǎo)通,P-MOS不導(dǎo)通,此時IO口接通在VSS 電源上面,此時輸出的是低電平。
一定要把這個MOS管理解成開關(guān)控制的水龍頭!!!
優(yōu)勢
帶載能力強(qiáng)。
8扇區(qū) 塊 頁 簇的概念????
扇區(qū)是磁盤中最小的物理存儲單位。通常情況下每個扇區(qū)的大小是512字節(jié)。
塊是操作系統(tǒng)中最小的邏輯存儲單位。操作系統(tǒng)與磁盤打交道的最小單位是磁盤塊。
與內(nèi)存操作,是虛擬一個頁的概念來作為最小單位。與硬盤打交道,就是以塊為最小單位。吧
9簡述處理器在讀內(nèi)存的過程中,CPU核、cache、MMU如何協(xié)同工作?畫出CPU核、cache、MMU、內(nèi)存之間的關(guān)系示意圖加以說明??
10請說明總線接口USRT、I2C、USB的異同點(diǎn)(串/并、速度、全/半雙工、總線拓?fù)涞?#xff09;?????
UART:通用異步串行口,速率不快,可全雙工,結(jié)構(gòu)上一般由波特率產(chǎn)生器、UART發(fā)送器、UART接收器組成,硬件上兩線,一收一發(fā)。
I2C:雙向、兩線、串行、多主控接口標(biāo)準(zhǔn)。速率不快,半雙工,同步接口,具有總線仲裁機(jī)制,非常適合器件間近距離經(jīng)常性數(shù)據(jù)通信,可實現(xiàn)設(shè)備組網(wǎng)。
SPI:高速同步串行口,高速,可全雙工,收發(fā)獨(dú)立,同步接口,可實現(xiàn)多個SPI設(shè)備互聯(lián),硬件3~4線。
USB:通用串行總線,高速,半雙工,由主機(jī)、hub、設(shè)備組成。設(shè)備可以與下級hub相連構(gòu)成星型結(jié)構(gòu)。
11什么是異步串口和同步串口?????
串行通信進(jìn)行數(shù)據(jù)傳送時是將要傳送的數(shù)據(jù)按二進(jìn)制位,依據(jù)一定的順序逐位發(fā)送到接收方。其有兩種通信方式:異步通信和同步通信。
異步通信,是指數(shù)據(jù)傳送以字符為單位,字符與字符間的傳送是完全異步的,位與位之間的傳送基本上是同步的。異步通信采用固定的通信格式,數(shù)據(jù)以相同的幀格式傳送。每一幀由起始位、數(shù)據(jù)位、奇偶校驗位和停止位組成。異步串行通信的特點(diǎn)可以概括為:
以字符為單位傳送信息。
相鄰兩字符間的間隔是任意長。
因為一個字符中的比特位長度有限,所以需要的接收時鐘和發(fā)送時鐘只要相近就可以。
異步方式特點(diǎn)簡單的說就是:字符間異步,字符內(nèi)部各位同步。
異步位系統(tǒng)是面向字符來傳輸信息的,也就是我們一般情況下的一個字符,8位,1bit,當(dāng)然了傳輸?shù)臅r候還要加上起始位和結(jié)束位,沒有這兩位接收方就不知道什么時候開始接收數(shù)據(jù)什么時候結(jié)束了。
同步通信,是指數(shù)據(jù)傳送是以數(shù)據(jù)塊(一組字符)為單位,字符與字符之間、字符內(nèi)部的位與位之間都同步。同步通信時,通信雙方共用一個時鐘,這是同步通信區(qū)分于異步通信的最顯著的特點(diǎn)。同步串行通信的特點(diǎn)可以概括為:
以數(shù)據(jù)塊為單位傳送信息。
在一個數(shù)據(jù)塊(信息幀)內(nèi),字符與字符間無間隔。
因為一次傳輸?shù)臄?shù)據(jù)塊中包含的數(shù)據(jù)較多,所以接收時鐘與發(fā)送進(jìn)鐘嚴(yán)格同步,通常要有同步時鐘。