前言:鄙人于學(xué)堂求學(xué)十余載,終是要踏足江湖求一寸安身處!以前都忙著學(xué)習(xí)新東西以及做項目,現(xiàn)如今也需要面對找工作的壓力。此篇博客是作者準備的嵌入式工程師常見的面試題目匯總,其答案包含網(wǎng)絡(luò)搜索和作者自己感悟總結(jié)的,可能存在問題,如有大的紕漏希望諸位前輩矯正!當然,也希望該博客可以幫助同樣求職的你,Respect(此篇博客將保持常年更新)!
第一章:進程線程的基本概念
1、什么是進程(Process),線程(Thread),有什么區(qū)別?
進程和線程都是操作系統(tǒng)中的基本概念,以下是它們的定義和區(qū)別:
進程(Process):
進程是操作系統(tǒng)中分配資源和調(diào)度的基本單位。一個程序至少要開啟一個進程,進程是由進程控制塊(PCB)、程序段、數(shù)據(jù)段三部分組成。一個進程可以包含多個線程,這些線程共享進程的地址空間和資源,并且通過同步機制來協(xié)調(diào)對共享資源的訪問。線程(Thread):
線程是進程的基本執(zhí)行單元,是處理器調(diào)度的最小單位。一個進程中的每個線程都有自己的線程控制塊(TCB)、指令指針(IP)、棧和寄存器組。線程的調(diào)度由操作系統(tǒng)負責(zé),當一個線程完成了一次調(diào)度后,它將返回自己的進程空間,從而執(zhí)行該進程的其他線程。以下是進程和線程的區(qū)別:
地址空間:
進程的地址空間是獨立的,而線程的地址空間是進程的一部分。這意味著,進程之間的地址空間是相互獨立的,而同一進程內(nèi)的線程之間可以共享數(shù)據(jù)和內(nèi)存。資源擁有:
進程擁有獨立的資源,如內(nèi)存、文件、I/O等,而同一進程內(nèi)的線程之間可以共享這些資源。這種共享可以通過同步機制來協(xié)調(diào),以確保多個線程對共享資源的訪問不會發(fā)生沖突。任務(wù)執(zhí)行:
進程是獨立的任務(wù)執(zhí)行單元,而線程是在進程內(nèi)的任務(wù)執(zhí)行單元。一個進程可以有多個線程,但一個線程只能屬于一個進程。崩潰風(fēng)險:
當一個進程的某個線程崩潰時,整個進程都會受到影響,因為其他線程也共享了該進程的地址空間和資源。相反,多個進程之間的相互獨立性更高,一個進程的崩潰不會影響其他進程。
2、多進程(Multi-Process)、多線程(Multi-Thread)的優(yōu)缺點?
多進程和多線程在操作系統(tǒng)中都具有其優(yōu)缺點。以下是一些主要的優(yōu)缺點:
多進程的優(yōu)點:
- 獨立性強:每個進程都有自己的地址空間和資源,進程之間相互獨立,一個進程的崩潰不會影響其他進程。
- 資源隔離:由于每個進程都有自己的資源,不同進程之間的資源不會相互干擾,這使得多進程在資源管理方面更加穩(wěn)定和安全。
多進程的缺點:
- 資源開銷大:每個進程都需要分配獨立的資源,包括內(nèi)存、文件等,這使得系統(tǒng)需要為每個進程分配不同的資源,造成了資源開銷較大的問題。
- 上下文切換:當多個進程同時運行時,處理器需要頻繁地進行上下文切換,即保存和恢復(fù)進程的狀態(tài),這會帶來一定的性能開銷。
多線程的優(yōu)點:
- 資源共享:同一進程內(nèi)的線程可以共享數(shù)據(jù)和內(nèi)存,這使得線程之間的協(xié)作更加高效。
- 效率高:由于線程之間共享地址空間和資源,使得多線程在執(zhí)行時可以更快地訪問共享數(shù)據(jù),提高了執(zhí)行效率。
- 調(diào)度方便:操作系統(tǒng)可以方便地對同一進程內(nèi)的線程進行調(diào)度,使得線程之間的切換更加迅速。
多線程的缺點:
- 同步問題:由于線程之間共享數(shù)據(jù)和資源,因此需要引入同步機制來確保線程之間的訪問不會發(fā)生沖突。然而,同步機制的實現(xiàn)可能會帶來額外的開銷和復(fù)雜性。
- 調(diào)度開銷:盡管多線程的調(diào)度比多進程更高效,但仍然存在調(diào)度開銷的問題。當線程數(shù)量較多時,調(diào)度開銷可能會對系統(tǒng)性能產(chǎn)生一定的影響。
- 性能限制:當多個線程同時運行時,由于共享資源的限制,系統(tǒng)的性能可能會受到限制。例如,當某個線程被阻塞時,其他線程的執(zhí)行也會受到影響。
綜上所述,多進程和多線程在操作系統(tǒng)中都具有其優(yōu)缺點。在實際應(yīng)用中,需要根據(jù)具體場景和需求來選擇合適的進程模型。在需要隔離和獨立性要求較高的場景下,可以選擇多進程;而在需要共享數(shù)據(jù)和協(xié)作頻繁的場景下,可以選擇多線程。同時,需要注意多進程和多線程可能帶來的上下文切換、同步問題、調(diào)度開銷等挑戰(zhàn),以及如何進行有效的優(yōu)化和管理。?
3、多進程、多線程同步(通訊)的方法?
多進程和多線程之間的同步和通信可以通過以下幾種方法實現(xiàn):
- 管道(Pipe):管道是一種進程間通信的方式,可以在不同進程之間傳遞數(shù)據(jù)??梢允褂霉艿篮瘮?shù)如pipe()、read()和write()等來實現(xiàn)進程間通信。
- 共享內(nèi)存(Shared Memory):共享內(nèi)存是一種高效的進程間通信方式,它可以讓多個進程共享同一塊內(nèi)存區(qū)域,從而實現(xiàn)數(shù)據(jù)共享??梢允褂霉蚕韮?nèi)存函數(shù)如shmget()、shmat()和shmdt()等來實現(xiàn)進程間通信。
- 信號量(Semaphore):信號量是一種同步機制,它可以用于控制多個進程之間的訪問權(quán)限??梢允褂眯盘柫亢瘮?shù)如semget()、semctl()和semop()等來實現(xiàn)進程間同步。
- 消息隊列(Message Queue):消息隊列是一種進程間通信方式,它可以讓不同進程之間傳遞消息,并且具有消息的優(yōu)先級和緩沖機制。可以使用消息隊列函數(shù)如msgget()、msgrcv()和msgsnd()等來實現(xiàn)進程間通信。
- 管道和共享內(nèi)存的組合:管道和共享內(nèi)存可以組合使用,例如使用管道將數(shù)據(jù)寫入共享內(nèi)存中,然后其他進程可以從共享內(nèi)存中讀取數(shù)據(jù)。
- 套接字(Socket):套接字是一種更為通用的進程間通信方式,可以在不同主機之間傳遞數(shù)據(jù)。可以使用套接字函數(shù)如socket()、bind()、listen()和connect()等來實現(xiàn)進程間通信。
需要注意的是,多進程和多線程之間的同步和通信往往比較復(fù)雜,需要結(jié)合具體的場景來選擇合適的同步和通信方式,并注意避免死鎖、競爭條件等問題。
4、進程線程的狀態(tài)轉(zhuǎn)換圖。什么時候阻塞,什么時候就緒?
推薦博客地址:進程的狀態(tài)轉(zhuǎn)換 - LRH呀 - 博客園 (cnblogs.com)
5、父進程、子進程的關(guān)系以及區(qū)別?
父進程和子進程之間的關(guān)系主要體現(xiàn)在子進程是由父進程通過操作系統(tǒng)提供的fork函數(shù)創(chuàng)建的。在fork函數(shù)調(diào)用后,父進程會復(fù)制自己的內(nèi)存空間和文件描述符等信息給子進程,使得子進程獲得與父進程相似的運行環(huán)境。
以下是父進程和子進程之間的區(qū)別:
- ID:子進程有一個新的進程ID,而父進程的進程ID不同于子進程的進程ID。
- 內(nèi)存空間:子進程擁有獨立的內(nèi)存空間,與父進程的內(nèi)存空間不完全相同。子進程的內(nèi)存空間是父進程內(nèi)存空間的一個副本,當父進程修改了某個內(nèi)存地址上的數(shù)據(jù)后,子進程在同樣的內(nèi)存地址上的數(shù)據(jù)也會發(fā)生改變。
- 文件描述符:子進程繼承了父進程的文件描述符,可以訪問相同的文件。
- 狀態(tài)和優(yōu)先級:子進程繼承了父進程的狀態(tài)、優(yōu)先級和信號屏蔽字等信息。
- 資源:子進程繼承了父進程的資源,如打開的文件、信號量等。
- 父子進程之間是獨立的,互相不共享代碼段和數(shù)據(jù)段。
補充說明:Linux 系統(tǒng)創(chuàng)建的第 1 個進程叫 init 進程,它是所有進程的祖宗,此進程pid為1。有時候父子進程之間會出現(xiàn),父進程運行結(jié)束了,在內(nèi)存中銷毀了。 而子進程還沒運行結(jié)束,此時,linux會把子進程掛在linux中的init進程下。
6、什么是進程上下文、中斷上下文?
進程上下文和中斷上下文是指在操作系統(tǒng)中執(zhí)行程序時,處理器所維護的兩個不同的執(zhí)行環(huán)境。
進程上下文:是在進程中執(zhí)行的程序的上下文環(huán)境。在進程上下文中,處理器保存了程序運行時的所有狀態(tài)信息,包括程序計數(shù)器、寄存器、堆棧指針、內(nèi)存映射等。當一個進程被調(diào)度器調(diào)度時,操作系統(tǒng)會將進程的上下文保存到進程控制塊(PCB)中,然后加載到內(nèi)存中的適當位置,以便處理器可以正確地執(zhí)行該進程。
中斷上下文:是在中斷處理程序中執(zhí)行的上下文環(huán)境。當一個中斷發(fā)生時,處理器會保存當前正在執(zhí)行的進程的上下文,并跳轉(zhuǎn)到中斷處理程序的入口地址。在中斷處理程序執(zhí)行完畢后,處理器會恢復(fù)之前保存的進程上下文,并將控制權(quán)交回被中斷的進程。
進程上下文和中斷上下文的主要區(qū)別在于其用途和執(zhí)行環(huán)境的差異。進程上下文主要用于保存和恢復(fù)進程的狀態(tài)信息,以實現(xiàn)進程的切換和調(diào)度;而中斷上下文則主要用于保存和恢復(fù)中斷處理程序的狀態(tài)信息,以實現(xiàn)中斷的處理和返回。
7、一個進程可以創(chuàng)建多少線程,和什么有關(guān)
一個進程可以創(chuàng)建的線程數(shù)受到操作系統(tǒng)和計算機硬件的限制。
具體的限制因操作系統(tǒng)和硬件的不同而有所不同。在操作系統(tǒng)方面,一些操作系統(tǒng)可能會限制進程可以創(chuàng)建的最大線程數(shù),例如,在一些嵌入式操作系統(tǒng)中,可能只允許創(chuàng)建幾個線程。而在其他操作系統(tǒng)中,可能會允許創(chuàng)建更多的線程。例如Windows Server操作系統(tǒng)限制每個進程可以創(chuàng)建2000個線程。
此外,計算機硬件的性能也會對線程數(shù)產(chǎn)生影響。在實際情況中,如果創(chuàng)建過多的線程,可能會導(dǎo)致系統(tǒng)性能下降,因為每個線程都需要占用一定的內(nèi)存和計算資源。因此,需要根據(jù)具體的計算機硬件和應(yīng)用程序的需求來調(diào)整線程數(shù)。
總的來說,一個進程可以創(chuàng)建的線程數(shù)取決于操作系統(tǒng)和計算機硬件的限制,而具體的限制條件需要根據(jù)實際情況來確定。
8、線程通訊(鎖):
這些鎖都是用于線程同步和互斥的機制,以下是它們的簡要介紹:
- 信號量(Semaphore):
信號量是一種計數(shù)信號,可以用于控制多個線程對共享資源的訪問。它通常由一個計數(shù)器和一個等待隊列組成,計數(shù)器用于記錄可用的資源數(shù)量,當計數(shù)器為零時,表示沒有可用的資源,線程將被阻塞。等待隊列中保存了被阻塞的線程,直到有可用的資源為止。
- 讀寫鎖(Read-Write Lock):
讀寫鎖是一種用于控制對共享資源的讀寫訪問的鎖。它允許多個線程同時讀取共享資源,但只允許一個線程進行寫操作。讀寫鎖的實現(xiàn)通常會根據(jù)讀寫操作的特性進行優(yōu)化,以最大化并發(fā)性能。
- 條件變量(Condition Variable):
條件變量是一種用于線程之間的通信機制。它可以用于在某個條件滿足時,喚醒一個或多個等待的線程。條件變量通常與互斥鎖一起使用,用于實現(xiàn)復(fù)雜的同步和通知機制。
- 互斥鎖(Mutex):
互斥鎖是一種用于保護共享資源的機制。它允許多個線程同時訪問共享資源的一部分,但只允許一個線程同時訪問共享資源的整個區(qū)域。當一個線程需要訪問共享資源的互斥鎖時,其他線程將被阻塞,直到該線程釋放鎖為止。
- 自旋鎖(Spinlock):
自旋鎖是一種基于忙等待的鎖機制。當一個線程嘗試獲取自旋鎖時,如果自旋鎖已經(jīng)被其他線程占用,則該線程會在循環(huán)中等待自旋鎖被釋放。自旋鎖的好處是可以避免線程進入阻塞狀態(tài),從而減少上下文切換的開銷,但缺點是可能會消耗大量的CPU時間。
這些鎖都是為了實現(xiàn)線程同步和互斥而設(shè)計的機制,但每種鎖都有其特點和應(yīng)用場景,需要根據(jù)實際情況選擇合適的鎖機制。
9、什么叫臨界區(qū)?
臨界區(qū)是指一個訪問共用資源(例如:共用設(shè)備或是共用存儲器)的程序片段,而這些共用資源又無法同時被多個線程訪問的特性,需要在同一時間只能被一個線程執(zhí)行。臨界區(qū)用于保護共享資源,以避免多個線程同時訪問或修改造成的數(shù)據(jù)競爭和不確定性。
第二章:C/C++面試題
1、new 和 malloc 的區(qū)別?
new 和 malloc 都是用于動態(tài)分配內(nèi)存的方法,但是它們在以下方面存在一些區(qū)別:
- 內(nèi)存分配位置:new 操作從自由存儲區(qū)為對象動態(tài)分配內(nèi)存空間,而 malloc 函數(shù)從堆上動態(tài)分配內(nèi)存。自由存儲區(qū)不僅可以是堆,還可以是靜態(tài)存儲區(qū),這取決于 new 在哪里為對象分配內(nèi)存。
- 返回類型安全性:new 操作符內(nèi)存分配成功時,返回的是對象類型的指針,與對象類型嚴格匹配,無需進行類型轉(zhuǎn)換,因此 new 是符合類型安全性的操作符。而 malloc 函數(shù)在內(nèi)存分配成功后返回的是 void*,需要通過強制類型轉(zhuǎn)換將 void* 指針轉(zhuǎn)換成所需類型。
- 內(nèi)存分配失敗時的返回值:當 new 內(nèi)存分配失敗時,會拋出 bac_alloc 異常,不會返回 NULL;而 malloc 內(nèi)存分配失敗時,返回 NULL。
- 是否需要指定內(nèi)存大小:使用new申請內(nèi)存時,不需要指定內(nèi)存塊的大小,編譯器會根據(jù)類型信息自行計算;而malloc則需要顯式地指出所需內(nèi)存塊的大小。
總的來說,new和malloc在內(nèi)存分配位置、返回類型安全性、內(nèi)存分配失敗時的返回值以及是否需要指定內(nèi)存大小等方面存在差異。
2、malloc的底層實現(xiàn)
(1)當開辟的空間小于 128K 時,調(diào)用 brk()函數(shù),malloc 的底層實現(xiàn)是系統(tǒng)調(diào)用函數(shù) brk(),其主要移動指針 _enddata(此時的 _enddata 指的是 Linux 地址空間中堆段的末尾地址,不是數(shù)據(jù)段的末尾地址)
(2)當開辟的空間大于 128K 時,mmap()系統(tǒng)調(diào)用函數(shù)來在虛擬地址空間中(堆和棧中間,稱為“文件映射區(qū)域”的地方)找一塊空間來開辟。
3、?在1G內(nèi)存的計算機中能否malloc(1.2G)?為什么?
在1G內(nèi)存的計算機中,無法使用malloc(1.2G)。
在C語言中,malloc()函數(shù)用于動態(tài)分配內(nèi)存。當使用malloc()請求超過可用內(nèi)存的大小時,會發(fā)生兩種情況:
- 分配失?。喝绻埱蟮膬?nèi)存大小超過了操作系統(tǒng)可用的內(nèi)存大小,malloc()將返回NULL,表示分配失敗。在這種情況下,程序?qū)o法繼續(xù)執(zhí)行。
- 分配成功但導(dǎo)致崩潰:如果請求的內(nèi)存大小超過了可用的內(nèi)存大小,但malloc()仍然返回了非NULL的指針,這通常是由于操作系統(tǒng)使用了內(nèi)存映射技術(shù)或虛擬內(nèi)存機制。這種情況下,程序可能會繼續(xù)執(zhí)行,但它可能會遇到未定義的行為,例如訪問已分配的內(nèi)存時崩潰或?qū)е滦阅芟陆怠?/li>
在1G內(nèi)存的計算機中,由于可用內(nèi)存只有1GB,因此無法使用malloc(1.2G),因為這將請求超過可用內(nèi)存大小的內(nèi)存大小。如果嘗試這樣做,malloc()將返回NULL,并且程序?qū)o法繼續(xù)執(zhí)行。
4、指針與引用的相同和區(qū)別;如何相互轉(zhuǎn)換?
引用時C++獨有的特性,而指針則是C/C++都有的,它們有一些相似之處,但也有很多區(qū)別。
- 相同點:
- 它們都是用來間接訪問內(nèi)存的方式。
- 它們本身都占用內(nèi)存(指針占用內(nèi)存來存儲所指向?qū)ο蟮牡刂?,引用則是對象的別名,所以其實引用本身也是對象)。
- 它們都可以用來訪問動態(tài)分配的內(nèi)存(使用malloc()等函數(shù))。
- 不同點:
- 指針是一個實體,它存儲的是一個地址,指向內(nèi)存的一個存儲單元。而引用是原變量的一個別名,它存儲的是原變量的值。
- 指針可以被重新賦值,指向不同的對象,而引用在聲明后就不能改變其指向的對象。
- 指針可以被const修飾,而引用不能被const修飾。
- sizeof運算符在操作引用時得到的是對象本身的大小,而操作指針時得到的是指針變量本身的大小。
- 相互轉(zhuǎn)換:
- 指針轉(zhuǎn)引用:將指針變量的值直接賦值給引用變量即可。
- 引用轉(zhuǎn)指針:可以使用類型轉(zhuǎn)換操作符(*)將引用轉(zhuǎn)換為指針。
總的來說,指針和引用在功能和使用上有一些區(qū)別,需要根據(jù)具體情況選擇使用哪種方式。
5、extern"C”的作用
extern "C"是一個C語言鏈接器的關(guān)鍵字,它有以下幾個作用:
使得在C++中使用C編譯方式成為可能,指明該函數(shù)使用C編譯方式。
在某些情況下,使用extern "C"聲明函數(shù),可以使得C++編譯器按照C語言的方式對函數(shù)進行編譯和鏈接,從而能夠正確地調(diào)用該函數(shù)。
extern "C"可以用于在C++中調(diào)用由C語言編寫的庫函數(shù)。因為C++與C語言的函數(shù)調(diào)用方式不同,使用extern "C"可以指明該函數(shù)使用C語言的方式進行鏈接,避免因為鏈接方式不同而導(dǎo)致的錯誤。
在使用動態(tài)鏈接庫(DLL)時,使用extern "C"可以保證函數(shù)的導(dǎo)出和導(dǎo)入與C語言一致。
總之,extern "C"的作用是為了在C++中使用C語言的編譯和鏈接方式,并且在一些特定情況下保證函數(shù)的正確導(dǎo)出和導(dǎo)入。
6、重寫memcpy()函數(shù)需要注意哪些問題,(strcat strncat strcmp strcpy)那些函數(shù)會導(dǎo)致內(nèi)存溢出?
重寫?
memcpy()
?函數(shù)時需要注意以下問題:
- 源地址和目標地址的正確性:確保源地址和目標地址是有效的、合法的內(nèi)存地址。在復(fù)制過程中,如果源地址無效或目標地址不足,會導(dǎo)致錯誤或未定義的行為。
- 復(fù)制的字節(jié)數(shù):確保復(fù)制的字節(jié)數(shù)不超過目標地址的剩余空間,以避免內(nèi)存溢出。在復(fù)制過程中,如果目標地址的剩余空間不足以容納要復(fù)制的數(shù)據(jù),會導(dǎo)致內(nèi)存溢出。
- 目標地址的內(nèi)存分配:如果目標地址是動態(tài)分配的內(nèi)存區(qū)域(例如通過?
malloc()
?函數(shù)分配的內(nèi)存),則在復(fù)制之前需要確保目標地址的內(nèi)存已經(jīng)分配,并且在復(fù)制完成后及時釋放,以避免內(nèi)存泄漏。- 邊界檢查和錯誤處理:對于類似于?
strcat()
、strncat()
、strcmp()
、strcpy()
?等函數(shù),在處理字符串時需要注意邊界檢查,確保輸入的字符串不會超過目標地址的限制。對于錯誤的輸入,應(yīng)該有適當?shù)腻e誤處理機制,例如報錯或者返回錯誤碼。下面是關(guān)于?
strcat()
、strncat()
、strcmp()
、strcpy()
?函數(shù)的一些注意事項:
strcat()
?函數(shù)用于將一個字符串追加到另一個字符串的末尾。如果目標字符串的長度不足,或者目標字符串的剩余空間不足以容納要追加的數(shù)據(jù),就會導(dǎo)致內(nèi)存溢出。strncat()
?函數(shù)類似于?strcat()
,但是可以指定要復(fù)制的字節(jié)數(shù)。在使用?strncat()
?時,需要確保目標字符串的剩余空間足夠大,以避免內(nèi)存溢出。strcmp()
?函數(shù)用于比較兩個字符串是否相等。這個函數(shù)不會導(dǎo)致內(nèi)存溢出,但是需要注意輸入的字符串長度,如果輸入的字符串過長可能會導(dǎo)致性能問題。strcpy()
?函數(shù)用于將一個字符串復(fù)制到另一個字符串中。在使用?strcpy()
?時,需要確保目標字符串的長度足夠大,以避免內(nèi)存溢出。此外,還需要注意源字符串是否具有足夠的空間,以避免訪問越界的問題。
7、char 和 int 之間的轉(zhuǎn)換
在C/C++中,可以使用以下方式將char和int之間進行轉(zhuǎn)換:
將char轉(zhuǎn)換為int:
- 使用強制類型轉(zhuǎn)換,將char的ASCII碼值轉(zhuǎn)換為int。例如,對于char c = 'A';,可以使用int i = (int)c;來將c轉(zhuǎn)換為int類型的i。
- 如果char類型的數(shù)據(jù)只包含ASCII碼值,可以使用自然的隱式轉(zhuǎn)換。例如,對于char c = 'A';,可以使用int i = c;來將c轉(zhuǎn)換為int類型的i。
將int轉(zhuǎn)換為char:
- 如果int類型的數(shù)據(jù)是ASCII碼值,可以直接賦值給char類型的變量。例如,對于int i = 65;,可以使用char c = i;來將i轉(zhuǎn)換為char類型的c。
- 如果int類型的數(shù)據(jù)不是ASCII
8、static的用法(定義和用途) static靜態(tài)變量,只初始化一次
在編程中,
static
?是一個關(guān)鍵字,用于指明變量或函數(shù)的特性。在C語言中,static
?可以用于以下兩種情況:
定義靜態(tài)變量:
- 靜態(tài)變量是在程序執(zhí)行期間只初始化一次的變量。它們在程序開始時被分配內(nèi)存,并在程序結(jié)束時被釋放。
- 靜態(tài)變量默認值為0,但也可以在定義時顯式地初始化。
- 靜態(tài)變量可以用于記錄某些狀態(tài)或計數(shù)器,因為它們不會在程序運行期間被重新初始化。
定義靜態(tài)函數(shù):
- 靜態(tài)函數(shù)是在程序執(zhí)行期間只初始化一次的函數(shù)。它們在程序開始時被分配內(nèi)存,并在程序結(jié)束時被釋放。
- 靜態(tài)函數(shù)只在其定義的模塊中被使用,不能被其他模塊直接調(diào)用。
- 靜態(tài)函數(shù)可以用于實現(xiàn)某些特定的功能,例如加密、解密、字符串處理等。
9、const的用法(定義和用途)
告訴編譯器該變量的值不能被修改:
使用 const 關(guān)鍵字定義變量可以明確告知編譯器該變量的值不可被修改,這有助于編譯器進行類型檢查和代碼優(yōu)化。避免不必要的內(nèi)存分配:
使用 const 關(guān)鍵字定義變量可以避免不必要的內(nèi)存分配,因為編譯器會將這些常變量存儲在符號表中,而不是在內(nèi)存中。在函數(shù)中使用:
在函數(shù)中使用 const 關(guān)鍵字可以確保函數(shù)不會修改傳入?yún)?shù)的值,這有助于提高函數(shù)的可讀性和安全性。同時,函數(shù)也可以返回 const 類型的值,以確保函數(shù)返回的值不會被修改。
10、const 常量和 #define 的區(qū)別(編譯階段、安全性、內(nèi)存占用等)
const 常量和#define 都是在C/C++中用于定義常量,但它們之間有一些重要的區(qū)別。
定義方式:
const 關(guān)鍵字用于定義常量,它是類型安全的,可以用于聲明各種類型的常量,如整數(shù)、浮點數(shù)、字符等。而#define 是通過預(yù)處理器定義的,它可以定義任何類型的常量,包括字符串和其他復(fù)雜的表達式。編譯階段:
const 是在編譯階段處理的,它在編譯時被解析為常量表達式,并且可以直接內(nèi)聯(lián)到代碼中。而#define 是由預(yù)處理器在編譯預(yù)處理階段處理的,它會被替換為相應(yīng)的常量表達式。類型安全:
const 關(guān)鍵字是類型安全的,它需要在聲明時指定類型,并且在編譯時進行類型檢查。而#define 沒有類型檢查,它只是一個簡單的文本替換,沒有類型檢查和語法檢查。內(nèi)存占用:
const 常量是靜態(tài)分配內(nèi)存的,它們被存儲在程序的數(shù)據(jù)區(qū)中,并且在編譯時就已經(jīng)確定了其值。而#define 只是一個符號,在編譯預(yù)處理階段被替換為相應(yīng)的值,因此它不會分配內(nèi)存,只是在編譯時進行了一次文本替換。可讀性和安全性:
const 常量具有更好的可讀性和安全性,它們可以提供更明確的語義,告訴讀者該值是不能被修改的。而#define 只是一個預(yù)處理器指令,容易被誤用或濫用,因此它的可讀性和安全性相對較低。綜上所述,const 常量提供了更好的類型安全性和可讀性,并且在編譯時進行內(nèi)存分配,同時也具有更好的性能。而#define 則更靈活,可以在編譯預(yù)處理階段進行一些復(fù)雜的操作,但它的類型安全性和可讀性相對較低。在實際編程中,應(yīng)根據(jù)具體情況選擇使用 const 常量還是 #define。
11、 volatile作用和用法
volatile 是一個修飾符,用于聲明在多線程環(huán)境下可能會被意外修改的變量。
在多線程環(huán)境下,由于有多個線程同時訪問共享變量,可能會導(dǎo)致一些意外的行為,如一個線程正在修改變量時,另一個線程正在讀取該變量,讀取到的值可能不是最新的值。這種情況下,就需要使用 volatile 關(guān)鍵字來確保變量的可見性和一致性。
具體來說,使用 volatile 關(guān)鍵字可以保證以下幾點:
保證變量的可見性:當一個線程修改變量的值時,其他線程會立即看到這個最新的值。
防止指令重排:由于編譯器可能會對代碼進行優(yōu)化,導(dǎo)致一些指令的執(zhí)行順序與代碼中的順序不一致。使用 volatile 關(guān)鍵字可以防止這種指令重排,確保代碼的執(zhí)行順序與代碼中的順序一致。
需要注意的是,雖然使用 volatile 關(guān)鍵字可以保證變量的可見性和一致性,但它不能保證線程之間的同步。如果需要保證線程之間的同步,還需要使用其他的同步機制。
12、變量的作用域(全局變量和局部變量)
變量的作用域是指變量在程序中可以使用的范圍。在C/C++中,變量可以分為全局變量和局部變量兩種。
- 全局變量(global variable):
全局變量是在函數(shù)外部定義的變量,它們的作用域是整個程序,可以從頭文件一直使用到程序結(jié)束。全局變量通常在程序啟動時初始化,并且可以被程序中的多個函數(shù)共同使用。- 局部變量(local variable):
局部變量是在函數(shù)內(nèi)部定義的變量,它們的作用域僅限于函數(shù)內(nèi)部。當函數(shù)執(zhí)行結(jié)束時,局部變量會被銷毀,其內(nèi)存空間也會被釋放。
13、sizeof 與 strlen (字符串,數(shù)組)
sizeof() 是 C/C++ 中的運算符,用于獲取變量或數(shù)據(jù)類型在內(nèi)存中所占用的字節(jié)數(shù)。而 strlen() 是 C/C++ 中的函數(shù),用于計算字符串的長度(不包括字符串結(jié)束符 '\0')。
對于字符串和數(shù)組,sizeof() 和 strlen() 的使用有以下區(qū)別:
字符串:
- sizeof() 運算符用于獲取整個字符串占用的字節(jié)數(shù),包括字符串結(jié)束符 '\0'。例如,對于 char str[] = "hello";,sizeof(str) 的結(jié)果是 6(包括 '\0')。
- strlen() 函數(shù)用于獲取字符串的長度,即從字符串的起始地址開始,直到遇到結(jié)束符 '\0' 前,所經(jīng)過的字節(jié)數(shù)。例如,對于 char str[] = "hello";,strlen(str) 的結(jié)果是 5。
數(shù)組:
- sizeof() 運算符用于獲取整個數(shù)組占用的字節(jié)數(shù)。例如,對于 int arr[] = {1, 2, 3};,sizeof(arr) 的結(jié)果是 sizeof(int) * 數(shù)組長度(即 sizeof(int) * 3)。
- strlen() 函數(shù)通常不用于數(shù)組,因為數(shù)組沒有結(jié)束符 '\0',無法計算其長度。
需要注意的是,sizeof() 運算符的結(jié)果是一個編譯時確定的常量表達式,而 strlen() 函數(shù)需要在運行時逐個字符地計算字符串的長度。在使用時需要根據(jù)具體情況選擇合適的函數(shù),并注意避免越界訪問和空指針異常等問題。
14、經(jīng)典的sizeof(struct)和內(nèi)存對齊(一字節(jié)對齊)?
在C語言中,sizeof()運算符用于獲取變量或數(shù)據(jù)類型的大小。對于struct類型,sizeof()運算符將返回整個struct的大小,而不是每個成員變量的大小之和。這是因為C語言中的struct成員變量的對齊方式可能會導(dǎo)致struct的大小不是成員變量大小的整數(shù)倍。
內(nèi)存對齊是為了提高內(nèi)存訪問的效率而引入的一種內(nèi)存布局技術(shù)。在32位系統(tǒng)中最小的對齊單位是4字節(jié),在64位系統(tǒng)中最小的對齊單位是8字節(jié)。根據(jù)對齊單位,編譯器會在變量或結(jié)構(gòu)體成員之間插入填充字節(jié),使得它們的起始地址滿足對齊要求。
對于一字節(jié)對齊,它通常用于一些特定的數(shù)據(jù)類型,例如char類型,它占用的空間就是1個字節(jié)。對于一些需要按照字節(jié)進行訪問的數(shù)據(jù)類型,例如位域(bit-fields),也需要使用一字節(jié)對齊來保證數(shù)據(jù)的正確性。
在使用sizeof()運算符時,需要注意以下幾點:
- 對于結(jié)構(gòu)體或聯(lián)合體類型,sizeof()返回的大小是整個結(jié)構(gòu)體或聯(lián)合體的占據(jù)的內(nèi)存空間,而不是每個成員變量的大小之和。
- 在進行內(nèi)存對齊時,需要考慮結(jié)構(gòu)體成員變量的類型、大小和順序,以及編譯器和系統(tǒng)的對齊要求。合理地規(guī)劃內(nèi)存布局可以提高程序的性能和效率。
- 對于一些特殊的對齊要求,例如一字節(jié)對齊,需要使用特定的語法或技巧來實現(xiàn),例如使用#pragma pack指令或者在結(jié)構(gòu)體中使用特定的對齊修飾符(如__attribute__((packed))。
總之,sizeof()運算符和內(nèi)存對齊是C語言中重要的概念,需要熟悉和掌握它們的使用方法和注意事項,以便更好地管理內(nèi)存和提高程序的性能和效率。
推薦博客地址:http://t.csdn.cn/sAlrc
15、const * char 與const char *?
"const * char" 和 "const char *" 都是C語言中的指針聲明,但它們有一些不同之處。
"const * char":
- 這個聲明表示一個指向常量字符的指針。這里的"const"修飾的是指針所指向的數(shù)據(jù),即字符數(shù)據(jù)是不可修改的,而指針本身是可修改的。
- 可以用作指向字符數(shù)組的首地址,或者指向字符串的地址。
"const char *":
- 這個聲明表示一個指向字符常量的指針。這里的"const"修飾的是指針本身,即指針自身是
不可修改的,而指針所指向的數(shù)據(jù)是可修改的。- 通常用于指向字符串字面值或字符常量。
總結(jié)來說,"const * char"表示一個指向常量字符的指針,而"const char *"表示一個指向字符常量的指針。在C語言中,對于字符串字面值或字符常量,通常使用"const char *"來聲明指針。
16、inline函數(shù)
inline
?是一個C/C++中的關(guān)鍵字,用于告訴編譯器該函數(shù)的實現(xiàn)應(yīng)該在編譯時進行內(nèi)聯(lián)。內(nèi)聯(lián)函數(shù)的目的是為了減少程序的運行時開銷,通過在編譯時將函數(shù)的調(diào)用替換為函數(shù)的實現(xiàn),避免了函數(shù)調(diào)用的額外開銷,提高了程序的執(zhí)行效率。
17、內(nèi)存四區(qū),什么變量分別存儲在什么區(qū)域,堆上還是棧上。
在執(zhí)行一個C/C++語言程序時,會將程序分配到的內(nèi)存分為四個區(qū)域:棧區(qū)、堆區(qū)、全局區(qū)(靜態(tài)區(qū))和代碼區(qū)。每個程序都有唯一的四個內(nèi)存區(qū)域,我們需要熟悉和了解各個區(qū)域的特性,例如存儲什么類型的數(shù)據(jù),有誰去申請開辟,又有誰去管理釋放。
- 棧區(qū):棧區(qū)是用來存儲函數(shù)調(diào)用和局部變量的一塊內(nèi)存區(qū)域,它是在程序執(zhí)行時自動分配的,并且只在函數(shù)調(diào)用時使用,不會造成內(nèi)存泄漏。在函數(shù)返回后,棧區(qū)會自動釋放。
- 堆區(qū):堆區(qū)是用來存儲動態(tài)分配的內(nèi)存的一塊內(nèi)存區(qū)域,它是由程序員分配和釋放的。在程序執(zhí)行時,通過malloc等函數(shù)從堆區(qū)分配一塊內(nèi)存,使用完后需要手動釋放,否則會造成內(nèi)存泄漏。
- 全局區(qū)(靜態(tài)區(qū)):全局區(qū)是用來存儲全局變量和靜態(tài)變量的一塊內(nèi)存區(qū)域,它是在程序執(zhí)行時就已經(jīng)分配好并且一直存在直到程序結(jié)束時才被釋放。
- 代碼區(qū):代碼區(qū)是用來存儲程序代碼的一塊內(nèi)存區(qū)域,它是在程序執(zhí)行時就已經(jīng)分配好并且一直存在直到程序結(jié)束時才被釋放。
需要注意的是,這四個區(qū)域是按照順序依次排列的,并且每個區(qū)域的存儲數(shù)據(jù)類型和申請方式都有所不同,需要根據(jù)具體情況進行管理和使用。
第三章 :網(wǎng)絡(luò)編程
1 、TCP、UDP的區(qū)別
TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報協(xié)議)是兩種常見的網(wǎng)絡(luò)傳輸協(xié)議,它們有以下區(qū)別:
- 連接:TCP是面向連接的協(xié)議,而UDP是無連接的協(xié)議。在發(fā)送數(shù)據(jù)前,TCP通過三次握手建立連接,而UDP不需要建立連接。
- 可靠性:TCP提供可靠的數(shù)據(jù)傳輸,保證了數(shù)據(jù)的可靠性和完整性。TCP通過序號、確認應(yīng)答和超時重傳等機制來實現(xiàn)可靠性。而UDP不提供可靠性保證,數(shù)據(jù)可能丟失、損壞或重復(fù)。
- 傳輸速度:UDP比TCP快,因為它不需要建立連接和提供可靠性保障。在一些場景中,如視頻、音頻等實時應(yīng)用,UDP更適合。
- 數(shù)據(jù)量限制:UDP的數(shù)據(jù)包大小通常受限于底層網(wǎng)絡(luò)協(xié)議(如以太網(wǎng)),一般不超過1472字節(jié)。而TCP的數(shù)據(jù)包大小則取決于操作系統(tǒng)和底層網(wǎng)絡(luò)協(xié)議。
- 應(yīng)用場景:TCP適用于可靠性要求高的應(yīng)用場景,如網(wǎng)頁瀏覽、電子郵件等。UDP適用于對速度和實時性要求高的應(yīng)用場景,如在線游戲、視頻流等。
- 頭部開銷:TCP的首部較大,為20個字節(jié),而UDP的首部較小,為4個字節(jié)。
總的來說,TCP提供了可靠的連接和數(shù)據(jù)傳輸,但相對較慢;而UDP快,但數(shù)據(jù)傳輸不可靠。在選擇傳輸協(xié)議時,需要根據(jù)具體的應(yīng)用場景來權(quán)衡。
2、TCP、UDP的優(yōu)缺點
TCP和UDP都有各自的優(yōu)缺點,以下是它們的比較:
TCP的優(yōu)點:
- 可靠:TCP提供了可靠的連接,保證了數(shù)據(jù)的可靠性和完整性,適用于對數(shù)據(jù)準確性要求高的場景。
- 高速:TCP的傳輸速度相對較快,尤其是在底層網(wǎng)絡(luò)支持的情況下。
- 適應(yīng)性:TCP的協(xié)議規(guī)范和實現(xiàn)獨立于底層網(wǎng)絡(luò)協(xié)議,可以適應(yīng)不同的網(wǎng)絡(luò)環(huán)境。
- 多路復(fù)用:TCP通過連接機制實現(xiàn)了多路復(fù)用,可以同時處理多個數(shù)據(jù)流,提高了傳輸效率。
TCP的缺點:
- 連接管理:TCP需要建立連接和斷開連接的過程,這可能會導(dǎo)致一定的開銷和延遲。
- 數(shù)據(jù)順序:TCP在傳輸過程中需要維護數(shù)據(jù)順序,如果某個數(shù)據(jù)包丟失或亂序,需要重新發(fā)送,這可能會影響傳輸速度。
- 數(shù)據(jù)量限制:TCP的數(shù)據(jù)包大小受限于底層網(wǎng)絡(luò)協(xié)議,如以太網(wǎng)的最大傳輸單元(MTU),超過該限制可能導(dǎo)致數(shù)據(jù)被分割為多個小包傳輸。
- 流量控制:TCP的傳輸速率受限于底層網(wǎng)絡(luò)協(xié)議的帶寬,如果發(fā)送速率過快,可能導(dǎo)致數(shù)據(jù)包丟失或傳輸受阻。
UDP的優(yōu)點:
- 快速:UDP的傳輸速度相對較快,尤其適用于實時性要求高的場景,如在線游戲、視頻流等。
- 靈活性:UDP的數(shù)據(jù)包大小靈活,可以根據(jù)應(yīng)用需要調(diào)整,同時不需要維護數(shù)據(jù)順序。
- 簡單:UDP的協(xié)議相對簡單,易于實現(xiàn)和維護,適用于一些輕量級的應(yīng)用場景。
- 多路復(fù)用:UDP的多路復(fù)用機制可以提高傳輸效率,同時處理多個數(shù)據(jù)流。
UDP的缺點:
- 不可靠:UDP不提供可靠性保障,數(shù)據(jù)可能丟失、損壞或重復(fù),適用于一些對數(shù)據(jù)準確性要求不高的場景。
- 數(shù)據(jù)順序:UDP的數(shù)據(jù)包順序需要應(yīng)用程序自行處理,適用于一些簡單的應(yīng)用場景。
- 數(shù)據(jù)量限制:UDP的數(shù)據(jù)包大小通常受限于底層網(wǎng)絡(luò)協(xié)議(如以太網(wǎng)),一般不超過1472字節(jié)。4. 流控制:UDP的發(fā)送速率受限于底層網(wǎng)絡(luò)協(xié)議的帶寬和接收方的能力,可能導(dǎo)致數(shù)據(jù)包丟失或傳輸受阻。
- 數(shù)據(jù)錯誤處理:UDP的數(shù)據(jù)包在傳輸過程中可能發(fā)生錯誤,如損壞或重復(fù),應(yīng)用程序需要自行處理這些問題。
- 連接管理:UDP沒有建立連接和斷開連接的過程,因此不需要維護連接狀態(tài),這使得它更加輕量級,適用于一些簡單的應(yīng)用場景。
3、TCP UDP適用場景
TCP和UDP都有各自的適用場景。
TCP(傳輸控制協(xié)議)通常用于對準確性要求相對高的場景,比如文件傳輸、接受郵件和遠程登錄。TCP在傳輸數(shù)據(jù)時需要進行數(shù)據(jù)的確認、重發(fā)、排序等操作,因此相對來說效率沒有UDP(用戶數(shù)據(jù)報協(xié)議)高。
UDP常用于對實時性要求高的場景,例如在線游戲、流媒體傳輸。UDP不可靠,因此它不適用于需要保證數(shù)據(jù)完整性和可靠性的應(yīng)用場景。但因為UDP不需要進行連接管理、確認和重傳等操作,所以它的數(shù)據(jù)傳輸速度比TCP快。同時,UDP還支持多播技術(shù),可以將數(shù)據(jù)包發(fā)送到多個目的地。
總的來說,TCP和UDP都有各自的優(yōu)點和適用場景,選擇使用哪一種協(xié)議,需要根據(jù)具體的需求來決定。
4、TCP為什么是可靠連接
TCP之所以被認為是可靠連接,是因為它采用了以下幾種機制來確保數(shù)據(jù)的可靠傳輸:
確認和應(yīng)答機制:TCP通過發(fā)送數(shù)據(jù)后等待接收方的確認,以及在數(shù)據(jù)傳輸過程中采用應(yīng)答機制,確保每個數(shù)據(jù)包都被正確接收。如果接收方?jīng)]有確認收到某個數(shù)據(jù)包,發(fā)送方將重新發(fā)送該數(shù)據(jù)包,直到接收方確認收到為止。
序列號:TCP給每個數(shù)據(jù)包分配一個獨特的序列號,接收方可以根據(jù)序列號對數(shù)據(jù)包進行排序,確保數(shù)據(jù)包的順序正確。
超時重傳:如果發(fā)送方在一定時間內(nèi)沒有收到接收方的確認,將重新發(fā)送數(shù)據(jù)包,以確保數(shù)據(jù)包能夠被正確傳輸。
流量控制:TCP通過流量控制機制,確保發(fā)送速度不會超過接收方處理速度,避免數(shù)據(jù)包丟失或傳輸錯誤。
擁塞控制:當網(wǎng)絡(luò)擁塞時,TCP會減緩發(fā)送速度,以避免過度擁塞網(wǎng)絡(luò),導(dǎo)致數(shù)據(jù)包丟失。
這些機制的結(jié)合,使得TCP能夠在網(wǎng)絡(luò)環(huán)境下實現(xiàn)可靠的連接。
5、OSI典型網(wǎng)絡(luò)模型,簡單說說有哪些
OSI(開放式系統(tǒng)互聯(lián))典型網(wǎng)絡(luò)模型是由七個層次組成的模型,每個層次都有其特定的功能和服務(wù)。以下是這七個層次及其簡要功能:
物理層:這一層的主要功能是建立物理連接,將比特流從一個地方傳輸?shù)搅硪粋€地方,并進行數(shù)模轉(zhuǎn)換和模數(shù)轉(zhuǎn)換。
數(shù)據(jù)鏈路層:這一層的主要功能是為網(wǎng)絡(luò)層提供服務(wù),確保數(shù)據(jù)在物理層上的傳輸可靠。數(shù)據(jù)鏈路層還提供了一些錯誤檢測和校正功能。
網(wǎng)絡(luò)層:這一層的主要功能是進行邏輯地址尋址,實現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇。
傳輸層:這一層的主要功能是定義傳輸數(shù)據(jù)的協(xié)議端口號,并進行流控和差錯校驗。其中最常用的協(xié)議是TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報協(xié)議)。
會話層:這一層的主要功能是建立、管理和終止會話。會話層還提供了一些同步和對話控制的功能。
表示層:這一層的主要功能是將數(shù)據(jù)進行加密、解密、壓縮、解壓縮等處理,以確保數(shù)據(jù)的完整性和一致性。
應(yīng)用層:這一層是OSI模型的最上層,它提供了網(wǎng)絡(luò)服務(wù)與最終用戶的一個接口,用戶可以操作的一個界面終端。
這些層次協(xié)同工作,共同構(gòu)成了一個完整的、完善的網(wǎng)絡(luò)模型。
6、三次握手、四次揮手
三次握手和四次揮手是TCP協(xié)議中建立連接和關(guān)閉連接的過程。
三次握手:
客戶端向服務(wù)器發(fā)送SYN(同步)報文,請求建立連接。此時,客戶端的SYN=1,ACK=0。
服務(wù)器收到客戶端的SYN報文后,向客戶端發(fā)送SYN+ACK(同步+確認)報文,表示確認收到客戶端的請求,并請求建立連接。此時,服務(wù)器的SYN=1,ACK=1。
客戶端收到服務(wù)器的SYN+ACK報文后,向服務(wù)器發(fā)送ACK(確認)報文,表示確認收到服務(wù)器的請求。此時,客戶端的ACK=1。
四次揮手:
客戶端向服務(wù)器發(fā)送FIN(結(jié)束)報文,請求關(guān)閉連接。此時,客戶端的FIN=1,ACK=0。
服務(wù)器收到客戶端的FIN報文后,向客戶端發(fā)送ACK(確認)報文,表示確認收到客戶端的請求關(guān)閉連接的請求。此時,服務(wù)器的ACK=1。
服務(wù)器向客戶端發(fā)送FIN(結(jié)束)報文,請求關(guān)閉連接。此時,服務(wù)器的FIN=1,ACK=0。
客戶端收到服務(wù)器的FIN報文后,向服務(wù)器發(fā)送ACK(確認)報文,表示確認收到服務(wù)器的請求關(guān)閉連接的請求。此時,客戶端的ACK=1。
這樣,TCP連接就建立成功了,并且確保了連接的可靠性。
第四章:常見算法
1、什么是 pid 算法,pid 算法有什么調(diào)參經(jīng)驗?
PID算法是一種常見的控制算法,用于調(diào)整系統(tǒng)的輸入信號,以使系統(tǒng)的輸出達到預(yù)期的目標。PID算法的名字來源于其三個基本的控制元素:比例(P)、積分(I)和微分(D)。
PID算法的主要作用是將系統(tǒng)的實際輸出與期望輸出之間的誤差最小化。具體的調(diào)參經(jīng)驗如下:
比例系數(shù)(P):比例系數(shù)主要影響系統(tǒng)的穩(wěn)定性。比例系數(shù)過大可能導(dǎo)致系統(tǒng)不穩(wěn)定,而比例系數(shù)過小則可能導(dǎo)致系統(tǒng)的反應(yīng)速度過慢。因此,在調(diào)參時需要根據(jù)實際情況選擇適當?shù)谋壤禂?shù)。
積分系數(shù)(I):積分系數(shù)主要影響系統(tǒng)的精度。積分系數(shù)過大可能導(dǎo)致系統(tǒng)出現(xiàn)過度調(diào)整,而積分系數(shù)過小則可能導(dǎo)致系統(tǒng)的精度不夠。在調(diào)參時,需要根據(jù)系統(tǒng)的精度要求選擇適當?shù)姆e分系數(shù)。
微分系數(shù)(D):微分系數(shù)主要影響系統(tǒng)的響應(yīng)速度。微分系數(shù)過大可能導(dǎo)致系統(tǒng)反應(yīng)過快,而微分系數(shù)過小則可能導(dǎo)致系統(tǒng)的響應(yīng)速度過慢。在調(diào)參時,需要根據(jù)系統(tǒng)的響應(yīng)速度要求選擇適當?shù)奈⒎窒禂?shù)。
此外,還有其他一些調(diào)參經(jīng)驗,如:
一般來說,先調(diào)整比例系數(shù),再調(diào)整積分系數(shù)和微分系數(shù)。
在調(diào)整積分系數(shù)和微分系數(shù)時,需要根據(jù)系統(tǒng)的延遲時間和響應(yīng)速度進行綜合考慮。
在調(diào)整參數(shù)時,需要進行逐步調(diào)整,以避免參數(shù)過大或過小的跳躍。
總之,PID算法的調(diào)參是一個需要綜合考慮各種因素的過程,需要根據(jù)實際情況進行靈活的調(diào)整
2、常見的濾波算法有哪些,如何實現(xiàn)的?
常見的濾波算法包括:一階補償濾波,算術(shù)平均濾波,中位值濾波,限幅平均濾波,滑動平均濾波和卡爾曼濾波。
推薦博客地址:http://t.csdn.cn/YHNiK
3、各種排序算法的時間空間復(fù)雜度、穩(wěn)定性
4、十大排序算法的實現(xiàn)
推薦博客地址:http://t.csdn.cn/Wmf3V
5、二分法查找的原理
二分法查找(也稱為折半查找)是一種在有序數(shù)組中查找特定元素的搜索算法。其基本原理如下:
- 首先,將數(shù)組按升序排列,使得數(shù)組中的元素位于一個單調(diào)遞增的序列中。
- 接著,選擇數(shù)組的中間元素作為查找的起始點,如果該元素正好是要查找的元素,則查找過程結(jié)束,否則執(zhí)行下一步。
- 如果要查找的元素大于中間元素,則在數(shù)組的右半部分重復(fù)步驟2;如果要查找的元素小于中間元素,則在數(shù)組的左半部分重復(fù)步驟2。
- 如果在某一步中,數(shù)組為空,則表示查找失敗,即要查找的元素不在數(shù)組中。
通過不斷將查找區(qū)間縮小一半,最終可以找到要查找的元素,或者確定該元素不在數(shù)組中。
第五章:?Linux操作系統(tǒng)常見面試題
1、Linux內(nèi)核的組成部分
Linux內(nèi)核主要由以下幾個部分組成:
進程調(diào)度(SCHED):負責(zé)控制CPU對進程的訪問,使多個進程能夠在同一時間競爭CPU資源。
內(nèi)存管理(MM):負責(zé)管理系統(tǒng)的內(nèi)存,包括物理內(nèi)存和虛擬內(nèi)存,以及內(nèi)核對內(nèi)存的訪問控制。
虛擬文件系統(tǒng)(VFS):提供對文件系統(tǒng)的統(tǒng)一抽象接口,使得不同的文件系統(tǒng)能夠在更高層次上進行訪問和操作。
網(wǎng)絡(luò)接口(NET):提供對網(wǎng)絡(luò)協(xié)議的支持,包括網(wǎng)絡(luò)接口驅(qū)動程序和網(wǎng)絡(luò)協(xié)議的處理。
進程間通信(IPC):提供進程之間的通信機制,包括信號、管道、共享內(nèi)存等。
模塊管理器(MODULES):負責(zé)加載和卸載內(nèi)核模塊,以及與模塊相關(guān)的管理和維護工作。
系統(tǒng)調(diào)用接口(SYSCALLS):提供用戶空間與內(nèi)核空間之間的接口,使得用戶程序能夠調(diào)用內(nèi)核提供的系統(tǒng)功能。
這些組成部分共同構(gòu)成了Linux內(nèi)核,使得Linux操作系統(tǒng)具有了強大的功能和靈活性。
2、用戶空間與內(nèi)核通信方式有哪些?
用戶空間與內(nèi)核空間之間的通信方式有以下幾種:
系統(tǒng)調(diào)用(System Call):當用戶程序需要內(nèi)核提供服務(wù)時,可以通過系統(tǒng)調(diào)用接口發(fā)起系統(tǒng)調(diào)用。系統(tǒng)調(diào)用是一種由用戶程序主動發(fā)起的從用戶空間向內(nèi)核空間發(fā)送的請求,通常用于完成一些與硬件或系統(tǒng)相關(guān)操作,如文件操作、進程控制、內(nèi)存管理等。
中斷(Interrupt):當硬件或軟件事件發(fā)生時,可以通過中斷接口將控制權(quán)轉(zhuǎn)移到內(nèi)核空間。中斷通常用于處理異步事件,如硬件中斷、時鐘中斷、進程中斷等。
信號(Signal):信號是一種由內(nèi)核或進程發(fā)送的異步事件,用于通知用戶程序某些事件已經(jīng)發(fā)生或需要立即執(zhí)行某個操作。信號通常用于進程間的通信和同步,如進程終止信號、錯誤信號等。
管道(Pipe):管道是一種半雙工的通信機制,用于實現(xiàn)進程之間的數(shù)據(jù)傳輸和共享。管道可以是字節(jié)流或消息流,可以用于實現(xiàn)進程之間的父子進程通信或進程與內(nèi)核模塊之間的通信。
共享內(nèi)存(Shared Memory):共享內(nèi)存是一種高效的進程間通信方式,通過將同一塊物理內(nèi)存映射到多個進程的虛擬地址空間中,使得多個進程可以同時訪問和修改該內(nèi)存區(qū)域中的數(shù)據(jù)。共享內(nèi)存可以實現(xiàn)不同進程之間的數(shù)據(jù)共享和同步。
這些通信方式提供了用戶空間和內(nèi)核空間之間的接口,使得用戶程序能夠調(diào)用內(nèi)核提供的系統(tǒng)功能,同時也實現(xiàn)了用戶空間和內(nèi)核空間之間的數(shù)據(jù)傳輸和通信。
3、系統(tǒng)調(diào)用read()/write(),內(nèi)核具體做了哪些事情
當用戶程序調(diào)用read()或write()系統(tǒng)調(diào)用時,內(nèi)核會執(zhí)行以下一系列操作:
驗證參數(shù):內(nèi)核會驗證用戶程序傳遞的參數(shù)是否合法,包括文件描述符、緩沖區(qū)地址、字節(jié)數(shù)等。如果參數(shù)不合法,內(nèi)核將返回錯誤碼,并終止系統(tǒng)調(diào)用。
權(quán)限檢查:內(nèi)核會檢查用戶程序是否有足夠的權(quán)限執(zhí)行讀取或?qū)懭氩僮?。如果?quán)限不足,內(nèi)核將返回錯誤碼,并終止系統(tǒng)調(diào)用。
數(shù)據(jù)傳輸:如果參數(shù)合法且權(quán)限檢查通過,內(nèi)核會根據(jù)文件描述符所代表的文件類型和文件偏移量,將數(shù)據(jù)從文件或設(shè)備中讀取或?qū)懭氲接脩舫绦虻木彌_區(qū)中。
緩沖區(qū)管理:內(nèi)核會管理文件緩沖區(qū),確保讀取和寫入的數(shù)據(jù)正確地緩存和刷新。在讀取和寫入完成后,內(nèi)核會將緩沖區(qū)中的數(shù)據(jù)傳遞給用戶程序或從用戶程序接收數(shù)據(jù)。
內(nèi)存管理:在讀取和寫入數(shù)據(jù)時,內(nèi)核會管理內(nèi)存,確保數(shù)據(jù)的正確存儲和訪問。如果需要,內(nèi)核會分配或釋放內(nèi)存,以適應(yīng)數(shù)據(jù)的大小和訪問需求。
錯誤處理:在讀取或?qū)懭氩僮魍瓿珊?,?nèi)核會檢查是否有錯誤發(fā)生。如果有錯誤發(fā)生,內(nèi)核會記錄錯誤碼,并將錯誤信息傳遞給用戶程序。
返回結(jié)果:如果讀取或?qū)懭氩僮鞒晒ν瓿?,?nèi)核會將結(jié)果返回給用戶程序,包括讀取或?qū)懭氲淖止?jié)數(shù)等。
總之,當用戶程序調(diào)用read()或write()系統(tǒng)調(diào)用時,內(nèi)核會執(zhí)行一系列操作來驗證參數(shù)、檢查權(quán)限、傳輸數(shù)據(jù)、管理緩沖區(qū)和內(nèi)存,并處理錯誤,并將結(jié)果返回給用戶程序。這些操作保證了用戶程序與內(nèi)核之間的安全和正確的數(shù)據(jù)傳輸。
4、系統(tǒng)調(diào)用與普通函數(shù)調(diào)用的區(qū)別
系統(tǒng)調(diào)用和普通函數(shù)調(diào)用在以下幾個方面存在區(qū)別:
調(diào)用方式:系統(tǒng)調(diào)用是通過中斷實現(xiàn)的,而普通函數(shù)調(diào)用是通過函數(shù)調(diào)用實現(xiàn)的。系統(tǒng)調(diào)用會將控制權(quán)從用戶空間切換到內(nèi)核空間,而普通函數(shù)調(diào)用是在用戶空間內(nèi)進行的。
調(diào)用層次:系統(tǒng)調(diào)用是操作系統(tǒng)提供給應(yīng)用程序的接口,可以訪問硬件和系統(tǒng)資源,而普通函數(shù)調(diào)用通常是為了實現(xiàn)應(yīng)用程序內(nèi)部的邏輯。
調(diào)用時長:系統(tǒng)調(diào)用的處理速度通常比普通函數(shù)調(diào)用慢,因為系統(tǒng)調(diào)用需要額外的開銷,例如中斷處理和上下文切換。
調(diào)用安全性:系統(tǒng)調(diào)用在執(zhí)行時具有更高的安全性,因為它們會進行參數(shù)驗證和權(quán)限檢查,而普通函數(shù)調(diào)用通常不會進行這些檢查。
調(diào)用范圍:系統(tǒng)調(diào)用是全局的,可以跨越不同的進程和用戶空間,而普通函數(shù)調(diào)用是局部的,僅限于當前進程和用戶空間。
總之,系統(tǒng)調(diào)用和普通函數(shù)調(diào)用在調(diào)用方式、調(diào)用層次、調(diào)用時長、調(diào)用安全性和調(diào)用范圍等方面存在明顯的區(qū)別。系統(tǒng)調(diào)用是為了實現(xiàn)操作系統(tǒng)提供給應(yīng)用程序的接口,而普通函數(shù)調(diào)用則是為了實現(xiàn)應(yīng)用程序內(nèi)部的邏輯。
5、內(nèi)核態(tài),用戶態(tài)的區(qū)別
內(nèi)核態(tài)和用戶態(tài)是操作系統(tǒng)中的兩個不同運行級別,它們之間存在以下區(qū)別:
權(quán)限不同:內(nèi)核態(tài)擁有更高的權(quán)限,可以訪問系統(tǒng)的所有資源,而用戶態(tài)只能訪問受限的資源,例如內(nèi)存、硬件設(shè)備等。
訪問資源:在內(nèi)核態(tài)下,操作系統(tǒng)可以直接訪問系統(tǒng)資源,而不需要通過用戶程序的請求,而在用戶態(tài)下,用戶程序需要通過系統(tǒng)調(diào)用才能訪問系統(tǒng)資源。
運行空間:內(nèi)核態(tài)運行在內(nèi)核空間,擁有系統(tǒng)的全部內(nèi)存空間,而用戶態(tài)運行在用戶空間,只擁有有限的內(nèi)存空間。
任務(wù)執(zhí)行順序:內(nèi)核態(tài)是搶占式執(zhí)行,優(yōu)先級更高,可以中斷用戶態(tài)任務(wù)的執(zhí)行,而用戶態(tài)是協(xié)作式執(zhí)行,優(yōu)先級較低。
驅(qū)動程序:內(nèi)核態(tài)下運行的是驅(qū)動程序,用于管理硬件設(shè)備的接入和訪問,而用戶態(tài)下運行的則是應(yīng)用程序和庫函數(shù)。
內(nèi)核態(tài)和用戶態(tài)之間的區(qū)別是為了保證系統(tǒng)的安全性和穩(wěn)定性。通過限制內(nèi)核態(tài)的訪問權(quán)限和資源,可以防止惡意程序?qū)ο到y(tǒng)造成損害,同時也提供了更好的靈活性和可擴展性。
6、bootloade、內(nèi)核、根文件的關(guān)系
BootLoader、內(nèi)核和根文件系統(tǒng)是操作系統(tǒng)啟動的三個重要組成部分,它們之間的關(guān)系如下:
BootLoader:BootLoader是操作系統(tǒng)啟動時首先執(zhí)行的程序,它的作用是加載內(nèi)核并將控制權(quán)交給內(nèi)核。BootLoader通過讀取內(nèi)核映像文件,將其加載到內(nèi)存中,然后跳轉(zhuǎn)到內(nèi)核的入口地址,使內(nèi)核開始執(zhí)行。
內(nèi)核:內(nèi)核是操作系統(tǒng)的核心部分,它負責(zé)管理系統(tǒng)的進程、內(nèi)存、設(shè)備驅(qū)動等核心功能。在內(nèi)核啟動后,它會檢查文件系統(tǒng)并掛載根文件系統(tǒng)到系統(tǒng)中。
根文件系統(tǒng):根文件系統(tǒng)是操作系統(tǒng)的文件系統(tǒng),它包含了操作系統(tǒng)的基本文件和目錄。在內(nèi)核啟動后,它會檢查文件系統(tǒng)并掛載根文件系統(tǒng)到系統(tǒng)中,使應(yīng)用程序能夠訪問和操作這些文件和目錄。
在操作系統(tǒng)的啟動過程中,BootLoader會加載內(nèi)核并將控制權(quán)交給內(nèi)核,內(nèi)核會初始化系統(tǒng)的各個組件,然后檢查和掛載根文件系統(tǒng)到系統(tǒng)中。這樣,應(yīng)用程序就可以通過根文件系統(tǒng)訪問和操作文件和目錄。因此,BootLoader、內(nèi)核和根文件系統(tǒng)之間的關(guān)系是相互依存、缺一不可的。
7、Bootloader啟動過程
推薦博客地址:http://t.csdn.cn/e8hzp
8、Linux下檢查內(nèi)存狀態(tài)的命令
在Linux下,可以使用以下命令來檢查內(nèi)存狀態(tài):
free命令:可以顯示系統(tǒng)內(nèi)存狀態(tài),包括物理內(nèi)存、已使用的內(nèi)存、空閑內(nèi)存、緩存等。
vmstat命令:可以顯示虛擬內(nèi)存狀態(tài),包括內(nèi)存使用情況、緩存、進程狀態(tài)等。
top命令:可以實時查看系統(tǒng)內(nèi)存使用情況,包括內(nèi)存使用率、進程狀態(tài)、CPU使用率等。
htop命令:可以以更為詳細的格式顯示系統(tǒng)內(nèi)存使用情況,包括每個進程的內(nèi)存使用情況、CPU使用率等。
sar命令:可以生成系統(tǒng)性能報告,包括內(nèi)存使用情況、CPU使用率、磁盤使用情況等。
dstat命令:可以顯示系統(tǒng)運行狀態(tài),包括內(nèi)存使用情況、CPU使用率、磁盤使用情況等。
這些命令可以幫助用戶實時查看系統(tǒng)內(nèi)存狀態(tài),并對系統(tǒng)性能進行監(jiān)控和分析。
9、大小端的區(qū)別以及各自的優(yōu)點,哪種時候用。(判斷大小端的三種方式)
大小端(Endian)是指計算機在存儲和表示數(shù)據(jù)時,對于多字節(jié)的數(shù)據(jù)類型(如整數(shù)、長整數(shù)等),以不同的字節(jié)順序進行存儲和表示。
大端(Big-Endian)表示將數(shù)據(jù)的高位字節(jié)存儲在低地址處,而低位字節(jié)存儲在高地址處。
小端(Little-Endian)表示將數(shù)據(jù)的低位字節(jié)存儲在低地址處,而高位字節(jié)存儲在高地址處。
以下是一些關(guān)于大小端的優(yōu)點和適用場景:
優(yōu)點:
- 對于網(wǎng)絡(luò)傳輸和跨平臺通信,使用小端可以減少數(shù)據(jù)在不同平臺之間的轉(zhuǎn)換次數(shù),提高傳輸效率。
- 對于大多數(shù)應(yīng)用程序來說,使用小端可以減少內(nèi)存的使用,因為低位字節(jié)可以更早地被釋放掉。
- 對于一些特定的算法和數(shù)據(jù)結(jié)構(gòu),使用小端可以提高數(shù)據(jù)的局部性,從而提高緩存的命中率。
適用場景:
- 對于需要跨平臺傳輸數(shù)據(jù)的應(yīng)用程序,例如網(wǎng)絡(luò)通信、分布式系統(tǒng)等,建議使用小端。
- 對于需要處理大量整數(shù)或浮點數(shù)運算的應(yīng)用程序,例如科學(xué)計算、圖形處理等,建議使用大端。
- 對于需要處理大量字符串操作的應(yīng)用程序,例如文本編輯器、編譯器等,建議使用小端。
判斷大小端的方式有以下三種:
- 編寫一個多字節(jié)的數(shù)據(jù)類型(例如int、long、float或double),并將其存儲到內(nèi)存中。然后,讀取內(nèi)存中的數(shù)據(jù),并逐字節(jié)地檢查它們的值,以確定字節(jié)順序。
- 使用C標準庫中的函數(shù),例如htonl(主機字節(jié)序)和ntohl(網(wǎng)絡(luò)字節(jié)序),將一個整數(shù)從主機字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序,或?qū)⒕W(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序。通過比較轉(zhuǎn)換前后的值來確定字節(jié)順序。
- 讀取和處理操作系統(tǒng)提供的系統(tǒng)寄存器或寄存器映射,以確定字節(jié)順序。不同的處理器架構(gòu)可能有不同的方式來讀取和處理這些寄存器。
需要注意的是,不同的處理器架構(gòu)可能具有不同的字節(jié)順序,因此在進行跨平臺通信或處理不同架構(gòu)的數(shù)據(jù)時,應(yīng)該特別注意字節(jié)順序的問題。
10、一個程序從開始運行到結(jié)束的完整過程(四個過程)
1、編譯預(yù)處理:處理偽指令
1> 頭文件包含
2> 宏定義
3> 條件編譯?? #if #endif??
???????????????? gcc -E xxx.c -o? xxx.i ??????????????
2、編譯:把預(yù)處理之后的文件進行語法分析,生成匯編代碼
???????????????? gcc? -S xx.i -o xx.s
3、匯編:將匯編文件生成機器代碼(二進制代碼)
???????????????? as xx.s -o xx.o
4、鏈接:去指定路徑下找?guī)旌瘮?shù) (頭文件包含的是聲明,具體實現(xiàn)封裝在庫中)
???????????????? gcc xx.o -o xx
11、什么是堆,棧,內(nèi)存泄漏和內(nèi)存溢出??
堆(Heap)和棧(Stack)是計算機內(nèi)存管理中的兩個重要概念,而內(nèi)存泄漏和內(nèi)存溢出則是與內(nèi)存管理相關(guān)的兩個問題。
堆(Heap):堆是一種動態(tài)分配的內(nèi)存區(qū)域,它由程序員分配和釋放。堆的大小受系統(tǒng)限制,通常位于棧的頂部。在程序運行過程中,當需要分配大塊內(nèi)存時,可以通過調(diào)用malloc等函數(shù)從堆中分配。堆的優(yōu)點是可以靈活地分配和釋放內(nèi)存,但需要注意的是,由于堆是動態(tài)分配的,可能會存在內(nèi)存碎片和內(nèi)存泄漏的問題。
棧(Stack):棧是一種靜態(tài)分配的內(nèi)存區(qū)域,它由系統(tǒng)自動分配和釋放。棧的大小也受系統(tǒng)限制,通常位于內(nèi)存的底部。在程序運行過程中,當需要分配局部變量或函數(shù)參數(shù)時,系統(tǒng)會自動從棧中分配內(nèi)存。棧的優(yōu)點是分配和釋放內(nèi)存的速度較快,但缺點是空間有限且大小固定,無法分配大塊內(nèi)存。
內(nèi)存泄漏(Memory Leak):內(nèi)存泄漏指的是程序中的某些代碼由于某些原因未能釋放已經(jīng)不再需要的內(nèi)存,導(dǎo)致內(nèi)存無法被再次使用。這通常會導(dǎo)致程序運行過程中出現(xiàn)內(nèi)存不足的情況,從而導(dǎo)致程序性能下降或崩潰。
內(nèi)存溢出(Out of Memory):內(nèi)存溢出指的是程序在運行過程中所需的內(nèi)存超過了系統(tǒng)所能提供的內(nèi)存大小。這通常會導(dǎo)致程序崩潰或出現(xiàn)不可預(yù)測的行為。為了解決內(nèi)存溢出問題,程序員需要優(yōu)化程序的內(nèi)存使用,避免無謂的內(nèi)存占用和泄漏。
綜上所述,堆、棧、內(nèi)存泄漏和內(nèi)存溢出是計算機內(nèi)存管理中的重要概念。程序員需要合理地使用堆和棧,避免內(nèi)存泄漏和
12、堆和棧的區(qū)別?
堆(Heap)和棧(Stack)是計算機內(nèi)存管理中的兩個重要概念,它們有以下區(qū)別:
分配方式:堆是動態(tài)分配的,而棧是靜態(tài)分配的。在程序運行過程中,當需要分配大塊內(nèi)存時,可以通過調(diào)用malloc等函數(shù)從堆中分配,而棧則是在程序編譯時就已經(jīng)分配好的。
大小限制:棧的大小是有限的,而堆的大小受系統(tǒng)限制。棧通常位于內(nèi)存的底部,大小固定,而堆位于棧的頂部,可能會占用系統(tǒng)的大部分內(nèi)存。
內(nèi)存釋放:堆的內(nèi)存釋放需要手動進行,而棧的內(nèi)存由系統(tǒng)自動釋放。在程序運行過程中,如果需要釋放堆中的內(nèi)存,需要手動調(diào)用free函數(shù),而棧中的內(nèi)存會自動釋放。
使用場景:棧通常用于存儲局部變量、函數(shù)參數(shù)和返回地址等,而堆通常用于存儲動態(tài)創(chuàng)建的數(shù)據(jù)結(jié)構(gòu)和對象。
需要注意的是,由于堆是動態(tài)分配的,可能會存在內(nèi)存碎片和內(nèi)存泄漏的問題。同時,由于棧的大小有限制,如果分配過多的局部變量或遞歸調(diào)用導(dǎo)致棧溢出的問題也可能出現(xiàn)。
綜上所述,堆和棧在分配方式、大小限制和內(nèi)存釋放方面存在明顯的區(qū)別。程序員需要合理地使用堆和棧來滿足程序的需求,避免內(nèi)存泄漏和溢出問題。
13、死鎖的原因、條件?
死鎖的原因主要有以下幾個:
- 系統(tǒng)資源不足。在這種情況下,進程的資源請求可能無法得到滿足,導(dǎo)致死鎖。
- 進程運行推進的順序不合適,或者由于進程運行推進順序與速度不同,也可能導(dǎo)致死鎖。
- 資源分配不當也是死鎖的原因之一。
產(chǎn)生死鎖的四個必要條件如下:
- 互斥條件:一個資源每次只能被一個進程使用。
- 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
- 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
- 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
只要上述條件之一不滿足,就不會發(fā)生死鎖,而只要系統(tǒng)發(fā)生死鎖,這些條件必然成立。
14、硬鏈接與軟鏈接的區(qū)別
硬鏈接和軟鏈接在以下幾個方面存在區(qū)別:
- 鏈接原理:硬鏈接是指通過文件索引節(jié)點(inode)進行的鏈接,而軟鏈接(也叫符號鏈接)則是指通過文件路徑進行的鏈接。
- 鏈接范圍:硬鏈接僅能在同一文件系統(tǒng)內(nèi)創(chuàng)建,而軟鏈接可以跨越不同的文件系統(tǒng)。
- 文件名和文件路徑:硬鏈接保持文件名不變,但文件路徑可以自由更改,而軟鏈接實際上是對文件的一個快捷方式,更改軟鏈接的文件路徑不會影響原始文件。
- 文件大小:硬鏈接和原始文件具有相同的大小,而軟鏈接則保存了文件路徑的長度。
- 創(chuàng)建方式:在Linux系統(tǒng)中,可以使用ln命令創(chuàng)建硬鏈接和軟鏈接。創(chuàng)建硬鏈接時,需要使用-l選項,而創(chuàng)建軟鏈接時,需要使用-s選項。
- 顏色區(qū)分:在Linux系統(tǒng)中,硬鏈接的文件名通常是白色的,而軟鏈接的文件名則是藍色的。
總結(jié)來說,硬鏈接和軟鏈接在功能上有明顯的區(qū)別。硬鏈接強調(diào)文件數(shù)據(jù)塊的一致性,可以在不同的目錄中創(chuàng)建相同的文件的多個副本,而軟鏈接則強調(diào)指向文件的路徑,可以跨越不同的文件系統(tǒng)。
15、虛擬內(nèi)存,虛擬地址與物理地址的轉(zhuǎn)換
虛擬內(nèi)存是一種計算機內(nèi)存管理技術(shù),它將計算機的物理內(nèi)存與硬盤上的虛擬內(nèi)存結(jié)合起來,通過將部分硬盤空間作為內(nèi)存來使用,從而實現(xiàn)擴大內(nèi)存的效果。
在虛擬內(nèi)存中,每個進程都有其獨立的虛擬地址空間,用于存儲進程的數(shù)據(jù)和代碼。虛擬地址是進程用來訪問內(nèi)存的地址,它與物理地址不同,虛擬地址需要通過虛擬內(nèi)存管理模塊進行轉(zhuǎn)換,才能與物理地址相對應(yīng)。
虛擬地址通常包括兩部分:基址和偏移量。基址是虛擬地址的起始值,而偏移量則是進程中某個數(shù)據(jù)或指令在虛擬地址中的位置。通過將基址和偏移量相加,可以得到進程在虛擬地址空間中的實際位置。
在虛擬內(nèi)存中,為了將虛擬地址轉(zhuǎn)換為物理地址,需要使用頁表這個數(shù)據(jù)結(jié)構(gòu)。頁表記錄了進程的虛擬地址和對應(yīng)的物理地址之間的映射關(guān)系。當進程訪問虛擬地址時,操作系統(tǒng)會根據(jù)頁表中的映射關(guān)系,將虛擬地址轉(zhuǎn)換為物理地址,并將數(shù)據(jù)從磁盤上的虛擬內(nèi)存映射到物理內(nèi)存中。
總結(jié)來說,虛擬內(nèi)存、虛擬地址和物理地址之間的轉(zhuǎn)換是通過頁表實現(xiàn)的。通過將虛擬地址與頁表中的映射關(guān)系相加,可以得到對應(yīng)的物理地址,從而實現(xiàn)虛擬地址到物理地址的轉(zhuǎn)換。(Linux貌似是通過內(nèi)存管理單元MMU進行虛擬映射的?。?/p>
16、計算機中,32bit與64bit有什么區(qū)別
計算機的位數(shù)一般指操作系統(tǒng)的位數(shù),32位操作系統(tǒng)可以尋址2的32次方個字節(jié)的內(nèi)存范圍,而64位操作系統(tǒng)則可尋址2的64次方個字節(jié)的內(nèi)存范圍。以下是它們的主要區(qū)別:
- 數(shù)據(jù)處理能力:32位計算機的CPU一次最多能處理32位數(shù)據(jù),例如它的EAX寄存器就是32位的,而64位計算機一次可以處理8個字節(jié),因此64位計算機數(shù)據(jù)處理能力更強,速度更快。
- 內(nèi)存容量支持:32位的系統(tǒng)許多支持4G的內(nèi)存,而64位系統(tǒng)則可以支持上百G的內(nèi)存。
- 軟件運行版本:64位的系統(tǒng)能夠兼容32位的軟件,但32位的系統(tǒng)不能向上兼容。
- 應(yīng)用場景:由于64位數(shù)據(jù)處理能力更強,因此適合處理大規(guī)模數(shù)據(jù)運算和復(fù)雜任務(wù),如大型數(shù)據(jù)庫、虛擬化和科學(xué)計算等應(yīng)用場景。而32位系統(tǒng)則更適合于小規(guī)模數(shù)據(jù)處理和簡單任務(wù),如Web瀏覽、電子郵件和輕度辦公等應(yīng)用場景。
總的來說,64位計算機相比32位計算機具有更強的數(shù)據(jù)處理能力和更大的內(nèi)存支持,適用于大規(guī)模數(shù)據(jù)運算和復(fù)雜任務(wù)。而32位計算機則適用于小規(guī)模數(shù)據(jù)和簡單任務(wù)。同時,64位操作系統(tǒng)也提供了更高的安全性。
17、中斷和異常的區(qū)別
中斷(Interrupt)和異常(Exception)在含義和本質(zhì)上存在明顯區(qū)別。
- 中斷:是指系統(tǒng)停止當前正在運行的程序,以便處理其他緊急事件或請求。中斷通常是由硬件設(shè)施引發(fā)的,例如,當處理器檢測到硬件故障(如輸入/輸出設(shè)備)或軟件優(yōu)先級較高的請求(如控制臺輸入)時,會觸發(fā)中斷。中斷被視為一種正?,F(xiàn)象,因為其目的是為了使系統(tǒng)能夠有效地處理各種緊急事件,以保證系統(tǒng)正常運行。
- 異常:與中斷不同,異常是由于軟件錯誤而引起的。異常通常是在程序運行過程中發(fā)生的,可能是由于程序本身的錯誤,或者是由于程序運行過程中出現(xiàn)了一些未被預(yù)料到的狀況。
總的來說,中斷和異常在本質(zhì)上都是為了處理緊急事件或請求,但中斷主要是由于硬件設(shè)施或高優(yōu)先級的軟件請求,而異常則主要是由于程序本身運行過程中發(fā)生的錯誤。
18、?Linux 操作系統(tǒng)掛起、休眠、關(guān)機相關(guān)命令
?在 Linux 操作系統(tǒng)中,掛起、休眠和關(guān)機相關(guān)的命令主要如下:
- 掛起(suspend):掛起是一種省電模式,系統(tǒng)將機器的硬盤、顯示器等外部設(shè)備停止工作,而 CPU 和內(nèi)存仍然工作,等待用戶隨時喚醒。在掛起狀態(tài)下,所有運行的程序和進程都會被暫停,而系統(tǒng)的狀態(tài)和數(shù)據(jù)也會被保存在內(nèi)存中。要掛起系統(tǒng),可以使用以下命令:
sudo pm-suspend
。- 休眠(hibernate):休眠是一種更加省電的模式,它將內(nèi)存中的數(shù)據(jù)保存于硬盤中,使 CPU 也停止工作。在休眠狀態(tài)下,系統(tǒng)的狀態(tài)和數(shù)據(jù)會被完整保存,并且可以隨時恢復(fù)到休眠前的狀態(tài)。要休眠系統(tǒng),可以使用以下命令:
sudo pm-hibernate
。- 關(guān)機(shutdown):關(guān)機是將計算機系統(tǒng)關(guān)閉,停止所有進程和活動。關(guān)機通常會關(guān)閉所有外部設(shè)備,包括電源和磁盤。要關(guān)機可以使用以下命令:
sudo shutdown -h now
。需要注意的是,這些命令需要在具有 root 權(quán)限的環(huán)境下執(zhí)行。另外,不同的 Linux 發(fā)行版可能會有一些命令上的差異,具體操作還需參考對應(yīng)的發(fā)行版說明文檔。
19、編譯優(yōu)化選項-o
在 Linux 系統(tǒng)中,GCC 編譯器提供了多種編譯優(yōu)化選項,其中?
-o
?是一個用于指定輸出文件名的選項。以下是關(guān)于編譯優(yōu)化選項?-o
?的詳細說明:
-o
:該選項用于指定輸出文件的名稱。在編譯過程中,GCC 編譯器會將生成的目標文件保存為一個文件,該文件的名稱可以是任意的,通過?-o
?選項可以指定輸出文件的名稱。例如,gcc -o myprogram mysource.c
?表示將?mysource.c
?文件編譯為名為?myprogram
?的可執(zhí)行文件。-O
:這個選項用于啟用編譯優(yōu)化。通過該選項,GCC 編譯器會在生成目標代碼時進行一些優(yōu)化操作,以提高代碼的運行效率。優(yōu)化的程度可以通過后續(xù)的數(shù)字參數(shù)來指定,例如?-O1
、-O2
、-O3
?等。以下是一些常用的編譯優(yōu)化選項:
-O0
:禁用所有優(yōu)化選項,以最小的編譯時間生成目標代碼。-O1
:啟用一些基本的優(yōu)化選項,主要優(yōu)化代碼大小和運行速度,但不會對編譯時間產(chǎn)生太大的影響。-O2
:啟用更多的優(yōu)化選項,除了基本的優(yōu)化外,還會采用更多的優(yōu)化算法以提高代碼的運行效率。-O3
:啟用更多的優(yōu)化選項,除了基本的優(yōu)化外,還會采用更多的優(yōu)化算法以提高代碼的運行效率,并可能增加編譯時間。-Os
:該選項用于優(yōu)化代碼尺寸,會啟用一些能夠減小目標代碼大小的優(yōu)化選項,但不會對運行效率產(chǎn)生太大影響。需要注意的是,不同的編譯優(yōu)化選項可能會對編譯時間和生成代碼的大小和運行效率產(chǎn)生不同的影響。因此,在實際使用時需要根據(jù)具體需求和系統(tǒng)資源進行選擇。另外,具體的編譯優(yōu)化選項可能會因 GCC 版本的不同而有所差異,需要參考相應(yīng)的文檔進行選擇和使用。
20、?在有數(shù)據(jù) cache 情況下,DMA 數(shù)據(jù)鏈路為:外設(shè)-DMA-DDR-cache-CPU,CPU 需要對 cache 做什么操作,才可以得到數(shù)據(jù)
在有數(shù)據(jù)cache的情況下,DMA數(shù)據(jù)鏈路為:外設(shè)-DMA-DDR-cache-CPU。為了使CPU能夠得到數(shù)據(jù),需要進行以下操作:
- 緩存同步(Cache Coherence):由于數(shù)據(jù)可能已經(jīng)被緩存在cache中,因此需要確保cache和DDR內(nèi)存中的數(shù)據(jù)保持一致。這可以通過使用緩存同步協(xié)議來實現(xiàn),例如MESI(Modified, Exclusive, Shared, Invalid)或MOESI(Modified, Owner, Exclusive, Shared, Invalid)協(xié)議。緩存同步的目的是確保CPU在任何時候都能夠正確地訪問到最新的數(shù)據(jù)。
- 數(shù)據(jù)更新(Data Update):如果數(shù)據(jù)已經(jīng)在DDR內(nèi)存中更新,但cache中仍保持著舊的數(shù)據(jù),那么CPU需要確保能夠獲取到最新的數(shù)據(jù)。這可以通過在緩存同步過程中使用寫回(Writeback)策略來實現(xiàn),即將cache中過時的數(shù)據(jù)寫回DDR內(nèi)存,從而保證數(shù)據(jù)的正確性。
- 數(shù)據(jù)訪問(Data Access):當CPU需要訪問數(shù)據(jù)時,它會首先檢查cache中是否存在所需的數(shù)據(jù)。如果cache中存在,則可以直接從cache中獲取數(shù)據(jù),而不需要訪問DDR內(nèi)存。如果cache中不存在所需的數(shù)據(jù),則需要進行內(nèi)存訪問,從DDR內(nèi)存中讀取數(shù)據(jù)。
總之,在有數(shù)據(jù)cache的情況下,CPU需要對cache進行緩存同步、數(shù)據(jù)更新和數(shù)據(jù)訪問操作,以確保能夠在正確的時機獲取到數(shù)據(jù)。這些操作通常由硬件自動處理,而不需要用戶的顯式干預(yù)。
21、Linux中改變文件屬性的命令: chmod
在Linux中,改變文件屬性的命令是
chmod
。chmod
命令用于修改文件的訪問權(quán)限,控制用戶或用戶組對文件的訪問權(quán)限。
chmod
命令的用法如下:chmod [選項] [模式] 文件名作者建議當運行某個文件時出現(xiàn)權(quán)限不夠的情況,直接使用chmod 777 [文件名]
22、Linux中查找文件中匹配字符串的命令: grep?
?在 Linux 中,查找文件中匹配字符串的命令是?
grep
。grep
?命令用于在文件中搜索指定的文本模式,并輸出匹配的行。
grep
?命令的用法如下:grep [選項] [匹配模式] 文件名其中,選項可以是以下之一:
-c
:只輸出匹配行的計數(shù)。-i
:忽略大小寫,即匹配模式中的字符不區(qū)分大小寫。-n
:在匹配的行前面輸出行號。-r
?或?-R
:遞歸地在目錄下查找匹配的行。-v
:輸出不匹配的行。匹配模式是一個正則表達式,用于指定需要匹配的文本模式。例如,以下命令將在文件?
test.txt
?中查找所有包含字符串 "hello" 的行,并將它們輸出到終端:grep "hello" test.txt
第六章:單片機常見面試題
1、ROM與RAM
ROM 和 RAM 都是一種存儲技術(shù),但它們有不同的原理和特點。
ROM(Read-Only Memory)是一種只能讀出事先存儲數(shù)據(jù)的固態(tài)存儲器。ROM 的特點是在數(shù)據(jù)存儲后,數(shù)據(jù)不可以被修改,即只能讀取數(shù)據(jù),不能寫入。ROM 在斷電后仍然可以保存數(shù)據(jù),因此常用于存儲固定的系統(tǒng)信息或程序,例如操作系統(tǒng)或預(yù)設(shè)的應(yīng)用程序等。
RAM(Random Access Memory)則是一種可以隨機讀寫數(shù)據(jù)的存儲器。RAM 的特點是數(shù)據(jù)可以被隨機讀取和寫入,但只有在電源存在的情況下可以保持數(shù)據(jù)的完整性。RAM 主要用于存儲運行時使用的數(shù)據(jù)和緩存,例如操作系統(tǒng)的臨時數(shù)據(jù)或應(yīng)用程序的緩存數(shù)據(jù)等。
此外,ROM 和 RAM 在計算機系統(tǒng)中也有不同的應(yīng)用場景。ROM 常用于存儲固定的系統(tǒng)信息或程序,例如操作系統(tǒng)或預(yù)設(shè)的應(yīng)用程序等。而 RAM 則主要用于存儲運行時使用的數(shù)據(jù)和緩存,例如操作系統(tǒng)運行時的臨時數(shù)據(jù)或應(yīng)用程序的緩存數(shù)據(jù)等。
總之,ROM 和 RAM 有不同的特點和應(yīng)用場景,根據(jù)需要選擇適合的存儲方式。
2、GPIO口的 8 種工作方式
在GPIO口的工作方式中,有8種不同的模式:
- 輸入浮空(GPIO_Mode_In_FLOATING):該模式下,GPIO口不連接任何功能,處于浮空狀態(tài),可以用于讀取外部的開關(guān)狀態(tài)或傳感器信號。
- 輸入上拉(GPIO_Mode_IPU):該模式下,GPIO口通過上拉電阻連接到正電源,可以用于讀取外部的開關(guān)狀態(tài)或傳感器信號。
- 輸入下拉(GPIO_Mode_IPD):該模式下,GPIO口通過下拉電阻連接到地電源,可以用于讀取外部的開關(guān)狀態(tài)或傳感器信號。
- 模擬輸入(GPIO_Mode_AIN):該模式下,GPIO口可以作為一個模擬輸入口使用,通常用于讀取模擬信號,例如溫度、濕度等傳感器信號。
- 開漏輸出(GPIO_Mode_Out_OD):該模式下,GPIO口可以通過控制輸出高低電平,實現(xiàn)線與邏輯,并且可以實現(xiàn)電平的轉(zhuǎn)換。
- 開漏復(fù)用功能(GPIO_Mode_AF_OD):該模式下,GPIO口可以通過控制輸出高低電平,實現(xiàn)線與邏輯和電平轉(zhuǎn)換的同時,還可以作為其他外設(shè)的擴展功能使用。
- 推挽式輸出(GPIO_Mode_Out_PP):該模式下,GPIO口可以通過控制輸出高低電平,實現(xiàn)線與邏輯和電平轉(zhuǎn)換的同時,還可以作為其他外設(shè)的擴展功能使用。
- 推挽式復(fù)用功能(GPIO_Mode_AF_PP):該模式下,GPIO口可以通過控制輸出高低電平,實現(xiàn)線與邏輯和電平轉(zhuǎn)換的同時,還可以作為其他外設(shè)的擴展功能使用。
這些工作方式可以根據(jù)實際應(yīng)用需求進行選擇和配置。
3、請說明總線接口USART、I2C、USB的異同點(串/并、速度、全/半雙工、總線拓撲等)
總線接口USART、I2C和USB在串/并、速度、全/半雙工和總線拓撲等方面存在一些異同點,以下是具體的比較:
- 串/并:USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是一種同步串行通信接口,它支持串行和并行數(shù)據(jù)傳輸。I2C(Inter-Integrated Circuit)是一種串行通信接口,只支持串行傳輸。而USB(Universal Serial Bus)是一種串行總線,也支持串行數(shù)據(jù)傳輸。
- 速度:USART和I2C的速度通常較低,它們適合于低速應(yīng)用。而USB的速度相對較高,支持高速數(shù)據(jù)傳輸。
- 全/半雙工:USART是全雙工和I2C是半雙工,而USB只支持全雙工通信。
- 總線拓撲:USART和I2C都是點對點通信協(xié)議,可以支持多個設(shè)備之間的通信,但需要額外的控制器來管理通信。而USB是一種樹形總線結(jié)構(gòu),設(shè)備通過Hub連接,可以支持多個設(shè)備的連接和通信。
綜上所述,USART、I2C和USB在串/并、速度、全/半雙工和總線拓撲等方面都存在差異,根據(jù)實際應(yīng)用場景的需求來選擇適合的總線接口。
推薦博客地址:http://t.csdn.cn/2IZ2B
4、單片機的SP指針始終指向:棧頂
單片機的堆棧指針(SP)始終是指向棧頂?shù)摹?/p>
在單片機中,堆棧是一種內(nèi)存區(qū)域,用于存儲臨時數(shù)據(jù)和地址。堆棧指針(SP)是一個指向棧頂?shù)募拇嫫?,它指向當前棧頂元素的位置。當新的元素被壓入棧中時,堆棧指針會向下移動,指向新的棧頂位置;當元素被彈出棧時,堆棧指針會向上移動,指向下一個棧頂元素的位置。
由于堆棧是一種先進后出(LIFO)的數(shù)據(jù)結(jié)構(gòu),所以堆棧指針始終指向棧頂,即最后一個壓入棧的元素。這樣在訪問棧頂元素時,只需要通過堆棧指針就可以快速定位到棧頂元素,而不必遍歷整個棧。
在單片機中,堆棧通常用于存儲程序的臨時變量、函數(shù)參數(shù)和返回地址等,它的使用可以大大簡化程序的編寫和執(zhí)行效率。
5、FIQ中斷向量入口地址
FIQ(Fast Interrupt Queue)是 ARM 架構(gòu)中的一種中斷機制,用于處理高優(yōu)先級的中斷。FIQ 的中斷向量入口地址是預(yù)先定義好的,根據(jù)ARM架構(gòu)的不同版本,F(xiàn)IQ 的中斷向量入口地址可能有所不同。
在 ARMv7 和 ARMv8 架構(gòu)中,F(xiàn)IQ 的中斷向量入口地址為0x0000001C。
在 ARMv9 和A RMv10 架構(gòu)中,F(xiàn)IQ 的中斷向量入口地址為0x00000028。
需要注意的是,這些中斷向量入口地址是在內(nèi)核空間中定義的,用戶空間中無法直接訪問。在編寫使用 FIQ 的中斷處理程序時,需要按照對應(yīng)架構(gòu)的規(guī)范來進行編寫。
6、全雙工總線類型
全雙工總線是指數(shù)據(jù)可以在兩個方向上傳遞,即可以同時進行發(fā)送和接收操作。以下是一些常見的全雙工總線類型:
- SPI總線(Serial Peripheral Interface):是一種常用的全雙工總線,它采用串行通信協(xié)議,可以在主設(shè)備和從設(shè)備之間進行雙向數(shù)據(jù)傳輸。SPI總線通常使用4條線,包括主設(shè)備到從設(shè)備的數(shù)據(jù)傳輸線(MOSI)和從設(shè)備到主設(shè)備的數(shù)據(jù)傳輸線(MISO)。
- I2C總線(Inter-Integrated Circuit):是一種低速半雙工總線,它采用串行通信協(xié)議,可以在主設(shè)備和從設(shè)備之間進行雙向數(shù)據(jù)傳輸。I2C總線通常使用兩條線,一條是數(shù)據(jù)線SDA,另一條是時鐘線SCL。
- USB總線(Universal Serial Bus):是一種高速全雙工總線,它采用串行通信協(xié)議,可以在主機和設(shè)備之間進行雙向數(shù)據(jù)傳輸。USB總線通常使用4條線,包括電源線、數(shù)據(jù)線、地線和ID線。
- 以太網(wǎng)(Ethernet):是一種高速全雙工總線,它采用并行通信協(xié)議,可以在網(wǎng)絡(luò)設(shè)備之間進行雙向數(shù)據(jù)傳輸。以太網(wǎng)通常使用多條線,包括傳輸數(shù)據(jù)的雙絞線和傳輸控制的LED線和CRS線等。
這些全雙工總線類型都有其獨特的特點和應(yīng)用場景,根據(jù)實際需求選擇適合的總線類型。
7、l2C協(xié)議時序圖和SPI的時序圖
I2C和SPI都是嵌入式非常基礎(chǔ)且必備的通信協(xié)議,內(nèi)容篇幅偏長,建議大家好好掌握!
8、CAN協(xié)議
CAN(Controller Area Network)協(xié)議是一種用于設(shè)備間通信的高效、可靠、安全的通信協(xié)議。以下是一些關(guān)于CAN協(xié)議的關(guān)鍵信息:
- CAN總線是一種廣播式通信協(xié)議,所有的節(jié)點都可以接收和發(fā)送數(shù)據(jù)。
- CAN具有多個不同等級的節(jié)點,這些節(jié)點可以通過不同的ID進行識別和區(qū)分。
- CAN總線采用差分信號傳輸,這種傳輸方式可以抵抗電磁干擾和噪聲,保證數(shù)據(jù)的穩(wěn)定傳輸。
- CAN協(xié)議具有強大的錯誤檢測和糾正能力,包括位錯誤檢測、填充錯誤檢測、CRC校驗等,這些功能可以確保數(shù)據(jù)的準確性和可靠性。
- CAN總線在汽車、工業(yè)控制、醫(yī)療設(shè)備等領(lǐng)域廣泛應(yīng)用,用于各種數(shù)據(jù)和控制信號的傳輸。
- CAN總線具有高速傳輸特性,通信速率可達1Mbps,適用于需要高速數(shù)據(jù)傳輸?shù)膽?yīng)用。
- CAN總線具有多主機通信的特點,多個節(jié)點可以同時發(fā)送和接收數(shù)據(jù),實現(xiàn)分布式控制。
總之,CAN協(xié)議是一種適用于各種設(shè)備間通信的可靠、安全的通信協(xié)議,具有廣泛的應(yīng)用場景和優(yōu)勢。
第七章:其他雜項面試題
1、講一講馮諾依曼和哈佛體系的區(qū)別
馮諾依曼體系和哈佛體系是兩種不同的計算機體系結(jié)構(gòu),它們在存儲器組織、指令和數(shù)據(jù)訪問方式等方面存在一些關(guān)鍵的區(qū)別。
- 存儲器組織:馮諾依曼體系將程序指令和數(shù)據(jù)存儲在同一個存儲器中,程序指令和數(shù)據(jù)共享同一組存儲器。而哈佛體系則將程序指令和數(shù)據(jù)分別存儲在兩個獨立的存儲器中,即程序存儲器和數(shù)據(jù)存儲器。
- 總線結(jié)構(gòu):馮諾依曼體系使用單一的指令總線,所有設(shè)備共享同一組總線。而哈佛體系使用兩個獨立的總線,一條用于程序指令傳輸,另一條用于數(shù)據(jù)傳輸。
- 執(zhí)行效率:由于馮諾依曼體系使用單一的指令總線,所有設(shè)備共享同一組總線,因此指令和數(shù)據(jù)的傳輸可能存在競爭和沖突,導(dǎo)致執(zhí)行效率較低。而哈佛體系通過獨立的總線實現(xiàn)指令和數(shù)據(jù)的傳輸,避免了沖突和競爭,提高了執(zhí)行效率。
- 復(fù)雜度:由于哈佛體系需要設(shè)計更多的硬件電路,因此相對于馮諾依曼體系而言,哈佛體系的硬件復(fù)雜度更高,成本也更高。
總體而言,馮諾依曼體系和哈佛體系各有優(yōu)缺點。馮諾依曼體系設(shè)計簡單,易于實現(xiàn),適用于對執(zhí)行效率和復(fù)雜度要求不高的應(yīng)用。而哈佛體系則適用于對執(zhí)行效率和復(fù)雜度要求較高的應(yīng)用,如嵌入式系統(tǒng)和實時系統(tǒng)。
2、講一講二叉樹和紅黑樹
二叉樹和紅黑樹是兩種常見的自平衡二叉查找樹,它們在計算機科學(xué)中有著重要的應(yīng)用。以下是它們的一些關(guān)鍵信息:
二叉樹:
* 定義:二叉樹是一種數(shù)據(jù)結(jié)構(gòu),它包含一個根節(jié)點和兩個子樹,每個子樹也是一棵二叉樹。
* 特點:二叉樹的每個節(jié)點最多有兩個子節(jié)點,左子節(jié)點的值小于父節(jié)點的值,右子節(jié)點的值大于父節(jié)點的值。
* 應(yīng)用:二叉樹常用于排序、查找、插入和刪除等操作,尤其是在數(shù)據(jù)庫和數(shù)據(jù)結(jié)構(gòu)的教學(xué)中經(jīng)常被使用。
紅黑樹:
* 定義:紅黑樹是一種自平衡的二叉查找樹,它通過顏色標記和旋轉(zhuǎn)操作來保持樹的平衡。
* 特點:紅黑樹的節(jié)點被涂成紅色或黑色,根據(jù)節(jié)點顏色和鏈接關(guān)系,通過旋轉(zhuǎn)操作保持樹的平衡,提高查找、插入和刪除等操作的效率。
* 應(yīng)用:紅黑樹常用于在需要高效地存儲和檢索數(shù)據(jù)的場景,例如在操作系統(tǒng)中的文件系統(tǒng)和內(nèi)存管理等。總結(jié)來說,二叉樹和紅黑樹都是基于二叉查找樹的算法,用于高效地管理數(shù)據(jù)。二叉樹結(jié)構(gòu)簡單,易于理解;紅黑樹則更具有平衡性,能夠在平均情況下更高效地處理操作。具體選擇哪種數(shù)據(jù)結(jié)構(gòu)取決于具體的應(yīng)用場景和需求。
3、http默認端口號:80
HTTP(超文本傳輸協(xié)議)的默認端口號是80。在 TCP/IP 協(xié)議中,HTTP 請求通過端口號 80 來傳輸數(shù)據(jù)。這是由于在傳統(tǒng)的互聯(lián)網(wǎng)應(yīng)用中,使用 80 號端口號的Web服務(wù)器是最常見的,因此它被約定俗成為 HTTP 默認端口號。
在 HTTP 請求中,客戶端通過 HTTP 請求頭(Request Header)中的 "Port" 字段來指定服務(wù)器端口號。如果未指定端口號,則默認使用 80 端口。同樣,在 HTTP 響應(yīng)中,服務(wù)器通過 HTTP 響應(yīng)頭(Response Header)中的 "Location" 字段來指定客戶端的端口號。
雖然 80 是 HTTP 的默認端口號,但在特定情況下,也可以使用其他端口號。例如,當服務(wù)器上存在多個 Web 站點時,可以使用不同的端口號來區(qū)分不同的站點。但這種情況下,客戶端仍然會將請求發(fā)送到服務(wù)器的 80 端口,服務(wù)器根據(jù)請求中的信息將請求轉(zhuǎn)發(fā)到相應(yīng)的端口。
需要注意的是,雖然 80 是 HTTP 的默認端口號,但這并不是 HTTP 協(xié)議所強制規(guī)定的。實際應(yīng)用中,也可以根據(jù)具體需求和場景選擇使用其他端口號或進行端口映射等操作。
4、面向?qū)ο缶幊痰娜筇匦?,以及重載的意思。
面向?qū)ο缶幊痰娜筇匦允欠庋b、繼承和多態(tài)。
- 封裝(Encapsulation):將對象的屬性和方法進行封裝,通過訪問控制符(public、protected、private)來控制訪問權(quán)限,實現(xiàn)數(shù)據(jù)和行為的保護。封裝可以使對象內(nèi)部的數(shù)據(jù)和實現(xiàn)細節(jié)被隱藏起來,只對外暴露有限的操作接口,從而提高安全性和代碼的可維護性。
- 繼承(Inheritance):允許一個類(稱為子類或派生類)繼承另一個類(稱為父類或基類)的屬性和方法,從而使得子類可以獲得父類的特性。繼承可以實現(xiàn)代碼的重用和擴展,提高代碼的復(fù)用性和可維護性。
- 多態(tài)(Polymorphism):指同一個方法在不同的情況下可以表現(xiàn)出不同的行為。多態(tài)性包括編譯時多態(tài)和運行時多態(tài)。編譯時多態(tài)是通過函數(shù)重載(Overloading)和運算符重載實現(xiàn)的,在編譯時確定具體的調(diào)用;運行時多態(tài)是通過動態(tài)綁定(Dynamic Binding)實現(xiàn)的,在運行時確定具體的調(diào)用。
重載(Overloading)是指在同一個作用域內(nèi),允許存在多個同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。重載可以提高代碼的復(fù)用性和可讀性,使得函數(shù)名能夠更清晰地表達其功能。在編譯時,編譯器會根據(jù)傳入的參數(shù)類型和數(shù)量來確定具體調(diào)用的函數(shù)。
5、Linux中mysql數(shù)據(jù)庫默認的端口是:3306
?Linux系統(tǒng)中,MySQL數(shù)據(jù)庫的默認端口號是3306。在MySQL中,端口號是用于標識和連接數(shù)據(jù)庫服務(wù)器的一個重要參數(shù)。在默認情況下,MySQL使用端口號3306來接受客戶端的連接請求。
在安裝和配置MySQL時,如果沒有特別指定端口號,通常會使用默認的3306端口。在Linux系統(tǒng)中,可以使用以下命令來查看MySQL的默認端口號:
mysql -e "show variables like 'port'"
6、C語言編程中,單片機平臺,一般有.c和.h文件,如果一個人在.h文件中定義了一個變量,會有什么后果。
在C語言編程中,如果在.h文件中定義了一個變量,可能會導(dǎo)致以下后果:
- 重復(fù)定義:如果同一個源文件中包含了多個.h文件,且其中有一個文件中定義了與其它文件中相同的變量,就會導(dǎo)致重復(fù)定義的問題。在編譯時,編譯器會報錯并停止編譯。
- 變量作用域問題:在.h文件中定義的變量通常是全局變量,可以在文件中的所有函數(shù)中使用。但是,如果在.h文件中定義了局部變量,且在不同的源文件中包含了該.h文件,可能會導(dǎo)致該變量的作用域超出預(yù)期,從而導(dǎo)致程序行為的不確定性。
- 變量重定義:如果在不同的源文件中包含了相同的.h文件,且其中有一個文件中定義了與其它文件中相同的變量,就會導(dǎo)致變量的重定義問題。在編譯時,編譯器會報錯并停止編譯。
為了避免以上問題,通常建議將變量的定義放在.c文件中,并在需要使用該變量的文件中包含對應(yīng)的.h文件。這樣可以確保每個文件中的變量不會發(fā)生重復(fù)定義或作用域問題。同時,也可以使用頭文件保護(#ifndef等)來避免重復(fù)包含同一個.h文件,從而避免重復(fù)定義的問題。
7、if 語句中如果是或運算(|),第一個條件滿足時,第二個條件還會判斷嗎
在if語句中使用或運算(|)時,如果第一個條件滿足,第二個條件不會被判斷。只有當?shù)谝粋€條件不滿足時,才會去判斷第二個條件。文章來源:http://www.zghlxwxcb.cn/news/detail-715293.html
作者有話
該博客為長期更新版本,作者如果平時遇到比較有特點且高頻的面試問題都會及時更新到該篇博客上的。因為,作者個人能力有限,部分答案也不敢保證百分百的正確性。所以,如果有大佬發(fā)現(xiàn)錯誤可以評論區(qū)留言指正!嵌入式工程師是個需要長期積累學(xué)習(xí)的職業(yè),看似八股文的面試問題背后常常也透露出些許工程難點的光輝,希望大家都能學(xué)有進步,萬事順義,Respect?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-715293.html
到了這里,關(guān)于嵌入式工程師常見面試題(持續(xù)更新版本)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!