---
# System prepended metadata

title: Java面試題
tags: [面試]

---

:::spoiler Java
其他補充資源 : https://hackmd.io/@camiol/By5H1aL0Y

<details>
    <summary>
     String、StringBuilder 和 StringBuffer 的區別
    </summary>
    
- String：不可變的字符串，每次操作都會創建新對象    
- StringBuilder：可變字符串，執行緒不安全，但性能最好
- StringBuffer：可變字符串，執行緒安全，性能比 StringBuilder 稍差
</details>
1
<details>
    <summary>
      equals() 和 == 的區別
    </summary>
    
 - equals()：比較物件的內容值是否相等
（需要類別覆寫 equals 方法）
 - ==：
    - 基本類型：比較值是否相等
    - 引用類型：比較內存地址是否相等
    - 補充說明：== 是比較儲存的值，
基本型別是儲存在Stack中，因此值是相同的。
字串是儲存在字串池(String Pool)中，
在Stack當中存的是址的值，
因此採用==比較時會對比就是址的值。
        
<details>
    <summary>
        補充 字串池 機制
    </summary>
    
Java的字串有字串池機制，當宣告一個新的字串時，
Java會先去字串池中尋找是否有相同的字串，
如果有則會使用原本舊有的字串，沒有時才會新增一個新的字串。
            
如此一來，如果都是用String s1=”Hello World;”
這種方式宣告新的字串，
String s2=”Hello World”;的址的值會與s1一樣。
            
值得注意的是，如果是用new來宣告，
如:String s3=new String(”Hello World”);這種方式，
則s3這個字串會存在Heap中，與s1、s2的址的值是不同的，
這時候使用==就會是false。 
    </details>      
</details>

<details>
    <summary>
     HashMap 和 ConcurrentHashMap 的區別
    </summary>
    
 - HashMap：
    - 非執行緒安全
    - 允許 key 和 value 為 null
    - 性能較好
 - ConcurrentHashMap：
    - 執行緒安全，使用分段鎖機制
    - 不允許 key 或 value 為 null
    - 支持高並發操作
</details>

<details>
    <summary>
     Arrays跟ArrayList的區別
    </summary>
    
 - Arrays可包含原始(primitive)及物件(object)，
   ArrayList只允許物件
 - Arrays大小固定，ArrayList可以動態調整
 - ArrayList提供較多方法，如removeAll、iterator(迭代器)
</details>

<details>
    <summary>
     stack跟heap區別
    </summary>
    
 - stack: 可被預測生命週期的變數或函數資訊都放在stack，
   例如區域變數(local variable)、物件或陣列的
   返回位址(function/method return address)等資訊。
 - heap: 動態配置的記憶體空間，放置被new出來的物件
   以及內含的成員變數及方法。
</details>

<details>
    <summary>
     Int以及Integer何者會占用更多記憶體?
    </summary>
    
 - Integer會占用較多記憶體，Integer是一個物件，
    會在Heap中儲存，並儲存址的值於Stack中，
 - 而Int只會保存值在Stack中，因此Int占用資源較少。
</details>

<details>
    <summary>
     a=a+b與a+=b的區別為何?
    </summary>
    
a+=b會先將資料型別提升至少至int型別，
而a=a+b則不會，因此如果今天將a與b都宣告為byte型別，
相加超過127時就會產生錯誤。
</details>

<details>
    <summary>
     Overload和Override區別?
    </summary>
    
 - 多載（Overload）：指在一個類別(class)中，
   定義多個名稱相同，但參數(Parameter)不同的方法(Method)。
 - 覆寫（Override）：指子類別可以覆寫父類別的方法內容，
   使該方法擁有不同於父類別的行為。
</details>

<details>
    <summary>
     Java 的多型?
    </summary>
 
