咻咻咻過去,參加課程已經滿一個月了啊!
這整個月就是拼了老命、把僅存的一咪咪意志力都拿來參加課程,這篇文是第五週作業,也是個很棒的機會做總檢討。
對課程內容有興趣的可以先看看:
總之這是一篇很長的血汗心得文,我看了都怕.jpg
week2
超級挑戰題week3
超級挑戰題week5
week2
綜合練習 Lv3_4 : 改成超過 3x3 陣列也適用week3
hw5: 大數加法 : 改成陣列寫法week4
挑戰題 & 超級挑戰題 : 改成 callbackweek5
curl 下載多檔 : 改用 parallel
一次下載全部暖身週注重在基本觀念釐清,比較沒有明顯的挑戰。
但第一週好像是目前最累的一週,可能還在逐漸摸索學習與時間管理的方式,蕃茄鐘也是第一週結束就放棄了啊,看到同學分享的工具 Timely 抓工作時間很有興趣。
每天都保持穩定的時間學習,也比三天衝過頭、兩天耍廢好。
前面簡答題
: 解釋 CLI、 Git、網路基礎
挑戰題
:用 shell 腳本產生 n
個檔案
超級挑戰題
: 用 curl
抓 GitHub API,再篩資料
--silent
關鍵字,最後成功很開心!本週算是複習 JS 基礎觀念、基礎排序法,初次感受 ESLint 愛的教育,位元運算也是新世界。
在傳值 or 傳址討論中,學到不再去追根究底名詞背後的定義是什麼,了解其中的行為,比「 該如何定義此行為 」還重要。
看同學作業才知道 code review 的重要性,明明自己有過基礎還寫成那樣、感到羞愧加生氣。同時認清本週作業的超級挑戰題是比自己強太多的對手,現實生活不是 JUMP 漫畫般熱血,所以還是等練高一點再來挑戰。
過去放棄的觀念,很開心有機會補回來。明明是一樣的內容,霧裡看花時覺得痛苦萬分,理解了卻覺得很好玩,這心境差異也覺得滿有趣的。
++
放前面跟後面居然有差Lv1_10
reduce
,以為只是效能更好的寫法而已,並不知道他的真正妙用,現在知道重點在於累積器,原來是可以把狀態存在裡頭,直接到回傳的參數,就不需要外部變數來存取,覺得蠻酷的!Lv2_6: 費氏數列
Lv2_8: 大小寫轉換
map
的運用。Lv3_2 : 壓平陣列
Lv3_3 : 聖誕樹
.repeat
可以用,導致用了超多迴圈再處理字串…Lv3_4 : 圈叉遊戲
3x3
的陣列也適用x = x || y
( 如果 x
的布林值為 false
,把 x
設為 y
)n >> 1
效果如同 n / 2
n << 1
效果如同 n * 2
n & 1
效果如同 n % 2
→ 1
, 代表 n
為 奇數
n & 1
效果如同 n % 2
→ 0
, 代表 n
為 偶數
hw1 - hw6
挑戰題: Binaray Search
start
大於 end
時,代表目標物不在資料裡。// 取中間數當作參照值
function searchIndex(start, end) {
return Math.floor((start + end) / 2);
}
// 主程式
function search(arr, target) {
let start = 0;
let end = arr.length;
let index = searchIndex(start, end);
// 起始點 與 終點 中間沒有其他數就跳出
while (end > start + 1) {
if (arr[index] === target) return index; // 找到目標
if (arr[index] > target) {
end = index;
} else {
start = index;
}
index = searchIndex(start, end); // 更新參照值
}
return -1;
}
超級挑戰題: BFS
0.1 + 0.2 => 0.30000000000000004
的文章都很難看懂… 筆記花了很多功夫還是沒辦法解釋好,更無法說服自己已經懂了。這週開始耐心好像有點下降,但作業寫得很開心。
日後會多善用 ES6 語法、引用模組、不自己造輪子,還有個重要的關鍵是,該怎麼把測資寫得好,真是一門大學問。
寫作業時踩到 NaN 的陷阱,把教訓寫成筆記,有痛點的收穫,印象非常深刻。
package.json
的 script
欄位.gitignore
資訊加上資料夾 node_modules
,不然等著上傳到天荒地老.test.js
的檔案。變數宣告 let、const
: 塊級作用域字串模板 Template
: 更方便的操作字串解構賦值 Destructuring
: 對應到陣列或物件的值展開運算子 Spread Operator
: 用 ...
符號,展開陣列或物件其餘運算子 Rest Parameters
: 用 ...
符號,集合剩餘的元素。參數預設值 Default Parameters
: 幫函式參數加入預設值箭頭函式 Arrow Function
: function 更簡潔的寫法import & export 引入跟匯出
: 跟 ES5 的 require
& module.exports
很像NaN == NaN
or NaN === NaN
→ 都是回傳 false
x
是不是 NaN
的函式
.isNaN(x)
x
轉換成數字類型 → .isNaN(Number(x))
,再進行比對是否為 NaN
Number.isNaN(x)
.isNaN()
可靠又嚴格一點number
的 NaN
才回傳 true
,其餘皆 false
hw1 - hw4
hw5: 大數加法
1
的情況,是測了 99
+ 1
才發現,開始有了一點測資寫法的概念function add(a, b) {
let temp10 = 0;
let ans = '';
const max = a.length > b.length ? a.length : b.length;
for (let i = 1; i <= max; i += 1) {
// 從後往前取數字,空位補 0
let temp = (Number(a[a.length - i]) || 0) + (Number(b[b.length - i]) || 0) + temp10;
temp10 = temp > 9 ? 1 : 0;
temp %= 10;
ans = temp + ans;
}
if (temp10) ans = `1${ans}`; // 最後還要再進一位,前面補 1
return ans;
}
挑戰題: 大數乘法
個位數
* 多位數
來寫,成功之後再換成雙迴圈n
個 0
,我居然用數字 10 的 n 次方
,好愚蠢啊我在想什麼!幸好被同學糾錯,後來改成加上 '0'
的字串,還比原本寫法簡單,感謝好心同學。function checkNum(str, index) {
return Number(str[str.length - index]) || 0; // 從後往前取數字,空位補 0
}
function add(a, b) {
let temp10 = 0;
let ans = '';
const Max = a.length > b.length ? a.length : b.length;
for (let i = 1; i <= Max; i += 1) {
let temp = checkNum(a, i) + checkNum(b, i) + temp10;
temp10 = temp > 9 ? 1 : 0;
temp %= 10;
ans = temp + ans;
}
if (temp10) ans = `1${ans}`; // 最後還要再進一位,前面補 1
return ans;
}
function times(a, b) {
let ans = '';
for (let i = 1; i <= a.length; i += 1) {
for (let j = 1; j <= b.length; j += 1) {
const temp = checkNum(a, i) * checkNum(b, j) + '0'.repeat(i + j - 2); // 乘積後面補上 n 位數的 0
ans = add(ans, temp); // 乘積不斷相加
}
}
return ans;
}
hw5: 大數除法
const obj_json = JSON.stringfy(obj)
const obj2 = JSON.parse(obj_json)
本週學的東西都比較抽象,理解 API 怎麼運作的是一回事,真的要串接時,還是碰到一堆困難,request header 的寫法明明也不複雜,但剛開始搞不懂時就是一直撞牆。
體會到好的文件很重要,規則不寫清楚,新手還不會通靈啊
Elements
跟 Console
之間遊走,本週正式踏入了 Network
標籤,開心。
發送 html 的 request
> 解析 html 內容
> 發現其他資源 ( CSS、JS、img )
> 發送其他資源 request
> 渲染網頁
GET
: 通常網頁都是 GET
的 request 比較多
POST
: 需要執行一些動作時,會傳送 POST
的 request
request
實作 Client 端http
,實作 Server 端HTTP
, HTTPS
, FTP
,DNS
…TCP
, UDP
IPv4
, IPv6
乙太網路
、Wi-Fi
POST
,但其實我不是很確定是否歸類在非 RESTful )curl [options] [URL...]
hw1 - hw4 : API 基礎串接
hw5 簡答題: 解釋 API、規劃 API 文件
挑戰題 & 超級挑戰題 : 串接 Twitch API
.then
,非常不理想。看到有同學提出用遞迴覺得很聰明!之後會再改成 callback + 遞迴
試試,感謝同學分享。const rp = require('request-promise');
const token = '11gzim2pdteu8xr2p6qgotmuiur42i';
const url = 'https://api.twitch.tv/helix/streams';
const id = '21779'; // game_id of LOL
const num = 100;
let keyNext;
const options = {
url: `${url}?game_id=${id}&first=${num}`,
headers: {
'Client-ID': token,
},
json: true, // auto transform to JSON
};
const printData = (body) => {
body.data.forEach(element => console.log(element.id, element.title));
};
const getItemFront = (body) => {
printData(body);
keyNext = body.pagination.cursor;
};
const getItemEnd = () => {
options.url = `${options.url}&after=${keyNext}`; // request url 加上更新過的 cursor
rp(options)
.then(body => printData(body));
};
rp(options)
.then(body => getItemFront(body)) // 抓前 100 個
.finally(() => getItemEnd()); // 抓後 100 個
寫這份心得的同時、也複習了前四週所學,還有 HTTP GAME 跟挑戰賽可以玩,完全是目前體驗最佳的一週,沒辦法,解題總是比聽理論有趣啊!
同時零機一動給自己出的抓作業小挑戰,能夠實現的感覺很好。
前幾題都蠻快通過的,第五題已經放生兩天了。 依照 Huli 說的佛系解題法,答案可以現身了嗎我還在等你欸!
第二題: 不公平的人,是誰?
第五題: 友好數
目前卡在 Lv14,完全看不懂題目,同樣被我放生。 但真的很好玩,雖然太急著過關沒時間注意彩蛋、連有 hint 都忘了啊哈哈哈
Access-Control-Allow-Origin: * # 允許所有網站發送的請求
Access-Control-Allow-Origin: lidemy.com # 只允許 lidemy.com 的請求
Huli 回答:這題跟同不同源其實沒關係,題目只有說 server 會檢查這個 header 而已。然後只有用瀏覽器送出的 request 會有同不同源的問題,其他方式送出的基本上都不受限制。
'Accept-Language': 'en-PH'
( 完全是被逼瘋 )'X-Forwarded-For': '115.85.29.130'
填上去居然過了!!超級爽 ( 事後才知道是邪門歪道,預設解答是去找菲律賓的 proxy 來用 )參考資料:
內容有點長,直接拉出一篇心得:[第五週] 練習串 GitHub API 抓同學作業
當時一看到課綱跟報名表,除了後端的部分,課程內容有 70% 都是「 以前有碰過、但不甚了解的 」,所以覺得超級興奮。
本來這段時間是要在家自學的,但我認為在家自學的障礙是,對於陌生的領域,很難挑到適合自己的教學材料、學習內容跟職場需求的切合度、訂出有挑戰性的大目標跟小目標,以及如何檢視學習成果。
雖然直接就業也不是不行,但以現在的實力能進的公司應該不理想,上戰場也很有可能被 Deadline 追著,這邊改一下、那邊再 ctrl + V
,反正可以動就好,這不是我期望的。
所以在課程的安排下,至少這四週都是很扎實的學習,而付出了努力多寡也體現在作業成果上,更好的機制是看同學作業,code review 真的可以學很多。只要付出足夠多的時間,我認為人人都可以轉職成功不是講假的。
自己都特地跑到一個偏遠地區、就是想遠離任何干擾,說實在是挺有效的。所以基本上沒有什麼外務纏身、時間很充裕,主要也是在測試自己的意志力,時間都放在那裡了,到底能不能好好利用。
雖然目前來說、好像有點每下愈況。( 汗 )
自己對於學習與做筆記還在摸索當中。 課程都是很友善地以初學者出發、善用各種比喻,所以教學影片就算只是講理論也都滿好理解的,但隔天的理解度就變成 50 %,或是我自己稱為「假性理解」,因為試圖用自己的話解釋就會卡住。
這時候再上網查不同資料就會很有幫助,就像同一個物體、每個人看到的角度都不同。
同一件觀念,看 5 個參考文章,會得到 5 種面向的解釋,雖然越查越困惑的情況也不在少數,但聽 Huli 講完課有個大方向的理解,有時間的話再看其他教學文的解釋,最後用筆記統整成自己的理解內容。 很多時候我直接看教學文都是看不懂的,有了 Huli 給的世界觀的前提再去深入理解,就變得沒有這麼困難了。
所以前幾週都有練習「 用自己的話解釋某觀念 」的作業,覺得這作業出的真好!
像是第四週,當時的日記寫著: 「 覺得 http 筆記寫的蠻好的,之前看一遍覺得懂了,但當我要寫下來才發現還是有許多可以釐清的地方,消化過再輸出成自己的語言,真的好重要! 」
總而言之,希望能保持著不斷有 output 的學習,才對得起課程用心的 input
雖然我知道大家都鼓勵多問問題,但我嘗試了一種方法。
如果不是三分鐘能解決的問題、就先列下來,不要急著查資料、也不要急著問,等本週的重點學習內容都告一段落,再來 google 所有列下來的問題,自己找解答、同時試著回答那個不懂的自己,真的找不到再發問。
會這麼做是因為自己很愛問問題、也很急性子,而我的經驗是,只要是我迅速拋出去的問題,得到的答案都不會留在我記憶太久,可能是因為還沒痛過、解答也來得太方便。
而這方法其實是以前主管教我的。
「你的問題先寫在一張紙上,留到我全部說完再發問。」
場景是我坐在他位子旁邊,主管手把手地教我某個功能,在過程中我總是會產生超多問題想問,一直想打斷主管,他可能被我搞瘋了,所以教(逼)我用這種方法之後,整個豁然開朗。
因為許多問題根本不需要發問,我要的答案都在之後會講的內容裡,而我需要的只是聽到最後,那時候才知道。
我會不會只是缺乏等候答案的耐心?
在第一週結束後,有比較多問題統整( 或者是那時比較認真哈哈哈 ),就開始搜尋整理成一篇 QA:
[第一週] 問題總整理
可以看得出來有些問題都很烙賽,但我就是想知道「 為什麼? 」,因為在面對陌生的事物時,連問題本身瞎不瞎我都無法判斷。
其實就跟玩海龜湯很像,問到一個關鍵問題算你幸運,但更常見的情況是,拋出去問題的回應都是「 不重要 」。
( 沒玩過海龜湯的可能無法體會這例子,但有人沒玩過嗎? )
總而言之,我想說的是,不需為爛問題而恥、不管多蠢的問題可以列下來,但不用急著丟出去,多等一下答案有可能自己找上門,或是試著自問自答也是蠻有趣的。
( 當然如果是卡關到無法進行下一步的另當別論啦! )
最後,感謝 @Huli 用心的課程內容、以及每次發問都超即時的回答,參加第三期的計畫真是我今年最好的決定。
還有感謝 @isshin、@ChihYang41 同學第五週的心得分享,內容讓我獲益良多,寫法也參考了同學的格式。
Written on May 13th, 2019 by Yakim shu