---
# System prepended metadata

title: Software Interview Note
tags: [工作]

---

# Software Interview Note

[TOC]

## **作業系統**

### **Program**
Program 為軟體工程師所寫的程式碼 (code) 的集合，也就是還**尚未 load 進記憶體**的程式碼，存放在次級儲存裝置 (Secondary storage)。

### **Process**
Process 為**已經執行且 load 到記憶體**中的 Program，process中的每一行程式碼隨時都有可能被 CPU 執行。

每一個 Process 由下面兩項組成：
* 一個*Memory Space*。相當於 Object 的 variable，不同 Process 的 Memory Space 也不同，彼此看不到對方的 Memory Space。
* 一個以上的*Thread*組成。

`Process 是電腦中已執行 Program 的實體，每一個 Process 互相獨立。`
`Process 不是基本執行單位，而是 Thread (執行緒) 的容器。`

### **Thread** 
Process 是 Thread 的容器，在同一個 Process 中會有很多個 Thread，每一個 Thread 負責某一項功能。

每一個 Thread 由下面兩項組成：
* Stack：紀錄從某個起始點開始 (例如main)，到目前為止所有函數的呼叫路徑，以及在這些呼叫路徑上所用到的區域變數。
* 紀錄 CPU 內部的暫存器 (如 Program Counter, Stack Pointer, Program Status Word 等) 的狀態。

在多執行緒中 (Multithreading)，兩個執行緒若同時存取或改變全域變數 (Global Variable)，可能會發生同步 (Synchronization) 問題。若執行緒之間互搶資源，則可能產生死結 (Deadlock)，如何避免 (Prevent) 或預防 (Avoid) 上述兩種情況的發生，仍是作業系統 (OS) 所關注的。

* `Thread 是系統處理工作的基本單元。`
* `一個 Process 底下的 Thread 共享資源，如記憶體、Global Variable 等，不同的 Process 則否。`
* `OS 會根據 Thread 的優先權以及使用過的 CPU 時間，切換不同的 Thread。`
* `同一個 Process 內的 Thread 使用相同的 Memory Space，但這些 Thread 各自擁有其 Stack。換句話說，Thread 能透過 reference 存取到相同的 Object，但是 local variable 各自獨立。`

### **Multi-processing v.s. Multi-threading**

#### **Multi-processing**
多個 Process 在執行，彼此有各自的資料空間，若有資料需要共用，必須採用特別的方法來傳遞。
* 相同的工作在比較短的時間內完成 
* 由於每個 Process 都需要一些資源來工作，所以 Multi-process 會比 Multi-thread 更**消耗資源**
#### **Multi-threading**
一個 Process 裡有多個執行緒在執行，彼此共用相同的資料空間。
* 相同的時間內完成較多的工作
* 同一Process下的threading之間也能夠擁有彼此獨立的資源
* std::thread in C++

## **Linux**

### **Linux kernel**
一個作業系統中最早被啟動的東西，他包含了所有可以讓硬體與軟體工作的資訊。

### **Critical section**
一個存取共用資源的程式片段，而這些共用資源有無法同時被多個執行緒存取。
`mutual exclusion`：若執行緒在執行「critical section」，其它執行緒都不該進入它們的「critical section」。

### **Mutex v.s. Semaphore**
確保多個執行單元運作並存取資源時，執行結果不會因為執行單元的時間先後的影響而導致錯誤。


:::    success
理論上，應該要先跟面試官互動，詢問一下其所謂的差異是指哪個部份 (實作、用途、還是結構？)，以及詢問這個問題時，想要將兩者應用在那邊，對於後續的回答會有所幫助。
:::

* 30秒：最大的差異在於 Mutex 只能由上鎖的 thread 解鎖，而 Semaphore 沒有這個限制，可以由原本的 thread 或是另外一個 thread 解開。另外，Mutex 只能讓一個 thread 進入 critical section，Semaphore 的話則可以設定要讓幾個 thread 進入。這讓實際上使用 Mutex 跟 Semaphore 場景有很大的差別。

