Try   HackMD

面試紀錄 & 練習 (聯發科)

發哥(聯發科)上機考題目整理
Benson Note
[分享]嵌入式經典面試題

聯發科實習面試

Overview

D = 履歷投遞(內推)
D + 20 = 安排面試
D + 30 = 面試
D + 37 = offer get

一般題目整理

寫出以下程式執行後之輸出結果

i = 0;
j = 10;
for (i = 0; i < 3 ; i++) {
    j+=i;
}
printf("%d\n",j);
  1. What are commonly put in the stack?

    1. Local variables
    2. Global variables
    3. Const data
    4. Malloced data
    5. Temporary storage for register contents
    6. Jum address within a function
    7. Function parameters
    8. Funtion return address (the address a function return to when it exits)
    9. Function return value 1578

what's the output

#include <stdio.h>
int count;
int calc(int x) {
    count++;
    return x> 0? calc(x - 1) + calc(x - 2) + 1 : 1;
}

int main (int argc, char* argv[]) {
    int result = calc(5);
    printf("Result %d %d \n", result, count);
    return 0;
}

what's the output ?

void main() {
    char s1[] = "MTK";
    char s2[] = "MTK";
    if (s1 == s2)
        printf("Same");
    else
        printf("Different");
}

what's the output

#include<stdio.h>
#define INC(x) x = 2x+=1

int main(int argc, char* argv[]) {
    int i, j;
    for(i = 0, j =1; i < 5; ++i)
        INC(j);
    printf("Result %d", j);
    return 0;
}

What will be output of the following c program ?

#include<stdio.h>
int main() {
    int goto = 5;
    printf("%d", goto);
    return 0;
}

What value does f() return ?

int x = 5;
int f() {
    int x = 3;
    {
        extern int x;
        return x;
    }
}

What does the following declaration mean?

int (*ptr)[10];

What is the output on screen?

void main(){
    int x = 0;
    if(x=0 || x==0)
        printf("1");
    if (x==0)printf("2");
    printf("3");
}

Can the code be compiled?

#include<stdio.h>
#define SWAP(a, b, c)(c t; t=a a=b, b=t)
int main(){
    int x=0, y=20;
    SWAP(x, y, int);
    printf("%d %d\n",x, y);
    return 0;
}

what is the initialized value individually?

int x;
void foo() {
    int y;
}

Given a sorted integer array "a", we want to check whether the target number is in the interval of (0, 10) of array "a". How many loop iteration will this binary search runs at most

bool foo(int a, int target) {
    int l = 0, r = 10;
    while(l < r) {
        int m = l + (r-l) / 2;
        if (a[m] == target) {
            return true;
        }
        if (a[m] > target) {
            r = m;
        } else {
            l = m;
        }
    }
    return false;
}

What is the output of the following code?

void swap(int x, int* y)
{
    int *temp = x;
    y = x;
    x = temp;
}
void main()
{
    int a = 10;
    int b = 20;
    swap(&a, &b);
    printf("%d %d", a, b);
}

What's the output?

void foo() {
    int i = 0;
    do {
        ++i;
        
        if(i < 3) {
            continue;
        }
        if( i == 5) {
            break;
        } 
    }while(false);
        std::cout << i << std::endl;
}

C test (考古)

1. Explain "#error"

#error指示詞會在編譯時期發出使用者指定的錯誤訊息,然後結束編譯。

#if !defined(__cplusplus)
#error C++ compiler required.
#endif

寫給編譯器看,常搭配 Cflag cplusplus flag 使用,在編譯的時候中斷錯誤,如果有找到 #error 則會發出致命錯誤,並且跳過進一步的編譯過程。

