---
# System prepended metadata

title: 我們用什麼技術開發
tags: [看]

---

---
lang: zh-tw
title: '我們用什麼技術開發'
tags: '看'
---
我們用什麼技術開發介紹
===

<br>


:crossed_swords::shield: 目前使用的開發技術介紹
---

![](https://i.imgur.com/eOcJpAN.png =100%x250)


上圖就是把常用的技術分類為五個主題，本篇會依據這些主題進行講解，這五個主題基本上就是工程師的工作日常，也是常用的核心技術的大分類。

說實在的這樣分類涵蓋的範圍太廣，要聊的東西非常的多，但講太細又怕讀者會感到無聊，所以我們每一個主題所提到的內容都是**精簡**過的資訊，好處是可以快速理解一門技術，壞處則是只理解表面而已。


<br>

:::success
每個技術可能會淺談到一點程式碼的應用，我認為帶點程式碼的語法，是為了讓讀者能夠在開發者的角度，去理解該技術能夠達到哪些目的，以及為什麼要使用它，**但不會去解釋過多的程式碼語法邏輯和規則**（~~*為了讓你繼續看下去，所以不能講太多*~~:joy:	）。
:::

<br>

## 前端

![](https://i.imgur.com/70xvCQq.png)

前端指的是客戶端瀏覽**網頁**的部分，以 「HTML」、「CSS」、「JavaScript」技術開發。

<br>

### HTML<small>（**H**yper**T**ext **M**arkup **L**anguage，超文本標記語言）</small>


一個網頁的組成，最基本的東西，就是「HTML」。可以把「HTML」想像成一堆文字，並將不同文字的**區間**去做**標記**，來表達不同的意義，並藉由**瀏覽器**去呈現內容。

<br>

以下是一份文字稿:scroll:
![](https://i.imgur.com/IxirFM4.png)


以**人**:shrug:的角度來看，就上面的內容，看起來像在解釋某個理論的原理，以及它有哪些額外的命名。
就字面上看，大部分的人應該都能判斷出，第一行為某理論的**主題**，以及後面的理論**說明**，和此理論不同命名的**項目**。

<br>

試著把這份文字稿:scroll:丟進瀏覽器:desktop_computer:內
```xml=
八二理論

定義：80% 的結果來自於 20% 的行動。

其他幾個不同的名稱：
* 帕雷托法則
* 80/20 法則 (最常見
* 關鍵少數法則
* 因子稀疏法則
```

<br>


以下是透過瀏覽器:desktop_computer:	解析後，網頁呈現的部分：
<iframe height="300" style="width: 100%;" scrolling="no" title="純文字稿" src="https://codepen.io/KingLongWu/embed/jOvNVgR?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/jOvNVgR">
  純文字稿</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<br>

看得出與先前不同，以結構來看，都變成一行了，完全看不出來在講什麼，只是一行單純的文字，毫無結構可言。

<br>
<br>

> 人類:shrug:看文字稿，是可以直覺反應出文章結構，但瀏覽器:desktop_computer:沒辦法，也看不懂。

<br>
<br>

然而為了讓瀏覽器看的懂，所以要在特定文字**區間**去做**標記**，來讓瀏覽器明白人類想表達的意義。
以下為文字稿轉換成「HTML」：
```xml=
<h1>八二理論</h1>
<p>定義：80% 的結果來自於 20% 的行動。</p>
<h2>其他幾個不同的名稱：</h2>
<ul>
    <li>帕雷托法則</li>
    <li>80/20 法則 (最常見)</li>
    <li>關鍵少數法則</li>
    <li>因子稀疏法則</li>
</ul>
```
經過「HTML」的標記：
* 原本第一行的主題，轉換為==h1==大標題
* 後面的理論說明，轉換為==p==段落
* 緊接著轉換為==h2==次標題
* 最後的各個名稱，轉為==ul==、==li==清單


<br>

以下是透過瀏覽器解析後，網頁呈現的部分：
<iframe height="300" style="width: 100%;" scrolling="no" title="文字稿轉HTML" src="https://codepen.io/KingLongWu/embed/JjaPEPb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/JjaPEPb">
  文字稿轉HTML</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<br>

就上面的呈現，可以看出大標題與次標題，皆有`粗體`、`字體較大`，清單的部份，幫你加上了`●`符號，並且每一個區段會幫你做好換行，這就是使用「HTML」的標記，讓瀏覽器讀懂後，而網頁上產生的變化。

<br>

#### 補充重點
* HTML 常被人比喻為人的骨架
* HTML 用來將資料結構化（樹狀結構，有階層的關係），並使資料變的有意義
* HTML 是標記語言，不是程式語言（程式語言涵蓋判斷式、迴圈等語法）
* HTML 要用大寫表示，不要用小寫 html 表示
* HTML 正確的使用標記，搜尋引擎的排名會更高


<br>

---

<br>

### CSS<small>（**C**ascading **S**tyle **S**heets，階層式樣式表）</small>

負責處理「HTML」這份純文字檔在網頁上面的**視覺外觀**與**版面配置**，就是「CSS」。

大部分的運用情境，不外乎就是處理文字的大小、顏色、粗細、段落之間的間距、超連結底線是否拿掉、圖片大小、圖片圓角、物件的上下左右對齊、浮動、固定位置、動畫等。

<br>

> 說穿了，「CSS」也是一份文字檔，也透過瀏覽器解析後，對「HTML」做樣式上的調整。

<br>

以上面的範例，再加上「CSS」後的效果：
<iframe height="300" style="width: 100%;" scrolling="no" title="文字稿轉HTML加CSS" src="https://codepen.io/KingLongWu/embed/bGxbgJN?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/bGxbgJN">
  文字稿轉HTML加CSS</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<br>

*<small class="text-muted">可以將原本的結構重新編排，也可以添加一些色彩，或是簡單的互動</small>*

<br>

#### RWD<small>（**R**esponsive **W**eb **D**esign，響應式網站）</small>

更進階的「CSS」技術，可以延伸出一個新的名詞「RWD」。在不同的3C裝置（:tv:電視、:desktop_computer:電腦、:iphone:手機...），瀏覽同一份網頁時，都能有良好的呈現。

以往的網頁設計中，只使用**電腦**螢幕的**尺寸**做開發，缺點隨著手機的流行而增加。人們用手機瀏覽此類型的網頁時，會發現版型跑版，使文章不易閱讀，這時候就會透過手機放大、縮小、平移的功能，來拼湊前後文的脈絡。

<br>

> 簡單的閱讀都有困難，怎麼可能留得住<s>（錢）</s>使用者

<br>

有些公司的網站行之有年，已有了一定程度的規模，此時若決定要導入「RWD」，搶救手機市場的使用者，必定是個大工程。

<br>

> 當時的時空背景，進而延伸出一個做法，就是再開發一個**手機版的網站**。

<br>

:desktop_computer:電腦版
https://ithelp.ithome.com.tw
![](https://i.imgur.com/OAQYjQj.png =75%x)


:iphone:手機版
https://ithelp.ithome.com.tw/m
![](https://i.imgur.com/wKr8Xod.png =30%x)


該網站就是透過程式技巧去分辨，當使用電腦則是去電腦的頁面，手機則進入手機的頁面。
注意到網址的差異，到手機版的網址最後面多一個`/m`，而這也是當時常見的處理方法。

<br>

不過這樣的做法，並不是最佳解，這樣會有幾個缺點：
* 維護上要做兩次工
* 網址不同，SEO 排名不佳

<br>

所以越早定義系統方向，進而導入「RWD」，所花的時間成本越少。但也要考慮你的網站性質，是否適合開發成「RWD」，以下情境就是不太適合：
1. 呈現的資料內容密集，如大量表格或圖表顯示。
2. 網頁內容需要精確定位，如地圖。 
3. 需要與使用者頻繁互動的功能，如滑動、拖曳，放大和縮小。


<br>


#### 補充重點
* CSS 常比喻為膚色或衣服:shirt:
* CSS 也是一個文字檔，只是因為瀏覽器，才給予了它價值
* 以電商為例，一個好的排版，能讓使用者願意花更多時間停留在上面；而一個亮眼的樣式按鈕，也能吸引使用者做出衝動性的消費
* RWD 是一種非常有用的技術，但它並不適合所有的網站，在選擇是否使用 RWD 之前，您應該考慮網站的需求和限制。


<br>
 
---

<br>


### JavaScript<small>（通常縮寫為 **JS**）</small>

網頁的最後一項技術「JavaScript」，這是一門**易學難精**:zombie:	的程式語言，與其它程式語言相比，有著特別多的**例外**特性需要熟悉，而有了「JavaScript」的存在，使網頁能處理的事情變得更加廣泛。

一個好的網頁，與使用者之間的互動應該是良好的，而網頁只使用「HTML」和「CSS」的話，所帶給使用者互動性的**回饋**:thumbsup:，是遠比不上使用過「JavaScript」的網頁。

<br>

而互動式網頁所提供的功能舉例如下：
* **即時**的新增、刪除、修改網頁上的內容或畫面
* 有階段性的去控制**引導**步驟
* 在適當的時機，**回應**描述資訊
* 觸發各類**事件**（點擊、雙擊、鍵盤事件、滑鼠事件...）與使用者互動
* ...

<br>
<br>

**「JavaScript」程式碼範例：**
<iframe height="500" style="width: 100%;" scrolling="no" title="JavaScript 練習" src="https://codepen.io/KingLongWu/embed/poZxXMy?default-tab=js%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/poZxXMy">
  JavaScript 練習</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<br>
<br>

#### jQuery

現今三大框架[^框架]:crossed_swords:	 `Anguler`、`Vue`、`React` 底層都是用「JavaScript」設計出來的，不過學習曲線很高，有很多困難的因素需要去克服（例如開發環境的建立、熟悉新的語法、了解此框架語言的特性、以及與以往寫`code`風格大不相同，需要習慣等）。

![](https://i.imgur.com/g0ArhsW.jpg)

<br>
<br>
<br>

> 而今天公司若需要即戰力，則可以使用「jQuery」來代替，
> 那麼什麼是「jQuery」呢?

<br>
<br>

<iframe src="https://jquery.com" style="border: 0" width="100%" height="170" frameborder="0" scrolling="no"></iframe>

（[jQuery官網](https://jquery.com)）

<br>
<br>

可以注意到官網 **Logo** 下方那串英文

> write less, do more，「*寫得更少，做的更多*」

<br>
<br>

「JavaScript」是一門**命名**上較~~囉嗦~~:nauseated_face:	豐富的語言，它在語法、函式命名用較多單字組成，但不巧的是我們常用到的語法，通常都很冗長，而為了讓撰寫「JavaScript」變的**快速**有趣，於是「jQuery」就被一位工程師給開發出來。

而「jQuery」就是用來簡化「JavaScript」的一個**函式庫**，它封裝了重複性的功能，移除:x:	掉不必要的程式碼命名，讓撰寫「JavaScript」語言變得簡單、易讀、又好學（~~*考試都考滿分了呢!!*~~）。

<br>
<br>

**同上面的功能以「jQuery」撰寫的範例：**
<iframe height="500" style="width: 100%;" scrolling="no" title="jQuery練習" src="https://codepen.io/KingLongWu/embed/MWBzWjg?default-tab=js%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/MWBzWjg">
  jQuery練習</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<br>
<br>
<br>


> 程式碼看起感覺沒有差太多，功能面也是沒有太大差異性，
> 那讓我們把它丟到 word 裡面，去算它的字元數看看

<br>

**兩邊程式碼字元數**
| JavaScript | jQuery |
|:----------:|:------:|
|   855 個   | 626 個 |

<br>

到了這邊應該可以感受到，確實可用更少的 `code` 來達到相同的功能，再如**事件**寫法的差異，要處理某件事情，我可以用更少的 `code` 完成，寫久了自然就會比別人更快做完案子:muscle:。
```javascript=
 //JavaScript
 document.getElementById("demo").addEventListener("click", function() {
     //...略     
 });

 //jQuery
 $("#demo").click(function() {
     //...略
 });
```


[^框架]: 遵循一定的規則去做程式碼的開發，以達到某些好處，並提高維護性


<br>

#### Bootstrap

<iframe height="300" style="width: 100%;" scrolling="no" title="Untitled" src="https://getbootstrap.com/docs/5.1/components/card/#body" frameborder="1" loading="lazy" allowtransparency="true" allowfullscreen="true"></iframe>

（[Bootstrap官網](https://getbootstrap.com/docs/5.1/components/card/#body)）

<br>
    
    
到了這邊不得不提到另一個前端元件庫，「Bootstrap」。

由 Twitter 的工程師開發，它針對「HTML」、「CSS」和「JavaScript」預先定義好語法，網頁常用到的各種功能的樣式，也處理了互動性的操作，且支援不同家**瀏覽器**相容性的問題，亦支援「**RWD**」的設計。

而它也同「jQuery」一樣地簡單、易學、靈活度高:angel:	，可快速開發完一個工整漂亮的網頁，不用特別花心思去設計樣式。

網路上大多找到的擴充套件（Web API），或是前端框架（`Anguler`、`Vue`、`React`），都有結合了「Bootstrap」的版本可以使用，這也降低不少找來的資源不相容的問題，是可以穩定的拿來做開發使用。


<br>
<br>

**一樣用上面的功能改成「Bootstrap」的範例：**
<iframe height="500" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/KingLongWu/embed/gOjQbjb?default-tab=js%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/KingLongWu/pen/gOjQbjb">
  Untitled</a> by 吳進隆 (<a href="https://codepen.io/KingLongWu">@KingLongWu</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<small class="text-muted">修改的過程很快，只要在「HTML」添加了「Bootstrap」原先定義好的樣式，加上官網提供的「HTML」模板，並對「jQuery」做些微調，即可得到看起來漂亮又工整的畫面。</small>

<br>
<br>

> 感恩的心，感謝有你:congratulations:	

<br>

對於多數的工程師來說，用「CSS」去切版是件困難的事情，而設計出漂亮又合適的樣式又是另一項挑戰，更別提要納入「RWD」去做開發了，這些都是開發網頁初期，工程師們頭痛的問題，而「Bootstrap」的誕生，一次性的把問題通通解決掉，工程師們就可以專心在**商業邏輯**上。

<br>
<br>

#### 補充重點
* JavaScript 常比喻為人的大腦，給予思考、行動
* JavaScript 與 Java 兩個是不同的東西
* JavaScript 是在前端使用的程式語言，但也可透過 node.js 在後端執行
* 常引戰的議題 jQuery 是否該淘汰，轉而使用前端框架（Anguler、Vue、React），我的看法是 jQuery 短時間不會被淘汰，但使用在大專案上，後期會變得不好維護；所以框架的誕生，基本上是為了有彈性的維護，但為了好維護，而面臨的是一大堆規則約束，以及不同的開發模式，各有利弊視情況而定，只是目前大方向都是往框架靠齊。
* 大部分的工程師，對於畫面的設計是不太擅長的，而有了 Bootstrap 後，工程師們喜極而泣~~

<br>
 
---
---
---

<br>

## 後端
![](https://i.imgur.com/8x3rGKd.png)

後端指的是伺服器端用來處理（加工）資料的部分，主要負責資料要放在哪裡、怎麼放，以及怎麼取得。

<br>

### 程式語言 C#<small>（**C**-**S**harp）</small>

要了解 C# 這門程式語言，最好先從微軟的生態開始了解，比較能助於了解整個面向，後面在介紹這門程式語言可以做到什麼事。

<br>

#### .NET 平台
:heart_eyes:	為微軟開發的一組技術和工具，可**建立**網頁或桌面程式、**部署**至 IIS 上和**運行**應用程式。

它的核心部分是 **.NET Framework、.NET Core**，以及開發工具（**Visual Studio**、**Visual Studio Code**）支援開發人員在 .NET 平台上進行開發。

<br>

#### 開發框架函式庫 .NET Framework　vs　.NET Core :zany_face:	
|              | .NET Framework                                                                                                                                                                                                                  | .NET Core                                                                                                                                                                                           |
|:------------:| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|  **函式庫**  | **Base class library**<br>提供**大量**的基本類別函式庫                                                                                                                                                                          | **Core library**<br>提供了和 .NET Framework **相似**的功能，並外加額外的特性                                                                                                                        |
|   **平台**   | 只能在 Windows 下使用                                                                                                                                                                                                           | 跨平台，可以在 Windows、macOS、Linux、iOS、Android 上執行                                                                                                                                           |
|   **開源**   | 部分開源                                                                                                                                                                                                                        | 開源                                                                                                                                                                                                |
|   **版本**   | .NET Framework 1.0 - 4.8.1                                                                                                                                                                                                        | .NET Core 1.0 - 3.1、.NET 5、.NET 6                                                                                                                                                                 |
| **出土時間** | .NET Framework 1.0 於 **2002 年**發行                                                                                                                                                                                           | 於 **2014 年**宣布要做跨平台框架 <br> **2016 年**釋出了 .NET Core 1.0                                                                                                                               |
| **線上資源** | 中、英文的資源較多                                                                                                                                                                                                              | 線上的資源較多原文，但近年中文的資源，有逐漸變多的趨勢                                                                                                                                              |
| **未來走向** | .NET Framework 4.8.1 是**最後一版**，未來仍會有技術支援，及**安全性**更新，但不會再改版，也不會被 .NET 5 取代<br><br>官方建議如果是已使用 .NET Framework 開發的軟體，不需要轉移，但**新開發**則建議使用 .NET 6 或更高的版本做開發 | .NET 5 是 .NET Core 3.1 的下個版本，未來將會依照 .NET 5、6、7、8...一路發展下去<br><br>未來每年固定11月釋出**新版**，在 3.1 LTS 之後，**雙數**版號才是 LTS 版，故 .NET 5 非 LTS，明年的 .NET 6 才是 |
| **使用準則** | 急著上線的系統可以使用<br>（*較擅長且多數情況都有解法*）                                                                                                                                                                        | 追求工作技術突破可以使用<br>（*每年都有變化*）                                                                                                                                                      |

<br>

> .NET Core 3.1 的下一個版本命名跳過 4.0，目的在於**避免**與 .NET Framework 4.x 混淆，並且**拿掉** Core 並更名為 .NTE 5，而目前 .NET 5 號稱執行效能，比 .NET Framework 或 .NET Core 3.1 還要高出許多，又給了我們除了跨平台外，更要使用它的誘因

<br>

#### .NET 總結
.NET 平台是一個超級大的**軟體的開發框架**，而 .NET Framework 是 .NET 平台的一個**實現**，專門使用在 Windows 平台；而隨著時代進步:earth_africa:	，微服務、容器化崛起，微軟開始搶占 Linux 等**跨平台**市場，所以推出了 .NET Core，而目前便以 .NET Core 為**核心**。


<br>


#### C#
為 .NET 平台中的其中一種**程式語言**（其他還有 VB、F#），是一種由 C 和 C++ 延伸出來的物件導向的程式語言，並以 .NET Framework 作為基礎。

C# 發音為「C sharp」，在音樂:musical_note:	中「C♯」表示 C 升半音，為比 C 高一點的音節，且「#」形似 **4 個加號**，微軟藉助這樣的命名，以表示 C# 在一些語言特性方面，是 C++ 的提升的意思。

<br>

該程式語言特色為：
* 語言風格相似
開發過 C、C++、Java 和 JavaScript 的工程師會感到熟悉，因為語法相似轉換語言成本較低
* 跨**語言**
只要是 .NET 框架的語言（VB、F#），程式碼都是可以共用的
* 跨平台
因為依賴於 .NET Framework 或 .NET core，所以你的選擇決定你能否跨平台
* 型別安全:sunglasses:	
定義資料的類型，該是整數就是整數，該是字串就是字串，避免不同型別的資料，發生運算錯誤
* 物件導向
利用現實生活中的各類實體，去模仿它的狀態或特性，來組織程式面的邏輯架構
* 垃圾回收機制:poop:（Garbage Collection，GC）
管理和釋放物件的記憶體資源，工程師不用手動去釋放資源，它會自動將沒用到的資源做回收

<br>
<br>

基本上 C# 有自己的版本線，並且每個版本都會和**某一版** .NET Framework、.NET Core 做搭配，並且也和**某一版** Visual Studio 共同釋出。
![](https://i.imgur.com/9NkO5bS.png)

<br>
<br>

只有 .NET Core 與 Visual Studio 的關係，可以注意到 .NET 6、.NET 8 為LTS
![](https://i.imgur.com/1rhvu0J.png)

<br>
<br>


#### C# 可以開發的項目
```graphviz
digraph ".NET架構圖" {
	node[shape=Mrecord]
    rankdir=LR;
    
    subgraph cluster_level0{
        label ="開發風格";
	    struct_MVC [label="MVC風格" fontcolor="#2196f3" color="#2196f3" shape=hexagon];
	    struct_RESTful [label="RESTful風格" fontcolor="#e91e63" color="#e91e63" shape=hexagon];
    }
    
    subgraph cluster_level1{
        label =".NET 平台";
        fontsize=22;
        
        struct_CSharp [label="C#"];
        
        struct_Core [label=".NET Core"];
        struct_FK [label=".NET Framework"];
        
        subgraph cluster_level2{
            label ="開發框架";
            fontcolor="#009688";
            color="#009688";
            style="bold";
            
            struct_FKs 
            [label=" Console Applications \n 主控台應用程式 | <f0> ASP.NET \n 網頁框架 | <f1> ASP.NET Web API \n HTTP 服務框架 | Windows Form \n 桌面應用程式框架 | Entity Framework \n 操作資料庫 ORM 框架 " height=4];
            struct_Cores 
            [label="Console Applications \n 主控台應用程式 | <f0>ASP.NET Core \n 網頁框架 | <f1> ASP.NET Core Web API \n HTTP 服務框架 | Windows Form .NET \n 桌面應用程式框架 | Entity Framework Core \n 操作資料庫 ORM 框架 " height=4];
        }
    }
    
	struct_CSharp -> struct_FK [label="Windows 平台"];
	struct_CSharp -> struct_Core [label="跨平台"];
	struct_FK -> struct_FKs;
	struct_Core -> struct_Cores;
    
    struct_FKs:f0 -> struct_MVC [label="   " color="#2196f3"];
    struct_FKs:f1 -> struct_RESTful [color="#e91e63"];
    struct_Cores:f0 -> struct_MVC [color="#2196f3"];
    struct_Cores:f1 -> struct_RESTful [color="#e91e63"];
}
```

<br>

從上圖`開發框架`可以看出，我們能使用**資料庫框架**去讀資料，並且可藉由**主控台、網頁、Web API、桌面程式**等框架，輸出讀到的內容，或者使用**原生**的**函式庫**（.NET Framework、.NET Core），處理郵件:email:發送、操作XML、操作檔案等，甚至可以透過**第三方套件**做更多事情（產生 Word 或 Excel、動態壓縮資料、資料格式轉換等）。

<br>

以下為用 Entity Framework，取得資料的語法範例
```csharp=
class Program {
     
    static void Main(string[] args) {
        
        // 建立資料庫連接
        using (var context = new YourDbContext()) {
            
            // Linq 語法讀取資料
            var results = from r in context.YourTable
                          select r;

            foreach (var item in results) {
                Console.WriteLine("Column1: " + item.Column1);
                Console.WriteLine("Column2: " + item.Column2);
                // ...
            }
        }
    }
}
```

<br>

#### :hammer_and_wrench:兩者開發框架差異
.NET Framework 和 .NET Core 所使用的開發框架，命名上都只**差幾個單字**:sweat_smile:	（`ASP.NET`、`ASP.NET Core`），但是在程式開發的面向來看，改變就不是差幾個單字可以輕鬆帶過的，以開發環境來說，若要開發 .NET 5，就需要額外安裝 .NET 5 所需要的執行環境（[SDK](https://blog.darkthread.net/blog/install-dotnet-5-sdk/)），而要能 Run 在 IIS 上，又要安裝另一個模組（[ASP.NET Core Hosting bundle](https://learn.microsoft.com/zh-tw/aspnet/core/host-and-deploy/iis/hosting-bundle?view=aspnetcore-5.0)），才可以部署。

<br>

#### 以網頁開發框架繼續探討
在`ASP.NET`所使用的技術稱為`Web Form`（網址的後綴為`.apsx`）；而在`ASP.NET Core`則可以使用`Razor Pages`（具有更簡潔的語法和高效的性能）。

而上述不論使用哪一種技術，它們皆有提供不同風格的開發準則:smiley:	，像是 MVC、RESTful（一種軟體設計模式，定義好開發的風格、標準，讓大家去實現）。

<br>

#### C# 能做到的事情其實比你想的還多:moyai:
除了上面提到的項目外，以下列舉了我還能理解的開發項目，至於不能理解的~~改天再說吧~~：
* 微服務（gRPC、MediatR、Docker...）
軟體架構風格，將大型應用程式拆分成許多小服務，每個服務獨立運行，且可使用不同語言、資料庫、工具開發和維護
* 遊戲
* 行動應用程式
* 機器學習
* 物聯網（IoT）
* ...

<br>

#### 補充重點
* 很多事情 .NET 的底層都幫我們處理好了，以至於不用再額外造輪子，或者考慮到資安:lock:方面的防範需求，同時，在容易變動的地方給開放出來，讓我們工程師可以客製化處理問題
* 夾在這兩者間，就產生出多種模式供我們選擇，也帶來需多規則需要遵守，這個也只能靠經驗去逐一克服了
<!--* C# 與 JavaScript 相比，雖同為程式語言，但背後能處理的事情，差異是非常大的-->

<br>

---

<br>

### 資料庫<small>（**D**ata**B**ase，DB）</small>

<br>

> 一個系統如果需要儲存**長時間**存在的資料，那就把它放進資料庫裡吧!

<br>

基本上，資料庫就是用來**存放**任何內容（文字、數字、圖片...），而資料庫的存在就是為了**好管理**，日益擴大且複雜:bomb:的資料，通常會牽扯到對它的存取、修改、保護、組織等。


若以寬鬆點來定義，只要**有邏輯**的將資料存在電腦裡，都可被認為是一個資料庫，例如：EXCEL、筆記本，但這種處理方式不恰當，因為要自行設計出一套架構去存取資料，這花費的時間成本太高:money_mouth_face:，而且此架構還要能應付，當它變大後是否還那麼好用等問題。

<br>

#### 資料庫管理系統<small>（**D**ata**B**ase **M**anagement **S**ystem）</small>

還好目前市面上已有極**穩定**且功能**強大**的資料庫系統可供選擇（MS-SQL、MySQL、Oracle...），而通常講的資料庫，本質上是在講資料庫管理系統，為管理資料庫而設計的軟體。

我們所使用的 **DBMS** 為 `Microsoft SQL Server`，為微軟推出的資料庫管理系統，它有幾個主要功能，**管理資料**、**管理權限**、**控制效能**與**備份資料**等，且提供了一個有介面的管理工具 **SSMS**（SQL Server Management Studio，圖形介面整合管理工具），幫助我們管理、開發、查詢資料庫。


<br>


#### SQL<small>（**S**tructured **Q**uery **L**anguage，結構化查詢語言）</small>

用來**操作**資料庫的程式語言，透過對資料庫下達查找的**指令**，幫助我們在茫茫資料中找出我們要的資訊，又或者可下達新增、修改、刪除等指令，去針對資料做出對應的**行為**。

<br>

:dizzy_face:	**CRUD**<small class=text-muted>（**C**reate、**R**ead、**U**pdate、**D**elete，增查改刪）</small>

這四個動作為最常見的行為

```sql=
--新增一筆資料
INSERT INTO Student VALUES(1, '王小明', '國語', 95);

--查詢資料表所有內容
SELECT * FROM Student;

--針對表內的所有 "王小明" 改為 "王永慶"
UPDATE Student SET NAME='王永慶' WHERE NAME='王小明';

--刪除表內 ID 為 1 的資料
DELETE FROM Student WHERE ID=1;
```

<br>
<br>

**下面為 MS-SQL 的程式碼範例：**
建立一個學生成績的資料表，並在最後把低於60分的學生找出來
<small class="text-muted">*（輸出結果在語法下方）*</small>
<iframe height="750" style="width: 100%;" scrolling="no" title="Untitled" src="https://dbfiddle.uk/3k4-ixAM" frameborder="1" loading="lazy" allowtransparency="true" allowfullscreen="true">
</iframe>

<br>
<br>
<br>
<br>

C# 有提供另一個用來讀資料庫的框架（`ADO.NET`）可以使用

```csharp=
class Program {
    
    static void Main(string[] args) {
        
        // 資料庫連接字串
        string connString = "...";

        // 建立資料庫連接
        using (SqlConnection conn = new SqlConnection(connString)) {
            
            // 開啟連接
            conn.Open();

            // 建立 SQL 指令
            string sql = "SELECT * FROM Student";

            // 執行 SQL 指令
            using (SqlCommand command = new SqlCommand(sql, conn)) {
                //...
            }

            // 關閉連接
            conn.Close();
        }
    }
}
```

可以注意`第15行`，那個地方就是可以下 MS-SQL 語法的區塊，當然不只可以下查詢語法，其它像新增、修改、刪除皆可以在那個地方處理。

<br>

#### :nerd_face: MS-SQL 的索引
當今天查資料的過程變慢，下意識就會想到是否有**建立**索引，而索引的建立就是提升查詢速度的關鍵之一，它背後是將資料表設定索引的欄位，預先**系統化整理**過，因為已經重新排序過，所以搜尋範圍縮小，搜尋速度就會提升。

但這個系統化整理，實際上是又建立一個對應表，來提升查詢速度，所以是用**空間換取時間**:timer_clock:	，所以千萬不要一昧地建立索引。

<br>

#### 補充重點
* MS-SQL、SQLServer 這兩者都是微軟的資料庫管理系統 Microsoft SQL Server，只是命名不同
* 我們雖然 C# 和 MS-SQL 都是微軟的產品，但並不表示 C# 只能和 MS-SQL 應用，C# 當然也能使用資料庫框架，去讀別的資料庫的資料（MySQL、Oracle…）
* 當然在開發過程中，還有其他需要關注的技術，如：
    * 檢視表
    * 預存程式
    * 函式
    * Trigger
    * 交易機制
    * 備份還原
    * ...

<br>
 
---
---
---

<br>

## 開發工具

![](https://i.imgur.com/4EkYxLp.png)
用友善的圖形介面進行程式的撰寫、編譯、除錯，幫助工程師更有效地進行程式開發。

<br>

### Visual Studio　vs　Visual Studio Code

兩者皆是微軟所提供的開發工具，只是兩者在定位上有點不同。

==Visual Studio== 是 **IDE**<small class="text-muted">（**I**ntegrated **D**evelopment **E**nvironment，整合開發環境）</small>，提供軟體開發生命週期中**所有階段的處理**，包括設計、開發、測試、佈署等工具，且收集了很多開發 .NET 程式的便捷功能（MVC 框架模板、資料庫視覺化介面...）。

==Visual Studio Code== 提供的僅只是單純的**程式碼編輯器**，目標就是讓你簡單快速的撰寫程式碼，適合用於前端開發。

<br>

|                  | Visual Studio                                             | Visual Studio Code |
|:----------------:| --------------------------------------------------------- | ------------------ |
|    **跨平台**    | 只能用在 Windows、macOS                                   | 跨平台             |
|    **跨語言**    | 跨語言                                                    | 跨語言             |
|     **收費**     | 免費、付費                                                | 免費               |
|   **軟體大小**   | 約 5 GB ~ 20 GB<br>因為含有大量的 .NET 功能，會佔很大空間 | 約 40 MB ~ 70 MB   |
| **開發專案大小** | 適合中、大型專案                                          | 適合小規模的專案   |
| **啟動程式速度** | 慢                                                        | 快                 |

<br>


#### Intelligent code completion 智能感知:see_no_evil:	
早期寫程式是要開筆記本，然後將程式碼一個個字元打進筆記本中，再依純文字檔的編碼，另外儲存成程式檔案。而這過程中，你必須把語言的語法背起來，再來要每個字元都打出來，整個過程必須正確無誤，再 Run 程式時，才會成功執行。

然而開發工具提供一項功能**程式碼輔助完成工具**:heartpulse:	，解決了需要背語法的問題，只要輸入程式前面的關鍵字，後面就會出現各種與此語言相關的語法組合供選擇。而這兩個開發工具都有此功能，大大的加速程式碼的撰寫，並提高程式的開發速度。

<br>

#### 程式碼重構:speak_no_evil:	
另一個優秀的功能就是程式碼排版，若要自行注意程式碼的排版，還要刻意的去用空白健、tab 鍵處理，但使用開發工具提供的排版功能（Format），讓你不論多複雜的版面（甚至不同語言），敲打**快捷鍵**後，程式碼一樣會呈現的漂漂亮亮的。

<br>

#### DeBug:hear_no_evil:		
而我認為使用開發工具，帶來最大的好處，就是有視覺化的除錯功能，讓你可以針對有問題的地方下**斷點**，並進入其中去逐一將問題做排除。

DeBug 也是在模擬程式碼執行的過程，藉由這項功能，可以去了解不同的工程師是怎麼想、怎麼寫 code 的，活用此功能，也是工程師必備的一項能力ㄚ~~

<br>

#### 補充重點
* Visual Studio 和 .NET 是有相依性的，所以若要使用新的語法，Visual Studio 就必須跟著做升級，不然它會不懂新語法的規則而報錯
* Visual Studio 與 .NET 綁得較緊，較適合開發與 .NET 相關的程式
* Visual Studio Code 有提供較多前端的套件，在只有開發網頁時，帶來的好處較大

<br>
 
---
---
---

<br>

## 網頁伺服器

![](https://i.imgur.com/yCNHyTb.png)

是一種軟體，負責接收並回應網路上的請求，例如瀏覽器中的網頁請求。


網頁伺服器其實也是一台電腦，只是這台電腦的等級:100:	，比起一般電腦來的高，且會有一個**網頁伺服器軟體**（IIS、Apache、nginx...）。

而這台電腦有幾個特點：
* 永遠要開機運作
* 永遠要連上網路
* 永遠要有固定的 IP

<br>

#### 簡要的運作機制
1. 在瀏覽器的網址列上輸入==https://www.geosmart.tw/GSMART_MIS/Default.aspx==，按下 Enter 鍵
2. 途中經過網路上的某一台 DNS 伺服器（也是台電腦），透過用 DNS 分析網域，並前往對應到的 IP 地址（也就是 Server）
3. 到達目的地後，網頁伺服器會先檢查請求的 URL 是否有配對到現有文件
*<small class="text-muted">GSMART_MIS：站台名稱、Default.aspx：網頁文件</small>*
4. 有配對到就複製一份，回傳至來源 IP，沒有就回應 404:face_with_head_bandage:	
5. 瀏覽器收到回應後，開始渲染網頁

<br>

> 瀏覽器向伺服器發送一個某文件的請求（Request），伺服器不論有沒有找到**都會**有回應（Response），找到了檔案就按**需求**（取得資料庫資料、或對資料進行一些加工）去處理，而未找到就會噴錯誤訊息給瀏覽器（404 Not Found）。

<br>
<br>


### IIS<small>（**I**nternet **I**nformation **S**ervices，網際網路資訊服務）</small>

![](https://i.imgur.com/uk1C5ch.png)

是一個支援 HTTP 協議、FTP 協議的網頁伺服器，這也是由微軟開發的軟體，且使用在 Windows 平台上，並提供豐富的圖形化介面可操作，常用於網頁架設、檔案傳輸、電子郵件等。

<br>

### 選擇 IIS 當 Web Server 的因素
基本上，自家的產品不打自家人:baby:	，我們從後端程式語言、資料庫、開發工具、作業系統，都選擇了微軟的產品，一方面是較熟悉 Windows 的操作環境、模式；另一方面則是因為，大家都是同個媽生的，**相容性**通常比其他家公司的產品還要好（*其他家的當然也可以用，只是比較麻煩*）。

從瀏覽器發出請求到回應，在 IIS 上都能有良好的控制權可以介入，而與其它網頁伺服器相比，IIS 在 Windows 平台下是最簡單好用的伺服器。

<br>

### IIS 常用的功能
* 建立應用程式集區（藉由獨立的 Session，去區分站台內的使用者）
* 建立多個網站站台
* 建立虛擬目錄
* 繫結憑證
* 支援負載平衡

<br>

### 內建不同的模組，提供不同的功能
* **Requset Filtering 要求過濾**
針對副檔名、HTTP 方法、Header 大小，做阻擋:no_entry:	
* **Default Document 預設文件** 
當只有輸入預設網址，會跑當初設定的檔案名稱
* **Directory Browsing 瀏覽目錄** 
當訪問任一個路徑，該路徑下沒有預設頁面，就會顯示為目錄樣式（通常會關掉）
* **Error Pages 錯誤網頁** 
當遇到 HTTP Error 要顯示的頁面
* **Dynamic IP Restriction IP位址及網域限制**
限制:shield:同一 IP 的同時最大連線數，或是時間內的連線數最多能有幾個
* ...


<br>
<br>


> 簡單來說，通過在 IIS 介面上的操作，可以輕鬆的達到一些效果，例如：AD 驗證、設定 SSL 或 Log 等機制

<br>
<br>

#### 補充重點
* 通常網頁伺服器分為軟體與硬體，軟體是我們可控制的部分，而以硬體會由第三方廠商負責，所以調校系統效能，在工程師範圍，只能進行 Code Review 去針對耗效能的 Code 做改寫
* 通常一個新開的 VM，都要先安裝 .NET Framework，再去安裝 IIS，之後才有辦法架站

<br>
 
---
---
---

<br>

## 版本管控

![](https://i.imgur.com/GW9g8kQ.png)

透過有效的管控，能記錄專案內各個版本的改動，並為每次改動編上序號。

<br>

### 為什麼版本需要管控
假設 A 有一份**燈會專案**，需要 B 協助撰寫

```sequence
Note left of A: 燈會專案_1.0
A->B: 哈摟，你好\n麻煩請你填寫某區塊的可行性
Note right of B: B 撰寫中
B-->A: 燈會專案_1.1
Note left of A: A 獲得一份，燈會專案_1.1
Note right of A: 過了一陣子後\n專案格式有變，需要 B 再次協助撰寫
Note left of A: 目前專案版本為\n燈會專案_2.0
A->B: 燈會專案_2.0\n
Note right of B: B 撰寫中
B-->A: 燈會專案_2.1
Note left of A: A 獲得一份，燈會專案_2.1
Note right of B: B 發現有寫錯，在重丟一份
B-->A: 拍謝\n燈會專案_2.1(改)
Note left of A: A 獲得一份，燈會專案_2.1(改)
```

可以發現，因為當下可能為小幅度的修改，而檔案命名就產生了不同的風格（==燈會專案_2.1== -> ==燈會專案_2.1(改)==）。

<br>

上面例子是個簡單的例子，實務上經過**長時間**不同**人**:raising_hand:	不斷的**修改**，到最後你的資料夾的版本線可能就會呈現一團亂，無法區分版本線，以及此版是誰改的，更別提要比對差異了。

<br>

> 現實中可能會出現的狀況...

![](https://i.imgur.com/gYNR0hY.png)
[圖片來源](https://backlog.com/git-tutorial/tw/intro/intro1_1.html)

<br>

:heavy_check_mark:	而這種用人工方式來管理文件版本，似乎不是個好辦法，這就是為什麼需要使用**版本管控系統**的其中一種原因。

<br>
<br>

### SVN<small>（**S**ub**V**ersio**N**）</small>
是一個開放原始碼的版本管理系統，用於管理開發過程中程式碼的變，它是一個**集中式版本管控系統**，意即所有的版本紀錄都放在某台電腦上，供所有有權限的開發人員做存取。

```graphviz
digraph 集中式版本管控系統 {
    node [shape=box]
    "SVN Server"->{"Computer A" "Computer B" "Computer C"}
}
```
*<small class="text-muted">此架構下，使用者將會透過 Server 的 URL（需要連線），在檔案總管內取得版本。</small>*

<br>

它也有提供一套圖形化介面的軟體（TortoiseSVN），在 Windows 平台上使用，與檔案總管整合，可透過在目錄上按右鍵選單，即可完成「SVN」的操作。

![](https://i.imgur.com/RzPFyTl.png)

<br>

### SVN 的特色
* 每次的提交（Commit）都會紀錄在版控上，並有自己的**版本碼**（不用手動編號）
* 可以知道是**誰**有做過新增、修改、刪除
* 可以做到簡單的**權限管控**
* 可以**比較**各版本之間的程式碼、文件有何差異
![](https://i.imgur.com/Xdn1xI2.png)
*<small class="text-muted">紅色字體為 word 新增的文字，下方為 SVN 版本差異的視窗</small>*
* 可以**回溯**到之前的任何版本

<br>

<!--### 實際執行面的過程
模擬從頭到尾的演練
順帶提到每次都要update取得最新版
<br>
-->


#### 補充重點
* 因為只有放在一台電腦上，當它出現什麼意外，就會損失慘重，所以要固定做備份
* Server 的空間，決定了 SVN 能存放資料的容量
* 因為是集中式管理，當一個人做完任何操作提交後，與此專案版本有關的人都得進行同步，否則版本將會出錯

<br>

---
---
---

<br>

## :crown:	總結
一個動態網頁的專案從開始到完成的生命週期，開發歷程大概會是這樣：
1. 決定做什麼類型的案子，了解一下資料面的內容、專案架構等
*<small class="text-muted">靜態網頁、動態網頁、資料再哪、形象網站還是地圖網站...</small>*
2. 決定是否要用「RWD」
3. 選擇「.NET Framework」或「.NET Core」
*<small class="text-muted">是否要跨平台</small>*
4. 使用「Visual Studio」開發程式
*<small class="text-muted">是否要用 .NET 的框架</small>*
5. 建立該專案的「SVN」版控
*<small class="text-muted">不論自己或多人協作，有個版本依據，當意外發生時，才不會出意外</small>*
6. 產生網頁框架（`ASP.NET`）的模板:dart:	
*<small class="text-muted">此模板可以在 .NET 的體系下，開發前、後端</small>*
7. 結合前端的技術「HTML」、「CSS」、「JavaScript」、「jQuery」、「Bootstrap」開發網頁
8. 後端則先規劃「MS-SQL」要開的表、欄位、設計關聯等
9. 並用「C#」撰寫核心邏輯
*<small class="text-muted">資料庫串接、資安防範、前端輸入驗證等</small>*
10. 經過反覆測試，直到確認完畢:fire:	
*<small class="text-muted">功能是否正常、基本資安防範、程式碼的重構、效能的改善</small>*
11. 最後部署到 IIS 上
*<small class="text-muted">確認是否有憑證需要安裝，有沒有負載平衡等</small>*

<br>

不同的專案類型（或甲方特別要求），所使用的技術都不太一樣

這就是一個專案的程式開發會 RUN 的過程，不過每位工程師的先後順序可能不太一樣，但這每一項基本上都會經歷過。

<br>


而前面只要決定好使用的技術後，後面就是考驗工程師的能力，是否能根據需求、規格開發出好維護、好擴充的程式碼，甚至會運用一些[**設計模式**](https://ithelp.ithome.com.tw/articles/10201706):mage:	去撰寫程式碼，期望能達到當需求與先前不同時，可以簡單快速的修改完成。

<br>

> 從 A 規則替換為 B 規則時，因為程式設計得當，所以比別人更快完成:zap:	

<br>
<br>
<br>

**<div class="text-center">介 紹 完 畢 ~ ~</div>**

<br><br><br>

:link: 參考
---
**前端資源**
[HTML](https://zh.wikipedia.org/zh-tw/HTML)
[HTML5](https://zh.wikipedia.org/zh-tw/HTML5)
[CSS](https://zh.wikipedia.org/zh-tw/%E5%B1%82%E5%8F%A0%E6%A0%B7%E5%BC%8F%E8%A1%A8)

**C#資源**
[維基百科C#](https://zh.wikipedia.org/zh-tw/C%E2%99%AF#%E8%AA%9E%E8%A8%80%E7%89%B9%E6%80%A7)
[C# 介紹](https://ithelp.ithome.com.tw/articles/10213175)
[淺談 C# 與 .NET](https://ithelp.ithome.com.tw/articles/10199526)
[.NET Framework 底層怎麼執行](https://ithelp.ithome.com.tw/articles/10287290)
[.NET Core vs .NET Framework](https://ithelp.ithome.com.tw/articles/10291631)
[.NET 5.0 亮點整理](https://blog.darkthread.net/blog/net5-highlight/)
[.NET 基本介紹~推](https://huier23.medium.com/net-%E6%96%B0%E6%89%8B%E6%9D%91-%E6%89%93%E4%BB%80%E9%BA%BC%E6%89%93-%E8%A6%81%E6%89%93%E5%8E%BB%E7%B7%B4%E8%88%9E%E5%AE%A4%E6%89%93-6da64ae1d61a)

**資料庫資源**
[什麼是資料庫](https://tw.alphacamp.co/blog/database-intro)
[維基百科資料庫](https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93#%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F)

**開發工具**
[維基百科Visual Studio](https://zh.wikipedia.org/zh-tw/Microsoft_Visual_Studio)
[維基百科Visual Studio Code](https://zh.wikipedia.org/zh-tw/Visual_Studio_Code)
[兩者區別](https://worktile.com/kb/ask/9303.html)
[純文字檔](http://kaiching.org/pydoing/cs-guide/unit-01-understanding-the-c-sharp-programming-language.html)

**網頁伺服器**
[mdn 網頁伺服器](https://developer.mozilla.org/zh-TW/docs/Learn/Common_questions/What_is_a_web_server)
[IIS](https://ithelp.ithome.com.tw/articles/10291454)

**版本管控**
[連猴子都能懂的Git入門指南](https://backlog.com/git-tutorial/tw/intro/intro1_1.html)
[版本控管vcs-基礎概念，svn、git比較](https://stevenjhu.com/2019/11/11/%E7%89%88%E6%9C%AC%E6%8E%A7%E7%AE%A1vcs-%E5%9F%BA%E7%A4%8E%E6%A6%82%E5%BF%B5%EF%BC%8Csvn%E3%80%81git%E6%AF%94%E8%BC%83/)
[IT 關於SVN(Subversion) 版本控制系統](https://ithelp.ithome.com.tw/articles/10285213)
[Subversion 版本控制系統的基礎觀念](https://www.huanlintalk.com/2009/04/introduction-to-version-control-system.html)


<br><br><br><br><br><br>

<style>
    code.red {
        color: #e91e63 !important;
        font-size: 1.6rem !important;
    }
    code.blackred{
        color:#900000 !important;
        font-size: 1.6rem !important;        
    }
    code.blue {
        color: #337AB7 !important;
        font-size: 1.6rem !important;
    }
    code.orange {
        color: #F7A004 !important;
        font-size: 1.6rem !important;
    }
    .markdown-body p > code {
        color: #c7254e !important;
        background-color: #f9f2f4 !important;
        border-radius: 4px !important;
        padding: 2px 4px !important;
        font-size: 90% !important;
    }
    .markdown-body pre {
        background-color: #112648;
    }
    .markdown-body pre,
    .markdown-body pre .code .hljs-tag {
        color: #eee;
    }
    img:not(.emoji) {
        padding: 5px;
        background: #ffffff;
        border: 1px solid #eeeeee;
        -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);
        -webkit-box-shadow: 1px 1px 5px rgb(0 0 0 / 10%);
        box-shadow: 1px 1px 5px rgb(0 0 0 / 10%);
        margin: 5px 0;
    }
    .markdown-body .alert hr {
        height: 1px;
        margin: 8px 0 15px 0;
        background-color: #31708f;
    }
    .markdown-body .alert h3,
    .markdown-body .alert h4 {
        margin: 0px;
    }
    .markdown-body blockquote > p {
       /* background-color: #f5f5f5;*/
    }
    .markdown-body strong {
       font-size: 2rem;
    }
    /*程式碼等於符號的顏色*/
    .token.operator {
        background: #102546;
    }
</style>


