跳到主要内容

JAVA Interview

1. 什麼是Spring Boot?

Spring Framework 是 Java 平臺利用依賴注入(Dependency Injection, DI)與控制反轉(Inversion of Control, IoC)核心概念實現的 Web 應用程式開源框架。

而Spring Boot 其實是 Spring 框架的簡化版,是由 Pivotal 團隊提供的全新框架,簡單來說就是一個懶人包。

  • 易於理解開發應用
  • 使配置變得簡單並彈性
  • 提供有力的管理Rest端點
  • 自動化配置
  • 依賴套件管理簡單
  • 內建Servlet容器
  • 獨立打包直接運行

2. 為什麼要使用Spring Boot?

  • 簡化開發流程:隻需要在pom檔中加入starter-web此依賴即可,不像spring 開發需要再pom檔加入很多依賴,還有其他springboot自帶的
  • 可簡化配置檔:在spring 中需要定義很多xml配置,但在spring boot中可使用annotation來簡化配置
  • 可簡化部屬:spring 通常要打包成war檔後丟入tomcat,但spring boot 自帶tomcat,隻需要打包成jar檔後雙擊即可啟動
  • 依賴套件管理簡單
  • 內建Servlet容器

3. Spring Boot有什麼配置文件,區別是什麼?

配置檔有以下兩種

  1. .yml : 以key,value來錶示此配置,以空白來與縮排來控製層級關係。
        ex:
    server:
    port: 8081
    path: /hello
  2. .properties : 檔案隻是一個一般文字檔案,也是key,value所組成,但是是以等號來賦值
        ex:
    server.port=8081
    server.path=hello

4. 說明MVC與MVVM差異?

MVC

  • 控制器(Controller)- 負責轉發請求,對請求進行處理。(實踐部分另計)
  • 視圖(View)- 圖形介面設計。
  • 模型(Model)- 數據管理和資料庫設計、實現算法等... mvc 不論是改 M, V 還是 C,都可以確保另外兩層可不用做任何修改, Controller 是 Model 和 View 之間的協調者 (coordinator),View 和 Model 不能直接溝通,以確保責任的分離。
View: resources/templates/... Login頁
<body>
<!-- login -->
<div id="app" style="margin: 20px 20%">
<form action="/demo/user/login" method="post">
用戶名<input type="text" name="name" placeholder="用戶名"/>
密碼<input type="password" name="password" placeholder="密碼"/>
<input type="submit" value="登錄">
</form>
</div>
<!-- index -->
<div id="app" style="margin: 20px 20%">
歡迎登錄,<span th:text="${user.name}"></span>
</div>
Model: thymeleaf/model/User.java
package com.example.template.thymeleaf.model;

import lombok.Data;

@Data
public class User {
private String name;
private String password;
}
Controller: thymeleaf/controller/IndexController.java
package com.example.template.thymeleaf.controller;
import com.example.template.thymeleaf.model.User;
...
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/login")
public ModelAndView login(User user, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
// mv.addObject(user);
mv.setViewName("redirect:/");
// Session 存值,可跨頁
request.getSession().setAttribute("user", user);
return mv;
}

//show 頁面
@GetMapping("/login")
public ModelAndView login() {
return new ModelAndView("page/login");
}
}
--------------------------------
public class IndexController {

@GetMapping(value = {"", "/"})
public ModelAndView index(HttpServletRequest request) {
ModelAndView mv = new ModelAndView();

// Session 取值
User user = (User) request.getSession().getAttribute("user");
if (ObjectUtil.isNull(user)) {
mv.setViewName("redirect:/user/login");
} else {
mv.setViewName("page/index");
// 把從 Session 取的值塞進 ModelAndView 中,前端方可顯示
mv.addObject(user);
}

return mv;
}
}

MVVM

MVVM 中的 VM 指的是 ViewModel,一樣負責接收從 View 傳來的使用者操作事件,並使用 Model 提供的方法來處理資料。

最主要的差異在於由數據來驅動 View 的更新,當資料改變時,UI 自動更新(一般用觀察者模式實現)。

  • Model(資料) Model是指代表真實狀態內容的領域模型(面向對象),或指代錶內容的數據訪問層(以數據為中心)。和MVC中的Model指代的內容相似。
  • View(網頁) 就像在MVC中一樣,View是用戶在螢幕上看到的結構、佈局和外觀(UI)。
  • ViewModel(資料繫結器) ViewModel 比較像是 View 的一個代理程式,它負責直接對 Model 做溝通, 而 View 可以透過一些機制 (js: Object.defineProperty,setter,getter) 來和 ViewModel 溝通以取得資料或將資料拋給 Model 做存取等工作,前端框架稱之為 Reactivity 響應式物件

優點

  1. 資料驅動: 事件都透過資料的變化來觸發,資料成為最關鍵的因素。
  2. 下層元件不需要知道上層元件: 在 MVC / MVP 中,都需要有 View 的引用來更新 UI。但在 MVVM 中,由View 主動觀察資料,在資料變化後收到通知,而自動更新。 ViewModel 不需要知道 View 是誰。

mvvm

