《ASP.NET MVC 5 網站開發之美》 - 學習筆記

《ASP.NET MVC 5 網站開發之美》

========== ========== ==========
[作者] (臺) demo (臺) 小朱 (臺) 陳傳興 (臺) 王育民 (臺) 陳仕傑
[出版] 清華大學出版社
[版次] 2015年09月 第1版
[印次] 2017年03月 第2次 印刷
[定價] 128.00元
========== ========== ==========

【第01章】 

(P004) 

目前網頁前端技術非常多元化,開發者一定要選擇容易自定義與修改的框架作爲主要開發框架。

(P005) 

Model 可翻譯爲數據模型, “數據模型” 用於封裝與應用程序在商業邏輯上相關的數據,以及對其數據操作的處理方法。

Model 並不依賴 View 或 Controller ,也就是說 Model 不需要知道它會如何被顯示或如何被應用,只需要專注於做好數據訪問、定義、驗證的責任即可。

在 ASP.NET MVC 中推薦使用強類型的方式設計 Model 層,纔可以有效地利用內建的模型綁定 (Model Binding) 與模型驗證機制。

(P007) 

在項目初期設計的時候建議將用戶接口層和商業邏輯層明確地分離開,後續在開發上也會比較順手。

(P010) 

開發人員可以在同一項目中增加許多核心引用。

(P011) 

Single Page Application 模板只使用單一頁面來呈現各種各樣的內容,單一頁面的數據交換依賴 JavaScript (Client) 調用 Web API (Server) 獲取,所以當開發人員選擇使用 Single Page Application 模板時會發現默認同時勾選 MVC 與 Web API 。

(P012) 

T4 爲 “Text Template Transformation Toolkit” 的縮寫,是一種文字模板轉換的工具,利用 T4 可以很容易地生成程序代碼。

(P017) 

現在網絡交換數據的格式,從以往的 XML 已經漸漸轉換到更省流量的 JSON 。

(P022) 

NuGet 會將此項目用到的程序包記錄在 packages.config 內,因此程序包還原必須依賴此配置文件,此配置文件請務必加入版本管理。

(P037) 

MVC 的設置方式是後端會將指定的數據傳輸到前端,不管後端開發者是使用 ViewBag 、 ViewData 、 TempData 或是直接傳一個 Model 到前端,默認的 DefaultModelBinder 類都會自動將名稱相同的部分自動綁定。

【第02章】 

(P060) 

程序是由數據和算法組成的,在 MVC 應用程序中,算法由 Controller 提供,而數據當然就是由 Model 來提供。

(P061) 

既然 Model 是程序外部提供的數據,也就代表了 Model 並不限於特定技術 (例如 EF) 。

(P062) 

Model 不會主動與數據源溝通,而是利用一箇中介層,這個中介層規定了數據源要怎麼處理 Model ,包括數據源的訪問和 Model 間的數據轉換等,這個中介層稱爲 Repository (主數據資源庫) , Repositpry 負責 Model 和數據源間的協調合作。

(P065) 

泛型的表示法由類與類型參數 (type parameter) 所組成,以 List<T> 爲例, List 爲類名稱,而 <T> 則表示此類爲泛型類,其中的 T 即是類型參數。

泛型也可以用在屬性與方法上。

(P068) 

如果一個泛型類要使用兩個以上的類型參數時,可以針對各個不同的類型參數設置 where 的限制,以確保類型參數是必要的。

(P074) 

SQL 指令一定要用參數化查詢法,否則就會出現 SQL Injection 的漏洞。

(P082) 

參數化查詢是目前唯一可預防 SQL Injection 漏洞的方法。

【第03章】 

(P085) 

LINQ 真正的威力其實並不只是 SQL 指令的終結,而是它隱含對集合對象的強大訪問能力,以及爲了實現 LINQ 技術而在 .NET Framework 內所添加的各種擴展能力,這些能力纔是 LINQ 真正的價值所在。

(P089) 

LINQ 本身的基礎建設實現於 System.Linq 命名空間內,若沒有使用 using 引入這個命名空間的話,所有 LINQ 功能都無法使用。

(P091) 

對象初始化器 (object initializer) 允許在程序中通過聲明的方式直接給對象屬性進行數值的初始化,而不必刻意建立有參數的構造函數,可降低程序員維護多個構造函數的負擔。

(P092) 

對象初始化器可和有參數的構造函數並用。

