[week15]你真的懂了嗎?-自我檢測


Posted by 生菜 on 2020-10-17

此份自我檢測目標:

給未來求職前的自己作為回頭複習ㄉ筆記
or(如果我寫到一半發懶)
直接想像自己在面試時被問到,我會怎麼回~

WEEK11

P1 你知道什麼是雜湊(Hash function)、你知道什麼是加密(Encryption)、你知道雜湊與加密的差別

如果使用者密碼直接被存入資料庫中,只要資料庫直接被偷看(像是在圖書館使用時上廁所忘了換頁),或用其他攻擊方式直接叫出密碼,使用者的資訊安全就會受到威脅,因此存在資料庫中密碼欄位的密碼最好不是原始的樣子。

雜湊和加密都是把原始的明碼輸入轉換成密碼,都是只要輸入字串和加密方法一樣,就可以得到一樣的密碼。

差別在加密是一對一,因此若知道加密規則和輸出結果,就可以回推出原本的明碼,是一對一的關係;但雜湊 (hash) 是多對一的關係,也就是雖然每次輸入都會得到同樣的輸出,但因為不止這組輸入會得到一樣的輸出,因此就算知道加密規則和結果,也無法回推原本是哪個字串,因此安全性又更高。

PHP 中雜湊的語法如下:

```
password_hash(<string>, <編碼方式>)
//可轉換成 hash ,建議存到預留 60 字元以上的欄位
password_verifty(<明文>, <hash>) 
//對照兩者是否相同。
```

P1 你知道什麼是 SQL Injection 以及如何防範

SQL Injection 是在輸入的字串中夾帶 SQL 的語法,又因為字串拼接設計不良,夾帶進去的內容被當成 SQL 語法的一部份執行而導致的資安漏洞。以下舉個例子:

程式碼如下:

```
$sql = sprintf("INSERT INTO comments(username, content) VALUES('%s', '%s')", $_POST['username'], $_POST['content']);
```

只要我在 content 的欄位輸入 '), ('not_me', (select password from users));# ,就會變成這樣:

    $sql = INSERT INTO comments(username, content) VALUES('me', ''), ('not_me', (select password from users));#')

因為 # 後面會變成附註,因此變成新增兩條留言,第二條的 username 和 content 附註,其中內容甚至可以叫出所有用戶的資料。超危險。

解決方法:使用 SQL 內建機制拼接

$sql = 
// 這邊預留空間的方法是用問號 '?'
$stmt = $conn->prepare($sql) ;
// 先準備好
$stmt->bind_param('<拼接什麼>', $<變數1>, $<變數2>) ;
// 如果要拼接兩個字串,就用 'ss' ,整數的話就是 'i'
$result = $stmt->execute()
// 執行 query
// 接著用原本的判斷式檢測是否執行成功

$result = $stmt->get_result()
//這樣才算拿到結果

P1 你知道什麼是 XSS 以及如何防範

XSS 全名 Cross-Site Scripting ,也就是跨網站執行 JavaScript。例如顯示留言的地方的 HTML 如下:

<div class='content'><?php echo $row['content']?><div>

這時只要使用者輸入 html 或 JavaScript 語法,例如 <script>alert('hacked')</script> ,就會直接被解讀為程式碼的一部份並被執行。

防範方法:字元跳脫

函式 htmlspecialchars() 可將 html 的特殊符號轉換成純文字。

值得注意的是,因為資料庫儲存原始資料就好,因此建議在輸出處使用。另外,因為不知道攻擊會從哪裡來,因此建議所有輸出都使用字元跳脫。

P1 你知道為什麼儘管前端做了驗證,後端還是要再做一次驗證

因為前端的驗證只針對瀏覽器畫面上的驗證,但除此之外還有許多漏洞,例如不透過瀏覽器發 request 給後端即可繞過。通常簡單如「是否有東西漏填」這種驗證會給前端,而和資安相關的例如身分驗證則由後端負責。

P2 你知道什麼是 CSRF 以及如何防範

參考資料:
讓我們來談談 CSRF
[week 11] 資訊安全 - 雜湊與加密 & 常見攻擊:SQL Injection、XSS

CSRF 的全名是 是 Cross Site Request Forgery(跨站請求偽造)。也被稱為 one-click attack 或 session riding。簡單來說就是「在不同 domain 下,偽造使用者本人發出的 request」。

