---
# System prepended metadata

title: JAVA面試題目

---

# JAVA面試題目

<style>
.title {
  color: #FF5809;
}
.subTitle {
    color: #8600FF;
}
</style>

<details>
<summary class="title">JAVA</summary>

<details>
<summary class="subTitle">Set、List、Map的差別
</summary>
Java 集合主要分為三種類型：
Set、List、Map
    
**Set 是最簡單的一種集合。集合中的物件不按特定的方式排序，並且沒有重復物件。**(無序不重複)
    
分成:
**HashSet 按照哈希算法來存取集合中的物件，存取速度比較快。**
**TreeSet 實現了 SortedSet 介面，能夠對集合中的物件進行排序**

List的特征是其元素以線性方式存儲，集合中可以存放重復物件。(有序可重複)

List介面主要實現類包括：
ArrayList 代表長度可以改變得陣列。可以對元素進行隨機的訪問，向 ArrayList() 中插入與刪除元素的速度慢。
LinkedList 在實現中采用鏈表數據結構。插入和刪除速度快，訪問速度慢。
    
Map 是一種把鍵物件和值物件映射的集合，它的每一個元素都包含一對鍵物件和值物件。 Map 沒有繼承於 Collection 介面從 Map 集合中檢索元素時，只要給出鍵物件，就會返回對應的值物件。
    
HashMap    
Map 基於散列表的實現。插入和查詢“鍵值對”的開銷是固定的。可以通過構造器設置容量 capacity 和負載因子 load factor，以調整容器的性能。HashMap 就是使用物件的 hashCode() 進行快速查詢的。此方法能夠顯著提高性能。
TreeMap
基於紅黑樹數據結構的實現。查看“鍵”或“鍵值對”時，它們會被排序(次序由 Comparabel 或 Comparator 決定)。TreeMap 的特點在 於，你得到的結果是經過排序的。TreeMap 是唯一的帶有 subMap() 方法的 Map，它可以返回一個子樹。
</details>

<details>
<summary class="subTitle">ArrayList 與LinkedList的差別</summary>
當我們需要頻繁的取得List內的資料時，使用ArrayList的效率較好，
因為它的資料結構是array，array採用隨機存取(random access)的方式，
也就是直接透過索引(Index)，取得值。 
而LinkedList要取得值必須從開始的節點一路搜尋到要需要的值的位址，需要花費大量的時間。

當我們需要頻繁的新增資料與刪除資料時，
使用LinkedList較好。因為使用LinkedList新增/刪除資料時，
**只要改動被新增/刪除的那筆資料前面一個節點所指向的位址及可**。
但若使用ArrayList，要新增或刪除array的資料，新增/刪除結束後，
需要重新搬動剛才被新增/刪除之後的所有節點，
並且重新給定之後所有節點的索引值，因此效率會較差。
</details>

<details>
<summary class="subTitle">HashSet和TreeSet</summary>
HashSet:
    
HashSet有以下特點
不能保證元素的排列順序
使用Hash算法來存儲集合中的元素，有良好的存取和查找性能
非同步，多線程併發要注意線程同問題
集合元素值可爲null
通過equal()判斷兩個元素是否相等，並兩個元素的hashCode()返回值也相等
    
---
    
TreeSet類
是SortedSet接口的實現類，根據元素實際值的大小進行排序
採用紅黑樹的數據結構來存儲集合元素
非同步
支持兩種排序方法：自然排序（默認情況）和定製排序。前者通過實現Comparable接口中的compareTo()比較兩個元素之間大小關係，然後按升序排列；後者通過實現Comparator接口中的compare()比較兩個元素之間大小關係，實現定製排列。
    
最重要：

1、TreeSet 是二元樹實現的,Treeset中的數據是自動排好序的，不允許放入null值。

2、HashSet 是哈希表實現的,HashSet中的數據是無序的，可以放入null，但只能放入一個null，兩者中的值都不能重複，就如數據庫中唯一約束。

3、HashSet要求放入的對象必須實現HashCode()方法，放入的對象，是以hashcode碼作爲標識的，而具有相同內容的 String對象，hashcode是一樣，所以放入的內容不能重複。但是同一個類的對象可以放入不同的實例 。

---
    