對於數組或集合的賦值,刻意利用相似的語法來實現,不過在初始化器內所初始化的不是集合的屬性,而是集合內的元素。

(P093) 

匿名類型雖然好用,但它有幾個麻煩的限制 :

1. 匿名方法一般只會用在同一個函數內,如果要讓它被其他函數共享,則必須要動用到 Reflection ,或是利用 .NET 4.0 提供的動態類型 (dynamic types) 機制;

2. 匿名類型只能有屬性,不可以有方法、事件或字段等;

3. 兩個匿名類型對象的相等 (equal) ,必須要兩個對象的屬性值都相等才行;

4. 匿名類型的初始化只能利用對象初始化器來進行,其屬性在生成後會變成只讀;

基本上,只要是匿名類型就一定得使用 var 來聲明,若是現有的類型則要看當時情況而定,全都用 var 來替代也是有副作用的。

(P094) 

var 類型雖然好用,但也有如下限制 : 

1. 使用 var 類型時賦值語句的右邊不可以是 null ,否則編譯器無法推斷出其類型;

2. var 類型只能用於局部變量的聲明,不能用於全局變量、類層級的變量或是函數的返回值;

3. var 類型不可用在匿名委派或是方法羣組中;

編譯器在程序中看到 foreach 語句時,會將它轉換成對 IEnumerable<T>.GetEnumerator() 的調用。

(P095) 

微軟提供了一個指令 yield ,它可以讓程序員以只傳回每個元素的方式來自動生成 IEnumerabel<T> 對象。

(P096) 

Enumerable 內所包含的 LINQ 擴展方法,都返回了 IEnumerable<T> ,這代表可以使用直接串接的方式來調用多個 LINQ 函數,而不用爲每個函數調用都編寫一行程序,這個技術稱爲 Fluent Interface。

Fluent Interface 具有三項特性 :

1. 通過調用方法來定義對象內容;

2. 對象會自我引用 (self-referential) ,且新的對象內容會和最後一個對象內容等價;

3. 通過返回 void 內容 (就是 null 或不返回最後的對象內容) 或非 Fluent Interface 的對象結束;

(P097) 

事件 (event) 機制均以委派爲主,所以若要在類聲明一個事件,則必定要聲明一個委派。

委派的聲明類似於抽象方法的聲明,只是將 abstract 換成 delegate 而已,不需要實現,只要聲明參數原型即可。

委派可以保證目標對象的實現方法必定符合委派所聲明的參數規格,以及返回的數據值,所以適合在需要由目標對象實現的流程,或是需要通知 (notification) 或是 發行/訂閱 (publish/subscrible) 的應用中,亦可應用於觀察者模式 (Observer Pattern) 的實現。

(P098) 

到了 .NET Framework 3.5 時,微軟更將 delegate 指令拿掉,以 “=>” 指令來替代 delegate 。

Lambda 表達式分成三種,一種是表達式型 Lambda (Expression Lambdas) ,一種是語句型 Lambda (Statement Lambdas) ,另一種則是異步型 Lambda (Asynchronous Lambdas) 。

表達式型 Lambda 的語法很簡單 : (input parameter) => expression ;

輸入參數有或沒有都可以,若沒有可直接以 “()” 來替代,若只有一個,則可以省去小括號,但若有兩個以上參數,就必須保留小括號。

當表達式有多行時,則要選擇語句型 Lambda ,它的語法結構和表達式型 Lambda 相似,差別就在大括號 (input parameter) => { statements; } 。

(P099) 

若語句只有一行,那麼使用表達式型 Lambda 和語句型 Lambda 只有大括號的差別。

當 Lambda 表達式要用於異步操作時,可使用異步型 Lambda ,異步型 Lambda 語法基本上和表達式語句型 Lambda 相同,差異是在聲明 Lambda 時要加上 async 指令,若在 Lambda 表達式本體內用到了其他異步方法時,要在調用加上 await 指令。

async 和 await 指令適用於 .NET Framework 4.5 以上的版本。

(P100) 

微軟在 .NET Framework 裏面放入了數個委派類型,用來簡化聲明委派的工作,像是無事件參數的委派 EventHandler ;有事件參數的委派 EventHandler<TEventArgs> ;無返回值的 Action ;有參數的 Func<TResult> ;以及設置準則的 Predicate<T> 等 5 種。

Predicate<T> 是一個特殊的通用委派,它基本上和 Func<T, bool> 是等價的,專門用來處理元素是否符合條件。

(P103) 

