嵌入式軟體工程師測試題20道與簡析

2021-02-24 嵌入式ARM

1.  C語言中,修飾符volatile含義是什麼?其應用場合有哪些?


答:volatile關鍵字的作用

volatile提醒編譯器它後面所定義的變量隨時都有可能改變,因此編譯後的程序每次需要存儲或讀取這個變量的時候,都會直接從變量地址中讀取數據。如果沒有volatile關鍵字,則編譯器可能優化讀取和存儲,可能暫時使用寄存器中的值,如果這個變量由別的程序更新了的話,將出現不一致的現象。下面舉例說明。在DSP開發中,經常需要等待某個事件的觸發,所以經常會寫出這樣的程序:

short flag;
void test()
{
do1();
while(flag==0);
do2();

}

這段程序等待內存變量flag的值變為1(懷疑此處是0,有點疑問,)之後才運行do2()。變量flag的值由別的程序更改,這個程序可能是某個硬體中斷服務程序。例如:如果某個按鈕按下的話,就會對DSP產生中斷,在按鍵中斷程序中修改flag為1,這樣上面的程序就能夠得以繼續運行。但是,編譯器並不知道flag的值會被別的程序修改,因此在它進行優化的時候,可能會把flag的值先讀入某個寄存器,然後等待那個寄存器變為1。如果不幸進行了這樣的優化,那麼while循環就變成了死循環,因為寄存器的內容不可能被中斷服務程序修改。為了讓程序每次都讀取真正flag變量的值,就需要定義為如下形式:

volatile short flag;

需要注意的是,沒有volatile也可能能正常運行,但是可能修改了編譯器的優化級別之後就又不能正常運行了。因此經常會出現debug版本正常,但是release版本卻不能正常的問題。所以為了安全起見,只要是等待別的程序修改某個變量的話,就加上volatile關鍵字。

 

2.  請問TCP/IP協議分為哪幾層?FTP協議在哪一層?

答:

TCP/IP整體構架概述

TCP/IP協議並不完全符合OSI的七層參考模型。傳統的開放式系統互連參考模型,是一種通信協議的7層抽象的參考模型,其中每一層執行某一特定任務。該模型的目的是使各種硬體在相同的層次上相互通信。這7層是:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層。而TCP/IP通訊協議採用了4層的層級結構,每一層都呼叫它的下一層所提供的網絡來完成自己的需求。這4層分別為:

應用層:應用程式間溝通的層,如簡單電子郵件傳輸(SMTP)、文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等。

傳輸層:在此層中,它提供了節點間的數據傳送服務,如傳輸控制協議(TCP)、用戶數據報協議(UDP)等,TCP和UDP給數據包加入傳輸數據並把它傳輸到下一層中,這一層負責傳送數據,並且確定數據已被送達並接收。

互連網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都能夠到達目的主機(但不檢查是否被正確接收),如網際協議(IP)。

網絡接口層:對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、SerialLine等)來傳送數據。

 

3.  在網絡應用中,函數htons,htonl,ntohs,ntohl的作用是什麼?

答:


htons

htons函數用來轉換u_short來自主機的TCP / IP網絡字節順序(即big-endian )的. u_short htons ( u_short hostshort ) ; 參數hostshort [ ] 16位元數的主機字節順序. 返回值的htons函數返回值的TCP /IP網絡字節順序. 須知htons函數有一個16位號碼主機字節順序並返回一個16位數字網絡字節命令中使用的TCP /IP網絡.

htonl

將主機的無符號長整形數轉換成網絡字節順序。

#include <winsock.h>

u_long PASCAL FAR htonl( u_long hostlong);

hostlong:主機字節順序表達的32位數。

注釋:

  本函數將一個32位數從主機字節順序轉換成網絡字節順序。

  返回值:htonl()返回一個網絡字節順序的值。

  參見:htons(), ntohl(), ntohs().

ntohs

將一個無符號短整形數從網絡字節順序轉換為主機字節順序。

#include<winsock.h>

u_short PASCAL FAR ntohs(u_short netshort);

netshort:一個以網絡字節順序表達的16位數。

  注釋:

  本函數將一個16位數由網絡字節順序轉換為主機字節順序。

  返回值:ntohs()返回一個以主機字節順序表達的數。

  參見:htonl(), htons(),ntohl().

