面試考題 2024 - 遞迴(實作) === ![image](https://hackmd.io/_uploads/ryWGwvg70.png) --- ###### tags: `面試問題`, `練習問題`, `2024` 在前端以為就不用做資料結構的設計嗎?no,no,no。 其實遞迴可以存在任何地方,不管是Web 還是 後端演算時,偶爾會發現它的存在。 面試官:“請問你知道遞迴嗎?請簡單說明” 2年高麗菜的我:“....老實說我真的沒用過,但我可以指出我所理解的《遞迴》” ## 什麼是遞迴? ![image](https://hackmd.io/_uploads/SJsv_bGXC.png) 假設你有一堆書要放在書架上,書本的數量是 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。 ![image alt](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYXg4Znc1MDNtYnZydXE0aDNxNmh0dnhscjU3YzhpcmJjaHVwMjJjaiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/fxe8v45NNXFd4jdaNI/giphy.gif)