实习修炼之第二天

学习进度

HttpRequest的使用

可学习如下代码

public boolean searchBuyLimit(Long userId , Long goodsId , Integer num , ServiceRequest request){
    SearchBuyLimitRequest searchBuyLimitRequest = new SearchBuyLimitRequest(request);
    BuyLimitVO buyLimitVO = new BuyLimitVO();
    buyLimitVO.setUserId(userId);
    buyLimitVO.setGoodsId(goodsId);
    buyLimitVO.setNum(num);
    searchBuyLimitRequest.setBuyLimit(buyLimitVO);
    ServiceResponse<BuyLimitResponse> response = buyLimitService.searchBuyLimit(searchBuyLimitRequest);
    if (response.isSuccess() && response.getData().isAllow()){
        return true;
    }else{
        return false;
    }
}

LinkedHashMap使用

Map接口
Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;
键(key值)不可重复,value值可以重复,一个value值可以和很多key值形成对应关系,每个键最多只能映射到一个值。
Map支持泛型,形式如:Map<K,V>
Map中使用put(K key,V value)方法添加
Map中使用Remove(K key)方法删除

HashMap类(初始size为16)
HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现
HashMap中的Entry对象是无序排列的
Key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)

Hashtable类(初始size为11,增加的方式是 old*2+1)
Hashtable也实现了Map接口,与HashMap基本相似,只有以下不同

他们两个都是无序的
HashMap是非synchronized的,可以接受为null的键值(key)和值(value)
Hashtable是synchronized,Hashtable是线程安全的,多个线程可以共享一个Hashtable,Hashtable不允许null值
如果没有正确的同步的话,多个线程是不能共享HashMap, HashMap不能保证随着时间的推移Map中的元素次序是不变的
因为Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,那么使用HashMap性能比Hashtable好
建议:如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。

mac 终端命令自动补全

在这里插入图片描述

@Resource注解

@Resource 注解被用来激活一个命名资源(named resource)的依赖注入。通常来说有两种使用方式。
@Resource(name="data") public void setData(Data data) { this.data= data; }

但是直接使用@Resource注解一个域(field)同样是可能的。通过不暴露setter方法,代码愈发紧凑并且还提供了域不可修改的额外益处。该方式被应用到setter方法的时候,默认名是从相应的属性衍生出来,如下代码所示:

@Resource
private DataSource data; 			// inject the bean named 'data'

lambda表达式

学习如下代码

callableList.add(() -> {
    ServiceResponse invokeResp = bizInvoke.doServiceInvoke(request);
    if (!invokeResp.isSuccess()) {
        throw new RollbackException(invokeResp.getDesc());
    }
    return invokeResp;
});

库存超卖问题

(此种情况下事务不能处理)
转载自 https://www.cnblogs.com/ZJOE80/p/5671567.html 感觉这篇博客介绍的很详细
库存超卖问题也就是在遇到如团购、秒杀、特价之类的活动时,访问量激增、上千甚至上万人抢购一个商品,如何控制库存不让出现超买防止造成不必要的损失。
解决方案1:
  将存库从MySQL前移到Redis中,所有的写操作放到内存中,由于Redis中不存在锁故不会出现互相等待,并且由于Redis的写性能和读性能都远高于MySQL,这就解决了高并发下的性能问题。然后通过队列等异步手段,将变化的数据异步写入到DB中。
优点:解决性能问题
缺点:没有解决超卖问题,同时由于异步写入DB,存在某一时刻DB和Redis中数据不一致的风险。

解决方案2:
引入队列,然后将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候就不在消费队列,并关闭购买功能。这就解决了超卖问题。
优点:解决超卖问题,略微提升性能。
缺点:性能受限于队列处理机处理性能和DB的写入性能中最短的那个,另外多商品同时抢购的时候需要准备多条队列。

解决方案3:
将写操作前移到Memcached中,同时利用Memcached的轻量级的锁机制CAS来实现减库存操作。
优点:读写在内存中,操作性能快,引入轻量级锁之后可以保证同一时刻只有一个写入成功,解决减库存问题。
缺点:没有实测,基于CAS的特性不知道高并发下是否会出现大量更新失败?不过加锁之后肯定对并发性能会有影响。

解决方案4:
  将提交操作变成两段式,先申请后确认。然后利用Redis的原子自增操作(相比较MySQL的自增来说没有空洞),同时利用Redis的事务特性来发号,保证拿到小于等于库存阀值的号的人都可以成功提交订单。然后数据异步更新到DB中。
优点:解决超卖问题,库存读写都在内存中,故同时解决性能问题。
缺点:由于异步写入DB,可能存在数据不一致。另可能存在少买,也就是如果拿到号的人不真正下 订单,可能库存减为0,但是订单数并没有达到库存阀值。

总结方法:

  • 前端三板斧【扩容】【限流】【静态化】
  • 后端两条路【内存】+【排队】

带构造器的枚举

在枚举类型中可以添加构造方法,但是规定构造方法必须为private修饰符所修饰,可学习下面代码

	//可以把PopUpType 理解为一个类
    public enum PopUpType {
    NEWPACK(1, "新客大礼包"),
    OLDCOUPON(2, "老客优惠卷"),
    EXITCOUPON(3, "未使用的优惠卷"),
    ACTIVEPOP(4, "活动弹窗"),;
    //而OLDCOUPON就是这个类的一个实例,因此,我们现在有4个这样的实例
    public static PopUpType getStatus(int status) {
        for (PopUpType type : values()) {
            if (status == type.getId()) {
                return type;
            }
        }
        return null;
    }
    private int id;
    private String desc;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    PopUpType() {
    }
    PopUpType(int id, String desc) {
        this.id = id;
        this.desc = desc;
    }

    public static PopUpType valueOfCode(int code){
        for (PopUpType ts : PopUpType.values()){
            if (ts.getId() == code){
                return ts;
            }
        }
        return null;
    }
}

serialVersionUID

其适用于Java的序列化机制。而Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。
具体序列化步骤:

  • 把当前类的serialVersionUID写入到序列化文件中;
  • 当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致;
  • 如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。serialVersionUID有两种显示的生成方式:

其一是默认的1L,比如:private static final long serialVersionUID = 1L;
其二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如我们常见的:
private static final long serialVersionUID = 1214456890L;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值