###### tags: `INFO2021`
{%hackmd BJrTq20hE %}
# 資訊科技產業專案設計課程作業 4
>貢獻者 : 高爾夫
## [NVIDIA : GPU Firmware Engineer (RDSS Intern)](https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite/job/Taiwan-Taipei/GPU-Firmware-Engineer--RDSS-Intern-_JR1946076-1)
### Job Description
* Develop, test, debug, and optimize GPU firmware and boot software throughout the entire GPU family lifecycle
* Design and implement SW tool applications built for GPU firmware support and various mainstream OS
* Collaborate with hardware, software, and business teams to transform new firmware features from idea to reality
* Interact with leading OS and PC vendors to improve and innovate on the startup experience
* Improve team software process and core infrastructure via projects dealing with build systems and regression farms
* Continuously evaluate and improve security for firmware and tools
### 分析職務
#### 需要的能力
1. C 語言開發能力
2. 對於作業系統有一定的認識與了解
3. 了解 x86 指令集與計算機架構
4. 有閱讀過 DP, HDMI, VGA 等規格書
#### 自我檢視
1. 對於 C 語言操作算是熟悉
2. 作業系統常見的 issue 已經有充分掌握
3. 沒有接觸過 x86 指令集
4. 沒有閱讀過顯示相關的規格書
### 上機考 ( 實際經驗 2021 / 11 / 25 )
總共有 12 題,其中 1 題是中翻英。沒列出來的是題目忘記了。
#### 第一題
##### 題目描述
Give a C code example of stack overflow
##### 回答
```C=1
#include <stdio.h>
int main()
{
while(1){
int x = 1; // stack overflow
}
return 0;
}
```
#### 第二題
##### 題目描述
volatile 跟 const 可以同時使用嗎 ?
##### 回答
可以,volatile 是使不讓編譯器最佳化,確保 cache 裡面的資料可以跟 memory 當中的資料一致。cost 則是在說明變數只能讀,而不能去改寫。因此兩個不衝突,可以同時使用。
#### 第三題
##### 題目描述
Give a C code example of pointer to pointer
##### 回答
```C=1
#include <stdio.h>
void fun(**int p)
{
*p = (int*) malloc(sizeof(int));
**p = 10;
}
int main()
{
int v = 0;
int *p = &v;
fun(&p);
printf("v is %d", v); // v = 0
printf("*p is %d", *p); // *p = 10
return 0;
}
```
#### 第四題
##### 題目描述
解釋 Process 跟 Thread
##### 回答
Process 是使用硬體的基本單位,一個 Process 當中可以有很多 Thread;Thread 則是使用 CPU 的基本單位,再同一個 Process 下的 Thread,可以共享全域變數、硬體資源等。
#### 第五題
##### 題目描述
解釋 Virtual memory, DMA, Interrupt, Context switch
##### 回答
***1. Virtual Memory***
Virtual Memory 是只將 Process 裡面的內容先放進 Disk 裡面,當要使用時,會觸發 Page Fault ,再將資料放進去 Memeory 當中,這種方法可以同時將大量的 Process
***2. DMA***
DMA 是指硬體可以直接對 Memory 進行讀寫,而不用透過 CPU 的幫忙,因此可以讓 CPU 做其他的計算,而不是一直在進行搬資料的動作
***3. Interrupt***
Interrupt 可以分成三種。首先是 External Interrupt,當 IO 完成時,會發出此 Interrupt;再來是 Internal Interrupt,這是當程式有錯誤時會發出的 Interrupt,像是除以 0 這類的錯誤;最後是 Software Interrupt,這是當使用到 System call 時會發出的 Interrupt。
整體流程:收到 Interrupt --> 將目前的 Process 暫停,並存到 PCB --> 從 Interrupt vector 去找對應的 Interrupt ID --> 執行 ISR --> 回去執行暫停的 Process
***4. Context Switch***
會給每個 Process 一段時間去執行,當時間到就會發出 Interrupt 去進行 Context Switch ,會另一個 Process 執行。透過 Context Switch 可以達到 Time - sharing 的成果。
#### 第六題
##### 題目描述
給單向 Linklist ,裡面只包含 `0 and 1` ,可視為一個二進制之數字,請回傳轉換成 10 進位的結果。
##### 回答
```C=1
int decimal(LinkNode *head){
if(!head) return -1;
int result = 0;
while(head){
result = result << 1 + head->val;
head = head->next;
}
return result;
}
```
#### 第七題
##### 題目描述
假設 1 月 1 號是禮拜二,二月有 28 天,請問 6 月份裡禮拜二的日期是多少?請用 C 語言實作。
##### 回答
```C=1
#include <stdio.h>
int main()
{
int months[] = {31, 28, 31, 30, 31};
int start = 2;
for(int i = 0; i < 5; i++){
start += months[i] % 7;
if(start > 7) start -= 7;
}
for(int i = 1; i < 31; i++){
if(start > 7) start -= 7;
if(start == 2) printf("6 / %d is thesday", i);
}
return 0;
}
```
### 面試問題 ( [參考](https://www.pttweb.cc/bbs/Tech_Job/M.1612848862.A.6D2) )
***Interviewer***
如果硬體不支援乘法,那 $x = y * 200$ 要怎麼改才能得到正確答案 ?
***Interviewee***
問題是不支援乘法,那加減支援嗎?
***Interviewer***
可以支援
***Interviewee***
了解,那我想可以使用 `bit operator` 去解決這個問題。首先可以知道
$200=2^3*5^2=2^3*(2^2+1)^2=2^3*(2^4+2^3+1)=2^7+2^6+2^3$
```C=1
int fun(int y){
int x = 0;
x = y << 7 + y << 6 + y << 3;
return x;
}
```
***Interviewer***
寫一個 DFS 演算法,自己設計節點跟使用情境
***Interviewee***
DFS 是深度優先搜尋的演算法,可以透過 Stack 去實現這個演算法,那我這邊想要舉迷宮的例子。
```C=1
#include <iostream>
#include <vector>
using namespace std;
int n,m;
vector<vector<int>> maze;
vector<vector<int>> best_path;
vector<vector<int>> temp_path;
void dfs(int i,int j)
{
if(i<0||i>=n||j<0||j>=m||maze[i][j]==1)
{
return;
}
maze[i][j]=1;
temp_path.push_back({i,j});
if(i==n-1&&j==m-1)
{
best_path=temp_path;
}
dfs(i-1,j);
dfs(i+1,j);
dfs(i,j-1);
dfs(i,j+1);
maze[i][j]=0;
temp_path.pop_back();
}
int main()
{
while(cin>>n>>m)
{
maze=vector<vector<int>>(n,vector<int>(m,0));
best_path.clear();
temp_path.clear();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>maze[i][j];
}
}
dfs(0,0);
for(vector<vector<int>>::iterator
it=best_path.begin();it!=best_path.end();it++)
{
cout<<'('<<(*it)[0]<<','<<(*it)[1]<<')'<<endl;
}
}
return 0;
}
```
***Interviewer***
實作一個 function,參數是 32-bit integer,回傳共有幾個 bits 是 1
***Interviewee***
```C=1
int count1bits(int x){
int count = 0;
while(x){
count++;
x = x & (x - 1);
}
return count;
}
```
## [Realtek : Android TV軟體設計工程師M2](https://recruit.realtek.com/zh/index.php?option=com_content&view=article&id=10341)
### Job Description
* 從事 TV 相關的軟體設計
* 需要出差 On Site Support
* TV 相關軟體的問題分析與解決
### 分析職務
#### 需要的能力
1. C 語言開發能力
2. 熟悉 Linux 環境
3. Linux or Android 應用程式開發經驗
4. 有 TV 軟體開發經驗
#### 自我檢視
1. 對於 C 語言操作算是熟悉
2. 有在 Linux 環境開發演算法經驗
3. 沒碰過 Android 相關議題
4. 沒有 TV 相關經驗
### 部門細節
#### 工作時間與錢錢
1. 工時長,平均 11 ~ 12 小時
2. 不用打卡,責任制
3. 分紅一年兩次 ( 10 月與過年 )
4. 保 13 個月,平均領 20 個月
5. TV 部門約佔 10 % 瑞昱總營收 ( 警訊 ? )
#### 工作總類
1. 繪圖相關 ( GPU 的相關底層應用 ) 部門代號 M2
2. 顯示 SoC 晶片 ( V - sink )
3. 顯示轉換晶片 ( Displayport to HDMI ) 多用到 Linux
4. OS 相關驅動
5. TV 開機啟動
### 白板題 ( 實際經驗 2021 / 11 / 17 )
主管會給一個 google docs 連結,題目已經在上面,依照要求改 Code
#### 第一題 ( 基礎暖身 )
```C=1
int x = 10;
int y = 11;
int temp;
// 請實作 swap 功能
temp = x;
x = y;
y = temp;
```
#### 第二題 ( 指標 ) 請回答顯示出來的答案
```C=1
char arr[] = "0123456789";
char *p = arr;
printf("%d\n", strlen(arr)); // 10
printf("%d\n", sizrof(arr)); // 11
printf("%d\n", sizeof(p)); // 4
```
#### 第三題 ( 指標的指標 ) 找出錯誤並修改
***Before***
```C=1
int gint = 0;
void changePtr (int *pInt)
{
pInt = &gint;
}
void main ()
{
int local_int = 1;
int *localPtr = &local_int;
changePtr (localPtr);
printf ("%d\n", *localPtr); // 1
}
```
***After***
```C=1
int gint = 0;
void changePtr (int **pInt)
{
*pInt = &gint;
}
void main ()
{
int local_int = 1;
int *localPtr = &local_int;
changePtr (&localPtr);
printf ("%d\n", *localPtr); // 0
}
```