- 多型(Polymorphism)是指父類別可透過子類別衍伸成多種型態，
   而父類別為子類別的通用型態，再透過子類別可覆寫父類別的方法
   來達到多型的效果，也就是同樣的方法名稱會有多種行為。   
    
 - 向上轉型：父類引用指向子類對象
 ```java=
    class Animal {
        void makeSound() { }
    }
    class Dog extends Animal {
        void makeSound() {
            System.out.println("Woof");
        }
    }
    Animal animal = new Dog(); // 向上轉型
 ```    
 ```java=
    polymorphism(多型)、overriding(覆寫)、overloading(多載)
// Superclass(父類別)
class Animal(){
 void sound(){
 }
}
// Subclass(子類別)
class Dog extends Animal{
 // 覆寫 Animal.sound()
 void sound(){
  汪汪;
 }
 // 多載 Dog.sound()
 void sound(int i){
 }
 // 多載 Dog.sound()
 void sound(String s, int i){
 }
}
// Subclass(子類別)
class Cat extends Animal{
 // 覆寫 Animal.sound()
 void sound(){
  喵喵();
 }
}
// main
void main(){
 // 以父類建立具有子類方法的物件
 Animal dog = new Dog();
 Animal cat = new Cat();
 // 以子類建立具有父類方法的物件，執行產生錯誤(runtime error)
 Dog d = (Dog)new Animal();
 ..
 ..
 dog.sound(); // 將會執行"汪汪();
}
 ```   
    
</details>

<details>
    <summary>
     Java 中如何實現執行緒安全
    </summary>
    
 - synchronized 關鍵字（方法或代碼塊）
 - volatile 關鍵字
 - Lock 介面的實現類（ReentrantLock等）
 - 執行緒安全的集合類（ConcurrentHashMap、Vector等）
 - Atomic原子類（AtomicInteger等）
 - ThreadLocal    
    
    <details>
        <summary>
         synchronized 補充說明
        </summary>
    
     使用原因: 在程式的某些危險區域，不同執行緒可能同時
     存取同一份資源而產生衝突或重複修改
            
     使用目的: 控制每次只能有一個執行緒再使用同一份資源，
     此時另外的執行緒”無法同時” 使用此同一份資源
            
      1. 在方法宣告中加入synchronized關鍵字
      2. 或程式區塊以synchronized標示
      3. 或類別資料以synchronized標示
    </details>        
</details>

<details>
    <summary>
     final、finally 和 finalize 的區別
    </summary>
    
 - final： 是一種**修飾關鍵字**
    - 加在**類別**前則該類別**不能被繼承**
    - 加在**方法**前則該方法**不能被覆寫**
    - 加在**變數**前該變數為**常數**
 - finally：
   是一個例外處理關鍵字，寫在catch最後面，
   try-catch 後必執行的代碼塊，主要功用是做資源釋放。
 - finalize：對象被垃圾回收前調用的方法，
   是一種Object類的方法，
   因此是所有類別都有的方法(所有類繼承Object)，
   當物件要被銷毀前，會執行的方法，
   此外可以透過System.gc呼叫資源回收。
</details>

<details>
    <summary>
     throw與throws的區別
    </summary>
    
 - throw關鍵字通常用在設計方法中，
   預先宣告可能會產生的例外，
   後續方法使用者需要使用try-catch處理例外，
   或者使用throws關鍵字再拋出例外    
    - throw關鍵字用於方法內部拋出異常
    - throw關鍵字後面只能有一個異常
    
 - throws關鍵字通常被應用在聲明方法時，
   放在方法的大括號前，用來拋出異常，多個異常可以使用逗號隔開。
   後續使用者要調用方法時必須要拋出異常或者使用try-catch語句
   處理異常。
    - throws用於方法聲明上拋出異常
    - throws 可以聲明多個異常
</details>


<details>
    <summary>
     Java 中的異常處理機制 checked 和 unchecked 異常的區別？
    </summary>
    
 - Checked Exception：
        - 編譯時必須處理
        - 例如：IOException, SQLException
        - 繼承自 Exception
 - Unchecked Exception：
        - 運行時異常
        - 例如：NullPointerException,
        ArrayIndexOutOfBoundsException
        - 繼承自 RuntimeException
</details>

<details>
    <summary>
     什麼是死鎖？如何避免？
    </summary>
    
死鎖是指兩個或多個執行緒互相等待對方持有的資源。

避免方法：
    
 - 按順序申請資源
 - 設置超時時間
 - 使用 tryLock()
 - 避免嵌套鎖    

     ```java=
    // 按固定順序申請資源
    synchronized(lockA) {
        synchronized(lockB) {
            // TODO
        }
    }
    
    // 使用 tryLock 設定超時
    Lock lockA = new ReentrantLock();
    if (lockA.tryLock(1000, TimeUnit.MILLISECONDS)) {
        try {
            // TODO
        } finally {
            lockA.unlock();
        }
    }
    ```       
