# 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: `工作`