2. Explain "struct" and "union"

  • 在存儲多個成員信息時,編譯器會自動給struct第個成員分配存儲空間,struct 可以存儲多個成員信息,而Union每個成員會用同一個存儲空間,只能存儲最後一個成員的信息。

  • 都是由多個不同的數據類型成員組成,但在任何同一時刻,Union只存放了一個被先選中的成員,而結構體的所有成員都存在。

  • 對於Union的不同成員賦值,將會對其他成員重寫,原來成員的值就不存在了,而對於struct 的不同成員賦值 是互不影響的。

  • 註:在很多地方需要對結構體的成員變量進行修改。只是部分成員變量,那麼就不能用聯合體Union,因為Union的所有成員變量占一個內存。eg:在鍊表中對個別數值域進行賦值就必須用struct.

  • struct 的大小會根據成員決定,且按照城市中的定義擺放的順序在內存中排序,按照宣告的順序擺放 (注意 alignment),union 的大小由內部最大的那個資料型態來定義, union 會用同一個儲存空間儲存資料,只能儲存最後的一個成員信息

補充
typedef: 保留字, C 語言:typedef 的用法

3. Explain "volatile". Can we use "const" and "volatile" in the same variable? Can we use "volatile" in a pointer?

volatile 加在變數前面,指編譯器每次對該變數進行存取時都要立即更新,不應該對其做任何最佳化。

A記憶體為硬體的記憶體,

當程式執行時候,有些記憶體經過編譯器編譯後,會暫存CPU暫存記憶體中(B),

然而,程式執行時優先取得B區的暫存器的值

意思是B區有個test變數=1,A區也有一個test=1

但如果有天A區的暫存值test改變了,B區的test CPU暫存器沒有隨著編譯器更新,

就會造成程式錯誤, 若使用volatile, 程式就會永遠都從(A)記憶區塊中取得test變數

不會對test編出一個位置在B區,也不會去取得B區塊的CPU暫存器

  • 可以跟 const 合用,假設要監看一個 CPU flag 時就是不錯的時機。 const 限定一個變量不被改變。

4. the value of v?

unsigned long v1 = 0x00001111;
unsigned long v2 = 0x00001202;
unsigned long v;

v = v1 & (~v2);
v = v | v2;

5. the value of *(a+1) and (*p-1)

int a[5] = {1, 2, 3, 4, 5};
int *p = (int*)(&a + 1);
  • *(a+1) = 2
  • (*p-1) = undefined
  • *(p-1) = 5

參考 int *p=(int *)(&a + 1)的理解 以及 一道试题引发的血案

6. write a code

  • set the specific bit
  • clear the specific bit
  • inverse the specific bit (0->1; 1->0)
#define SETBIT(x,n) (x |= (1 << n))
#define CLEARBIT(x,n) (x &= ~(1 << n))
#define INVERSEBIT(x,n) (x ^= (1 << n))

7. Re-write

void(*(*papf)[3])(char*);
typedef______;
pf(*papf)[3];

Ans

typedef void(*pf)(char *);

參考 difference between int *a[3] and int (*a)[3]? [duplicate]

8. Write a code that check the input is a multiple of 3 or not without using division or mod

int divide3(int a)
{
    int ans = 0;
    while(a) {
        ans += a & 0x1;
        a>>=1;
        ans -= a& 0x1;
        a>>=1;
    }
    return !(ans);
}

通用算法 (This can use for any number)

set Number = abcde; // binary
abcde = abc << 2 + de
      = abc * (4) + de
      = abc * (3) + (abc + de)
int isMult3(unsigned int n)
{
    if( n == 0 || n == 3)
        return 1;
    if (n < 3)
        return 0;
    n = (n >> 2) + (n & 3);
    
    return(isMult3(n));
}

9. Explain lvalue and rvalue
C語言中的lvalue, rvalue

  • lvalue 是程式運行時可以通過地址資訊存取的值 (&),也可以 dereferenced (*)
  • lvalue 一定可以擷取地址,但不要求是可以修改的 (const)
  • lvalue 是等號的左值, rvalue 是等號的右值
  • lvalue 是一個物件, rvalue 是一個物件在某個時間單位的結果
  • ++c 是 lvalue , c++ 是 rvalue

