Redis操作笔记

//添加事务回滚:
@Transactional(rollbackOn = Exception.class)  

//指定缓存失效时间:
redisTemplate.expire(key,time,TimeUnit.SECONDS);
//根据key获取过期时间:
redisTemplate.getExpire(key,TimeUnit.SECONDS);
//判断key是否存在:
redisTemplate.hasKey(key);
//删除缓存:
    if(key!=null&&key.length>0){
	     if(key.length==1){
	          redisTemplate.delete(key[0]);
	      }else{
	          redisTemplate.delete(CollectionUtils.arrayToList(key));
	      }
	}
//普通缓存获取:
key==null?null:redisTemplate.opsForValue().get(key);
//普通缓存放入:
redisTemplate.opsForValue().set(key,value);
//普通缓存放入并设置时间:
redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
//递增:
redisTemplate.opsForValue().increment(key,delta);
//递减:
redisTemplate.opsForValue().increment(key,-delate);

//Map
//HashGet:
redisTemplate.opsForHash().get(key,item);
//获取hashKey对应的所有键值:
redisTemplate.opsForHash.entries(key);
//HashSet:
redisTemplate.opsForHash().putAll(key,map);
//HashSet并设置时间:
      redisTemplate.opsForHash().putAll(key,map);
		if(time>0){ 
		 expire( key , time ) ; 
		  }
//向一张hash表中放入数据,如果不存在将创建:
redisTemplate.opsForHash().put(key,item,value);
//同上+时间:
redisTemplate.opsForHash().put(key,item,value);
if(time>0){
  expire( key , time ) ; 
   }
//删除hash表中的值:
[key,tiem(可以多个)]不能为空. redisTemplate.opsForHash().delete(key,item);
//判断hash表中是否有该项的值: [key,tiem]不能为空. 
redisTemplate.opsForHash().hasKey(key,item);
//hash递增 如果不存在,就会创建一个 并把新递增后的值返回 
redisTemplate.opsForHash().increment(key,item,by);
//hash递减:
 redisTemplate.opsForHash().increment(key,item,-by);

//Set
//根据key获取Set中的值:
redisTemplate.opsForSet().members(key);

持久化方式:RDB AOF

一般来说,想媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。
如果非常关心数据,但仍可以承受数分钟以内的数据丢失,那么可以只使用RDB持久化。
由于AOF持久化的实时性更好,当进程意外退出时丢失的数据更少,因此AOF是主流的持久化方式,
只使用AOF持久化并不推荐,因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且RDB恢复数据速度比AOF要快。


锁提供的两种特性:互斥(mutual exclusion) 和 可见性(visibility);
(1) 互斥即一次只允许一个线程持有某个特定的锁,可使用该特性实现对共享数据的协调访问协议,一次就只有一个线程能够使用该共享数据。

编写多线程程序的时候遵循的最佳实践之 并发程序 遵循的一些最佳实践:
①给线程命名,可以帮助调试
②最小化同步的范围,只对关键部分做同步,而不是将整个方法同步
③如果可以,更偏向于使用 volatile 而不是 synchronized
④使用更高层次的并发工具 如 BlockingQueue CountDownLatch 及 Semeaphore
⑤优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性

Java 中 Collections 的最佳实践:
①不需要同步列表,使用 ArrayList 而不是 Vector
②优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性
③使用接口代表和访问集合,如使用 List 存储 ArrayList,使用 Map 存储 HashMap 等
④使用迭代器循环集合
⑤使用集合时使用泛型

IO 的最佳实践:(IO面向流,单向的,阻塞IO)

①使用缓冲区的IO类,而不要单独读取字节或字符
②使用 NIO 和 NIO2
(NIO支持面向缓冲区(Buffer)的、基于单双向通道(Channel)的IO操作,非阻塞IO,有选择器)
③在 finally
块中关闭流,或者使用try-with-resource 语句
④使用内存映射文件获取更快的 IO (内存映射文件I/O是一种读和写文件数据的方法,它比唱过的基于流或者基于通道的I/O快的多,是通过使文件中的数据神奇般的出现为内存数组的内容来完成的。尽管创建内存映射文件相当简单,但是向它写入可能是危险的。仅只是改变数组的单个元素这样的简单操作,就可能会直接修改磁盘上的文件。修改数据与将数据保存到磁盘是没有分开的。
内存映射文件用在堆性能非常敏感的应用程序中,例如高频电子交易系统 )

Optional<User> userOpt = Optional.ofNullable(user);

return userOpt.map(User::getUserName)
            .map(String::toUpperCase)
            .orElse(null);