平時登入網站後會得到一組 SESSION ,之後就算離開該網站,瀏覽器還是會幫你在 COOKIE 中保留 SESSION 一段時間。此時如果有個釣魚網站騙你在不知情的情況下,對該網站送出 Request (例如放在按鈕或圖片中),此時因為瀏覽器還留著你的 SESSION ,該網站以為是合法請求並接受,這樣一來釣魚網站就可以用你的身分在該網站進行操作。

不同層面的防範辦法

對使用者端來說,最好懂的就是隨時清空 SESSION,不過這就代表每次都要重新登入,很麻煩。

Server 端可以進行雙重驗證,像是輸入驗證碼就很直接,但每個動作都要輸入一次驗證碼有點麻煩,因此最好的方法是多加一層雙重認證。可以用表單中夾帶 CSRF token ,資料確認時也要保證其有被帶上才執行,產生和儲存都由 Server 端負責,但如果攻擊者先發出 request 就可破解;第二種方法是 Double Submit Cookie ,利用「cookie 只會從相同 domain 帶上來」的特性,把資料存在使用端,但只要攻擊者掌握任何 subdomain 就可破解;最後一種是由 Client 產生 token ,同時放到表單和 cookie 中。

瀏覽器方面, Chrome 也有提供 SameSite cookie 幫 cookie 加上一層驗證。

WEEK12

P1 你知道什麼是 SPA

Single Page Application 簡稱 SPA ,單介面應用程式,顧名思義就是所有動作都在一個頁面上完成,不會重新導向 index.html 以外的地方。其原理是 JavaScript 用 Ajax 動態從 Server 端拿資料,再即時 render 到 client 端上。

優點:

  1. 使用者體驗較佳。每次動態更新資料只會更新部分頁面,而不是導向完全不同的頁面。
  2. 前後端分工較明確。後端負責提供 API 給前端 render。
  3. 就算 JS 掛掉, HTML 檔案還是會顯示基本的畫面而非直接掛掉。

缺點

  1. 一個頁面要載入超多 .js 檔案,會跑比較慢。
  2. SEO 差。因為真正的內容要等 JS 渲染完,比較笨的爬蟲只看到 HTML 的話就是個空殼 → 可靠 SSR 解決。
  3. 前端變的超級複雜,還會有回傳順序的問題。要是沒寫好可能會出現「明明都點到第三頁了,卻顯示第一頁的畫面」這種狀況。

P1 你知道怎麼樣用 PHP 自己寫出 API

PHP 基礎語法:

// 建立一個空陣列
$json = array();
// 在陣列中增加一個新的物件
$array_push($json, array(
    "id" => 13         
));
// 轉換成 json 格式
$response = json_encode($json); 
// 印出來看看
echo $respons;
// 結果 [{"id": 13}]

之後前端只要讀取 PHP echo 的 JSON 格式結果就好。

P1 你知道如何在前端與自己開的 API 串接

串接 API 的方法有很多種,以下示範用 jQuery 實作 Ajax 的方法:

 $.ajax({
    method: 'GET',
    url: 'https://'
}).done(function(data) {
    console.log(data)
}).fail(function(err)) {
    console.log(err)
})

或是

$.ajax({
    method: 'GET',
    url: 'https://',
    success: (data) => function,
    error: (err) => functuon
})

P1 你知道在 server 與在 client render 的差別

server

  • PHP拿出資料 → render 到 HTML 上 → 回傳 HTML 檔案給瀏覽器。
  • 以上流程每進行一次就會刷新一次頁面。

client render

  • PHP 拿出資料 → 變成特定格式(JSON) → 傳給 JavaScript → JavaScript render 到沒有資料的 HTML 上。
  • 以上流程並不會更換頁面, PHP 只負責回傳 API 給前端,再由前端動態 render 到頁面上。
  • 優缺點可參照上面 SPA 的條目。

也來借用 minw 助教提供的圖解:

P1 你知道 jQuery 是做什麼的

jQuery 是 JavaScript 的 library ,將常用的函式包在一起。早期瀏覽器和寫法都未被統一, jQuery 可以跨瀏覽器的特性是很大的優勢,也提供了更為簡潔的語法。

P1 你知道 jQuery 與 vanilla js 的差別

vanilla js 就是原生 JavaScript 。而 jQuery 則是以此為基礎建立的 library ,使用前要先引入檔案才能使用。前端發展至今大專案已經有更好維護的框架了,不過較小的專案使用 jQuery 自由度反而較高。

P1 你知道什麼是 Bootstrap、P2 你知道 Bootstrap 原理及如何應用

Bootstrap 是一個由 HTML、CSS 和 JavaScript 寫成的前端框架,核心的設計目標是達成RWD響應式與行動優先,也就是讓你的網站排版可以自動適應螢幕大小。