* 60秒 (cont.)：舉例而言，Mutex 的兩個特性：一個是只能有持鎖人解鎖、一個是在釋放鎖之前不能退出的特性，讓 Mutex 常使用在 critical section 只能有一個 thread 進入，而且要避免 priority inversion 的時候；Semaphore 也能透過 binary semaphore 做到類似的事情，卻沒有辦法避免 priority inversion 出現。

* 120秒 (cont.)：而 Semaphore 更常是用在同步兩個 thread 或功能上面，因為 Semaphore 實際上使用的是 signal 的 up 與 down，讓 Semaphore 可以變成是一種 notification 的作用，例如 A thread 執行到某個地方時 B thread 才能繼續下去，就可以使用  Semaphore 來達成這樣的作用。

## **Object Oriented Programming**
### **封裝 (Encapsulation)**
將物件內部的資料隱藏起來，只能透過物件本身所提供的介面(interface)取得物件內部屬性或者方法。
### **繼承 (Inheritance)**
在某種情況下，一個類別會有「子類別」。子類別比原本的類別(稱為父類別)要更加具體化，也就是說子類別繼承了父類別。
### **多型 (Polymorphism)**
多個相同名稱的方法，傳入不同的參數，會執行不同的敘述，包含Overloading及Overriding。
* Overloading：相同類別中，定義名稱相同，但是參數個數不同，或是參數型態不同的函式。
* Overriding：覆寫掉父類別中的函式
* Virtual：不強制子類一定要實作，子類不實作的話會以父類的實作為主，子類實作的話會以子類的實作為主

## **Programming**
### **extern**
告訴 compiler 這個變數的存在，但是並不是由source file做宣告，而是由include source file的檔案宣告。

### **Static**
<font color="#0072E3">1. Static出現在variable之前，且該variable宣告在某個function之中</font>
在variable前加上static，則此variable不會在function消失後消失。

<font color="#0072E3">2. Static出現在variable之前，且該variable不是宣告在某個function之中</font>
此處static的用意是讓這樣的global只限定在該檔案內，而不是整個程式中。

<font color="#0072E3">3. Static出現在class的member variable/function之前</font>
此處static的用意是指該variable/function不屬於某個instance，他屬於這個class，所有以此class生成出來的instance都共用這個variable/function。

### **inline**
編譯時便會把函數中的程式直接展開，而不是跳至函數的記憶體位置處理。常用於函數中的程式碼或處理較短，並且常呼叫使用。

### **Macro**
巨集，前置處理器語言定義之內容，如:
```javascript= 
#define min(a,b) ((a)<(b)?(a):(b))
```
```javascript= 
#define add(a,b) a+b

add(10,5)*5    // = 10 + 5 * 5 = 35
```

### **Volatile**
加在變數前面。是在指示編譯器每次對該變數進行存取時都要「立即更新」，不應該對其做任何最佳化，可以跟const及pointer一起使用。

### **Template**
宣告出通用函式，如
```javascript= 
#include <iostream>

template<typename T, typename V>
T fun(T a, V b) {
	return a + b;
}

int main(){
    
    int a = 10;
    float b = 5.5;
    
    cout << fun(a,b) <<endl;    // 15
    cout << fun(b,a) <<endl;    // 15.5
    
    return 0;
}
```

### **nullptr** 
空指標，可以視為指向所有型別的指標

## **演算法**

### **Merge Sort**
```javascript=
void merge(vector<int>& v, int front, int mid, int end) {
	vector<int> leftSub(v.begin() + front, v.begin() + mid + 1),
		rightSub(v.begin() + mid + 1, v.begin() + end + 1);

	leftSub.insert(leftSub.end(), MAX);
	rightSub.insert(rightSub.end(), MAX);

	int indexL = 0, indexR = 0;

	for (int i = front; i <= end; i++) {

		if (leftSub.at(indexL) < rightSub.at(indexR)) {
			v.at(i) = leftSub.at(indexL);
			indexL++;
		}
		else {
			v.at(i) = rightSub.at(indexR);
			indexR++;
		}
	}
}

void mergeSort(vector<int>& v, int front, int end) {
	if (front < end) {
		int mid = (front + end) / 2;
		mergeSort(v, front, mid);
		mergeSort(v, mid + 1, end);
		merge(v, front, mid, end);
	}
}
```

###### tags: `工作`