紅黑樹:自平衡二元搜尋樹
樹上的每個節點 (node) 只能是紅色或黑色
根節點 (root) 一定要是黑色
葉節點 (leaf) 一定要是黑色的空值 (NULL)
紅色節點的兩個子節點 (child) 一定要是黑色 (亦即不能有兩個紅色節點相連，注意：黑色節點的子節點顏色沒有限制)
從任何節點出發，其下至葉節點所有路徑的黑色節點數目要相同
滿足上述規則的二元樹，相比一般的二元樹更能保持平衡性，往後套用二元樹的算法來查找資料時能更快速、方便地到達目的地，套用運算的時間複雜度為 O(log n)，這是因為紅黑樹保證最長路徑不會超過最短路徑的兩倍。

左子樹上所有的節點的值均小於或等於他的根節點的值

右子樹上所有的節點的值均大於或等於他的根節點的值

    
兩項基本運算可以用來幫助調整樹狀結構以滿足紅黑樹的規則，這兩個運算分別為變色與旋轉 (左旋、右旋)。

所有新增的節點預設都是紅色
</details>
    
<details>
<summary class="subTitle">HashMap和TreeMap</summary>


TreeMap 是一個有序的key-value集合，它是通過紅黑樹實現的。
HashMap：適用於在Map中插入、刪除和定位元素。
Treemap：適用於按自然順序或自定義順序遍歷鍵(key)。
</details>    

<details>
<summary class="subTitle">== 和 equal的差別</summary>