使用 Bootstrap 前要先引入檔案,其中設定好各種 CSS 樣式和 JavaStript 樣式,想使用時只要更改 HTML 中的 class 即可。

雖然 Bootstrap 提供各種 UI 對不善設計的工程師是一大福音,不過也因此出現了大量相似的網頁 XD

WEEK13

P1 你知道 webpack 的目的以及原理

Webpack 是一種 module bundler ,也就是可以將各種資源打包在一起,讓你可以在瀏覽器使用它。

之前使用 node.js 時,如果要將檔案外的模組(例如另一個檔案寫好一個功能後輸出)引入,可以使用 require。但這個語法和瀏覽器不相容,相對的瀏覽器要使用 <script src='目標檔案'> 引入作為全域變數,但若一次引入不只一個檔案,可能會發生變數名稱衝突,此時就必須使用 jQuery 提供的 .conflic() 排除。

既然沒有支援就自己寫ㄅ,於是就出現各種非官方的模組化規範,直到最近出現 ES6 規範。不過 ES6 的規範支援度還是不好,例如必須開 Server 、 必須在引入時標註 type="module"; 而且在想要引入其他人寫的套件時,必須將整份 node_modules 傳上去,或是在 import 輸入完整路徑,十分不好維護。

使用 Webpack 可以將所有檔案包成一個 main.js ,這樣瀏覽器只要引入就好了。更甚者它將模組的概念向外延伸至各種資源,像是 CSS 或圖片,再經過 loader 將資源打包成 .js 檔給瀏覽器使用。

P1 你熟悉如何使用 webpack 進行模組化開發

不太熟悉(喂)

以下簡單列一下使用自己的模組的基本流程好ㄌ:

  1. 在專案資料夾內安裝 webpack
     npm init -y // 初始化 npm
     npm install webpack webpack-cli --save-dev // 安裝
    
  2. 設定 webpack.config.js ,最基本設定如下:

     const path = require('path');
    
    module.exports = {
      mode: 'production',  // 預設是production(壓縮代碼), development 指定為開發環境(未壓縮代碼)
      entry: './src/index.js', // 從哪裡引入模組
      output: {
        filename: 'main.js', // 輸出之後放到哪裡
        path: path.resolve(__dirname, 'dist'),
      },
    };
    
    1. 設定 package.json
      "scripts": {
       "build": "webpack", // 之後輸入 npm run build 時就會跑 webpack ㄌ
       "test": "echo \"Error: no test specified\" && exit 1"
      },
      
    2. 在檔案使用 requireexport 進行模組的輸入和輸出
    3. npm run build 跑起來!

另外在使用外部模組和 Loader 時,也是遵循安裝 → 更改設定檔和指令的方法。

P1 你知道如何使用 Promise、P2 你知道如何使用 fetch

資料來源:MDN - fetchMDN - Promise

在 JavaScript 上想發非同步的 request 時,除了使用 XMLHttpRequest 以外,也可以使用 fetch 讓程式更簡潔。

最基本的語法是:

fetch('url')

之後如果要加 header 或其他設定可以用物件形式放在第二個參數中。另外,如果要 POST 的話,body 中的 content type 必須符合才行。

值得注意的是,因為 fecth 的回傳值不會 reject HTTP 的 error status ,因此之後還要額外偵測 status 才不會出現錯誤。另外, fetch 雖然可以接收跨站的 cookies ,卻不會主動傳送 cookies 。

fetch 出來的結果會以 Promise 形式出現,必須用 .then(cb) 才能取得其中內容。

Promise 是一個表示非同步運算的最終完成或失敗的物件。因此自己建立一個 Promise 必須輸入兩個函數:成功和失敗的值,而且通常只會有一個被觸發。以下是示意:

function init(resolve, reject) {
    resolve(3);
    reject(5);
}

const myPromise = new Promise(init)

myPromise.then((data) => {
    console.log(data) // 如果成功就跑出 3
}).catch((err) => {
    console.log(err) // 有錯誤的話就跑出 5
})

P2 你知道 gulp 的目的以及原理

glup 是一套 task manager ,將任務集中管理並設定執行流程。其中 task 的類型可以有很多種,也可以自訂功能。

P2 你知道 CSS Sprites 與 Data URI 的優缺點

參考資料:使用 DATA URI 將圖片以 Base64 編碼並內崁至網頁中,加速載入速度

