起立!这份Redis笔记面试官看了高呼空前绝后!,spring的相关面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

2. set

【大厂面试】面试官看了赞不绝口的Redis笔记

可选参数

从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改:

EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。

PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。

NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。

XX : 只在键已经存在时, 才对键进行设置操作。

关于返回值

在 Redis 2.6.12 版本以前, SET 命令总是返回 OK 。

从 Redis 2.6.12 版本开始, SET 命令只在设置操作成功完成时才返回 OK ; 如果命令使用了 NX 或者 XX 选项, 但是因为条件没达到而造成设置操作未执行, 那么命令将返回空批量回复(NULL Bulk Reply)。

3. INCR

【大厂面试】面试官看了赞不绝口的Redis笔记

对储存数字值的键 key 执行 DECR 命令:

redis> SET page_view 20

OK

redis> INCR page_view

(integer) 21

redis> GET page_view # 数字值在 Redis 中以字符串的形式保存

“21”

对不存在的键执行 DECR 命令:

redis> EXISTS count

(integer) 0

redis> DECR count

(integer) -1

4. DECR

【大厂面试】面试官看了赞不绝口的Redis笔记

对已经存在的键执行 DECRBY 命令:

redis> SET count 100

OK

redis> DECRBY count 20

(integer) 80

对不存在的键执行 DECRBY 命令:

redis> EXISTS pages

(integer) 0

redis> DECRBY pages 10

(integer) -10

5. INCRBY

【大厂面试】面试官看了赞不绝口的Redis笔记

示例演示与上面类似

6. DECRBY

【大厂面试】面试官看了赞不绝口的Redis笔记

示例演示与上面类似

使用上面这一些命令,其实我们就可以做一些事情了。

应用

1.比如说记录每个用户博文的访问量

incr userid:pageview(单线程:无竞争)

2.缓存用户的基本信息(数据源在 MySQL中),信息被序列化存放在value中。

【大厂面试】面试官看了赞不绝口的Redis笔记

一般而言,需要通过我们自定义规则的key,从Redis获取value,如果key存在的话,则直接获取value使用;如果不存在的话,从Mysql中读取使用,然后存在Redis中。

主要的命令是 get 和 set

【大厂面试】面试官看了赞不绝口的Redis笔记

3.分布式id生成器

如果集群规模和运算不太复杂的话,可以用Redis生成分布式id,因为Redis单线程的特点,一次只执行一条指令,保证了id值的唯一。

主要的命令还是incr

【大厂面试】面试官看了赞不绝口的Redis笔记

7. SETNX

【大厂面试】面试官看了赞不绝口的Redis笔记

redis> EXISTS job # job 不存在

(integer) 0

redis> SETNX job “programmer” # job 设置成功

(integer) 1

redis> SETNX job “code-farmer” # 尝试覆盖 job ,失败

(integer) 0

redis> GET job # 没有被覆盖

“programmer”

8. SETEX

【大厂面试】面试官看了赞不绝口的Redis笔记

SETEX 命令的效果和以下两个命令的效果类似:

SET key value

EXPIRE key seconds # 设置生存时间

SETEX 和这两个命令的不同之处在于 SETEX 是一个原子(atomic)操作, 它可以在同一时间内完成设置值和设置过期时间这两个操作, 因此 SETEX 命令在储存缓存的时候非常实用。

这两个命令的典型应用就是分布式锁了。

⽐如⼀个操作要修改⽤户的状态,修改状态需要先读出⽤户的状态,在内存⾥进⾏修改,改完了再存回去。如果这样的操作同时进⾏了,就会出现并发问题。这个时候就要使⽤到分布式锁来限制程序的并发执⾏。Redis 分布式锁使⽤⾮常⼴泛,必须要掌握。

分布式锁本质上要实现的⽬标就是在 Redis ⾥⾯占⼀个“位置”,当别的进程也要来占时,发现“位置”被占了,就只好放弃或者稍后

