├── .eslintrc.js ├── .gitignore ├── README.md ├── codewar.md ├── examples ├── README.md ├── week11 │ └── README.md ├── week12 │ └── README.md ├── week13 │ └── README.md ├── week14 │ └── README.md ├── week16 │ └── README.md ├── week17 │ └── README.md ├── week18 │ └── README.md ├── week19 │ └── README.md ├── week2 │ └── README.md ├── week21 │ └── README.md ├── week22 │ └── README.md ├── week23 │ └── README.md ├── week24 │ └── README.md ├── week3 │ └── README.md ├── week4 │ ├── README.md │ ├── hw3.js │ ├── package-lock.json │ ├── package.json │ └── twitch.js ├── week6 │ └── README.md ├── week7 │ ├── README.md │ └── hw1.html ├── week8 │ └── README.md └── week9 │ └── README.md ├── homeworks ├── week1 │ ├── README.md │ ├── hw1.md │ ├── hw3.md │ ├── hw4.md │ └── hw5.md ├── week10 │ ├── README.md │ └── hw1.md ├── week11 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ ├── hw3 │ │ └── index.html │ └── hw4.md ├── week12 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ └── hw3.md ├── week13 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ ├── hw3 │ │ └── index.html │ ├── hw4.md │ └── todo.png ├── week14 │ ├── README.md │ └── hw3.md ├── week15 │ ├── README.md │ └── hw1.md ├── week16 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ └── hw4.md ├── week17 │ ├── README.md │ ├── hw1.md │ ├── hw2.md │ ├── hw3.md │ ├── hw4.md │ └── hw5.md ├── week18 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ ├── hw3 │ │ └── index.html │ └── hw4.md ├── week19 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ └── hw3.md ├── week2 │ ├── README.md │ ├── hw1.js │ ├── hw2.js │ ├── hw3.js │ ├── hw4.js │ ├── hw5.js │ └── hw6.md ├── week20 │ ├── README.md │ └── hw1.md ├── week21 │ ├── be │ │ ├── README.md │ │ └── hw1 │ │ │ └── index.html │ └── fe │ │ ├── README.md │ │ ├── blog.png │ │ ├── hw1 │ │ └── index.html │ │ ├── hw2 │ │ └── index.html │ │ ├── hw3 │ │ └── index.html │ │ └── hw4.md ├── week22 │ ├── be │ │ ├── README.md │ │ ├── hw1 │ │ │ └── index.html │ │ ├── hw2 │ │ │ └── index.html │ │ └── hw3.md │ └── fe │ │ ├── README.md │ │ ├── hw1 │ │ └── index.html │ │ └── hw2.md ├── week23 │ ├── be │ │ ├── README.md │ │ ├── hw1 │ │ │ └── index.html │ │ └── hw2.md │ └── fe │ │ ├── README.md │ │ ├── hw1 │ │ └── index.html │ │ └── hw2.md ├── week24 │ ├── be │ │ ├── README.md │ │ └── hw2.md │ └── fe │ │ ├── README.md │ │ ├── hw1 │ │ └── index.html │ │ └── hw2.md ├── week3 │ ├── README.md │ ├── hw1.js │ ├── hw1.test.js │ ├── hw2.js │ ├── hw2.test.js │ ├── hw3.js │ ├── hw3.test.js │ ├── hw4.js │ ├── hw4.test.js │ ├── hw5.js │ ├── hw5.test.js │ └── hw6.md ├── week4 │ ├── README.md │ ├── hw1.js │ ├── hw2.js │ ├── hw3.js │ ├── hw4.js │ └── hw5.md ├── week5 │ ├── README.md │ └── hw1.md ├── week6 │ ├── README.md │ ├── example.png │ ├── example2.png │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ └── hw5.md ├── week7 │ ├── README.md │ ├── acco.gif │ ├── calculator.png │ ├── carousel.gif │ ├── form.png │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ ├── hw3 │ │ └── index.html │ ├── hw4.md │ ├── reaction.gif │ └── twitch.png ├── week8 │ ├── README.md │ ├── hw1 │ │ └── index.html │ ├── hw2 │ │ └── index.html │ ├── hw3 │ │ └── index.html │ ├── hw4.md │ ├── twitch.png │ └── twitch_amelie.png └── week9 │ ├── README.md │ ├── board.png │ ├── board2.png │ ├── board3.png │ ├── hw1.md │ ├── hw2 │ └── index.html │ └── hw4.md ├── package-lock.json └── package.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | node: true, 6 | jest: true 7 | }, 8 | extends: 'airbnb', 9 | globals: { 10 | Atomics: 'readonly', 11 | SharedArrayBuffer: 'readonly', 12 | }, 13 | parserOptions: { 14 | ecmaFeatures: { 15 | jsx: true, 16 | }, 17 | ecmaVersion: 2018, 18 | }, 19 | plugins: [ 20 | 'react', 21 | ], 22 | rules: { 23 | "no-console": "off" 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | conn.php 3 | .DS_STORE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 程式導師實驗計畫第三期 2 | 3 | ## 這是什麼 4 | 5 | [程式導師實驗計畫第三期](https://medium.com/hulis-blog/mentor-program-3rd-47a2e85e33b3)是一個為期六個月的計畫,要求學生付出一定的時間(每週至少付出四十小時),希望能在結業時培養出合格的(意思就是找得到工作)的工程師,並且在就職後依舊能持續成長,成為好的工程師。 6 | 7 | ## 課程目標 8 | 9 | ### 核心能力 10 | 1. 具有找資料的能力,能夠知道如何找到相關資訊 11 | 2. 具有分析問題的能力,能夠快速定位問題 12 | 3. 知道如何解決問題,包括但不限於拆解問題、簡化問題、轉化問題 13 | 4. 解決問題後能夠重新歸納並整理 14 | 15 | ### 工具能力 16 | 17 | 1. 後端:知道後端原理,知道什麼是資料庫、Server,可以寫出簡單的網站並且自己部署 18 | 2. 前端:知道前端原理,HTML、CSS、JavaScript,知道 Ajax 以及如何與後端串接 19 | 3. 資安:基本資安概念,SQL Injection、XSS、CSRF 20 | 21 | ## 課程規則 22 | 23 | ### 1. 每日進度報告 24 | 25 | 為了更方便追蹤大家的進度,必須在禮拜一到五每一天簡短報告自己今天學了什麼和碰到什麼問題(已解決或未解決),除了作為淘汰制的參考以外,其實也是幫自己簡單複習一下所學過的東西。 26 | 27 | 進度報告你可以選擇早上 po 或是晚上 po,早上的話就是講昨天的事,晚上的話就是講今天的。 28 | 29 | ### 2. 每日心得(鼓勵但非強迫) 30 | 31 | 之前我有寫過一篇文章叫做[《每一篇心得都有價值——為什麼初學者才更應該要寫心得筆記》](https://medium.com/hulis-blog/why-blogging-ab77fd8c6ffa),裡面跟大家稍微講了一下寫心得的好處,在這課程中我也希望能把這個習慣帶給大家。 32 | 33 | 每天寫心得真的不是件容易的事,連我自己都做不太到,因此這一項是「鼓勵非強迫」,你沒有做到也沒關係,但我希望至少能夠每個禮拜寫個兩三篇,重點其實是在連續,這樣才有完整的紀錄可以看。 34 | 35 | 心得內容其實要寫什麼都行,沒有強迫,你簡單寫三個字:「我好累」或是「收穫多」也都可以,當日記在寫就好,我之前就先示範了[每日筆記](https://github.com/aszx87410/daily-notes/issues),記錄一些教學上的思考。 36 | 37 | 若是你不知道心得該如何下手,這邊推薦一個不錯的模板叫做 ORID 筆記,每天根據這四項來寫: 38 | 39 | #### Objective 客觀 40 | 41 | 關於今天的課程,你記得什麼? 42 | 完成了什麼? 43 | 44 | #### Reflective 感受 45 | 46 | 你要如何形容今天的情緒 47 | 今天的高峰是什麼? 48 | 今天的低點是什麼? 49 | 50 | #### Interpretive 解釋反思 51 | 52 | 我們今天學到了什麼? 53 | 今天一個重要的領悟是什麼? 54 | 55 | #### Decisional 決定行動 56 | 57 | 我們會如何用一句話形容今天的工作? 58 | 有哪些工作需要明天繼續努力? 59 | 60 | 有了基本架構之後會容易很多,你只要根據提供的問題模板去思考就行了。 61 | 62 | 細節可參考:[初探 ORID 焦點討論法](https://blog.niclin.tw/2016/08/09/%E5%88%9D%E6%8E%A2-orid-%E7%84%A6%E9%BB%9E%E8%A8%8E%E8%AB%96%E6%B3%95/)、[如何使用ORID总结学习,加快进步?](https://www.jianshu.com/p/56e5bf8ae9ee) 63 | 64 | ### 3. 交作業前先檢查 65 | 66 | 身為工程師,在交付產品以前自己有義務先做一些基本的測試,至少不要出現一打開就掛掉或者是 UI 差超級多這種狀況。交作業也是一樣的,如果你的作業連範例附的簡單 測試都跑不過,或者是基本功能都沒完成,那我也不知道我要改什麼。 67 | 68 | 所以,在交作業前請先自己檢查一下,如果品質太差的我會直接退件。 69 | 70 | ### 4. 簡答題規範 71 | 72 | 注意,簡答題不像你以前學生時期做報告那樣可以直接複製貼上,這是最沒有用的答題方法。我希望的是你找資料閱讀,吸收並理解以後再用自己的文字寫出來,這樣的理解程度會高很多,而不是複製貼上就了事。若是只會複製貼上,我保證一個月後我再問你同樣的問題,你也答不出來。 73 | 74 | 如果真的寫不出來,可以試著看著相關資料自己照著重打,這樣也會加深記憶。 75 | 76 | 有任何查到的相關資料都可以一併附上,第一是給別人一個 credit,可以讓作者知道他的文章對你有幫助,第二也是給自己留一個筆記,之後忘記可以再回來這邊找。 77 | 78 | ### 5. 程式碼規範 79 | 80 | 第三期首次導入 [eslint](https://eslint.org),幫整個專案都裝了 eslint,每一次 commit 都會自動檢查 JavaScript 的程式碼,有違反規則的話需要修正以後才能 commit。從第一週開始就強迫大家養成良好的程式碼撰寫習慣。 81 | 82 | ### 其他 83 | 84 | 1. 第十三週以前禁止使用 jQuery(除非你原生的 DOM API 真的很熟了) 85 | 86 | ## 課程進行方式 87 | 88 | 本期進行方式與前兩期差異頗大,這期「原則上完全沒有直播」,課程以線上影片為主,全部課程內容皆為預錄好的線上影片(無字幕)。 89 | 90 | 每一週都會有指定教材以及導讀影片,若有需要的話可以自行尋找其他資源學習。 91 | 92 | 還有一點請特別注意,沒教的內容也可能出現在作業裡,不要被當期的內容給迷惑了,以為一定要用當週教的東西來解題。 93 | 94 | ## 課程大綱 95 | 96 | 從 2019/04/15 至 2019/10/15 ,為期六個月的課程,一共約二十六週。每週的開始為禮拜一,結束為禮拜日。 97 | 98 | ### 第一週(04/15 ~ 04/21):暖身週 99 | 100 | 大致介紹整個計畫以及帶學生看過一次課程大綱,接著說明整體架構,介紹各種不同工程師職位所負責的工作內容並著重在網頁工程師的介紹,並說明課程進行方式。 101 | 102 | 除此之外,也會帶大家看一下學習的方法並推薦相關課程,為之後的課程做好準備。 103 | 104 | Mindset 建立: 105 | 106 | 1. 不要害怕問問題,每個問題都值得被提出來,你的問題可能也是其他人的問題 107 | 2. 問問題前應該要自己查詢資料(有些很難查的直接問也可以) 108 | 3. 你有老師讓你盡量問,反正問就對了,有錯的話我會提醒你 109 | 4. 重點是「目的」,而不是「手段」,持續問為什麼為什麼為什麼為什麼 110 | 5. 學程式需要換一個思維模式 111 | 112 | 建置基礎環境,例如說 Command Line Tool 與 Git,以及學會如何交作業。 113 | 114 | 指定教材: 115 | 116 | 1. [CMD101] Command Line 超新手入門:全部 117 | 2. [GIT101] Git 超新手入門:全部 118 | 3. [CS101] 初心者的計概與 coding 火球術:1-1 ~ 2-4、4-1、4-2、11 119 | 4. 程式導師實驗計畫第二期:Lesson 1-1(可以快轉忽略與第二期本身相關的部分) 120 | 121 | [HW1 作業連結](/homeworks/week1) 122 | 123 | #### 自我檢測 124 | 125 | - [ ] 你說得出程式如何執行 126 | - [ ] 你理解寫程式的本質只是一行行的指令 127 | - [ ] 你了解前端與後端的區別 128 | - [ ] 你能說出從發出一個 request 到接收 response 中間發生的事 129 | - [ ] 你了解不同載具的差異在哪(Desktop、Mobile、Web) 130 | - [ ] 你了解基本的 command line 指令 131 | - [ ] 你知道 Git 在做什麼,以及為何我們需要 Git 132 | - [ ] 你知道 add、commit、push、pull 等基本 Git 指令 133 | - [ ] 你知道怎麼使用 branch 並送出 Pull Request 134 | - [ ] 你熟悉 Git Workflow(其實就是交作業的流程) 135 | 136 | ### 第二週(04/22 ~ 04/28):程式基礎(上) 137 | 138 | 前四週其實是這個計畫最重要的一個月,希望能在這四週讓學生把基礎打得相對紮實,這樣比較好應付之後的課程。 139 | 140 | 這一週的學習目標是程式基礎,包括但不限於:變數、陣列、迴圈、判斷式以及函式(以 ES5 為例)。 141 | 142 | 必須要強迫自己轉換成寫程式的思考模式,否則這一週對你來說會是惡夢。對於從來沒有接觸過類似思考模式的人可能會需要點時間,但只要慢慢練習,就會越來越進入狀況。 143 | 144 | 還有一點請大家注意,程式是按照你寫的跑,不是按照你想的跑。當程式執行結果超出預期時,`console.log`是你的好朋友,可以把東西印出來看看是不是跟你想的一樣。 145 | 146 | 最後,在這週也會講到 eslint,我已經幫大家設置好了 eslint,這是一個能夠幫你自動做語法檢查的工具,在每次 commit 之前都會自動檢查程式碼的規範,不符合規範的話不會讓你 commit。 147 | 148 | 指定教材: 149 | 150 | 1. [JS101] 用 JavaScript 一步步打造程式基礎:開頭到綜合練習 Lv1 151 | 152 | 進階閱讀: 153 | 154 | 1. [CS101] 初心者的計概與 coding 火球術:7-1~7-4 155 | 156 | [HW2 作業連結](/homeworks/week2) 157 | 158 | #### 自我檢測: 159 | 160 | - [ ] 你能靈活運用變數、迴圈、判斷式等等基本概念來解題 161 | - [ ] 你能一行行的說出現在程式在做什麼 162 | - [ ] 你知道「回傳」跟「輸出」的差異 163 | - [ ] 你可以把用文字寫好的演算法轉成程式碼 164 | 165 | ### 第三週(04/29 ~ 05/05):程式基礎(下) 166 | 167 | 在程式基礎的部分一週是絕對不夠的,因此本週會繼續加強程式基礎。在這一週裡面我們會延伸上一週的內容,並且多講一些有關於 ES6 的語法。 168 | 169 | 像是介紹常用內建函式如 replace、indexOf、split、map、filter、join、parseInt 以及 Math 等等。 170 | 171 | 也會教大家寫簡單的 unit test,並且自己寫 test case 檢驗自己的函式。 172 | 173 | 本週的作業有自動批改系統,請傳到 [Lidemy OJ](https://lidemy-oj.netlify.com) 上,並且確認每一題都有答對之後再交作業,否則我會直接退件(hw5 除外,因為這題比較難,沒有通過依然可以先交作業)。 174 | 175 | [HW3 作業連結](/homeworks/week3) 176 | 177 | 指定教材: 178 | 179 | 1. [JS101] 用 JavaScript 一步步打造程式基礎:全部 180 | 2. [JS102] 升級你的 JavaScript 技能:ES6 + npm + Jest:全部 181 | 182 | 上一期相關部分: 183 | 184 | 1. 程式導師實驗計畫第二期:Week2 加強 JavaScript 185 | 2. 程式導師實驗計畫第二期:Week2 - ES6 186 | 187 | 寫完作業以後才能看: 188 | 189 | 1. 程式導師實驗計畫第二期:Week3 - 第二週作業檢討 190 | 191 | #### 自我檢測 192 | 193 | - [ ] 你理解常用內建函式如何使用 194 | - [ ] 你熟悉程式語法並知道如何解決基礎問題 195 | - [ ] 你知道為什麼我們需要 unit test 196 | - [ ] 你知道什麼是 unit test 197 | - [ ] 你知道如何寫 unit test 198 | - [ ] 你知道如何測試一個 function 199 | 200 | ### 第四週(05/06 ~ 05/12):網路基礎 201 | 202 | 無論是前端還是後端,身為一個網頁工程師,你必須很清楚整個網路運作的輪廓。細節你可以日後再研究,但一定要能掌握大方向以及重要概念,否則你未來的路絕對會走得很崎嶇。 203 | 204 | 在這週裡面我們會學到兩台電腦在網路上該怎麼溝通,從上層往下,再從底層往上,一步步建立起你對網路的世界觀。 205 | 206 | 當然,只有理解是不夠的,我們也會用 Node.js 讓你實作簡單的網路爬蟲以及串接基本的 API,帶你熟練與網路相關的知識。 207 | 208 | [HW4 作業連結](/homeworks/week4) 209 | 210 | 指定教材: 211 | 212 | 1. [NET101] 網路基礎概論(搭配 JS 實作練習):全部 213 | 2. [CS101] 初心者的計概與 coding 火球術:4-1 ~ 4-4 214 | 3. [從拉麵店的販賣機理解什麼是 API](https://medium.com/@hulitw/ramen-and-api-6238437dc544) 215 | 216 | #### 自我檢測 217 | 218 | - [ ] 你知道網路背後大概的運作模式 219 | - [ ] 你知道什麼是 Request 跟 Response 220 | - [ ] 你知道什麼是 DNS 以及運作原理 221 | - [ ] 你知道 HTTP 與 HTTPS 的差異 222 | - [ ] 你知道 localhost 跟 127.0.0.1 是什麼 223 | - [ ] 你知道 GET 與 POST 的差別 224 | - [ ] 你知道常用的 HTTP Header 225 | - [ ] 你知道什麼是 API 226 | - [ ] 你會使用 node.js 寫出串接 API 的程式 227 | - [ ] 你知道 HTTP method 有哪些 228 | - [ ] 你知道基本的 HTTP statud code,像是 200、301、400、404、500 229 | 230 | ### 第五週(05/13 ~ 05/19):複習週 231 | 232 | 經過前面四週的各種摧殘,終於迎來了第一次的複習週! 233 | 234 | 複習週顧名思義,就讓大家複習前面這四週的進度用的,這四週我們一共學了四項主要的技能: 235 | 236 | 1. Command line 的使用 237 | 2. Git 的基本操作 238 | 3. JavaScript 基本語法及程式思維 239 | 4. 網路基本概念 240 | 241 | 如果你之前因為趕時間亂寫而亂寫作業,現在是回去重新省視一遍的好時機;或者是之前有查到什麼有趣的延伸資料但沒時間看的,這一週你就有時間看了。 242 | 243 | 在複習週是沒有任何進度的,但是會有兩個小挑戰,讓你們檢驗自己前面學到的技能。 244 | 245 | #### HTTP Game 246 | 247 | 為了檢驗你對於 API 串接是否理解,我特地做了一個很有趣的小遊戲:[Lidemy HTTP Challenge](https://lidemy-http-challenge.herokuapp.com/start)。 248 | 249 | 建議使用之前教過的 node.js 搭配 [request](https://github.com/request/request) 這個 library 來解題,才能比較有效確認自己是否前面都有學進去。 250 | 251 | 我有藏了一些很無聊的梗在裡面,解題的時候可以順便找找。 252 | 253 | #### NPSC 題目練習 254 | 255 | NPSC 中文全名為[網際網路程式設計全國大賽](https://contest.cc.ntu.edu.tw/npsc2018/),是台大每年都會辦給國中生跟高中生參加的比賽。 256 | 257 | 裡面很多題目都很有趣,適合拿來給程式初學者練習,我特地找了一些比較簡單的題目,大家可以用來檢驗自己的程式基礎是否紮實:[Lidemy OJ](https://lidemy-oj.netlify.com/contests)。 258 | 259 | [HW5 作業連結](/homeworks/week5) 260 | 261 | ### 第六週(05/20 ~ 05/26):前端基礎(一) 262 | 263 | 本週將會正式進入到前端課程的領域,開始用 HTML 與 CSS 打造出基本的網頁,並且利用 media query 實現簡單的 RWD(Responsive Web Design)。 264 | 265 | HTML 的部分就簡單帶過幾個常見的 tag,帶到 head 的一些屬性跟設定,也會講到跟 SEO 有關的一些 tag(title, description, json ld...)。 266 | 267 | 主要會著重在 CSS 的部分,並且讓大家多多練習。 268 | 269 | 也可以先看一下這兩篇文章(很多地方你會看不懂,但沒關係)先培養一下對前端的感覺,等幾週過後當我們學得越來越多,再看一次會有完全不同的感受:[零基礎的小明要如何成為前端工程師?](https://medium.com/hulis-blog/frontend-engineer-guide-297821512f4e)、[跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR](https://medium.com/@hulitw/introduction-mvc-spa-and-ssr-545c941669e9) 270 | 271 | 指定教材: 272 | 273 | 1. [FE101] 前端基礎:HTML 與 CSS:全部 274 | 2. 程式導師實驗計畫第二期:Week3-2 - CSS 275 | 3. [Chrome 網頁除錯功能大解密](https://www.udemy.com/chrome-devtools/) 276 | 277 | 寫完作業才能看: 278 | 279 | 1. 程式導師實驗計畫第二期:Week4-1 - 上週作業檢討 280 | 281 | [HW6 作業連結](/homeworks/week6) 282 | 283 | #### 自我檢測 284 | 285 | - [ ] 你知道 HTML 是在做什麼的 286 | - [ ] 你知道如何使用有語意的(semantic)標籤 287 | - [ ] 你知道基本 SEO 的概念 288 | - [ ] 你知道 CSS 是什麼 289 | - [ ] 你知道 inline、block 跟 inline-block 的區別 290 | - [ ] 你知道什麼是 box model 291 | - [ ] 你知道 position 的所有屬性及其差別 292 | - [ ] 你知道 :hover, :before, :after 293 | - [ ] 你知道 :nth-child 的各種用法 294 | - [ ] 你熟悉 CSS selector,可以輕鬆選到想選到的元素 295 | 296 | ### 第七週(05/27 ~ 06/02):前端基礎(二) 297 | 298 | 這一週將會進入到 JavaScript,讓網頁變得有互動性,並結合 `
` 做表單驗證,以及讓大家寫出簡單的網頁應用程式。 299 | 300 | 這會是我們第一次把 JavaScript 應用在網頁上,來學習怎麼使用 JavaScript 操控 DOM 物件,讓網頁動起來。 301 | 302 | 指定教材: 303 | 304 | 1. [FE102] 前端必備:JavaScript:到 ajax 之前 305 | 2. 程式導師實驗計畫第二期:Week4-2 - JavaScript 306 | 307 | 指定閱讀: 308 | 309 | 1. [DOM 的事件傳遞機制:捕獲與冒泡](https://blog.techbridge.cc/2017/07/15/javascript-event-propagation/) 310 | 311 | [HW7 作業連結](/homeworks/week7) 312 | 313 | #### 自我檢測 314 | 315 | - [ ] 你知道 JavaScript 跑在網頁上跟跑在 Node.js 上差在哪裡 316 | - [ ] 你知道 DOM 是什麼 317 | - [ ] 你知道如何用 JavaScript 操控 DOM 物件 318 | - [ ] 你知道如何幫一個按鈕加上 event listener 319 | - [ ] 你知道捕獲與冒泡是什麼 320 | - [ ] 你知道什麼是事件代理(delegation) 321 | - [ ] 你知道怎麼用 JavaScript 更改元素的 style 322 | - [ ] 你知道 preventDefault 與 stopPropagation 的差異 323 | 324 | ### 第八週(06/03 ~ 06/09):前端基礎(三) 325 | 326 | 之前在第四週時有提過 API,也有讓大家試著用 node.js 寫些小程式來串接。 327 | 328 | 而前端當然也能串接 API,理解前後端如何串接是很重要的一部分,因此這週會花滿多心力再來講 API 串接,讓大家複習一下 API 的概念,並且教大家什麼是 Ajax。 329 | 330 | 指定教材: 331 | 332 | 1. [FE102] 前端必備:JavaScript:ajax 以後 333 | 334 | 寫完作業才能看: 335 | 336 | 1. [從假資料到真資料:Ajax 與 API 串接](https://www.youtube.com/watch?v=PNGRPYFcAms) 337 | 338 | 339 | 相關學習資源: 340 | 341 | 1. [輕鬆理解 Ajax 與跨來源請求](https://blog.techbridge.cc/2017/05/20/api-ajax-cors-and-jsonp/) 342 | 2. [RESTful API Design by TritonHo](https://github.com/TritonHo/slides/blob/master/Taipei%202016-04%20talk/RESTful%20API%20Design-tw-2.1.pdf) 343 | 344 | 345 | [HW8 作業連結](/homeworks/week8) 346 | 347 | ### 自我檢測 348 | 349 | - [ ] 你知道什麼是 API 350 | - [ ] 你知道什麼是 Ajax 351 | - [ ] 你知道從網頁前端呼叫 API 與在自己電腦上寫程式呼叫的差異 352 | - [ ] 你知道什麼是同源政策(Same-origin policy) 353 | - [ ] 你知道如何存取跨網域的資源(CORS) 354 | - [ ] 你知道什麼是 JSON 355 | - [ ] 你知道什麼是 JSONP 及其原理 356 | - [ ] 你知道 Fetch 的基本使用方法 357 | 358 | ### 第九週(06/10 ~ 06/16):後端基礎(一) 359 | 360 | 前端基礎打得差不多以後,就要進入後端的課程,這次課程會以 PHP 為主要的語言,Node.js 為輔助。 361 | 362 | 這週的課程會講解 PHP 基本觀念、語法,並且教大家安裝設定 MySQL,寫出簡單的 CRUD 應用。 363 | 364 | 指定教材(學習順序請參考 Lidemy.com 上的說明): 365 | 366 | 1. 程式導師實驗計畫:Lesson 5-1 之後端基礎 367 | 2. 程式導師實驗計畫:Lesson 5-2 之資料庫 368 | 3. [CS101] 初心者的計概與 coding 火球術:5-3 369 | 4. [BE101] 用 PHP 與 MySQL 學習後端基礎:全部 370 | 5. 程式導師實驗計畫第二期:Week5-2:物件導向程式設計 371 | 6. Week5 物件導向(續):繼承與 static 372 | 373 | 上一期相關內容: 374 | 375 | 1. 程式導師實驗計畫第二期:Week5 - 後端基礎 376 | 377 | 物件導向相關閱讀: 378 | 379 | 1. http://expect7.pixnet.net/blog/post/38682120 380 | 2. https://noob.tw/java-oop/ 381 | 3. https://blog.miniasp.com/post/2009/08/27/OOP-Basis-What-is-class-and-object.aspx 382 | 4. http://blog.turn.tw/?p=3093 383 | 5. https://www.ptt.cc/bbs/OOAD/M.1256403807.A.8AE.html 384 | 385 | 如果作業寫不出來,可參考: 386 | 387 | 1. 程式導師實驗計畫第二期:Week10-1 PHP 簡易會員系統 + 留言板 388 | 2. 程式導師實驗計畫:Lesson 6-1 之 live coding 389 | 3. 程式導師實驗計畫:Lesson 5-3 之作業檢討 390 | 391 | 相關學習資源: 392 | 393 | 1. [第一正規化(First Normal Form, 1NF)](https://matthung0807.blogspot.com/2017/11/first-normal-form-1nf.html) 394 | 395 | [HW9 作業連結](/homeworks/week9) 396 | 397 | #### 自我檢測 398 | 399 | - [ ] 你知道 PHP 是什麼 400 | - [ ] 你知道前端與後端的差別 401 | - [ ] 你知道什麼是資料庫 402 | - [ ] 你了解基本的 SQL 語法,包括 Select、Insert Into、Delete 與 Update 403 | - [ ] 你能夠寫出基本到 CRUD 應用 404 | 405 | ### 第十週(06/17 ~ 06/23):複習週 406 | 407 | 這是第二次的複習週,在前四週我們一共學了: 408 | 409 | 1. HTML 與 CSS 410 | 2. DOM 以及 JavaScript 如何與網頁互動 411 | 3. 前端利用 Ajax 與後端串接 412 | 4. PHP 與 MySQL 413 | 414 | 這一週可以讓你有時間好好複習之前的內容,若是覺得都 ok 了,也可以試試看之前的進階挑戰題、挑戰題以及超級挑戰。 415 | 416 | 這次跟第五週一樣,怕大家太無聊,於是準備了兩個有趣的小遊戲給大家玩。 417 | 418 | ### 綜合能力測驗 419 | 420 | 這邊有一份參考某間公司面試考題的[綜合能力測驗](http://mentor-program.co/huli/game/index.php),還滿有趣的,主要是測前幾週的整合能力。 421 | 422 | 如果你點進去看到一片白畫面,那或許不代表網頁壞了。 423 | 424 | ### 闖關遊戲 425 | 426 | 一共十關,看你能闖到第幾關:[r3:0 異世界網站挑戰](https://r30challenge.herokuapp.com/)(特別感謝 @minw 製作遊戲)。 427 | 428 | [HW10 作業連結](/homeworks/week10) 429 | 430 | ### 第十一週(06/24 ~ 06/30):後端基礎(二) 431 | 432 | 接下來幾週都會以之前的留言板作為主軸,一步步加強它,使它成為一個比較完整的產品。 433 | 434 | 在這過程中你會學到許多新的後端概念,也會幫留言板加上更多更多的新功能! 435 | 436 | 指定教材(學習順序請參考 Lidemy.com 上的說明): 437 | 438 | 1. [BE101] 用 PHP 與 MySQL 學習後端基礎:全部 439 | 2. [CS101] 初心者的計概與 coding 火球術:4-3、5-4 440 | 441 | [HW11 作業連結](/homeworks/week11) 442 | 443 | #### 自我檢測 444 | 445 | - [ ] 你知道什麼是雜湊(Hash function) 446 | - [ ] 你知道什麼是加密(Encryption) 447 | - [ ] 你知道雜湊與加密的差別 448 | - [ ] 你知道什麼是 Session 449 | - [ ] 你知道什麼是 Cookie 450 | - [ ] 你知道 Cookie、Local Storage 與 Session Storage 的差別 451 | - [ ] 你知道 Session 與 Cookie 的差別 452 | 453 | ### 第十二週(07/01 ~ 07/07):後端基礎(三) 454 | 455 | 這一週我們要強調一個很重要的觀念:資訊安全。 456 | 457 | 無論你是前端還是後端,都必須時時刻刻在心裡惦記著資訊安全的概念,總結為一句話就是:「不要相信任何來自 client 端的資料」,只要能做到這點,其實就可以阻止掉很多的惡意攻擊。 458 | 459 | 指定教材(學習順序請參考 Lidemy.com 上的說明): 460 | 461 | 1. [BE101] 用 PHP 與 MySQL 學習後端基礎:全部 462 | 2. 程式導師實驗計畫:Lesson 6-2 之 Web Security 463 | 3. 程式導師實驗計畫:Lesson 6-3 之 HW6 作業檢討 464 | 4. 程式導師實驗計畫第二期:Week6-1:後端基礎(中) 465 | 5. 程式導師實驗計畫第二期:Week6-2:資訊安全 466 | 6. [CS101] 初心者的計概與 coding 火球術:5-5 467 | 468 | 若是作業寫不出來: 469 | 470 | 1. 程式導師實驗計畫第二期:Week10-2 會員系統安全加強 + 兩層留言板 471 | 2. 程式導師實驗計畫第二期:Week11-1 資訊安全加強 472 | 473 | 延伸閱讀: 474 | 475 | 1. [讓我們來談談 CSRF](https://blog.techbridge.cc/2017/02/25/csrf-introduction/) 476 | 477 | [HW12 作業連結](/homeworks/week12) 478 | 479 | #### 自我檢測 480 | 481 | - [ ] 你知道什麼是 SQL Injection 以及如何防範 482 | - [ ] 你知道什麼是 XSS 以及如何防範 483 | - [ ] 你知道什麼是 CSRF 以及如何防範 484 | - [ ] 你知道為什麼儘管前端做了驗證,後端還是要再做一次驗證 485 | 486 | ### 第十三週(07/08 ~ 07/14):前端基礎(四) 487 | 488 | 首先帶大家串接之前自己寫出來的 API,把前端介面用 Ajax 改寫,使網頁互動性變得更高。讓大家熟悉 jQuery,把現有應用用 jQuery 改寫一次。 489 | 490 | 版面的部分則利用 Bootstrap 搭配 Bootswatch 讓介面變得美觀。利用網格系統實作 RWD。 491 | 492 | 除了這些呢,也會幫大家補充 Promise 的一些用法。 493 | 494 | 指定教材: 495 | 496 | 1. 程式導師實驗計畫第二期:Week7-1 前端基礎(下) 497 | 2. 程式導師實驗計畫第二期:Week7-2 Fetch & Promise 498 | 3. 程式導師實驗計畫:Lesson 7-1 之 jQuery 與 Bootstrap 499 | 4. 程式導師實驗計畫:Lesson 7-2 之 jQuery Bootstrap 實戰應用 500 | 501 | 作業寫不出來可參考: 502 | 503 | 1. 程式導師實驗計畫第二期:Week11-2 改寫 Ajax 504 | 505 | [HW13 作業連結](/homeworks/week13) 506 | 507 | #### 自我檢測 508 | 509 | - [ ] 你知道 jQuery 是做什麼的 510 | - [ ] 你知道 jQuery 與 vanilla js 的差別 511 | - [ ] 你知道用 Ajax 去 call API 與伺服器直接輸出資料的差別 512 | - [ ] 你知道如何與自己寫的 API 串接 513 | - [ ] 你知道什麼是 Bootstrap 514 | - [ ] 你知道 Bootstrap 原理及如何應用 515 | - [ ] 你知道什麼是網格系統以及如何應用在 RWD 516 | - [ ] 你知道什麼是 Promise 517 | - [ ] 你知道 Promise 的三種狀態 518 | 519 | ### 第十四週(07/15 ~ 07/21):後端基礎(四) 520 | 521 | 有了自己的前後端程式之後,就可以開始來部署了。這週的重點會放在帶大家直接去買主機(AWS、Digital Ocean、Linode),並且了解如何連上主機。 522 | 523 | 也會讓大家購買自己的網域,理解如何將網域以及主機串連起來,讓大家可以連線到你的網站。 524 | 525 | 在這個章節也會讓大家理解後端基本架構(NAT、Load balancer、DB replication 等等) 526 | 527 | 最後也會補齊跟資料庫的一些知識,像是 ACID、Transaction、View 以及 Stored procedure。 528 | 529 | 這週也要特別感謝 [gandi](https://www.gandi.net/) 連續三期全額贊助了網域的費用 <(_ _)>。 530 | 531 | 532 | 指定教材(學習順序請參考 Lidemy.com 上的說明): 533 | 534 | 1. 程式導師實驗計畫:Lesson 8-2 之資料庫 535 | 2. 程式導師實驗計畫第二期:Week8-1 後端基礎(下) 536 | 3. 程式導師實驗計畫:Lesson 8-1 之後端基礎與網路相關知識 537 | 4. 程式導師實驗計畫:Lesson 8-3 之 hw8 作業檢討 538 | 5. 程式導師實驗計畫第二期:Week9-1 基礎到中階 539 | 540 | 推薦閱讀: 541 | 542 | 1. [部署 AWS EC2 遠端主機 + Ubuntu LAMP 環境 + phpmyadmin](https://github.com/Lidemy/mentor-program-2nd-yuchun33/issues/15) 543 | 2. [一小時完成 VPS (Virtual Private Server) 部署](https://github.com/Lidemy/mentor-program-2nd-futianshen/issues/21) 544 | 3. [如何遠端連接虛擬主機上的 mySQL 資料庫 ?](https://github.com/Lidemy/mentor-program-2nd-futianshen/issues/33) 545 | 546 | 相關學習資源: 547 | 548 | 1. [MySQL 超新手入門(11)Views](http://www.codedata.com.tw/database/mysql-tutorial-11-views/) 549 | 2. [MySQL Views](http://www.mysqltutorial.org/mysql-views-tutorial.aspx) 550 | 3. [MySQL 超新手入門(13)Stored Routines 入門](http://www.codedata.com.tw/database/mysql-tutorial-13-stored-routines/) 551 | 4. [只要說「我要下午茶!」——什麼是資料庫預存程序?](http://www.newtype.com.tw/aw/Article_ShareDetail.aspx?UniqueID=3) 552 | 5. [MySQL Stored Procedure](http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx) 553 | 6. [MySQL 超新手入門(16)Triggers](http://www.codedata.com.tw/database/mysql-tutorial-16-triggers/) 554 | 7. [MySQL Triggers](http://www.mysqltutorial.org/mysql-triggers.aspx) 555 | 8. [跟 Trigger 與 View 相關的簡報 by TritonHo](https://github.com/TritonHo/slides/blob/master/internal-talk/internal_talk1.pdf) 556 | 9. [跟 ACID 有關的簡報 by TritonHo](https://github.com/TritonHo/slides/blob/master/Taipei%202018-06%20talk/lesson0.pdf) 557 | 10. [MySQL CREATE INDEX](http://www.mysqltutorial.org/mysql-index/mysql-create-index/) 558 | 11. Stored procedure 相關討論:[討論一](https://www.facebook.com/groups/616369245163622/permalink/1315254285275111/)、[討論二](https://www.facebook.com/groups/616369245163622/permalink/1316314398502433/)、[討論三](https://www.facebook.com/groups/616369245163622/permalink/1315406481926558/)、[討論四](https://www.facebook.com/yftzeng.tw/posts/10209307179835921) 559 | 560 | [HW14 作業連結](/homeworks/week14) 561 | 562 | #### 自我檢測 563 | 564 | - [ ] 你知道虛擬空間、虛擬主機以及實體主機的差別 565 | - [ ] 你知道什麼是網域(Domain) 566 | - [ ] 你知道如何設定網域(A、CNAME) 567 | - [ ] 你知道如何用 SSH 遠端連線到自己的主機 568 | - [ ] 你知道如何部署應用程式 569 | - [ ] 你知道什麼是 No SQL 570 | - [ ] 你知道什麼是 Transaction 與 lock 571 | - [ ] 你知道資料庫的 ACID 是什麼 572 | - [ ] 你知道什麼是資料庫的 View 以及使用時機 573 | - [ ] 你知道什麼是 Stored procedure 以及如何使用 574 | - [ ] 你知道資料庫的 Trigger 以及使用時機 575 | 576 | ### 第十五週(07/22 ~ 07/28):複習週 577 | 578 | 終於到了第三次的複習週,這次要複習的東西比以往都多了點: 579 | 580 | 1. Session 與 Cookie 的差異 581 | 2. 資訊安全(Hashing, SQL Injection, XSS) 582 | 3. jQuery 583 | 4. Bootstrap 584 | 5. Promise 585 | 6. 部署 586 | 587 | 這次提供三個跟資訊安全相關的練習網站,都跟我們以前複習週的模式差不多,可以一直闖關: 588 | 589 | 1. https://xss-game.appspot.com([解題影片,有雷](https://www.youtube.com/watch?v=MMMkvHwqPRY)) 590 | 2. http://www.hackertest.net/ 591 | 3. http://xss-quiz.int21h.jp/ (這個可能會被 Chrome 擋下來...可以用 Firefox 或是其他網站玩) 592 | 593 | 祝大家玩得開心! 594 | 595 | 另外,這一週的作業除了心得以外,也提供了一個跟以往不太一樣的測驗:[網站前後端開發基礎測試](https://forms.gle/qvrQc9pWWNGaoGpn8),一共十題簡答題,Google 表單在送出之後可以看見參考解答,能夠自己對答案。 596 | 597 | [HW15 作業連結](/homeworks/week15) 598 | 599 | ### 第十六週(07/29 ~ 08/04):前端中階(上) 600 | 601 | 這週的東西比較分散一些,我們會著重在三個部分: 602 | 603 | 1.CSS 預處理器 604 | 605 | 在被 CSS 折磨這麼久之後,終於有機會用程式化的方法來撰寫 CSS,這週將介紹幾個不同的 CSS preprocessor(LESS, SASS, Stylus),讓學生自行選擇看順眼的並且練習,把之前的 CSS 都改寫。 606 | 607 | 2.基本資料結構 608 | 609 | 這週會介紹到基本的資料結構 stack 與 queue 與 JavaScript 的物件導向。 610 | 611 | 3.什麼是快取(Cache)? 612 | 613 | 快取對工程師來說是一定要理解的概念,前端有前端的快取,後端也有後端的。這週主要會著重在前端快取的介紹上。 614 | 615 | 指定教材(學習順序請參考 Lidemy.com 上的說明): 616 | 617 | 1. 程式導師實驗計畫:Lesson 9-1 之 CSS 預處理器 618 | 2. 程式導師實驗計畫:Lesson 9-2 之資料結構、Cache 與 Event Loop 619 | 3. 程式導師實驗計畫:Lesson 9-3 之作業檢討 620 | 4. 程式導師實驗計畫第二期:Week9-1 基礎到中階 621 | 5. 程式導師實驗計畫第二期:Week9-2 JavaScript 執行原理 622 | 623 | [HW16 作業連結](/homeworks/week16) 624 | 625 | #### 自我檢測 626 | 627 | - [ ] 你知道什麼是 Cache 628 | - [ ] 你知道 HTTP Cache 的原理以及相關 Header 629 | - [ ] 你了解 CSS 預處理器的目的以及原理 630 | - [ ] 你知道什麼是 Stack 631 | - [ ] 你知道什麼是 Queue 632 | - [ ] 你可以用 JavaScript 實作出 Stack 跟 Queue 633 | - [ ] 你知道 CSS Selector 權重的計算方式 634 | 635 | ### 第十七週(08/05 ~ 08/11):前端中階(中) 636 | 637 | 本週主要會放在 JavaScript 的一些重要基礎以及瀏覽器運作時的機制。 638 | 639 | 第一個重點是瀏覽器在運行 JavaScript 時的 Event Loop 機制。 640 | 641 | 第二個重點就是 JavaScript 的一些重要基礎,包含:scope、hoisting、closure、prototype、this 等等。 642 | 643 | 指定教材: 644 | 645 | 1. 程式導師實驗計畫第二期:Week9-2 JavaScript 執行原理 646 | 2. [JS201] 進階 JavaScript:那些你一直搞不懂的地方 647 | 3. [What the heck is the event loop anyway? | Philip Roberts | JSConf EU](https://www.youtube.com/watch?v=8aGhZQkoFbQ) 648 | 649 | [HW17 作業連結](/homeworks/week17) 650 | 651 | #### 自我檢測 652 | 653 | - [ ] 你知道 Event Loop 的運作方式 654 | - [ ] 你知道什麼是作用域(Scope) 655 | - [ ] 你知道 Hoisting(提升)是什麼 656 | - [ ] 你知道 Hoisting 的原理為何 657 | - [ ] 你知道 Closure(閉包)是什麼 658 | - [ ] 你能夠舉出一個運用 Closure 的例子 659 | - [ ] 你知道 Prototype 在 JavaScript 裡是什麼 660 | - [ ] 你知道大部分情況下 this 的值是什麼 661 | 662 | ### 第十八週(08/12 ~ 08/18):前端中階(下) 663 | 664 | 這週將學習把工作自動化,利用 gulp 管理工作流程,避免繁瑣的手動操作。 665 | 666 | 也會講到 Webpack 誕生的理由以及模組化的 JavaScript 開發,讓學生理解為何需要使用 Webpack。 667 | 668 | 除此之外也會講到一些與 CSS 相關的優化小技巧,例如說針對圖片做優化的 CSS Sprites 或是 Data URI,或是 JavaScript 與 CSS 的 uglify、minify 等等。 669 | 670 | 最後也會用跟以往不太一樣的模式,做出一個簡單的 todo list。 671 | 672 | 指定教材: 673 | 674 | 1. 程式導師實驗計畫:Lesson 10-1 之 gulp 與 webpack 675 | (注意,影片裡面教的是舊版的 Gulp 與 Webpack,學概念就好,實作請參考其他教學或是官方文件) 676 | 677 | 寫完作業可參考: 678 | 679 | 1. 程式導師實驗計畫:Lesson 10-2 之 HW10 作業檢討 680 | 681 | [HW18 作業連結](/homeworks/week18) 682 | 683 | #### 自我檢測 684 | 685 | - [ ] 你知道 gulp 的目的以及原理 686 | - [ ] 你知道 webpack 的目的以及原理 687 | - [ ] 你熟悉如何使用 webpack 進行模組化開發 688 | - [ ] 你熟悉如何使用 gulp 建構自動化工作流程 689 | - [ ] 你能夠快速打造出基礎環境 690 | - [ ] 你知道 CSS 優化的一些小技巧 691 | - [ ] 你知道 CSS Sprites 與 Data URI 的優缺點 692 | - [ ] 你知道什麼是 uglify 與 minify 693 | 694 | ### 第十九週(08/19 ~ 08/25):網路基礎複習 695 | 696 | 學到這週為止,前後端的概念你應該滿清楚了,我們也學了不少東西,下一週是複習週,再下一週就要正式進入前後端框架的領域了。 697 | 698 | 在進入到那邊以前,我們還要來複習一些東西並且加強基礎。 699 | 700 | 我們首先要加強的第一個東西是複習前面教的網路基礎,你必須對前後端溝通的每一個流程都很確定,在之後的單元中才不會迷失自我。 701 | 702 | 接著要來講的是 SPA,還記得之前貼給你們看過的那兩篇文章嗎?[零基礎的小明要如何成為前端工程師?](https://medium.com/hulis-blog/frontend-engineer-guide-297821512f4e)、[跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR](https://medium.com/@hulitw/introduction-mvc-spa-and-ssr-545c941669e9),這週的重點會放在這兩篇文章上面,讓大家清楚知道背後的概念為何。 703 | 704 | 指定教材: 705 | 706 | 1. 複習第四週網路概念:[CS75 (Summer 2012) Lecture 0 HTTP Harvard Web Development David Malan](https://www.youtube.com/watch?v=8KuO4r5CHjM) 707 | 2. 複習第十四週系統架構:[CS75 (Summer 2012) Lecture 9 Scalability Harvard Web Development David Malan](https://www.youtube.com/watch?v=-W9F__D3oY4) 708 | 709 | [HW19 作業連結](/homeworks/week19) 710 | 711 | #### 自我檢測 712 | 713 | - [ ] 你知道什麼是 SPA 714 | - [ ] 你知道後端 MVC 與前端 MVC 的差異 715 | - [ ] 你知道前端路由與後端路由的差異 716 | 717 | ### 第二十週(08/26 ~ 09/01):複習週 718 | 719 | 這是最後一次的複習週了,在前幾週我們一共學了: 720 | 721 | 1. CSS 預處理器 722 | 2. 基本資料結構 723 | 3. HTTP Cache 724 | 4. JavaScript 觀念:scope、hoisting、closure、prototype、this 725 | 5. Event Loop 726 | 6. Gulp 與 Webpack 727 | 7. 網頁圖片優化 728 | 729 | 至此,這個課程的基礎跟中階都學完了,從下週開始就要進入到前後端框架的領域。 730 | 731 | 為了怕大家複習週太無聊,這次也準備了一個有趣的小測驗,[Lazy Hackathon](https://lidemy.github.io/lazy-hackathon/) 是一個速度很慢的網站,原因有很多,原始碼在這裡:https://github.com/Lidemy/lazy-hackathon (特別感謝 [@yakim-shu](https://github.com/yakim-shu) 同學製作這個小測驗) 732 | 733 | 現在呢,你要來負責優化這個網站,在「不動內容」的情形下來調整,意思就是說網頁看起來要「長得一模一樣」,把圖片變黑白、刪減文字或是更動排版都是不允許的,但刪減多餘的 HTML、CSS 和 JS 是 ok 的,只要保證網頁看起來一樣就行了,原始碼怎麼動隨便你,總之目標是使網站的載入速度變快。 734 | 735 | 詳細說明請參考上面的原始碼連結。 736 | 737 | 若是你沒有任何靈感,可參考 [web.dev](https://web.dev/) 或是 [Website Performance Optimization](https://www.udacity.com/course/website-performance-optimization--ud884) 738 | 739 | [HW20 作業連結](/homeworks/week20) 740 | 741 | ### 第二十一週(09/02 ~ 09/08):前後端框架(一) 742 | 743 | ### 後端框架(一) 744 | 745 | 這一週終於正式進入後端框架的領域了! 746 | 747 | 之前我們學過了原生的 PHP,而這一週呢,你要來自學一個輕量的 PHP 框架 [CodeIgniter](https://codeigniter.org.tw/)。 748 | 749 | 相信大家之前在寫留言板的時候,寫到後面會發現自己的程式碼愈來愈亂,而且不知道怎麼整理。框架就是解決這個問題的方法之一,因為它已經制定了一系列的規範,你只要學習並且照著做就好,每一個部分的分工都會比之前明確。 750 | 751 | 再者,用框架來改寫的好處就是你可以迅速跟之前的專案做比對,一定會有許多心得!所以這週在教完之後,會讓大家把之前的留言板從純 PHP 用 CodeIgniter 這套框架改寫,就可以比較一下兩者之間有哪裡不一樣。 752 | 753 | (這一週預期會卡的很嚴重,如果你卡超過兩週,請果斷先放棄這週並且往下一週前進,其實這週跟之後三週比較沒有順序關係,要先跳到下一週也是可以的) 754 | 755 | 指定教材: 756 | 757 | 1. 程式導師實驗計畫:Lesson 14-1 之 CodeIgniter 上 758 | 2. [CodeIgniter 使用手冊](https://codeigniter.org.tw/userguide3/) 759 | 760 | [HW21 作業連結](/homeworks/week21/be) 761 | 762 | #### 自我檢測 763 | 764 | - [ ] 我了解一般後端框架的各個元素 765 | - [ ] 我了解 Route 以及 MVC 766 | - [ ] 我能透體驗到純 PHP 跟有框架的差別在哪裡 767 | 768 | ### 前端框架(一) 769 | 770 | 終於要進入到前端框架 React 了(雖然嚴格來說 React 並不是一個框架,但搭配其他各種 React 生態系成員,其實就算是一個框架了)。 771 | 772 | 這週會學習到 React 的基本應用以及原理,了解為什麼我們需要使用 React。 773 | 774 | 延伸閱讀:[React 性能優化大挑戰:一次理解 Immutable data 跟 shouldComponentUpdate](https://blog.techbridge.cc/2018/01/05/react-render-optimization/) 775 | 776 | 指定教材: 777 | 778 | 1. [FE301] React 基礎:全部 779 | 2. 程式導師實驗計畫第二期:Week12-1 React 780 | 3. 程式導師實驗計畫第二期:Week12-2 React 續 781 | 4. [官方教學](https://reactjs.org/tutorial/tutorial.html) 782 | 5. [React.js 小書](http://huziketang.mangojuice.top/books/react/) 783 | 784 | 不確定有沒有幫助(因為內容跟第二期重疊的部分很多): 785 | 786 | 1. 程式導師實驗計畫:Lesson 12-1 之 React 787 | 2. 程式導師實驗計畫:Lesson 12-2 之 React 下 788 | 789 | [HW21 作業連結](/homeworks/week21/fe) 790 | 791 | #### 自我檢測 792 | 793 | - [ ] 我知道 React 的目的以及原理 794 | - [ ] 我知道我們為什麼需要 React 795 | - [ ] 我知道使用 React 跟之前使用 jQuery 的區別 796 | - [ ] 我理解 state 跟 props 的不同 797 | 798 | ### 第二十二週(09/09 ~ 09/15):前後端框架(二) 799 | 800 | ### 後端框架(二) 801 | 802 | 之前上過了 PHP 與輕量框架 CodeIgniter,這一週會帶大家上 Express 並且來用 JavaScript 寫後端。 803 | 804 | [Express](https://expressjs.com/) 是可以在 Node.js 環境下執行的輕量後端框架,自由度極高,也能夠快速開發出後端應用程式。 805 | 806 | 跟之前有完整 MVC 架構的 CodeIgniter 相比,Express 其實鬆散(或者說自由)很多,許多地方並沒有強制規範,都只是按照前人的方法或者是慣例來實踐,十個人可能會有十種不的寫法。 807 | 808 | 有了之前 PHP 以及 CodeIgniter 的基礎,我相信學習 Express 會快速許多,因此在這一週裡面可以試試看能不能快速上手 Express 並完成作業。 809 | 810 | 指定教材: 811 | 812 | 1. [BE201] Express 與 Sequelize:「ORM 與 Sequelize」單元前所有內容 813 | 814 | [HW22 作業連結](/homeworks/week22/be) 815 | 816 | #### 自我檢測 817 | 818 | - [ ] 學習如何使用 Express 及其相關套件 819 | - [ ] 學過兩套不同語言的框架之後,我能發現其中的異同 820 | - [ ] 我理解為什麼會需要框架 821 | 822 | ### 前端框架(二) 823 | 824 | 在上一週結束之後,大家應該對 React 有了一些基本的感覺,這一週我們要繼續培養對 React 的感覺,讓大家對 React 越來越熟練。 825 | 826 | 除此之外也會教大家用 React Router 這一套 library,來實做前端的路由。 827 | 828 | 指定教材: 829 | 830 | 1. [FE301] React 基礎:全部 831 | 2. 程式導師實驗計畫第二期:Week13-1 還是 React 832 | 3. 程式導師實驗計畫第二期:Week13-2 依舊 React 833 | 834 | [HW22 作業連結](/homeworks/week22/fe) 835 | 836 | 延伸閱讀:[前後端分離與 SPA](https://blog.techbridge.cc/2017/09/16/frontend-backend-mvc/)、[跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR](https://medium.com/@hulitw/introduction-mvc-spa-and-ssr-545c941669e9) 837 | 838 | #### 自我檢測 839 | 840 | - [ ] 我熟悉 React 的基本使用 841 | - [ ] 我知道如何使用 React Router 842 | - [ ] 我了解 React Router 的目的 843 | - [ ] 我知道什麼是 Single Page Application 844 | - [ ] 我理解現在的前端與以往的差別 845 | 846 | ### 第二十三週(09/16 ~ 09/22):前後端框架(三) 847 | 848 | ### 後端框架(三) 849 | 850 | 上一週我們學會了 Express 並且成功把留言板移植過來,對基本的操作都已經很熟悉了。 851 | 852 | 這一週要介紹的是一個新的東西:ORM(Object Relational Mapping),簡單來說就是把一個程式碼裡面的物件跟資料庫的物件做映射,優點就是當你操作程式裡的物件時,就會改到資料庫裡的資料。 853 | 854 | 而且你幾乎不需要寫任何 SQL Query,因為 ORM 都會幫你處理的好好的,你只要學習怎麼用就可以了。這一週會使用 Sequelize 這個套件來做 ORM 以及串接資料庫,讓你體驗看看不用寫 SQL Query 的爽快感。 855 | 856 | 指定教材: 857 | 858 | 1. [BE201] Express 與 Sequelize:「部署:Nginx + PM2」前所有單元 859 | 860 | [HW23 作業連結](/homeworks/week23/be) 861 | 862 | #### 自我檢測 863 | 864 | - [ ] 了解什麼是 ORM 865 | - [ ] 了解 ORM 的優缺點 866 | - [ ] 了解什麼是 N+1 problem 867 | 868 | ### 前端框架(三) 869 | 870 | 在之前的 React 課程中,我們已經慢慢熟悉 React 的思考模式,可是還有一些問題還沒解決,雖然你現在感受不太到,但是在 App 慢慢變大之後就會碰到了。 871 | 872 | 接續之前的課程,這一週會讓你的 Web App 變得更加完整,會導入一個新的東西:Redux,說明我們為什麼需要它。 873 | 874 | 指定教材: 875 | 876 | 1. 程式導師實驗計畫第二期:Week14-1 Redux 877 | 2. 程式導師實驗計畫:Lesson 13-1 之 React + Redux 878 | 879 | [HW23 作業連結](/homeworks/week23/fe) 880 | 881 | #### 自我檢測 882 | 883 | - [ ] 我理解 Redux 的目的以及原理 884 | - [ ] 我知道我們為什麼需要 Redux 885 | 886 | ### 第二十四週(09/23 ~ 09/29):前後端框架(四) 887 | 888 | ### 後端框架(四) 889 | 890 | 這週會使用 Nginx + PM2 來部署我們之前寫好的 Web Application。 891 | 892 | 除此之外也會簡單介紹 CI/CD。 893 | 894 | 指定教材: 895 | 896 | 1. [BE201] Express 與 Sequelize:「部署:Nginx + PM2」前所有單元 897 | 2. 程式導師實驗計畫:Lesson 14-2 之 CI/CD 898 | 899 | [HW24 作業連結](/homeworks/week24/be) 900 | 901 | #### 自我檢測 902 | 903 | - [ ] 我知道如何使用 Nginx 904 | - [ ] 我知道如何使用 PM2 905 | - [ ] 我知道如何部署 Node.js 應用程式 906 | 907 | ### 前端框架(四) 908 | 909 | 最後一週裡面我們將用 redux 來解決非同步操作的問題,讓大家知道如何利用它與 redux-promise 來解決非同步的一些問題。 910 | 911 | 指定教材: 912 | 913 | 1. 第二期 Redux 補充講解:redux-thunk 與 redux-promise 914 | 2. 程式導師實驗計畫:Lesson 13-2 之 React + Redux 下 915 | 3. 第二期 React 補充:什麼是 super 以及生命週期的運用 916 | 4. 第二期 React 補充:再來談談什麼是 this 917 | 918 | [HW24 作業連結](/homeworks/week24/fe) 919 | 920 | #### 自我檢測 921 | 922 | - [ ] 我知道 Redux 如何搭配 middleware 解決非同步操作的問題 923 | 924 | ### 第二十五週(09/30 ~ 10/06):Final Project 925 | 926 | ### 第二十六週(10/07 ~ 10/13):Final Project 927 | 928 | 929 | # Final Project 930 | 931 | 正式的課程就到這邊告一段落了,你學了前端後端與程式相關的基礎知識,接下來需要做一些作品累積經驗,因此接下來幾週都會讓同學做出屬於自己的 Final Project,建議可以與其他人合作,但也可以選擇一個人單打獨鬥。 932 | 933 | 根據第一期的經驗,其實找人合作會是比較好的選擇(第二期因進度問題沒有 Final Project)。 934 | 935 | 如果大家一點靈感都沒有的話,可以參考以下幾個提案(但有自己的想法當然是最好的): 936 | 937 | ## 留言板 938 | 939 | 既然我們這次的課程做了這麼多個留言板,不如把留言板給做到極致吧! 940 | 941 | 你可以做一個「讓大家都能申請留言板」的系統,就像是無名小站那樣,每個人都可以申請帳號,有帳號之後可以開設自己的留言板,然後可以自己選擇要不要開放訪客來留言,不開放的話就預設是只有會員可以留言。 942 | 943 | 點下去會員的帳號之後還可以看到會員個人資料,或者是直接跳到會員自己的留言板去(如果有的話)。 944 | 945 | 除此之外,如果你想走前端的話,可以試著把前端改成 SPA 試試看! 946 | 947 | ## 論壇系統 948 | 949 | 建立一個論壇系統,能有不同的板塊(討論區),例如說: 950 | 951 | 1. 閒聊 952 | 2. 購物 953 | 3. 程式相關主題 954 | 955 | 在不同板塊底下都可以發表文章,除了發表文章以外,下面也能夠有回覆。 956 | 957 | 或者是你也可以把板塊當成是 Tag 而已,在同一個頁面就可以看到所有的文章,如果你想找範例的話,可以參考:http://react-china.org/ 958 | 959 | ## 購物網站 960 | 961 | 做個簡單的購物網站,可以參考任何一家市面上的電商,例如說這個我隨便找的電商:https://www.yuyufarm.com/ 962 | 963 | 重點是除了前端以外,你必須要有後台能夠讓管理者登入,並且管理商品(例如說調整價錢、上傳圖片、調整順序等等),可以先完成一個最簡單的版本,之後再慢慢加強。 964 | 965 | ## 社交網站 966 | 967 | 可以直接參考 Twitter:https://twitter.com/?lang=zh-tw 968 | 969 | 你可以 follow 人,然後就能夠看到他的動態,也可以自己 po 動態,會出現在自己的 follower 的牆上。 970 | 971 | 總之呢,關於 Final Project,沒有靈感的話可以先從自己常用的東西開始下手,先打造出一個最簡單的版本再慢慢加強。也可以盡量去找一些第三方的 API 來串,增加自己串 API 的經驗,例如說: 972 | 973 | 1. Firebase 974 | 2. Google Map API 975 | 3. Google Login, Facebook Login 976 | 4. 金流 977 | 978 | ## 繳交 Final Project 979 | 980 | 請準備好以下幾個東西並且於第二十七週 po 到 Slack 裡面: 981 | 982 | 1. 作品網址(沒主機或是 deploy 碰到問題的可以來找我) 983 | 2. 5 分鐘以內介紹作品的短片,上傳到 YouTube(可以不用露臉,你不想出聲的話後製加文字也可以) 984 | 3. GitHub 網址(請確保你有把一些敏感的資訊例如說資料庫密碼之類的拿掉) 985 | 4. 做 final project 的心得(看你想寫在哪裡都可以) 986 | 987 | ## 自我練習 988 | 989 | Codewar 是一個程式解題平台,靠這些題目,可以訓練自己對語法的熟悉度以及維持手感,更進階的題目則是能夠訓練思考邏輯以及解題方法。 990 | 991 | 我依照難度整理出了一些題目,平常做作業卡關或是沒事做的時候,都可以解一下這些題目。 992 | 993 | [Codewar 題目列表](/codewar.md) 994 | 995 | ## Tech Stack 996 | 997 | 這邊列舉這堂課程用到的所有工具。 998 | 999 | 1. 課程直播:YouTube 1000 | 2. 群組聊天:Slack 1001 | 3. 交作業:GitHub + GitHub Classroom 1002 | 4. 練習題目:Codewar 1003 | 1004 | -------------------------------------------------------------------------------- /codewar.md: -------------------------------------------------------------------------------- 1 | # Codewar 練習題 2 | 3 | Codewar 是一個程式解題平台,上面充滿著各種開發者出的題目,會使用這個平台的理由為: 4 | 5 | 1. 可以自己寫測試驗證基本測資 6 | 2. 過關後可以看到其他人的解答 7 | 3. 方便導師追蹤解題成效 8 | 9 | ## 注意事項 10 | 11 | 解題最重要的一點就是:絕對不要輕易看答案。為什麼解題能夠成長?是因為你有思考,思考過後想出來的答案才是你的,如果你放棄了然後去看別人的答案,那就始終是別人的,不會是你自己的。 12 | 13 | 想了一陣子還是想不出來的話,不用急,去洗個澡或是散個步搞不好就想通了(真心不騙) 14 | 15 | 若是認真想過還是想不出來,這時候可以先尋求一些提示,如果還是沒頭緒,這時候才能去查解答。但看完解答之後務必理解,並且重新再測驗一遍。 16 | 17 | 做完之後請自行把標題的 ❌ 換成 ✅。 18 | 19 | ## 題目列表 20 | 21 | 以下按照題目難度分類 22 | 23 | ## 零顆星(超簡單) 24 | 25 | ### ❌ Opposite number 26 | 題目連結:https://www.codewars.com/kata/opposite-number/javascript 27 | 題目說明:正數變負數,反之亦然 28 | 29 | ### ❌ Even or Odd 30 | 題目連結:https://www.codewars.com/kata/even-or-odd/javascript 31 | 題目說明:判斷是奇數或是偶數 32 | 33 | ## 一顆星(熟悉語法) 34 | 35 | ### ❌ Number-Star ladder 36 | 題目連結:https://www.codewars.com/kata/number-star-ladder/javascript 37 | 題目說明: 38 | 這題就是依照規律輸出文字,沒什麼好講的 39 | 40 | ### ❌ Who likes it 41 | 題目連結:https://www.codewars.com/kata/who-likes-it 42 | 題目說明:模擬 Facebook 按讚時或出現的文字 43 | 44 | ### ❌ String repeat 45 | 題目連結:https://www.codewars.com/kata/string-repeat/javascript 46 | 題目說明:回傳重複 n 遍的字串 47 | 48 | ### ❌ Build Tower 49 | 題目連結:https://www.codewars.com/kata/build-tower 50 | 題目說明: 51 | 也是依照規律輸出文字即可 52 | 53 | ### ❌ Reversed Strings 54 | 題目連結:https://www.codewars.com/kata/reversed-strings/javascript 55 | 題目說明: 56 | 把輸入的文字反轉過後回傳,如果想挑戰自己的話,可以試試看用陣列的各種內建函式組合完成 57 | 58 | ### ❌ Reversed Words 59 | 題目連結:https://www.codewars.com/kata/reversed-words 60 | 題目說明: 61 | 這一題是進階版的字串反轉,原本的只要把每個「字元」反轉,這個則是要把每個「單字」反轉。 62 | 63 | ### ❌ Alternate case 64 | 題目連結:https://www.codewars.com/kata/alternate-case 65 | 題目說明:把大寫字母轉成小寫,小寫字母轉成大寫 66 | 67 | ### ❌ You only need one - Beginner 68 | 題目連結:https://www.codewars.com/kata/you-only-need-one-beginner/javascript 69 | 題目說明:回傳要找的元素是否在陣列裡面 70 | 71 | ### ❌ Find the capitals 72 | 題目連結:https://www.codewars.com/kata/find-the-capitals-1/javascript 73 | 題目說明:回傳大寫字母所在的 index 74 | 75 | ### ❌ Sum arrays 76 | 題目連結:https://www.codewars.com/kata/sum-arrays/javascript 77 | 題目說明:把陣列加總回傳結果 78 | 79 | ### ❌ Find the smallest integer in the array 80 | 題目連結:https://www.codewars.com/kata/find-the-smallest-integer-in-the-array 81 | 題目說明:找出陣列中最小的數字 82 | 83 | ## 兩顆星(需要花點時間思考) 84 | 85 | ### ❌ Shortest Word 86 | 題目連結:https://www.codewars.com/kata/shortest-word/javascript 87 | 題目說明:回傳最短的單字的長度 88 | 89 | ### ❌ Bit Counting 90 | 題目連結:https://www.codewars.com/kata/bit-counting/javascript 91 | 題目說明:計算 bit 的總數 92 | 93 | ### ❌ Find The Parity Outlier 94 | 題目連結:https://www.codewars.com/kata/find-the-parity-outlier/javascript 95 | 題目說明:全部的數字裡,只有一個的奇偶跟其他的不一樣,你要找出這個數字 96 | 97 | ### ❌ Take a Ten Minute Walk 98 | 題目連結:https://www.codewars.com/kata/take-a-ten-minute-walk/javascript 99 | 題目說明:有一個人他可以往東南西北這四個方向走,請幫他計算它能否剛好在十步的時候回到原點 100 | 101 | ### ❌ Tribonacci Sequence 102 | 題目連結:https://www.codewars.com/kata/tribonacci-sequence/javascript 103 | 題目說明:費式數列的進階版 104 | 105 | ### ❌ A Man and his Umbrellas 106 | 題目連結:https://www.codewars.com/kata/a-man-and-his-umbrellas/javascript 107 | 題目說明: 108 | 這題需要花多一點時間去思考。 109 | 110 | input 會給你每天的氣象預報,基本上就是下雨跟沒下雨。如果早上下雨,那就會從家裡帶一把傘去公司,如果家裡沒傘的話需要買一把。如果晚上下雨,必須要從公司帶一把傘回家。如果公司沒傘,必須去買一支傘。 111 | 112 | 你要輸出的結果就是:總共需要買幾支傘才行。 113 | 114 | 舉例來說:`["rainy", "clear", "rainy", "cloudy"]`,就是第一天早上下雨,所以要買第一把傘到公司,回家的時候沒下雨,所以把傘放在公司。而第二天早上又下雨,家裡沒傘,需要買第二把傘,因此答案是 2。 115 | 116 | `["rainy", "rainy", "rainy", "rainy", "thunderstorms", "rainy"]`的話,每一天的早上跟晚上都在下雨,所以只要買一把傘就可以從家裡到公司,再從公司帶回家裡。 117 | 118 | ### ❌ Check if two words are isomorphic to each other 119 | 題目連結:https://www.codewars.com/kata/check-if-two-words-are-isomorphic-to-each-other 120 | 題目說明: 121 | 這題比較複雜一點,如果兩個字串 A 跟 B 存在「一對一關係」,那我們就可以說這兩個字串是同構(isomorphic)的。 122 | 123 | 舉例來說,ABB 跟 CDD,A 對應到 C,B 對應到 D,存在一對一的關係,所以是同構的。 124 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | 這個資料夾底下是每一週的參考解答,或比起參考解答,更精確地說法是:「我的解答」。 4 | 5 | 在交作業前請勿觀看,以免破壞學習樂趣。參考解答主要是給想要更精進的同學看的,若你只是題目解不出來,建議先參考同學的程式碼,他的程度會跟你的比較相近。 6 | 7 | -------------------------------------------------------------------------------- /examples/week11/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | 提示:在寫完作業之後看效果最佳,沒寫作業前請不要看 4 | 5 | ## 雜湊跟加密的區別 6 | 7 | 雜湊不可逆,加密可逆,叫做解密。 8 | 9 | 雜湊為什麼不可逆?你這樣想就很簡單了:因為無限的輸出對應到有限的輸入,就代表一定會有很多個 input 對應到同一個 output(就叫做碰撞),那你從同一個 output 怎麼可能知道 input 是哪一個?這是個很簡單的邏輯問題。 10 | 11 | 這樣大家就知道為什麼存密碼要用雜湊了,就不會有人知道你密碼原來是什麼。 12 | 13 | 但雜湊是不是絕對安全?當然不是,有一種最古老但也最有用的方法,叫做暴力破解。 14 | 15 | 今天你行李箱的數字鎖忘記密碼了,怎麼辦?有些人會 999 種組合都試過,雖然費時但有效。 16 | 17 | 破解雜湊也是類似的,假如我把 0000~9999 這一萬種組合都事先跑過一遍雜湊並把結果存入資料庫,我就有著這中間的對應關係。當我看見某個雜湊過後的值,就可以來這邊查表,如果有的話我就知道 input 是什麼了。 18 | 19 | 所以雜湊唯一能破解的就是這樣暴力破解而已,事先存好結果然後查表。若是六位數字的密碼,大小寫加數字就是 62 種組合,62^6 就是五百億種組合了。要是先把五百億種組合跑出來才能查到結果。 20 | 21 | 而且,為了增加密碼的長度,有一種方法很可愛,叫做「加鹽」(salting),會幫每一個 user 產生一個不同的鹽巴,例如說十六位的英數混合好了:`ab48fogir38e9fjl`,然後我的密碼是 abc123,那存在資料庫裡的密碼就是 `hash(ab48fogir38e9fjlabc123)`,這樣就需要先算好 22 位數的組合才有可能回推出原文是什麼。 22 | 23 | 難嗎?難。 24 | 25 | ## 來自 client 端的資料都不可信 26 | 27 | 大家千萬不要忘記一件事情了,千萬不要忘記什麼是我們可以自己改的,什麼不行。你要站在攻擊者的角度去想什麼東西可以被偽造。 28 | 29 | GET 跟 POST 的參數值可不可以被偽造?當然可以!我想傳什麼就傳什麼,本來就沒有限制。 30 | 31 | Cookie 的內容可不可以被偽造?當然可以,這也是我想帶什麼就帶什麼。 32 | 33 | 資料庫的值可不可以被偽造?可以,但如果被偽造的話就代表你資料庫已經被駭客拿下了,所以不用擔心這個問題。 34 | 35 | 所以為什麼第九週會員系統那樣不 ok?因為我們把會員 id 帶在 cookie,今天只要攻擊者自己改變 cookie 內容(可不可以?當然可以),就可以換一個身份登入,所以是有安全漏洞的。 36 | 37 | 這也是為什麼這一週要換成通行證機制,比起會員 id,我們隨機產生的通行證 id 是沒辦法被猜到的。那攻擊者可不可以竄改通行證 id?當然可以,他可以自己改變 cookie 的值,可是他要改成什麼? 38 | 39 | 通行證 id 是隨機產生的,他怎麼可能隨便猜就猜得到一組正確的? 40 | 41 | 所以在這情景下你不用去考慮什麼「如果他用別人的通行證,不就也可以利用別人的身份登入嗎?」,對啊,當然,但這個機制本來就只認證不認人,用別人的通行證本來就應該用別人的身份登入。 42 | 43 | 今天的重點是攻擊者沒辦法「拿到別人的通行證」或者是猜到,所以這個機制還是可靠的。 44 | 45 | 有些人作業把通行證的產生規則弄固定了,就是多此一舉。例如說通行證就是 `md5(username)`,一但這個規則被猜到了,我不就也可以產生出別人的通行證嗎?那這機制就沒用了。 46 | 47 | 所以我才強調要隨機產生,隨機就代表猜不到(精確一點的說法是很難猜啦,例如說機率是兩億分之一,就可以想成猜不到) 48 | 49 | 然後,這個通行證機制就叫做 Session。 50 | 51 | Session 就是把資料存在 server,然後靠著一組 session id 傳到 cookie 存起來,以後都透過這個 session id 認人。所以 session 就是通行證機制,session 就是通行證本身,就是你的專屬會員卡。 52 | 53 | ## 用最適合的東西 54 | 55 | 如果有 a 可以用,就沒必要寫一個元素加上 onclick listener,然後再使用 window.location 去導向。a 這個元素本來就是要讓你導向的,何必多此一舉? 56 | 57 | 還有一個同學寫了一個滿有趣的機制,例如說編輯留言好了,到編輯留言頁面時他先把留言 id 存在 cookie 裡面,編輯完按下 submit 的時候導到 handle_edit.php,後端直接從 cookie 把留言 id 拿出來。 58 | 59 | 這樣帶資料當然也可以,但不是好的做法。 60 | 61 | 那什麼是好的做法?就是直接用 GET 或是 POST,把留言 id 放在表單裡面一起帶過去就好,沒必要直接存在 cookie。 62 | 63 | ## Early return 64 | 65 | 大家之前在寫 code 的時候,應該有看過一個 eslint 的錯誤: 66 | 67 | ``` js 68 | function test(a) { 69 | if (a === '123') { 70 | return true 71 | } else { 72 | return false 73 | } 74 | } 75 | ``` 76 | 77 | 會給你一個 [Disallow return before else (no-else-return)](https://eslint.org/docs/rules/no-else-return) 的錯誤。 78 | 79 | 為什麼呢?因為上面的程式碼你仔細想一下,會發現 else 完全沒必要。 80 | 81 | 如果條件成立,就 return 了,函式就結束了。如果條件不成立,就要執行 `return false` 那行。那不就寫成下面這樣就好? 82 | 83 | ``` js 84 | function test(a) { 85 | if (a === '123') { 86 | return true 87 | } 88 | return false 89 | } 90 | ``` 91 | 92 | 執行出來的結果跟順序是完全一樣的,所以才會跟你說 else 完全沒必要。 93 | 94 | 而今天要講的 early return 原理類似,請大家看一下以下程式碼: 95 | 96 | ``` php 97 | $sql = "SELECT * FROM ChihYang41_users WHERE account = ?"; 98 | $stmt = $conn->stmt_init(); 99 | if ($stmt->prepare($sql)) { 100 | $stmt->bind_param("s", $account); 101 | $stmt->execute(); 102 | $result = $stmt->get_result(); 103 | $row = $result->fetch_assoc(); 104 | if ($result->num_rows > 0) { 105 | if (password_verify($password, $row['password'])) { 106 | getSessionId($conn, $account); 107 | setcookie("session_id", setSessionId($conn, $account), time()+3600*24); 108 | echo ""; 112 | } else { 113 | header("Location: ./login.php?error=pwderror"); 114 | exit(); 115 | } 116 | } else { 117 | header("Location: ./login.php?error=othererror"); 118 | exit(); 119 | } 120 | 121 | $stmt->close(); 122 | $conn->close(); 123 | } 124 | ``` 125 | 126 | 你會看到因為狀況很多種,所以需要有很多 if 跟 else。但你可以注意到一個特性,就是 else 裡面的東西通常執行完畢就 exit 了,不會再執行其他程式碼。 127 | 128 | 這時候就可以利用這個特性,把條件「反過來寫」,先寫說如果不符合狀況就怎樣,可以少掉很多巢狀,可以參考底下程式碼: 129 | 130 | ``` php 131 | $sql = "SELECT * FROM ChihYang41_users WHERE account = ?"; 132 | $stmt = $conn->stmt_init(); 133 | 134 | if (!$stmt->prepare($sql)) { 135 | exit(); 136 | } 137 | 138 | $stmt->bind_param("s", $account); 139 | $stmt->execute(); 140 | $result = $stmt->get_result(); 141 | $row = $result->fetch_assoc(); 142 | 143 | if ($result->num_rows == 0) { 144 | header("Location: ./login.php?error=othererror"); 145 | exit(); 146 | } 147 | 148 | if (!password_verify($password, $row['password'])) { 149 | header("Location: ./login.php?error=pwderror"); 150 | exit(); 151 | } 152 | 153 | getSessionId($conn, $account); 154 | setcookie("session_id", setSessionId($conn, $account), time()+3600*24); 155 | echo ""; 159 | 160 | $stmt->close(); 161 | $conn->close(); 162 | ``` 163 | 164 | 是不是超級神奇! 165 | 166 | 原本三層 if 的程式碼,在換個順序判斷之後就改成只有一層,程式碼看起來乾淨很多。這個就叫做 early return,能早點 return(在這情形下是 exit,但也是離開)就早點,就可以避免掉無謂的 else 判斷。 167 | 168 | (上面 code 來自同學的真實案例,可參考:https://github.com/Lidemy/mentor-program-3rd-ChihYang41/pull/28/files/c09007e1b0c8f2f54662cbbb7e1bb90eebcd6e2b ) 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /examples/week12/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | 提示:在寫完作業之後看效果最佳,沒寫作業前請不要看 4 | 5 | ## 資訊安全的意識 6 | 7 | 這一週的重點就只有這個,沒了。 8 | 9 | 但光是這一個重點就可以把一大堆人打趴了。 10 | 11 | 資訊安全意識代表的是你在寫 code 的時候會去注意自己的 code 有沒有一些會被攻擊的地方,而這之中最最最常見的就是在處理與使用者相關輸入的時候,都要特別小心。 12 | 13 | 只要你能有這個意識,就能防止大多數的攻擊;但如果沒有的話...呵呵。 14 | 15 | 本週最常見的三個錯誤: 16 | 17 | 1. 沒有把所有用到 SQL 的地方都改成 prepared statement 18 | 2. 忘了防止使用者暱稱的 XSS 19 | 3. 沒有做好權限管理,可以刪除與編輯任意文章或是仿冒身份發文 20 | 21 | 以下直接來看幾個 case: 22 | 23 | ``` php 24 | query($sql)) { 29 | header("Location: ./index.php"); 30 | } else { 31 | die("failed."); 32 | } 33 | ?> 34 | ``` 35 | 36 | 問題是什麼? 37 | 38 | 第一個問題是沒有判斷權限,這邊只接收一個 GET 的參數然後就把留言給刪了。今天儘管我沒有登入,我還是可以刪除留言。 39 | 40 | 改一下之後變成這樣: 41 | 42 | ``` php 43 | query($sql)) { 52 | header("Location: ./index.php"); 53 | } else { 54 | die("failed."); 55 | } 56 | ?> 57 | ``` 58 | 59 | 好,這樣沒有登入的話就沒辦法刪除留言了。 60 | 61 | 夠了嗎?當然不夠,雖然有檢查登入但沒有檢查作者,意思就是我可以刪除任何人的留言,因為你後端沒做檢查。所以後端要記得檢查「這個留言是不是他的」,不然攻擊者就可以刪除任何人的留言了。 62 | 63 | 這邊最簡單的方法就是直接改 SQL query: 64 | 65 | ``` php 66 | query($sql)) { 75 | header("Location: ./index.php"); 76 | } else { 77 | die("failed."); 78 | } 79 | ?> 80 | ``` 81 | 82 | 要同時符合文章 id 跟作者,就能確保只有作者本人可以刪到文章。 83 | 84 | 這樣夠了嗎?還不夠,你忘記 SQL Injection 了嗎?我 username 如果傳一個 `' or '1'='1` 之類的,SQL query 就變成 `DELETE FROM comment where id = xx AND username='' or '1'='1'`,就一樣可以刪除任何文章了。 85 | 86 | 所以要把上面的 query 換成 prepared statement,這樣才沒問題。 87 | 88 | 接著來看第二個 case,cookie 裡面存的是這一週作業要大家實作的 certificate: 89 | 90 | ``` php 91 | query($sql); 102 | if(!$result || $result->num_rows <=0){ 103 | $user = null; 104 | }else { 105 | $row = $result->fetch_assoc(); 106 | $user = $row['nickname']; 107 | } 108 | }else{ 109 | $user = null; 110 | } 111 | 112 | function isLogin() { 113 | if (isset($_COOKIE["user"]) && !empty($_COOKIE["user"])) { 114 | return true; 115 | } else{ 116 | return false; 117 | } 118 | } 119 | ?> 120 | ``` 121 | 122 | 第一個問題是什麼? 123 | 124 | 跟上面一樣,SQL Injection,我如果改 Cookie 的值,就可以去操縱裡面那一個 query,就可以用任何人的身份登入了。 125 | 126 | 第二個問題跟資安無關,是邏輯問題。上面是用 cookie 存不存在來判斷是否登入,但這是錯的。如果我 cookie 隨便放個 123,我也叫登入嗎?當然不是,登入代表的是我要有一個合法的帳號才叫登入。 127 | 128 | 所以正確的檢驗方法是拿 cookie 裡面的值去 certificates 裡面查詢,有查到資料才代表我真的有登入。不然通行證機制都白做了。 129 | 130 | 在這邊提醒大家兩件事: 131 | 132 | 1. 永遠記得權限驗證,做任何操作時都要想一下有沒有人可以繞過權限驗證(或你根本忘記做權限驗證) 133 | 2. 永遠使用 prepared statement。你可能會說:「可是有些地方沒有參數,或有些地方參數是我自己能控制的」,對,這些地方可能不會有 SQL Injection 的風險,但第一如果你之後改那段 code 呢?第二,你怎麼知道那邊不會有? 134 | 135 | 上面舉的那些範例也可能是自認為沒有 SQL Injection 的風險,但這才是最致命的地方。不要為了偷懶用回比較方便的 query,只要有用到 SQL 的地方,全部都用 prepared statement 才是正解。 136 | 137 | 補充: 138 | 139 | XSS 的部分除了留言內容,使用者暱稱也要防啊!不確定的話你就每個輸出的地方都 escape 就好,千萬不要自作聰明! 140 | 141 | 另外,這邊有 SQL Injection 的真實範例:https://www.youtube.com/watch?v=ABi1jUbDzPg&feature=youtu.be 142 | 143 | ## 什麼是 Session? 144 | 145 | 記得這一週的第二個作業嗎?通行證機制。這個就是 session。 146 | 147 | 你產生的通行證 ID 就是 session id,你在 users_certificate 這個 table 放的資料就是 session data。 148 | 149 | 那 $_SESSION 又是什麼?跟 session 有什麼關係? 150 | 151 | 在回答這個之前,先問你一個問題: 152 | 153 | > cookie 跟 $_COOKIE 有什麼關係? 154 | 155 | Cookie 是瀏覽器存資料的地方,它是一個 browser 跟 server 交換資料的機制。而 $_COOKIE 是 PHP 要用來操作 cookie 時的語法。 156 | 157 | session 也是一樣的。 158 | 159 | Session 就是通行證機制,可以在 server 端存放資料,在 client 端只透過 session id 來驗證身份;而 $_SESSION 是 PHP 用來操作 session 時的語法。 160 | 161 | session 只是個機制,就像是投票那樣。但它本身不會規定投票要怎麼投。你可以每個人發紙條寫要投誰;你可以線上電子投票;你可以在想投的箱子放一個球,這些都叫做投票。 162 | 163 | session 也是一樣的,這個機制也能有很多不同的實作方式,你可以像我們一樣自己用 users_certificate 這個 table 來實作,也可以用 PHP 內建的 $_SESSION 來實作,這些都叫做 session,只是實作方法不同。 164 | 165 | 更多細節可以參考 Session 與 Cookie 三部曲: 166 | 167 | 1. [白話 Session 與 Cookie:從經營雜貨店開始](https://github.com/aszx87410/blog/issues/45) 168 | 2. [淺談 Session 與 Cookie:一起來讀 RFC](https://github.com/aszx87410/blog/issues/45) 169 | 3. [深入 Session 與 Cookie:Express、PHP 與 Rails 的實作](https://github.com/aszx87410/blog/issues/46) 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /examples/week13/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | 提示:在寫完作業之後看效果最佳,沒寫作業前請不要看 4 | 5 | ## 網格系統 6 | 7 | 可以參考這一套非常簡單的 library:https://simplegrid.io/ 8 | 原始碼:https://github.com/zachacole/Simple-Grid 9 | 10 | 基本上就是把每一行都切成 12 格(或你要切成其他數字也可以),這樣就可以讓版面隨著不同的尺寸調整一行要顯示幾格。比如我這樣寫: 11 | 12 | ``` html 13 |
14 |
15 |
16 |
17 | ``` 18 | 19 | 在正常狀況下會兩格併排,但是當螢幕寬度小的時候就會變成兩行。用這樣子的方式來實現 RWD。可以回應一下我們第六週做過的那個三欄式的版面,其實就很適合用網格系統。 20 | 21 | ## Bootstrap 22 | 23 | 就讓大家試試看這個熱門的 framework 而已,如果覺得用不到也可以不要用。但若是你本身做的畫面不好看,它可以幫到滿多忙的。 24 | 25 | Bootstrap 出來之後幫了一堆沒什麼美感的工程師,但副作用就是你會發現有好多版面都好眼熟,因為都是從 Bootstrap 去改的。 26 | 27 | ## Session 機制 28 | 29 | 前幾週的鋪成都是為了讓你自己利用 cookie 來實作這個 session 機制,功德圓滿之後在這週就可以換成 PHP 內建的 session 機制了。PHP 內建的跟我們實作的差不多,只是 PHP 會用檔案來存 session 的內容,不像我們之前用資料庫。 30 | 31 | 會用內建 session 機制之後,以後都用內建的就行了,之前只是想確保大家有理解原理。 32 | 33 | 延伸閱讀: 34 | 35 | 1. [白話 Session 與 Cookie:從經營雜貨店開始](https://medium.com/@hulitw/session-and-cookie-15e47ed838bc) 36 | 2. [淺談 Session 與 Cookie:一起來讀 RFC](https://blog.huli.tw/2019/08/09/session-and-cookie-part2/) 37 | 38 | ## 把留言板改成 ajax 39 | 40 | 作業裡面只讓大家做新增跟刪除是因為要做其他功能有點複雜。刪除的話我只預期大家 call api 之後把畫面上的元素刪掉,不需要考慮到分頁(因為如果你要考慮到的話,會需要把下一頁的第一筆也顯示出來);新增也是一樣的,只要在畫面上新增元素就好,不用考慮分頁問題(例如說把最後一個拿掉,因為它會變成在第二頁)。 41 | 42 | 這週改成 ajax 是我認為學習前後端溝通的最後一塊拼圖,因為前後端溝通就兩種方式,一種是透過表單,另外一種就是 ajax 了。在把新增跟刪除改成 ajax 的時候應該會碰到一些問題,例如說你原本可能會從 PHP echo 出一些 ` 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/week8/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | 4 | ## URL encode 5 | 6 | 大概九成九的同學都有犯這個錯,但我沒有特別點出來,我想說一次點出來比較有效率。 7 | 8 | 這個錯是什麼呢?就是你在新增留言時這樣寫: 9 | 10 | ``` js 11 | `content=${content}` 12 | ``` 13 | 14 | 你把留言內容直接放進去,然後就 POST 出去了。 15 | 16 | 問題在哪邊?問題在於如果我想要發表的內容是 `1&a=2` 怎麼辦?就會變成 `content=1&a=2`,最後出來的 content 就只有 1 而已,因為後半段被判定成另外一個參數。 17 | 18 | 解法是「編碼」,這邊 JS 有現成的函式可以用:[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent)。編碼的意思就是把一些特殊字元給編碼成另外一種表示方法: 19 | 20 | ``` js 21 | encodeURIComponent('1&a=2') // 1%26a%3D2 22 | ``` 23 | 24 | 它會把那些干擾到的部分用其他方式取代掉,在 Server 時則會自動轉成正確地表示方法,所以內容還是會是正確的,這邊不用擔心。 25 | 26 | 這就是新增留言時必須特別注意的地方。 27 | 28 | ## Request 的重新使用 29 | 30 | 有很多人在留言板那題新增完留言之後都會重新讀取一次,有些人可能以為節省資源,就會沿用同一個 request: 31 | 32 | ``` js 33 | request.open('/posts?content=123') 34 | request.send() 35 | 36 | request.open('/posts') 37 | request.send() 38 | ``` 39 | 40 | 這樣是不對的,而且會造成一些問題。最常見的就是第一個 request 會被取消掉,因為還沒發出去就要發第二個了。 41 | 42 | 正確的解法是每一個 request 就 new 一個新的 XMLHttpRequest,你直接包成 function 就好了: 43 | 44 | ``` js 45 | function addPost(content) { 46 | const xhr = new XMLHttpRequest() 47 | xhr.open() 48 | xhr.send() 49 | xhr.onload = function() { 50 | //... 51 | } 52 | } 53 | ``` 54 | 55 | 56 | 這樣就不會有問題了。 57 | 58 | ## Race condition 59 | 60 | (這一段要講的觀念超級無敵重要,不懂的話請在 slack 提問) 61 | 62 | 有些人可能聽過這名詞,但不知道是什麼,剛好這一次作業就能夠讓你體會到。誠如我上面所說的,很多人在留言板那題都會在新增留言之後立刻抓取新的留言: 63 | 64 | ``` js 65 | newRequest.open('/posts?content=123') 66 | newRequest.send() 67 | 68 | getRequest.open('/posts') 69 | getRequest.send() 70 | ``` 71 | 72 | 那結果會是什麼? 73 | 74 | > 我先新增留言,再抓取留言,這樣應該沒什麼問題吧? 75 | 76 | 不,問題可大了。 77 | 78 | 你 Request 先發歸先發,但「先發不代表會先到達」,這點超級重要。所以兩個 Request 如果第二個先到了,那你拿到的就還是舊的留言。 79 | 80 | 再來,儘管第一個先到,但你其實是「立刻」就發了第二個 Request,兩個相差的時間可能只有 1ms 而已,這根本不是什麼差距。而 Server 處理第一個新增留言的時間很有可能大於這個差距,因此你新增了留言沒錯,但你第二個 Request 拿到的東西依然是舊的。 81 | 82 | 簡單來說好了,「從你電腦發 Request 到 Server 的時間」跟「Server 的處理時間」以及「從 Server 發 Response 傳到你電腦的時間」這三者都是「無法估計」的,所以什麼事都有可能發生,有可能快有可能慢。 83 | 84 | 接下來我們直接假設幾種狀況就好。 85 | 86 | ### 狀況一 87 | 88 | 1. 先發第一個 request,並且第一個 request 先抵達 89 | 2. 第二個 request 抵達 server 的時候,第一個 request 已經處理完成並且傳回 response 90 | 3. 第二個 response 抵達 91 | 92 | 這是你原本心裡所想的情況,新增完留言之後你才抓取留言列表,而你拿到的就已經是最新的列表,有你剛剛留的留言。 93 | 94 | ### 狀況二 95 | 96 | 1. 先發第一個 request,並且第一個 request 先抵達 97 | 2. 第二個 request 抵達 server 的時候,第一個 request 還在處理 98 | 3. 回傳第二個 response,拿到當下的留言 99 | 4. 留言新增完成 100 | 101 | 在這種情形下,因為第二個 response 處理的時候,你其實是還沒有新增留言的,因此拿到的結果會是舊的,不會有你剛剛新增的留言。 102 | 103 | 除了以上兩種,還可以再假設超級多種,而且每一種情況都有可能發生。 104 | 105 | 或是再舉一個例子,我這樣寫: 106 | 107 | ``` js 108 | for(let i=1; i<=5; i++) { 109 | let xhr = new XMLHttpRequest() 110 | xhr.open('/posts/' + i) 111 | xhr.send() 112 | xhr.onload = function() { 113 | console.log('response: ' + i) 114 | } 115 | } 116 | ``` 117 | 118 | 其實就是拿第一篇到第五篇文章的內容,那請問我最後 log 出來的結果會是什麼? 119 | 120 | 12345 嗎? 121 | 122 | 不是,結果是我不知道。有可能是 12345,也有可能是 54321,甚至是 13542,每一種排列組合都有可能。原因就是我上面講過的:「從你電腦發 Request 到 Server 的時間」跟「Server 的處理時間」以及「從 Server 發 Response 傳到你電腦的時間」這三者都是「無法估計」的。 123 | 124 | 所以如果我拿出下面那段程式碼: 125 | 126 | ``` js 127 | newRequest.open('/posts?content=123') 128 | newRequest.send() 129 | 130 | getRequest.open('/posts') 131 | getRequest.send() 132 | ``` 133 | 134 | 問你說結果會是什麼,答案是:「不知道」。 135 | 136 | 這種情況就叫做 race condition,最後的產出完全憑當下他們競爭的結果,你在事前無法預料結果是什麼。你有可能先新增留言,也有可能先拿到結果,每一種都有可能,所以結果變得無法預期。 137 | 138 | 所以這種情況當然要避免。 139 | 140 | 那怎麼避免?最好的方法當然就是:「確保第一個 request 處理完成時,我才發送第二個 request」。 141 | 142 | 那我怎樣才知道第一個處理完了?當然就是從我拿到第一個的 response 的時候,我自然就知道第一個處理完了,不然我不可能拿得到 response 嘛。 143 | 144 | 所以呢,如果你要先新增文章,然後拿到最新的文章列表,你要這樣寫: 145 | 146 | ``` js 147 | newRequest.open('/posts?content=123') 148 | newRequest.send() 149 | newRequest.onload = function() { 150 | getPosts() // 這邊才去拿文章列表 151 | } 152 | 153 | function getPosts() { 154 | getRequest.open('/posts') 155 | getRequest.send() 156 | } 157 | 158 | ``` 159 | 160 | 這樣是唯一能保證順序的方法。 161 | 162 | 之前還有看過同學偷吃步: 163 | 164 | ``` js 165 | newRequest.open('/posts?content=123') 166 | newRequest.send() 167 | 168 | setTimeout(() => { 169 | getRequest.open('/posts') 170 | getRequest.send() 171 | }, 1500) // 等個 1.5 秒 172 | 173 | ``` 174 | 175 | 但這樣依然無法保證結果是正確的,因為我們可以假設第一個 request 處理完成時已經超過 1.5 秒了(而且這完全有可能發生),這樣你拿到的文章列表依然還是錯的。 176 | 177 | 牽扯的網路的東西都是非同步的,而非同步就代表著順序是無法被預知的。你只能靠著自己寫 code 來掌握正確的順序。 178 | 179 | ## 有關參考資料 180 | 181 | 有些我附的資料其實我本來就沒有預期你全部看懂,例如說這一週放的「RESTful API Design by TritonHo」,我只是想大家有個粗淺的理解而已,至少看過一些名詞有個印象,你不必完全理解也沒關係,只要大略看過去就好。 182 | 183 | ## 表單的 submit 184 | 185 | 留言板那題有個很有趣的現象,有很多人都在按下 submit 按鈕時送出新增留言的 request,然後整題的程式碼就這樣子,但按下送出之後卻一樣會顯示新的留言。 186 | 187 | 送出留言之後又沒有特地寫 code 去抓新的留言,這些新的是哪來的? 188 | 189 | 這是因為你表單送出了,所以就換頁了,換到同一頁就幾乎等於重新整理,所以留言自然就更新了,因為頁面重新載入一遍。 190 | 191 | 但這當然是錯誤的,錯誤的第一個點是如果要換頁,那我幹嘛要你用 ajax;錯誤的第二個點是可能會發生問題。 192 | 193 | 這問題就是上面提到的 race condition,如果我換頁的時候,新增留言的 request 還沒發出去,那不就不會新增留言了嗎?有人跟我說他試了很多次都沒試出來,對,這不一定試的出來,但你要知道理論上是有可能的,那就要避免掉這種情形。 194 | 195 | 所以這題應該要 ajax 送出留言成功之後,再用 ajax 去把最新的留言撈回來並顯示。 196 | 197 | 還有,表單要記得 e.preventDefault 阻止送出。 198 | 199 | ## 第一題獎項機率 200 | 201 | first 5% 202 | second 20% 203 | third 30% 204 | none 40% 205 | error 5% 206 | -------------------------------------------------------------------------------- /examples/week9/README.md: -------------------------------------------------------------------------------- 1 | # 注意事項 2 | 3 | ### 注意,以下都與第九週作業簡答題相關,還沒寫完請不要看喔! 4 | 5 | 6 | ## 資料庫欄位型態 VARCHAR 跟 TEXT 的差別是什麼 7 | 8 | 網路上查可以查到很多相關資料,但我個人覺得最重要的一個點在於 VARCHAR 可以設長度但是 TEXT 不行。 9 | 10 | 意思就是說,當你本來就知道大概會需要多少字元的時候,就用 VARCHAR,真的逼不得已東西很長(例如說要存文章)的時候才用 TEXT,才能節省空間。 11 | 12 | ## Cookie 跟 Session 不要搞混了 13 | 14 | 這週其實還沒講到 Session 的概念,為的其實就是希望大家不要搞混。但因為之前 CS101 火球術其實已經提到了,所以反而有點弄巧成拙(?),還是滿多人搞混的。 15 | 16 | 請大家注意這一週作業問的問題: 17 | 18 | > Cookie 是什麼?在 HTTP 這一層要怎麼設定 Cookie,瀏覽器又會以什麼形式帶去 Server? 19 | 20 | 如果是我的話大概會這樣答: 21 | 22 | Cookie 是個儲存在瀏覽器的小型文字檔案,在 HTTP 這層 Server 可以透過 Set-Cookie 這個 response header 來讓瀏覽器儲存相對應的 Cookie。而瀏覽器發送 Request 時,會把相對應的 Cookie 放在 `Cookie` 這個 Header,Server 就可以拿到資料。 23 | 24 | 「相對應的」指的是每一個 Cookie 都有一些選項可以設置,要符合條件才能寫入以及傳送,例如說你無法寫入其他 domain 的 cookie。 25 | 26 | 所以我這邊在談的是 Cookie 的本質:儲存資料。而另一個重點就是伺服器可以把資料寫在 Cookie,瀏覽器也會幫你把 Cookie 帶給伺服器。 27 | 28 | 至於其他用途(廣告追蹤、身份驗證)那都是再延伸出去的東西了,其實不是這題的重點。可以當作額外補充,但你要知道的是 Cookie 本身就是個儲存容器,身份驗證是其中的用途之一,但還有其他用途。 29 | 30 | ## 這週會碰到的問題 31 | 32 | 這週的作業主要會碰到的問題有兩個(當然還有更多啦,先提兩個): 33 | 34 | 1. 密碼存明碼,當駭客入侵把你資料庫偷走之後,你家會員的密碼就全部被駭客知道了。解法在十一週會講。 35 | 2. 利用 cookie 裡的 user id 來判斷登入的人是誰,我只要把 cookie 裡面的值一改掉,就可以偽造別人身份登入。解法在十一週也會講。 36 | -------------------------------------------------------------------------------- /homeworks/week1/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | 附註:.md 代表文章格式為 markdown,可自行上網搜尋相關教學,檔案內容請盡可能遵守[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines)。 4 | 5 | ## hw1:交作業流程 6 | 7 | 請用文字一步步敘述應該如何交作業。 8 | 9 | 範例: 10 | 11 | 1. 新開一個 branch:`git branch hw1` 12 | 2. 切換到 branch:`git checkout hw1` 13 | 14 | 請將答案寫在 [hw1.md](hw1.md)。 15 | 16 | ## hw2:理解放鬆很重要 17 | 18 | 大腦會在兩種不同的工作模式中切換,所以在卡關時讓大家適當休息一下是很重要的,否則只會越卡越深,陷入泥淖之中。 19 | 20 | 因此,這個作業希望讓大家學會休息的重要。請你找個時間出去散步(像是家裡附近的公園之類的,反正哪裡都可以)。 21 | 22 | ## hw3:教你朋友 CLI 23 | 24 | 學了一項東西之後若是想驗證自己是不是真的懂,教別人是最快的方法。 25 | 26 | 有天,你的麻吉 h0w 哥跑來找你說:「欸!能不能教我 command line 到底是什麼,然後怎麼用啊?我想用 command line 建立一個叫做 wifi 的資料夾,並且在裡面建立一個叫 afu.js 的檔案。就交給你了,教學寫好記得傳給我,ㄅㄅ」 27 | 28 | 可...可惡,居然這樣子就跑走了。但因為他是你的麻吉,所以你也沒辦法拒絕。 29 | 30 | 因此這個作業要請你寫一篇簡短的文章,試圖教會 h0w 哥什麼是 command line 以及如何使用,並且要教他如何達成他想要的功能。 31 | 32 | 請將答案寫在 [hw3.md](hw3.md)。 33 | 34 | ## hw4:跟你朋友介紹 Git 35 | 36 | 因為你的人實在是太好,時不時就會有朋友跑來找你來幫忙。 37 | 38 | 這次來的是一個叫做菜哥的朋友,會叫做菜哥是因為家裡賣菜,跟你認識的其他人同名的話純屬巧合。 39 | 40 | 菜哥:「就是啊,我最近有一個煩惱。因為我的笑話太多了,所以我目前都用文字檔記錄在電腦裡,可是變得越來越多之後很難紀錄,而且我的笑話是會演進的。會有版本一、版本二甚至到版本十,這樣我就要建立好多個不同的檔案,弄得我頭很痛,聽說你們工程師都會用一種程式叫做 Git 來做版本控制,可以教我一下嗎?」 41 | 42 | 『好吧,我試試看』 43 | 44 | 菜哥:「謝啦,話說你來參加這個計畫學程式真的選對了欸,之後就不會有貧血的困擾了」 45 | 46 | 『為什麼』 47 | 48 | 「因為你會寫程式」 49 | 50 | 『...』 51 | 52 | 「喔...原來是血乘四的部分啊(拍手)」 53 | 54 | 就是這樣,在一陣尬聊之中你答應了菜哥的要求,要教他怎麼使用 Git 來管理他的笑話。 55 | 56 | 因此,你必須教他 Git 的基本概念以及基礎的使用,例如說 add 跟 commit,若是還有時間的話可以連 push 或是 pull 都講,菜哥能不能順利成為電視笑話冠軍,就靠你了! 57 | 58 | 請將答案寫在 [hw4.md](hw4.md)。 59 | 60 | ## hw5:簡答題 61 | 請將答案寫在 [hw5.md](hw5.md)。 62 | 63 | 1. 請解釋後端與前端的差異。 64 | 2. 假設我今天去 Google 首頁搜尋框打上:JavaScript 並且按下 Enter,請說出從這一刻開始到我看到搜尋結果為止發生在背後的事情。 65 | 3. 請列舉出 3 個「課程沒有提到」的 command line 指令並且說明功用。 66 | 67 | ## 挑戰題 68 | 69 | 有一種東西叫做 [shell script](http://linux.vbird.org/linux_basic/0340bashshell-scripts.php),可以用 command line 指令以及一些語法寫成一個腳本,執行之後可以很方便地做很多事。 70 | 71 | 舉例來說,下面這個檔案我們存檔並取名叫做 test.sh: 72 | 73 | ``` bash 74 | #!/bin/bash 75 | 76 | touch "$1.js"; 77 | echo "檔案建立完成"; 78 | ``` 79 | 80 | 接著為了讓他可以執行,我們要更改檔案權限:`chmod +x test.sh`。 81 | 82 | 最後執行它:`./test.sh abc`,傳入參數`abc`。 83 | 84 | 就會建立一個叫做 abc.js 的檔案,這就是一個很簡單的 shell script。 85 | 86 | 現在請你寫一個 shell script,可以傳入一個數字 n,然後會產生 1~n 個檔案,檔名是 `{number}.js`。 87 | 88 | 舉例來說:`./num.sh 10`會產生`1.js`、`2.js`...`10.js`。 89 | 90 | ## 超級挑戰題 91 | 92 | 請寫一個`github.sh`,可以傳入一個參數 username,執行之後就會輸出這個 GitHub 使用者的暱稱、介紹、地點跟個人網站。 93 | 94 | 範例: 95 | 96 | ``` 97 | ./github.sh aszx87410 98 | 99 | 輸出: 100 | Huli 101 | Love coding, teaching, and writing. Believe sharing can make the world a better place. 102 | Taipei, Taiwan 103 | https://medium.com/@hulitw 104 | ``` 105 | -------------------------------------------------------------------------------- /homeworks/week1/hw1.md: -------------------------------------------------------------------------------- 1 | ## 交作業流程 2 | 3 | -------------------------------------------------------------------------------- /homeworks/week1/hw3.md: -------------------------------------------------------------------------------- 1 | ## 教你朋友 CLI 2 | 3 | -------------------------------------------------------------------------------- /homeworks/week1/hw4.md: -------------------------------------------------------------------------------- 1 | ## 跟你朋友介紹 Git 2 | 3 | -------------------------------------------------------------------------------- /homeworks/week1/hw5.md: -------------------------------------------------------------------------------- 1 | ## 請解釋後端與前端的差異。 2 | 3 | 4 | ## 假設我今天去 Google 首頁搜尋框打上:JavaScri[t 並且按下 Enter,請說出從這一刻開始到我看到搜尋結果為止發生在背後的事情。 5 | 6 | 7 | 8 | ## 請列舉出 5 個 command line 指令並且說明功用 -------------------------------------------------------------------------------- /homeworks/week10/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:六到十週心得與解題心得 4 | 5 | 第二次的複習週終於來了,在這週裡面可以好好整理一下自己前面幾週學到的東西,因此這一週不會有什麼新的進度。 6 | 7 | 這次的作業希望大家整理一下前面幾週的心得,畢竟我們終於開始進入到網頁前後端的領域了,應該會有滿多心得可以寫。 8 | 9 | 而複習週的慣例就是會提供闖關遊戲讓大家玩,也可以一併把心得寫下來 10 | 11 | 請將答案寫在 [hw1.md](hw1.md)。 12 | -------------------------------------------------------------------------------- /homeworks/week10/hw1.md: -------------------------------------------------------------------------------- 1 | ## 六到十週心得與解題心得 2 | 3 | 4 | -------------------------------------------------------------------------------- /homeworks/week11/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ### 注意 4 | 5 | 這週的 hw1~hw3 是連續的作業,只要交一份就好,不用每一個都特地交一個。然後記得把你連線到資料庫的檔案(conn.php),加入`.gitignore`,否則這檔案會被放到 GitHub 上,大家就知道資料庫的帳號密碼了。 6 | 7 | 另外,請你在留言板的最上方加註一行警語:「本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼」,加警語的目的是因為這週要做的網站極度不安全,很有可能被駭客拿到整個資料庫的資料,因此請切記在這網頁上不要輸入任何敏感資訊。 8 | 9 | ## hw1:幫密碼穿衣服 10 | 11 | 在課程中有提到上次寫的會員系統的缺陷之一,那就是密碼存明碼。密碼存明碼的風險就是一旦你的伺服器被入侵,資料庫被偷走的時候,使用者的密碼就外洩了。 12 | 13 | 你可能會問說:「所以,難道資料庫不能存密碼嗎?」 14 | 15 | 是的,我們要改存「另外一種形式」。 16 | 17 | 這是什麼意思呢?有一種東西叫做:Hash function,中文翻作雜湊函數,這個函數的重點就是它是單向的。你輸入 123 可以得到 202cb962ac59075b964b07152d234b70,但你沒辦法從 202cb962ac59075b964b07152d234b70 推出輸入是 123。 18 | 19 | 聽起來很神奇對吧? 20 | 21 | 所以我們的密碼就必須利用這種 hash function,在存入資料庫以前先轉變成另外一種形式。在驗證密碼的時候也是同理,我們不驗證密碼,而是驗證`hash_function(password)`跟資料庫裡面所存的密碼是不是一致。 22 | 23 | 這樣一來,就算我們的資料庫整個被偷走,駭客們還是不知道使用者的密碼是什麼(或其實是說很難知道啦,要花很多時間)。 24 | 25 | PHP 在 5.5 以上提供了兩個函式:`password_hash`跟`password_verify`,請你利用這兩個函式把之前會員註冊跟登入的頁面改寫,讓你的系統變得更安全一點。 26 | 27 | ## hw2:通行證 28 | 29 | 在上一週的作業裡面,我們把會員的帳號存在 Cookie 裡面,藉此判斷會員是不是已經登入了,以及驗證身份。可是這樣子做其實會有問題產生,首先,先跟我唸一遍資安金句: 30 | 31 | > 千萬不要相信來自 Client 端的資料 32 | 33 | 為什麼?因為只要是存在 Client 端的資料,都是可以被篡改的。假設有人把 Cookie 裡面的會員帳號改成:admin,那他就可以以管理員的身份登入了。 34 | 35 | 那要怎麼辦才好呢? 36 | 37 | 你可以回想你要去商業辦公大樓面試的時候,通常會要你在櫃檯換證。換了證之後,認證不認人,你的證是誰,你就是誰。在會員系統的實作上面,我們也可以參考這一個機制。 38 | 39 | 1. 會員輸入帳號密碼,按下登入 40 | 2. 若錯誤,返回錯誤訊息 41 | 3. 若正確,亂數產生一個通行證 ID,並且在資料庫裡面記下通行證 ID 與會員 ID 的對應關係 42 | 4. 把通行證 ID 設置到 Cookie 43 | 5. 下次再發 Request 來,就會把通行證 ID 一起帶上來 44 | 6. 檢查通行證 ID 是否有對應到的 ID,有的話就代表是那個人 45 | 46 | 我們引入了通行證的機制以後,就不用怕有人會竄改 Client 端的資料了,除非通行證被偷走,不然不可能用猜的把通行證 ID 猜出來。(所以你的通行證 ID 通常會長得很像亂碼,可以去查查 PHP 怎麼去產生亂數) 47 | 48 | 現在這個作業,就要你把會員系統的驗證換成上面這個通行證的機制,你會需要在資料庫新增一個 Table 來儲存通行證跟帳號的對應關係,可參考以下結構: 49 | 50 | Table 名稱:users_certificate 51 | 52 | | 欄位名稱 | 欄位型態 | 說明 | 53 | |----------|----------|------| 54 | | id | VARCHAR(32) | 通行證 id | 55 | | username | VARCHAR(16) | 帳號 | 56 | 57 | (附註:這一題你絕對不會用到 $_SESSION 這個東西,如果你查到任何跟 $_SESSION 有關的東西請自動略過。) 58 | 59 | ## hw3:加強留言板 60 | 61 | 在上次的作業中,只有顯示留言跟新增留言這兩個基本功能而已。而這次的作業,我們要再多加幾個功能,讓這個留言板變得更完整。 62 | 63 | 1. 會員可以刪除自己的留言 64 | 2. 會員可以編輯自己的留言 65 | 3. 實作分頁系統,一頁只顯示二十筆資料,並且可以換到其他頁 66 | 67 | ## hw4:簡答題 68 | 69 | 1. 請說明雜湊跟加密的差別在哪裡,為什麼密碼要雜湊過後才存入資料庫 70 | 2. 請舉出三種不同的雜湊函數 71 | 3. 請去查什麼是 Session,以及 Session 跟 Cookie 的差別 72 | 4. `include`、`require`、`include_once`、`require_once` 的差別 73 | 74 | 請將答案寫在 [hw4.md](hw4.md)。 75 | 76 | ## 挑戰題 77 | 78 | 新增一個「管理員」的功能以及後台。 79 | 80 | 幫每個 user 都加上一個新的欄位代表身份,身份有兩種:normal 跟 admin。 81 | 82 | 新增一個管理員專屬的後台,身份要是 admin 才看得到,進去之後可以看到所有的文章,並且有權限編輯與刪除任意一篇文章。 83 | 84 | ## 超級挑戰題 85 | 86 | 承上,再新增另一種新的身份叫做 super admin。 87 | 88 | 新增一個權限管理的頁面,只有 super admin 看得見,而 super admin 可以看到所有會員的資料,並且把任意使用者的身份改成 admin。 89 | 90 | -------------------------------------------------------------------------------- /homeworks/week11/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week11/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week11/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week11/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week11/hw3/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week11/hw3/index.html -------------------------------------------------------------------------------- /homeworks/week11/hw4.md: -------------------------------------------------------------------------------- 1 | ## 請說明雜湊跟加密的差別在哪裡,為什麼密碼要雜湊過後才存入資料庫 2 | 3 | 4 | ## 請舉出三種不同的雜湊函數 5 | 6 | 7 | ## 請去查什麼是 Session,以及 Session 跟 Cookie 的差別 8 | 9 | 10 | ## `include`、`require`、`include_once`、`require_once` 的差別 -------------------------------------------------------------------------------- /homeworks/week12/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ### 注意 4 | 5 | 這週的 hw1~hw2 是連續的作業,只要交一份就好,不用每一個都特地交一個。然後記得把你連線到資料庫的檔案(conn.php),加入`.gitignore`,否則這檔案會被放到 GitHub 上,大家就知道資料庫的帳號密碼了。 6 | 7 | 另外,請你在留言板的最上方加註一行警語:「本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼」,加警語的目的是因為這週要做的網站極度不安全,很有可能被駭客拿到整個資料庫的資料,因此請切記在這網頁上不要輸入任何敏感資訊。 8 | 9 | ## hw1:修補漏洞 10 | 11 | 如同我在課程中提過的,上週做出來的網頁裡面,會有兩個網頁最知名的漏洞: 12 | 13 | 1. SQL Injection 14 | 2. XSS 15 | 16 | 現在請你試試看對你上週做出來的網頁做這兩種攻擊,看看是否能成功,並且修補這兩個漏洞。 17 | 18 | ## hw2:加強留言板 19 | 20 | 這一週要再次增強留言板的功能: 21 | 22 | 1. 身為使用者,可以在別人的留言底下新增留言,一樣可以輸入暱稱跟留言內容 23 | 2. 身為系統,在顯示留言時應該一併列出底下所有的子留言 24 | 3. 會員在自己的留言底下回覆的話,背景會顯示不同的顏色 25 | 26 | 簡單來說就是新增一個「子留言」的功能,只要有一層即可,不需要實作多層的子留言。然後也加一個小功能,如果原 po 自己回覆自己的留言,那篇子留言的背景要用不同顏色,這樣大家很容易辨別他是原 po。 27 | 28 | ## hw3:簡答題 29 | 30 | 1. 請說明 SQL Injection 的攻擊原理以及防範方法 31 | 2. 請說明 XSS 的攻擊原理以及防範方法 32 | 3. 請說明 CSRF 的攻擊原理以及防範方法 33 | 34 | 請將答案寫在 [hw3.md](hw3.md)。 35 | 36 | ## 挑戰題 37 | 38 | 幫每個留言都新增一個「讚」的按鈕,使用者可以點任何留言讚,但只能點一次。再點一次的話會取消讚。前端介面要顯示總共被讚了幾次。 39 | 40 | ## 超級挑戰題 41 | 42 | 支援多層子留言,最多到五層。意思就是說,我的留言可以長這樣(`--`代表一層): 43 | 44 | ``` 45 | 大家好,我是新的會員 46 | -- 你好 47 | ---- 幸會幸會 48 | ---- 最近好嗎 49 | -- 安安,我台北人 50 | ---- 我也台北人欸 51 | ------ 有人是高雄人嗎? 52 | ------ 有人嗎? 53 | -------- 我是高雄人 54 | -------- 高雄有什麼好吃的 55 | ---- 好巧喔 56 | ---- 台北好玩的點有什麼 57 | -- 哈囉,我也是新的會員 58 | ``` 59 | -------------------------------------------------------------------------------- /homeworks/week12/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week12/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week12/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week12/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week12/hw3.md: -------------------------------------------------------------------------------- 1 | ## 請說明 SQL Injection 的攻擊原理以及防範方法 2 | 3 | 4 | ## 請說明 XSS 的攻擊原理以及防範方法 5 | 6 | 7 | ## 請說明 CSRF 的攻擊原理以及防範方法 8 | 9 | -------------------------------------------------------------------------------- /homeworks/week13/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:實作基本網格系統 4 | 5 | 其實網格系統說穿了,就只是在不同寬度的時候依照比例調整 column 的寬度而已。這一個作業,你要實作出基本的網格系統,詳細規格可參考下面: 6 | 7 | 1. 每一個 row 有 12 格 8 | 2. 有一個叫做 container 的 class 會把裡面的內容置中,寬度則是 960px 9 | 3. 一共有 12 種 col 的 class,col-1, col-2...col-12 10 | 11 | 只要螢幕寬度小於 720px,每一格都會佔滿整個 row。 12 | 13 | ## hw2:超基礎 Todo list 14 | 15 | ![](todo.png) 16 | 17 | 請你完成一個很簡單的 Todo List,需要有以下功能: 18 | 19 | 1. 身為使用者,我可以新增 todo item 20 | 2. 身為使用者,我可以刪除 todo item 21 | 3. 身為使用者,我可以標記某個 todo item 已完成 22 | 23 | ## hw3:加強留言板 24 | 25 | 之前在課程中講過 Bootstrap 這一個好用的 library,能夠讓你把版面變得好看一點,現在就請你利用 Bootstrap 改造之前的留言板 UI。 26 | 27 | 另外,請把發送留言跟刪除留言的地方改成 ajax,新增留言跟刪除的時候都不用換頁,藉此增進使用者體驗。 28 | 29 | 最後,我們在之前有實作過「通行證」的機制,其實在 PHP 裡面有內建的可以用,而這個機制就叫做 session。可以參考 [PHP 5 Sessions](https://www.w3schools.com/php/php_sessions.asp) 或是 [PHP Session 使用介紹,啟用與清除 session](http://www.webtech.tw/info.php?tid=33),把之前留言板的作業改成用 PHP 內建的 session 機制,而不是用我們自己實作的。 30 | 31 | ## hw4:簡答題 32 | 33 | 1. Bootstrap 是什麼? 34 | 2. 請簡介網格系統以及與 RWD 的關係 35 | 3. 請找出任何一個與 Bootstrap 類似的 library 36 | 4. jQuery 是什麼? 37 | 5. jQuery 與 vanilla JS 的關係是什麼? 38 | 39 | 請將答案寫在 [hw4.md](hw4.md)。 40 | 41 | ## 挑戰題 42 | 43 | 把留言板用自己寫的網格系統,改成支援 RWD。 44 | 45 | ## 超級挑戰題 46 | 47 | 把所有跟留言板有關的操作都變成 Ajax,並且與自己寫的後端 API 串接。 48 | -------------------------------------------------------------------------------- /homeworks/week13/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week13/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week13/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week13/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week13/hw3/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week13/hw3/index.html -------------------------------------------------------------------------------- /homeworks/week13/hw4.md: -------------------------------------------------------------------------------- 1 | ## Bootstrap 是什麼? 2 | 3 | 4 | 5 | ## 請簡介網格系統以及與 RWD 的關係 6 | 7 | 8 | 9 | ## 請找出任何一個與 Bootstrap 類似的 library 10 | 11 | 12 | 13 | ## jQuery 是什麼? 14 | 15 | 16 | 17 | ## jQuery 與 vanilla JS 的關係是什麼? 18 | 19 | 20 | -------------------------------------------------------------------------------- /homeworks/week13/todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week13/todo.png -------------------------------------------------------------------------------- /homeworks/week14/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:短網址系統設計 4 | 5 | 請你畫出一張短網址服務的後端系統架構圖,越詳細越好,可以考慮到如何增進效能、scaling 以及備份資料。 6 | 7 | 沒靈感的話可參考:[短网址(short URL)系统的原理及其实现](https://hufangyun.com/2017/short-url/)、[Design TinyURL](https://leetcode.com/problems/design-tinyurl/description/) 8 | 9 | 圖片可參考下圖(這是一張 Mobile 與 Web 前端如何跟後端溝通的圖,這示意圖只是大概講一下應該要怎麼畫,但你實際畫出來一定跟這個長得不一樣): 10 | ![](http://ithelp.ithome.com.tw/upload/images/20161211/20091346nyV3Lex42r.jpg) 11 | 12 | ## hw2:部署 13 | 14 | 請把你之前寫的 PHP 程式部署到自己的機器上面,並且對應到自己購買的網域。 15 | 16 | 可參考其他同學的心得(特別感謝 @yuchun33 跟 @futianshen ): 17 | 1. [部署 AWS EC2 遠端主機 + Ubuntu LAMP 環境 + phpmyadmin ](https://github.com/Lidemy/mentor-program-2nd-yuchun33/issues/15) 18 | 2. [一小時完成 VPS (Virtual Private Server) 部署 ](https://github.com/Lidemy/mentor-program-2nd-futianshen/issues/21) 19 | 20 | ## hw3:簡答題 21 | 22 | 1. 什麼是 DNS?Google 有提供的公開的 DNS,對 Google 的好處以及對一般大眾的好處是什麼? 23 | 2. 什麼是資料庫的 lock?為什麼我們需要 lock? 24 | 3. NoSQL 跟 SQL 的差別在哪裡? 25 | 4. 資料庫的 ACID 是什麼? 26 | 27 | 請將答案寫在 [hw3.md](hw3.md)。 28 | 29 | ## 挑戰題 30 | 31 | 在主機上使用 nginx 來當伺服器而不是 Apache。 32 | 33 | ## 超級挑戰題 34 | 35 | 使用 Docker 把 PHP 留言板以及資料庫都包進去,並且使用 Docker 來部署。 36 | -------------------------------------------------------------------------------- /homeworks/week14/hw3.md: -------------------------------------------------------------------------------- 1 | ## 什麼是 DNS?Google 有提供的公開的 DNS,對 Google 的好處以及對一般大眾的好處是什麼? 2 | 3 | 4 | ## 什麼是資料庫的 lock?為什麼我們需要 lock? 5 | 6 | 7 | ## NoSQL 跟 SQL 的差別在哪裡? 8 | 9 | 10 | ## 資料庫的 ACID 是什麼? -------------------------------------------------------------------------------- /homeworks/week15/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:十一到十五週心得 4 | 5 | 第三次的複習週東西變得比以往還多,需要一些時間好好消化這些資訊。若是有什麼心得的話,都歡迎寫下來。覺得複習已經夠累了,懶得寫心得的話也沒關係。 6 | 7 | 請將答案寫在 [hw1.md](hw1.md)。 8 | -------------------------------------------------------------------------------- /homeworks/week15/hw1.md: -------------------------------------------------------------------------------- 1 | ## 十一到十五週心得 2 | 3 | 4 | -------------------------------------------------------------------------------- /homeworks/week16/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:CSS 預處理器 4 | 5 | 自從學會 CSS 預處理器之後,寫 CSS 的複雜度一下子降低了很多,一方面是巢狀 CSS 可以很簡單的實作出來,另一方面是多了變數這個好用的東西。 6 | 7 | 現在請你把以前寫的 CSS 用你自己挑的 CSS preprocessor(LESS, SASS, Stylus)來改寫(要選哪一個作業都行,隨便選一個就好,只是想讓大家熟悉一下預處理器的用法) 。 8 | 9 | ## hw2:實作出 Stack 與 Queue 10 | 11 | 請你實作出`Stack`跟`Queue`兩個 Function(或是 Class),讓以下程式碼可以順利執行: 12 | (禁止使用內建函式`push`與`pop`) 13 | 14 | ``` js 15 | var stack = new Stack() 16 | stack.push(10) 17 | stack.push(5) 18 | console.log(stack.pop()) // 5 19 | console.log(stack.pop()) // 10 20 | 21 | var queue = new Queue() 22 | queue.push(1) 23 | queue.push(2) 24 | console.log(queue.pop()) // 1 25 | console.log(queue.pop()) // 2 26 | ``` 27 | 28 | ## hw3:HTTP Cache 29 | 30 | 請閱讀這篇文章:[循序漸進理解 HTTP Cache 機制](https://blog.techbridge.cc/2017/06/17/cache-introduction/)來理解 HTTP Cache 機制。 31 | 32 | ## hw4:簡答題 33 | 34 | 1. CSS 預處理器是什麼?我們可以不用它嗎? 35 | 2. 請舉出任何一個跟 HTTP Cache 有關的 Header 並說明其作用。 36 | 3. Stack 跟 Queue 的差別是什麼? 37 | 4. 請去查詢資料並解釋 CSS Selector 的權重是如何計算的(不要複製貼上,請自己思考過一遍再自己寫出來,沒有很完整也行) 38 | 39 | 請將答案寫在 [hw4.md](hw4.md)。 40 | 41 | ## 挑戰題 42 | 43 | 去查詢什麼是 PostCSS 並使用它,順便解釋為什麼我們需要 PostCSS。 44 | 45 | ## 超級挑戰題 46 | 47 | 去學習兩種新的資料結構:Deque 與 Priority queue,並且用 JavaScript 來實作。 48 | -------------------------------------------------------------------------------- /homeworks/week16/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week16/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week16/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week16/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week16/hw4.md: -------------------------------------------------------------------------------- 1 | ## CSS 預處理器是什麼?我們可以不用它嗎? 2 | 3 | 4 | ## 請舉出任何一個跟 HTTP Cache 有關的 Header 並說明其作用。 5 | 6 | 7 | ## Stack 跟 Queue 的差別是什麼? 8 | 9 | ## 請去查詢資料並解釋 CSS Selector 的權重是如何計算的(不要複製貼上,請自己思考過一遍再自己寫出來) -------------------------------------------------------------------------------- /homeworks/week17/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:Event Loop 4 | 5 | 在 JavaScript 裡面,一個很重要的概念就是 Event Loop,是 JavaScript 底層在執行程式碼時的運作方式。請你說明以下程式碼會輸出什麼,以及盡可能詳細地解釋原因。 6 | 7 | ``` js 8 | console.log(1) 9 | setTimeout(() => { 10 | console.log(2) 11 | }, 0) 12 | console.log(3) 13 | setTimeout(() => { 14 | console.log(4) 15 | }, 0) 16 | console.log(5) 17 | ``` 18 | 19 | 請將答案寫在 [hw1.md](hw1.md)。 20 | 21 | ## hw2:Event Loop + Scope 22 | 23 | 請說明以下程式碼會輸出什麼,以及盡可能詳細地解釋原因。 24 | 25 | ``` js 26 | for(var i=0; i<5; i++) { 27 | console.log('i: ' + i) 28 | setTimeout(() => { 29 | console.log(i) 30 | }, i * 1000) 31 | } 32 | ``` 33 | 34 | 請將答案寫在 [hw2.md](hw2.md)。 35 | 36 | ## hw3:Hoisting 37 | 38 | 請說明以下程式碼會輸出什麼,以及盡可能詳細地解釋原因。 39 | 40 | ``` js 41 | var a = 1 42 | function fn(){ 43 | console.log(a) 44 | var a = 5 45 | console.log(a) 46 | a++ 47 | var a 48 | fn2() 49 | console.log(a) 50 | function fn2(){ 51 | console.log(a) 52 | a = 20 53 | b = 100 54 | } 55 | } 56 | fn() 57 | console.log(a) 58 | a = 10 59 | console.log(a) 60 | console.log(b) 61 | ``` 62 | 63 | 請將答案寫在 [hw3.md](hw3.md)。 64 | 65 | ## hw4:What is this? 66 | 67 | 請說明以下程式碼會輸出什麼,以及盡可能詳細地解釋原因。 68 | 69 | ``` js 70 | const obj = { 71 | value: 1, 72 | hello: function() { 73 | console.log(this.value) 74 | }, 75 | inner: { 76 | value: 2, 77 | hello: function() { 78 | console.log(this.value) 79 | } 80 | } 81 | } 82 | 83 | const obj2 = obj.inner 84 | const hello = obj.inner.hello 85 | obj.inner.hello() // ?? 86 | obj2.hello() // ?? 87 | hello() // ?? 88 | ``` 89 | 90 | 請將答案寫在 [hw4.md](hw4.md)。 91 | 92 | ## hw5:簡答題 93 | 94 | 1. 這週學了一大堆以前搞不懂的東西,你有變得更懂了嗎?請寫下你的心得。 95 | 96 | 請將答案寫在 [hw5.md](hw5.md)。 97 | 98 | ## 挑戰題 99 | 100 | 看完 [Dmitry Soshnikov 這個部落格](http://dmitrysoshnikov.com/)的兩個系列:ECMA-262-3 in detail 與 ECMA-262-5 in detail。 101 | 102 | ## 進階挑戰題 103 | 104 | 大略讀過 [ES3](https://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf) 文件(共 188 頁),至少知道裡面大概有哪些東西以及專有名詞。 105 | -------------------------------------------------------------------------------- /homeworks/week17/hw1.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week17/hw1.md -------------------------------------------------------------------------------- /homeworks/week17/hw2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week17/hw2.md -------------------------------------------------------------------------------- /homeworks/week17/hw3.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week17/hw3.md -------------------------------------------------------------------------------- /homeworks/week17/hw4.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week17/hw4.md -------------------------------------------------------------------------------- /homeworks/week17/hw5.md: -------------------------------------------------------------------------------- 1 | ## 這週學了一大堆以前搞不懂的東西,你有變得更懂了嗎?請寫下你的心得。 2 | 3 | -------------------------------------------------------------------------------- /homeworks/week18/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:Gulp 4 | 5 | gulp 就是用來把原本的工作流程自動化的,現在請你寫一個 gulp 的設定檔,依序完成以下事情: 6 | 7 | 1. 把 scss 編譯成 css 8 | 2. 把 js 用 babel 轉成 ES5 語法 9 | 3. 把 css 以及 js 壓縮 10 | 11 | ## hw2:Webpack 12 | 13 | Webpack 的目的其實就是讓前端也能夠像 Node.js 那樣,支援 `module.exports` 以及 `require`。 14 | 15 | 為了讓你體驗 Webpack,在這個作業中你只要做以下簡單的幾件事情就好: 16 | 17 | 1. 寫一個檔案叫做 `utils.js`,裡面有一個叫做 `add` 的 function 18 | 2. 寫一個檔案叫做 `index.js` 19 | 3. 在 `index.js` 裡面引入 `add` 這個 function 並且輸出`add(10, 3)` 20 | 4. 用 Webpack 把以上檔案打包產生出 `bundle.js` 21 | 22 | ## hw3:Todo List 23 | 24 | 之前在第十三週時已經讓大家寫過一個 todo list,這次我們要來點不一樣的。 25 | 26 | 其實有一種寫法非常直覺,而且寫起來非常方便,那就是「只要資料更新,我就全部重新 render」。 27 | 28 | 什麼意思呢?之前我們寫第七週的作業時,新增的話就是新增一筆資料,然後在 DOM 上面 append,刪除的話就是直接把 DOM 上面的那筆元素刪掉。 29 | 30 | 可是其實還有另外一種做法,用程式碼示意的話會長這樣: 31 | 32 | ``` js 33 | var list = [] 34 | function addTodo(todo) { 35 | list.push(todo) 36 | render() 37 | } 38 | 39 | function removeTodo(id) { 40 | list = list.filter(item => item.id !== id) 41 | render() 42 | } 43 | 44 | function render(){ 45 | $('.todo-list').empty() 46 | $('.todo-list').append(list.map(item => `
  • ${todo.content}
  • `)) // 示意 47 | } 48 | ``` 49 | 50 | 每次只要資料有更新,你就更新資料就好,然後把畫面全部重新渲染。如此一來的好處就是你完全不用管 DOM,你只要更新程式裡面的資料即可。 51 | 52 | 現在請你把之前實作的 Todo list 改成這種形式,更新資料並且 re-render。 53 | 54 | ## hw4:簡答題 55 | 56 | 1. gulp 跟 webpack 有什麼不一樣?我們可以不用它們嗎? 57 | 2. hw3 把 todo list 這樣改寫,可能會有什麼問題? 58 | 3. CSS Sprites 與 Data URI 的優缺點是什麼? 59 | 60 | 請將答案寫在 [hw4.md](hw4.md)。 61 | 62 | ## 挑戰題 63 | 64 | 把我們用 Gulp 做的事情: 65 | 66 | 1. 把 scss 編譯成 css 67 | 2. 把 js 用 babel 轉成 ES5 語法 68 | 3. 把 css 以及 js 壓縮 69 | 70 | 全都改成用 Webpack 來做。 71 | 72 | ## 超級挑戰題 73 | 74 | 實作出一個超級陽春的打包工具叫做 `easy-bundle`,只要指定 entry point 的檔案就可以進行打包。 75 | 76 | 假設我現在一個檔案叫做 `utils.js`,裡面有一個叫做 `add` 的 function,然後有另一個檔案叫做 `index.js`,並且在 `index.js` 裡面引入 `add` 這個 function 然後輸出`add(10, 3)` 77 | 78 | 範例: 79 | 80 | ``` 81 | node easy-bundle.js index.js // 開始打包,指定入口點為 index.js 82 | // 產生出一個 bundle.js 83 | ``` 84 | 85 | 簡單來說,就是實作出一個超級陽春版的 Webpack。 86 | -------------------------------------------------------------------------------- /homeworks/week18/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week18/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week18/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week18/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week18/hw3/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week18/hw3/index.html -------------------------------------------------------------------------------- /homeworks/week18/hw4.md: -------------------------------------------------------------------------------- 1 | ## gulp 跟 webpack 有什麼不一樣?我們可以不用它們嗎? 2 | 3 | 4 | ## hw3 把 todo list 這樣改寫,可能會有什麼問題? 5 | 6 | ## CSS Sprites 與 Data URI 的優缺點是什麼? -------------------------------------------------------------------------------- /homeworks/week19/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:Todo list 4 | 5 | 還記得你的好朋友 h0w 哥嗎? 6 | 7 | 他最近實在是太忙太忙了,接了一大堆案子跟業配,完全忙不過來。而現在最困擾他的事情是有時候會忘記廠商交代的事情,最後被罵個臭頭。這時候他想到了之前樂於助人的你,於是跑來找你,希望你能幫他做一個 Todo list 的 API 就好,只有 API 而已,可以不用有前端沒關係,前端他會再找其他朋友來做。 8 | 9 | 因此,你的任務就是幫 h0w 哥做一個 Todo list 的 API,需要有以下功能: 10 | 11 | 1. 獲取所有 todo 12 | 2. 讀取單一 todo 13 | 3. 刪除 todo 14 | 4. 新增 todo 15 | 5. 修改 todo 16 | 6. 一個 todo 會有內容跟狀態,狀態可分為兩種:已完成跟未完成。 17 | 18 | ## hw2:邊緣人 19 | 20 | 當你完成了 todo list API 兩天以後,h0w 哥又跑過來找你:「欸欸,可以幫我把前端也做一做嗎?」 21 | 22 | 『靠北喔,阿你之前不是說要找其他朋友幫你做』 23 | 24 | 「可是我...沒朋友」 25 | 26 | 『嗚嗚...這真是太可憐了,那我就幫你做吧!』 27 | 28 | 於是乎,你就接下了這個燙手山芋,決定好人做到底,把前端的部分也做一做,但這次 h0w 哥提出了一個前所未見的需求:為了使用者體驗著想,我希望前端永遠不會換頁,都在同一個頁面上操作。 29 | 30 | 翻成技術白話文,意思就是:所有跟後端的溝通都透過 ajax,這樣就不會換頁了。 31 | 32 | 因此,這就是你的任務!請實作出一個不會換頁的 todo list,並跟上一個作業自己寫出來的 api 串接。 33 | 34 | ## hw3:簡答題 35 | 36 | 1. 請簡單解釋什麼是 Single Page Application 37 | 2. SPA 的優缺點為何 38 | 39 | 請將答案寫在 [hw3.md](hw3.md)。 40 | 41 | ## 挑戰題 42 | 43 | 無 44 | 45 | 46 | ## 超級挑戰題 47 | 48 | 無 49 | 50 | -------------------------------------------------------------------------------- /homeworks/week19/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week19/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week19/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week19/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week19/hw3.md: -------------------------------------------------------------------------------- 1 | ## 請簡單解釋什麼是 Single Page Application 2 | 3 | 4 | ## SPA 的優缺點為何 5 | 6 | 7 | -------------------------------------------------------------------------------- /homeworks/week2/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | 備註:以下題目請看清楚題目要求,如果要你「印出」,代表你要在 function 內使用`console.log`印出正確答案,如果要你「回傳」,則是用`return`把正確的值傳回去。 4 | 5 | 在提交作業以前麻煩把自己份內的事情做好,確認我範例給的 input 你都輸出了正確的 output 才提交。 6 | 7 | ## hw1:印出星星 8 | 9 | 給定 n(1<=n<=30),依照規律「印出」正確圖形 10 | 11 | ``` 12 | printStars(1) 13 | 14 | 正確輸出: 15 | * 16 | ``` 17 | 18 | ``` 19 | printStars(3) 20 | 21 | 正確輸出: 22 | * 23 | * 24 | * 25 | ``` 26 | 27 | ``` 28 | printStars(6) 29 | 30 | 正確輸出: 31 | * 32 | * 33 | * 34 | * 35 | * 36 | * 37 | ``` 38 | 39 | ## hw2:首字母大寫 40 | 給定一字串,把第一個字轉成大寫之後「回傳」,若第一個字不是英文字母則忽略。 41 | 42 | ``` 43 | capitalize('nick') 44 | 正確回傳值:Nick 45 | 46 | capitalize('Nick') 47 | 正確回傳值:Nick 48 | 49 | capitalize(',hello') 50 | 正確回傳值:,hello 51 | ``` 52 | 53 | ## hw3:反轉字串 54 | 給定一個字串,請「印出」反轉之後的樣子(不能使用內建的 `reverse` 函式) 55 | 56 | ``` 57 | reverse('yoyoyo') 58 | 正確輸出:oyoyoy 59 | 60 | reverse('1abc2') 61 | 正確輸出:2cba1 62 | 63 | reverse('1,2,3,2,1') 64 | 正確輸出:1,2,3,2,1 65 | ``` 66 | 67 | ## hw4:印出因數 68 | 先幫大家複習一下數學,給定一個數字 n,因數就是所有小於等於 n 又可以被 n 整除的數,所以最明顯的例子就是 1 跟 n,這兩個數一定是 n 的因數。現在請寫出一個函式來「印出」所有的因數 69 | 70 | ``` 71 | printFactor(10) 72 | 73 | 正確輸出: 74 | 1 75 | 2 76 | 5 77 | 10 78 | ``` 79 | 80 | ``` 81 | printFactor(7) 82 | 83 | 正確輸出: 84 | 1 85 | 7 86 | ``` 87 | 88 | ## hw5:自己的函式自己寫 89 | 其實仔細思考的話,你會發現那些陣列內建的函式你其實都寫得出來,因此這一題就是要讓你自己動手實作那些函式! 90 | 91 | 我們要實作的函式有兩個:join 以及 repeat。(再次強調,這一題要你自己實作這些函式,所以你不會用到內建的`join`以及`repeat`) 92 | 93 | join 會接收兩個參數:一個陣列跟一個字串,會在陣列的每個元素中間插入一個字串,最後回傳合起來的字串。 94 | 95 | repeat 的話就是回傳重複 n 次之後的字串。 96 | 97 | ``` 98 | join([1, 2, 3], ''),正確回傳值:123 99 | join(["a", "b", "c"], "!"),正確回傳值:a!b!c 100 | join(["a", 1, "b", 2, "c", 3], ','),正確回傳值:a,1,b,2,c,3 101 | 102 | repeat('a', 5),正確回傳值:aaaaa 103 | repeat('yoyo', 2)正確回傳值:yoyoyoyo 104 | ``` 105 | 106 | ## hw6:簡答題 107 | 108 | 在學程式的時候有一個能力很重要,你必須靜下心來一行一行在看這個程式到底在幹嘛,並且在腦中模擬出這個程式執行的樣子,意思就是你要假裝自己就是 JS 引擎。 109 | 110 | 這是一個非常實用的技能,我來舉個例子。 111 | 112 | ``` js 113 | for(var i=59; i<=61; i++) { 114 | if(i === 60) { 115 | console.log('剛好及格') 116 | } else if (i < 60) { 117 | console.log('不及格') 118 | } else { 119 | console.log('及格') 120 | } 121 | } 122 | ``` 123 | 124 | 1. 執行第 1 行,設定變數 i 是 59,檢查 i 是否 <= 61,是,繼續執行,開始進入第一圈迴圈 125 | 2. 執行第 2 行,判斷 i 是否等於 60,不是,繼續往下 126 | 3. 執行第 4 行,判斷 i 是否小於 60,是 127 | 4. 執行第 5 行,log 不及格 128 | 5. 第一圈迴圈結束,跑回第一行,i++,i 變成 60,檢查是否 <= 61,是,繼續執行 129 | 6. 執行第 2 行,判斷 i 是否等於 60,是 130 | 7. 執行第 3 行,log 剛好及格 131 | 8. 第二圈迴圈結束,跑回第一行,i++,i 變成 61,檢查是否 <= 61,是,繼續執行 132 | 9. 執行第 2 行,判斷 i 是否等於 60,不是,繼續往下 133 | 10. 執行第 4 行,判斷 i 是否小於 60,不是,繼續往下 134 | 11. 執行第 6 行並進入到第 7 行,log 及格 135 | 12. 第三圈迴圈結束,跑回第一行,i++,i 變成 62,檢查是否 <= 61,否 136 | 13. 執行完畢 137 | 138 | 寫起來非常冗長,但每寫一步都會讓你對這個程式怎麼運作的變得更清晰,對程式思維非常有幫助。而且一但你習慣了這樣的方式,很快地對於一些簡單的情形你就不需要寫下來了,你可以直接用大腦模擬出程式執行的樣子。 139 | 140 | 現在,請假裝自己是電腦,像是上面示範的那樣,一步步寫下底下這個程式的執行流程,並且試著猜猜看它在做什麼: 141 | 142 | ``` js 143 | function isValid(arr) { 144 | for(var i=0; i 3 168 | search([1, 3, 10, 14, 39], 299) => -1 169 | ``` 170 | 171 | 這題之所以放在挑戰題,是因為這一題的解法要比這個更快: 172 | 173 | ``` 174 | function search(arr, n) { 175 | for(var i=0; i true 38 | n = 3 => true 39 | n = 10 => false 40 | n = 37 => true 41 | n = 38 => false 42 | ``` 43 | 44 | ## hw4:判斷迴文 45 | 給定一個長度小於 100 的字串 s,請回傳 s 是否為迴文(迴文的定義:正著唸倒著念都一樣) 46 | 47 | ``` 48 | abcba => true 49 | apple => false 50 | aaaaa => true 51 | applppa => true 52 | ``` 53 | 54 | ## hw5:大數加法 55 | 給定兩個長度為 l(1<=l<=1000)的數字(但型態為字串),請回傳兩個數字相加後的結果。 56 | 57 | 提示: 58 | 59 | 1. 這題不是要考你型態轉換,而且這題很難,真的很難 60 | 2. 小時候怎麼做直式加法,這一題就怎麼做,可以拿紙跟筆試試看 61 | 62 | ``` 63 | "123"+"456" => "579" 64 | "12312383813881381381"+"129018313819319831" => "12441402127700701212" 65 | ``` 66 | 67 | ## hw6:簡答題 68 | 請將答案寫在 [hw6.md](hw6.md)。 69 | 70 | 1. 請寫下以上五題的解題心得 71 | 72 | ## 挑戰題 73 | 74 | 大數乘法:給定兩個長度為 l(1<=l<=1000)的數字(但型態為字串),請回傳兩個數字「相乘」後的結果。 75 | 76 | ## 超級挑戰題 77 | 78 | 大數除法:給定兩個長度為 l(1<=l<=1000)的數字(但型態為字串),請回傳兩個數字「相除」後的結果。 -------------------------------------------------------------------------------- /homeworks/week3/hw1.js: -------------------------------------------------------------------------------- 1 | function stars(n) { 2 | console.log(n); 3 | } 4 | 5 | module.exports = stars; 6 | -------------------------------------------------------------------------------- /homeworks/week3/hw1.test.js: -------------------------------------------------------------------------------- 1 | const stars = require('./hw1'); 2 | 3 | describe('hw1', () => { 4 | it('should return correct answer when n = 1', () => { 5 | expect(stars(1)).toEqual(['*']); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /homeworks/week3/hw2.js: -------------------------------------------------------------------------------- 1 | function alphaSwap(str) { 2 | console.log(str); 3 | } 4 | 5 | module.exports = alphaSwap; 6 | -------------------------------------------------------------------------------- /homeworks/week3/hw2.test.js: -------------------------------------------------------------------------------- 1 | const alphaSwap = require('./hw2'); 2 | 3 | describe('hw2', () => { 4 | it('should return correct answer when str = nick', () => { 5 | expect(alphaSwap('nick')).toBe('NICK'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /homeworks/week3/hw3.js: -------------------------------------------------------------------------------- 1 | function isPrime(n) { 2 | console.log(n); 3 | } 4 | 5 | module.exports = isPrime; 6 | -------------------------------------------------------------------------------- /homeworks/week3/hw3.test.js: -------------------------------------------------------------------------------- 1 | const isPrime = require('./hw3'); 2 | 3 | describe('hw3', () => { 4 | it('should return correct answer when n = 1', () => { 5 | expect(isPrime(1)).toBe(false); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /homeworks/week3/hw4.js: -------------------------------------------------------------------------------- 1 | function isPalindromes(str) { 2 | console.log(str); 3 | } 4 | 5 | module.exports = isPalindromes; 6 | -------------------------------------------------------------------------------- /homeworks/week3/hw4.test.js: -------------------------------------------------------------------------------- 1 | const isPalindromes = require('./hw4'); 2 | 3 | describe('hw4', () => { 4 | it('should return correct answer when str = abcdcba', () => { 5 | expect(isPalindromes('abcdcba')).toBe(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /homeworks/week3/hw5.js: -------------------------------------------------------------------------------- 1 | function add(a, b) { 2 | console.log(a, b); 3 | } 4 | 5 | module.exports = add; 6 | -------------------------------------------------------------------------------- /homeworks/week3/hw5.test.js: -------------------------------------------------------------------------------- 1 | const add = require('./hw5'); 2 | 3 | describe('hw5', () => { 4 | it('should return correct answer when a=111111111111111111111111111111111111 and b=111111111111111111111111111111111111', () => { 5 | expect(add('111111111111111111111111111111111111', '111111111111111111111111111111111111')).toBe('222222222222222222222222222222222222'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /homeworks/week3/hw6.md: -------------------------------------------------------------------------------- 1 | ## hw1:好多星星 2 | 3 | 4 | ## hw2:大小寫互換 5 | 6 | ## hw3:判斷質數 7 | 8 | ## hw4:判斷迴文 9 | 10 | ## hw5:大數加法 -------------------------------------------------------------------------------- /homeworks/week4/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## API 文件 4 | 5 | Base URL: https://lidemy-book-store.herokuapp.com 6 | 7 | | 說明 | Method | path | 參數 | 範例 | 8 | |--------|--------|------------|----------------------|----------------| 9 | | 獲取所有書籍 | GET | /books | _limit:限制回傳資料數量 | /books?_limit=5 | 10 | | 獲取單一書籍 | GET | /books/:id | 無 | /books/10 | 11 | | 新增書籍 | POST | /books | name: 書名 | 無 | 12 | | 刪除書籍 | DELETE | /books/:id | 無 | 無 | 13 | | 更改書籍資訊 | PATCH | /books/:id | name: 書名 | 無 | 14 | 15 | 16 | ## hw1:來自秋秋鞋的任務 17 | 18 | 有一天,住你隔壁的鄰居秋秋鞋跑來按門鈴,說有事想要找你討論,他最近在做一個知識型的 YouTube 頻道,可是快要沒有靈感了。 19 | 20 | 這時,他想到一個好主意!他只要能夠看到書店提供的書籍相關資訊,就可以從中汲取靈感,之後就可以發想相關題材,頻道就不會一直不更新了。 21 | 22 | 身為秋秋鞋的好朋友,這個重責大任當然就交給你了! 23 | 24 | 請閱讀開頭給的 API 文件並串接,用 node.js 寫出一個程式,執行後會在 console 列出前十本書籍的 id 以及書名。 25 | 26 | 順帶一提,叫做秋秋鞋是因為他很喜歡秋天。 27 | 28 | 範例: 29 | 30 | ``` js 31 | node hw1.js 32 | 33 | 1 克雷的橋 34 | 2 當我想你時,全世界都救不了我 35 | 3 我殺的人與殺我的人 36 | .... 37 | ``` 38 | 39 | ## hw2:不滿足的秋秋鞋 40 | 41 | 雖然說上次你幫秋秋鞋完成了列出書籍清單的程式,但是一次列出十本實在是太少了,大概一個禮拜就可以把這些資訊消化完,但是經營頻道卻是長期的事情,他需要更多更多的資料才行。例如說一次應該要輸出二十本書,然後可以輸入一個 id 就返回書籍資料,這樣他就可以隨便想一個數字,然後看看是哪本書,對於靈感很有幫助。 42 | 43 | 請你閱讀開頭給的 API 文件並串接,用 node.js 寫出一個程式並接受參數,輸出相對應的結果,範例如下: 44 | 45 | ``` js 46 | node hw2.js list // 印出前二十本書的 id 與書名 47 | node hw2.js read 1 // 輸出 id 為 1 的書籍資料 48 | ``` 49 | 50 | ## hw3:最後的考驗 51 | 52 | 原本以為上次就已經是最後一次幫忙,沒想到秋秋鞋還是又跑來找你了。他說他想要更多功能,他想把這整個書籍資料庫當作自己的來用,必須能夠刪除、新增以及修改書本,這樣他就可以管理自己的書籍了。 53 | 54 | 雖然你很想問他說為什麼不用 Excel 就好,但你問不出口,再加上你最近剛學成是需要練習的機會,於是你就答應了。 55 | 56 | 請閱讀開頭給的 API 文件並串接,用 node.js 寫出一個程式並接受參數,輸出相對應的結果,範例如下: 57 | 58 | ``` js 59 | node hw3.js list // 印出前二十本書的 id 與書名 60 | node hw3.js read 1 // 輸出 id 為 1 的書籍 61 | node hw3.js delete 1 // 刪除 id 為 1 的書籍 62 | node hw3.js create "I love coding" // 新增一本名為 I love coding 的書 63 | node hw3.js update 1 "new name" // 更新 id 為 1 的書名為 new name 64 | ``` 65 | 66 | ## hw4:探索新世界 67 | 68 | 上次幫秋秋鞋做完那個小程式以後,你會寫程式的消息似乎就傳開了,有一位 Twitch 平台實況主果凍跑來聯繫你,想請你幫忙做個東西。 69 | 70 | 事情是這樣的,他原本是 LOL 的玩家,但因為某些原因帳號被 ban 掉了,為了維持實況的熱度,需要去找其他遊戲來玩,可是他又不知道哪些遊戲比較熱門,會有比較多人觀看。 71 | 72 | 因此,他寫請你寫一個小程式,能夠去撈取 Twitch 上面受歡迎的遊戲,他就能夠參考這個列表來決定要實況哪個遊戲。 73 | 74 | 由於你偶爾也會看他的實況,所以你欣然接受了這個挑戰,準備來串串看真實世界的 API。 75 | 76 | 請參考 [Twitch API](https://dev.twitch.tv/docs/api/) 的文件,寫一隻程式去呼叫 Twitch API,並拿到「最受歡迎的遊戲列表(Get Top Games)」然後依序印出 id 跟遊戲名稱。 77 | 78 | ``` js 79 | node hw4.js 80 | 81 | 21779 League of Legends 82 | 29595 Dota2 83 | 511224 Apex Legends 84 | 33214 Fortnite 85 | .... 86 | ``` 87 | 88 | ## hw5:簡答題 89 | 90 | 請將答案寫在 [hw5.md](hw5.md)。 91 | 92 | 1. 請以自己的話解釋 API 是什麼? 93 | 2. 請找出三個課程沒教的 HTTP status code 並簡單介紹 94 | 3. 假設你現在是個餐廳平台,需要提供 API 給別人串接並提供基本的 CRUD 功能,包括:回傳所有餐廳資料、回傳單一餐廳資料、刪除餐廳、新增餐廳、更改餐廳,你的 API 會長什麼樣子?請提供一份 API 文件。 95 | 96 | ## 挑戰題 97 | 98 | 寫一個 node.js 的程式並串接 Twitch API,輸出遊戲「League of Legends」底下最受歡迎的前 200 個實況的名稱與 id。 99 | 100 | ## 超級挑戰題 101 | 102 | 寫一個 node.js 的程式並串接 Twitch API,接收一個參數是遊戲名稱,輸出那個遊戲底下最受歡迎的前 200 個實況的名稱與 id。 103 | 104 | ``` js 105 | // 範例 106 | node twitch.js "Apex Legends" 107 | ``` 108 | 109 | -------------------------------------------------------------------------------- /homeworks/week4/hw1.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week4/hw1.js -------------------------------------------------------------------------------- /homeworks/week4/hw2.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week4/hw2.js -------------------------------------------------------------------------------- /homeworks/week4/hw3.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week4/hw3.js -------------------------------------------------------------------------------- /homeworks/week4/hw4.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week4/hw4.js -------------------------------------------------------------------------------- /homeworks/week4/hw5.md: -------------------------------------------------------------------------------- 1 | ## 請以自己的話解釋 API 是什麼 2 | 3 | 4 | 5 | ## 請找出三個課程沒教的 HTTP status code 並簡單介紹 6 | 7 | 8 | 9 | ## 假設你現在是個餐廳平台,需要提供 API 給別人串接並提供基本的 CRUD 功能,包括:回傳所有餐廳資料、回傳單一餐廳資料、刪除餐廳、新增餐廳、更改餐廳,你的 API 會長什麼樣子?請提供一份 API 文件。 10 | 11 | -------------------------------------------------------------------------------- /homeworks/week5/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:前四週心得與解題心得 4 | 5 | 複習週除了複習以往的內容以外,也可以好好整理一下自己這四週學到了些什麼,因此這次的作業就是寫一下自己對於前四週學習的心得感想。 6 | 7 | 除此之外,這一週的兩個小挑戰應該也會讓你們有一些心得,可以一併把它記錄下來。 8 | 9 | 請將答案寫在 [hw1.md](hw1.md)。 10 | -------------------------------------------------------------------------------- /homeworks/week5/hw1.md: -------------------------------------------------------------------------------- 1 | ## 前四週心得與解題心得 2 | 3 | 4 | -------------------------------------------------------------------------------- /homeworks/week6/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:切版 4 | 5 | 請切出如下圖的版面: 6 | 7 | ![](example.png) 8 | 9 | 不需要做到完全一樣,但可以盡你所能做的相似,除此之外,還要支援超基本的 RWD,在手機上看也不會跑版。 10 | 11 | 你可以觀察[這個網頁](https://lidemy.github.io/mentor-program-kristxeng/homeworks/week2/hw1/)來決定應該如何實作。 12 | 13 | ### 進階挑戰題 14 | 15 | 1. 把內容改成一些真的文字(主題自己想,重點是要讓這網站看起來是真的可以用的網站)並美化網站 16 | 17 | ## hw2:仿 Medium 18 | 19 | 請切出如下圖的版面: 20 | ![](example2.png) 21 | 22 | 可以先觀察[這個網頁](https://lidemy.github.io/mentor-program-kristxeng/homeworks/week2/hw2)。 23 | 24 | 文字可以自己換成其他的,只要效果有達到就好。一樣要支援簡易的 RWD,在手機上看不會跑版(拍手會自動隱藏)。 25 | 26 | ### 進階挑戰題 27 | 28 | 1. 去觀察 Medium 的網站,連下面的推薦文章一起實作 29 | 2. 去觀察 Medium 的網站,左側的功能不只拍手,連社交分享功能一起切出來 30 | 3. 去觀察 Medium 的網站,並加上網頁上方的 nav bar 31 | 32 | ## hw3:CSS Diner 33 | 34 | 請完成這個小遊戲:https://flukeout.github.io/ 35 | 36 | ## hw4:Flexbox Froggy 37 | 38 | 請完成這個小遊戲:http://flexboxfroggy.com/ 39 | 40 | ## hw5:簡答題 41 | 42 | 請將答案寫在 [hw5.md](hw5.md)。 43 | 44 | 1. 請找出三個課程裡面沒提到的 HTML 標籤並一一說明作用。 45 | 2. 請問什麼是盒模型(box modal)? 46 | 3. 請問 display: inline, block 跟 inline-block 的差別是什麼?什麼時機點會用到? 47 | 4. 請問 position: static, relative, absolute 跟 fixed 的差別是什麼?分別各舉一個會用到的場合 48 | 49 | ## 挑戰題 50 | 51 | [Hacker News](https://news.ycombinator.com/) 是一個很知名的網站,上面有著各種與科技相關的資訊。現在請你看著這個網站,把它切出來。 52 | 53 | 或是如果你想把它變得更美,也可以試試看。 54 | 55 | ## 超級挑戰題 56 | 57 | 打開你的 Facebook,看著它。 58 | 59 | 打開你的文字編輯器,開始依樣畫葫蘆,切出一個 Facebook。 60 | 61 | 你只要切出你現在看得到的版面就好,不用考慮往下滑什麼的。但如果你切完還是心有餘力,那也可以試試看。 62 | -------------------------------------------------------------------------------- /homeworks/week6/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week6/example.png -------------------------------------------------------------------------------- /homeworks/week6/example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week6/example2.png -------------------------------------------------------------------------------- /homeworks/week6/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week6/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week6/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week6/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week6/hw5.md: -------------------------------------------------------------------------------- 1 | ## 請找出三個課程裡面沒提到的 HTML 標籤並一一說明作用。 2 | 3 | 4 | ## 請問什麼是盒模型(box modal) 5 | 6 | 7 | ## 請問 display: inline, block 跟 inline-block 的差別是什麼? 8 | 9 | 10 | ## 請問 position: static, relative, absolute 跟 fixed 的差別是什麼? 11 | 12 | -------------------------------------------------------------------------------- /homeworks/week7/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:反應力小遊戲 4 | 5 | 不知道大家有沒有玩過一種小遊戲,那就是畫面會在隨機的時間變色,你看到變色的那瞬間就要點擊螢幕,直接先讓大家看範例: 6 | 7 | ![](reaction.gif) 8 | 9 | 點擊完之後會彈出一個視窗跟你說從變色到你按下按鈕總共多少秒,若是點的時候畫面還沒變色,會彈出視窗跟你說你失敗了。無論成功或失敗都可以再玩一次。 10 | 11 | 這個作業就是要讓大家實作這個小遊戲,做出來以後也可以來跟朋友比賽,看誰的反應力快! 12 | 13 | ### 作業規範 14 | 15 | 1. 變色的隨機時間請設在 1~3 秒,否則會太長跟太短 16 | 2. 再玩一次的按鈕要在遊戲結束時才會出現 17 | 3. 若是失敗,畫面就不會再變色了,除非你點選再玩一次 18 | 4. 成功以後如果再點一次畫面,不會有任何反應 19 | 20 | ### 作業提示 21 | 22 | 1. 可以先不考慮再玩一次的功能,先實作一次性的會比較簡單 23 | 2. 這題看似不難,但有滿多細節要注意,詳情請參考上面的作業規範 24 | 25 | ### 進階挑戰題 26 | 27 | 1. 畫面變色的時候不是變成固定顏色,而是會隨機變一個顏色 28 | 2. 原本是偵測滑鼠左鍵點擊,改成用鍵盤按下空白鍵也可以玩 29 | 3. 用鍵盤按下 r 可以自動觸發再玩一次 30 | 4. 會記下自己所有紀錄的前三名(重新整理就會消失)並顯示在畫面上 31 | 32 | ## hw2:仿 Google 表單 33 | 34 | 請實作出你們當初報名時所填寫的表單:https://docs.google.com/forms/d/e/1FAIpQLSf_VezMf-V20hMDYTNEM0LEkuztIg-ZIsSI9Zy9xLAwGYzxGA/viewform?usp=sf_link 35 | 36 | ![](form.png) 37 | 38 | 可參考範例:[https://lidemy.github.io/mentor-program-pychiang/homeworks/week4/hw2/](https://lidemy.github.io/mentor-program-pychiang/homeworks/week4/hw2/)(第一期學生 pychiang 的作品) 39 | 40 | 背景隨便用一個顏色就好了,重點是實做出表單內容以及驗證。UI 可以不用完全一樣,只要功能有做出來就好,UI 只是讓你參考的。 41 | 42 | ### 作業規範 43 | 44 | 1. 文字輸入框可以選擇必填或是非必填 45 | 2. 送出表單時,必填的地方如果空白,要能夠把背景變紅色並且提示使用者 46 | 3. 成功提交之後,把表單的資料輸出在 console,並且用`alert`跳出提示即可 47 | 48 | ### 作業提示 49 | 50 | 1. 先切好版,然後驗證一個一個來做,不要一次想把所有驗證做完 51 | 52 | ### 進階挑戰題 53 | 54 | 1. 切的跟 Google 表單幾乎一模一樣 55 | 2. 支援 RWD 56 | 57 | ## hw3:計算機 58 | 59 | ![](calculator.png) 60 | 61 | 可參考範例:[https://lidemy.github.io/mentor-program-kristxeng/homeworks/week4/hw1/](https://lidemy.github.io/mentor-program-kristxeng/homeworks/week4/hw1/)(第一期學生 Kris 的作品) 62 | 63 | 請用你在之前學會的網頁技術(HTML, CSS, JavaScript)打造出一個簡單的計算機,功能如下: 64 | 65 | 1. 要有 0 到 9 66 | 2. 要有加減乘除 67 | 3. 要能夠清空 68 | 69 | 計算機這一題其實要難可以到很難,這個作業的目的只是想讓你熟悉基本操作而已,只要以下的範例能夠通過就好: 70 | 71 | ### 測試1 72 | 73 | 1. 按下 123 74 | 2. 按下 + 75 | 2. 按下 456 76 | 3. 按下 = 77 | 4. 出現 579 78 | 79 | ### 測試2 80 | 81 | 1. 按下 20 82 | 2. 按下 - 83 | 2. 按下 25 84 | 3. 按下 = 85 | 4. 出現 -5 86 | 87 | ### 作業提示 88 | 89 | 1. 不要想得太難,只要加減能夠成功就行了 90 | 2. 先想怎麼通過上面附的兩個測試就好 91 | 92 | ### 進階挑戰題 93 | 94 | 1. 實作出具有完整功能的計算機,加減乘除都沒問題 95 | 2. 重構程式碼,用迴圈或是 delegate 的方式處理 click event 96 | 97 | ## hw4:簡答題 98 | 99 | 1. 什麼是 DOM? 100 | 2. 事件傳遞機制的順序是什麼;什麼是冒泡,什麼又是捕獲? 101 | 3. 什麼是 event delegation,為什麼我們需要它? 102 | 4. `event.preventDefault()` 跟 `event.stopPropagation()` 差在哪裡,可以舉個範例嗎? 103 | 104 | 請將答案寫在 [hw4.md](hw4.md)。 105 | 106 | ## 挑戰題 107 | 108 | 參考 Bootstrap,實作出一個 Accordion(手風琴)元件,可參考:https://getbootstrap.com/docs/4.3/components/collapse/#accordion-example 109 | 110 | 備註:只能使用 HTML、CSS 與 JavaScript,禁止使用任何套件 111 | 112 | ![](acco.gif) 113 | 114 | ## 超級挑戰題 115 | 116 | 參考 Bootstrap,實作出一個 Carousel 元件,可參考:https://getbootstrap.com/docs/4.3/components/carousel/#with-captions 117 | 118 | 備註:只能使用 HTML、CSS 與 JavaScript,禁止使用任何套件 119 | 120 | ![](carousel.gif) 121 | 122 | 123 | -------------------------------------------------------------------------------- /homeworks/week7/acco.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/acco.gif -------------------------------------------------------------------------------- /homeworks/week7/calculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/calculator.png -------------------------------------------------------------------------------- /homeworks/week7/carousel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/carousel.gif -------------------------------------------------------------------------------- /homeworks/week7/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/form.png -------------------------------------------------------------------------------- /homeworks/week7/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week7/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week7/hw3/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/hw3/index.html -------------------------------------------------------------------------------- /homeworks/week7/hw4.md: -------------------------------------------------------------------------------- 1 | ## 什麼是 DOM? 2 | 3 | 4 | ## 事件傳遞機制的順序是什麼;什麼是冒泡,什麼又是捕獲? 5 | 6 | 7 | ## 什麼是 event delegation,為什麼我們需要它? 8 | 9 | 10 | ## event.preventDefault() 跟 event.stopPropagation() 差在哪裡,可以舉個範例嗎? 11 | -------------------------------------------------------------------------------- /homeworks/week7/reaction.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/reaction.gif -------------------------------------------------------------------------------- /homeworks/week7/twitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week7/twitch.png -------------------------------------------------------------------------------- /homeworks/week8/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ## hw1:抽獎程式 4 | 5 | 住你家樓上的王媽媽最近剛開了火鍋店,想要讓每個來消費的客人都能夠抽獎,可是他想要創新一點,不想要用實體的籤,想要靠著程式來作抽獎,而且希望每個獎項都有固定的機率。 6 | 7 | 她已經委託一間公司寫好了抽獎的 API,而你要幫忙的地方是實作前端介面並且跟 API 串接,這樣子就是一個完整的抽獎程式了!就衝著王媽媽答應你做完後可以獲得一客免費的 A5 和牛火鍋這點,說什麼也要把這個網站做好! 8 | 9 | 這是 API 的網址:https://dvwhnbka7d.execute-api.us-east-1.amazonaws.com/default/lottery 10 | 11 | 用 GET 即可,API 會回傳一個 JSON 格式的物件,內容為: 12 | 13 | ``` 14 | { 15 | prize: "獎項名稱" 16 | } 17 | ``` 18 | 19 | API 會按照機率回傳不同的獎項名稱,請你針對不同的獎項名稱做處理。 20 | 21 | 獎項名稱一共有四種:FIRST、SECOND、THIRD 以及 NONE。 22 | 23 | 1. FIRST,頭獎,在網頁上顯示字樣:「恭喜你中頭獎了!日本東京來回雙人遊!」,並且把背景改成天空色,網頁上放一張飛機的圖片。 24 | 2. SECOND,二獎,在網頁上顯示字樣:「二獎!90 吋電視一台!」,並且在網頁上放一張電視的圖片。 25 | 3. THIRD,三獎,在網頁上顯示字樣:「恭喜你抽中三獎:知名 YouTuber 簽名握手會入場券一張,bang!」,並且在網頁上放 YouTube 的 Logo。 26 | 4. NONE,銘謝惠顧,在網頁上顯示字樣:「銘謝惠顧」,並起把整個網頁變成黑底白字。 27 | 28 | 有一點要特別注意,API 偶爾可能會不太穩定,會回傳錯誤。如果發生任何預期之外的情形(回傳的獎項不是以上四種,或是 Server 直接回傳錯誤),請跳出提示視窗(alert):「系統不穩定,請再試一次」。 29 | 30 | ### 進階挑戰題 31 | 32 | 請問這四種獎項的機率為何? 33 | 34 | ## hw2:留言板 35 | 36 | 上次你幫王媽媽寫的抽獎程式大受好評,成功吸引了許多消費人潮,而 A5 和牛火鍋的滋味你也念念不忘,希望有機會能夠再吃一次。 37 | 38 | 剛好,王媽媽又有了新的需求,他希望可以做一個留言板,讓客人們都可以上去留言,他就可以從這些留言中得知店裡哪邊做得好,哪邊做不好,並且加以改善。同樣地,他也去找了外包公司把 API 的部分搞定了,所以你只要負責前端的部分即可。 39 | 40 | 老樣子,這次做完一樣會有 A5 和牛火鍋可以吃。 41 | 42 | 底下是一個留言板的 API,主要的功能有兩個:撈取留言與新增留言,現在請你做一個頁面,可以讓他們新增留言以及看到最新的 20 則留言。 43 | 44 | Base URL:https://lidemy-book-store.herokuapp.com/ 45 | 46 | | 說明 | Method | path | 參數 | 範例 | 47 | |--------|--------|------------|----------------------|----------------| 48 | | 獲取所有留言 | GET | /posts | _limit:限制回傳資料數量, _sort:要排序的欄位, _order:順序,可填 asc 或 desc | /posts?_limit=20 | 49 | | 新增留言 | POST | /posts | content: 內容 | 無 | 50 | 51 | 52 | ### 進階挑戰題 53 | 54 | 實作分頁功能,讓他們可以點不同頁數來看不同的留言。 55 | 56 | ## hw3:再戰 Twitch API 57 | 58 | 還記得之前你幫果凍做的小程式嗎?可以看到 Twitch 上面熱門的遊戲,讓他從中挑選一個並且直播。這個成效很不錯,但是身為一個實況主,他又面臨了新的挑戰。 59 | 60 | 最近又太多太多實況主了,每個都有不同的特色,除了精進自己的實力以外,也要觀察一下競爭對手在做什麼。於是,他想拜託你寫一個網頁,可以顯示出某個特定遊戲的一些熱門實況,好讓他能夠方便觀察競爭對手。 61 | 62 | 請串接 [Twitch API v5](https://dev.twitch.tv/docs/v5/),顯示出 League of Legends 目前正在直播的前 20 個實況。 63 | 64 | ![](twitch.png) 65 | 66 | ### 作業提示 67 | 68 | 1. [Twitch API](https://dev.twitch.tv/docs/v5/) 裡面有一個 API 是可以拿到現在正在直播的某個遊戲底下的資料,API 的描述是「Gets a list of live streams.」,看到這行就代表你找對 API 了。 69 | 2. API 要帶的參數有一個 `game` 的欄位,請帶`League%20of%20Legends` 70 | 3. 請顯示 20 個實況,不多不少,要剛好 20 個 71 | 72 | 附註:Twitch API 有兩個版本,v5 是舊版,但這個作業建議用 v5 73 | 74 | 75 | ## 進階挑戰題 76 | 77 | 這個頁面最底下加上一個按鈕:「載入更多」,點了之後會繼續載入之後的 20 個實況。按鈕不會消失,除非已經沒有更多的實況可以載入了。 78 | 79 | ## hw4:簡答題 80 | 81 | 1. 什麼是 Ajax? 82 | 2. 用 Ajax 與我們用表單送出資料的差別在哪? 83 | 3. JSONP 是什麼? 84 | 4. 要如何存取跨網域的 API? 85 | 5. 為什麼我們在第四週時沒碰到跨網域的問題,這週卻碰到了? 86 | 87 | 請將答案寫在 [hw4.md](hw4.md)。 88 | 89 | ### 挑戰題 90 | 91 | 做出一個像這樣的網頁:https://cwenwen.github.io/APIsPractice/Twitch_API/ 92 | 93 | ![](twitch_amelie.png) 94 | 95 | 可以切換不同的遊戲,顯示不同遊戲的熱門實況。 96 | 97 | ### 超級挑戰題 98 | 99 | 同上,但新增兩個功能: 100 | 101 | 1. 無限滾動(Infinite scroll),當你頁面往下捲到底的時候,會自動載入新的實況 102 | 2. 導覽列新增一個搜尋欄,可以搜尋你想顯示的遊戲,搜尋的時候必須要有自動完成的功能,例如說我打 Lea 就會出現 League of Legends,按搜尋之後可以看到這個遊戲的熱門實況 103 | 104 | -------------------------------------------------------------------------------- /homeworks/week8/hw1/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week8/hw1/index.html -------------------------------------------------------------------------------- /homeworks/week8/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week8/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week8/hw3/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week8/hw3/index.html -------------------------------------------------------------------------------- /homeworks/week8/hw4.md: -------------------------------------------------------------------------------- 1 | ## 什麼是 Ajax? 2 | 3 | 4 | ## 用 Ajax 與我們用表單送出資料的差別在哪? 5 | 6 | 7 | ## JSONP 是什麼? 8 | 9 | 10 | ## 要如何存取跨網域的 API? 11 | 12 | 13 | ## 為什麼我們在第四週時沒碰到跨網域的問題,這週卻碰到了? 14 | 15 | -------------------------------------------------------------------------------- /homeworks/week8/twitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week8/twitch.png -------------------------------------------------------------------------------- /homeworks/week8/twitch_amelie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week8/twitch_amelie.png -------------------------------------------------------------------------------- /homeworks/week9/README.md: -------------------------------------------------------------------------------- 1 | # 作業 2 | 3 | ### 注意 4 | 5 | hw2 與 hw3 寫在一起就好,不用分開。然後記得把你連線到資料庫的檔案(conn.php),加入`.gitignore`,否則這檔案會被放到 GitHub 上,大家就知道資料庫的帳號密碼了。 6 | 7 | 另外,請你在留言板的最上方加註一行警語:「本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼」,加警語的目的是因為這週要做的網站極度不安全,很有可能被駭客拿到整個資料庫的資料,因此請切記在這網頁上不要輸入任何敏感資訊。 8 | 9 | 10 | ## hw1:設計留言板 Database 結構 11 | 12 | 在開始動手做之前,需要先花點時間想好怎麼樣規劃你的資料庫結構,確定沒問題以後再下去動手實作。 13 | 14 | 我們接下來要做的作業是:留言板。 15 | 16 | 可以參考以下需求來想要怎麼設計資料庫結構: 17 | 18 | 1. 身為使用者,在新增留言時應該可以輸入暱稱跟留言內容 19 | 2. 身為系統,應該顯示出留言者的暱稱跟留言內容以及留言時間 20 | 3. 身為系統,顯示留言時應該按照時間排序,最後留的顯示在最上面 21 | 4. 身為系統,應該只顯示最新的前五十筆留言 22 | 23 | 請把答案依照格式寫在:[hw1.md](hw1.md) 24 | 25 | ## hw2:留言板 26 | 27 | 請實作出一個簡易的留言版頁面,需要以下元素: 28 | 29 | 1. 有一個留言的區塊可以新增留言 30 | 2. 能夠顯示留言 31 | 32 | 可參考以下示意圖(擷取自[iT 邦幫忙](https://ithelp.ithome.com.tw/articles/10185630)) 33 | 34 | ![](board.png) 35 | ![](board2.png) 36 | 37 | 或是這個: 38 | 39 | ![](board3.png) 40 | 41 | 不用做得像上面那麼精緻,只要基本功能有達成就好。例如說留言的區塊只要能輸入純文字就夠了,留言區左邊的那個按讚數也可以不用實作,子留言也不必實作。 42 | 43 | 可以參考下面附的需求來實作: 44 | 45 | 1. 身為使用者,在新增留言時應該可以輸入暱稱跟留言內容 46 | 2. 身為系統,應該顯示出留言者的暱稱跟留言內容以及留言時間 47 | 3. 身為系統,顯示留言時應該按照時間排序,最後留的顯示在最上面 48 | 4. 身為系統,應該只顯示最新的前五十筆留言 49 | 50 | ## hw3:會員系統 51 | 52 | 上面的留言板系統完成之後,要來多加一個功能,那就是會員系統。現在的系統是開放每個訪客可以自己取暱稱,但有了會員系統以後,必須要是會員才能夠留言。 53 | 54 | 這個時候問題就來了,應該要怎麼實作會員系統呢? 55 | 56 | 最大的問題是: 57 | 58 | > 每個 Request 之間都是獨立的,在會員登入之後,你要怎麼知道上一個 Request 跟現在的是同一個人呢? 59 | 60 | 意思就是,你要怎麼知道使用者已經登入了?你要怎麼記錄這個狀態? 61 | 62 | 在瀏覽器這邊,我們有個東西可以使用,叫做 Cookie,其實它就是可以讓瀏覽器儲存資料的地方。而且呢,Server 端可以主動把資料存到 Cookie 去。 63 | 64 | 在 PHP 裡面,你可以使用`setcookie`函式達成這件事。 65 | 66 | ``` php 67 | // 設定一個 24 小時之後會過期的 Cookie 68 | setcookie("member_id", "001", time()+3600*24); 69 | ``` 70 | 71 | 如此一來,在會員登入之後,我們就能夠利用 setcookie,把會員的資料存到使用者瀏覽器的 cookie 裡面。而瀏覽器在送出 request 的時候,也會把 cookie 的內容一起帶上來,你可以用 `$_COOKIE[$cookie_name]` 來取得。 72 | 73 | ``` php 74 | if(!isset($_COOKIE["member_id"])) { 75 | echo "not login"; 76 | } else { 77 | echo "member id: " . $_COOKIE["member_id"]; 78 | } 79 | ``` 80 | 81 | 有了 Cookie 之後,我們就能夠知道使用者是不是登入狀態了。那如果要登出的話呢?也很簡單,只要把 cookie 的內容清掉就好了(換句話說,就是設定一個內容為空的 Cookie),這樣子使用者下次再拜訪頁面時,就會跳出需要登入的提示了。 82 | 83 | 會員系統的資料庫設計可參考以下的結構: 84 | 85 | Table 名稱:users 86 | 87 | | 欄位名稱 | 欄位型態 | 說明 | 88 | |----------|----------|------| 89 | | id | integer | 使用者 id | 90 | | username | VARCHAR(16) | 帳號 | 91 | | password | VARCHAR(16) | 密碼 | 92 | | nickname | VARCHAR(64) | 暱稱 | 93 | 94 | 接著,你需要實作的就是以下幾個頁面: 95 | 96 | 1. 註冊頁面 97 | 2. 登入頁面 98 | 3. 登出頁面 99 | 100 | 以及把原本的留言板改成需要登入才能夠留言,並且自動帶入使用者的暱稱。 101 | 102 | ## hw4:簡答題 103 | 104 | 1. 資料庫欄位型態 VARCHAR 跟 TEXT 的差別是什麼 105 | 2. Cookie 是什麼?在 HTTP 這一層要怎麼設定 Cookie,瀏覽器又會以什麼形式帶去 Server? 106 | 3. 我們本週實作的會員系統,你能夠想到什麼潛在的問題嗎? 107 | 108 | 請將答案寫在 [hw4.md](hw4.md)。 109 | 110 | ## 挑戰題 111 | 112 | 請實作出 BE101 課程中 Job Board 職缺報報與 Blog 部落格裡的進階練習。 113 | 114 | ## 超級挑戰題 115 | 116 | 請實作出 BE101 課程中 Job Board 職缺報報與 Blog 部落格裡的魔王練習。 117 | -------------------------------------------------------------------------------- /homeworks/week9/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week9/board.png -------------------------------------------------------------------------------- /homeworks/week9/board2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week9/board2.png -------------------------------------------------------------------------------- /homeworks/week9/board3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week9/board3.png -------------------------------------------------------------------------------- /homeworks/week9/hw1.md: -------------------------------------------------------------------------------- 1 | 資料庫名稱:comments 2 | 3 | | 欄位名稱 | 欄位型態 | 說明 | 4 | |----------|----------|------| 5 | | id | integer | 留言 id | 6 | -------------------------------------------------------------------------------- /homeworks/week9/hw2/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lidemy/mentor-program-3rd/3f956f0310b8835f5bea977b6cf7f599a25bd823/homeworks/week9/hw2/index.html -------------------------------------------------------------------------------- /homeworks/week9/hw4.md: -------------------------------------------------------------------------------- 1 | ## 資料庫欄位型態 VARCHAR 跟 TEXT 的差別是什麼 2 | 3 | 4 | 5 | ## Cookie 是什麼?在 HTTP 這一層要怎麼設定 Cookie,瀏覽器又會以什麼形式帶去 Server? 6 | 7 | 8 | 9 | 10 | ## 我們本週實作的會員系統,你能夠想到什麼潛在的問題嗎? 11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mentor-program-3rd", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "lint": "eslint ./homeworks/**/*.js", 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "husky": { 10 | "hooks": { 11 | "pre-commit": "lint-staged" 12 | } 13 | }, 14 | "lint-staged": { 15 | "*.js": [ 16 | "eslint", 17 | "git add" 18 | ] 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/aszx87410/program-3rd.git" 23 | }, 24 | "author": "", 25 | "license": "ISC", 26 | "bugs": { 27 | "url": "https://github.com/aszx87410/program-3rd/issues" 28 | }, 29 | "homepage": "https://github.com/aszx87410/program-3rd#readme", 30 | "dependencies": { 31 | "eslint": "^5.15.1" 32 | }, 33 | "devDependencies": { 34 | "eslint": "^5.15.1", 35 | "eslint-config-airbnb": "^17.1.0", 36 | "eslint-plugin-import": "^2.16.0", 37 | "eslint-plugin-jsx-a11y": "^6.2.1", 38 | "eslint-plugin-react": "^7.12.4", 39 | "husky": "^1.3.1", 40 | "lint-staged": "^8.1.5" 41 | } 42 | } 43 | --------------------------------------------------------------------------------