除非是要重新組裝數據或是編寫 LINQ 語句選取數據,否則基本上用到 Select() 的機率並不高。

(P107) 

GroupBy() 本身具有延遲執行的特性,而 ToLookUp() 沒有。

(P111) 

如果要設置多重排序條件,請務必使用 OrderBy() 加上 ThenBy() 的組合。

(P113) 

在數據庫查詢時,爲了達到最佳的性能,在數據量大時要進行分頁處理 (paging) 是一件很重要的工作。

若是要在大集合內切出少量數據時,還需要有“美工刀”,這些方法的功能就是扮演着美工刀的角色 : Skip() 、 SkipWhile() 、 Take() 、 TakeWhile() 。

(P114) 

Skip() 用來在集合中跳躍,讓 LINQ 核心直接將遊標跳到指定的位置,而不用通過 “巡航” 來移動,在大型集合中可節省不少時間。

Take() 用來傳回集合中特定數量的元素,它會告知 LINQ 核心直接返回它所指定的元素數量,很適合使用於分頁的功能。

(P117) 

針對遠程數據源,使用 Any() 來判斷有無數據是較好的選擇。

若是針對本地的集合 (數組、列表或字典類型等) ,則 Any() 和 Count() 幾乎沒有性能上的差異。

【第04章】 

(P136) 

當數據變動完成時,程序員只要調用 ObjectContext<T>.SaveChanges() ,就能將改變送到 EntityDataModel ,再傳入數據庫內。

(P156) 

基本上,在 EF 6.0 內所有數據庫的操作 (除了 Entity Client 外) 都要經由 DbContext 來進行,也就是說,若想要用程序代碼操作 EF ,就必須要從 DbContext 派生自己的 Model 類。

若要定義在 EF 中使用的表格或視圖表,則要在 DbContext 的派生類內定義以 DBSet<T> 爲來類型的屬性,屬性名稱則會決定要生成在數據庫中的數據表名稱。

(P163) 

基本上,若可以用關聯來解決繼承的需求,就不要使用繼承。

(P170) 

在商用系統中,存儲過程和函數的使用十分廣泛。

(P172) 

無論是使用何種方式建立模型,對程序員來說,只有一個對象要關注,那就是 DbContext 類對象,所有的數據訪問動作都要通過它。

DbSet<T> 必須定義在 DBContext 的派生類內,代表數據源的一個對象,它是實現於 IDbSet<T> 接口,基本上可以將 DBSet<T> 看作是一個數據表。

(P173) 

DBContext 的查詢是由 DbSet<T> 進行的,也有 DbQuery<T> 類對象的功能,DbQuery<T> 類負責將查詢的動作往下層送,下層有 ObjectQuery<T> 負責生成查詢計劃並再往下送,直到查詢被處理,得到返回值爲止,所以程序員只要在 DbSet<T> 上使用 LINQ 來查詢,就能訪問數據庫。

EF 6 在對象查詢的性能上做了許多改進,因此讓應用程序的性能會更好。

【第05章】 

(P191) 

網址在 SEO 中擁有很高的比重,如果能有優秀的設計,那麼網址本身就是很好的關鍵詞。

(P206) 

只要記住利用空字符串可以回到主層而明確指定 Area 名稱,就可以前往各個層的 Area 內。

【第06章】 

(P211) 

在 ASP.NET MVC 中默認的返回 ActionResult 類型,這個 ActionResult 類型本身是一個抽象類,可以返回任何實現 ActionResult 類的類型內容,換句話說,它封裝 Action 方法的結果,是 Action 方法結果的基類。

ASP.NET 目前實現了 9 種派生自 ActionResult 類的結果類型供開發者選擇。

(P213) 

新添加的 View 會繼承 System.Web.Mvc.ViewPage 類, ViewPage 類提供許多有用的屬性與方法,以幫助呈現 HTML 的輸出,其中包含如 ViewData、 ViewBag、 TempData 等對象字典屬性。

(P216) 

調用 HTTP POST 的 Action 方法需要額外設置 HttpPost 屬性,調用 HTTP GET 的 Action 方法也有 HttpGet 屬性。但 ASP.NET MVC 裏所有 public 修飾詞的 Action 方法默認會套用 HttpGet 屬性,一般不會特別設置。

(P228) 

ViewData 與 ViewBag 都有一個特性,它們都無法跨 Action 方法訪問,只能存在於當次的 HTTP 請求中。

(P229) 

ViewData 會在 Action 方法調用 ViewPage 時自動傳遞過去。

dynamic 對象會略過編譯時靜態類型檢查,而解析工作會改變在運行時進行 (有錯誤也要此階段才知道) 。

(P230) 

使用 ViewBag.KeyName 並將數據存儲於 ViewData 的字典中。效果等同於 ViewData ,不過因爲動態的關係,性能會比 ViewData 差,就操作而言,所有特性都和 ViewData 一模一樣,但可以得到一個程序代碼輸入時的優點。

(P231) 

ViewBag 屬性在輸入時使用 “對象.屬性” 的輸入方法,對於程序代碼編寫比字典更爲直觀 (而且輸入更少字) 。

ViewBag 會在 Action 方法調用 ViewPage 時自動傳遞過去。

(P236) 

ViewData 與 ViewBag 屬性無法跨 Action 方法傳遞數據,當需要在 Action 方法之間傳遞數據的,可採用 TempData 屬性。

(P245) 

一個 ViewPage 只能聲明一個 @model 關鍵字。

(P248) 

ViewModel 應該只封裝屬性, ViewModel 與 View 之間最好只有一對一的關係。

只帶屬性的 ViewModel 類本質上是一種 Data Transfer Object (DTO , 數據傳輸對象) 的應用。

(P251) 

運用 Tuple 對象編寫讀取使用的程序代碼可讀性不好,但可以省下不少項目中定製化的 ViewModel 類。

(P253) 

ModelBinding 是一個自動化機制,主要是通過 DefaultModelBinder 類進行自動化數據轉換工作。

(P254) 

DefaultModelBinder 運行機制非常依賴 <form> 表單域的 name 屬性名稱。

DefaultModelBinder 類基本上已經可以應付實際運用中 95% 以上的需求。

(P263) 

在 ASP.NET MVC 使用 DataAnnotations 另一個好處是,它是一個集成好用戶端與服務器端的驗證環境,換句話說,雖然只是在 Model 屬性上設置驗證規則,但此驗證規則會同時在服務器端與用戶端 (View) 生效,這省下了非常多的開發時間,同時也爲服務器提供了基本的安全數據源環境。

T4 是一種用程序代碼生成程序代碼的技術。

(P267) 

在 ASP.NET MVC 5.1.1 (含 5.1.1 版本) 之後的版本, MaxLength 與 MinLength 屬性支持用戶端驗證,之前的版本只支持服務器端驗證。

(P272) 

目前 HTML 5 的 forms 的 input 類型支持 color 、 date 、 detetime 、 datetime-local 、 email 、 month 、 number 、 range 、 search 、 tel 、 time 、 url 、 week 等,具體實現的程度各瀏覽器有所差異。

(P275) 

CustomValidation 屬性類只在服務器端有效果。

(P287) 

ModelState 是服務器端一道重要的防線,可以不用瞭解它的工作原理,使用起來就是簡單的判斷式。

(P288) 

如果在某些情況下,不希望 ModelState 對象被傳遞至 View ,使用 Clear 方法將 ModelState 字典清除即可。

(P291) 

UpdateModel 方法 (MVC 5) 內部其實是調用 TryUpdateModel 方法 (MVC 5) 來處理, TryUpdateModel 方法 (MVC 5) 執行之後會返回一個 bool 值,而 UpdateModel 方法 (MVC 5) 則多做了一層彈出例外的動作。

(P297) 

每一個 Controller 的 Action 方法操作完成後,最終結果一定要返回一個實現 ActionResult 抽象類的類型。

(P301) 

CSV 簡單說就是使用逗號來分割每一個字段數據。

(P304) 

ASP.NET MVC 爲避免 JSON Hijacking 攻擊,默認不允許 HTTP GET 請求。

(P317) 

一個可下載的文件必須提供兩個必要信息與一個選擇性信息。第一個是要下載的文件內容,文件內容的來源由 3 個 FileResult 子類來提供。第二個是 ContentType ,是一種因特網媒體類型 (Internet Media Type) ,當在網絡上傳遞數據時,用戶端與服務器端會溝通所要使用的 ContentType ,通常是多對一的選擇,意思是,用戶端會提供多個選項讓服務器來選擇,服務器端會從用戶端提供的選項中選擇其中一種支持的選項來進行響應。

(P320) 

HttpPostedFileBase (System.Web 命名空間) 是一個抽象類,它可以獲取用戶端上傳的單個文件。