再试。

占位置⼀般是使⽤ setnx(set if not exists) 指令,只允许被⼀个客户端占据。先来先占,⽤完了,再调⽤ del 指令释放位置。

如果逻辑执⾏到中间出现异常了,可能会导致 del指令没有被调⽤,这样就会陷⼊死锁,锁永远得不到释放。于是我们在拿到锁之后,再给锁加上⼀个过期时间。

但如果在 setnx 和 expire 之间服务器进程突然挂掉了,可能是因为机器掉电或者是被⼈为杀掉的,就会导致expire 得不到执⾏,也会造成死锁。

原因是 setnx 和 expire 是两条指令⽽不能保证都一定成功执行。如果这两条指令可以⼀起执⾏就不会出现问题(要么成功,要么失败)。所以说setex是最佳的方案

上面就是分布式锁的基本思想。但是在真正投入使用的时候,还会面临一个常见的问题:超时问题

Redis 的分布式锁不能解决超时问题,如果在加锁和释放锁之间的逻辑执⾏的时间太⻓,超出了锁的超时限制,就会出现问题。这时候第⼀个线程持有的锁过期了,临界区的逻辑没有执⾏完,而第⼆个线程就提前重新持有了这把锁,导致临界区代码不能严格地串⾏执⾏。

为了避免这个问题,Redis 分布式锁不要⽤于较⻓时间的任务。

我们会在下篇文章,也就是分布式章节继续探讨分布式锁。

9. MSET

【大厂面试】面试官看了赞不绝口的Redis笔记

同时对多个键进行设置:

redis> MSET date “2012.3.30” time “11:00 a.m.” weather “sunny”

OK

redis> MGET date time weather

  1. “2012.3.30”

  2. “11:00 a.m.”

  3. “sunny”

覆盖已有的值:

redis> MGET k1 k2

  1. “hello”

  2. “world”

redis> MSET k1 “good” k2 “bye”

OK

redis> MGET k1 k2

  1. “good”

  2. “bye”

10 . MGET

【大厂面试】面试官看了赞不绝口的Redis笔记

redis> SET redis redis.com

OK

redis> SET mongodb mongodb.org

OK

redis> MGET redis mongodb

  1. “redis.com”

  2. “mongodb.org”

redis> MGET redis mongodb mysql # 不存在的 mysql 返回 nil

  1. “redis.com”

  2. “mongodb.org”

  3. (nil)

下面说说mset和mget的好处

不使用mget和mset::

【大厂面试】面试官看了赞不绝口的Redis笔记

客户端和服务器端可能不在同一个地方n次get/set=n次网络时间+n次命令时间

一次mget/mset:

【大厂面试】面试官看了赞不绝口的Redis笔记

1次mget/mset=1次网络时间+n次命令时间

随着n的增大,差距一下子就体现出来了。

下面的命令不太常用,大体过一下:

10. GETSET

GETSET key value

将键 key 的值设为 value , 并返回键 key 在被设置之前的旧值。

11. STRLEN

STRLEN key

返回键 key 储存的字符串值的长度

12. APPEND

APPEND key value

如果键 key 已经存在并且它的值是一个字符串, APPEND 命令将把 value 追加到键 key 现有值的末尾。

13. INCRBYFLOAT

INCRBYFLOAT key increment

为键 key 储存的值加上浮点数增量 increment 。

如果键 key 不存在, 那么 INCRBYFLOAT 会先将键 key 的值设为 0 , 然后再执行加法操作。

如果命令执行成功, 那么键 key 的值会被更新为执行加法计算之后的新值, 并且新值会以字符串的形式返回给调用者。

