Skip to main content

Posts

Showing posts from May, 2017

[探索 5 分鐘] stack 與 heap 的底層概念

這是經典的概念題。要寫出能動的程式很簡單, 要去解釋背後的記憶體管理運用原則, 還是需要一點時間內化。而且不知道為什麼, 一般的軟體工程師跟架構師來說這兩個詞, 那個講起來那個味道就是不太一樣, 有時候面談別人時, 還會覺得有些求職者有獨到的見解。 簡單來說, 從記憶體配置的角度, 用一個二分法 stack 用於靜態記憶體配置, 大陸翻譯為棧, 棧, 棧 (why ?) heap 用於動態記憶體配置, 大陸翻譯為堆 抱怨一下, 堆跟棧我一直覺得命名混亂, 用 Google 翻譯也會發現 stack 跟 heap 都翻譯為堆疊的「堆」, 連 Google 都搞錯了, 所以後面還是用英文來說吧。 這張 All-in-one 的圖是我目前最喜歡的圖像解釋, 來源是  Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing  : 首先記得這個範例, 圖片是由上而下逐行介紹, public void Method1() { int i = 4; //Line1 int y = 2; //Line2 Class1 cls1 = new Class1(); //Line3 } 總結是 : value type 的變數, 包括指標變數會放在 stack reference type 的變數 (如 string, object) 本身也會放 stack, 然而他的值 (value) 則是放 heap box 就是 value types to reference types 的過程, 所以 value 會被放到 heap 中, 而產生一個 object 變數來指向這個 value, 變數指標則是在 stack unbox 是  reference types to value types 的過程,  所以原本 object 所指向的值 (heap 中) 會被複製到 stack 中並賦予明確 value type 型別 深入 Stack 現在回到最原點, 我們略懂 stack 與 heap 的區別了, 但還是沒有一個「感覺」對不對 ? 因為我們不懂 why。我個人建議有空可以 K

[探索 3 分鐘] 書本提到的 class, interface, abstract

類別、介面、抽象這些詞, 應該算是物件導向的基礎知識, 但由於他有一點抽象, 很多人還是覺得跟他們有些距離, 解釋也不一定到位。面試時大家又很愛問, 似乎想要知道你對物件導向的認知到哪邊。小弟有幸在 10 年前參加公司的讀書會討論這兩本書 :《物件導向設計模式 - 可再利用物件導向軟體之要素》與《Effective C++ 3/e 中文版 - 改善程式與設計的 55 個具體作法》看完之後雖然還是沒有具體答案, 但肯定直到現在都有一個「物件導向感覺」的。 以下請謙虛參拜。 Object 物件 《物件導向設計模式》 物件導向程式是由物件所構成。物件將資料和可施於其上的程序包裝在一起, 此處的程序通常較作 method 或操作 (operation)。當物件收到客戶端 (client) 送來的要求 (request), 或稱為訊息 (message) 時, 就會執行對應的操作。 訊息是唯一可令物件執行操作的管道, 操作則是唯一可改變物件內部狀態的管道。有了這些限制, 物件內部狀態可說是被妥為封裝了起來 (encapsulation) : 無法接觸及, 無法自外界窺伺。 Interface 介面 《物件導向設計模式》 介面是物件導向系統的基石。 物件所宣告的每一個操作, 都得訂出該操作的名字、參數、回傳值, 也就是該操作的外貌簽名 (Signature)。所有已訂定的物件操作之 Signature, 稱為此物件的介面  (Interface)。 物件的介面, 界定出能送給此物件的訊息類型; 只有符合物件介面的 signature, 才能送給此物件。想辨識物件, 只有靠介面這條路; 若不知道介面, 便無從得知物件的資訊, 也無法叫他做任何事。物件介面並不含任何時做事項 — 物件有權自主決定該如何時做這些操作。 兩物件即使介面完全一樣, 也可能會有完全不同的實作。  《Effective C++》 對於其他語言轉換至 C++ 陣營的程式員而言, 另一個可能造成困惑的術語是介面 (interface)。  Java 和 .NET 語言都提供 interfaces 為語言元素, 但 C++ 沒有。當使用術語「介面」時, C++ 通常談的是函式的簽名 (signature) 或 class 的可存取元素 (如 cla

[探索 5 分鐘] 淺談 ASP.NET MVC 的生命週期

任何「生命週期」的探討都是一門學問,  ASP.NET MVC Life Cycle 的官網以及網路文獻也很多,今天找到一個淺顯易懂的版本  ASP.NET MVC - Life Cycle 。 他將所謂的生命週期分兩個來探討, 然後再配上圖片 : The application life cycle The request life cycle Web Application 的生命週期是起於 IIS (或其他 web server) 運行應用程式, 終止於服務暫停, 回收或關閉。但細部的 process 是: 當第一個請求發出時, 觸發 Application_Start() 事件 (Global.asax.cs 文件中), 做應用程式初始配置、路由設定等等載入工作。但當 web 服務器回收應用程序或在一段不活動狀態 (InActive) 或超過 cpu、memory 閾值之後, Application_End() 事件將觸發, 接下來的請求將被視為第一個請求, 並且再次觸發 Application_Start() 事件。 request 比較複雜, 但對 MVC 有概念的人大方向應該可以抓出一個順序: request → routing → controller → action → result → response。 提醒兩點, 應該有看到一個 Controller Intialization ? 順便分享一下, 過去曾有專案有效能問題, 結果是 Controller 建構子做了一些 AutoMapper.Attributes 的 mapping 動作, 天真以為他只會初始化一次。但 sorry, 是每一個請求都會進入構造函式, 這邊慢, 大家就一起漫步了。第二點, 不是每個 result 都需要 view engine 處理, 我們也可以回傳一個字串, JSON..., 對吧 ? 所以上圖 Result Execution 才會有兩種處理方式。 System.Web.Mvc / MvcHandler.cs 的  程式碼  也滿值得欣賞一下。是由 IControllerFactory 類來創建 Controller 實體去執行後續動作 : protected internal virtual void Proce

[探索 5 分鐘] jQuery 發展歷史

第一版 jQuery 在 2006 年發布, 支持跨瀏覽器。有人會以為 jQuery 是一個 Framework, 但其實他歸類為 JavaScript Library。 wiki 也是這麼解釋: jQuery is a cross-platform JavaScript library designed to simplify the client-side scripting of HTML. 寫在前頭, 由於 JavaScript 是很靈活的直譯式語言, 只要在 <head> <script> 參考一隻 js 就完成 jQuery 載入, 但是 1.6 版前後, 有 .attr() 與 .prop() 的差異; 以及 2.0 版以後不再相容 IE 6, 7, 8。有些開發者在維護舊系統時為了避免新舊版本衝突, 在獨立開發頁面載入較新版本, 久了造成單一站台共存 jQuery 版本, 這是非常不具維護性的做法。為了與時俱進, 建議逐漸換為新版, 並配置唯一版本的 jQuery 到 master or layout 頁統一管理。企業內若對 IE 愛不釋手, 就避免追到 1.9 版以後。因為這樣寫其實滿醜的。 <!--[if lt IE 9]> <script src="jquery-1.9.0.js"></script> <![endif]--> <!--[if gte IE 9]><!--> <script src="jquery-2.0.0.js"></script> <!--<![endif]--> jQuery History 縱看 jQuery 的版號跟出版日期, 非常活躍, 發展已經超過 10 年 (2006 ~ 2017截稿), 每年都有一次以上的版本更新, 而且還能保持精簡, Production 檔案大小約在 100 KB 內。 ver release date note 1 2006-08-26 First stable release 1.1 2007-01-14 1.2 2007-09-10 1.3 2009-0

[探索 5 分鐘] method chaining 設計原理

有用 jQuery 操作過 DOM 物件的同學是不是有時候會好奇, 這種把方法不斷的用「點」運算式的背後是怎麼設計的 ? 它叫做 Method chaining, 方法鏈, 比如 jQuery 這麼寫 <div id="d1" onmouseover="foo()">jQuery is fun!!</div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> function foo() { $("#d1").css("color", "red").slideUp(2000).slideDown(2000); } </script> 可以讓一個黑色文字, 滑鼠移上去時依序 > 變為紅色 > 向上滑動 2 秒 > 向下滑動 2 秒。現在大家傾向這麼寫 $("#d1").css("color", "red") .slideUp(2000) .slideDown(2000); /* 囉嗦又不流暢的寫法 var d1 = $("#d1"); if (d1 != null) { d1.css("color", "red"); d1.slideUp(2000); d1.slideDown(2000); }*/ 較為流暢, 英文叫 Fluent, 每一行有一個重點, 卻又與第一行的物件串在一起, 比傳統這麼寫好多了 wiki  有演示很多語言怎麼實作 Method chaining, 其實重點就是每次呼叫完函式, 把自己 (this or self) 回傳 (當然你回傳 null, 就 GG了)。由於大部分物件是 reference type, 僅回傳物件所在位址, 一般而言就是 4 bytes 的大小, 會影響一點效能但不大, 換

[探索 3 分鐘] 網頁 onload 與 onready 的發生順序

不知道各位辛苦的開發者, 從英文來解讀這兩個事件, 會不會遇到混淆 ? 每過一段時間, 我就會覺得觸發的順序是先 load 再 ready ? 因為 ready 放在最後面, 這才叫 ready 阿 ! 然後又記錯了, 是很嚴重的相反。只好來做一個探索筆記加深印象。 先講結論, 正確順序是先 ready 再 load, 所以聯想為 "ready to load", 這個口訣希望能幫到大家, 來一起念三次: ready to load ready to load ready to load OnLoad 首先, MDN  文件很清楚這麼說: The load event is fired when a resource and its dependent resources have finished loading. 是完成 load 時被觸發, 也就是 on loaded, on finished, 不是 on loadstart 或 on loading。這是內建的 JavaScript 事件, 常見的用途是在 body.onload, image.onload, 代表資源載入完畢了, 正在操作的用戶開始欣賞美麗的視覺。 OnReady 這個是一個非標準的事件, 並沒有內建, 網路上查到的 onready, DOMContentReady, document.ready ..., 基本上都是後來加工的。最常見的加工就是 jQuery 提供的 $(document).ready 函式, 時機點是 DOM 文件讀取完畢, 進入 ready to load (開始讀取圖片, 影音...等資源), 但對 JavsScript 腳本語言來說, 是絕佳的程式進入點 (因為你可以拿到所有的 DOM 物件了)。 程式筆記 用程式碼來記憶一下順序, 我在系統中撒了一堆程式碼片段, 在 console.log 時也把流水號加上去, 方便了解觸發順序。以下你覺得 log 顯示順序為何呢 ? document.addEventListener("DOMContentLoaded") body onload image onloadstart onloadeddata onload video

[探索 3 分鐘] session 與 cookies

Web 開發者除了必須了解 HTTP 協定, session 與 cookies 大概也是數一數二重要的概念了。最近不小心爬文爬到 2005 年  Cookieless ASP.NET  這篇文章, 覺得挺有趣, 這邊筆記一下重點。 概念 wiki  關於 HTTP session state 的解釋 HTTP is a stateless protocol. A stateless protocol does not require the HTTP server to retain information or status about each user for the duration of multiple requests. However, some web applications implement states or server side sessions using for instance HTTP cookies or hidden variables within web forms. HTTP 本身是一種無狀態的協定, 這是天生的。所以 session state 其實是一個人工的產物, 微軟在 1997 年推出 ASP 技術時提到這個概念。session state 可以讓應用程序保存 user 的部分資訊做為持續互動用途。每個 session 會有一個唯一的 ID (字符串), 瀏覽器若啟用 cookies 機制則 session ID 會存入 cookies 中 (或其他 hidden 欄位中), 客戶端每次發出 request 的封包內就會夾帶這個 session ID 供伺服器驗證並取回先前資料用。 Cookies 是有問題的東西 ? cookies 好像是個麻煩精 ? 他其實只是一堆文字形式的 key value 組合, 儲存於客戶端, 依據建立連線的 domain 為名的資料夾中, 本身並不是一隻程式, 所以不會有攻擊行為。但就是因為是一個單純的檔案以及文字, 任何安裝於客戶機器上的電腦, 都有機會取得內容, 有些敏感信息可能因此曝光, 更惡意的還可能竄改資料。 使用 Cookieless Sessions 如果因為瀏覽器被取消 cookie 功能或是要支持 Mobile 應用, 不使用 C

[探索 10 分鐘] ASP.NET MVC 操作 HTTP handler 與 module

首先, 一個整體觀, HttpHandler 與 HttpModule 這兩種處理模式, 可以互相搭配運用, 也可以互相取代, 取決於需求。他們的關係如 Implementing HTTPHandler and HTTPModule in ASP.NET 文章提到, 是這樣: 一個 request 可以通過許多 module (IHttpModule 介面), 被整個生命週期期間 (BeginRequest() ~ EndRequest()) 被各種事件函式做加工, 如驗證, 轉址, 寫 Log; 而後透過路由導到 handler (IHttpHandler 介面) 做最後 ProcessRequest() 加工, 如副檔名 .jpg 要做什麼, .zip 要做什麼, 並產生 HttpRequest 的 response。前者 module 類可以攔截所有 request, 而後者 handler 類專注在被分配到的特定資源請求處理。對於一個 web 應用, 這些都是可以選配的類別。 HttpHandler MSDN 解釋: An ASP.NET HTTP handler is the process that runs in response to a request that is made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page handler. ASP.NET HTTP 處理常式是為了回應對 ASP.NET Web 應用程式所提出之要求而執行的處理序。最普通的處理常式是處理 .aspx 檔案的 ASP.NET 網頁處理常式。當使用者要求 .aspx 檔案時,會透過網頁處理常式處理要求。HttpHandler 負責特定副檔名資源請求的處理常式, 如 ASP.NET page handler (*.aspx) Web service handler (*.asmx) Generic Web handler (

[探索 5 分鐘] 淺談 ASP.NET MVC 路由 (routing)

路由 (routing) 的組合千變萬化, 但對於 ASP.NET routing 的起手式, 就是這一條: public static void RegisterRoutes(RouteCollection routes) { routes.MapRoute( name: "Default", // Route name url: "{controller}/{action}/{id}", // URL with parameters defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } 進階的用法非常多, 但專案需求若沒有非常特殊(如多層 routing, 或安全性考量故意混淆), 使用大家約定俗成的 pattern, 其實易於維護。當然還有一種用於 Web API 的 routing 方式, 稱為  Attribute Routing 。就是在 Action 或 Controller 上方標上一行清楚到不行的 routing rule, 個人是滿推薦的, 像下方這樣: public class BooksController : ApiController { [Route("api/books")] public IEnumerable<Book> GetBooks() { ... } [Route("api/books/{id:int}")] public Book GetBook(int id) { ... } [Route("api/books")] [HttpPost] public HttpResponseMessage CreateBook(Book book) { ... } } 是不是非常清楚呢 ? Web API如何Routing 從技術上來看, Web API 是如何做 routing 呢 ? 參考

[探索 5 分鐘] 淺談 ASP.NET View Engine

參考  Difference Between Razor View Engine and ASPX View Engine  所整理兩種 View 引擎的特性, 提列重點如下, 並於文末針對 Razor 語法做注意事項筆記 (陸續新增)。 Razor View Engine Web Form View Engine 適用於 MVC3 以後版本, Razor 不是一種新的語言, 算一種標記語法 ASP.NET 預設的 View Engine 命名空間為 System.Web.Razor 命名空間為 System.Web.Mvc.WebFormViewEngine 附檔名為 .cshtml (Razor with C#) 或 .vbhtml (Razor with VB) 附檔名為 .aspx 或 .ascx 或 .master. Razor具有更新更進階的語法. 與舊有的 .aspx 頁面語法完全相同. Razor 語法 更直覺或易用, 比如使用  @ 前置詞: @Html.ActionLink("SignUp", "SignUp") 使用 .aspx 既有定義符號 <% 與 %> 如: <% Html.ActionLink("SignUp", "SignUp") %> 預設會預防 XSS 攻擊 (Cross-Site Scripting Attacks), 所以輸出到 View 之前會自動 encode 特殊字元( Scripts 或 HTML 標籤), 如 <,>  預設無預防 XSS 攻擊 不緩存情況, 處理速度稍慢 處理速度比 Razor 稍快 Razor 不支持頁面預覽 用 Visual Studio 可看到頁面預覽 (design mode), 方便不啟動服務進行頁面設計 Razor 支持 TDD (Test Driven Development) , 因為他不與 UI 元件相依, 如 System.Web.UI.Page 類 依賴 System.Web.UI.Page 類, 所以進行 TDD 或測試較為複雜 Layout的定義 微軟  layout  這篇文章帶領的不錯, By conv