(P333) 

ASP.NET MVC 默認執行 WebFormViewEngine 再執行 RazorViewEngine 。

(P334) 

PartialViewResult 的結果不合適直接輸出,適合拿來組合或重複組合。

(P335) 

名稱按照習慣, MasterPager 會在最前方加 “_ (底線)” , PartialView 會在最前方加 “_ (底線)” 後面加上 Partial 以便區分。

(P337) 

HostingEnvironment 類 (比 System.Web.Hosting 命名空間) 和 Server.MapPath 方法效果一樣,不過未來的執行 (常駐) 環境會比現在靈活許多。

(P340) 

新 Authentication Filter 的執行順序優先於以往所有的 Filters 。

在信息安全上 AAA 是一種標準做法,它是 Authentication (驗證) 、 Authorization (授權) 、 Accounting (賬戶) 的縮寫。

Authentication : 確認用戶的唯一身份;

Authorization : 用戶能做什麼或不能做什麼;

(P347) 

Authorization Filter (授權過濾器) 在 ASP.NET MVC 4 (含) 之前是最早執行的 Filter ,從 ASP.NET MVC 5 會在 Authentication Filter 之後執行。

(P356) 

OutputCache 屬性是 ASP.NET MVC 高速緩存機制的實現,基本上是移植 Web Forms 的 @OutputCache 輸出高速緩存架構, OutputCache 屬性 (ASP.NET MVC) 唯一不支持的是 @OutputCache 的 VarByControl 屬性。

【第07章】 

(P380) 

Windows 進程 (Precess) 是一個執行的程序,正式地說,進程是一個系統層級用來描述一組資源和程序執行所需的內存份分配。對於每一個被加載到內存的 .exe ,在它的生命週期中操作系統會爲它建立一個單獨且隔離的進程。

(P381) 

每個 Windows 進程都有用於進入程序的進入點 (entry point) 的主線程 (Main Thread) 。線程是進程中的基本執行單元,換句話說 : 進程的進入點建立的第一個線程被稱爲主線程。

(P382) 

線程是 Windows 進程中的獨立執行單元,每個線程都有一個主線程 (在執行進入點時建立) ,並且每個線程還可以以程序方式建立新的線程。

(P388) 

Task.Run 方法是 .NET Framework 4.5 提供的新方法,在 .NET Framework 4.0 可以調用 Task.Factory.StartNew 方法,可以實現相同的效果。 Task.Run 方法相當於 Task.Factory.StartNew 方法的縮寫方式。

(P393) 

加入了 async 修飾詞後必須瞭解以下內容 : 

1. async 修飾詞指示編譯器將 await 運算符視爲一個關鍵字;

2. async 修飾詞只能使用在返回 void 、 Task 與 Task<TResult> 類型的方法上 (或 Lambda 表達式) 上;

有 async 修飾詞不一定有 await 運算符,但有 await 運算符一定有 async 修飾詞。

按照微軟的建議,開發人員自己編寫的異步方法最好也採用 “*Async” 結尾。

【第08章】 

(P412) 

執行階段通過 ViewResult 執行 View 之前都會先執行 ViewStart.cshtml ,所有開發者可以在這個文件中設置屬於全站 View 的共同默認特徵,如此一來就不必在每個 View 中各自指定。

(P413) 

在 Views 中會發現名爲 Shared 的目錄,如同其名,這個目錄是用來存放全站通用的共享型文件的,如 _Layout.cshtml 以及 Error.cshtml 。

在 View Engine 搜索 View 的算法中,定義了多個搜索路徑, ~/Views/Shared 目錄是搜索可用 View 的最後一個嘗試。

(P414) 

View 文件的配置慣例,事實上是 ASP.NET MVC 運行階段 View Engines 搜索文件的方式。

(P420) 

在執行順序上, View 會被優先執行,然後被 View 引用的 Layout 執行。

(P425) 

需要注意 ViewData 、 ViewBag 兩者之間並不相同,設置在 ViewBag 中的數據不會出現在 ViewData 中。

(P426) 

當 ViewResult 的 ExecuteResult 被執行後會啓動 View Engine 工作,完成以下的事情 : 

1. 讓系統中註冊的 View Engine (s) 根據 context 獲取應該使用的 View ;

2. 讓 View (模板程序) 與 Model (數據) 結合;

3. 產生的運行結果 (HTML) 寫到 Response 中;

(P429) 