无论是键 key 的值还是增量 increment , 都可以使用像 2.0e7 、 3e5 、 90e-2 那样的指数符号(exponential notation)来表示, 但是, 执行 INCRBYFLOAT 命令之后的值总是以同样的形式储存, 也即是, 它们总是由一个数字, 一个(可选的)小数点和一个任意长度的小数部分组成(比如 3.14 、 69.768 ,诸如此类), 小数部分尾随的 0 会被移除, 如果可能的话, 命令还会将浮点数转换为整数(比如 3.0 会被保存成 3 )。

此外, 无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 命令的计算结果最多只保留小数点的后十七位。

当以下任意一个条件发生时, 命令返回一个错误:

键 key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型);

键 key 当前的值或者给定的增量 increment 不能被解释(parse)为双精度浮点数。

14. GETRANGE

GETRANGE key start end

返回键 key 储存的字符串值的指定部分, 字符串的截取范围由 start 和 end 两个偏移量决定 (包括 start 和 end 在内)。

负数偏移量表示从字符串的末尾开始计数, -1 表示最后一个字符, -2 表示倒数第二个字符, 以此类推。

GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

15. SETRANGE

SETRANGE key offset value

从偏移量 offset 开始, 用 value 参数覆写(overwrite)键 key 储存的字符串值。

不存在的键 key 当作空白字符串处理。

SETRANGE 命令会确保字符串足够长以便将 value 设置到指定的偏移量上, 如果键 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ), 那么原字符和偏移量之间的空白将用零字节(zerobytes, “\x00” )进行填充。

因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内, 所以用户能够使用的最大偏移量为 2^29-1(536870911) , 如果你需要使用比这更大的空间, 请使用多个 key 。

在对字符串类型有了整体的了解之后,我们看看它具体的结构

Redis 的字符串名字是SDS(Simple Dynamic String)。它的结构是⼀个带⻓度信息的字节数组。

struct SDS {

T capacity; // 数组容量

T len; // 数组⻓度

byte flags; // 特殊标识位,不理睬它

byte[] content; // 数组内容

}

capacity 表示所分配数组的⻓度,len 表示字符串的实际⻓度。前⾯API提到⽀持 append操作(字符串是可修改的)。如果数组没有冗余空间,那么追加操作必然涉及到分配新数组,然后将旧内容复制过来,再 append 新内容。如果字符串的⻓

度⾮常⻓,这样的内存分配和复制开销就会⾮常⼤。

/* Append the specified binary-safe string

pointed by ‘t’ of ‘len’ bytes to the

  • end of the specified sds string ‘s’

.

  • After the call, the passed sds string is no

longer valid and all the

  • references must be substituted with the new

pointer returned by the call.

*/

sds sdscatlen(sds s, const void *t, size_t len) {

size_t curlen = sdslen(s); // 原字符串⻓度

// 按需调整空间,如果 capacity 不够容纳追加的内容,就会重新分配字节数组并复制原字符串的内容到新数组中

s = sdsMakeRoomFor(s,len);

if (s == NULL) return NULL; // 内存不⾜

memcpy(s+curlen, t, len); // 追加⽬标字符串的内容到字节数组中

sdssetlen(s, curlen+len); // 设置追加后的⻓度值

s[curlen+len] =‘\0’; // 让字符串以\0 结尾,便于调试打印,还可以直接使⽤ glibc 的字符串函数进⾏操作

return s;

}

上⾯的 SDS 结构使⽤了范型 T,这是Redis 对内存做出的优化,不同⻓度的字符串使⽤不同的结构体来表示,字符串⽐较短时,len 和 capacity 可以使⽤ byte 和 short来表示。

Redis 规定字符串的⻓度不得超过 512M 字节。创建字符串时 len和 capacity ⼀样⻓,不会多分配冗余空间,这是因为绝⼤多数场景下我们不会使⽤ append 操作来修改字符串。

(五)hash (字典)

Redis 的字典结构为数组 +链表⼆维结构。第⼀维 hash 的数组位置碰撞时,就会将碰撞的元素使⽤链表串接起来。Redis 的字典的值只能是字符串。当字典很大的时候,会进行rehash,Redis 为了⾼性能,不能堵塞服务,采⽤了渐进式 rehash 策略。

渐进式 rehash 保留新旧两个 hash 结构,查询时会同时查询两个 hash 结构,然后在后续的定时任务中以及hash 操作指令中,循序渐进地将旧 hash 的内容⼀点点迁移到新的hash 结构中。当搬迁完成了,就会使⽤新的hash结构取⽽代之。当 hash 移除了最后⼀个元素之后,该数据结构⾃动被删除,内存被回收。

【大厂面试】面试官看了赞不绝口的Redis笔记

下面我们看一下它的API, 所有hash的命令都是h开头

1. HSET hash field value

时间复杂度: O(1)

将哈希表 hash 中域 field 的值设置为 value 。如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET 操作。如果域 field 已经存在于哈希表中, 那么它的旧值将被新值 value 覆盖。当 HSET 命令在哈希表中新创建 field 域并成功为它设置值时, 命令返回 1 ; 如果域 field 已经存在于哈希表, 并且 HSET 命令成功使用新值覆盖了它的旧值, 那么命令返回 0 。

设置一个新域:

redis> HSET website google “www.g.cn”

(integer) 1

redis> HGET website google

“www.g.cn”

对一个已存在的域进行更新:

redis> HSET website google “www.google.com”

(integer) 0

redis> HGET website google

“www.google.com”

2.HGET hash field

时间复杂度: O(1)

返回哈希表中给定域的值。HGET 命令在默认情况下返回给定域的值。如果给定域不存在于哈希表中, 又或者给定的哈希表并不存在, 那么命令返回 nil 。

域存在的情况:

redis> HSET homepage redis redis.com

(integer) 1

redis> HGET homepage redis

“redis.com”

域不存在的情况:

redis> HGET site mysql

(nil)

3.HDEL

HDEL key field [field …]

O(N), N 为要删除的域的数量。

删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。返回值为被成功移除的域的数量,不包括被忽略的域。

测试数据

redis> HGETALL abbr

  1. “a”

  2. “apple”

  3. “b”

  4. “banana”

  5. “c”

  6. “cat”

  7. “d”

  8. “dog”

删除单个域

redis> HDEL abbr a

(integer) 1

删除不存在的域

redis> HDEL abbr not-exists-field

(integer) 0

删除多个域

redis> HDEL abbr b c

(integer) 2

redis> HGETALL abbr

  1. “d”

  2. “dog”

4. HSETNX hash field value

时间复杂度: O(1)

当且仅当域 field 尚未存在于哈希表的情况下, 将它的值设置为 value 。如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。如果哈希表 hash 不存在, 那么一个新的哈希表将被创建并执行 HSETNX 命令。HSETNX 命令在设置成功时返回 1 , 在给定域已经存在而放弃执行设置操作时返回 0 。

域尚未存在, 设置成功:

redis> HSETNX database key-value-store Redis

(integer) 1

redis> HGET database key-value-store

“Redis”

域已经存在, 设置未成功, 域原有的值未被改变:

redis> HSETNX database key-value-store Riak

(integer) 0

redis> HGET database key-value-store

“Redis”

5. HLEN

时间复杂度:O(1)

返回哈希表 key 中域的数量。当 key 不存在时,返回 0 。

redis> HSET db redis redis.com

(integer) 1

redis> HSET db mysql mysql.com

(integer) 1

redis> HLEN db

(integer) 2

redis> HSET db mongodb mongodb.org

(integer) 1

redis> HLEN db

(integer) 3

6.HMSET

HMSET key field value [field value …]

时间复杂度:O(N), N 为 field-value 对的数量。

同时将多个 field-value (域-值)对设置到哈希表 key 中。此命令会覆盖哈希表中已存在的域。如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。如果命令执行成功,返回 OK 。当 key 不是哈希表(hash)类型时,返回一个错误。

redis> HMSET website google www.google.com yahoo www.yahoo.com

OK

redis> HGET website google

“www.google.com”

redis> HGET website yahoo

“www.yahoo.com”

7. HMGET

HMGET key field [field …]

时间复杂度:O(N), N 为给定域的数量。

返回哈希表 key 中,一个或多个给定域的值。

如果给定的域不存在于哈希表,那么返回一个 nil 值。因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。具体返回一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。

redis> HMSET pet dog “doudou” cat “nounou” # 一次设置多个域

OK

redis> HMGET pet dog cat fake_pet # 返回值的顺序和传入参数的顺序一样

  1. “doudou”

  2. “nounou”

  3. (nil) # 不存在的域返回nil值

8.HINCRBY

HINCRBY key field increment

时间复杂度:O(1)

为哈希表 key 中的域 field 的值加上增量 increment 。增量也可以为负数,相当于对给定域进行减法操作。如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。本操作的值被限制在 64 位(bit)有符号数字表示之内。执行 HINCRBY 命令之后,返回值哈希表 key 中域 field 的值。

increment 为正数

redis> HEXISTS counter page_view # 对空域进行设置

(integer) 0

redis> HINCRBY counter page_view 200

(integer) 200

redis> HGET counter page_view

“200”

increment 为负数

redis> HGET counter page_view

“200”

redis> HINCRBY counter page_view -50

(integer) 150

redis> HGET counter page_view

“150”

尝试对字符串值的域执行HINCRBY命令

redis> HSET myhash string hello,world # 设定一个字符串值

(integer) 1

redis> HGET myhash string

“hello,world”

redis> HINCRBY myhash string 1 # 命令执行失败,错误。

(error) ERR hash value is not an integer

redis> HGET myhash string # 原值不变

“hello,world”

9. HKEYS

时间复杂度:O(N), N 为哈希表的大小。

返回哈希表 key 中的所有域。即一个包含哈希表中所有域的表。当 key 不存在时,返回一个空表。

哈希表非空

redis> HMSET website google www.google.com yahoo www.yahoo.com

OK

redis> HKEYS website

  1. “google”

  2. “yahoo”

空哈希表/key不存在

redis> EXISTS fake_key

(integer) 0

redis> HKEYS fake_key

(empty list or set)

10.HVALS

HVALS key

时间复杂度:O(N), N 为哈希表的大小。

返回哈希表 key 中所有域的值。即一个包含哈希表中所有值的表。当 key 不存在时,返回一个空表。

非空哈希表

redis> HMSET website google www.google.com yahoo www.yahoo.com

OK

redis> HVALS website

  1. “www.google.com”

  2. “www.yahoo.com”

空哈希表/不存在的key

redis> EXISTS not_exists

(integer) 0

redis> HVALS not_exists

(empty list or set)

11.HGETALL

时间复杂度:O(N), N 为哈希表的大小。

HGETALL key

返回哈希表 key 中,所有的域和值。在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。返回值以列表形式返回哈希表的域和域的值。若 key 不存在,返回空列表。

redis> HSET people jack “Jack Sparrow”

(integer) 1

redis> HSET people gump “Forrest Gump”

(integer) 1

redis> HGETALL people

  1. “jack” # 域

  2. “Jack Sparrow” # 值

  3. “gump”

  4. “Forrest Gump”

小心单线程 数据量大的话 会比较慢

12. hsetnx

时间复杂度: O(1)

当且仅当域 field 尚未存在于哈希表的情况下, 将它的值设置为 value 。如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。如果哈希表 hash 不存在, 那么一个新的哈希表将被创建并执行 HSETNX 命令。HSETNX 命令在设置成功时返回 1 , 在给定域已经存在而放弃执行设置操作时返回 0 。

域尚未存在, 设置成功:

redis> HSETNX database key-value-store Redis