- [== 和 equal的差別1](https://www.delftstack.com/zh-tw/howto/java/java-string-equals-vs-/)
- [== 和 equal的差別2](http://puremonkey2010.blogspot.com/2010/07/java-java-equals.html)
- [在字串中 == 和 equal的差別3](https://openhome.cc/Gossip/Java/InsideString.html)
- [Java中「equal「與「==「聯絡和區別的總結](https://tw511.com/a/01/27138.html)
- [Java String Pool 字串池，使用 == 比較兩個String是否相等](https://matthung0807.blogspot.com/2019/06/java-string-pool-string.html)
</details>

<details>
<summary class="subTitle">基本資料型態和Wrapper類別</summary>

- [基本資料型態和Wrapper類別](https://ithelp.ithome.com.tw/articles/10227404?sc=rss.iron)
- [Wrapper Classes 與 Primitive Data Type](http://marsping.blogspot.com/2008/08/java-wrap-autoboxing-unboxing.html)  
- [基本資料型態共有八種](http://kevin.hwai.edu.tw/~kevin/material/JAVA/PrimitiveDataType.htm)

整數範圍: -2147483648~2147483647
</details>    

<details>
<summary class="subTitle">String、StringBuffer和StringBuilder的比較</summary>

- [String、StringBuffer和StringBuilder的比較](https://www.itread01.com/content/1548164730.html)
</details>

<details>
<summary class="subTitle">Override(覆寫) & Overload(多載) &Polymorphism(多型)的差異</summary>

- [Override(覆寫) & Overload(多載) &Polymorphism(多型)的差異](https://medium.com/@c824751/override-%E8%A6%86%E5%AF%AB-overload-%E5%A4%9A%E8%BC%89-polymorphism-%E5%A4%9A%E5%9E%8B-%E7%9A%84%E5%B7%AE%E7%95%B0-3de1a499de29)
</details>



</details>

<details>
<summary class="title">JVM</summary>

- [JDK、JRE、JVM是什麼關係](https://iter01.com/574266.html)
JDK>JRE>JVM
    
- [JVM 的 Stack 和 Heap](https://blog.marklee.tw/java-interview-jvm-stack-heap/)
</details>



<details>
<summary class="title">Serverlet</summary>

<details>
<summary class="subTitle">Serverlet的生命週期</summary>

- [Servlet 生命週期](http://www.w3big.com/zh-TW/servlet/servlet-life-cycle.html)

Servlet通過調用init ()方法進行初始化。
Servlet調用service()方法來處理客戶端的請求。
每次服務器接收到一個Servlet 請求時，服務器會產生一個新的線程並調用服務。 service() 方法檢查HTTP 請求類型（GET、POST、PUT、DELETE 等），並在適當的時候調用doGet、doPost、doPut，doDelete 等方法。
Servlet通過調用destroy()方法終止（結束）。
最後，Servlet 是由JVM 的垃圾回收器進行垃圾回收的。
    
</details> 


</details>

<details>
<summary class="title">Maven</summary>
    
<details>
<summary class="subTitle">Maven的生命週期</summary>

- [Maven的生命週期](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/91049/)
- [Maven的生命週期2](https://medium.com/learning-from-jhipster/1-maven%E7%9A%84%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F-phase-plugin-goal-d69a2591dc45)
    
Maven的生命週期分為互相獨立的三部分，分別是clean,default,site。
而每一個週期又包括若干階段。

1. clean:用於清理專案，分為3個階段(phase)
2. default:用於構建專案，分為23個階段
3. site:用於建立專案站點，分為4個階段

在呼叫maven的階段時，會順序執行本週期當前階段之前的所有階段，直至當前階段。

$ mvn deploy
    
則maven就會依照下方的順序開始執行：
**validate**：檢查專案是否為正確的專案以及確定是否所有必需的資訊都有符合或都為正確資訊。
**compile**：編譯專案的原始程式碼。
**test**：透過一些單元測試的框架來執行測試。
**package**：將編譯完成後的內容打包成被指定的格式，例如.jar或.war。
**verify**：檢查測試結果，以確保專案的品質
**install**：將打包後的結果安裝在本地端的maven repository，供其他本地端的專案導入使用。
**deploy**：在本地端(建構環境)中完成建構並確任沒有錯誤發生後，就會將打包後的結果上傳到遠端的maven repository供全世界的人使用。

</details>
    
</details>

<details>
<summary class="title">MVVM架構</summary>

- [MVVM架構](https://medium.com/ken-do-everything/mvvm-%E6%9E%B6%E6%A7%8B%E7%AF%87-%E6%9B%B8%E8%AE%80%E5%BE%97%E5%A4%9A-%E4%BA%BA%E8%87%AA%E7%84%B6%E5%B0%B1%E5%A5%BD%E7%9C%8B%E8%B5%B7%E4%BE%86-4fd595581e7f)
- [MVVM架構2](https://ithelp.ithome.com.tw/articles/10192829)

M - V - X 的架構
M - V - X 的架構中，把程式分成三個層級，分別有各自的職責。
V：View — 負責定義和顯示使用者介面，並接受使用者的操作。
M：Model — 負責處理和資料有關的事務，包括獲取資料和儲存資料。
X：通常在 View 和 Model 間扮演橋樑的角色。

MVC (Model — View — Controller)
MVC 架構中的 M 和 V 就是上面提到的 Model 和 View，而 C 指的是 Controller，負責接收來自 View 的事件，和操作 Model 處理資料。
    
MVP (Model — View — Presenter)
P 是 Presenter，負責擔任 View 與 Model 之間的橋樑。一個 Presenter 一般只對應到一個 View。
和 MVC 不同的地方是，View 和 Model 不直接互動，完全透過 Presenter 來進行溝通，成為兩個獨立的單元。

MVVM (Model — View — ViewModel)
MVVM 中的 VM 指的是 ViewModel，一樣負責接收從 View 傳來的使用者操作事件，並使用 Model 提供的方法來處理資料。
最主要的差異在於由數據來驅動 View 的更新，當資料改變時，UI 自動更新（一般用觀察者模式實現）。
ViewModel並不使用callback的方式來通知View，而是用Observer pattern的概念，由View來訂閱(subscribe)ViewModel中它要的資料，並在資料異動時才更新UI，因此，MVVM都會搭配如Data Binding等library來實現Observer pattern。

Observer Pattern（觀察者模式）是屬於設計模式中Behavioral Pattern（行為模式）。當物件(object)間的有一對多(one-to-many)關係時，可利用Observer Pattern來設計。

例如當一個物件的狀態(state)發生變化時，希望所相依的所有物件都可以自動收到通知的狀況。
通常會以現實生活中讀者(Reader)訂閱新聞(News)的例子來解釋Observer Pattern。訂閱新聞時，讀者不用隨時主動地去檢查是否有新的新聞，因為這樣太麻煩了，比較聰明的方法是當有新的新聞時，新聞會自動通知所有訂閱的讀者。在訂閱新聞的例子中，讀者就是Observer，新聞就是Observable，有很多的讀者訂閱某一新聞，所以是一對多關係。

</details>

<details>
<summary class="title">Spring Boot</summary>

# **什麼是Spring Boot**

Spring Boot其設計目的是用來簡化Spring應用的建立、執行、除錯、部署等。使用Spring Boot可以做到專注於Spring應用的開發，而無需過多關注XML的配置。

Spring Boot 的特色:
1.可獨立執行的Spring專案：Spring Boot可以以jar包的形式獨立執行。

2、 內嵌的Servlet容器：Spring Boot可以選擇內嵌Tomcat、Jetty或者Undertow，無須以war包形式部署專案。

3、 簡化的Maven配置：Spring提供推薦的基礎 POM 檔案來簡化Maven 配置。

4、 自動配置Spring：Spring Boot會根據專案依賴來自動配置Spring 框架，極大地減少專案要使用的配置。

5、 提供生產就緒型功能：提供可以直接在生產環境中使用的功能，如效能指標、應用資訊和應用健康檢查。

6、 無程式碼生成和xml配置：Spring Boot不生成程式碼。完全不需要任何xml配置即可實現Spring的所有配置。
</details>

<details>
<summary class="title">JDBC</summary>

總結：JDBC是訪問資料庫的一種通用的訪問機制，記住六個步驟：

1.裝載資料庫驅動

2.建立連線

3.建立Statement物件

4.建立ResultSet物件執行SQL語句

5.處理結果集

6.釋放資源（先建立後釋放，後建立先釋放）

---
1.裝載資料庫驅動
```java=\
//以mysql為例
Class.forName("com.mysql.jdbc.Driver");
```
2.建立連線
```java=\
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "lvzhiqi*****";
Connection conn = DriverManager.getConnection(url,username,password);
//url為："jdbc:mysql://localhost:3306/資料庫名"
//username為：root（資料庫名稱，一般本地資料庫名都為root）
//password為：資料庫密碼
```
3.建立Statement物件
```java=\
Statement state = conn.createStatement();
```
4.建立ResultSet物件執行SQL語句
```java=\
String sql = "sql語句"
ResultSet rs = state.executeQuery(sql);
```
5.處理結果集
```java=\
while(rs.next()){
 	rs.getString(1);//1代表在資料庫表種列的位置
	rs.getString(2);
 	rs.getString(3);
 }
```
6.釋放資源
```java=\
//先建立後釋放，後建立先釋放
try{
    if(rs!=null){
        rs.close();
    }
    if(state!=null){
        state.close();
    }
    if(conn!=null){
        conn.close();
    }
}
```
</details>

<details>
<summary class="title">N個正整數的最大公因數和最小公倍數</summary>

[[Java]如何求N個整數的最大公因數](https://gn00466269.pixnet.net/blog/post/46545498)
    
**最大公因數使用輾轉相除法來求，
最小公倍數則由這個公式來求：GCD * LCM = 兩數乘積**
 
接下來三個整數的最大公因數就是將前兩個最大公因數跟第三個數字做最大公因數
四個整數的最大公因數則是將三個整數的最大公因數與第四個數字做最大公因數...
以此類推
    
```java=\
package practice;

public class GCD {

    public static void main(String[] args) {
        int m = 12;
        int n = 54;
        int gcd = gcd(m,n);
        System.out.println("最大公因數:"+gcd);
        
        System.out.println("最小公倍數:"+(m*n/gcd));
        
        
        int[] num = {4,12,36};
        
        
        int LCM = 1;
        for(int i=0;i<num.length;i++) {
            LCM = num[i]*LCM;
            System.out.println("LCM"+LCM);
        }
        int GCD = doGCD(num);
        System.out.println("最大公因數:"+GCD);
        System.out.println("最小公倍數:"+(LCM/GCD));
      }
      
      //while寫法
      public static int gcd(int m,int n) {
          if(m == 0 || n == 0) {
              System.out.println("必須為大於0的正整數!");
              return 0;
          }
          
          if(m<n) {
              int temp = m;
              m = n;
              n = temp;
          }
          
          int gcd = n;

          while(m%n != 0) {
              gcd = m%n;
              
              if(gcd == 1) {
                  break;
              }else {
                  m = n;
                  n = gcd;
              }
          }
          
          return gcd;
      }
      
      //遞迴寫法
      public static int gcd2(int m ,int n) {
          if(m == 0 || n == 0) {
              System.out.println("必須為大於0的正整數!");
              return 0;
          }
          
          if(m < n) {
              int temp = m;
              m = n;
              n = temp;
          }
          
          if(m%n == 0) {
              return n;
          }else {
              return gcd(n,m%n);
          }
      }

      public static int doGCD(int[] num) {
          for(int i=0;i<num.length-1;i++) {
              num[i+1] = gcd(num[i], num[i+1]);
          }
          
          return num[num.length-1];
      }
}

```
</details>

<details>
<summary class="title">費式數列</summary>

費氏數列範例：
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.....

從以上數列可以觀察到，從第三個數字開始，其值為前兩個數字的相加。

```java=\
package practice;

public class Fibonacci {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(fibonacci2(6));
    }

    //用for迴圈解
    public static long fibonacci(int n) {
        long[] fib = new long[n];
        
        fib[0] = 1;
        if(n > 1) {
            fib[1] = 1;
            
            for(int i=2; i<n ; i++) {
               fib[i] = fib[i-1] + fib[i-2]; 
            }
        }
        
        return fib[n-1];
    }
    
    //用遞迴寫
    public static long fibonacci2(int n) {
        if(n == 1 || n == 2) {
            return 1;
        }else {
            return fibonacci2(n-1) + fibonacci2(n-2);
        }
    }
}

```
</details>

<details>
<summary class="title">氣泡排序法</summary>
Bubble Sort (泡沫排序)是一種簡單的排序演算法。
它重複地走訪過要排序的數列，一次比較兩個元素，如果他們的順序錯誤就把他們交換過來。
走訪數列的工作是重複地進行直到沒有再需要交換，也就是說該數列已經排序完成。

Bubble Sort (泡沫排序)可以原地排序。盡管這個演算法是最簡單瞭解和實作的排序演算法之一，但它對於包含大量的元素的數列排序是很沒有效率的。

泡沫排序演算法的運作如下：

比較相鄰的元素。如果第一個比第二個大，就交換他們兩個。
對每一對相鄰元素作同樣的工作，從開始第一對到結尾的最後一對。這步做完後，最後的元素會是最大的數。
針對所有的元素重複以上的步驟，除了最後一個。
持續每次對越來越少的元素重複上面的步驟，直到沒有任何一對數字需要比較。
    
```java=\
package practice;

public class BubbleSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] num = {2,6,3,9,0,5,3};
        bubbleSort(num);
    }

    public static void bubbleSort(int[] num) {
        int temp;
        
        for(int i=0;i<num.length;i++) {
            for(int j=0; j<num.length-i-1;j++) {
                if(num[j]>num[j+1]) {
                    temp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = temp;
                }
            }
            printArray(num);
        }
    }
    
    public static void printArray(int[] num) {
        for(int i=0;i<num.length;i++) {
            System.out.print(num[i]+" ");
        }
        System.out.println();
    }
}
最佳情況：T(n) = O(n)   最差情況：T(n) = O(n2)   平均情況：T(n) = O(n2)

```
</details>

[十大經典排序演算法最強總結（含JAVA程式碼實現）](https://iter01.com/16751.html)
[[Java] 取得使用者輸入 Scanner](https://www.dotblogs.com.tw/freedom42408/2013/11/20/130586)
[Design Patterns(設計模式) 自我整理](https://jimmy0222.pixnet.net/blog/post/37095632)
[Java 設計模式 單例模式 Singleton Pattern](https://matthung0807.blogspot.com/2018/02/java-singleton.html)
[深入理解Spring兩大特性：IoC和AOP](https://kknews.cc/zh-tw/code/e526e4q.html)

**Spring是一個輕量級的控制反轉（IoC）和面向切面編程（AOP）的容器框架。**

為降低java開發的複雜性，Spring採取了以下四種關鍵策略：
    1.基於POJO的輕量級和最小入侵性程式設計
    2.通過依賴注入和面向介面實現鬆耦合
    3.基於切面和慣例進行宣告式程式設計
    4.通過切面和模板減少樣板式程式碼
    
---
有彙總函數  count、sum、avg（平均值）、max（最大值）、min 時, 可以用group by或子查詢來使用,如果要進一步針對彙總函數來過濾,就要用having 
    
SELECT s.Name, SUM(c.Score) AS Score 
FROM Student s left join Score c
on s.id = c.StudentID
GROUP BY s.Name
HAVING SUM(c.Score) > 100

---
spring MVC 生命週期

（1）用戶發送請求至前端控制器DispatcherServlet； 
（2） DispatcherServlet收到請求後，調用HandlerMapping處理器映射器，請求獲取Handle；
（3）處理器映射器根據請求url找到具體的處理器，生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet； 
（4）DispatcherServlet 調用 HandlerAdapter處理器適配器； 
（5）HandlerAdapter 經過適配調用 具體處理器(Handler，也叫後端控制器)； 
（6）Handler執行完成返回ModelAndView； 
（7）HandlerAdapter將Handler執行結果ModelAndView返回給DispatcherServlet； 
（8）DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器進行解析； 
（9）ViewResolver解析後返回具體View； 
（10）DispatcherServlet對View進行渲染視圖（即將模型數據填充至視圖中） 
（11）DispatcherServlet響應用戶。
   
[spring MVC 生命週期](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/311438/)
[spring MVC 生命週期2](https://read01.com/zh-mo/J8jL4zz.html#.YgCt9OpBw2w)
[spring MVC 生命週期 英文版](https://www.fatalerrors.org/a/spring-mvc-introduction-spring-mvc-life-cycle.html)
    
---

SQL隱碼攻擊(SQL INJECTION ATTACK)
藉由在輸入字串中夾帶惡意指令，試圖改變SQL語法上的邏輯，得以非法破壞、入侵資料庫伺服器，例如竊取使用者機密資料，帳戶資料，密碼等，
    
SQL語法的註解
註解是SQL使用者寫下的註記，資料庫伺服器會自動略過註解後的文字不會執行，註解符號視資料庫版本而有所差異，常見有以下三種：
```
/*
--
#
```
這裡要特別注意，使用--註解符號後面要記得空一格，空白之後再輸入註解文字，否則有些版本的資料庫會報錯
範例1-非法登入網站
首章提及資料庫會自動忽略註解的文字，以下範例說明駭客如何利用註解特性來通過帳密驗證機制以非法登入網站。
一個具備會員登入系統的網站，後端程式(如PHP語言)會驗證表單的帳號及密碼的正確性，以判斷該User是否為合法的會員。一個簡單直觀的SQL語法如下：
SELECT * FROM members WHERE account='$name' AND password='$password'
如果只在帳號輸入欄位輸入「' or 1=1 /*」，SQL語法會變成：
SELECT * FROM members WHERE account=’’ OR 1=1 /*’ AND password=’’
其中WHERE後面的條件判斷， account='' or 1=1 ，因為1=1數學式恆等，該判斷式永遠會成立，而/*是註解符號，意味程式會忽略後面的文字，因此該SQL語法實際效果如下：
SELECT * FROM members WHERE account='' or 1=1
藉由在字串中夾帶特殊字元，便可以改變SQL語法邏輯進而登入網站。

範例2-非法取得資料庫內容
SQL injection除了發生在登入表單的場景，也可能發生在網頁的參數上，以UNION聯集方式取得資料庫內容。
比方說，在經營部落格的讀者可能會發現，你的網頁網址會有如下的格式:
http://example.com/blog/post/1
「post/」後面的數字1，即是該篇貼文專屬的ID。後端程式解析GET Method的參數取得該獨一無二的ID，便能透過SQL語法，在資料庫檢索出吻合該ID的相關欄位資訊，像是文章標題、作者、內文等。
假設資料表名稱為BLOGPOSTS，後端SQL語法大致如下：
SELECT author,title,content FROM BLOGPOSTS where id=$id
駭客如果將id參數，設為
0 UNION SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
後端接收的SQL語法將變成：
SELECT author,title,content FROM BLOGPOSTS where id=0 UNION SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
因此，只要UNION中的SELECT敘述欄位數量一致，就是合法的SQL語法，便能獲取資料庫的INFORMATION_SCHEMA(資訊結構描述)中的相關訊息，掌握這些訊息，將有利駭客進行更深入的攻擊。

[SQL injection](https://bingchengqiu.medium.com/sql-injection%E5%8E%9F%E7%90%86%E5%8F%8A%E7%AF%84%E4%BE%8B-74d90d7e8962)
    
[SQL injection2](https://ithelp.ithome.com.tw/articles/10240102?sc=iThelpR)
    
---
    Cross-site scripting (XSS)跨網站指令碼攻擊
    就是網站上被攻擊者植入程式碼
    
    [XSS攻擊](https://medium.com/hannah-lin/%E5%BE%9E%E6%94%BB%E6%93%8A%E8%87%AA%E5%B7%B1%E7%B6%B2%E7%AB%99%E5%AD%B8-xss-cross-site-scripting-%E5%8E%9F%E7%90%86%E7%AF%87-fec3d1864e42)

    內容安全策略 (Content Security Policy)
    
---
[Spring 設計模式](https://kknews.cc/zh-tw/code/6ap3zap.html)
工廠設計模式 : Spring使用工廠模式通過 BeanFactory、ApplicationContext 創建 bean 對象。
代理設計模式 : Spring AOP 功能的實現。
單例設計模式 : Spring 中的 Bean 默認都是單例的。
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結尾的對資料庫操作的類，它們就使用到了模板模式。
包裝器設計模式 : 我們的項目需要連接多個資料庫，而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫。這種模式讓我們可以根據客戶的需求能夠動態切換不同的數據源。
觀察者模式: Spring 事件驅動模型就是觀察者模式很經典的一個應用。
適配器模式 :Spring AOP 的增強或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配Controller。


原文網址：https://kknews.cc/code/6ap3zap.html
    
---
   
深拷貝(deep copy)和淺拷貝(shallow copy) java

---
    
[簡明RESTful API設計要點](https://tw.twincl.com/programming/*641y)
[ESTful Web API 設計指南](https://www.footmark.info/programming-language/design/restful-webapi-design-guide/)
    
HttpMethod :用來當作動詞
    
GET:
POST:
PUT:
DELETE:
    
URI : 用來當作名詞
一般資源用複數名詞,複數可以保持API endpoint的一致性，所以一般資源建議用複數。

唯一資源（亦即對client而言只有一份的資源）用單數名詞
    
建議URI components都用小寫，兩個字之間用減號-或底線_隔開皆可，但應保持一致。（我個人偏好用-）

2xx: 成功
200 OK: 通用狀態碼
201 Created: 資源新增成功
202 Accepted: 請求已接受，但尚在處理中
204 No Content: 請求成功，但未回傳任何內容
3xx: 重新導向
301 Moved Permanently: 資源已移至它處
303 See Other: 回傳的內容可在它處取得（例如在用戶端發送了一個POST請求之後）
304 Not Modified: 請求的資源並未修改（通常是用戶端發送了帶有If-Modified-Since或If-None-Match表頭的請求）
4xx: 用戶端錯誤（用戶端不應retry原始請求）
400 Bad Request: 通用狀態碼
401 Unauthorized: 用戶端尚未驗證*
403 Forbidden: 用戶端被禁止此請求*
404 Not Found: 請求的資源不存在
405 Method Not Allowed: 不支援請求的HTTP方法
406 Not Acceptable: 不支援請求所要求的內容類型*（Accept表頭）
415 Unsupported Media Type: 不支援請求所用的內容類型*（Content-Type表頭）
5xx: 伺服器錯誤（用戶端可合理retry）
500 Internal Server Error: 工程師要找bug了
501 Not Implemented: 用戶端的請求目前未支援（也就是將來有可能支援）
502 Bad Gateway: 上游的伺服器未回傳正確結果，一般是gateway或proxy server才會回傳此狀態碼
503 Service Unavailable: 暫停服務（也就是過不久就會恢復服務──如果一切順利的話）
504 Gateway Timeout: 上游的伺服器逾時，一般是gateway或proxy server才會回傳此狀態碼
    
優秀的 URI 設計，應一目了然且容易記憶。
URI 設計原則如下：

簡短便於輸入的 URI：去除無意義且重覆的單詞，例如 https://api.example.com/api/v1/employees，由 domain 就能得知這是一個 API，但在路徑又重覆了一次 api。
使用者能讀懂的 URI：使用有意義的英文單字，而不使用縮寫。
小寫英文字母的 URI：一律使用小寫英文字母，更不可大小寫字母混用。
修改方便的 URI：例如 https://api.example.com/v1/employees/1，即可看出該員工 ID 為 1，而且只要修改 ID 就能獲取其他員工的資源。
不暴露 server 架構的 URI：例如 https://api.example.com/v1/employees.php，就知道應該是用 PHP 程式語言編寫的，這讓黑客更容易針對漏洞發起惡意攻擊。
規則統一的 URI：例如使用英文字母複數 https://api.example.com/v1/employees 來取得所有員工資源組，但確用單數 https://api.example.com/v1/employee/1 來取得一位員工的資源，類似這種不統一的 URI 容易造成 client 的混亂。
使用英文單字名詞的複數。
不使用空格及需要編碼的字元。
使用連接符 - 連結多個英文單字：但應避免多個英文單字連結，而是使用路徑 / 劃分的方式。
URI 應加入 API 的版本號：如 https://api.example.com/v1/employees。
    
[簡單理解REST設計風格與RESTful API](https://hackmd.io/@monkenWu/Sk9Q5VoV4/https%3A%2F%2Fhackmd.io%2F%40gen6UjQISdy0QDN62cYPYQ%2FHJh9zOE7V?type=book)   

    Representational State Transfer表現層狀態轉換

資源是由URL來進行指定
資源的操作須包括：取得、建立、修改以及刪除。而這些操作正好對應HTTP Request Method中的GET、POST、PUT與DELETE方法。
通過表現形式來操作資源，取決於不同的讀取者。
資源的表現可以是HTML或XML，若有別的應用也可以是JSON。

名稱(API Name)	路由(Route)	HTML動詞(Verb)	描述(Description)
Create News	/api/news	POST	新增一則新聞
List News	/api/news	GET	獲取新聞列表
Get Single News	/api/news/:newsId	GET	獲取一則新聞
Edit News	/api/article/:newsId	PATCH	編輯一則新聞
Delete News	/api/article/:newsId	DELETE	刪除一筆文章
 
[restful API 設計Level](https://www.itread01.com/content/1555153204.html)
    
---
    
[設計模式](https://skyyen999.gitbooks.io/-study-design-pattern-in-java/content/oodPrinciple.html)
  

---
[ACID Transaction](https://oldmo860617.medium.com/database-transaction-acid-156a3b75845e)
何謂transaction:
transaction 所具備的四個特性：
    
Atomicity 原子性
Consistency 一致性
Isolation 隔離性
Durability 永久性
    
---
[Spring bean 的scope](https://matthung0807.blogspot.com/2020/06/spring-bean-bean-scope.html)    

---
[TDD vs BDD](https://medium.com/hobo-engineer/ricky%E7%AD%86%E8%A8%98-tdd-bdd-and-test-double-76eee9e75092)    

---
關聯和非關聯DB    
    
---
[lambda](https://magiclen.org/java-8-lambda/)
[stream](https://mycollegenotebook.medium.com/java-stream-%E7%AD%86%E8%A8%98-%E4%B8%8A-34df0e282fc8)
 
[Java Functional Interface是什麼？](https://matthung0807.blogspot.com/2020/06/what-is-java-functional-interface.html)
[functional interface：Java 8 重新製作的概念](http://blog.dontcareabout.us/2013/03/functional-interfacejava-8.html)
 interface 當中有一個共同的特點，就是它們只定義了一個 method。 JDK 當中有一堆這樣的 interface、Java 開發人員也製造了一堆。 這些 interface 也被稱為 Single Abstract Method interface（SAM interface）。 

[Java 8函数式接口functional interface的秘密](https://colobu.com/2014/10/28/secrets-of-java-8-functional-interface/)
    函数式接口中可以额外定义多个抽象方法，但这些抽象方法签名必须和Object的public方法一样
    
---

[Spring 常用的annotation](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/12317/)
    
[@Value 與 Spring EL](https://openhome.cc/Gossip/Spring/Value.html)

---
 [甚麼是GC](https://matthung0807.blogspot.com/2018/02/java-gc-garbage-collection.html)   
    
---
[Web】瀏覽器如何繪製網頁？探討 DOM、CSSOM 與渲染](https://medium.someone.tw/web-%E7%80%8F%E8%A6%BD%E5%99%A8%E5%A6%82%E4%BD%95%E7%B9%AA%E8%A3%BD%E7%B6%B2%E9%A0%81-%E6%8E%A2%E8%A8%8E-dom-cssom-%E8%88%87%E6%B8%B2%E6%9F%93-%E7%BF%BB%E8%AD%AF-e9ba8c2be451) 
[[熱門面試題] 從輸入網址列到渲染畫面，過程經歷了什麼事？](https://w3c.hexschool.com/blog/8d691e4f)

[網路通訊DNS 伺服器是什麼？如何運用？](https://www.stockfeel.com.tw/dns-%E4%BC%BA%E6%9C%8D%E5%99%A8%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F%E5%A6%82%E4%BD%95%E9%81%8B%E7%94%A8%EF%BC%9F/)
    
[什麼是 SSL 憑證？](https://www.websecurity.digicert.com/zh/hk/security-topics/what-is-ssl-tls-https)
    
[02. [HTML] script tag 加上 async & defer 的功能及差異？](https://ithelp.ithome.com.tw/articles/10216858)
                                         
---
[深入淺出 Java 8 新語法特性](https://www.gss.com.tw/blog/java8)
    
---
[Java併發--final關鍵字](https://iter01.com/522258.html)

---
[hashMap和Hashtable的區別](https://sziyu.pixnet.net/blog/post/30233792)
[Java集合篇：fail-fast機制 與 fail-safe](https://www.itread01.com/content/1541492112.html)
[HashMap、HashTable、ConcurrentHashMap的區別](https://iter01.com/579686.html)
    
---
[git線上練習](https://learngitbranching.js.org/?locale=zh_TW)
    
[JAVAweb面試題](https://kknews.cc/code/xr53evo.html)