崩潰遞迴地獄

這週ㄧ樣是瘋狂面試週,想來分享一道目前印象最深的面試題,有興趣的人也可以試著解解看(?)

題目是這樣的,一個 sitemap 陣列存著網站上的選單結構,寫出一個 function ,帶入所有選單及某個選單 name 會回傳一個陣列除了包含傳入的參數 name 外還有它的所有父層 name。例如 find(sitemap, '草莓蛋糕'),會返回 ['草莓蛋糕', '蛋糕', '甜點'],注意 function 需要能符合很多層(不只目前的三層)。

完整題目如下:(如有雷同純屬巧合🙈)

const sitemap = [{
name: '三明治',
children: []
},
{
name: '甜點',
children: [{
name: '蛋糕',
children: [{
name: '草莓蛋糕',
children: []
},
{
name: '水果蛋糕',
children: []
}
]
},
{
name: '鬆餅',
children: [{
name: '奶油鬆餅',
children: []
},
{
name: '蜂蜜鬆餅',
children: []
}
]
},
{
name: '甜甜圈',
children: [{
name: '原味甜甜圈',
children: []
}
]
}
]
},
{
name: '飲品',
children: [{
name: '奶茶',
children: []
},
{
name: '紅茶',
children: []
},
{
name: '拿鐵',
children: []
}
]
}
]
function find (sitemap, current) {
// your code
}
const current = '草莓蛋糕'
console.log(find(sitemap, '草莓蛋糕')) // ['草莓蛋糕', '蛋糕', '甜點']

當下一聽到題目,第一個念頭是覺得「似乎不難」,因為我有碰過類似的情境,只是那時用 vue 解決。總之我沒想太多的寫出答案,現在想起來很蠢,因為我是寫死只有三層可以用的 function,後來面試官才講要很多層都可以才行,也另外提示我可以使用「遞迴」,不過面試當下我還是寫不出來,於是就把題目帶回家好好想,。

最初的版本有點忘記了, 這應該算是第二個版本,會這樣寫是來自面試官的提示:「先把每層的 name 都找出來,然後把 name 丟進結果,不對的話再拿出來」,總之就寫了很久,但結果還是一直不對。

let result = [];
let flag = false;
function find (sitemap, current) {
for (let i = 0; i < sitemap.length; i++) {
if(flag) {
return result
}
result.push(sitemap[i].name);
if(sitemap[i].name === current) {
flag = true;
}
find(sitemap[i].children, current)
if(!flag) {
result.pop();
}
}
}

話不多說,直接來講最後怎麼解的好了,當然我又再一次仰賴了 Huli 老師🤣 再次感謝老師一步一步的引導,結果只有最後一小步是我自己想的😂

  1. 第一步:先只考慮第一層
function find (sitemap, current) {
for (let i = 0; i < sitemap.length; i++) {
const site = sitemap[i]
if (site.name === current) {
return [site.name] // 如果找到了,回傳自己本身
}
}
}

2. 然後往下找,相信他會傳給你結果(這句話聽起來很玄,不過也是因為這句才解出來的)

function find (sitemap, current) {
for (let i = 0; i < sitemap.length; i++) {
const site = sitemap[i]
if (site.name === current) {
return [site.name] // 如果找到了,回傳自己本身
}

// result 會是往下找的結果,會是一個陣列,如果找不到會是 undefined
const result = find(site.children, current)
}
}

3. 如果 result 有值,就把它存起來。最後這一步看似很簡單但也想了很久,最後竟然是卡在想著如何把結果存起來,完全忘記有 concat 這方法,大傻眼😱

function find (sitemap, current) {
for (let i = 0; i < sitemap.length; i++) {
const site = sitemap[i]
if (site.name === current) {
return [site.name]
}
const result = find(site.children, current)
if(result) {
return result.concat(site.name)
}
}
}

解完的瞬間真的想放煙火🎊 但還是覺得遞迴好難啊,想再多做幾個遞迴的題目(歡迎出題考我🤣)

附上自己畫的示意圖XD

好文推薦:軟體工程師必修的三門課

作者就點出在這行本科系和非本科系的差別,非本科系因為缺乏一些基礎的底子知識,遇到問題就比較不知道怎麼解決。(例如我不知道要用遞迴解決)

作者認為必修的三門課是分別是資料結構與演算法 (Data Structure and Algorithm, DSA)計算機結構 (Computer Architecture)作業系統 (Operation System),內文敘述的還不錯可以點進去參考。

IE 9 issue: console is not defined

有天一個後端的朋友來問我一個前端的問題,一開始說「js 有一段只要不開開發工具就不會跑」我想說這也太詭異了吧,js 跑不跑怎麼跟開發工具有關係,但資訊給的實在太少,很難幫 debug 。

後來他仔細追查後(過了 4 個小時)找到了:「有ㄧ段有 console.log 的 js 在 IE 9 會報錯」,然後也自己找到解答了,總之就是:

在 IE 10 之前的版本要開啟 IE Dev Tools 執行才能存取 console 物件。

雖然沒踩到這個雷但還是分享一下,只能說 IE10 以前的版本太多雷!

meet.jobs 創辦人聊求職祕技

Amos 的 youtube 頻道請來了 meet.jobs 的創辦人 Reinhardt 來談談求職祕技(與業界八卦?)

整理幾個在影片中看到的重點:

  1. 公司人資是怎麼看履歷的?快速的掃過一遍,看有沒有符合的關鍵字(像是工作需要的技能、工具),關鍵字越多才停下來多看幾眼。
  2. 建議相關工作經驗要超過履歷篇幅的一半,不要寫了很多不相關的,相關經驗卻只寫一點點。
  3. 工作內容包山包海的不要去,尤其是新人,更需要有人帶。
  4. 學歷隨著出社會越久越不重要。
  5. 急徵不要去,好公司砍人砍很快,找人找很久,爛公司相反。
  6. 履歷寫期望薪資不一定是好的。其實薪水不是求職者決定的,公司想請人是為了解決問題,而這個薪水就是公司為了解決問題所需要花費的成本。

無所不在的數學

想說寫寫程式好像不會再碰到很複雜的數學了(哪來想法?),結果工作上還是修度欸丟,上圖是為了卡片上面的 label 標籤特地複習了畢氏定理😎(有人可能會問為什麼設計稿沒有標示呢阿就沒有啊🤔)

然後又聽到傳聞 css 可能要加入三角函數的 function 😨

後記

這週 delay 了因為是瘋狂面試週!不過接下來告一個段落了😎 要來準備面試心得囉。

不忘附上最近愛的歌(你們一定要聽!)

Habits (Stay High) Tove Lo // Madilyn Bailey & Alex Goot (Acoustic Version)🎵

對了,如果你喜歡我的文章,記得幫我拍拍手哦 👏🏻 也歡迎留言給我任何 Feedback 🖐🏻

--

--

Debby Ji
Debby’s Playground

Frontend Developer / 不趕快寫下來的話就忘記了