# 面試常見問題
1.介紹專案做了什麼?
主要負責登入登出註冊、會員中心、linepay
2.有用了什麼套件、遇到什麼困難、問題
主要用了react-route、query、recaptcha、jwt-decode、axios等
困難方面這些套件的用法跟功能等等
3.專案開發遇到那些困難
資料格式、一些語法、邏輯、串接
4.你用過那些hooks
useState、useEffect、useContext
5.介紹一下你用這些hooks
useState用來存狀態、透過裡面改變當前參數的函數來使用
useEffect用2個參數第一個是一個函數第2個用來決定什麼時候調用這個函數
useContext我覺得是最複雜的透過createContext()創建完context物件
並且在Provider中寫好要讓在子組件中可以傳遞的函數,之後包裹在子組件的最外層
就可以不透過Props接取到全域變數
## 專案Context講解
export const JwtCsrfTokenContext = createContext();
export const JwtCsrfTokenProvider = ({ children }) =>{}
export const useJwtCsrfToken = () => useContext(JwtCsrfTokenContext);
可以解釋這3行的邏輯以及相互之間的關係嗎?
這三行程式碼是在 React 中使用 Context API 建立一個全域的狀態管理系統,
用來共享 JWT 和 CSRF token。
createContext() 創建一個 Context 物件,即 JwtCsrfTokenContext,並將其導出 (export)。
JwtCsrfTokenProvider 是一個 React 元件,它是一個 Context Provider。它接受一children參數,
表示 JwtCsrfTokenProvider 的子元件,並使用 Context API 中的 Provider
提供一個名為 JwtCsrfTokenContext 的 Context,
這個 Context 會包含一個名為 jwtCsrfToken 的狀態值和一個更新狀態值的函數 setJwtCsrfToken。
useJwtCsrfToken 是一個自定義的 Hook 函數,
用來從 JwtCsrfTokenContext 中取出狀態值和更新狀態值的函數。
它使用了 Context API 中的 useContext 函數,
這個函數可以取得 JwtCsrfTokenContext 提供的狀態值和函數。
總之, createContext 創建一個全域的 Context,JwtCsrfTokenProvider
提供這個 Context 中的狀態值和函數,useJwtCsrfToken 自定義的 Hook 函數
可以讓元件從 Context 中取出狀態值和函數,方便元件之間共享這些狀態。
所以當我想在其他頁面使用JwtCsrfTokenContext 我必須引入useJwtCsrfToken在其他頁面對嗎?
是的,如果你想在其他頁面使用 JwtCsrfTokenContext 中的資料,
你需要引入 useJwtCsrfToken hook。這樣才能讓其他頁面可以使用 JwtCsrfTokenContext 的資料
並且更新資料。請記得在使用 useJwtCsrfToken 之前,要確保該頁面被 JwtCsrfTokenProvider 包覆。
6.你們怎麼協作的
我們先溝通每個人負責頁面及單獨功能接下來討論功能相通之部分,
大多問題都來自資料表格式問題調整成一樣就沒問題
另外透過gitflow建立各自分支來避免專案產生問題透過在develope上創立各自組員分支最後整合
到develope上
7.你們有遇過衝突?怎麼解決
大部分merge都在develope本地端解決 除了一些重複的依賴項需要手動刪除之外
沒有太大的問題
8.怎麼解決CSS衝突
我們透過設定全域global.style.scss的檔案 某些樣式是唯一的,其他的樣式我們則是加上組員代號
來防止撞名問題
9.你們狀態管理是怎麼處理的
大部分都透useState做處理全站變數則用到useContext
10.資料庫正規劃
沒做
11.CSS權重問題
1.!important:最高優先級
2.行內樣式:style屬性
3.ID 選擇器:#example
4.類別、屬性和偽類選擇器:.example, [type="text"], :hover
5.元素和偽元素選擇器:div, ::before
6.*通用選擇器和相鄰選擇器(+、~):*, h2 + p
12.JS問題 log出什麼
13.Promise
const promise = new Promise((resolve, reject) => {
// 異步操作
// 如果操作成功,調用 resolve(value)
// 如果操作失敗,調用 reject(error)
});
promise.then((value) => {
// 當 Promise 成功完成時調用
}).catch((error) => {
// 當 Promise 失敗時調用
});
## 當使用Promise時,常見的問題和注意事項包括:
必須要處理Promise回傳的狀態,即pending、fulfilled和rejected。
可以使用.then()方法和.catch()方法來處理這些狀態,或是使用async/await來簡化處理過程。
使用Promise時,必須注意避免callback hell,即多層巢狀的.then()方法,
這會導致程式碼難以維護和閱讀。可以使用async/await來解決這個問題,讓程式碼更加清晰易讀。
Promise物件可以被鏈式調用,即在一個Promise物件上使用.then()方法返回一個新的Promise物件,
這樣可以實現多個異步任務的串聯。但要注意,每個.then()方法返回的Promise物件都是一個全新的Promise,
因此不要直接對Promise物件進行操作。
在使用Promise時,必須注意避免綁定過多的回調函數。如果需要多個回調函數來處理異步任務,
可以將它們封裝成一個函數,這樣可以減少代碼量,也更易於維護。
Promise物件具有狀態不可逆的特點,即一旦Promise從pending狀態轉變為fulfilled或rejected狀態,
就不能再改變狀態。因此,在使用Promise時,必須注意處理Promise的錯誤,
避免Promise一旦進入rejected狀態就沒有對應的處理。
使用Promise時,必須注意避免過度依賴Promise,因為Promise並不是萬能的解決方案,
有些異步任務可能需要其他方法來解決。在使用Promise之前,要先仔細分析問題,
確定Promise是最適合的解決方案。
## 以下是一個 Promise 實例的範例,使用 .then() 與 .catch() 處理 Promise 回傳值以及錯誤處理:
```
const myPromise = new Promise((resolve, reject) => {
// 假設這個 Promise 是用來向伺服器發送請求的
// 這邊使用 setTimeout 模擬一個非同步操作
setTimeout(() => {
const response = { status: 200, message: "Request success!" };
resolve(response); // 成功回傳 response
// 若發生錯誤,則使用 reject 回傳錯誤
}, 1000);
});
// 使用 .then() 與 .catch() 處理回傳值與錯誤
myPromise
.then((response) => {
console.log(response.message); // "Request success!"
})
.catch((error) => {
console.log(error); // 若發生錯誤,印出錯誤訊息
});
```
#### 以上 Promise 實例中,我們使用 setTimeout() 模擬一個非同步操作,並在 1 秒後回傳一個 response 物件。使用 .then() 與 .catch() 分別處理成功回傳的 response 與錯誤處理。
### 以下是如何將 Promise 轉成 async/await 方法:
```
async function sendRequest() {
try {
const response = await myPromise;
console.log(response.message); // "Request success!"
} catch (error) {
console.log(error); // 若發生錯誤,印出錯誤訊息
}
}
```
#### 使用 async/await 可以將 Promise 更簡潔的寫法,讓程式碼更具可讀性,上述範例中將 sendRequest() 方法宣告為 async function,並使用 await 等待 myPromise 回傳結果,成功時則直接取用 response 物件,錯誤則由 try-catch 處理。
14.如何提升SEO
SEO(Search Engine Optimization)是指針對搜索引擎優化網站,提高網站在搜索引擎中的排名,
吸引更多的有價值的流量。以下是一些提升SEO的方法:
關鍵詞研究:瞭解目標受眾在搜索引擎上使用的關鍵詞和詞組,以及這些關鍵詞和詞組的搜索量和競爭情況。
優化網站內容:創建有價值的內容,並在內容中使用目標關鍵詞。
確保內容結構清晰,包含標題、段落、列表和圖像等元素,以增加可讀性。
優化網站結構:使用清晰、簡潔的網站結構和內部鏈接,方便搜索引擎爬行和索引網站的內容。
提高網站速度:優化網站速度,減少頁面加載時間,這有助於提高用戶體驗和搜索引擎排名。
優化網站技術:確保網站技術的正確性和可靠性,包括使用正確的HTML和CSS代碼、適當的標籤和元素等。
社交媒體營銷:使用社交媒體平台進行營銷,提高網站知名度和流量。
建立高品質的外部鏈接:通過優質內容和網站,獲得其他網站的外部鏈接,增加網站的權威性和排名。
15.對Vue了解有多深
以下是 Vue 和 React 的一些不同点:
模板语法不同:Vue 使用 HTML 模板,而 React 则使用 JSX。
数据绑定方式不同:Vue 使用双向数据绑定,而 React 使用单向数据流(单向绑定)。
状态管理:Vue 可以使用 Vuex 进行状态管理,而 React 则使用 Redux。
插件和工具:Vue 提供了 Vue Router、Vuex、Vue CLI 等工具和插件,
而 React 则使用 React Router、Redux、Create React App 等。
## 数据绑定方式不同:Vue 使用双向数据绑定,而 React 使用单向数据流(单向绑定)。
以下是一个简单的示例,展示了 Vue 的双向绑定和 React 的单向数据流:
在 Vue 中,你可以使用 v-model 来实现双向数据绑定。例如,假设有一个名为 message 的数据属性,
你可以将它绑定到一个表单输入框上,这样当用户在输入框中输入时,message 的值也会随之改变。
```
<template>
<div>
<input v-model="message" type="text">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: '',
};
},
};
</script>
```
在 React 中,数据流是单向的,因此我们需要通过 props 将数据从父组件传递到子组件。在子组件中,
当用户与它交互时,需要触发一个回调函数并将新的值传递回父组件。父组件可以通过修改自己的 state
来重新渲染子组件,并将最新的值通过 props 传递给它。例如:
```
import React, { useState } from 'react';
function Input({ value, onChange }) {
return (
<input value={value} onChange={e => onChange(e.target.value)} />
);
}
function App() {
const [message, setMessage] = useState('');
function handleInputChange(newValue) {
setMessage(newValue);
}
return (
<div>
<Input value={message} onChange={handleInputChange} />
<p>{message}</p>
</div>
);
}
export default App;
```
16.Vue跟React比較喜歡哪個
17.解釋什麼是closure(閉包)
閉包(Closure)是指在 JavaScript 中,函數可以獲取在它被創建的當前環境中的變量,
即使在它被調用的其他環境中,它仍然可以訪問這些變量。
簡單來說,當一個函數被定義時,它可以訪問其包含執行上下文中的變量,
這些變量可以在該函數的生命週期內一直被引用,而不必擔心這些變量在函數被呼叫後會被銷毀。
這就是閉包的核心概念,它可以使得 JavaScript 中的函數能夠存儲狀態,
並能夠在以後的某個時間點被調用以使用這些狀態。
18.什麼是IIFE
IIFE 是 Immediately Invoked Function Expression 的縮寫,意思是立即調用的函式表達式。
它是 JavaScript 中一種常見的模式,通常用來封裝變量,並且可以為這些變量創建一個私有作用域,
避免污染全局作用域。
(function() {
// 函式內容
})();
19.什麼是EventLoop
Event loop(事件循环)是 JavaScript 异步编程中非常重要的一个概念。
JavaScript 的异步编程模型是基于事件循环机制的。
简单来说,event loop 是 JavaScript 运行时的一种机制,
它会不停地从任务队列中取出任务,执行任务,当任务执行完毕后再去取下一个任务,
直到任务队列中没有任务为止。
在 JavaScript 中,所有的异步任务都是通过事件循环来实现的,例如定时器、事件监听、Promise 等。
当我们创建一个异步任务时,它会被放入一个任务队列中,当任务被触发时,它就会被加入到任务队列的尾部。
然后 JavaScript 引擎会不断地检查任务队列,执行队列中的任务,直到队列为空为止。
Event loop 的作用是实现 JavaScript 的异步编程,它使得 JavaScript 在执行异步任务时不会被阻塞,
可以继续执行其他任务,从而提高 JavaScript 的执行效率。
### 以下是一個簡單的 JavaScript 程序範例,該程式示範了 JavaScript 的事件循環(event loop):
```
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise');
});
console.log('end');
start
end
Promise
setTimeout
```
上面的程式碼中,首先輸出 "start",然後使用 setTimeout 設定一個計時器,等待 0 毫秒,當計時器到期時,
輸出 "setTimeout"。接下來,使用 Promise,使用 then 方法在 Promise 队列中設置一個回調函數,
當 Promise 隊列被清空時,該回調函數將被執行,輸出 "Promise"。最後,輸出 "end"。
由於 JavaScript 是一個單線程的語言,因此必須使用事件循環來處理所有的事件和任務,包括延遲執行的計時器
、Promise 回調函數等。事件循環會從事件隊列中取出一個事件並執行它,然後繼續從事件隊列中取出事件,
直到事件隊列中沒有任何事件為止。在每個事件的執行期間,JavaScript 引擎只會執行該事件的代碼,
不會處理其他事件和任務。因此,JavaScript 是一個非阻塞的單線程語言,它可以快速且高效地處理大量的事件
和任務。
20.什麼是CORS
CORS (Cross-Origin Resource Sharing) 是一種安全機制,用於防止跨來源(即跨域)HTTP請求。
當前的 Web 應用程式通常是使用 AJAX 技術來從其他網站上請求資料。但是,瀏覽器出於安全考慮,
禁止跨網域請求。為了讓 Web 應用程式可以從其他網站獲取資料,
需要在伺服器端設定 Access-Control-Allow-Origin 头標頭。
這個標頭指定了哪些網域可以訪問這個資源。如果瀏覽器接收到的回應沒有包含這個標頭或者標頭中的網域不在列表
中,瀏覽器就會拒絕請求。
CORS 為 Web 應用程式提供了更多的安全性,但需要開發者在伺服器端進行一些額外的設定。
21.什麼是事件冒泡
事件冒泡指的是当一个元素上发生了事件,该事件会从这个元素开始向上冒泡传播,
直到传播到文档的根节点,而在这个过程中,所有的祖先元素都可以监听到该事件并进行相应的处理。
举个例子,假设我们在一个网页上有一个嵌套的结构,其中一个子元素上注册了一个鼠标点击事件的监听器。
当我们在这个子元素上点击鼠标时,该事件会首先被传播到该子元素上,然后再向上冒泡到父元素、祖先元素,
直到最终传播到文档的根节点。
在这个过程中,我们可以在每一个元素上注册一个监听器来处理该事件,这就是事件冒泡机制的基本原理。
通过这种机制,我们可以在多个元素上共享一个事件监听器,并实现复杂的交互逻辑。