CSS Sprites 是為了避免每次顯示一張圖就要發一次 HTTP request ,乾脆將所有小圖放在一張大圖上一次拿進來。顯示個別小圖的原理是先顯示大圖並設定成小圖的大小、設定成不重複,再位移到指定位置。這麼做的好處是全部只要載入一張圖,降低網路載入時間;但缺點是拼圖再選取的調整比較麻煩、不易維護,也不方便 SEO 讀取。

Data URI 是一種檔案格式,其資料全部都是經過 base64 編碼之後,以文字的方式來儲存的。優點是可以減少 HTTP 請求的數量,直接寫進 HTML 或 CSS 中,不需要透過外部的檔案儲存;不過維護時若要修改就要重新編碼,無法快取且易讀性很差,對 SEO 同樣不友善。

P2 你知道什麼是 uglify 與 minify

參考資料:wiki - 極簡化

minify 是在不影響功能的情況下,移除所有非功能性必要之原始碼字元,例如換行、空白、變數和函式名稱縮短之類,在不會影響運作的前提下將檔案縮小。

uglify 則是除了壓縮外,還會混淆程式碼,讓程式變得難以被人閱讀,可作為隱藏商業邏輯的手段。

P3 你熟悉如何使用 gulp 建構自動化工作流程

不知道(等等),以下紀錄跑 SASS 的方法,列一下在設定檔 gulpfile.js 要做的事:

 const { src, dest } = require('gulp');
const sass = require('gulp-sass');
sass.compiler = require('node-sass');

function defaultTask() {
  return src('src/*.scss') // 輸入這個檔案
    .pipe(sass().on('error', sass.logError))
    .pipe(dest('./css')) // 輸出成這個檔案
}

exports.default = defaultTask;

P3 你知道 CSS 優化的一些小技巧

前端的 CSS 優化主要分成三個方向:

  1. 資源大小
    • minify:上面介紹過了。
    • gzip:用重新編碼的方式壓縮,此時瀏覽器已經看不懂了,必須經過解碼才能解讀。主要由後端負責。
  2. 載入方式
    • CSS Sprite :上面介紹過了,將小圖拼成大圖一起載入再分別呈現。
    • Critical CSS:全部都要載入太慢了,先載入重要的部分。最簡單的作法是直接放至 .html 檔中。
    • Cache:將傳過的東西放在 client 端。主要由後端負責。
  3. 執行方式

    • CSS 選擇器:需要另外做判斷的 CSS Selector 較複雜,從 SASS 轉到 CSS 可能會變複雜,要注意。
    • 屬性渲染:有些屬性可能會造成大規模重繪,例如用 top 定位不如用 transform ,因為前者定位是用 layout 會牽扯較多東西。

    ## WEEK14
    ### P1 你知道虛擬空間、虛擬主機以及實體主機的差別

    資料來源:60秒,搞懂虛擬主機、VPS、實體主機間的差異

Dedicated Hosting 實體主機就是我們現在用的電腦的主機,如果用實體主機當伺服器的話,除了要像這週部屬時要裝好作業系統和架網路線外,維護起來也有點麻煩,尤其是一旦關機別人就進不來了 XD

Shared hosting 虛擬主機則是在遠端有台實體主機,然後切出不同的空間作為不同伺服器,但還是共用 CPU 、記憶體和硬碟,想像成宿舍有各自房間和公共空間那樣。雖然比實體主機方便維護,也較便宜,但缺乏獨立性,而且要是你鄰居習慣很差(像是流量大爆),你的伺服器就很容易不穩或當機。

Virtual Private Server ,也就是常聽到的 VPS也是大家共用一台主機,透過虛擬化技術把一台電腦硬體切成很多帳號,讓每個VPS帳號可以安裝自己的作業系統、軟體、自己管理。因為硬體成本還是大家一起均分,所以跟實體主機比起來,VPS的費用頓時也變低了~

P1 你知道什麼是網域(Domain)

Domain 全名是 Domain Name ,算是 IP 位置的代稱,方便人們閱讀。

P1 你知道如何設定網域(A、CNAME)

資料來源:PM筆記:HTTPS、A紀錄與CNAME

A 是 Address 。可以想像成 IP 位置是詳細地址,而域名則是建築物名。買好域名後 A 就是定位這棟建築物在哪裡,之後使用者輸入域名就會自動導向 A 的位置。

CNAME 全名是 Canonical Name ,是關連名稱與地點,其會指到一個網域名稱。用建築物來比喻可能是不同的餐廳(CNAME)都在同的大樓(網域)內,那不管我和司機說想去其中哪家餐廳都會自動被載到該大樓了。

P1 你知道如何用 SSH 遠端連線到自己的主機、P1 你知道如何部署應用程式