10. the value of array a?

int a[5] = {1,2,3,4,5};
int *p = a;
*(p++)+=123;
*(++p)+=123;
124, 2, 126, 4, 5

11. 保證 n 一定是 5 個數字之一,不使用 if ,請用認為最快的方式實作 main

extern void func1(void);
extern void func2(void);
extern void func3(void);
extern void func4(void);
extern void func5(void);

void main(int n)
{
    if n==1 execute func1;
    if n==2 execute func2;
    if n==3 execute func3;
    if n==4 execute func4;
    if n==5 execute func5;
}
void (*fp[5])();
fp[0] = func1;
fp[1] = func2;
fp[2] = func3;
fp[3] = func4;
fp[4] = func5;

fp[n-1]();    // execute

12. 保證 n 一定是 5 個數字之一, 使用 if ,用認為最快的方式實做 main

extern void func1(void);
extern void func2(void);
extern void func3(void);
extern void func4(void);
extern void func5(void);

void main(int n)
{
    if n==33 execute func1;
    if n==67 execute func2;
    if n==324 execute func3;
    if n==231 execute func4;
    if n==687 execute func5;
}
void main(int n)
{
    if (n < 231)
        n!=67 ? fun1() : fun2();
    else if (n > 231)
        n!=324 ? fun3() : fun5();
    else
        fun4();
}

13. 寫一個 function 可傳入正整數 N ,回傳 1+2+3++N 之和

int nSum(int n)
{
    return (n+1)*n/2;
}

14. reverse a string(good problem)

void swap(char *a, char *b)
{
    *a = *a^*b;
    *b = *a^*b;
    *a = *a^*b;
}
void reverseOne(char *s)
{
    if(*(s+1) == '\n')
        return;
    reverseOne(s+1);
    swap(s,s+1);
}
void reverseAll(char *s)
{
    if((s=='\0'))
        return;
    while(s+1 != '\0') {
        reverseOne(s);
        s++;
    }
}

15. 寫一個"標準"巨集 MIN,這個巨集輸入兩個參數並返回比較小的一個 參考

#define MIN(a,b) ((a<b)?(a):(b))

16. 寫出一個 function 判斷輸入的數是 2 的次方

int define2N(int n)
{
    return (!(n & n-1) && n != 0);
}

17. Write a MACRO to caculate the squre of integer a.

#define squre(x) ((x)*(x))

18. Write a function to find the middle field of singled-linked list without traverse whole list

while(fast != null & fast.next != null) {
    slow = slow.next;
    fast = fast.next.next;
}
return slow;

19. Write a code to reverse the linked list.

20. Find the possible error

int ival;
int **p;
ival = *p;

21. What is the possible error of below SQR function.

int SQR(volatile int *a) {
    return (*a)*(*a);
}

因為是 volatile ,所以會產生類次下面這樣的代碼

{
    int temp1, temp2;
    temp1 = *a;
    temp2 = *a;
    return temp1 * temp2;
}

由於 *a 可能被意想不到的改變,所以 temp1 和 temp2 可能是不同的,導致返回的不是平方值。

22. 用預處理指令 #define 聲明一個常數,用以表明一年中有多少秒

#define SECONDPERYEAR (60*60*24*365UL)

23. bunch of question

  1. 一個整型數(An integer)
  2. 一個指向整型數的指標(A pointer to an integer)
  3. 一個指向指標的的指標,它指向的指標是指向一個整型數(A pointer to a pointer to an integer)
  4. 一個有10個整型數的陣列(An array of 10 integers)
  5. 一個有10個指標的陣列,該指標是指向一個整型數的(An array of 10 pointers to integers)
  6. 一個指向有10個整型數陣列的指標(A pointer to an array of 10 integers)
  7. 一個指向函數的指標,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer)
  8. 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整型參數並返回一個整型數(An array of ten pointers to functions that take an integer argument and return an integer)