目前的缓存策略常用的LFU、LRU、ARC、FIFO、MRU [不常用–>常用]
①LFU: 使用一个计数器来记录条目被访问的频率。通过使用LFU缓存算法,最低访问数的条目首先被移除。这个方法并不经常使用,因为它无法对一个拥有最初高访问率之后长时间没有被访问的条目缓存负责。
②LRU: 将最近使用的条目存放到靠近缓存顶部的位置。当一个新条目被访问时,LRU将它放置到缓存的顶部。当缓存达到极限时,较早之前访问的条目将从缓存底部开始被移除。这里会使用到昂贵的算法,而且它需要记录“年龄位”来精确显示条目是何时被访问的。此外,当一个LRU缓存算法删除某个条目后,“年龄位”将随其他条目发生改变。
③ARC: 自适应缓存替换算法,这个缓存算法同时跟踪记录LFU和LRU,以及驱逐缓存条目,来获得可用缓存的最佳使用。
④FIFO: 一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
⑤MRU: 这个缓存算法最先移除最近最常使用的条目。一个MRU算法擅长处理一个条目越久,越容易被访问的情况。

springboot添加过滤器有两种方式:
1、通过创建FilterRegistrationBean的方式
2、 使用@WebFilter

里氏替换原则:龙生龙,凤生凤,老鼠的儿子会打洞。
迪米特法则:“只和朋友说话,不要和陌生人说话”

|=:两个二进制对应位都为0时,结果等于0,否则结果等于1;
&=:两个二进制的对应位都为1时,结果为1,否则结果等于0;
^=:两个二进制的对应位相同,结果为0,否则结果为1

 // 请把字符串数组转list
    public List<String> arrToListStr(String[] arr) {
        return Arrays.asList(arr);
    }

// 请把字符串list转数组
    public String[] listToArrStr(List<String> list) {
        return list.toArray(new String[list.size()]);
    }

// 请把list数组转成int[]
    public int[] arrToListInt (List<Integer> list) {
        // 不可以toArray,int[]和Integer[]是不同的
        //return list.toArray(new int[list.size()]);
        return list.stream()
                .mapToInt(Integer::valueOf)
                .toArray();
    }

// 请把int[] 数组转成list
    public List<Integer> arrToListInt (int[] num) {
        // 不可以asList,因为int[]和Integer[]不同
        // return Arrays.<Integer>asList(num);
        return Arrays
                .stream(num)
                .boxed()
                .collect(Collectors.toList());
    }

// 初始化list为5个1
    public static List<Integer> fillList() {
        List<Integer> list = Collections.nCopies(5,1);
        System.out.println(list);
        return list;
    }

// 初始化arr为5个1
    public static int[] fillArr() {
        int[] arr = new int[5];
        Arrays.fill(arr, 1);
        return arr;
    }

// 返回1个list数组,并且里面的list已经初始化完成
    public static List[] fillListArray() {
        List[] lists = new List[5];
        IntStream.rangeClosed(0, 4).boxed()
                .forEach(i->lists[i] = new ArrayList());
        return lists;
    }


//不做重复的put:
map.putIfAbsent(key, value)//字面意思: absent指不存在,那么就是不存在的时候,把value放入,如果存在,则直接返回原value值。

//例如每次对key中的值加1  有两种方式:
map.put(key, map.getOrDefault(key, 0)+1);
map.compute(key, (k,v)->(v==null?1:v+1));

//在一个比较复杂的情况下,compute比较有用。
computeIfAbsent(key, (k,v)->f(k,v)//只在key不存在的时候,才计算这个labmda式子。 如果存在的话,就不计算了,直接返回旧值。
computeIfPresent(key, (k,v)->f(k,v)//只有存在才会更新,不存在就不更新。

常见队列用法
普通队列:
优先队列priorityQueue:
能够保证出队的永远是按照你设定的最大或者最小的元素。
很有用。
用labma写内部比较式子,避免忘记接口怎么写
PriorityQueue<int[]> queue = new PriorityQueue<>((a, b) -> a[1] - b[1]);
a[1] - b[1] 是小顶堆
a[1]-b[1] >0,则交换。

如何记忆?
堆更新的时候,都是从上往下更新的, 让
那么a是上面的点,b是下面的点(儿子节点)
当返回大于0时,交换a和b。

这样就好理解了
大顶堆: a-b<0时,需要交换,即父亲比儿子小,所以需要交换
小丁堆: a-b>0, 需要交换, 即父亲比儿子大,得换,让父亲是小顶。

优先队列延时删除
当优先队列中某个元素会被删除,但是不在堆顶时,使用延迟删除, 直到他走到堆顶才会清理。
因此这时候要使用额外的数量realCount来统计队列实际数量, 并使用特定的删除标志位(勿用会干扰到队列compare方法的方式去设定删除标志位)


字典序算法:
①:从右往走,找出第一个左边小于右边的数,设为list[a];
②:从右往左,找出第一个大于list[b]的数,设为list[b];
③:交换list[a],list[b];
④:将list[a]后面的数据,由小往大排列;

递归版本:
就是第一个数分别以后面的数进行交换。

创建型模式:
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式

结构型模式:
适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式

行为型模式:
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

还有两类:
并发型模式和线程池模式。

————————————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值