在计算机领域中,FGC 通常代表 Full Garbage Collection,即全垃圾收集。垃圾收集是一种自动管理内存的机制,它负责回收不再被程序使用的内存,以便释放资源和提高程序性能。
当系统执行 Full Garbage Collection 时,它会检查整个堆内存,并尝试回收所有不再使用的对象。这个过程可能会导致一些系统暂时停止执行,特别是在大型内存堆上。因此,频繁的 Full Garbage Collection 可能会对系统性能产生影响。
"FGC增加 44次" 可能表示在一个时间段内进行了 44 次 Full Garbage Collection 操作。这可能表明系统在处理大量内存回收,可能是因为程序生成了大量的垃圾对象,需要频繁进行全堆垃圾收集。
考虑优化程序的内存使用,减少产生垃圾对象的频率,以降低 Full Garbage Collection 的次数,从而提高系统性能。
在 Java 虚拟机中,YGC 通常表示 Young Generation Garbage Collection,即年轻代垃圾收集。Java 堆被分为年轻代、老年代和持久代(在一些较新的 JVM 中可能不存在),而年轻代是 Java 对象的初始分配和短期存活的地方。
年轻代通常被划分为三个部分:
Eden 区(伊甸园区): 这是对象的初始分配区域,大多数对象最初都在这里分配。
Survivor 区(幸存者区): Survivor 区有两个,通常称为 S0 和 S1。它们用于存放在 Eden 区中经过一次垃圾收集后仍然存活的对象。
老年代(Old Generation): 如果对象在年轻代经历了一定次数的垃圾收集仍然存活,它将被晋升到老年代。
Young Generation Garbage Collection 就是指针对年轻代的垃圾收集操作。在年轻代,主要的垃圾收集算法是通过复制(Copying)和标记-清除(Mark-Sweep)结合的方式进行的。垃圾收集的目标是尽可能快速地清理掉那些很快就不再使用的对象,以提高程序的性能。
因此,YGC 的发生频率相对较高,通常不会影响整个系统的性能。相比之下,FGC(Full Garbage Collection)涉及到整个堆的垃圾收集,会导致更大的停顿时间,因此通常希望 YGC 的次数较多,FGC 的次数较少。
配置中心&服务注册&发现:Nacos
API网关:Spring Cloud Gateway
认证授权:Spring Security OAuth2 Authorization Server
远程调用:Dubbo & Spring Cloud OpenFeign & OkHttp & HttpClient & WebClient
负载均衡:Spring Cloud Loadbalancer & OpenResty
服务熔断&降级&限流:Sentinel
分库分表&读写分离:Mybatis Plus & ShardingSphere
分布式事务:Seata & RocketMQ
消息队列:RocketMQ & Kafka & MQTT
服务监控:Spring Boot Admin & Prometheus
链路跟踪:SkyWalking
任务调度:XXL Job
日志分析:EFK
缓存&分布式锁:Redis & Redisson
统计报表:MongoDB
对象存储:Amazon S3
自动化部署:Docker
网络通讯:Netty
持续集成&交付:Jenkins
持久层框架:Mybatis Plus
JSON序列化:Jackson
对象转换:MapStruct
数据库:Mysql & Postgresql
工作流:Flowable
数据库迁移:Flyway
微服务框架
[界面一览]
[产品简介]
[Docker启动基础服务]
[Nacos安装]
[Sentinel安装]
[导入Nacos配置]
[数据库导入]
[运行Cloud版本]
[告警部署]
[监控部署]
[前端部署]
[后端部署]
[对接准备]
[Jar模式对接]
<el-table-column>
中的 type="selection"
用于显示表格的选择列,允许用户选择表格中的行。在这个列上,你可以使用一些属性来定制选择的行为。在你提供的代码中,有两个属性被使用到:
:selectable
: 该属性接受一个函数,用于判断某一行是否可以被选择。这个函数将会接收表格当前行的数据作为参数,你可以在这个函数中编写逻辑来决定该行是否可以被选择。如果返回true
,则表示该行可以被选择,否则不可以。在你的代码中,这个属性被绑定到selectable
变量,但你没有提供这个变量的定义。这个函数可以不传,默认为返回true
。:reserve-selection
: 该属性接受一个布尔值,表示是否保留用户之前所选的内容。如果设置为true
,则在切换分页时保留之前所选的项。在你的代码中,这个属性被设置为true
。
这两个属性的使用可以帮助你在表格中实现选择行的功能。在用户选择行时,可以通过监听 selection-change
事件,获取用户选择的数据,并进行相关的处理。
统一验证
@NotNull
不能为null@NotEmpty
不能为null、空字符串、空集合@NotBlank
不能为null、空字符串、纯空格的字符串@Min
数字最小值不能小于x@Max
数字最大值不能大于x@Email
字符串为邮件格式@Max
数字最大值不能大于x@Size
字符串长度最小为x、集合长度最小为x@Pattern
正则表达式
public class SysUser implements Serializable {private static final long serialVersionUID = 1L;/*** 用户ID**/@TableIdprivate Long userId;/*** 用户名*/@NotBlank(message="用户名不能为空")@Size(min = 2,max = 20,message = "用户名长度要在2-20之间")private String username;/*** 密码*/@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)private String password;/*** 邮箱*/@NotBlank(message="邮箱不能为空")@Email(message="邮箱格式不正确")private String email;/*** 手机号*/@Pattern(regexp="0?1[0-9]{10}",message = "请输入正确的手机号")private String mobile;/*** 状态 0:禁用 1:正常*/private Integer status;/*** 用户所在店铺id*/private Long shopId;/*** 角色ID列表*/@TableField(exist=false)private List<Long> roleIdList;/*** 创建时间*/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();}
}
当然,我们也要简单介绍下oauth的运行流程:
+--------+ +---------------+| |--(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*/@TableIdprivate Long orderId;/*** 店铺id*/private Long shopId;/*** 订购流水号*/private String orderNumber;/*** 订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6 交易失败*/private Integer status;/*** 订购时间*/private Date createTime;/*** 订单更新时间*/private Date updateTime;/*** 付款时间*/private Date payTime;/*** 发货时间*/private Date dvyTime;/*** 完成时间*/private Date finallyTime;/*** 取消时间*/private Date cancelTime;
商品信息
/*** 产品名称,多个产品将会以逗号隔开*/private String prodName;/*** 总值*/private Double total;/*** 实际总值*/private Double actualTotal;/*** 订单商品总数*/private Integer productNums;/*** 优惠总额*/private Double reduceAmount;
买家信息
/*** 订购用户ID*/private String userId;/*** 订单备注*/private String remarks;
userId
,买家用户编号。remarks
,买家购买备注。
total
:商品总价。该字段通过 OrderItem的price
求和计算。freightAmount
:运费总价。该字段通过 OrderItem的商品的运费价格求和计算。reduceAmount
:交易优惠金额。注意,TradeOrder 的total = 100
,reduceAmount = 72
,actualTotal = 18
。total = 100
,reduceAmount = 10
,actualTotal = 90
。购买的商品参加 折扣活动,原价 100 元,折扣价 10 元。那么数据如下(我们会看到折扣活动跟着 商品走):
购买的商品使用优惠劵,在上面例子的基础上,优惠劵打 2 折。那么数据如下(我们会看到优惠劵跟着 Trade 走):
actualTotal
:actualTotal = total + freightAmount - reduceAmount
物流
/*** 配送类型*/private String dvyType;/*** 配送方式ID*/private Long dvyId;/*** 物流单号*/private String dvyFlowId;
收货人信息UserAddrOrder
public class UserAddrOrder implements Serializable {/*** ID*/@TableIdprivate Long addrOrderId;/*** 地址ID*/private Long addrId;/*** 用户ID*/private String userId;/*** 收货人*/private String receiver;/*** 省*/private String province;/*** 城市*/private String city;/*** 区*/private String area;/*** 地址*/private String addr;/*** 邮编*/private String postCode;/*** 省ID*/private Long provinceId;/*** 城市ID*/private Long cityId;/*** 区域ID*/private Long areaId;/*** 手机*/private String mobile;/*** 建立时间*/private Date createTime;/*** 版本号*/private Integer version;}
结算信息OrderSettlement
public class OrderSettlement implements Serializable {/*** 支付结算单据ID*/@TableIdprivate Long settlementId;/*** 用户系统内部的订单号*/private String payNo;/*** 外部订单流水号*/private String bizPayNo;/*** 订单号*/private String orderNumber;/*** 支付方式 0 手动代付 1 微信支付 2 支付宝*/private Integer payType;/*** 支付金额*/private Double payAmount;/*** 用户ID*/private String userId;/*** 是否清算 0:否 1:是*/private Integer isClearing;/*** 创建时间*/private Date createTime;/*** 清算时间*/private Date clearingTime;/*** 支付状态*/private Integer payStatus;/*** 版本号*/private Integer version;/*** 支付方式名称*/private String payTypeName;}
orderNumber
:关联订单的订单号payNo
: 支付时的支付订单号,根据雪花算法生成payAmount
:实付金额。bizPayNo
:外部交易编号。比如,如果支付方式是微信支付,就是财付通的交易单号。
订单项 OrderItem
每个订单都会有多个商品,每个商品就是一个订单项。
/*** 订单项ID*/@TableId(type = IdType.AUTO)private Long orderItemId;private Long shopId;/*** 订单orderNumber*/private String orderNumber;/*** 产品ID*/private Long prodId;/*** 产品SkuID*/private Long skuId;/*** 购物车产品个数*/private Integer prodCount;/*** 产品名称*/private String prodName;/*** sku名称*/private String skuName;/*** 产品主图片路径*/private String pic;/*** 产品价格*/private Double price;/*** 用户Id*/private String userId;/*** 商品总金额*/private Double productTotalAmount;/*** 购物时间*/private Date recTime;/*** 评论状态: 0 未评价 1 已评价*/private Integer commSts;/*** 推广员使用的推销卡号*/private String distributionCardNo;/*** 加入购物车的时间*/private Date basketDate;
orderNumber
:订单编号,指向Order.orderNumber
。prodId
:商品id冗余商品字段:
prodName
,商品标题。pic
,商品主图片地址。
skuId
,商品 SKU 编号,指向ItemSku.id
。冗余商品 SKU 字段:
skuName
,SKU的值,即:商品的规格。如:机身颜色:黑色;手机套餐:官方标配。
num
,购买数量。
地区管理
model实体类:
@Data
@TableName("tz_area")
public class Area implements Serializable {private static final long serialVersionUID = -6013320537436191451L;@TableId@ApiModelProperty(value = "地区id",required=true)private Long areaId;@ApiModelProperty(value = "地区名称",required=true)private String areaName;@ApiModelProperty(value = "地区上级id",required=true)private Long parentId;@ApiModelProperty(value = "地区层级",required=true)private Integer level;@TableField(exist=false)private List<Area> areas;
}
areaId
,地区idareaName
,地区名称level
,级别,根据上面所说的地区枚举parentId
,地区上级id
model实体类:
运费模板类(tz_transport)
@Data
@TableName("tz_transport")
public class Transport{/*** 运费模板id*/@TableId@ApiModelProperty(value = "运费模板id",required=true)private Long transportId;/*** 运费模板名称*/@ApiModelProperty(value = "运费模板名称",required=true)private String transName;/*** 店铺id*/@ApiModelProperty(value = "店铺id",required=true)private Long shopId;/*** 参考 TransportChargeType* 收费方式(0 按件数,1 按重量 2 按体积)*/@ApiModelProperty(value = "收费方式(0 按件数,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;/*** 创建时间*/@ApiModelProperty(value = "创建时间",required=true)private Date createTime;
}
transportId
,运费模板idtransName
,运费模板名称,存在多个运费模板时,方便商家选择更好的运费模板shopId
,店铺id,可扩展为B2B2C模式isFreeFee
,是否包邮,如果商家选择了包邮,则不需要后面的其他操作chargeType
,收费方式可分为按件数、按重量 、按体积,影响运费项表中firstPiece
、continuousFee
的单位hasFreeCondition
,是否包含包邮条件,勾选后,商家可以设定指定包邮的地区与条件
运费项(tz_transfee)
@Data
@TableName("tz_transfee")
public class Transfee {/*** 运费项id*/@TableId@ApiModelProperty(value = "运费项id",required=true)private Long transfeeId;/*** 运费模板id*/@ApiModelProperty(value = "运费模板id",required=true)private Long transportId;/*** 续件数量*/@ApiModelProperty(value = "续件数量",required=true)private Double continuousPiece;/*** 首件数量*/@ApiModelProperty(value = "首件数量",required=true)private Double firstPiece;/*** 续件费用*/@ApiModelProperty(value = "续件费用",required=true)private Double continuousFee;/*** 首件费用*/@ApiModelProperty(value = "首件费用",required=true)private Double firstFee;}
运费项关联城市表(tz_transcity)
@Data
@TableName("tz_transcity")
public class Transcity implements Serializable {@TableIdprivate Long transcityId;/*** 运费项id*/private Long transfeeId;/*** 城市id*/private Long cityId;
}
运费项可以根据需求指定特定区域的进行设置,运费项表与运费项关联城市表之间为一对多的关系,设定的区域优先于所有地区。
transcityId
, 模板项关联城市IDtransfeeId
,关联的模板项目IDcityId
, 关联亚米商城系统中的区域管理模块
指定条件包邮项表(tz_transfee_free)
@Data
@TableName("tz_transfee_free")
public class TransfeeFree {/*** 指定条件包邮项id*/@TableId@ApiModelProperty(value = "指定条件包邮项id",required=true)private Long transfeeFreeId;/*** 运费模板id*/@ApiModelProperty(value = "运费模板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 = "实际总值", required = true)private Double actualTotal;@ApiModelProperty(value = "商品总值", required = true)private Double total;@ApiModelProperty(value = "商品总数", required = true)private Integer totalCount;@ApiModelProperty(value = "订单优惠金额(所有店铺优惠金额相加)", required = true)private Double orderReduce;@ApiModelProperty(value = "地址Dto", required = true)private UserAddrDto userAddr;@ApiModelProperty(value = "每个店铺的购物车信息", required = true)private List<ShopCartOrderDto> shopCartOrders;@ApiModelProperty(value = "整个订单可以使用的优惠券列表", 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 相关的软件包。它先使用 yum remove
命令移除了以下 Docker 相关的软件包:
container-selinux
docker
docker-client
docker-common
然后,它输出了一些关于仓库的信息,包括签名和主要数据库的下载进度。在这之后,它列出了所有将要被移除的软件包及其版本和大小,然后询问用户是否继续。用户选择了 y
表示同意进行卸载操作。
最后,它给出了一个提示,如果用户希望回滚上述操作,可以使用 yum load-transaction
命令。这个命令会加载之前保存的事务信息,从而可以回滚到之前的状态。
dump下来的文件大约1.8g,用jvisualvm查看,发现用char[]
类型的数据占用了41%内存,同时另外一个com.alibaba.druid.stat.JdbcSqlStat类型的数据占用了35%的内存,也就是说整个堆中几乎全是这两类数据。
加群联系作者vx:xiaoda0423
仓库地址:https://github.com/webVueBlog/JavaGuideInterview