</details>

<details>
    <summary>
     介面和抽象類別 有什麼差別?
    </summary>
    
 - 介面：
    - 只能有常數和抽象方法
     （Java 8後介面可以有默認方法（default））
    - 可以多個實現
    - 方法默認 public abstract
    - 屬性默認 public static final
 - 抽象類：
    - 可以有普通屬性、方法和構造函數
    - 只能單個繼承
    - 可以有訪問修飾符
            
    抽象類別中可以宣告抽象方法，提供子類別實作。
    介面中的方法必定是抽象方法。
    但是一個類別僅能繼承一個抽象類別，
    可以實作多個介面，達到類似多重繼承效果。
</details>

<details>
    <summary>
     List、Set、Map區別
    </summary>
    
 - List:
    1.有順序性(索引值)
    2.可重複
    3.ArrayList實作了List介面
    4.ArrayList : 插入、刪除速度慢，走訪速度快
    5.LinkedList : 插入、刪除速度快，走訪速度慢，雙向連結
    
 - Set:
    1.無順序性(搭配迭代器)
    2.不可重複、搜尋速度快
    3.HashSet實作了Set介面
    4.HashSet : 無順序性，查找速度快
    5.LinkedHashSet : 有順序性
    6.TreeSet : 有排序性(依字母)
    
 - Map:
    1.有元素鍵值(Key-Value)，搜尋快
    2.元素可重複，鍵值如果重複新加入值會覆蓋舊有值
    3.HashMap : 查找速度慢，插入刪除速度快
    4.TreeMap : 有排序性
</details>
    
<details>
    <summary>
     在Java裡面 1/0 , 0/0 會發生什麼事?
    </summary>
    
 - 如果整數相除，分母為0會產生例外ArithmeticException
 - 如果是浮點數，分母為0.0，不會有例外不會進到catch，
   結果為無窮 Infinite
</details>

<details>
    <summary>
     Java 8 Stream API 常用方法?
    </summary>
    
 - collect 收集
   將 Stream 轉換為其他形式的集合
 ```java=
 List<String> list = stream.collect(Collectors.toList());  // 轉成 List
 Set<String> set = stream.collect(Collectors.toSet());     // 轉成 Set
 Map<String, String> map = stream.collect(Collectors.toMap()); // 轉成 Map
 ```

 - filter 過濾
   根據條件過濾元素
 ```java=        
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)  // 只保留偶數
            .collect(Collectors.toList()); // 結果：[2, 4]
 ```

 - reduce 歸納
   將所有元素組合成一個結果 
 ```java=
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream()
            .reduce(0, (a, b) -> a + b);  // 計算總和：15
 ```   
    
 - sorted 排序
   對元素進行排序   
 ```java= 
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
        List<String> sortedNames = names.stream()
            .sorted()  // 按字母順序排序
            .collect(Collectors.toList()); // 結果：[Alice, Bob, Charlie]
 ```  
    
 - distinct 去重
   去除重複元素
 ```java= 
        List<Integer> numbers = Arrays.asList(1, 1, 2, 2, 3);
        List<Integer> uniqueNumbers = numbers.stream()
            .distinct()  // 去除重複
            .collect(Collectors.toList()); // 結果：[1, 2, 3]
 ```    
    
 - flatMap 扁平化
   將多個集合合併成一個集合
 ```java= 
        List<List<Integer>> nestedNumbers = Arrays.asList(
            Arrays.asList(1, 2), 
            Arrays.asList(3, 4)
        );
        List<Integer> flatNumbers = nestedNumbers.stream()
            .flatMap(List::stream)  // 將嵌套列表展平
            .collect(Collectors.toList()); // 結果：[1, 2, 3, 4]
 ``` 
    
 - forEach 跌代
   對每個元素執行操作
 ```java= 
        List<String> names = Arrays.asList("Alice", "Bob");
        names.stream()
            .forEach(name -> System.out.println(name));  // 印出每個名字
 ```
    
 - count 計數
   計算元素個數    
 ```java= 
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        long count = numbers.stream()
            .count();  // 結果：5
 ```
    
 - min/max 最小值/最大值
   找出最小或最大的元素
 ```java= 
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        Optional<Integer> min = numbers.stream()
            .min(Integer::compareTo);  // 最小值：1
        Optional<Integer> max = numbers.stream()
            .max(Integer::compareTo);  // 最大值：5
 ```

 - anyMatch/allMatch/noneMatch 匹配判斷
    - anyMatch：是否存在符合條件的元素
    - allMatch：是否所有元素都符合條件
    - noneMatch：是否沒有元素符合條件 
 ```java=
            List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
            boolean hasEven = numbers.stream()
                .anyMatch(n -> n % 2 == 0);     // 是否有偶數：true
            boolean allEven = numbers.stream()
                .allMatch(n -> n % 2 == 0);     // 是否全部是偶數：false
            boolean noNegative = numbers.stream()
                .noneMatch(n -> n < 0);         // 是否沒有負數：true
 ```
                                       
