12/27 ~ 1/2 週記(v2.0)
迎接2021的第一週
讀書
極簡閱讀
整本書的核心很明確,在跟你說不是「只讀書」或是「畫重點」而已,而是要「用這本書」,作者分享了好幾年累積的「拆書」經驗,告訴你該怎麼拆解一本書,並為自己所用,不僅如此,如果能成為「拆書家」促進他人學習,作為輔助知識的傳播者,自己能學到更多、更深、更廣。
使用這本書教的RIA、便利貼法,將書的知識內化於己,應用在生活,解決「自己」的問題,閱讀會比以往純粹的看書更有價值!
技術
演算法
參考王者歸來…那本書的章節內容,已於上週介紹過,書本中的範例程式碼原為python,不過以下皆轉換為javaScript作為程式碼範例。
- 遞迴
遞迴,簡單來說就是自己呼叫自己,在程式中算是stack(堆疊)的形式,會把程式計算的結果依序存放起來,等到確實能夠算出值之後,再往回加總,採先進後出的處理,直接看費波那契數列的例子比較清楚。
一般遞迴:
function basicFibonacci(n) {
if(n === 0) {
return 0
}
if(n === 1) {
return 1
}
return basicFibonacci(n - 2) + basicFibonacci(n - 1)
}
memo遞迴:優化一般遞迴每次處理都要重新計算,用一個陣列將「上次的結果」存放在記憶體,省去重新計算,也就是用空間換取時間
function memoFibonacci(n) {
let res = [0, 1] // 等同n為0 or 1的情況
function innerFibo(i) {
if(typeof res[i] !== 'number') {
res[i] = innerFibo(i - 2) + innerFibo(i - 1)
}
return res[i]
} return innerFibo(n)
}
兩者比較:
basicFibonacci(10) // 55, 共呼叫了176次
memoFibonacci(10) // 55, 只呼叫了20次(含memoFibonacci和innerFibo)
- 搜尋法
在「圖形」(或稱為資料樹)中有兩種常見的搜尋演算法,分別為「廣度」與「深度」,廣度是以搜尋同一層為優先,深度則是以搜尋子節點為優先,兩種演算法各有優缺點,以應用時的資料格式來決定使用哪一種,如下圖所示:
廣度
function BFS(graph, start, goal) {
let findResult = false
let visited = [] if(!graph[start] || !graph[goal]) {
return ({
visited,
findResult,
})
} let queue = [start]
while(queue.length > 0) {
// 跟DFS唯一的差別只在於從前面抓出元素(先進先出),只要有新元素都先抓"最前面的",會先把同一層的搜尋完,再往下一層找,所以是廣度搜尋
const node = queue.shift() if(node === goal) {
visited.push(node)
findResult = true
break
} if(!visited.includes(node)) {
visited.push(node)
queue.push(...graph[node])
}
} return ({
visited,
findResult,
})
}
深度
function DFS(graph, start, goal) {
let findResult = false
let visited = [] if(!graph[start] || !graph[goal]) {
return ({
visited,
findResult,
})
} let queue = [start]
while(queue.length > 0) {
// 跟BFS唯一的差別只在於從後面抓出元素(後進先出),只要有新元素都先抓"最後面的"(子節點會先被抓出來),所以是深度搜尋
const node = queue.pop() if(node === goal) {
visited.push(node)
findResult = true
break
} if(!visited.includes(node)) {
visited.push(node)
queue.push(...graph[node])
}
} return ({
visited,
findResult,
})
}
操作範例:
const graph = {
'1': ['10', '7', '9'],
'10': ['1', '5', '2'],
'7': ['1', '3'],
'9': ['1', '4', '11'],
'5': ['10'],
'2': ['10'],
'3': ['7'],
'4': ['9'],
'11': ['9']
}console.log(BFS(graph, '1', '11'))
// visited: ["1", "10", "7", "9", "5", "2", "3", "4", "11"]console.log(DFS(graph, '1', '11'))
// visited: ["1", "9", "11"]
雜談&回顧
雜談 — 關於街頭連署
假日在逛街的時候,聽到清楚有力的聲音,在喊著「用手機就可以連署,連署來減少塑膠,為環保盡一份心力」之類的口號,忍不住往聲音的方向看過去,只看到一個人拿著一張有QRcode的牌子,牌子上沒什麼能夠一目瞭然的資訊,在好奇心驅使之下,觀察了一陣子,只見人來人往但都沒有人因此駐足理睬他,更別說照著他說的話使用手機來掃QRcode這件事,但是明明是如此簡單的事情,為何大家(包含我)都不會想要做個「舉手之勞」?
我覺得可以從兩個點來看:
- 對我的好處是?
簡單來說,我認為人類幾乎都是「自私」的,即便是幫助別人,大多也是為了之後的回報,因此,今天即便只是舉手之勞,但是沒有任何立刻看得到的好處,也沒有讓人足以「想像」美好未來的好處,只是說著無關痛癢的口號或是打著冠冕堂皇的精神口號,對於大部分的人來說,可不會因此動心看你一眼,更別說駐足好好聽你說話。
因此,如果要達到吸引他人目光,如果你沒有辦法給予立即的回饋或實質的好處(例如DM、贈品、抽獎等等),倒是可以用一些「足夠急迫」、「可以想像的美好未來/糟糕未來」等等,足以讓人可以在腦中浮現畫面的話語來感動他人,如果剛好聽者也是擁有同樣的價值觀,或許更有可能產生共鳴,因而將目光轉向你,仔細聽聽你想表達的,這樣才有辦法進一步達成你的目標。 - 警覺心:
「假借善心名義填問卷,驚覺是化妝品的直銷」,這類的新聞層出不窮,這也讓人在路上看到類似的招攬、宣傳行為,基於警覺心不自覺地避開,少一事總比多一事還好,心想反正我也沒什麼好處,還是避開為妙。
因為太多居心不良的人利用了大家的善心,導致大家常常都處於戒備狀態,即便今天是真的在做好事,例如善心募款、連署法案等等,我們必須能夠要在幾秒之內「分辨」出你是做善事還是在濫用同情心的,這實在非常難做到,不只需要經驗,而且你還要知道對方所屬的團體等等,因此大多人與其想這麼多,不如通通拒絕還比較快,省得自己困擾呢。
雜談 — 關於「創作」這回事
雖然有人會說創作不過是把就有的東西拼湊出來而已,這麼說也沒錯,但重點是如何拼湊。
即便有再好的食材,你沒有正確的食譜,也沒有精湛的手藝,拼出來也不過是坨「高級的廚餘」,精湛的手藝可以透過反覆的「刻意練習」來加強,但是終究會到達自己的頂點,會碰到那個自己的高牆,再也跨不過去,這時候或許就要認知到,自己的「食譜」,也就是創作的內涵,關於如何創作這一塊,是時候該加強了。
常常看到一些人在抱怨自己不夠努力或是感到創作的無力,好像只要抱怨和一直埋頭苦幹就行,而不管在畫畫或寫作等等領域都是,常常都會覺得別人都已經這麼優秀了,還如此的努力,而覺得自己好像永遠追不上。
不管是一直都有能力輩出的後輩,還是目前仍在進步的前輩,現實就是如此的殘酷,技術上可能一輩子無法「贏過」別人,這時候或許可以停下來問自己,真的要執著於技術嗎? 我自己想創作的是什麼?
放下手中的筆,仔細分析別人的作品,看看別人好在哪,不要只看到表面而已,可以運用極簡閱讀的便利貼學習法,分析他人的作品,用自己的話語闡述與解釋,並將那些自己喜歡的(創作上來說喜不喜歡很重要)點寫下來,接著回頭看自己的作品,想想有哪些類似的創作經驗,將其寫下來(RIA中的A1),接著參考別人的作品,設定目標與行動,創作出更好的作品。
執著於自己的想法只會讓作品越來越僵化,好作品是幾乎不可能憑空生出(除非你是天才)的,唯有不停學習與進步,才有機會將他人的作品「內化於己」,並且持續與人交流,討論各種想法,不僅於自身的專業而已,這樣更有機會揉合並創作出自己滿意的創作。
雖然自己也知道要多多與他人交流,不要只關在自己創造出來的空間之中,但在互動分享的場合之中,難免會怕被「比較」,心裡也不自覺的比較孰優孰劣,會太在意他人的眼光,勇於接受自己「就是比較差」(我就爛),心裡會比較坦然舒暢,創作的時候會比較能夠放開執著,嘗試各種不同的風格創作,反正自己也沒什麼好失去的。