這裏所說的 Razor 內容轉換,都是調用對象的 ToString() 方法獲取結果,即便對象是一個 string 類型對象也是如此。

(P430) 

開發者可以使用 “@@ (連續兩個@)” 的標記方式來讓 Razor 直接輸出爲 “@” 。

(P433) 

在 View 裏定義預期的 Model ,使用的是 @model 指示詞。

(P434) 

Model 只能有一個類型,所以 @model 指示詞也只能在 View 中出現一次。

在 View 裏面使用到類庫時,與編寫一般類時相同,必須引入該類庫的名稱空間,在 View 裏面使用 @using 來導入該名稱空間,指示詞不必以 “; (分號)” 結束。

Razor View Engine 提供定義全站 View 引用 namespace 的地方,它默認存在 ~/Views/web.config 中。

Razor 使用 @section 來將內容 “填入” 到 Layout 額外提供的保留區段。

(P443) 

Helpers 在 ASP.NET MVC 中的協助開發角色佔據重要位置,並且不同用途的 Helper 由 ASP.NET MVC Framework 中直接提供,主要有三個 Helper : UrlHelper 、 HtmlHelper 、 AjaxHelper 。

在開發 View 時可分別使用 Url 、 Html 、 Ajax 等屬性來獲取 UrlHelper 、 HtmlHelper 、 AjaxHelper 的實例。

UrlHelper 的主要功能就是用來生成與特定 Controller / Action 及其參數匹配的網址。

UrlHelper 的實例 (instance) 在 WebViewPage 及 Controller 中以只讀的 Url 屬性來提供,開發人員可以直接取用 Url 屬性獲得,不必自行生成。

(P445) 

HtmlHelper 是在 View 中最常見到的 Helper ,可分爲三大類型 : 常規類、窗體類及功能類。

HtmlHelper 的實例 (instance) 在 WebViewPage 中以一個只讀的 Html 屬性來提供,開發人員可以直接取用 Html 屬性獲得,不必自行生成。

使用 HtmlHelper 時,有很大一部分方法依賴 Model 與 Lambda Expression ,這也是 HtmlHelper 中功能強大的部分,方法名稱中結尾爲 For 的這一系列方法都是以 Lambda Expression 的方式來取代以字符串來聲明對象 (Model) 的屬性或字段名。

(P448) 

ActionLink 方法爲開發者提供了最簡便的方式生成 <a> 超鏈接標籤。

(P450) 

Raw 方法將輸入的字符串參數直接包裝爲 MvcHtmlString 對象後返回,這樣就避免了在 Razor 的 @Expression 中會隱含調用 Html.Encode 的情況。

(P451) 

由於 using { } 區塊在關閉時會調用 BeginForm 返回 MvcForm 實例的 Dispose 方法,內含的 EndForm 被調用,所以不需要自行調用 EndForm 方法。

(P465) 

AjaxHelper 的實例 (instance) 在 WebViewPage 中以只讀的 Ajax 屬性來提供,開發人員可以直接取用 ajax 屬性獲得,不必自行生成。

【第10章】 

(P525) 

Elmah 管理外來因素造成的錯誤收集與管理, NLog 管理內部錯誤的收集與管理。

【第11章】 

(P552) 

在密碼存儲上,應當採取哈希的方式,在存儲與更新之前,明文密碼一律使用哈希加密,然後纔可以存儲進數據庫。

(P553) 

ASP.NET 加密算法絕大部分集中在 System.Security.Cryptography 命名空間。

(P554) 

AES 類是 ASP.NET 官方所推薦的對稱加密算法。

哈希算法是單向函數,主要用於驗證數據的完整性,無法逆向解出原始明文數據。

哈希函數可接受任意長度的明文數據,但會生成固定長度的加密文。

【第13章】 

(P623) 

在 JSON 裏表示一個 Object 需符合以下條件 : 

1. 以 { (左大括號) 開始,以 } (右大括號) 結尾;

2. 每個名稱後跟着一個 : (冒號) ;

3. 多個 “名稱 : 值” 之間用 “,” (逗號) 分隔;

在 JSON 裏表示一個 Array 需符合以下條件 : 

1. 以 [ (左括號) 開始,以 ] (右括號) 結尾;

2. 值與值之間使用 “,” 分隔;

【第14章】 

(P637) 

敏捷開發期望的是,每一次的需求變動,都是軟件開發的動力,而每一次的變動,都是質量的累積,並使得產品更符合用戶的需求。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章