ntohl

將一個無符號長整形數從網絡字節順序轉換為主機字節順序。

  #include <winsock.h>

u_long PASCAL FAR ntohl(u_long netlong);

netlong:一個以網絡字節順序表達的32位數。

  注釋:

  本函數將一個32位數由網絡字節順序轉換為主機字節順序。

  返回值:ntohl()返回一個以主機字節順序表達的數。

  參見:htonl(), htons(),ntohs().

 

4.  C語言中static函數與普通函數的區別是什麼?

答:

1.static有什麼用途?(請至少說明兩種)

1)在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。

2) 在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所有函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。

3) 在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用

 

static全局變量與普通的全局變量有什麼區別?static局部變量和普通局部變量有什麼區別?static函數與普通函數有什麼區別?

全局變量(外部變量)的說明之前再冠以static 就構成了靜態的全局變量。全局變量本身就是靜態存儲方式,靜態全局變量當然也是靜態存儲方式。這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。而靜態全局變量則限制了其作用域,即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。從以上分析可以看出,把局部變量改變為靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量後是改變了它的作用域,限制了它的使用範圍。

static函數與普通函數作用域不同。僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件static全局變量與普通的全局變量有什麼區別:static全局變量只初使化一次,防止在其他文件單元中被引用; static局部變量和普通局部變量有什麼區別:static局部變量只被初始化一次,下一次依據上一次結果值;static函數與普通函數有什麼區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝

 

5.  請實現內存複製函數voidmemcpy(void *dst const void *src,int size)

 

原型:extern void*memcpy(void *dest, void *src, unsigned int count);
用法:#include<string.h>
功能:由src所指內存區域複製count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。

舉例:
// memcpy.c

#include <syslib.h>
#include <string.h>
int main(int argc, char* argv[])
{
    char *s="Golden Global View";
    char d[20];
    clrscr();
memcpy(d,s,strlen(s));
d[strlen(s)]='\0';
printf("%s",d);
getchar();
return 0;
}
截取view
#include <string.h>
int main(int argc, char* argv[])
{
char *s="Golden Global View";
char d[20];
memcpy(d,s+14,4);
//memcpy(d,s+14*sizeof(char),4*sizeof(char));也可
d[5]='\0';
printf("%s",d);
getchar();
return 0;
}
輸出結果:
View

初始化數組
char msg[10];
memcpy(msg,0,sizeof(memcpy));

 

方法2:

寫一個內存拷貝函數

 

// 考慮重疊的狀況
void* _memcpy(void* dest, void* src, int len)
{
    if(!dest || !src || !len || dest == src)
        return dest;

    char* pdest = static_cast<char*>(dest);
    char* psrc = static_cast<char*>(src);

    // dest 在 src + len 範圍內
    if(pdest > psrc && pdest < (psrc + len))
    {
        // 先備份被覆蓋部分
        int need = psrc + len - pdest;
        int offset = pdest - psrc;
        char* pcache = new char[need];

        int i = 0;
        for (i = 0; i < need; ++i)
            pcache[i] = psrc[offset + i]; 

        // 拷貝起始部分
        for (i = 0; i < offset; ++i)
            pdest[i] = psrc[i];
        
        // 拷貝剩餘部分
        for (i = 0; i < need; ++i)
            pdest[offset + i] = pcache[i]; 

        delete[] pcache;
    }
    else
    {
        for (int i = 0; i < len; ++i)
            pdest[i] = psrc[i];
    }

    return dest;
}

6.32位機器上,假設有一個32位數字0x1234abcd保存在0x00000000開始的內存中,那麼在little endian和big endian的機器上,按字節該整數在內存中存放的順序是怎麼樣的?


答:大端模式:數據的高字節存儲在內存地址的低字節,(正常存儲)小端模式:數據的高字節存儲在內存地址的高字節.

littleendian:0x00000000-0x000000003h:cd,ab,34,12

big endian: 0x00000000-0x000000003h:   12,34,ab,cd



7.ISO七層模型是什麼,tcp/udp屬於哪一層?

