1. API拆分原则:如商品详情页API,商品详情页包含商品评价信息,应拆分成多个API,不应该放在一个API中。
a. 如果商品评价报错,商品应当可以正常浏览购买,仅评价不能查看。
b. 一个接口做的事情太多了,压力太大,有并发时可能抗不住。
2. 确认问题原则:先由请求确认的人说清楚他的想法,再去看他拿来的东西。 比较两者之间的差异才能确保确认结果无误,否则按照自己的理解认为这个事情是对的,实际上可能差很多。xy问题,提需求的人提出x需求,实际上是为了解决y问题,要问下提需求的人提出x需求的原因是什么。
3. DB设计中绝大多数表都应该有date_added, user_id, user_name, date_modified, user_id, user_name等字段,调查问题的时候总能用上。加了又有什么坏处呢?
4. 如存在条件A,B,C,D,在校验时,如仅满足条件A或B时能通过校验,就编码仅A+B能通过校验,其余条均件报错。
原因: 如写为当C/D时报错,之后新増一个条件E,此处未调整的话,则E可以通过校验,如写为仅A或B能通过校验,新增审核状态此处未调整会报错,意识到E也需通过校验的话,调整代码即可,防止引起BUG。
5. 定义错误码时,要参考类似业务的大公司的报错规范,简单、严谨又专业。 如商品管理参考有赞微商城报错
6. 推进困难时先写一顿业务代码完成下工作,再思考,不然容易思考很久没有产出,为下不了班而焦虑。😀
7. 对于创建一些记录的创建时间字段,如果调用方传时间就用传的值,说明该记录是在调用方数据库上历史创建的,如果调用方没传时间值,则认为该记录是实时创建的,使用服务器时间。
8. 如果看不到日志 1. 使用curl在对应服务器上调一下接口 2. 看一下有无写日志的权限
9. 写API存实体时,将manager层与controller层的bean解耦,如后续需要从其他地方保存实体入数据库,可以快速复用。
失败案例:
10. 地域标准化方案与开发
前提:
联系人表的地域信息,不标准化也要存,因为不存就没有机会存了。
问题及解决方案:
1. 地域版本过多,无法映射,如 客户1 使用地域版本1,客户2使用地域版本2,客户3使用地域版本3,我们的地域版本是2,如何同时兼容版本1和版本3?
解决方案:使用别名映射。(到底行不行,有待仔细考虑)
2. 当标准化出现问题时,需要人工介入处理,但是未通知到外部,人工不知道要处理这件事情。
解决方案:写一个job每天定时报告地域标准化问题,再写一个job在人工处理补全地域数据之后,修正错误的地域数据信息。
11. 代码和人必须有一个要跑,代码不能跑,人就得跑
12. 不要写大事物,rpc调用放到事物之外。
13. 不要过度设计,有些项目的ROI过低会被直接砍掉,满足现有需求的最简单设计就是最好的设计。
14. 其实自己解决也花了不少时间,有些事情还是想的太过于深入最后发现对自己解决问题没什么用,应该也给自己设置一个思考超时时间和行动超时时间,比如都设置半个小时,如果没有任何进展要么去尝试其他的,要么去短暂的休息一下,说不定你会产生更好的思路。
15. 订单号生成规则,把用户ID放进订单号生成规则可有效防止并发问题,因为一个用户在短时间内的突然并发属于极端异常情况。
/**
* <p>
* 1 - 要货
* 2 - 采购
* 3 - 出库
* 4 - 入库/收货
* 5 - 结算
* 6 - 退货
* <p>
* 类型码+日期+7位userid+100以内的随机数
* 1_20210929_0000001_100 (不需要_)
*/
@Component
public class OrderNoGenerator {
private static final FastDateFormat format = FastDateFormat.getInstance("yyyyMMddHH");
private final ThreadLocalRandom random = ThreadLocalRandom.current();
public String gen(OrderTypeEnum orderType, Integer userId) {
return orderType.getCode() + format.format(new Date()) +
String.format("%07d", userId) + String.format("%03d", random.nextInt(100));
}
public OrderNoMsg parseOrderNo(String orderNo) {
String payload = orderNo.substring(0, orderNo.length() - 3);
int userIdStart = payload.length() - 7;
int userId = Integer.parseInt(payload.substring(userIdStart));
int dateStart = payload.length() - 17;
String date = payload.substring(dateStart, userIdStart);
int orderType = Integer.parseInt(payload.substring(0, dateStart));
return new OrderNoMsg().setDate(date).setUserId(userId).setOrderType(OrderTypeEnum.getByCode(orderType));
}
}