大家好,春招說來就來啦!最近我可太有感觸了,好多小伙伴都在瘋狂準(zhǔn)備面試,一心想拿下大廠 offer。前陣子,有個(gè)讀者找到我,說想試試模擬面試,我就想著幫他一把。結(jié)果好家伙,這面試過程可太讓我驚喜了!不管我拋出啥問題,他都能穩(wěn)穩(wěn)接住。我把模擬面試過程中的一些問題整理了出來,希望對(duì)大家有幫助。
模擬面試問題匯總
基礎(chǔ)問題
C/C++
關(guān)鍵字static的作用是什么?
在函數(shù)體,只會(huì)被初始化一次,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。
在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個(gè)本地的全局變量(只能被當(dāng)前文件使用)。
在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用(只能被當(dāng)前文件使用)。
C語(yǔ)言中 struct與 union的區(qū)別是什么?
-
- 結(jié)構(gòu)體與聯(lián)合體雖然都是由多個(gè)不同的數(shù)據(jù)類型成員組成的,但不同之處在于聯(lián)合體中所有成員共用一塊地址空間,即聯(lián)合體只存放了一個(gè)被選中的成員,而結(jié)構(gòu)體中所有成員占用空間是累加的,其所有成員都存在,不同成員會(huì)存放在不同的地址。在計(jì)算一個(gè)結(jié)構(gòu)型變量的總長(zhǎng)度時(shí),其內(nèi)存空間大小等于所有成員長(zhǎng)度之和(需要考慮字節(jié)對(duì)齊),而在聯(lián)合體中,所有成員不能同時(shí)占用內(nèi)存空間,它們不能同時(shí)存在,所以一個(gè)聯(lián)合型變量的長(zhǎng)度等于其最長(zhǎng)的成員的長(zhǎng)度。
-
- 對(duì)于聯(lián)合體的不同成員賦值,將會(huì)對(duì)它的其他成員重寫,原來成員的值就不存在了,而對(duì)結(jié)構(gòu)體的不同成員賦值是互不影響的。
堆與棧有什么區(qū)別?
申請(qǐng)方式棧的空間由操作系統(tǒng)自動(dòng)分配/釋放,堆上的空間手動(dòng)分配/釋放。
申請(qǐng)大小的限制??臻g有限。在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié) 構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是 一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小堆是很大的自由存儲(chǔ)區(qū)。堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。
申請(qǐng)效率棧由系統(tǒng)自動(dòng)分配,速度較快。但程序員是無法控制的。堆是由new分配的內(nèi)存,一般速度比較慢,而且容易產(chǎn)生內(nèi)存碎片,不過用起來最方便.
什么是外部碎片和內(nèi)部碎片??jī)?nèi)存碎片如何解決
函數(shù)指針和指針函數(shù)有什么區(qū)別?
函數(shù)指針如果在程序中定義了一個(gè)函數(shù),那么在編譯時(shí)系統(tǒng)就會(huì)為這個(gè)函數(shù)代碼分配一段存儲(chǔ)空間,這段存儲(chǔ)空間的首地址稱為這個(gè)函數(shù)的地址。而且函數(shù)名表示的就是這個(gè)地址。既然是地址我們就可以定義一個(gè)指針變量來存放,這個(gè)指針變量就叫作函數(shù)指針變量,簡(jiǎn)稱函數(shù)指針。
指針函數(shù)首先它是一個(gè)函數(shù),只不過這個(gè)函數(shù)的返回值是一個(gè)地址值。函數(shù)返回值必須用同類型的指針變量來接受,也就是說,指針函數(shù)一定有“函數(shù)返回值”,而且,在主調(diào)函數(shù)中,函數(shù)返回值必須賦給同類型的指針變量。
數(shù)組下標(biāo)可以為負(fù)數(shù)嗎?
可以,因?yàn)橄聵?biāo)只是給出了一個(gè)與當(dāng)前地址的偏移量而已,只要根據(jù)這個(gè)偏移量能定位得到目標(biāo)地址即可。下面給出一個(gè)下標(biāo)為負(fù)數(shù)的示例:
操作系統(tǒng)
請(qǐng)簡(jiǎn)述操作系統(tǒng)的主要功能有哪些
答案:操作系統(tǒng)主要有進(jìn)程管理(負(fù)責(zé)進(jìn)程的創(chuàng)建、調(diào)度、終止等,確保多個(gè)進(jìn)程能高效有序地共享 CPU 資源)
存儲(chǔ)管理(對(duì)內(nèi)存進(jìn)行分配、回收與保護(hù),讓不同進(jìn)程合理使用內(nèi)存空間)
設(shè)備管理(統(tǒng)一管理各類外部設(shè)備,如打印機(jī)、磁盤等,實(shí)現(xiàn)設(shè)備的驅(qū)動(dòng)加載、分配與回收,為用戶程序提供統(tǒng)一的設(shè)備操作接口)
文件管理(負(fù)責(zé)文件的存儲(chǔ)、檢索、共享與保護(hù),提供文件系統(tǒng)給用戶方便地操作文件)和
作業(yè)管理(控制用戶作業(yè)的提交、執(zhí)行與結(jié)束流程,協(xié)調(diào)系統(tǒng)資源來完成用戶任務(wù))解釋:了解操作系統(tǒng)全貌,看面試者是否清楚其核心職能,這是深入學(xué)習(xí)操作系統(tǒng)各模塊的基礎(chǔ)。
操作系統(tǒng)中的進(jìn)程和線程的區(qū)別
進(jìn)程是資源分配的基本單位,擁有獨(dú)立的地址空間,包含代碼段、數(shù)據(jù)段、堆棧段等,不同進(jìn)程間數(shù)據(jù)相對(duì)隔離;
線程是 CPU 調(diào)度的基本單位,隸屬于進(jìn)程,一個(gè)進(jìn)程內(nèi)可以有多個(gè)線程,它們共享進(jìn)程的地址空間和資源,如打開的文件、全局變量等,但擁有各自獨(dú)立的??臻g用于保存局部變量和函數(shù)調(diào)用信息。
線程間切換開銷相對(duì)進(jìn)程切換小,因?yàn)闊o需切換地址空間等大量資源信息。解釋:這是操作系統(tǒng)并發(fā)編程的關(guān)鍵概念,能反映面試者對(duì)并發(fā)執(zhí)行單元的理解深度。
FreeRTOS 相關(guān)部分
FreeRTOS 任務(wù)主要有哪幾種狀態(tài)
FreeRTOS 任務(wù)主要有就緒(Ready)、運(yùn)行(Running)、阻塞(Blocked)、掛起(Suspended)狀態(tài)。
就緒態(tài)任務(wù)等待 CPU 資源,一旦獲得就進(jìn)入運(yùn)行態(tài);
運(yùn)行態(tài)任務(wù)時(shí)間片用完或被更高優(yōu)先級(jí)任務(wù)搶占,會(huì)回到就緒態(tài);
運(yùn)行態(tài)任務(wù)如果等待某個(gè)事件(如信號(hào)量未獲取到、隊(duì)列無數(shù)據(jù)等),就會(huì)進(jìn)入阻塞態(tài),等事件滿足條件后回到就緒態(tài);
掛起態(tài)任務(wù)是被人為暫停,需要通過 API 調(diào)用才能恢復(fù)到就緒態(tài),與阻塞態(tài)不同在于掛起態(tài)不依賴于某個(gè)事件的發(fā)生,純粹是外部控制。
解釋:深入考查對(duì) FreeRTOS 任務(wù)調(diào)度核心機(jī)制的掌握,任務(wù)狀態(tài)流轉(zhuǎn)是理解任務(wù)運(yùn)行邏輯的關(guān)鍵。
FreeRTOS 中如何使用隊(duì)列進(jìn)行任務(wù)間通信
首先要?jiǎng)?chuàng)建隊(duì)列,使用 xQueueCreate() 函數(shù),設(shè)置好隊(duì)列長(zhǎng)度和單個(gè)消息大小。比如在一個(gè)數(shù)據(jù)采集任務(wù)和數(shù)據(jù)處理任務(wù)間通信,采集任務(wù)采集到數(shù)據(jù)后,
使用 xQueueSend() 函數(shù)將數(shù)據(jù)指針(或數(shù)據(jù)本身,取決于數(shù)據(jù)大小和設(shè)計(jì))放入隊(duì)列
數(shù)據(jù)處理任務(wù)則在循環(huán)中使用 xQueueReceive() 函數(shù)嘗試從隊(duì)列獲取數(shù)據(jù),當(dāng)隊(duì)列中有數(shù)據(jù)時(shí),處理任務(wù)就能取到并進(jìn)行后續(xù)處理。
FreeRTOS 中信號(hào)量和互斥量的區(qū)別
信號(hào)量主要用于任務(wù)間同步或資源計(jì)數(shù),比如協(xié)調(diào)多個(gè)任務(wù)對(duì)某個(gè)共享資源的訪問順序,初始值可以設(shè)定為大于 0,表示資源初始可用數(shù)量,任務(wù)獲取信號(hào)量后信號(hào)量值減 1,釋放加 1;
互斥量本質(zhì)也是一種特殊的信號(hào)量,初始值為 1,用于互斥訪問共享資源,同一時(shí)間只允許一個(gè)任務(wù)獲取互斥量進(jìn)入臨界區(qū)操作共享資源,避免數(shù)據(jù)沖突,獲取不到互斥量的任務(wù)會(huì)進(jìn)入阻塞態(tài)等待,直到持有互斥量的任務(wù)釋放。
解釋:這兩者容易混淆,區(qū)分它們能看出面試者對(duì) FreeRTOS 同步與互斥機(jī)制的精準(zhǔn)理解。
中斷與內(nèi)存管理部分
FreeRTOS 中,基于中斷的任務(wù)切換機(jī)制是怎樣的?
當(dāng)中斷發(fā)生時(shí),硬件首先保存當(dāng)前任務(wù)的上下文(寄存器值等),然后進(jìn)入中斷服務(wù)程序(ISR),
在 ISR 中如果滿足任務(wù)切換條件(如更高優(yōu)先級(jí)任務(wù)就緒且中斷允許任務(wù)切換),會(huì)調(diào)用 FreeRTOS 的中斷任務(wù)切換函數(shù),
將當(dāng)前任務(wù)狀態(tài)更新,選擇最高優(yōu)先級(jí)就緒任務(wù),恢復(fù)新任務(wù)的上下文,實(shí)現(xiàn)從舊任務(wù)到新任務(wù)的切換,最后從中斷返回后新任務(wù)開始運(yùn)行。
在一個(gè)具有多個(gè)中斷源的FreeRTOS系統(tǒng)中,不同中斷源需要與不同任務(wù)進(jìn)行通信。請(qǐng)?jiān)O(shè)計(jì)一種方案,實(shí)現(xiàn)各中斷源與對(duì)應(yīng)任務(wù)之間高效、可靠的通信,并說明如何避免通信過程中的數(shù)據(jù)丟失和沖突。假設(shè)系統(tǒng)資源有限,如何在滿足通信需求的同時(shí)優(yōu)化系統(tǒng)資源的使用?
答案:可以使用消息隊(duì)列實(shí)現(xiàn)中斷源與任務(wù)的通信。為每個(gè)中斷源創(chuàng)建獨(dú)立的消息隊(duì)列,中斷發(fā)生時(shí),將相關(guān)數(shù)據(jù)發(fā)送到對(duì)應(yīng)的隊(duì)列。任務(wù)從隊(duì)列中讀取數(shù)據(jù)進(jìn)行處理。
為避免數(shù)據(jù)丟失和沖突,發(fā)送數(shù)據(jù)時(shí)設(shè)置合適的超時(shí)時(shí)間,確保數(shù)據(jù)成功入隊(duì)。在中斷處理中,使用中斷安全的隊(duì)列操作函數(shù)。對(duì)于系統(tǒng)資源有限的情況,合理設(shè)置隊(duì)列大小,避免過大的內(nèi)存占用。同時(shí),可復(fù)用部分?jǐn)?shù)據(jù)結(jié)構(gòu),減少內(nèi)存開銷。例如,使用共享緩沖區(qū),通過標(biāo)志位區(qū)分不同中斷源的數(shù)據(jù)。
FreeRTOS 空閑內(nèi)存是用什么數(shù)據(jù)結(jié)構(gòu)管理的,簡(jiǎn)單講講是如何管理的。
鏈表實(shí)現(xiàn)內(nèi)存分配基于空閑內(nèi)存塊鏈表,初始化時(shí)將系統(tǒng)空閑內(nèi)存按一定大小劃分成多個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊包含控制信息(如大小、是否已分配標(biāo)志等),并通過鏈表指針連接起來,分配內(nèi)存時(shí)遍歷鏈表找合適大小的空閑塊,標(biāo)記為已分配并返回給申請(qǐng)者,回收時(shí)將內(nèi)存塊重新鏈入空閑鏈表并更新狀態(tài)。
FreeRTOS 的鏈表實(shí)現(xiàn)內(nèi)存分配中,如何處理內(nèi)存碎片化問題?有哪些優(yōu)化策略?
內(nèi)存碎片化是指隨著內(nèi)存的反復(fù)分配與回收,內(nèi)存空間被分割成許多小塊,即使總空閑內(nèi)存足夠,但難以滿足較大內(nèi)存需求的情況。FreeRTOS 處理碎片化的一種策略是采用內(nèi)存合并算法,在回收內(nèi)存塊時(shí),檢查相鄰的空閑內(nèi)存塊,若滿足合并條件(如相鄰塊空閑且屬于同一類型內(nèi)存區(qū)域),則將它們合并成一個(gè)更大的空閑塊,減少碎片數(shù)量;
優(yōu)化策略還包括定期進(jìn)行內(nèi)存整理,不過這通常會(huì)帶來一定的性能開銷,所以要權(quán)衡使用,例如在系統(tǒng)空閑時(shí)段執(zhí)行整理操作,或者根據(jù)內(nèi)存使用閾值觸發(fā)整理,另外合理設(shè)置初始內(nèi)存塊大小和分配策略,如采用大內(nèi)存塊優(yōu)先分配,對(duì)于頻繁分配小內(nèi)存塊的場(chǎng)景,單獨(dú)開辟小內(nèi)存區(qū)域進(jìn)行管理,避免小碎片過多影響大內(nèi)存需求的分配。
在 FreeRTOS 任務(wù)調(diào)度中,如果多個(gè)任務(wù)處于同一優(yōu)先級(jí),系統(tǒng)是如何處理的?
當(dāng)多個(gè)任務(wù)處于同一優(yōu)先級(jí)時(shí),F(xiàn)reeRTOS 采用時(shí)間片輪轉(zhuǎn)調(diào)度算法在這些任務(wù)間分配 CPU 時(shí)間。每個(gè)任務(wù)運(yùn)行一個(gè)預(yù)先設(shè)定好的時(shí)間片(由系統(tǒng)節(jié)拍周期和配置參數(shù)決定),時(shí)間片用完后,任務(wù)會(huì)被強(qiáng)制掛起,切換到同優(yōu)先級(jí)的下一個(gè)就緒任務(wù)運(yùn)行,如此循環(huán)往復(fù),保證同優(yōu)先級(jí)任務(wù)都能獲得公平的 CPU 執(zhí)行機(jī)會(huì)。
若任務(wù)在時(shí)間片內(nèi)主動(dòng)放棄 CPU(如進(jìn)入阻塞態(tài)等待資源),則立即切換到同優(yōu)先級(jí)的下一個(gè)就緒任務(wù)。
對(duì)于 FreeRTOS 中的隊(duì)列,當(dāng)隊(duì)列已滿,繼續(xù)調(diào)用 xQueueSend() 函數(shù)會(huì)發(fā)生什么情況?如何根據(jù)不同需求處理這種情況?
當(dāng)隊(duì)列已滿,繼續(xù)調(diào)用 xQueueSend() ,默認(rèn)情況下任務(wù)會(huì)進(jìn)入阻塞態(tài),等待隊(duì)列有空閑空間,直到超時(shí)(可設(shè)置超時(shí)時(shí)間)。
若不想讓任務(wù)阻塞,可以使用 xQueueSendToBackFromISR() 或 xQueueSendToFrontFromISR() 等從中斷安全版本的函數(shù)(用于中斷服務(wù)程序中),它們不會(huì)阻塞任務(wù),而是直接返回錯(cuò)誤碼,由調(diào)用者根據(jù)返回值決定后續(xù)操作,比如在中斷中簡(jiǎn)單記錄錯(cuò)誤信息,后續(xù)再處理;
或者在任務(wù)中結(jié)合錯(cuò)誤處理邏輯,決定是重試發(fā)送、調(diào)整數(shù)據(jù)處理策略還是采取其他補(bǔ)救措施。
USART 相關(guān)
USART(通用同步異步收發(fā)器)的工作模式,異步和同步模式有何區(qū)別?
答案:USART 異步模式下,數(shù)據(jù)傳輸不需要時(shí)鐘同步信號(hào),收發(fā)雙方依靠起始位、停止位和波特率來同步數(shù)據(jù),每個(gè)字符獨(dú)立傳輸,傳輸效率相對(duì)較低,但接線簡(jiǎn)單,常用于低速、遠(yuǎn)距離通信場(chǎng)景。同步模式則需要額外的時(shí)鐘線來同步數(shù)據(jù)傳輸,數(shù)據(jù)按位連續(xù)傳輸,傳輸速率高,適合高速、近距離且對(duì)時(shí)鐘同步要求嚴(yán)格的應(yīng)用,如與某些高速外設(shè)芯片通信。
IIC 相關(guān)
描述 IIC(集成電路總線)協(xié)議的通信流程,起始信號(hào)和停止信號(hào)是如何定義的?
答案:IIC 通信以起始信號(hào)開始,當(dāng)時(shí)鐘線SCL 為高電平時(shí),數(shù)據(jù)線 SDA 由高電平向低電平跳變表示起始信號(hào);停止信號(hào)則相反,在SCL 為高電平時(shí),SDA 由低電平向高電平跳變。通信時(shí),主機(jī)發(fā)送起始信號(hào)后,接著發(fā)送設(shè)備地址(包含讀寫位),從機(jī)響應(yīng)后,主機(jī)開始傳輸或接收數(shù)據(jù),數(shù)據(jù)傳輸以字節(jié)為單位,8 位數(shù)據(jù)后有一個(gè)應(yīng)答位,由從機(jī)反饋,整個(gè)過程靠 SCL 時(shí)鐘線同步。
IIC 總線上如何實(shí)現(xiàn)多設(shè)備連接?設(shè)備地址沖突怎么解決?
- 答案:IIC 允許通過不同的設(shè)備地址在同一總線上連接多個(gè)設(shè)備。設(shè)備地址通常由固定部分(廠商定義)和可編程部分(用戶設(shè)置)組成。若出現(xiàn)設(shè)備地址沖突,首先要排查硬件連接是否正確,確認(rèn)是否有重復(fù)地址設(shè)備誤接入;在軟件層面,若使用可編程地址的設(shè)備,修改沖突設(shè)備的地址,確保每個(gè)設(shè)備地址唯一,保證通信順暢。
SPI 相關(guān)
SPI(串行外設(shè)接口)有幾種工作模式,它們是如何區(qū)分的?
答案:SPI 有四種工作模式(0、1、2、3),主要依據(jù)時(shí)鐘極性(CPOL)和時(shí)鐘相位(CPHA)區(qū)分。CPOL 決定時(shí)鐘空閑時(shí)電平,0 為低電平,1 為高電平;CPHA 決定數(shù)據(jù)采樣時(shí)刻,0 表示在時(shí)鐘前沿采樣,1 表示在時(shí)鐘后沿采樣。如模式 0:CPOL = 0,CPHA = 0,時(shí)鐘空閑低電平,數(shù)據(jù)在上升沿采樣;模式 3:CPOL = 1,CPHA = 1,時(shí)鐘空閑高電平,數(shù)據(jù)在下降沿采樣。不同模式適配不同外設(shè)需求。
對(duì)比 SPI 與 IIC 協(xié)議,它們?cè)趥鬏斔俾?、硬件連接、應(yīng)用場(chǎng)景上有何不同?
答案:傳輸速率上,SPI 通常比 IIC 快,SPI 全雙工通信,時(shí)鐘頻率較高,能實(shí)現(xiàn)高速數(shù)據(jù)傳輸;IIC 半雙工,受應(yīng)答機(jī)制等限制,速率相對(duì)較低。硬件連接方面,SPI 至少需要 4 根線(MISO、MOSI、SCK、SS),不同設(shè)備可能還需額外控制線;IIC 只需 2 根線(SDA、SCL),連接簡(jiǎn)單。應(yīng)用場(chǎng)景,SPI 適合高速數(shù)據(jù)傳輸如顯示屏、Flash 存儲(chǔ)驅(qū)動(dòng);IIC 多用于連接低速、對(duì)功耗要求低且內(nèi)部有 IIC 接口的芯片,如傳感器、EEPROM 等。
裸機(jī)與基于 RTOS 的開發(fā)調(diào)試綜合
在裸機(jī)開發(fā)中,如何處理多個(gè)任務(wù)之間的資源共享問題?以 USART 數(shù)據(jù)發(fā)送為例,若有兩個(gè)任務(wù)都要向 USART 發(fā)送數(shù)據(jù),你會(huì)怎么做?
- 答案:裸機(jī)開發(fā)中,處理資源共享可采用關(guān)中斷、查詢標(biāo)志位等方法。以 USART 發(fā)送為例,可設(shè)一個(gè)全局標(biāo)志位,任務(wù)先查詢標(biāo)志位,若 USART 空閑(標(biāo)志位表示可發(fā)送),則置位標(biāo)志位,獨(dú)占 USART 發(fā)送數(shù)據(jù),發(fā)送完成后置零標(biāo)志位,期間若另一任務(wù)查詢,發(fā)現(xiàn)標(biāo)志位已置,需等待。這種方式簡(jiǎn)單直接,但在復(fù)雜系統(tǒng)中容易出現(xiàn)優(yōu)先級(jí)倒置等問題,相比 RTOS 缺乏靈活性。解釋:考查裸機(jī)環(huán)境下解決并發(fā)問題的基本思路,凸顯與 RTOS 環(huán)境下任務(wù)管理的差異。
在基于 RTOS(如 FreeRTOS)的開發(fā)中,使用消息隊(duì)列實(shí)現(xiàn)任務(wù)間通信有什么優(yōu)勢(shì)?如果要將 USART 接收的數(shù)據(jù)傳遞給另一個(gè)處理任務(wù),如何用消息隊(duì)列搭建通信鏈路?
- 答案:使用消息隊(duì)列優(yōu)勢(shì)在于解耦任務(wù)間關(guān)系,提高系統(tǒng)靈活性、可維護(hù)性,避免任務(wù)間強(qiáng)耦合造成的開發(fā)困難。比如將 USART 接收任務(wù)和處理任務(wù)解耦,接收任務(wù)只管接收數(shù)據(jù)放入隊(duì)列,處理任務(wù)從隊(duì)列取數(shù)據(jù)處理,兩個(gè)任務(wù)可獨(dú)立開發(fā)、調(diào)試。搭建通信鏈路時(shí),先創(chuàng)建消息隊(duì)列(設(shè)定隊(duì)列長(zhǎng)度、消息大?。?,USART 接收任務(wù)用 “xQueueSend ()” 函數(shù)將接收的數(shù)據(jù)放入隊(duì)列,處理任務(wù)用 “xQueueReceive ()” 函數(shù)從隊(duì)列獲取數(shù)據(jù)進(jìn)行后續(xù)處理。解釋:深入考查對(duì) RTOS 任務(wù)通信核心機(jī)制的運(yùn)用,以實(shí)際場(chǎng)景展示優(yōu)勢(shì)與操作方法。
當(dāng)基于 RTOS 的系統(tǒng)出現(xiàn)死機(jī)現(xiàn)象,你會(huì)如何排查故障?請(qǐng)列出至少三種排查方向。
- 答案:一是查看任務(wù)堆棧是否溢出,RTOS 任務(wù)堆??臻g有限,若任務(wù)內(nèi)局部變量過多、函數(shù)調(diào)用鏈過長(zhǎng)或任務(wù)死鎖等,可能導(dǎo)致堆棧溢出,可通過調(diào)試工具查看堆棧使用情況;二是檢查任務(wù)間同步互斥機(jī)制,如信號(hào)量、互斥量是否正確使用,若出現(xiàn)死鎖,會(huì)導(dǎo)致系統(tǒng)停滯,分析任務(wù)阻塞、等待資源的情況排查;三是排查中斷處理,是否有中斷服務(wù)程序未正確返回、中斷優(yōu)先級(jí)設(shè)置不當(dāng)干擾任務(wù)調(diào)度等,借助硬件調(diào)試器查看中斷觸發(fā)與執(zhí)行情況。
項(xiàng)目問題
為什么要多版本固件存儲(chǔ)?基于什么場(chǎng)景考慮的?
Xmodem 協(xié)議相關(guān)
在基于 Xmodem 協(xié)議實(shí)現(xiàn)系統(tǒng)本地在應(yīng)用升級(jí)(IAP)過程中,Xmodem 是如何進(jìn)行數(shù)據(jù)包傳輸?shù)男r?yàn)的?如果校驗(yàn)出錯(cuò),系統(tǒng)采取了哪些措施來保證升級(jí)的可靠性?
-
- 答案:Xmodem 通常采用 CRC(循環(huán)冗余校驗(yàn))或 Checksum(校驗(yàn)和)來校驗(yàn)數(shù)據(jù)包。以 CRC 為例,發(fā)送方根據(jù)數(shù)據(jù)包內(nèi)容計(jì)算出 CRC 值并附加在數(shù)據(jù)包末尾發(fā)送,接收方收到數(shù)據(jù)包后,按照相同算法重新計(jì)算 CRC 值,與接收到的 CRC 值比對(duì)。若校驗(yàn)出錯(cuò),系統(tǒng)一般會(huì)采取
重發(fā)
- 機(jī)制,向發(fā)送方請(qǐng)求重發(fā)出錯(cuò)的數(shù)據(jù)包,并重試一定次數(shù),若多次重發(fā)仍失敗,則停止升級(jí)并報(bào)錯(cuò),提示用戶檢查連接或升級(jí)文件完整性,以此確保升級(jí)過程數(shù)據(jù)準(zhǔn)確可靠。
當(dāng)本地 IAP 升級(jí)觸發(fā)時(shí),如何確保系統(tǒng)在升級(jí)過程中的狀態(tài)切換是安全的?比如從正常運(yùn)行狀態(tài)進(jìn)入升級(jí)準(zhǔn)備態(tài),再到升級(jí)執(zhí)行態(tài),期間涉及的任務(wù)暫停、資源釋放等操作是如何協(xié)調(diào)的?
- 答案:首先,在觸發(fā)升級(jí)前,系統(tǒng)會(huì)發(fā)送通知給正在運(yùn)行的任務(wù),讓其有序停止,保存關(guān)鍵數(shù)據(jù),如正在處理的瞳孔檢測(cè)數(shù)據(jù)緩存等,避免數(shù)據(jù)丟失。然后,關(guān)閉不必要的外設(shè)及中斷,防止在升級(jí)過程中受到干擾。對(duì)于資源釋放,會(huì)釋放一些動(dòng)態(tài)分配的內(nèi)存,如為臨時(shí)圖像處理開辟的緩沖區(qū),確保升級(jí)所需內(nèi)存空間充足。進(jìn)入升級(jí)準(zhǔn)備態(tài)時(shí),系統(tǒng)會(huì)初始化 Xmodem 協(xié)議相關(guān)參數(shù)、打開通信端口等;升級(jí)執(zhí)行態(tài),嚴(yán)格按照 Xmodem 流程接收數(shù)據(jù)包、校驗(yàn)、寫入 Flash 存儲(chǔ)區(qū),各狀態(tài)轉(zhuǎn)換通過設(shè)置標(biāo)志位和狀態(tài)機(jī)機(jī)制協(xié)調(diào),保障升級(jí)流程順暢。
MQTT 協(xié)議相關(guān)
在基于 MQTT 協(xié)議實(shí)現(xiàn)云端空中升級(jí)(OTA)時(shí),如何保證設(shè)備與云端連接的穩(wěn)定性?若遇到網(wǎng)絡(luò)中斷情況,系統(tǒng)有什么策略來恢復(fù)連接并繼續(xù)未完成的升級(jí)?
- 答案:為保證連接穩(wěn)定性,設(shè)備端與云端建立 MQTT 連接時(shí),會(huì)設(shè)置?;钚奶鼨C(jī)制,設(shè)備按一定時(shí)間間隔(如 30 秒)向云端發(fā)送心跳包,云端收到后回復(fù)確認(rèn),若設(shè)備一段時(shí)間未收到確認(rèn),就判定連接可能中斷,主動(dòng)重連。遇到網(wǎng)絡(luò)中斷,系統(tǒng)首先嘗試重連網(wǎng)絡(luò),重連成功后,從上次斷點(diǎn)處繼續(xù)升級(jí)。這需要在升級(jí)前記錄已接收數(shù)據(jù)包的序號(hào)、升級(jí)進(jìn)度等信息,重連后向云端請(qǐng)求補(bǔ)發(fā)缺失數(shù)據(jù)包,利用 MQTT 的 QoS(服務(wù)質(zhì)量)機(jī)制確保數(shù)據(jù)可靠傳輸,保障升級(jí)完整性。
MQTT 協(xié)議有不同的 QoS 級(jí)別(0、1、2),在本項(xiàng)目的 OTA 升級(jí)中,選用了哪個(gè) QoS 級(jí)別?為什么?結(jié)合瞳孔檢測(cè)系統(tǒng)的實(shí)時(shí)性與可靠性需求進(jìn)行闡述。
答案:本項(xiàng)目選用 QoS 1。原因是 QoS 0 只管發(fā)送,不保證接收,對(duì)于固件升級(jí)這種對(duì)數(shù)據(jù)完整性要求高的場(chǎng)景風(fēng)險(xiǎn)太大;QoS 2 雖保證最強(qiáng)可靠性,但帶來較高的開銷與延遲,因需多次握手確認(rèn),在網(wǎng)絡(luò)條件一般時(shí)會(huì)影響升級(jí)效率。而 QoS 1 提供 “至少一次” 的送達(dá)保證,即消息若丟失會(huì)重發(fā),既滿足固件升級(jí)對(duì)數(shù)據(jù)不丟失的要求,又在一定程度上兼顧了實(shí)時(shí)性,確保升級(jí)數(shù)據(jù)包能較快傳輸,符合瞳孔檢測(cè)系統(tǒng)需要及時(shí)更新固件又不能長(zhǎng)時(shí)間中斷服務(wù)的特性。
通用升級(jí)問題
在進(jìn)行本地 IAP 和云端 OTA 升級(jí)時(shí),如何對(duì)升級(jí)包進(jìn)行版本管理?如何確保只有合法的、經(jīng)過驗(yàn)證的升級(jí)包才能用于系統(tǒng)升級(jí)?
答案:對(duì)于版本管理,系統(tǒng)為每個(gè)固件版本設(shè)定唯一版本號(hào),遵循一定規(guī)則,如主版本號(hào)。次版本號(hào)。修訂號(hào),升級(jí)時(shí)對(duì)比本地版本與待升級(jí)版本號(hào),只有待升級(jí)版本號(hào)高于本地版本號(hào)才允許升級(jí)。對(duì)于升級(jí)包驗(yàn)證,采用數(shù)字簽名技術(shù),在制作升級(jí)包時(shí),使用私鑰對(duì)包內(nèi)數(shù)據(jù)生成簽名,設(shè)備端用公鑰驗(yàn)證簽名,若簽名不匹配,說明升級(jí)包可能被篡改,拒絕升級(jí),以此保證只有合法、安全的升級(jí)包能用于系統(tǒng),防止惡意軟件入侵。
無論是本地 IAP 還是云端 OTA 升級(jí),一旦升級(jí)失敗,如何進(jìn)行降級(jí)處理或故障恢復(fù),以保證瞳孔檢測(cè)系統(tǒng)盡快恢復(fù)到可用狀態(tài)?
- 答案:升級(jí)失敗后,系統(tǒng)首先會(huì)嘗試回滾操作,若本地有備份的上一版本固件,從備份區(qū)恢復(fù)固件到運(yùn)行區(qū),重啟系統(tǒng)恢復(fù)正常功能;若沒有備份,對(duì)于本地 IAP 失敗,會(huì)提示用戶通過特定工具重新刷入原始固件;對(duì)于云端 OTA 失敗,會(huì)在網(wǎng)絡(luò)恢復(fù)穩(wěn)定后,重新下載上一可靠版本固件進(jìn)行升級(jí),期間系統(tǒng)盡量維持部分基礎(chǔ)功能運(yùn)行,如僅提供簡(jiǎn)單人機(jī)交互告知用戶升級(jí)狀態(tài),避免完全 “死機(jī)”,保障瞳孔檢測(cè)系統(tǒng)的可用性。
FreeRTOS 任務(wù)間通信機(jī)制相關(guān)
在多線程框架下,如何確保任務(wù)的優(yōu)先級(jí)分配合理?以寵物喂養(yǎng)機(jī)為例,哪些任務(wù)應(yīng)該具有較高優(yōu)先級(jí),哪些相對(duì)較低?如果優(yōu)先級(jí)設(shè)置不當(dāng),可能會(huì)出現(xiàn)什么問題?
答案:對(duì)于寵物喂養(yǎng)機(jī),像緊急制動(dòng)任務(wù)(防止電機(jī)異常運(yùn)轉(zhuǎn)造成危險(xiǎn))、實(shí)時(shí)監(jiān)測(cè)寵物接近喂食口防止夾傷的任務(wù)等關(guān)乎設(shè)備安全與寵物健康的任務(wù)應(yīng)設(shè)置較高優(yōu)先級(jí),確保能及時(shí)響應(yīng)。而一些如定期記錄設(shè)備運(yùn)行日志、非緊急狀態(tài)下向云端上傳歷史數(shù)據(jù)的任務(wù)優(yōu)先級(jí)相對(duì)較低。
若優(yōu)先級(jí)設(shè)置不當(dāng),例如將日志記錄任務(wù)優(yōu)先級(jí)設(shè)得過高,當(dāng)系統(tǒng)資源緊張時(shí),可能導(dǎo)致關(guān)鍵的監(jiān)測(cè)與控制任務(wù)得不到及時(shí)執(zhí)行,出現(xiàn)食物投放延遲、無法及時(shí)響應(yīng)寵物靠近等問題,影響設(shè)備正常運(yùn)行甚至引發(fā)安全隱患。
flash分區(qū)
在對(duì) Flash 進(jìn)行分區(qū)實(shí)現(xiàn) BootLoader 基礎(chǔ)上的 OTA 升級(jí)時(shí),F(xiàn)lash 各分區(qū)的功能是如何劃分的?為什么要這樣劃分?
- 答案:一般分為 BootLoader 區(qū)、應(yīng)用程序區(qū)、OTA 升級(jí)暫存區(qū)。BootLoader 區(qū)存放啟動(dòng)引導(dǎo)代碼,負(fù)責(zé)系統(tǒng)初始化、判斷是否有可用的 OTA 升級(jí)包,若有則將升級(jí)包從暫存區(qū)搬運(yùn)到應(yīng)用程序區(qū)并啟動(dòng)更新。應(yīng)用程序區(qū)運(yùn)行寵物喂養(yǎng)機(jī)日常功能代碼。OTA 升級(jí)暫存區(qū)用于在接收云端 OTA 升級(jí)包時(shí)臨時(shí)存儲(chǔ),其大小要根據(jù)升級(jí)包最大可能尺寸合理設(shè)置。這樣劃分保證了系統(tǒng)啟動(dòng)的獨(dú)立性與升級(jí)過程的安全性,即使升級(jí)失敗,BootLoader 仍能維持基本啟動(dòng)功能,嘗試恢復(fù)或等待再次升級(jí),避免設(shè)備 “變磚”,保障設(shè)備持續(xù)可用性。解釋:Flash 分區(qū)是 OTA 升級(jí)底層架構(gòu)關(guān)鍵,合理布局反映面試者對(duì)嵌入式系統(tǒng)存儲(chǔ)管理與升級(jí)流程理解,關(guān)乎項(xiàng)目可維護(hù)性。
總結(jié)
- 面試的時(shí)候,自我介紹邏輯清晰,把個(gè)人的亮點(diǎn)都講了出來:保送研究生+探索+堅(jiān)持+熱愛運(yùn)動(dòng)。面試過程問題回答的也很詳細(xì),但是在某些問題上有些過于“著急”。面試回答問題時(shí)無重點(diǎn),面試官可能沒有耐心聽你講完。遇到某些不會(huì)的問題,最好不要直接說不會(huì),而是嘗試表達(dá)自己對(duì)于這個(gè)問題思考的過程。
沒過多久,這位讀者就來報(bào)喜了,成功拿下了兩個(gè)大廠實(shí)習(xí)offer。
關(guān)于模擬面試
看完這次模擬面試,相信大家心里都有數(shù)了,嵌入式軟件工程師面試到底是咋回事。
如果你也想在春招里殺出重圍,穩(wěn)穩(wěn)拿捏面試節(jié)奏,對(duì)那些高頻問題了如指掌,別猶豫,趕緊來找我!我肯定根據(jù)你的情況,給你定制一套專屬模擬面試,讓你提前適應(yīng)面試場(chǎng)景,把自己的短板都補(bǔ)上。面試完成后會(huì)深入分析面試存在的問題及解決辦法,手把手教你如何回答問題。
春招不等人,機(jī)會(huì)都是留給有準(zhǔn)備的人,咱們一起加油,向著理想的崗位沖!
想要參加模擬面試(社招校招均可)的同學(xué),可以掃碼加我微信,備注 模擬面試,一定要記得備注!