面試考題 2024 - 遞迴(實作)
===

---
###### tags: `面試問題`, `練習問題`, `2024`
在前端以為就不用做資料結構的設計嗎?no,no,no。
其實遞迴可以存在任何地方,不管是Web 還是 後端演算時,偶爾會發現它的存在。
面試官:“請問你知道遞迴嗎?請簡單說明”
2年高麗菜的我:“....老實說我真的沒用過,但我可以指出我所理解的《遞迴》”
## 什麼是遞迴?

假設你有一堆書要放在書架上,書本的數量是 n 本。如果我們要描述 “把這些書放在書架上”的任務,可以用遞迴的思維來考慮: (不是啊,就放上去就好了!)
1. 限制:**使用遞迴必須必須必須要小心設一個停止的門檻**!
- 如果書的數量為0 的時候(n === 0),即沒有書要放,那這個任務自然就完成了!
2. 遞迴步驟:
- 如果有 n 本書要放,我們可以先放一本,然後“把剩下的 n-1 本書放上去”。(注意,這裡的“**把剩下的 n-1 本書放上去**”實際上是一個規模縮小了的同樣任務)(就好像for(let i = arr.length; i = 0; i--) 執行一次就減一次這樣。)
```jsx!
function factorial(n){
if(n === 0) return 1;
if(n !== 0) return n * factorial(n-1);//重複使用這個功能就是遞迴!
}
console.log(factorial(5)) // 輸出 5 * 4 * 3 * 2 * 1 = 120
```
### 解說
在網頁上呢,遞迴可以處理“主題和內容設計都一樣”的情況。他允許一個函數調用自身來解決問題。遞迴函數通常會處理一個任務,將其分解成更小的相同任務,直到達到一個設定限制。
遞迴的關鍵在於每次遞迴調用都必須趨向於這個終止條件,***防止無限循環***!
簡單說,遞迴呢就是可以**簡單地處理一樣的設計**。但例如主題和內容要用不一樣的UX,可能要想辦法可能傳入一個 **boolean 的 props 做區別表現**。
## Web裡使用遞洄:
```jsx!
interface innerCommentDataType{
id: number;
author: string;
text: string;
}
interface commentDataType {
id:number;
author: string;
text:string;
replies : innerCommentDataType;
}
function Comment({data}:{data:commentDataType[]}) {
return (
<div>
<h4>{data.author}</h4>
<p>{data.text}</p>
{data.replies ? (
<div style={{marginLeft: "20px"}}>
{data.replies.map(reply => <Comment key={reply.id} dasta={reply}/>)}
</div>
): null}
</div>
)
}
const commentData = {
id: 1,
author: "User1",
text: "This is a comment.",
replies: [
{
id: 2,
author: "User2",
text: "This is a nested reply.",
replies: [
{
id: 3,
author: "User3",
text: "This is a nested nested reply."
}
]
}
]
}
function App() {
return <Comment data={commentData} />;
}
```
* 我們可以從中發現,如果只是要做單一的資料呈現在web上,我們可以考慮使用遞迴的方式,這樣可以減少寫Code的時間。
```jsx!
function Menu({item}){
return (
<ul>
{item.map(item =>(
<li key={item.id}>
{item.title}
{item.subitems && <Menu item={item.subitems}/>}
</li>
))}
</ul>
);
}
const menuItems = [
{ id : 1, title : "Home"},
{
id:2,
title:"About",
subitems:[
{id:3 , title:"Team"},
{id:4 , title:"Company"},
]
}
];
function App(){
return <Menu items={menuItems} />
}
```
在這個例子中,“Menu”組件通過遞迴調用自己來渲染任意深度的菜單項。
在網站開發中使用遞迴時要注意:
* **性能考量**: 雖然遞迴可以簡化組件的開發,但對於大規模數據或深層嵌套,遞迴可能導致性能問題。在這種情況下,考慮遞迴組建的優化,如使用 “React.memo” 或不免不必要的重新渲染。
* 遞迴深度: **JS的調用棧(call stack)有限**,深度過大的遞迴可能導致推棧溢出錯誤。適當控制遞迴深度或改用迭代方法是必要的!
通過上面的在網頁上使用遞迴的例子和說明,希望可以讓你更了解在 web develop 中要怎麼使用遞迴,正確地使用遞迴可以大幅簡化代碼,使代碼更加清晰和易於管理。
希望上面的解說能幫助到正在面試和考慮面試和正在學習的你們!大家一起加油!PEACE。
