CURD系統怎麼做出技術含量--怎樣引導面試

程式設計一生發表於2021-11-09

引子

很多朋友可能會因為自己做的工作不是特別核心或者業務簡單而引起面試中沒有自信。但是很多公司面試的時候是可以接受面試者之前崗位的併發量、交易量低一些的。比如我們要招聘和我們交易量同等級或者以上的出來的人才,業界本來就沒有多少,但我們還是要招人的。所以很多時候更偏向於考察面試者的設計底蘊、思考和解決問題的能力。

我建議面試時,面試者要爭取主動權,主動引導面試。一般作為面試官也很樂意被面試者引導。因為面試官的職責是發現面試者的技術特長,為此我們絞盡腦汁的從簡歷中、自我介紹中去發掘。如果面試者可以自己有完整清晰的思路,是面試官求之不得的事情。

假設我是一個面試者,近幾年做的都是XX後臺管理系統。後臺管理系統嘛,沒有高併發、沒有高可用需求、沒有複雜架構,屬於三無系統。要是我的話,會把自己的以下知識技能放到專案介紹裡展示給面試官:

  • 可測試性設計

    • 謙卑物件模式

    • RESTful風格

  • 領域驅動設計DDD

    • 充血模型

    • CQRS

可測試性設計

謙卑物件模式

作為一個後臺管理系統,一般場景下微服務化的價值不大。DDD領域驅動設計這種專門用於複雜問題的解決辦法在這裡多半也是殺雞用牛刀。後面會講到一些DDD技巧還是可以用的。實際中大多是採用前後端分離的架構,這種架構實踐一方面是動靜分離,便於快取優化等效能考慮,另一方面也是一個出於可測試性的考慮。分離出可自動化測試的介面層和測試難度高的展現層。

展現層物件等測試難度高的物件在整潔架構中被稱為謙卑物件。通過拆分不同的類或者模組,來區分容易測試的行為和不容易測試的行為,這種設計上的隔離模式被稱為謙卑物件模型。

現在的很多設計對程式的可測試性提供了友好的改進和支援。比如:程式呼叫資料庫執行操作,mybatis等持久層框架將把sql以介面的形式對外提供服務,介面有成熟的工具來做mock打樁,這是比較典型的謙卑物件模式。

另外一個比較典型的比較典型的謙卑物件模式是feign。netflix的feign把原本需要手寫的httpClient(或者OKHttp)程式碼使用介面呼叫的的形式,實現了命令式到宣告式的轉換。同時,謙卑物件和非謙卑物件之間有很好的隔離層,也對測試更友好。對feign想做進一步瞭解的可參考我之前的文章《Java&Spring過時的經典語錄》,這裡簡單舉個例子:

public interface TestHttpService {

 

    @RequestLine("GET /xxxx?appkey={appkey}&ips={ip}&username={username}&operator={operator}")
Response getTest(@Param(value = "appkey") String appkey,
@Param(value = "ip") String ip,
@Param(value = "username") String username,
@Param(value = "operator") String operator);

}

 

RESTful

說起後臺管理系統的介面層,RESTful風格的介面是比較流行的最佳實踐。雖然這個被提了很多年了,實際嚴格按照這種風格設計的介面並不多。大多數系統的介面風格像是跟著江南七怪學武的郭靖一般,武功路數駁雜不成體系。

來做個判斷題:

下面的程式碼,類上用了RestController的註解,這是RESTful風格的程式碼嗎?

@RestController
public class JacksonController {
@Resource
private User user;
@GetMapping("/writeStringAsString")
public String writeStringAsString(String toWrite) throws Exception {
System.out.println(user.getAge());
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(toWrite);

            }

    }

REST(英文:Representational State Transfer,簡稱REST) 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程式或設計就是 RESTful。

理論上REST架構風格並不是繫結在HTTP上,但是REST本身受Web技術的影響很深, 目前HTTP是唯一與REST相關的例項。
我們們來看看需要滿足哪些約束條件和原則。

資源設計規則:

1>不用大寫;
2>用中槓-不用下槓_;
3>用名詞不用動詞;
4>URI中的名詞表示資源集合,使用複數形式。

動作設計規則:

1>GET(SELECT):從伺服器取出資源(一項或多項)。

2>POST(CREATE):在伺服器新建一個資源。

3>PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。

4>PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性)。

5>DELETE(DELETE):從伺服器刪除資源。

返回結果規則:

與HTTP協議標準基本沒有新的約束。要注意content-type的accept,包含accept-encoding。之前出個我在測試環境出個一個問題,我們自動化測試迴歸平臺不支援gzip,但是請求時帶了gzip,其實平臺並不支援導致亂碼。

 

 

通過上面的約束條件和原則我們們來總結一下為什麼叫REST:"資源"是一種資訊實體,它可以有多種外在表現形式。我們把"資源"具體呈現出來的形式,叫做它的"表現層"(Representation)。

網際網路通訊協議HTTP協議,是一個無狀態協議。這意味著,所有的狀態都儲存在伺服器端。因此,如果客戶端想要操作伺服器,必須通過某種手段,讓伺服器端發生"狀態轉化"(State Transfer)。而這種轉化是建立在表現層之上的,所以就是"表現層狀態轉化"。

如果大家都理解,那上面判斷題的答案也呼之欲出了:因為不滿足相應的約束條件和原則,所以不是RESTful風格。@RestController 只是讓資源返回結果是RESTful風格的。但不管是不是RESTful風格,都是URI。統一資源識別符號(Uniform Resource Identifier,URI)是一個用於標識某一網際網路資源名稱的字串。 只要定位到資源了,都是URI。

 

領域驅動設計DDD

充血模型

貧血模型是指實體物件或者說是POJO只包含簡單的set、get方法,充血模型認為一個物件是擁有狀態和行為的。什麼叫狀態和行為呢?舉個例子:

@Setter
@Getter
@ToString
@EqualsAndHashCode
public class Pojo {
private String name ;
private String status;
public int getStatus() {
return NumberUtils.toInt(status);
}
}

上面類程式碼上用了lombok的@Setter、@Getter註解之外,還用了@ToString、@EqualsAndHashCode,這兩個雖然是Object物件的基本方法,實際上也是做了狀態和行為的事情,而不只是@Setter、@Getter的資料存取。與之類似的還有上面的int getStatus,實際上進行了型別轉換這個行為。

現在針對到底使用貧血模型還是充血模型更好說法不一。我個人更傾向於使用充血模型,因為這種方法從領域上更內聚。但是很多人不建議使用,主要是因為充血模型對個人能力有更高的要求。充血模型開發者需要自己去識別哪些是實體領域中的。對於一般的spring開發者來說,個人經驗上有個簡單的辦法:凡是要引用@Service、@Component的都不要放到裡面,之前本來要放到XXUtils的建議看看更符合哪個實體領域,不要一股腦放到util包下面,看看是否可以劃分到實體領域中。

 

CQRS

CQRS — Command Query Responsibility Segregation,顧名思義是將 command 與 query 分離的一種模式。CQRS 將系統中的操作分為兩類,即「命令」(Command) 與「查詢」(Query)。命令則是對會引起資料發生變化操作的總稱,即我們常說的新增,更新,刪除這些操作,都是命令。而查詢則和字面意思一樣,即不會對資料產生變化的操作,只是按照某些條件查詢資料。

在後臺系統中,某些查詢操作可能會過於頻繁,比如頁面定時重新整理獲取資料。這些查詢操作不需要保證每次都成功。而命令操作如果失敗則涉及到事務回滾等操作,需要保證操作的成功率。這時候可以使用CQRS隔離,比如將檢查流量和命令流量使用hystrix隔離,架構清晰了,還可以畫出下面這樣清晰的架構圖:

圖片

 

總結

上面都是後臺管理系統中常用的一些技術,其實還有ACL(防腐層),批量操作的隔離、熔斷、分片,資料非同步轉同步等限於篇幅這裡就不介紹了。只要面試中能夠引導面試官提問這方面的技術並且可以講的明明白白,已經可以超過大部分的面試者。

 

推薦閱讀

服務設計要解決的問題

分散式儲存系統的一致性-可見性差異

程式碼榮辱觀-以運用風格為榮,以隨意編碼為恥

程式設計師如何破局前行

相關文章