知道……吧(眼神飄忽)

P2 你知道什麼是 No SQL

參考資料:了解NoSQL不可不知的5項觀念網站部署

無論是 SQL 或 NoSQL 指的都是拿來查詢資料庫的語言,而非資料庫系統。

關聯式資料庫 SQL

  • 儲存格式為 table (像是表格那樣)
  • table 之間互相關聯(例如 id 都一樣)
  • 結構穩定,但相對彈性低,也不支援 JOIN 。
  • Transaction 遵守 ACID 。
  • 常見如 MySQL、PostgreSQL、Microsoft SQL Server、SQLite

非關聯式資料庫 NoSQL

  • Not Only SQL
  • 用不同型態儲存,因此資料可放的型態也更多元(例如陣列)
  • 結構較不明顯,因此彈性更高,適合搜集數據。
  • 相對的,查詢資料也比較慢。
  • 使用 key-value 存資料,可以想像成 JSON。
  • 具有水平擴充能力,只要增加新的伺服器節點,就可以不斷擴充資料庫系統的容量。
  • Transaction 遵守 CAP 。
  • 常見如 mongodb。

    ### P2 你知道什麼是 Transaction 與 lock

    Transaction 指的是一組一次牽涉到多個 query 的操作,實際應用例如轉帳和購物。例如交易的時後小明給小美一百塊,這意味著小明少了一百,而小美多了一百這兩個操作。

此時只有兩個人還好,但使用者一多像是搶購票券之類的就會出問題,因為多筆資料同時進行更改時可能造成互相影響,比如說只有十張票卻有一百個人搶,發生 race condition ,最後發生超賣情形。

要避免這種狀況,只要在有人交易時先把門鎖上或放個標示說:「裡面有人ㄛ~」就可以避免了,這就是資料庫的 lock 。回到資料庫,為了維持 Transaction 的一致性(consistency)和隔離性(isolation),我們可以在資料被讀取或寫入時掛上一個 lock (像是公眾廁所燈有人使用時就會亮),其他 transaction 可以決定是否要等待或依然讀取。

P2 你知道資料庫的 ACID 是什麼

參考資料: 維基百科 - ACID

Transaction 是指由一系列資料庫操作組成的一個完整的邏輯過程,為了保證 Transaction 的正確性,要符合以下四個特性:

  • 原子性 atomicity:要嘛全部失敗,要嘛全部成功。可以想像匯款的時後只有成功(錢過去了)或失敗(錢沒過去),不會出現這邊錢減少但那邊卻沒增加的情形。如果過程中發生錯誤,則會退回開始前的狀態,就像什麼都沒發生一樣。
  • 一致性 consistency:維持資料的一致性。也就是錢的總數相同。
  • 隔離性 isolation:多筆交易不會互相影響,比如說不能同時改同一個值,詳細作法可看前兩題。
  • 持久性 durability:交易成功之後,寫入的資料不會不見,就算系統故障也不會消失。

    ### P3 你知道什麼是資料庫的 View 以及使用時機

    View 是一張虛擬 table ,只能讀取不能改寫,好處是方便檢視不同 table 的特定欄位,在開放資料庫給他人時也方便隱藏比較機密的欄位,不過缺點是不易維護。

CREATE VIEW view_name [(column_list)] AS
SELECT column_name(s)
FROM table_name
WHERE condition;

P3 你知道什麼是 Stored procedure 以及如何使用

SQL 的 function 有分兩種,一種是內建函式例如 SUM() ,另一種則是 Stored procedure ,其設定完後可以直接取代 query 。

DELIMITER //
CREATE PROCEDURE functionName()
  BEGIN 
    SQL query;
  END //
DELIMITER ;

DELIMITER 是設定換行符號,先設定成 // 才不會和 Stored procedure 中的 query 撞到。

之後要使用 Stored procedure 就用 CALL functionName() 就可~

P3 你知道資料庫的 Trigger 以及使用時機

資料來源:維基百科 - trigger)

Trigger 的用於記錄資料庫的變動,並用 table 將變動記錄下來。

delimiter //
CREATE TRIGGER 名稱
    BEFORE UPDATE FROM table名稱
    FOR EACH ROW
  BEGIN 
    要做什麼;
  END //
  delimiter;

跨題目資料來源

同學們的自我檢測:

Nicolacha
awu
Ruofan










Related Posts

N + 1 problem

N + 1 problem

Day 137

Day 137

網路爬蟲問題解析 --- CSS select 出現 list index out of range

網路爬蟲問題解析 --- CSS select 出現 list index out of range


Comments