vue2 示範代碼
<template>
<!-- View -->
Count is: {{ count }}
</template>
<script>
export default {
data() {
// ViewModel
return {
count: 1

}
},
mounted() {
this.increment()
},
// Model
methods: {
increment() {
this.count++
}
}
}
</script>

5. 什麼是Swagger?

Swagger 是一種 API 開發工具(springboot自帶)

假如RESTful API 開發完成了,一般來說只能使用post man去測試,若使用swagger後可以在網頁上看到漂亮的api介面,也可以依照各個api去提示需要輸入何種型態的參數。

6. 何謂RESTful API?

restful1

RESTful API 主要由三種元件組成:

  1. Nouns 名詞:定義資源位置的 URL,每個資源在網路上都會有唯一的位置,就如每戶人家都有唯一的地址一樣。
  2. Verbs 動詞:對資源要做的動作。使用了 HTTP protocol (GET/POST/PUT/DELETE),代表對資料的 (read/create/update/delete) rest-and-http
  3. Content Types 資源呈現方式:API 資源可以以多種方式表現,最常用的是 JSON,較輕,也較好處理。

restful2

Bad examples:
http://api.example.com/v1/store/CreateItems/{item-id}❌
http://api.example.com/v1/store/getEmployees/{emp-id}❌
http://api.example.com/v1/store/update-prices/{price-id}❌
http://api.example.com/v1/store/deleteOrders/{order-id}❌

Good examples:
http://api.example.com/v1/store/items/{item-id}✅
http://api.example.com/v1/store/employees/{emp-id}✅
http://api.example.com/v1/store/prices/{price-id}✅
http://api.example.com/v1/store/orders/{order-id}✅

優點及限制:

  1. 有唯一的URL表示資源位置,統一的 API 接口。(Uniform Interface)

  2. 無狀態。(Stateless)

    RESTful 的狀態,意即 HTTP 的請求狀態,一般 Web 服務中,Server 端和 Client 端交互的資訊,會存在 Server 端的 Session (例如:已登入狀態),在 Client 端再次發送請求的時候,Server 端透過保存在 Server 端的 Session,去執行 request。無狀態的意思,即 Client 端自行保存狀態,在請求 Server 的時候,一併附上給 Server 端,Server 端無保存 Client 端的狀態資訊。

    舉例來說,可能在用戶登錄系統時,Server 產生 token 紀錄 user 已登錄系統,然後把 token 還給 Client,在 Client 再次發送請求的時候,把 token 一起發給 Server,這樣 Server 就知道這一個 Client 是已經處於登錄的狀態。

    意即所有的資源都可以 URI 定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而變化,資源相互的依賴性降低。

  3. 可更高效利用快取來提高回應速度 (Cachable)

    在 server-side,GET 過的資源,如果沒有被變更過,可以利用 cache 機制減少 request。 在 client-side,透過 client 端 cache 紀錄 cache 版本,若向 server 要求資源時發現 server 最新版與 cache 相同,則 client 端直接取用本地資源即可,不需要再做一次查詢

7. 如何保護Spring Boot應用?

  1. 使用https
  2. Spring Security CSRF

8. Spring Boot 配置文件載入順序為何?

  1. 內部配置文件yam or properties
  2. 外部配置--命令列後面參數 ex:java -jar xxx.jar --server.port=8087

9. Spring Boot支援哪些日誌框架

  1. 支援Logback,log4j
  2. 分布式日誌系统Graylog、Loki及ELK (花錢或自己搭),把上面(1)當 client 用

10. 資料存取是使用JPA或MyBatis,差異為何?

MyBatis

  • 現在學coding學數據庫基本都學過SQL,Mybatis面向DB基於SQL的模式相對來說就顯得特別直觀友好。
  • 少一層ORM,跑起來比較快。
  • 規範較JPA少,代碼可能比較亂。

JPA

使用 ORM 的框架是有好有壞,對於常見的 CRUD 與簡單的關聯是可以簡短開發時間,也因為物件導向的關係所以使得程式碼的架構可以比較統一。

JPA是基於ORM的,把代碼和DB分離,相當於在代碼和DB之間增加了一個新的層面,一套新的標準,去間接操作DB,相對SQL的模式來說就顯得不夠直接和易於控製,增加了學習成本,碰到這樣那樣問題的時候,很容易讓人放棄。特別是在團隊開發的時候,你很難掌控每個人對JPA的深層機制的理解程度,為了避免木桶效應,還不如幹脆都用Mybatis。

簡單的說「透過 Java 將資料儲存到資料庫的 API」就叫做 JPA。不過實際上 JPA 只是一種規範 (或者叫他 Interface) 而已,它是由 Sun (官方)所統一的規範,規範了「映射物件與持久層的 API 的實作方式」

遵循 JPA 規範的 ORM 框架

  • Hibernate
  • Spring Data JPA
  • Open JPA
  • EclipseLink
  • Toplink

11. Spring Boot運行方式有幾種?

  1. 在IDE中運行main方法
  2. 到專案跟目錄下運行mvn spring-boot:run
  3. 打包成jar檔後運行java -jar xxxx.jar