答:物理層-數據鏈路層-網絡層-傳輸層-會話層-表示層-應用層,tcp/udp工作在傳輸層。

8.下面是一個中斷服務程序的代碼,請指出有那些問題?

_interrupt double compute_area(double radius)

{

double area=PI*radius*radius;

return area;

}

答:中斷子程序不能有返回值,去掉return area; compute_area之前的double關鍵字。這個函數有太多的錯誤了,以至讓人不知從何說起了:

                                                                                                       1)ISR 不能返回一個值。如果你不懂這個,那麼你不會被僱用的。

2) ISR 不能傳遞參數。如果你沒有看到這一點,你被僱用的機會等同第一項。

3) 在許多的處理器/編譯器中,浮點一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點運算。此外,ISR應該是短而有效率的,在ISR中做浮點運算是不明智的。

4) 與第三點一脈相承,printf()經常有重入和性能上的問題。如果你丟掉了第三和第四點,我不會太為難你的。不用說,如果你能得到後兩點,那麼你的被僱用前景越來越光明了。

8.多任務系統中,常見的任務通訊機制有哪些?


答:作業系統還提供進程間的通訊機制來幫助完成這樣的任務。Linux中常見的進程間通訊機制有:信號、管道、共享內存、信號量和套接字等。

9.請實現內存複製函數memcpy(void *dst,const void*src,int size).

答:

舉例:

// memcpy.c
#include <syslib.h>
#include <string.h>
int main(int argc, char* argv[])
{
    char *s="Golden Global View";
    char d[20];
    clrscr();

memcpy(d,s,strlen(s));
d[strlen(s)]='\0';
printf("%s",d);
getchar();
return 0;
}

截取view
#include <string.h>
int main(int argc, char* argv[])
{
char *s="Golden Global View";
char d[20];
memcpy(d,s+14,4);
//memcpy(d,s+14*sizeof(char),4*sizeof(char));也可
d[5]='\0';
printf("%s",d);
getchar();
return 0;
}
輸出結果:
View

初始化數組

char msg[10];

memcpy(msg,0,sizeof(memcpy));

 

10.請列舉主流linux的發布版本(四個以上)。

答:

(1)Redhat有兩大Linux產品系列,其一是免費的Fedora Core系列主要用於桌面版本,提供了較多新特性的支持。另外一個產品系列是收費的Enterprise系列,這個系列分成:AS/ES/WS等分支。

(2)Advanced Server,縮寫即AS。AS在標準Linux內核的基礎上,做了性能上的增強,並提高了可靠性,集成了眾多常見伺服器的驅動程序。可輕鬆識別IBM/DELL/HP等常見機架式伺服器的磁碟陣列卡等設備。

11.當前linux最主流的兩大桌面環境是什麼,兩者區別是什麼?


答:KDE與GNOME是目前Linux/UNIX系統最流行的圖形操作環境


12.linux系統下主要三類設備文件類型是什麼?

答:塊設備、字符設備、網絡設備。

Linux 中的設備有2種類型:字符設備(無緩衝且只能順序存取)、塊設備(有緩衝且可以隨機存取)。每個字符設備和塊設備都必須有主、次設備號,主設備號相同的設備是同類設備(使用同一個驅動程序)。這些設備中,有些設備是對實際存在的物理硬體的抽象,而有些設備則是內核自身提供的功能(不依賴於特定的物理硬體,又稱為"虛擬設備")。

13.乙太網的MTU是多大?


答:通常意義上的乙太網MTU是指沒有乙太網header和FCS的乙太網payload部分,IEEE802規定了大小為0~1500位元組;所以,二層乙太網幀長應該為這個長度加上18B(6B的DA、6B的SA和2B的Length/Etype以及4B的FCS),這樣大小應該<1518;在Dot1Q情況下,應該在加上4B的802.1Q的Tag,即應該<1522B;在MPLS VPN環境中,IGP標籤和VPN標籤各是4B,所以,作為中間環節的交換機如果不支持Jumbo幀的話,就需要手工配置MTU=1500+N*4(N為MPLS Tag層數)。

14. ARP協議作用