可以組合使用，例如：
 ```java=
            List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5);
            List<Integer> result = numbers.stream()
                .filter(n -> n % 2 == 0)    // 過濾偶數
                .distinct()                 // 去重
                .sorted()                   // 排序
                .collect(Collectors.toList()); // 結果：[2, 4]  
 ```                                       

最後來總匯一下 : 
 ```java=
 List<String> list = Arrays.asList("a", "b", "c");
    list.stream()
        .filter(s -> s.startsWith("a"))    // 過濾
        .map(String::toUpperCase)          // 轉換
        .sorted()                          // 排序
        .distinct()                        // 去重
        .collect(Collectors.toList())      // 收集
        .forEach(System.out::println);     // 遍歷
 ```       
</details>

<details>
    <summary>
     MVC 是什麼?以及MVC架構的優點與缺點?
    </summary>
    
MVC是程式設計的一種架構方法，
主要涵蓋模型（Model）、視圖（View）和控制器（Controller）。
    
 - 模型（Model）: 程式設計師編寫程式應有的功能，
   資料庫專家進行資料管理和資料庫設計(可以實現具體的功能)
   Model主要負責資料存取。
 - 視圖（View）: 介面設計人員進行圖形介面設計。
   View主要負責顯示資料。
 - 控制器（Controller）: 負責轉發請求，對請求進行處理。
   Controller主要負責處理訊息。

**優點**
 1.好維護、方便擴充
 2.控制器與 Model 和 View 保持相對獨立，
   所以可以方便的改變應用程式的資料層和業務規則。
 3.多個 View 能共享一個 Model，大幅度提高程式重複使用性。
    
**缺點**
 1.開發時間長
 2.分層細    
</details>
        
<details>
    <summary>
     sendRedirect() 、 
     forward(request,response)的差別
    </summary>
    
 - forward
    1.定義在RequestDispatcher的介面，
    由request.getRequestDispatcher呼叫
    2.內部轉址,url不會顯示程式名稱(可設定成參數)
    3.可透過setAttribute傳遞參數(因為是內部傳址)
    4.效率高
    5.適用於權限管理轉頁時使用
    
 - sendRedirect()
    1.定義在HttpServletResponse
    2.直接外部呼叫另一支程式，會顯示程式名稱
    3.效率較低(因為client會在request一次)
    4.適用於跳到外部網站或回主畫面使用
</details>        

<details>
    <summary>
     JSP隱含物件有哪些?
    </summary>
    
1.request
2.response
3.out
4.session
5.application
6.config
7.pageContext
8.page
9.Exception
</details>
:::   
    
---    

:::spoiler SQL
<details>
    <summary>
    ...
    </summary>
    
...
</details>

<details>
    <summary>
     ...
    </summary>
    
... 
</details>
        
<details>
    <summary>
...
    </summary>
...
</details>        

<details>
    <summary>
     ...
    </summary>
...
</details>
    
<details>
    <summary>
     ...
    </summary>
...
</details>    
::: 
    
---       

:::spoiler 其他..
<details>
    <summary>
    ...
    </summary>
    
...
</details>

<details>
    <summary>
     ...
    </summary>
    
... 
</details>
        
<details>
    <summary>
...
    </summary>
...
</details>        

<details>
    <summary>
     ...
    </summary>
...
</details>
    
<details>
    <summary>
     ...
    </summary>
...
</details>    
::: 
    
---      