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


引子

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

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

假設我是一個面試者,近幾年做的都是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(防腐層),批量操作的隔離、熔斷、分片,數據異步轉同步等限於篇幅這里就不介紹了。只要面試中能夠引導面試官提問這方面的技術並且可以講的明明白白,已經可以超過大部分的面試者。

 

推薦閱讀

服務設計要解決的問題

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

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

程序員如何破局前行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM