:doodle{ @size: 100vm 98vmin; } position: fixed; top: @r(1%, 100%); left: @r(1%, 100%); width: 2px; height: 2px; background: #04033e; border-radius: 50%; z-index:-999; background: hsl(@r(90, 120, 3), @r(90%, 100%), @r(30%, 40%)); zoom: @rn(.1, 5, 3); transform: rotate(@r(360deg)) translate(@r(-50, 50)vmin, @r(-50, 50)vmin); animation: move @r(20, 40)s infinite @r(-10, 0)s @p(linear, ease-in, ease-in-out) alternate; box-shadow: 0 0 1px hsl(@r(90, 120, 3), @r(90%, 100%), @r(30%, 40%)), 0 0 3px hsl(@r(90, 120, 3), @r(90%, 100%), @r(30%, 40%)); @keyframes move { 0% { transform: rotate(0) translate(0, 0); } 100% { transform: rotate(720) translate(-90, -90); } } @keyframes starMove{ from { } to { } } @keyframes weiba{ 100%{ box-shadow: 0 0 100px #fff, 0 0 300px #fff; } }

【Redis】存入redis的值,莫名其妙多了很多“\u0000”

背景

记录在redis中的多语言缓存,突然发现取值无法正常解析,加日志后发现,从redis取出来的值,有些在正常值的前面多了很多 \u0000 ,有些值好像是覆盖原有值但没覆盖全的样子 {"key":"new Value"}lue"},导致在解析数据是报错。

定位问题

通过记录日志,发现在向redis中添加值时,值还是正常的,再取出来,就会发生这些变化,于是怀疑问题出在set方法上。

排查代码,发现代码中使用了两种set方法。

  1. set(k, v, expireTime);
  2. set(k, v, expireTime,TimeUnit.SECONDS);

这两个方法乍一看,好像是少了个设置超时时间的单位,但实际上这两个方法的功能完全不一样。

void set(K key, V value, long offset)

这个三参的方法de Jdoc如下,用指定的值,追加覆盖原有内容,追加覆盖的位置由offset确定。

Overwrite parts of key starting at the specified offset with given value.
Params:
key – must not be null.
value –
offset –

需要注意的是,如果原有内容长度不够,则会使用\u0000填充到足够的长度。

比如:现有键值对 {"test":"ABCD"}, 使用set("test","12",10),会有以下操作

ABCD不足10,所以使用 \u0000填充到长度10,即 ABCD\u0000\u0000\u0000\u0000\u0000\u0000

然后追加覆盖12, 最后的值为ABCD\u0000\u0000\u0000\u0000\u0000\u000012

这个在调试时才会看到,控制台打印出来的结果是ABCD12

void set(K key, V value, long timeout, TimeUnit unit)

这个方法才是正确的保存键值对,并设置过期时间。

Set the value and expiration timeout for key.
Params:
key – must not be null.
value – must not be null.
timeout – the key expiration timeout.
unit – must not be null.

总结

使用重载方法时,需要确认方法每个参数的含义,确认方法的功能,虽然有些参数类型是一样的,但实现的功能也会千差万别。 切记切记。

posted @ 2021-03-31 11:58  不拖延从明天开始  阅读(3494)  评论(0编辑  收藏  举报
xxxx