(integer) 1

redis> HGET database key-value-store

“Redis”

域已经存在, 设置未成功, 域原有的值未被改变:

redis> HSETNX database key-value-store Riak

(integer) 0

redis> HGET database key-value-store

“Redis”

13. hincrbyfloat

HINCRBYFLOAT key field increment

时间复杂度:O(1)

为哈希表 key 中的域 field 加上浮点数增量 increment 。如果哈希表中没有域 field ,那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ,然后再执行加法操作。如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。当以下任意一个条件发生时,返回一个错误:

域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)

域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)

返回值为返回值:执行加法操作之后 field 域的值。

值和增量都是普通小数

redis> HSET mykey field 10.50

(integer) 1

redis> HINCRBYFLOAT mykey field 0.1

“10.6”

值和增量都是指数符号

redis> HSET mykey field 5.0e3

(integer) 0

redis> HINCRBYFLOAT mykey field 2.0e2

“5200”

对不存在的键执行 HINCRBYFLOAT

redis> EXISTS price

(integer) 0

redis> HINCRBYFLOAT price milk 3.5

“3.5”

redis> HGETALL price

  1. “milk”

  2. “3.5”

对不存在的域进行 HINCRBYFLOAT

redis> HGETALL price

  1. “milk”

  2. “3.5”

redis> HINCRBYFLOAT price coffee 4.5 # 新增 coffee 域

“4.5”

redis> HGETALL price

  1. “milk”

  2. “3.5”

  3. “coffee”

  4. “4.5”

知道上面的命令后,就可以做一些事情了。

应用类似于字符串,我们可以记录网站每个用户个人主页的访问量

hincrby user chenxiao pageviewCount

当然还有缓存用户信息。

对于记录个人主页的访问量,自然字符串要比hash更好点。

但是对于缓存用户新信息这种逻辑要好好斟酌一下

字符串Key:Value的结构:(第一种方案 String-v1)

key: ‘user:userId’

value:

{

“name”: “chenxiao”,

“age”:100,

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Java核心知识

  • Spring全家桶(实战系列)

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

  • 其他电子书资料

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

值和增量都是普通小数

redis> HSET mykey field 10.50

(integer) 1

redis> HINCRBYFLOAT mykey field 0.1

“10.6”

值和增量都是指数符号

redis> HSET mykey field 5.0e3

(integer) 0

redis> HINCRBYFLOAT mykey field 2.0e2

“5200”

对不存在的键执行 HINCRBYFLOAT

redis> EXISTS price

(integer) 0

redis> HINCRBYFLOAT price milk 3.5

“3.5”

redis> HGETALL price

  1. “milk”

  2. “3.5”

对不存在的域进行 HINCRBYFLOAT

redis> HGETALL price

  1. “milk”

  2. “3.5”

redis> HINCRBYFLOAT price coffee 4.5 # 新增 coffee 域

“4.5”

redis> HGETALL price

  1. “milk”

  2. “3.5”

  3. “coffee”

  4. “4.5”

知道上面的命令后,就可以做一些事情了。

应用类似于字符串,我们可以记录网站每个用户个人主页的访问量

hincrby user chenxiao pageviewCount

当然还有缓存用户信息。

对于记录个人主页的访问量,自然字符串要比hash更好点。

但是对于缓存用户新信息这种逻辑要好好斟酌一下

字符串Key:Value的结构:(第一种方案 String-v1)

key: ‘user:userId’

value:

{

“name”: “chenxiao”,

“age”:100,

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

[外链图片转存中…(img-Whe8TYqQ-1713362770692)]

Java核心知识

  • Spring全家桶(实战系列)

[外链图片转存中…(img-yM937cDT-1713362770693)]

  • 其他电子书资料

[外链图片转存中…(img-ZfiKHBgM-1713362770693)]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-jUIUH0Ra-1713362770693)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-oquZmxZu-1713362770694)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值