天天看點

.NET架構師知識普及

今天看到一篇漫畫,[3年.NET開發應聘大廠慘遭淘汰,如何翻身打臉面試官?],好多問題,一下子還真的回答不了,這裡對這些問題進行了整理,增加下腦容量,哈哈。俗話說不想當将軍的士兵不是好士兵,不想當架構師的程式員,不是一個努力要進步的程式員,努力加油,不斷學習。有人說架構師都是一批秃頂的人,程式員都是一群XX,其實作實是,架構師好多不是秃頂,不用擔心自己成了架構師變成秃頂,那都是吓人的。程式員也是懂得浪漫的,要不然那麼多浪漫的程式,那麼多酷炫的技巧都是怎麼實作的。

1.C#中的委托是什麼?事件是不是一種委托?

委托是一種引用類型,表示對具有特定參數清單和傳回類型的方法的引用。委托用于将方法作為參數傳遞給其他方法。事件就是通過委托調用的方法。

例如:

public class DelegateTest
{
    public delegate int AddDelegate(int a, int b); //定義委托類型
    public AddDelegate addDelegate; //定義委托
    public event AddDelegate AddDelegateForEvent; //定義事件

    public int Add(int a, int b) {
        Console.WriteLine($"a:{a},b:{b}");
        return a + b;
    }
    //委托和事件的使用
    public static void Test() {
        DelegateTest text = new DelegateTest();
        text.addDelegate = text.Add; ;
        text.addDelegate(1, 2);

        text.AddDelegateForEvent += text.addDelegate;
        text.AddDelegateForEvent += text.addDelegate;
        text.AddDelegateForEvent(10, 20);//或者下面的使用
        //AddDelegate d = text.AddDelegateForEvent;
        //d(10, 20);
        //結果
        //a: 1,b: 2
        //a: 10,b: 20
        //a: 10,b: 20
    }
    //Func和Action的使用
    public static void Test2() {
        Func<int, int, int> add = (int a, int b) => { return a + b; };
        Action<int, int> addVoid = (int a, int b) => { int c = a + b; };
    }
}      

C#中委托這篇文章,對委托有更多的介紹。Fun和Action是微軟封裝的委托,一個有傳回值,一個沒有,C#進階功能(三)Action、Func,Tuple這篇文章介紹的比較詳細。

2.聊聊.NET的管道和.NET Core的中間件

.NET的管道:在管道模型運作開始前,首先HTTP的請求被被傳遞到HttpRuntime類的一個執行個體中,然後這個執行個體對象檢測請求并找到被接受的那個應用程式,接下來管道模型就使用HttpApplicationFactory對象來建立一個HttpApplication對象來處理這個請求(在此同時也将建立HttpContext,HttpRequest和HttpResponse),一個HttpApplication可以包含一系列HttpModule對象。

ASP.NET MVC請求生命周期

URL Routing Module →→ Matching Route Entry →→ Route Handle →→ Http Handle →→ Controller Factory →→ Controller →→ Action Invoker →→ Module Binders →→ Authentication Filter →→ Authorization Filter →→ Action Filter →→ Action Execution →→ Action Filter →→ Action Result

簡單就是:Url →→ Route →→ Controller →→ Action →→ View

其他的ASP.NET生命周期的文章,ASP.NET生命周期 , WebForm頁面運作周期--頁面關系

.NET Core的中間件

中間件是一種裝配到應用管道中以處理請求和響應的程式,使用Run、Map和Use擴充方法來配置請求委托。請求委托用于建構請求管道,處理每個HTTP請求。每個委托可以在下一個委托之前和之後執行操作。委托還可以決定不将請求傳遞給下一個委托,這稱為請求管道的短路。短路通常是可取的,因為它避免了不必要的工作。

public class Startup
{
    //此處省略部分代碼,建立一個新的Core web項目,可以自行檢視
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}      

Configure方法中的就是中間件,中間件元件的順序定義了在請求上調用它們的順序,以及響應的相反順序,此排序對于安全性,性能和功能至關重要。

常用的中間件順序

1. 異常/錯誤處理

2. HTTP 嚴格傳輸安全協定,HTTP協定介紹

3. HTTPS 重定向

4. 靜态檔案伺服器

5. Cookie 政策實施

6. 身份驗證

7. 會話

8.MVC

中間件例子:

public class LogMiddleware
{
    private readonly RequestDelegate _next;
    public LogMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        Debug.WriteLine("程式運作 開始。");
        await _next(context);
        Debug.WriteLine("程式運作 結束。");
    }
}

public static class LogMiddlewareExtensions {
    public static IApplicationBuilder UseLog(this IApplicationBuilder app) {
        return app.UseMiddleware<LogMiddleware>();
    }
}      

在Configure中 app.UseLog();就可,程式運作,會在VS調試輸出的地方顯示

程式運作 開始。

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "Index", controller = "Home"}. Executing action ----此處省略部分輸出

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action WebCore.Controllers.HomeController.Index (WebCore) in 13.9555ms

程式運作 結束。

3.說說資料庫的隔離級别,資料庫有哪些鎖

