###### tags: `JavaScript 學習紀錄`
# Interview Questions
## HTML & CSS
- **什麼是 semantic HTML?**
- 使用HTML標記向瀏覽器和開發人員描述它的含義
```javascript=
// non-semantic elements: Tells nothing about its content.
<div> and <span>
// semantic elements: Clearly defines its content.
<form>, <table>, and <article>
```
- **什麼是 box model? CSS 中的 box-sizing 又是什麼?**
- box model: 所有的 HTML elements都可以被想像成一個box, 且box model描述box的design和layout

- **display: inline 和 display: block 的差異?**
- display: inline-> element寬高是多少就是多少,不佔據一整行
- display: block-> element佔據一整行
- **display: none 和 visibility: hidden 的差異?**
- display: none -> 瀏覽器畫面上隱藏, 並且不佔位置
- visibility: hidden -> 瀏覽器畫面上隱藏, 但佔位置
- **div 和 span 的差異?**
- div -> 佔據一整行,有margin可用
- span -> 不佔據一整行,且沒有margin可用
- **px, em, rem 的差異?**
- px -> 絕對單位,代表螢幕中每個「點」( pixel )
- em -> 相對單位,每個子元素透過「倍數」乘以父元素的 px 值
- rem -> 相對單位,每個元素透過「倍數」乘以根元素的 px 值
- % -> 相對單位,每個子元素透過「百分比」乘以父元素的 px 值
- **試著說明 flex box 的用法**
```css=
display: flex;
flex-direction: row|column;
justify-content: start|center|end|space-between | space-around;
align-items: stretch (將內容元素撐開至 flexbox 大小)|flex-start|center|flex-end|space-between|space-around| baseline (對齊內容物的基線) (適用於單行容器);
align-self: 針對align-items的個別item做設定;
align-content: stretch (每行內容元素全部撐開至 flexbox 大小);
|center|flex-start|flex-end|space-between|space-around; (無法用於flex-wrap: no-wrap容器)
```
- **試著說明 cascade 和 specificity**
- cascade (串接)-> cascade 會使用各元素上屬性的 declared value 的無序列表,透過下面所述的 Cascading 流程,以宣告的優先度從高到低進行排序,並輸出一個 cascaded value:
1. Origin and Importance
2. Specificity
3. Order of Appearance
- specificity (明確度)-> 定義css時,彼此間元素鎖定衝突的情況,則由明確度(權重)決定, 明確度相同由後者決定, 明確度不同由明確度較高者決定
1. 行內定義的css => 1,0,0,0
2. id => 0,1,0,0
3. class => 0,0,1,0
4. html元素和虛擬元素 => 0,0,0,1
- CSS preprocessor:
- 像是LESS, CSS有巢狀結構或變數繼承, preprocessor可以轉成純CSS, 方便管理
## JavaScript
- **null 和 undefined 的差異?**
- null -> 有宣告一個value, 只是這個value是null(空), typeof 是 false
- undefined -> 有宣告一個value記憶體位置, 但這個記憶體位置沒assign值, typeof 是undefind
- **什麼是 NaN?在什麼情況下會出現 NaN?如何偵測變數中的資料是 NaN?**
```javascript=
NaN -> not a number
當用非數字做運算時會出現NaN
// isNaN() 函式-> 判斷某個數值是不是 NaN, 會強制將參數轉換成數字, 你可能會想改用在 ECMAScript 6 導入的 Number.isNaN()、或是用 typeof 來判斷某個數值是不是「非數字」(Not-A-Number)。
isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false, 會先轉成數字在判斷
isNaN('Hello') //true, 無法轉成數字的就會是true
isNaN('2005/12/12') //true, 無法轉成數字的就會是true
isNaN('') //false, 會先轉成數字在判斷
isNaN(true) //false, 會先轉成數字在判斷
isNaN(undefined) //true, 無法轉成數字的就會是true
isNaN('NaN') //true, 無法轉成數字的就會是true
isNaN(NaN) //true, 無法轉成數字的就會是true
isNaN(0 / 0) //true, 無法轉成數字的就會是true
// Number.isNaN() 函式-> 確定傳遞的值是否為NaN和其類型是Number, 它是原始的全局isNaN()的更強大的版本
Number.isNaN(123) //false
Number.isNaN(-1.23) //false
Number.isNaN(5-2) //false
Number.isNaN(0) //false
Number.isNaN('123') //false
Number.isNaN('Hello') //false
Number.isNaN('2005/12/12') //false
Number.isNaN('') //false
Number.isNaN(true) //false
Number.isNaN(undefined) //false
Number.isNaN('NaN') //false
Number.isNaN(NaN) //true, 是isNaN()加強版, 只有NaN與不是數字的數字才會是true
Number.isNaN(0 / 0) //true, 是isNaN()加強版, 只有NaN與不是數字的數字才會是true
```
- **解釋 Primitive 和 Reference Data Type 的差別?**
- js可以自動garbage collection回收記憶體位置
```javascript=
// Primitive: 原始型態(非物件)
Primitive Type 又可以再細分成六種:
undefined
null:typeof是object但又是call by value
string
number
boolean
symbol (ES6): 很少使用
// Object: 物件型態
而非以上六種的類型,就是物件類型 Object Type :
Function
Array
Date
```
- **使用 var, let, const 宣告變數有什麼差別?**
```javascript=
// var -> 宣告的scope是屬於函數內的, 且可以重複宣告, 如:
function printV3(){
if(true) {
var v = 2
}
console.log(`printV3:`, v)
}
printV3() // => pritnV3: 2
function printV2(){
var v = 2
var v = 3
var v = 4
console.log(`printV2:`, v)
}
printV2() // "printV2:" 4
// let -> 宣告的scope較var小是屬於block內的, 不可以重複宣告, 但可被覆蓋
function printL3(){
if(true){
let l = 3 // 宣告在block內
}
try {
console.log(`printL2:`, l)
} catch {
console.log(`can't find l in printL3`) // 在block就抓不到value
}
}
printL3() // => can't find l in printL2
// const -> 常數, 宣告的scope與let相同在block內,不可重複宣告也不可被覆蓋
```
- **什麼是 Closure?能否舉例說明?**
- 閉包 (Closure): 是一種函式, 此函式可以存取外層變數,以及函式可以作為回傳值, 進而「保留」環境。
```javascript=
// example1
function sayHi() {
let name = "John";
function displayName() {
console.log(name);
}
displayName();
}
sayHi();
// example2
function makeSayHi() {
function sayHi() {
console.log("John");
}
return sayHi;
}
const sayHi = makeSayHi();
sayHi(); // John
// example3
function makeFunc() { // 1
let name = "John" // 2
function displayName() { // 3
console.log(name);
}
return displayName; // 4
}
let func1 = makeFunc(); // 5
func1();
// 在JavaScript中,即使在外層區塊已經回傳的狀況下,只要內層區塊還保留著一份參考,那麽外層區塊的環境不會隨著回傳而消失,我們依然可以存取外層環境中的變數。
// 以這個例子來說,雖然 makeFunc() 回傳了,但是因為我們還保留著一份 displayName 的參考(存在 func1 變數裡),所以 JavaScript 會在記憶體中為我們繼續保留 displayName 所在的環境,包含 name 變數等,所以我們可以繼續存取 name 變數。
```
- **試說明 hoisting 的現象?**
- hoisting(提升):先宣告再執行, 幫你留位子的意思
Javascript 在執行任何程式碼之前,先把宣告的變數和函式放進記憶體空間裡,就像是事先幫他們留個位子的感覺。
- undefined 跟 is not defined 是不一樣的錯誤,undefined 的意思是「我不知道他的值是多少」,is not defined 是「未宣告」的意思,Javascript 給已宣告未賦值的變數或是函數的預設值都是 undefined
```javascript=
//example
var a;
console.log(a); // undefined
a = 1;
//example
callMe('emma'); // hello emma
function callMe(name){
console.log('hello '+name);
}
// example
console.log(myName); // undefined
myName('emma'); // myName is not a function
var myName = function(name){
console.log('i am + name);
}
```
- **什麼是 this?**
- 參考: https://hackmd.io/@Emmacheng/HkOP_dNPq
- **什麼是 pure function?**
- 將相同的輸入丟入,永遠都會回傳相同的輸出,並且不對任何該函數以外的任何作用域產生影響
- **什麼是 higher-order function?**
- input是函式 or 輸出是函式的function稱作higher-order function
- **什麼是非同步?如何運用 callback 或 promise 或 async/await 包裝非同步程式?**
- 同時可以做很多件事情,不需要等到前一件事情做完才做下一件事情
```javascript=
// async/await
const getApiToken = async () => {
const token = await api.finMindLogin();
return token;
};
// promise
const signIn = (email, password) => new Promise((resolve, reject) => {
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
const { user } = userCredential;
resolve(user);
}).catch((error) => {
reject(error.code);
});
});
```
- **有寫過箭頭函式嗎?箭頭函式和其他函式的寫法除了語法之外,還有什麼差異?(特別是 this 的差異)**
- arrow function的this指的是父層的this
- **解釋一下你對原型鍊的理解?**
- 指的是Prototype, 用以繼承函式與屬性
- **== 和 === 的差別?**
- ==: 轉成同一類型後的值" 看"值" 是否相等
- ===: type不同就不同
- **請解釋 deep copy 與 shallow copy 的差異?**
- deep copy: 原始物件資料與複製物件資料「完全獨立」,沒有任何一層資料指向相同的地址。
- shallow copy: 原始物件資料與複製物件資料「並非完全獨立」,可能第一層就有指向相同地址的資料,也可能第二層才有指向相同地址的資料。
## Browser & Network
- **試說明事件傳遞(event propagation)的流程?**
- 先捕獲(CAPTURING_PHASE),再冒泡(BUBBLING_PHASE)

- **試說明事件物件(event object) target 和 currentTarget 的差別**
- e.currentTarget:指的是綁監聽事件的物件
- e.target:指的是實際觸發事件的物件
- **什麼是 RESTful API,能否分享你串接 RESTful API 的經驗?**
- 語義化的API能看出要對什麼資料、進行什麼操作 (ex: get, post, put, delete)
- **HTTP 和 websocket 有什麼不一樣?**
- websocket: 瀏覽器和伺服器只需要完成一次交握,兩者之間就可以建立永續性的連接,並進行雙向資料傳輸。
- HTTP: 是單向傳輸, client發出request, server回response, 不支持永久連接
- **什麼是 cookie?試說明 cookie 的運作方式?**
- 儲存在使用者電腦上的小檔案,協助儲存所造訪網頁上的偏好和其他資訊
- **什麼是 web storage?和 cookie 有什麼差別?**
- web storage有兩種:sessionStorage 與 localStorage
- cookie → 可設定失效時間,預設式瀏覽器關閉失效 / 容量4k / 佔網路流量 會被攜帶在http中與Sever 溝通
- sessionStorage → 瀏覽器或單一分頁分頁關閉就會清除 / 容量5mb / 不參與Sever 溝通
- localStorage → 不會過期,手動清除 / 容量5mb / 不參與Sever 溝通
- 補充:
- sessionStorage: 在新分頁或新視窗中開啟連結時,用戶端程式將會為新開啟的視窗建立一個新會期(session),每一個會期代表一組獨立的可用資源。而 sessionStorage 就是歸屬於會期管理的資料項目。這表示每個視窗都會有自己的 sessionStorage ;不同視窗的 sessionStorage 就是不同的內容。另一方面,當網頁視窗關閉時,表示這個會期結束了,故此會期內的 sessionStorage 也會被刪除。使用者下次再開啟此網頁時,sessionStorage 的內容將會重新開始。就此特性來看,sessionStorage 只適合用於儲存暫時性資料
- localStorage: localStorage 的持續時間與存在範圍與 Cookie 類似。它的持續時間由程序員自行指定,不會隨著瀏覽器關閉而自動終止。它的存在範圍遵循相同來源政策(The Same Origin Policy),同一個網站的所有網頁都會使用同一個 localStorage
- event delegation好處與限制?
- 好處:將事件綁在parent就不用把事件綁在每個child上, 減少事件綁定
- 限制:如果child停止傳遞就無法使用了
- stopPropagation 或 stopImmediatePropagation?
- 前者只會防止目前 Dom Tree 的上一層事件,後者則是會防止全部 Dom Tree 事件
```javascript=
$("p").click(function(event){
event.stopPropagation();
});
$("p").click(function(event){
alert('test');
});
$("div").click(function(event){
alert('test');
});
// 執行過後,你會發現點選該區域只會跳出一個 alert 視窗,如果把 event.stopPropagation() 換成 event.stopImmediatePropagation() 則完全不會跳出 alert 視窗。
```
- **如何知道一個語法功能否相容於所有瀏覽器?如何處理跨瀏覽器的問題?**
- 用 can i use查詢語法支援的瀏覽器及版本: https://caniuse.com/
- 補充: Babel、CSS preprocessor(可以針對不同瀏覽器幫你添加前綴詞,並巢狀編寫CSS,使用變數,函數,for 迴圈、判斷式…等JS的語法)
- **試著說明從瀏覽器上輸入網址並搜尋會發生什麼事?**
- 對瀏覽器server發出request, 然後server回response且瀏覽器解析
## React
- **什麼是 virtual DOM?**
- Virtual DOM,中文翻譯叫做虛擬 DOM,顧名思義,他不是一個真正的 DOM, 是一個 JavaScript 的物件,存在在 memory 當中, 前端框架在設計與實作上,會先將原本的 DOM 結構複製一份出來,但不會完整複製 DOM 當中的所有資訊。每當有事件產生,或是資料變動的時候,前端框架會先建立一個新的 virtual DOM,接著,計算出新舊 virtual DOM 之間的差別,最後才會操作真正的 DOM,並僅僅操作有變動的部分,藉此避免不必要的 reflow 或 repaint 以提升效能, **而這個過程就叫reconciliation**「和解」或「調停」、「重新建立關係」的意思。
- **試說明 props 和 state 的差異?**
- props是父層傳給子層的value
- state是component內暫存value
- **試說明 class component 的生命週期?**
1. Mount:初始化階段(只執行一次)
- constructor
- getDerivedStateFromProps
- render
- componentDidMount
2. Update:組件更新階段
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
3. Unmount:組件卸載階段(只執行一次)
- componentWillUnmount
- **什麼是 props drilling?如何解決這樣的問題?**
- 曾曾曾祖父的值要傳到孫子, 需要一直傳下去
- 用useContex provider state 給所有子層或子孫曾都可以使用到values, 不用靠props一層層傳下去


- **什麼是 react router 嗎?react router 是想解決什麼樣的問題?**
- 路由
- 實現SPA:
- 把所有資料都放在同一個頁面,**不需要換頁**,使用者可以在單一頁面裡瀏覽全部內容,也就是說只會有一個index.html 檔
- 透過 AJAX 技術,client 可以向 server 發出非同步請求,索取局部內容的資料進行抽換,降低每次請求與回應的資料量,提高瀏覽速度
- **有使用過任何 react 相關的套件嗎?你如何選擇以及如何使用?**
- canvasJS, 看doc文件使用
- **解釋 useEffect 的用法**
- render component時執行一次, 或是dependence改變再重新執行, 又或是沒有[]時一直執行
- **解釋 useReducer 的用法**
- dispatch action, update state
- **解釋 useCallback 的用法**
- 記住function, 希望function只宣告一次或是dependence改變再重新宣告
- **解釋 useMemo 的用法**
- 記住value, component內有複雜的計算, 希望計算的值只計算一次或是dependence改變再重新計算
- **解釋 memo 的用法**
- 希望render父層的時候子層的component不要render時用memo
- **什麼時候會用到 key? 為什麼需要?**
- 用map render item的時候, 需要標記item讓user可以對item操作
- **context:主要是為了解決props要一層一層傳遞**
- 放在父層, 有使用到的child會re-render
- **react vs react dom**
- react:主要核心功能
- react dom: 實際真的去操作更新 dom
- **useEffect vs useLayoutEffect**
- useLayoutEffect->render->useEffect
- useLayoutEffect: 在render畫面前執行, 實務上是跟有畫面有關的操作才會使用, 會阻擋到畫面的渲染
- useEffect:render畫面後執行
- https://kentcdodds.com/blog/useeffect-vs-uselayouteffect
- module, script, script type=module有什麼差異?
- module: 在module裡面宣告的變數只有module可以用
- script: 裡面的變數全域都可以拿到
- script type=module:
- script type=module只能透過server打開, 不能用http打開
- type=module會自動是stric mode
## Code Quality
- **什麼是 eslint?有沒有設定過 eslint config 的經驗?**
- 解決關於程式碼品質和程式碼風格的問題
- **什麼是 refactor?你怎麼做 refactor?**
- 重構是不影響城市功能的情況下優化程式碼
- 把程式碼做優化重複的code抽出來, function參數控制在3個以內, 讓程式碼好維護好閱讀
- **知道 git flow 嗎?你如何在開發過程中使用 git 做版本控制?**
- 開發流程, master, develop, feature1 2 3, hot-fix
- **git merge 和 git rebase 有何差別?**
- git merge
- pros: 紀錄非常詳盡,有助於了解每次合併發生的方式和時間的完整歷史, 很容易發現錯誤並解決它們
- cons: 導致笨拙的歷史記錄, 不是很人性化

- git rebase
- pros: 紀錄是線性的
- cons: 無法追蹤提交在目標分支上合併的時間和方式

- **怎樣是好的 commit message?如何整理自己的 commit?**
- 清楚描述做的事情
- 盡量清楚描述做的事情, commit要做的事情切乾淨