springboot第52集:微服務(wù)分布式架構(gòu),統(tǒng)一驗(yàn)證,oauth,訂單,地區(qū)...
在計(jì)算機(jī)領(lǐng)域中,F(xiàn)GC 通常代表 Full Garbage Collection,即全垃圾收集。垃圾收集是一種自動(dòng)管理內(nèi)存的機(jī)制,它負(fù)責(zé)回收不再被程序使用的內(nèi)存,以便釋放資源和提高程序性能。
當(dāng)系統(tǒng)執(zhí)行 Full Garbage Collection 時(shí),它會(huì)檢查整個(gè)堆內(nèi)存,并嘗試回收所有不再使用的對(duì)象。這個(gè)過程可能會(huì)導(dǎo)致一些系統(tǒng)暫時(shí)停止執(zhí)行,特別是在大型內(nèi)存堆上。因此,頻繁的 Full Garbage Collection 可能會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響。
"FGC增加 44次" 可能表示在一個(gè)時(shí)間段內(nèi)進(jìn)行了 44 次 Full Garbage Collection 操作。這可能表明系統(tǒng)在處理大量?jī)?nèi)存回收,可能是因?yàn)槌绦蛏闪舜罅康睦鴮?duì)象,需要頻繁進(jìn)行全堆垃圾收集。
考慮優(yōu)化程序的內(nèi)存使用,減少產(chǎn)生垃圾對(duì)象的頻率,以降低 Full Garbage Collection 的次數(shù),從而提高系統(tǒng)性能。
在 Java 虛擬機(jī)中,YGC 通常表示 Young Generation Garbage Collection,即年輕代垃圾收集。Java 堆被分為年輕代、老年代和持久代(在一些較新的 JVM 中可能不存在),而年輕代是 Java 對(duì)象的初始分配和短期存活的地方。
年輕代通常被劃分為三個(gè)部分:
- Eden 區(qū)(伊甸園區(qū)): 這是對(duì)象的初始分配區(qū)域,大多數(shù)對(duì)象最初都在這里分配。
- Survivor 區(qū)(幸存者區(qū)): Survivor 區(qū)有兩個(gè),通常稱為 S0 和 S1。它們用于存放在 Eden 區(qū)中經(jīng)過一次垃圾收集后仍然存活的對(duì)象。
- 老年代(Old Generation): 如果對(duì)象在年輕代經(jīng)歷了一定次數(shù)的垃圾收集仍然存活,它將被晉升到老年代。
Young Generation Garbage Collection 就是指針對(duì)年輕代的垃圾收集操作。在年輕代,主要的垃圾收集算法是通過復(fù)制(Copying)和標(biāo)記-清除(Mark-Sweep)結(jié)合的方式進(jìn)行的。垃圾收集的目標(biāo)是盡可能快速地清理掉那些很快就不再使用的對(duì)象,以提高程序的性能。
因此,YGC 的發(fā)生頻率相對(duì)較高,通常不會(huì)影響整個(gè)系統(tǒng)的性能。相比之下,F(xiàn)GC(Full Garbage Collection)涉及到整個(gè)堆的垃圾收集,會(huì)導(dǎo)致更大的停頓時(shí)間,因此通常希望 YGC 的次數(shù)較多,F(xiàn)GC 的次數(shù)較少。
- 配置中心&服務(wù)注冊(cè)&發(fā)現(xiàn):Nacos
- API網(wǎng)關(guān):Spring Cloud Gateway
- 認(rèn)證授權(quán):Spring Security OAuth2 Authorization Server
- 遠(yuǎn)程調(diào)用:Dubbo & Spring Cloud OpenFeign & OkHttp & HttpClient & WebClient
- 負(fù)載均衡:Spring Cloud Loadbalancer & OpenResty
- 服務(wù)熔斷&降級(jí)&限流:Sentinel
- 分庫(kù)分表&讀寫分離:Mybatis Plus & ShardingSphere
- 分布式事務(wù):Seata & RocketMQ
- 消息隊(duì)列:RocketMQ & Kafka & MQTT
- 服務(wù)監(jiān)控:Spring Boot Admin & Prometheus
- 鏈路跟蹤:SkyWalking
- 任務(wù)調(diào)度:XXL Job
- 日志分析:EFK
- 緩存&分布式鎖:Redis & Redisson
- 統(tǒng)計(jì)報(bào)表:MongoDB
- 對(duì)象存儲(chǔ):Amazon S3
- 自動(dòng)化部署:Docker
- 網(wǎng)絡(luò)通訊:Netty
- 持續(xù)集成&交付:Jenkins
- 持久層框架:Mybatis Plus
- JSON序列化:Jackson
- 對(duì)象轉(zhuǎn)換:MapStruct
- 數(shù)據(jù)庫(kù):Mysql & Postgresql
- 工作流:Flowable
- 數(shù)據(jù)庫(kù)遷移:Flyway
- 微服務(wù)框架
- [界面一覽]
- [產(chǎn)品簡(jiǎn)介]
- [Docker啟動(dòng)基礎(chǔ)服務(wù)]
- [Nacos安裝]
- [Sentinel安裝]
- [導(dǎo)入Nacos配置]
- [數(shù)據(jù)庫(kù)導(dǎo)入]
- [運(yùn)行Cloud版本]
- [告警部署]
- [監(jiān)控部署]
- [前端部署]
- [后端部署]
- [對(duì)接準(zhǔn)備]
- [Jar模式對(duì)接]
<el-table-column> 中的 type="selection" 用于顯示表格的選擇列,允許用戶選擇表格中的行。在這個(gè)列上,你可以使用一些屬性來定制選擇的行為。在你提供的代碼中,有兩個(gè)屬性被使用到:
-
:selectable: 該屬性接受一個(gè)函數(shù),用于判斷某一行是否可以被選擇。這個(gè)函數(shù)將會(huì)接收表格當(dāng)前行的數(shù)據(jù)作為參數(shù),你可以在這個(gè)函數(shù)中編寫邏輯來決定該行是否可以被選擇。如果返回true,則表示該行可以被選擇,否則不可以。在你的代碼中,這個(gè)屬性被綁定到selectable變量,但你沒有提供這個(gè)變量的定義。這個(gè)函數(shù)可以不傳,默認(rèn)為返回true。 -
:reserve-selection: 該屬性接受一個(gè)布爾值,表示是否保留用戶之前所選的內(nèi)容。如果設(shè)置為true,則在切換分頁(yè)時(shí)保留之前所選的項(xiàng)。在你的代碼中,這個(gè)屬性被設(shè)置為true。
這兩個(gè)屬性的使用可以幫助你在表格中實(shí)現(xiàn)選擇行的功能。在用戶選擇行時(shí),可以通過監(jiān)聽 selection-change 事件,獲取用戶選擇的數(shù)據(jù),并進(jìn)行相關(guān)的處理。
-
@NotNull不能為null -
@NotEmpty不能為null、空字符串、空集合 -
@NotBlank不能為null、空字符串、純空格的字符串 -
@Min數(shù)字最小值不能小于x -
@Max數(shù)字最大值不能大于x -
@Email字符串為郵件格式 -
@Max數(shù)字最大值不能大于x -
@Size字符串長(zhǎng)度最小為x、集合長(zhǎng)度最小為x -
@Pattern正則表達(dá)式
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用戶ID
*
*/
@TableId
private Long userId;
/**
* 用戶名
*/
@NotBlank(message="用戶名不能為空")
@Size(min = 2,max = 20,message = "用戶名長(zhǎng)度要在2-20之間")
private String username;
/**
* 密碼
*/
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
/**
* 郵箱
*/
@NotBlank(message="郵箱不能為空")
@Email(message="郵箱格式不正確")
private String email;
/**
* 手機(jī)號(hào)
*/
@Pattern(regexp="0?1[0-9]{10}",message = "請(qǐng)輸入正確的手機(jī)號(hào)")
private String mobile;
/**
* 狀態(tài) 0:禁用 1:正常
*/
private Integer status;
/**
* 用戶所在店鋪id
*/
private Long shopId;
/**
* 角色I(xiàn)D列表
*/
@TableField(exist=false)
private List<Long> roleIdList;
/**
* 創(chuàng)建時(shí)間
*/
private Date createTime;
}
@RestController
@RequestMapping("/sys/user")
public class SysUserController {
/**
* 保存用戶
*/
@SysLog("保存用戶")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys:user:save')")
public ResponseEntity<String> save(@Valid @RequestBody SysUser user){
String username = user.getUsername();
SysUser dbUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUsername, username));
if (dbUser!=null) {
return ResponseEntity.badRequest().body("該用戶已存在");
}
user.setShopId(SecurityUtils.getSysUser().getShopId());
user.setPassword(passwordEncoder.encode(user.getPassword()));
sysUserService.saveUserAndUserRole(user);
return ResponseEntity.ok().build();
}
}
當(dāng)然,我們也要簡(jiǎn)單介紹下oauth的運(yùn)行流程:
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
訂單
Order,訂單。一次下單,生成一條訂單記錄,即使多種商品。
/**
* 訂單ID
*/
@TableId
private Long orderId;
/**
* 店鋪id
*/
private Long shopId;
/**
* 訂購(gòu)流水號(hào)
*/
private String orderNumber;
/**
* 訂單狀態(tài) 1:待付款 2:待發(fā)貨 3:待收貨 4:待評(píng)價(jià) 5:成功 6 交易失敗
*/
private Integer status;
/**
* 訂購(gòu)時(shí)間
*/
private Date createTime;
/**
* 訂單更新時(shí)間
*/
private Date updateTime;
/**
* 付款時(shí)間
*/
private Date payTime;
/**
* 發(fā)貨時(shí)間
*/
private Date dvyTime;
/**
* 完成時(shí)間
*/
private Date finallyTime;
/**
* 取消時(shí)間
*/
private Date cancelTime;
image.png
商品信息
/**
* 產(chǎn)品名稱,多個(gè)產(chǎn)品將會(huì)以逗號(hào)隔開
*/
private String prodName;
/**
* 總值
*/
private Double total;
/**
* 實(shí)際總值
*/
private Double actualTotal;
/**
* 訂單商品總數(shù)
*/
private Integer productNums;
/**
* 優(yōu)惠總額
*/
private Double reduceAmount;
買家信息
/**
* 訂購(gòu)用戶ID
*/
private String userId;
/**
* 訂單備注
*/
private String remarks;
-
userId,買家用戶編號(hào)。 -
remarks,買家購(gòu)買備注。
-
total:商品總價(jià)。該字段通過 OrderItem的price求和計(jì)算。 -
freightAmount:運(yùn)費(fèi)總價(jià)。該字段通過 OrderItem的商品的運(yùn)費(fèi)價(jià)格求和計(jì)算。 -
reduceAmount:交易優(yōu)惠金額。注意,TradeOrder 的-
total = 100,reduceAmount = 72,actualTotal = 18。 -
total = 100,reduceAmount = 10,actualTotal = 90。 - 購(gòu)買的商品參加 折扣活動(dòng),原價(jià) 100 元,折扣價(jià) 10 元。那么數(shù)據(jù)如下(我們會(huì)看到折扣活動(dòng)跟著 商品走):
- 購(gòu)買的商品使用優(yōu)惠劵,在上面例子的基礎(chǔ)上,優(yōu)惠劵打 2 折。那么數(shù)據(jù)如下(我們會(huì)看到優(yōu)惠劵跟著 Trade 走):
-
-
actualTotal:actualTotal = total + freightAmount - reduceAmount
物流
/**
* 配送類型
*/
private String dvyType;
/**
* 配送方式ID
*/
private Long dvyId;
/**
* 物流單號(hào)
*/
private String dvyFlowId;
收貨人信息UserAddrOrder
public class UserAddrOrder implements Serializable {
/**
* ID
*/
@TableId
private Long addrOrderId;
/**
* 地址ID
*/
private Long addrId;
/**
* 用戶ID
*/
private String userId;
/**
* 收貨人
*/
private String receiver;
/**
* 省
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 區(qū)
*/
private String area;
/**
* 地址
*/
private String addr;
/**
* 郵編
*/
private String postCode;
/**
* 省ID
*/
private Long provinceId;
/**
* 城市ID
*/
private Long cityId;
/**
* 區(qū)域ID
*/
private Long areaId;
/**
* 手機(jī)
*/
private String mobile;
/**
* 建立時(shí)間
*/
private Date createTime;
/**
* 版本號(hào)
*/
private Integer version;
}
結(jié)算信息OrderSettlement
public class OrderSettlement implements Serializable {
/**
* 支付結(jié)算單據(jù)ID
*/
@TableId
private Long settlementId;
/**
* 用戶系統(tǒng)內(nèi)部的訂單號(hào)
*/
private String payNo;
/**
* 外部訂單流水號(hào)
*/
private String bizPayNo;
/**
* 訂單號(hào)
*/
private String orderNumber;
/**
* 支付方式 0 手動(dòng)代付 1 微信支付 2 支付寶
*/
private Integer payType;
/**
* 支付金額
*/
private Double payAmount;
/**
* 用戶ID
*/
private String userId;
/**
* 是否清算 0:否 1:是
*/
private Integer isClearing;
/**
* 創(chuàng)建時(shí)間
*/
private Date createTime;
/**
* 清算時(shí)間
*/
private Date clearingTime;
/**
* 支付狀態(tài)
*/
private Integer payStatus;
/**
* 版本號(hào)
*/
private Integer version;
/**
* 支付方式名稱
*/
private String payTypeName;
}
-
orderNumber:關(guān)聯(lián)訂單的訂單號(hào) -
payNo: 支付時(shí)的支付訂單號(hào),根據(jù)雪花算法生成 -
payAmount:實(shí)付金額。 -
bizPayNo:外部交易編號(hào)。比如,如果支付方式是微信支付,就是財(cái)付通的交易單號(hào)。
訂單項(xiàng) OrderItem
每個(gè)訂單都會(huì)有多個(gè)商品,每個(gè)商品就是一個(gè)訂單項(xiàng)。
/**
* 訂單項(xiàng)ID
*/
@TableId(type = IdType.AUTO)
private Long orderItemId;
private Long shopId;
/**
* 訂單orderNumber
*/
private String orderNumber;
/**
* 產(chǎn)品ID
*/
private Long prodId;
/**
* 產(chǎn)品SkuID
*/
private Long skuId;
/**
* 購(gòu)物車產(chǎn)品個(gè)數(shù)
*/
private Integer prodCount;
/**
* 產(chǎn)品名稱
*/
private String prodName;
/**
* sku名稱
*/
private String skuName;
/**
* 產(chǎn)品主圖片路徑
*/
private String pic;
/**
* 產(chǎn)品價(jià)格
*/
private Double price;
/**
* 用戶Id
*/
private String userId;
/**
* 商品總金額
*/
private Double productTotalAmount;
/**
* 購(gòu)物時(shí)間
*/
private Date recTime;
/**
* 評(píng)論狀態(tài): 0 未評(píng)價(jià) 1 已評(píng)價(jià)
*/
private Integer commSts;
/**
* 推廣員使用的推銷卡號(hào)
*/
private String distributionCardNo;
/**
* 加入購(gòu)物車的時(shí)間
*/
private Date basketDate;
-
orderNumber:訂單編號(hào),指向Order.orderNumber。 -
prodId:商品id - 冗余商品字段:
-
prodName,商品標(biāo)題。 -
pic,商品主圖片地址。
-
-
skuId,商品 SKU 編號(hào),指向ItemSku.id。 - 冗余商品 SKU 字段:
-
skuName,SKU的值,即:商品的規(guī)格。如:機(jī)身顏色:黑色;手機(jī)套餐:官方標(biāo)配。
-
-
num,購(gòu)買數(shù)量。
image.png
model實(shí)體類:
@Data
@TableName("tz_area")
public class Area implements Serializable {
private static final long serialVersionUID = -6013320537436191451L;
@TableId
@ApiModelProperty(value = "地區(qū)id",required=true)
private Long areaId;
@ApiModelProperty(value = "地區(qū)名稱",required=true)
private String areaName;
@ApiModelProperty(value = "地區(qū)上級(jí)id",required=true)
private Long parentId;
@ApiModelProperty(value = "地區(qū)層級(jí)",required=true)
private Integer level;
@TableField(exist=false)
private List<Area> areas;
}
-
areaId,地區(qū)id -
areaName,地區(qū)名稱 -
level,級(jí)別,根據(jù)上面所說的地區(qū)枚舉 -
parentId,地區(qū)上級(jí)id
model實(shí)體類:
運(yùn)費(fèi)模板類(tz_transport)
@Data
@TableName("tz_transport")
public class Transport{
/**
* 運(yùn)費(fèi)模板id
*/
@TableId
@ApiModelProperty(value = "運(yùn)費(fèi)模板id",required=true)
private Long transportId;
/**
* 運(yùn)費(fèi)模板名稱
*/
@ApiModelProperty(value = "運(yùn)費(fèi)模板名稱",required=true)
private String transName;
/**
* 店鋪id
*/
@ApiModelProperty(value = "店鋪id",required=true)
private Long shopId;
/**
* 參考 TransportChargeType
* 收費(fèi)方式(0 按件數(shù),1 按重量 2 按體積)
*/
@ApiModelProperty(value = "收費(fèi)方式(0 按件數(shù),1 按重量 2 按體積)",required=true)
private Integer chargeType;
/**
* 是否包郵 0:不包郵 1:包郵
*/
@ApiModelProperty(value = "是否包郵 0:不包郵 1:包郵",required=true)
private Integer isFreeFee;
/**
* 是否含有包郵條件
*/
@ApiModelProperty(value = "是否含有包郵條件",required=true)
private Integer hasFreeCondition;
/**
* 創(chuàng)建時(shí)間
*/
@ApiModelProperty(value = "創(chuàng)建時(shí)間",required=true)
private Date createTime;
}
-
transportId,運(yùn)費(fèi)模板id -
transName,運(yùn)費(fèi)模板名稱,存在多個(gè)運(yùn)費(fèi)模板時(shí),方便商家選擇更好的運(yùn)費(fèi)模板 -
shopId,店鋪id,可擴(kuò)展為B2B2C模式 -
isFreeFee,是否包郵,如果商家選擇了包郵,則不需要后面的其他操作 -
chargeType,收費(fèi)方式可分為按件數(shù)、按重量 、按體積,影響運(yùn)費(fèi)項(xiàng)表中firstPiece、continuousFee的單位 -
hasFreeCondition,是否包含包郵條件,勾選后,商家可以設(shè)定指定包郵的地區(qū)與條件
運(yùn)費(fèi)項(xiàng)(tz_transfee)
@Data
@TableName("tz_transfee")
public class Transfee {
/**
* 運(yùn)費(fèi)項(xiàng)id
*/
@TableId
@ApiModelProperty(value = "運(yùn)費(fèi)項(xiàng)id",required=true)
private Long transfeeId;
/**
* 運(yùn)費(fèi)模板id
*/
@ApiModelProperty(value = "運(yùn)費(fèi)模板id",required=true)
private Long transportId;
/**
* 續(xù)件數(shù)量
*/
@ApiModelProperty(value = "續(xù)件數(shù)量",required=true)
private Double continuousPiece;
/**
* 首件數(shù)量
*/
@ApiModelProperty(value = "首件數(shù)量",required=true)
private Double firstPiece;
/**
* 續(xù)件費(fèi)用
*/
@ApiModelProperty(value = "續(xù)件費(fèi)用",required=true)
private Double continuousFee;
/**
* 首件費(fèi)用
*/
@ApiModelProperty(value = "首件費(fèi)用",required=true)
private Double firstFee;
}
運(yùn)費(fèi)項(xiàng)關(guān)聯(lián)城市表(tz_transcity)
@Data
@TableName("tz_transcity")
public class Transcity implements Serializable {
@TableId
private Long transcityId;
/**
* 運(yùn)費(fèi)項(xiàng)id
*/
private Long transfeeId;
/**
* 城市id
*/
private Long cityId;
}
運(yùn)費(fèi)項(xiàng)可以根據(jù)需求指定特定區(qū)域的進(jìn)行設(shè)置,運(yùn)費(fèi)項(xiàng)表與運(yùn)費(fèi)項(xiàng)關(guān)聯(lián)城市表之間為一對(duì)多的關(guān)系,設(shè)定的區(qū)域優(yōu)先于所有地區(qū)。
-
transcityId, 模板項(xiàng)關(guān)聯(lián)城市ID -
transfeeId,關(guān)聯(lián)的模板項(xiàng)目ID -
cityId, 關(guān)聯(lián)亞米商城系統(tǒng)中的區(qū)域管理模塊
指定條件包郵項(xiàng)表(tz_transfee_free)
@Data
@TableName("tz_transfee_free")
public class TransfeeFree {
/**
* 指定條件包郵項(xiàng)id
*/
@TableId
@ApiModelProperty(value = "指定條件包郵項(xiàng)id",required=true)
private Long transfeeFreeId;
/**
* 運(yùn)費(fèi)模板id
*/
@ApiModelProperty(value = "運(yùn)費(fèi)模板id",required=true)
private Long transportId;
/**
* 包郵方式 (0 滿x件/重量/體積包郵 1滿金額包郵 2滿x件/重量/體積且滿金額包郵)
*/
@ApiModelProperty(value = "包郵方式 (0 滿x件/重量/體積包郵 1滿金額包郵 2滿x件/重量/體積且滿金額包郵)",required=true)
private Integer freeType;
/**
* 需滿金額
*/
@ApiModelProperty(value = "需滿金額",required=true)
private Double amount;
/**
* 包郵x件/重量/體積
*/
@ApiModelProperty(value = "包郵x件/重量/體積",required=true)
private Double piece;
}
@Data
public class ShopCartOrderMergerDto implements Serializable{
@ApiModelProperty(value = "實(shí)際總值", required = true)
private Double actualTotal;
@ApiModelProperty(value = "商品總值", required = true)
private Double total;
@ApiModelProperty(value = "商品總數(shù)", required = true)
private Integer totalCount;
@ApiModelProperty(value = "訂單優(yōu)惠金額(所有店鋪優(yōu)惠金額相加)", required = true)
private Double orderReduce;
@ApiModelProperty(value = "地址Dto", required = true)
private UserAddrDto userAddr;
@ApiModelProperty(value = "每個(gè)店鋪的購(gòu)物車信息", required = true)
private List<ShopCartOrderDto> shopCartOrders;
@ApiModelProperty(value = "整個(gè)訂單可以使用的優(yōu)惠券列表", required = true)
private List<CouponOrderDto> coupons;
}
yum remove docker \ > docker-client \ > docker-client-latest \ > docker-common \ > docker-latest \ > docker-latest-logrotate \ > docker-logrotate \ > docker-selinux \ > docker-engine-selinux \ > docker-engine
這段命令是在卸載 Docker 相關(guān)的軟件包。它先使用 yum remove 命令移除了以下 Docker 相關(guān)的軟件包:
- container-selinux
- docker
- docker-client
- docker-common
然后,它輸出了一些關(guān)于倉(cāng)庫(kù)的信息,包括簽名和主要數(shù)據(jù)庫(kù)的下載進(jìn)度。在這之后,它列出了所有將要被移除的軟件包及其版本和大小,然后詢問用戶是否繼續(xù)。用戶選擇了 y 表示同意進(jìn)行卸載操作。
最后,它給出了一個(gè)提示,如果用戶希望回滾上述操作,可以使用 yum load-transaction 命令。這個(gè)命令會(huì)加載之前保存的事務(wù)信息,從而可以回滾到之前的狀態(tài)。
image.png
image.png
image.png
image.png
image.png
dump下來的文件大約1.8g,用jvisualvm查看,發(fā)現(xiàn)用char[]類型的數(shù)據(jù)占用了41%內(nèi)存,同時(shí)另外一個(gè)com.alibaba.druid.stat.JdbcSqlStat類型的數(shù)據(jù)占用了35%的內(nèi)存,也就是說整個(gè)堆中幾乎全是這兩類數(shù)據(jù)。
加群聯(lián)系作者vx:xiaoda0423
倉(cāng)庫(kù)地址:https://github.com/webVueBlog/JavaGuideInterview