資料庫事物的四大特性:原子性、一緻性、隔離性、持續性(永久性)。原子性:要麼全做,要麼全不做;一緻性:事務執行的結果必須是使資料庫從一個一緻性狀态變到另一個一緻性狀态。一緻性與原子性是密切相關的;隔離性:一個事務的執行不能被其他事務幹擾;永久性:一個事務一旦送出,它對資料庫中資料的改變就應該是永久性的。

事務的隔離性:未送出讀(Read uncommitted),已送出讀(Read committed),可重複讀(Repeatable read),可串行化(Serializable )。未送出讀:最低級别,任何情況都無法保證;已送出讀:可避免髒讀的發生;可重複讀:可避免髒讀、不可重複讀的發生;串行化:可避免髒讀、不可重複讀、幻讀的發生。舉例:未送出讀:A更新了資料沒有送出B可以看到;已送出讀:A更新了資料沒有送出B看不到,送出之後可以看到;可重複讀:A插入一條資料,送出之後,B看不到,B事物結束之後,在查詢可以看到;可串行化:A執行完之後B才可執行。(所有的一切操作都是并行操作)

資料庫中的鎖:分為獨占鎖(即排它鎖),共享鎖和更新鎖,細分又可分為表鎖、行鎖、頁鎖等。

為什麼需要所?當并發事務同時通路一個資源時,有可能導緻資料不一緻,是以需要一種機制來将資料通路順序化,以保證資料庫資料的一緻性。

共享鎖表示對資料進行select操作,多個事務可以同時為一個對象加共享鎖。排他鎖也叫寫鎖,排他鎖表示對資料進行insert、update或delete操作,如果一個事務對對象加了排他鎖,其他事務就不能再給它加任何鎖了。更新鎖在的初始化階段用來鎖定可能要被修改的資源,這可以避免使用共享鎖造成的死鎖現象。

4.口述下如何設計一個SOA架構

SOA的全稱是Service Oriented Architecture,即面向服務的架構。它可以根據需求通過網絡對應用元件進行分布式部署、組合和使用,服務層是SOA的基礎,可以直接被應用調用,進而有效控制系統松耦合。簡單來說就是A功能布置在A伺服器,B功能布置在B伺服器,他們都開放出接口供C。。等通路,C不用知道A,B是如何實作的,隻管用就可以了。簡單的例子webservice、WCF、web api等等。

SOA架構的文章,Web Service 和WCF的比較

5.SOA和微服務架構之間的主要差別是什麼?

我的了解是:SOA和微服務是一脈相承的,兩者都是中立性,語言無關,協定跨平台。微服務的目的是有效的拆分應用,服務的細粒度,重用組合,甚至是每個操作(或方法)都是獨立開發的服務,足夠小到不能再進行拆分。SOA更适合大型企業中的業務過程編排、應用內建。

6.了解各個framework的底層不?

C#源碼檔案 →→ C#編譯器 →→ 程式集 →→ 本機語言

底層的庫:CLR(Common Language Runtime)公共語言運作時,CTS(Common Type System)通用類型系統,CLS(Common Language Specfication)公共語言規範,CIL(Common Intermediate Language)公共中間語言,CLI(Common Language Infrastructure)公共語言基礎結構

7.說說浏覽器頁面的渲染過程

DNS查詢 →→ TCP連結 →→ HTTP請求 → 伺服器響應 →→ 用戶端渲染(HTML,CSS,JS)

8.說說中介模式的設計原理和應用場景

中介者模式是用來降低類類之間的耦合的,因為如果類類之間有依賴關系的話,不利于功能的拓展和維護,隻要修改一個對象,其它關聯的對象都得進行修改,如果使用中介者模式,隻需關心和Mediator類的關系,具體類類之間的關系及排程交給Mediator就行。房産中介、QQ遊戲平台、聊天室、QQ群和短信平台

9.請問如何構架一個高負載的系統?

應用服務和資料服務分離,使用緩存改善網站性能,使用應用伺服器叢集改善網站的并發處理能力,資料庫讀寫分離,使用反向代理和CDN加速網站響應,使用分布式檔案系統和分布式資料庫系統,使用NoSQL和搜尋引擎,對業務拆分,建立分布式服務。

10..NET系統如何實作水準擴充、如何解決高并發問題

水準擴充:利用Nginx建立分布式系統,增加伺服器,增加CPU

解決高并發問題:增加緩存、禁止使用者重複操作、建立請求隊列

11.說說IIS的工作原理?

對比IIS來說,它依賴HTTP.SYS的内置程式來監聽外部的HTTP請求,如果請求的是一個可通路的URL,HTTP.SYS會将這個請求交給IIS工作程序,把資訊儲存到HttpWorkRequest中,在互相隔離的應用程式域AppDomain中加載HttpRuntime,調用HttpRuntime的ProcessRequest方法,之後就是我們的程式操作,最後傳回資料流,并重新傳回到HTTP.SYS,HTTP.SYS在将資料傳回給用戶端浏覽器。

Win10下IIS配置圖解、MVC項目釋出圖解、IIS添加網站圖解。

12.手寫一個千萬并發的商品秒殺功能

Redis緩存秒殺的商品ID,數量,一個請求數量減少一個,數量等于0的時候,直接傳回失敗,成功的資料儲存到消息隊列中,之後儲存到資料庫,秒殺的商品比較少的,直接用一個線程安全的清單就可以了。