答:IP數據包常通過乙太網發送。乙太網設備並不識別32位IP位址:它們是以48位乙太網地址傳輸乙太網數據包的。因此,IP驅動器必須把IP目的地址轉換成乙太網網目的地址。在這兩種地址之間存在著某種靜態的或算法的映射,常常需要查看一張表。地址解析協議(Address Resolution Protocol,ARP)就是用來確定這些映象的協議。

ARP工作時,送出一個含有所希望的IP位址的乙太網廣播數據包。目的地主機,或另一個代表該主機的系統,以一個含有IP和乙太網地址對的數據包作為應答。發送者將這個地址對高速緩存起來,以節約不必要的ARP通信。

如果有一個不被信任的節點對本地網絡具有寫訪問許可權,那麼也會有某種風險。這樣一臺機器可以發布虛假的ARP報文並將所有通信都轉向它自己,然後它就可以扮演某些機器,或者順便對數據流進行簡單的修改。ARP機制常常是自動起作用的。在特別安全的網絡上, ARP映射可以用固件,並且具有自動抑制協議達到防止幹擾的目的。

 

15. 編寫一個簡單的ECHO伺服器

答:如下代碼是一個簡單的echo伺服器,它示例的一些Winsock函數的用法。

#include <iostream>
using namespace std;

#ifdef WIN32

#   include <WinSock2.h>
/// 也可在setting/liker/input/Additional dependencies加入導入庫引用
#   pragma comment(lib, "ws2_32.lib")

/// 包含AcceptEx,TransmitFile,DisconnectEx等函數
#   include <mswsock.h>
#   pragma comment(lib,"Mswsock.lib")

#   define PRINT_SOCKET_ERROR(FUNC) 
    do 

    { 
    cout << "<" << #FUNC << "> Call Error!" << "" 
    << "Error Number : " << WSAGetLastError() << endl; 
    } while(0)

#endif // WIN32

#define PORT 5432

int main(int argc, char* argv[])
{
    // = 初始化Lib庫
    int nRet;
    WSAData wsaData;
    if ((nRet = WSAStartup(0x0202, &wsaData)) != 0)
    {   
        PRINT_SOCKET_ERROR(WSAStartup);
        return -1;
    }

    // = 設置監聽socket句柄
    SOCKET hListen;

    /// #1 
    if ((hListen = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        PRINT_SOCKET_ERROR(socket);
        return -1;
    }

    /// #2
    SOCKADDR_IN hostAddr; 
    {
        u_long nIp = htonl(INADDR_ANY);
        {
            /// 相關函數示例
            char szHostName[256] = {0};
            gethostname(szHostName, 256);
            hostent* thisHost = gethostbyname(szHostName);
            nIp = inet_addr(inet_ntoa(*((in_addr*)thisHost->h_addr_list[0])));
        }
        hostAddr.sin_family = AF_INET;
        hostAddr.sin_port = htons(PORT);
        hostAddr.sin_addr.s_addr = nIp;
    }   
    
    if ((nRet = bind(hListen, (PSOCKADDR)&hostAddr, sizeof(SOCKADDR_IN))) != 0)
    {
        PRINT_SOCKET_ERROR(bind);
        return -1;
    }

    /// #3
    if ((nRet = listen(hListen, 5)) != 0)
    {
        PRINT_SOCKET_ERROR(listen);
        return -1;
    }
    else
    {
        cout << "Listening at " << inet_ntoa(hostAddr.sin_addr) 
             << ":" << ntohs(hostAddr.sin_port) << endl;
    }

    // = 處理請求
    SOCKET hConnected;
    SOCKADDR_IN remoteAddr;
    int remote_addr_size = sizeof(SOCKADDR_IN);
    if ((hConnected = accept(hListen, (PSOCKADDR)&remoteAddr, &remote_addr_size)) == INVALID_SOCKET)
    {
        PRINT_SOCKET_ERROR(accept);
        return -1;
    }
    else
    {
        cout << "Connect from " << inet_ntoa(remoteAddr.sin_addr) 
             << ":" << ntohs(remoteAddr.sin_port) << endl;        
    }

    // = 數據收發
    do
    {
        char buffer[1024] = {0};
        int recv_bytes = recv(hConnected, buffer, 1024, 0);
        if (recv_bytes == -1)
        {
            PRINT_SOCKET_ERROR(recv);
            break;
        }
        else if (recv_bytes == 0)
        {  
           /// 客戶端關閉了連結
            cout << "Connection closed from " << inet_ntoa(remoteAddr.sin_addr)
                 << ":" << ntohs(remoteAddr.sin_port) << endl;
           closesocket(hConnected);
            break;
        }
        else
        {
            buffer[recv_bytes] = 0;
            cout << buffer; cout.flush();
            int send_bytes = send(hConnected, buffer, recv_bytes, 0);
            if (send_bytes != recv_bytes)
            {
                cout << "Not send out all data!" << endl;
            }
        }

    } while (1);

    closesocket(hListen);

    // = 清理Lib庫
    if (WSACleanup() !=  0)
    {
        PRINT_SOCKET_ERROR(WSACleanup);
        return -1;
    }

    return 0;
};

16.  什麼是DSP?請簡述DSP與通用CPU的差別。

答:以微處理器解度看,兩者似乎沒什麼差別. 但二者所專注的鄰域卻完全不一樣. 通用的CPU專注的事務處理,對實時性的支持相對DSP差了很多.雖然一些通用CPU也在加入一些高性能的運算支持,但它和DSP相比還是天差地遠.
   

比如現在的通用DSP可以在幾個us內完成1024點的複數FFT,通用處理器是咋都達不到這水平(現在的情況),雖然其系統時鐘有可能比DSP高出一個數量級.但一個周期完成多個複雜操作和多個周期完成一個操作的差別是很大的.
  

DSP完成的都是算法密集性的事務,可能工作比較單一而簡單,但對實時要求很高很高.必需要某個確定的時間內(有可能就那麼幾us)完成所需要的所有操作.

通用CPU對事務管理很突出, 在這方面的能力比DSP支持得要好得多.

所以大多數的高性能系統會是DSP和通用CPU的結合.充分利用各自的優點.
   

由於DSP特注重高性能,其結構在同等條件比通用CPU要複雜得多,設計上也更困難.因此其價格相比通用CPU要貴那麼一些(只是通用DSP和通用CPU 相比),一些很單一功能的DSP可是很便宜的,比通用CPU還便宜. 通用DSP因為要考慮通用,所以結構和專用的也是不一樣的.從表面上來看,DSP與標準微處理器有許多共同的地方:一個以ALU為核心的處理器、地址和數據總線、RAM、ROM以及I/O埠,從廣義上講,DSP、微處理器和微控制器(單片機)等都屬於處理器,可以說DSP是一種CPU。但DSP和一般的CPU又不同:
    

 首先是體系結構:CPU是馮.諾伊曼結構的,而DSP有分開的代碼和數據總線即「哈佛結構」,這樣在同一個時鐘周期內可以進行多次存儲器訪問——這是因為 數據總線也往往有好幾組。有了這種體系結構,DSP就可以在單個時鐘周期內取出一條指令和一個或者兩個(或者更多)的操作數。     
     

標準化和通用性:CPU的標準化和通用性做得很好,支持作業系統,所以以CPU為核心的系統方便人機互動以及和標準接口設備通信,非常方便而且不需要硬體 開發了;但這也使得CPU外設接口電路比較複雜,DSP主要還是用來開發嵌入式的信號處理系統了,不強調人機互動,一般不需要很多通信接口,因此結構也較為簡單,便於開發。如果只是著眼於嵌入式應用的話,嵌入式CPU和DSP的區別應該只在於一個偏重控制一個偏重運算了。
     

流水線結構:大多數DSP都擁有流水結構,即每條指令都由片內多個功能單元分別完成取指、解碼、取數、執行等步驟,這樣可以大大提高系統的執行效率。但流水線的採用也增加了軟體設計的難度,要求設計者在程序設計中考慮流水的需要。
     

快速乘法器:信號處理算法往往大量用到乘加(multiply-accumulate,MAC)運算。DSP有專用的硬體乘法器,它可以在一個時鐘周期內 完成MAC運算。硬體乘法器佔用了DSP晶片面積的很大一部分。(與之相反,通用CPU採用一種較慢的、迭代的乘法技術,它可以在多個時鐘周期內完成一次 乘法運算,但是佔用了較少了矽片資源)。
     

地址發生器:DSP有專用的硬體地址發生單元,這樣它可以支持許多信號處理算法所要求的特定數據地址模式。這包括前(後)增(減)、環狀數據緩衝的模地址以及FFT的比特倒置地址。地址發生器單元與主ALU和乘法器並行工作,這就進一步增加了DSP可以在一個時鐘周期內可以完成的工作量。
     

硬體輔助循環:信號處理算法常常需要執行緊密的指令循環。對硬體輔助循環的支持,可以讓DSP高效的循環執行代碼塊而無需讓流水線停轉或者讓軟體來測試循環終止條件。
     

低功耗:DSP的功耗較小,通常在0.5W到4W,採用低功耗的DSP甚至只有0.05W,可用電池供電,很適合嵌入式系統;而CPU的功耗通常在20W以上。

17.  靜態局部變量與普通局部變量的區別是什麼?

答:全局變量(外部變量)的說明之前再冠以static就構成了靜態的全局變量。全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。

 

從以上分析可以看出,把局部變量改變為靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量後是改變了它的作用域, 限制了它的使用範圍。

static函數與普通函數作用域不同。僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件

  

static全局變量與普通的全局變量有什麼區別:static全局變量只初使化一次,防止在其他文件單元中被引用;static局部變量和普通局部變量有什麼區別:static局部變量只被初始化一次,下一次依據上一次結果值;static函數與普通函數有什麼區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝。程序的局部變量存在於(堆棧)中,全局變量存在於(靜態區 )中,動態申請數據存在於( 堆)中。

 

18.請說明DSP中定點、浮點的概念

答:定點數指小數點在數中的位置是固定不變的,通常有定點整數和定點小數。在對小數點位置作出選擇之後,運算中的所有數均應統一為定點整數或定點小數,在運算中不再考慮小數問題。 

(1)定義:數據中小數點位置固定不變的數 (2)種類:定點整數(3)小數點在符號位與有效位之間。 

註:定點數受字長的限制,超出範圍會有溢出。 

19.定點數與浮點數區別 

答:定點表示法運算直觀,但數的表示範圍較小,不同的數運算時要考慮比例因子的選取,以防止溢出。浮點表示法運算時可以不考慮溢出,但浮點運算,編程較難。要掌握定、浮點數的轉換方法及浮點數規格化方法。

 

20.什麼是cache?cache有哪些操作?

答:cache n. 高速緩衝存儲器 一種特殊的存儲器子系統,其中複製了頻繁使用的數據以利於快速訪問。存儲器的高速緩衝存儲器存儲了頻繁訪問的 RAM 位置的內容及這些數據項的存儲地址。當處理器引用存儲器中的某地址時,高速緩衝存儲器便檢查是否存有該地址。如果存有該地址,則將數據返回處理器;如果沒有保存該地址,則進行常規的存儲器訪問。因為高速緩衝存儲器總是比主RAM 存儲器速度快,所以當 RAM 的訪問速度低於微處理器的速度時,常使用高速緩衝存儲器。

相關焦點

  • 嵌入式軟體工程師:兩手都要硬!
    除了國家和社會的發展,兩手都要抓,兩手都要硬的原則也以其頗合「中庸之道」,在各個領域發揮著重要的指導作用,比如筆者,就在多年職業生涯的風風雨雨中,悟出想幹好嵌入式軟體工程師,軟體、硬體兩手都要硬的經驗體會。
  • 嵌入式軟體工程師一般都在開發什麼
    打開APP 嵌入式軟體工程師一般都在開發什麼 發表於 2019-04-10 15:22:51 在嵌入式這個行業,只要工作了幾年的同仁。
  • 一位70後嵌入式軟體工程師的經歷和小經驗
    打開APP 一位70後嵌入式軟體工程師的經歷和小經驗 工程師吳畏 發表於 2018-06-13 16:34:00 放棄華為不錯的收入,進入未知領域:在華為累,有各種委屈,但是如果僅僅追求的是純嵌入式技術以及收入,華為是我知道的最好選擇,沒有之一。講我的收入不太合適,就透露一下我的主管的年收入吧,他帶團隊管技術,據說是80w,實際可能更多。但我,厭倦了無休止的加班,決定換一種方式貢獻自己的勞動力,所以今年10月選擇離開了華為,成立了一家小小公司,準備外接一些項目來做。
  • 一個嵌入式軟體工程師的角度如何看波音737MAX8墜機事件
    打開APP 一個嵌入式軟體工程師的角度如何看波音737MAX8墜機事件 發表於 2019-04-17 16:13:52 小編也來湊個熱鬧,從一個嵌入式軟體工程師的角度來談談看法。 1、MCAS(機動特性增強)系統 波音737MAX是737改進機型,目前訂單排隊已達4600架。由於發動機增大,整個飛機的平衡性變差,因此增加一個名為MCAS的軟體系統來彌補,防止飛機失速。 以下是小編根據有關資料畫出的MCAS軟體系統工作流程圖:
  • 嵌入式系統測試題40道附詳細解析
    A)  嵌入式系統與具體應用緊密結合,具有很強的專用性 B)  嵌入式系統通常包含在非計算機設備(系統)中,具有隱蔽性 C)  嵌入式系統的軟硬體資源往往受到嚴格的限制 D)  嵌入式系統性能較低,價格也比較便宜【解析】:與人們日常使用的個人計算機相比,嵌入式系統具有許多不同的特點
  • 嵌入式軟體工程師從初級邁入合格,可以這麼來做!
    就一位嵌入式系統軟體工程師而言,用人單位會特別關注你在該領域中所具備的特定的職業技能,比如你所擅長的是嵌入式系統驅動軟體開發,還是嵌入式系統應用開發,或者是嵌入式系統測試;你具體掌握了哪一種作業系統,是否有在某一種嵌入式系統結構上進行嵌入式系統軟體開發的技能。
  • 嵌入式+AI,嵌入式工程師的前景如何?
    說起嵌入式,其官方定義為:IEEE(國際電氣和電子工程師協會)的定義—嵌入式系統是「控制、監控或者輔助設備、機器和車間運行的裝置」。這主要是從應用上加以定義的,從中可以看出嵌入式系統是軟體和硬體的綜合體,還可以涵蓋機械等附屬裝置。
  • 嵌入式系統測試題(附詳細解析)
    A)  嵌入式系統與具體應用緊密結合,具有很強的專用性 B)  嵌入式系統通常包含在非計算機設備(系統)中,具有隱蔽性 C)  嵌入式系統的軟硬體資源往往受到嚴格的限制 D)  嵌入式系統性能較低,價格也比較便宜【解析】:與人們日常使用的個人計算機相比,嵌入式系統具有許多不同的特點
  • 小學一年級:1000道20以內加減法測試題,搞定這些,分數立馬提高
    下面,是我們為一年級的同學們整理的1000道20以內加減法測試題,希望同學們能在期末考前做一做!學習有方,教育有法,讓孩子有章有法,才能讓孩子更出色。由於篇幅原因,今天的內容就先分享到這裡,希望這份資料能夠幫助到同學們。如果家長還想獲取其他學科學習資料,歡迎在評論區留言,我會抽時間整理,再分享給大家!
  • 【練習題】20道CSS基礎測試題
    ()A、font:bB、font-weight:boldC、style:bold17、如何顯示這樣一個邊框:上邊框 10 像素、下邊框 5 像素、左邊框 20 像素、右邊框 1 像素?()A、border-width:10px 5px 20px 1pxB、border-width:10px 20px 5px 1pxC、border-width:5px 20px 10px 1pxD、border-width:10px 1px 5px 20px18
  • 嵌入式開發中要用的三種程序架構~
    在嵌入式軟體開發,包括單片機開發中,軟體架構對於開發人員是一個必須認真考慮的問題。軟體架構對於系統整體的穩定性和可靠性是非常重要的,一個合適的軟體架構不僅結構清晰,並且便於開發。我相信在嵌入式或單片機軟體開發的初期大多數開發者採用的都是簡單的前後臺順序執行架構(我就是這樣的)。在嵌入式軟體開發中,程序架構主要分為三種,本篇文章將對這三種程序架構做出詳解。 可以說一個好的程序架構,是一個有經驗的工程師和一個初學者的分水嶺。
  • 哈佛大學智商測試題:普通人最多會5道,據說全部答對的人是天才
    也許你不相信,不要緊,今天小磊就和大家分享一套來自哈佛大學的智商測試題,據說這套測試題是哈佛學子們學習之餘的一種能力測試。這套測試題總共只有九小題,限時20分鐘,普通人最多會5道,據說全對的人是天才。哈佛大學智商測試題第1題:Merry(女)的弟弟點了一下兄弟姐妹的人數,發現自己的兄弟比姐妹多1人。那麼,Merry的兄弟比她的姐妹多幾人?第2題:有排列成一行的四戶人家。
  • 門薩智商測試題_國際標準智力測試題及答案
    這並不困難,以下這組門薩智商測試題是最準確的國際標準智商測試題,共33道IQ測試題目,無標準答案,只有屬於你自己的答案。在線測試完畢提交答案即可自動得出您的IQ。測試時間15分鐘左右,最大IQ為174分。智商越高,則表示越聰明。點「開始計時」按鈕開始IQ測試...也許你就是一個天才!
  • Jean Hsu:當女軟體工程師的那些好處
    雖然這裡沒有很多女性軟體工程師,但作為一個女性工程師,這一點也不差!我喜歡當一個軟體工程師,原因有很多,但和具體性別沒有關係,比如:能影響真 實用戶的新版本發布所來的興奮,和優秀團隊一起共事,成為帕洛阿爾託市創業社區的活躍分子…… 但我喜歡當一個女性軟體工程師,其實還有很多理由。
  • 最短的智商測試題,題目只有3道,超過8成的人做錯,你做對了嗎?
    說起智商測試題,最出名的當屬《國際標準智商測試30題》和《門薩智商測試題》,但是這兩個測試的題量都較大:第1個測試30道題,第2個測試33道題,甚至還有題量更大的測試題。在這個快節奏的時代,很多人已經不願意花這麼長的時間來做這樣的智商測試題了。
  • 這3道哈佛大學入學測試題,據說100秒內,能全部答對的不超過10%
    有一組數據表明:每年申請哈佛的學生近萬之多,但真正能夠踏入哈佛大學的學子卻不到20%,由此可見,哈佛的入學門檻是多麼的高。或許這些數據並不能讓你直觀感受到進入哈佛大學的難度,但是從這些年哈佛官方放出的一些入學考試題,可以讓我們略知一二。例如這道大家非常熟悉的題目:請仔細觀察上圖,你能夠確定這四個人中,下一秒哪個人最疼呢?就如圖中所說,能夠答出來的人智商絕對高。
  • 12道測試題,測出你家孩子的空間感水平!(適合3-8歲)
    今天整理了一套完整的測試題,用12道測試題,幫助父母科學了解孩子的空間感能力~● 本套題目主要是空間感的專項測試;● 全套測試題覆蓋3-8歲全年齡段;通過宏觀輪廓識別、圖形匹配、立體交叉、三維視圖、重疊遮擋五大角度,對兒童進行全方位考察;第一部分:空間輪廓識別☞ 測評能力說明:本模塊主要聚焦於宏觀空間輪廓的觀察
  • 如果C不行了,嵌入式編程是否應該用C+替代C語言!
    前言 幾十年來,嵌入式軟體工程師們一直在爭論是否應該使用C++替代C語言進行開發工作。 根據IEEE和github的市場調查顯示,微控制器製造商提供的軟體大部分都是由C語言編寫。
  • 影響嵌入式薪資的各種原因!
    他表示,其實嵌入式只是一個完成目的的手段,更重要的還是做事的方法、態度、決心。 魔都晶片原廠,嵌入式底層軟體,總共幾家加起來工作十年了,年薪20幾萬。 某電力儀表行業8年985碩士表示,武漢公司,有接近20個人的團隊,Linux移植和驅動,產品開發,cpp軟體開發都有,2018年一年將近50W。
  • 華東師大:180道心理測試題面試免費師範生
    此次面試與以往不同,除了專家面試外,還增加了「180道心理測試題」。    早在2006年,華東師大就開始醞釀在自主招生中引入「心理測試」。目前正在使用的心理測試系統由華東師大心理學專業的名師研發,每名考生需在電腦上測試半小時。