int p;
int* p;
int** p;
int p[10];
int *p[10];
int (*p)[10];
int (*p)(int);
int (*p[10])(int);

24 實作一個矩陣相乘的 function

Some problem

關鍵字static的作用是什麼?
這個簡單的問題很少有人能回答完全。在C語言中,關鍵字static有三個明顯的作用:

  1. 在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。
  2. 在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。
  3. 在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。
     
    大多數應試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個應試者的嚴重的缺點,因為他顯然不懂得本地化數據和代碼範圍的好處和重要性。

下述程式碼行為

#include <stdio.h>

int foo(int x, int n)
{
    int val = 1;
    while (n) {
        if(n%2 == 1) val = val * x;
        val = val * foo(x*x, n/2);
        n /= val;
    }
    return val;
}
  • pow(x, n)

問輸出

int main(void) 
{
    char src[] = "Hello world!";
    char dst[20];
    
    strncpy(dst, src, sizeof(dst));
    printf("%ld\n", strlen(dst));
    memcpy(dst, src, 5);
    printf("%ld\n", strlen(dst));
    strncpy(dst, src, 5);
    printf("%ld\n", strlen(dst));

    return 0;
}
  • %ld 輸出 long 整數

Ans

12
12
12

問輸出

#include <stdio.h>

int main(void) 
{
    int i = 10, j = 0;
    while(i-- != 0) {
        j++;
    }
    printf("%d", j);
    return 0;
}

問輸出

#include <stdio.h>

int main(void) 
{
    int A = 26;
    if(A & 0xF > 0x8)
        printf("MORE %d", A & 0xF);
    else
        printf("LESS %d", A & 0xF);
    return 0;
}
LESS 10
  • > 比 & 優先

輸入 n 印出 n 層的直角三角形

#include <stdio.h>

int main(int argc, char* argv[]) 
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n ; i++) {
        for(int j = 0; j < 2 * i + 1 ; j++) {
            printf("*");
        }
        printf("\n");
    }
    
    return 0;
}

不使用運算子 sizeof 算出結構大小

#include<stdio.h>
struct ABC {
	int a;
	float b;
	char c;
};

int main() {
    struct ABC a;
    printf("size = %d\n", sizeof(struct ABC));
    printf("alignof = %d\n", __alignof(struct ABC));
    printf("my method = %p\n", &a);
    printf("my method = %p\n", (struct ABC*)(&a+1));
    printf("ans = %d\n", ((int)(&a+1) - (int)&a));
    return 0;
}

實戰

1. stdio.h -> <\stdio.h> 在哪一步發生

  • pre process
  • linker
  • compile
  • execution

2. a=?

#undef CHIP1
#define CHIP2 1200
#define OPT1 100
#define OPT2 200
#undef OPT1

int a = 0;

#ifdef CHIP1
#if define (OPT1)
#if OPT1 > 100
a+=1;
#else
a+=2;
#endif
#elif define (OPT2)
#if OPT2 > 100
a+=3;
#else
a+=4;
#endif
#else
a+=5;
#endif
#else
#ifdef (OPT1)
#if OPT1 > 100
a+=6;
#else
a+=7;
#endif
#if OPT2 > 100
a+=8;
#else
a+=9;
#endif
#else
a+=10;
#endif
#endif

3. output?

  • 題目大概就是一堆 dereference 詳細長怎樣忘了
int a = 2;
int b = 4;
int c = 8;

int* arr1[] = {&a, &b};
int* arr2[] = {&b, &c};
int (*arr[2])[2] = {&arr1, &arr2};

printf("%d %d", *(*arr[0]++), *(*(**arr[0]+1)+1)

寫 code 題

  1. 不用 sizeof 算出 struct 的大小

  2. 數字一個一個丟進來 (沒有 sort) 輸出每次的中位數