redis总结笔记

为什么80%的码农都做不了架构师?>>>   hot3.png

1、Redis的介绍和安装部署
NOSQL =》 Not Only SQL
NOSQL以key-value形式存储
特点:非关系型、分布式、开源的、水平可扩展
NOSQL:  数据高并发读写
对海量数据的高效率存储和访问
对数据的搞可扩展性和高可用性
Redis是一个开源的先进的key-value存储。他被称为数据结构服务器,因为键包含字符串、哈希、链表、集合和有序集合
所有数据存储在内存中,可以周期性的把更新数据写入磁盘或者修改操作写入追加到记录文件

一般两种方式:
application 直接访问写读redis主从服务【有一定的数据隐患】
application 访问redis,访问redis失败后,再读写取数据库mysql
【应用程序读写redis时候,redis会同步到mysql中,确保redis集群和mysql集群数据同步,确保数据安全】


redis应用场景:
适合海量数据
1、取最小的N个数据的操作
2、排行榜应用,取Top N 的操作
3、需要精确设置过期时间的应用
4、计数器应用
5、Uniq操作,获取某段时间所有数据排重值
6、实时系统,反垃圾系统
7、Pub/Sub构建实时消息系统
8、构建队列系统
9、缓存

reids和MYSQL相同点和不同点,都有数据库的概念,reids无表无字段无序列,mysql有表和字段

reids安装:
解压文件
-- tar -xzvf redis-2.8.17.tar.gz
-- cd redis-2.8.17
编译和安装
-- make
-- cd src && make install
移动文件便于管理
-- mkdir -p /usr/local/redis/bin
-- mkdir -p /usr/local/redis/etc
-- mv ~/redis-2.8.17/redis.conf /usr/local/redis/etc
-- cd ~/redis-2.8.17/src
-- mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server /usr/local/redis/bin
启动Redis服务
-- /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
-- redis默认的端口6379
客户端连接
-- /usr/local/redis/bin/redis-cli
停止Redis服务
-- /usr/local/redis/bin/redis-cli shutdown
or
-- pkill redis-server

--后台启动redis
-- redis.conf daemonize 修改成yes
-- 查看端口 netstate -tunpl | grep 6379

2、redis数据类型
String 类型,一个Key对应一个value,string类型是二进制安全的,redis的string可以包含任何数据,比如图片二进制
set方法 设置key对应的值为string类型的value
eg:添加name=cxq的键值对
>>> set name cxq
get方法 获取key对应的值
>>> get name
setnx方法 设置可以对应的值为string类型的value,如果key已经存在返回0,nx标识no exist的意思.不存在则设置一个新值
>>> set name chenxiangqi
>>> get name
setex方法 设置key对应的值为string类型的value,并指定此键值对应的有效期
>>> setex haircolor 10 red //设置haircolor键对应的值为red 有效期10s
setrange方法 设置指定key的value值的子字符串
>>> get name
"cxq@126.com"
>>> setrange name 4 gmail.com //从[0开始]第4个字符往后替换
(integer) 13
>>> get name
mset方法 一次设置多个key的值,成功返回ok表示所有的值都设置了失败返回0表示所有的值都没有设置
>>> mset key1 cxq key2 chenxiangqi
msetnx方法 一次设置多个key的值,成功返回OK表示所有的值都设置了,失败返回0表示没有任何值被设置,但不会覆盖已经存在的key
>>> msetex key1 cxq key2 chenxiangqi
getset方法 设置key的值并返回key的旧值
>>> getset name 20
"30"
getrange方法 设置key的子字符串
>>> getrange name 0 5 //从name的值的第0个字符到第5个字符返回
mget方法 批量获取
>>> mget key1 key2 key3
incr方法 对key的值进行递增,并返回递增的值
>>> incr name 
“31”
incrby方法 同incr类似,加指定值,如果对应的可以不存在则加入新值,原来的值为0
>>> incrby key6 5  //让key6的值增加5
>>> incrby key6 -5 //让key6的值减少5
decr方法 对key的值进行自减操作
descrby方法 对key的值进行指定值减少
>>> decr key6 
>>> desrby key6 5
>>> desrby key6 -5 //让key6增加5
append方法  给指定key的字符串追加value,返回新字符串的长度
>>> append name .net
strlen方法  取指定key的值的字符串长度

Hash数据类型  是一个string类型的field和value的映射表,它可以添加删除操作都是01,hash特别适合存储对象,将一个对象存储在hash类型会占用更少的内存,并且更方便的存取整个对象
hset方法  设置hash field为指定值,如果key不存在则先创建
>>> hset myhash field1 Hello
>>> hset user:001 name chenxiangqi
>>> hget user:0001 name
hsetnx方法 设置hash field为指定值,如果key不存在则先创建
>>> hsetnx myhash field "HELLO"
(integer) 1
>>> hsetnx myhash field "HELLO"
(integer) 0
hmset方法 同时设置多个 hash 的多个field
>>> hmset myhash field "HELLO" field2 world
hget方法  
>>> hget user:003 name
hmget方法 获取hash 指定的多个键值
>>> hmget user:003 name sex age
hincrby方法 给指定的 hash field加上指定值
>>> hincrby user:003 age 5
hexists方法 测试指定的field是否存在
>>> hexists user:003 name
>>> hexists user:003 hhhhh
hlen方法 返回hash field所有的键数
>>> hlen user:001
>>> hlen user:003
hdel方法 删除指定hash的field
>>> hdel myhash age
hkeys方法 返回hash里面所有的field
>>> hkeys user:003
hvals方法 返回hash里面的索引value
>>> hvals user:003
hgetall方法  获取某个hash里面的所有的field和value
>>> hgetall user:003

List数据类型 List是一个链表结构、主要功能push、pop获取一个范围里面的值,List类型其实就是每个元素都是String类型的双向链表
lpush方法 对链表从头部压入一个元素
>>> lpush mylist world
>>> lpush mylist hello
lrang方法 对指定list取得指定区间的元素
>>> lrange mylist 0 -1 //从链表中取出从第一个元素取到最后一个元素
rpush方法 对list从尾部压入一个元素
>>> rpush mylist2 hello
>>> rpush mylist2 world
>>> lrange mylist2 0 -1
linsert方法 在key对应的list的特定位置前或后添加字符串
>>> rpush list:003 world
>>> linsert list:003 before world hello //在world前面插入hello
>>> lrange 0 -1
lset方法 设置list中指定下标的元素替换掉
>>> lpush list5 one
>>> lpush list5 two
>>> lpush list5 three
>>> lset list5 0 four  //设置下标为0的元素更改成four
>>> lrange list5 0 -1
lrem方法 从key对应的list中删除n个和value相同的值[n<0从未删除 n=0全部删除],返回的值为删除的个数
>>> lpush list6 one
>>> lpush list6 one
>>> lpush list6 one
>>> lrem list6 1 "one" //从list6中删除一个和one相同的值
ltrim方法 保留指定key的值范围内的数据
>>> lpush list8 "one"
>>> lpush list8 "two"
>>> lpush list8 "three"
>>> ltrim list8 1 -1 //保留下标从1到-1【最后】的元素,删除其他元素
lpop方法 从list的头部删除一个元素,并返回被删除的元素
>>> lpop list8
rpop方法 从list的尾部删除一个元素,并返回被删除的元素
>>> rpop list8
rpoplpush方法 从第一个list的尾部移除元素并添加到第二个list的头部
>>> rpoplpush list7 list8 //从list7中尾部移除一个元素并将该元素从头部压入list8
lindex方法返回名称key的list中index位置的元素
>>> lindex list5 1 //返回list5中元素索引下表为1[index]的元素
llen方法 返回key对应的list的长度
>>> llen list7


Set数据类型 集合,实际是String类型的无序集合,set通过hashtable实现。添加删除查找复杂度都是0(1)
sadd方法 向名称为key的set添加元素
>>> sadd set1 hello
>>> sadd set1 world
>>> sadd set1 world
srem方法 删除名称为key的set中的元素
>>> srem set1 world
spop方法 随机返回并删除名称为key的set中一个元素
>>> spop set2 "one" //无法指定的 error
>>> spop set2 "two" //无法指定的 error
>>> spop set2       //success 
sdiff方法 返回给定key与第一个key的差集【两个集合的差集,谁在前以谁为标准】
>>> sdiff set1 set2 //以set1为标准返回set1中对比set2中不同的元素
sdiffstore方法 返回索引给定key与第一个可以的差集,并将差集存储到指定的集合中
>>> smembers set1
>>> smembers set2
>>> sdifstore set1 set2 set3  //将set1和set2差集存储到set3中
sinter方法 返回给点key的交集
>>> sinter set1 set2 //返set1和set2的交集
sinterstore方法 返回指定交集并将交集存储到指定集合里面
>>> sinterstore set1 set2 set4
sunion方法 返回所有key的集合的并集
>>> sunion set1 set2
sunionstore方法
>>> sunionstore set1 set2 set5
smove方法 从给定的第一个key的集合移除某一个元素添加到第二个key指定的集合里面
>>> smove set1 set2 three //将set1中的three移除并添加到set2中
scard方法 返回名称为key的set的元素个数
>>> scard set2
sismember方法 测试某一个元素是否是 指定key对应的set的元素
>>> sismember set2 two //判断two是否是set2的元素
srandmember方法 随机返回名称为key的set的一个元素但不删除
>>> srandmember set2
smembers方法 展示指定集合的所有元素
>>>smembers set1

storted sets类型 是set的一个升级版本,他在set的基础上增加了一个顺序属性,在添加修改删除元素的时候可以指定,每次指定后,zset会自动为你排序
zadd方法 添加一个有序集合的元素,score 用于排序
>>> zadd zset1 1 "one" //项zset1中添加一个元素,指定顺序为1
>>> zadd zset1 2 "two"
>>> zadd zset1 3 "two"
zrange方法 取得有序集合里面的元素【指定范围,withscores输出顺序号】
>>> zrange zset1 0 -1 withscores //输出zset1中索引为0到-1 的元素,并输出顺序号
zrem方法 删除名称为key的zset的元素member
>>> zrem zset1 two  //删除zset1中的two
zincry方法 如果在名称为key的zset中已经存在元素member,则该元素的score增加increment否则项该集合中添加该元素,其score的值为increment
>>> zincry zset3 1 "one"
>>> zincry zset3 2 "two"
>>> zincry zset3 3 "three"
zrank方法 返回名称为key的zset中member的排名(按score从小到大排序)即下标
>>> zrank zset3 tow
zrevrank方法 返回名称为key的zset中member的排名(按score从大到小排序)即下标
>>> zrevrank zset3 two
zrangebyscore方法 返回指定socre的范围的元素
>>> zrangebyscore zset3 2 3 withsocres
zcount 返回指定score的给定区间的数量
>>> zcount zset3 2 4
zcard方法 返回给点key的zset的所有元素个数
zremrangebyrank方法 删除zset中排名在给定区间的元素
>>> zremrangebyrank zset3 1 1 //删除zset3的根据下表排名的 索引1到1的元素
zremrangebyscore方法 删除集合中的指定score的区间的元素
>>> zremrangebyscore方法 zset3 3 4


3、redis常用命令及高级应用
键值相关命令
keys 返回满足给定pattern的所有的key
>>> keys *
>>> keys r*
exists 确认一个key是否存在 0不存在 1 存在
>>> exists name
>>> exists age
del  删除一个key  1 成功 
>>> del age
expire 设置一个key的过期时间
ttl 获取一个key的有效时长
>>> expire age 10
>>> ttl age
move 将当前数据库的key移转到其他库中
select  选择数据库
>>> select 0
>>> set age 30
>>> get age 
>>> move age 1
>>> get age 
>>> select 1 
>>> get age
persist 移除给定key的过期时间
>>> expire age 3000
>>> ttl age
>>> perisist age
>>> ttl age
randomkey 随机返回key空间的一个key
>>> randomkey
rename 重命名key
>>> rename set2 set_r_2
type 测试key返回值类型
>>> type set2
>>> type set_r_2

服务器相关命令
ping 测试链接是否存活 PONG存活  否则连接失败
>>> ping
echo 在命令行打印一些内容
select 选择数据库【redis数据库编号从0~15】
quit 退出连接
dbsize 返回当前数据库中key的数目
>>> dbsize  
>>> select 1
>>> dbsize
info 获取redis服务器相关的信息
>>> info
config get 实时转储收到的请求 、返回相关配置的数据
>>> config get dir
>>> config get *
>>> config get timeout
flushdb 删除当前数据库中的所有key
>>> dbsize
>>> flushdb
>>> dbsize
flushall 删除所有数据库的所有键

4、Redis高级应用
安全性:
设置客户端来年结婚进行任何其他指定前需要使用的密码,
警告:因为redis速度非常快,所以设置密码要求很强,否则1s中能允许15万次的密码尝试
//在配置文件中配置requirepass 密码
#requirepass foobared
requirepass beijing 

客户端登录后 auth 密码;
登录时候 redis-cli -a 密码


主从复制:
主从复制允许多个slave server 拥有和master server相同的数据库副本
redis主从复制特点
1)master可以用于多个slave【副服务器】
2)多个slave可以连接同一个master外,还可以链接到其他slave
3)主从复制不会阻塞master,在同步数据时,master可以继续处理client请求
4)提高系统的伸缩扩展性【原理:当一个主机当机,其他另外一个slave立马变成主机(依靠心跳感应)】

redis主从复制过程:
slave与master建立连接,发送sync同步命令
master启动后台进程,将数据库快照保存到文件中,同时master主进程会开始手机新的写命令并缓存
后台完成保存后,将此文件发送给slave
slave将此文件保存到硬盘上

配置主从服务器
配置slave服务器很简单,只需要在slave的配置文件加入以下配置
slaveof 192.168.1.1 6379 #指定master的ip和端口
masterauth beijing #这是主机密码

事务处理:
支持事务比较简单,redis织女呢个保证一个client发起的事务中的命令
可以连续只写,而中间不会插入其他命令,
当一个茨愣头在一个连接中发出multi命令时,这个连接会进入一个事务上下文,
该连接后续的命令不会立即执行,而是先放到一个队列中,
当只写exec命令时候,redis会顺序只写队列中的所有命令
multi 打开事务上下文
discard 取消事务,事务回滚
exec 执行事务
>>> get age
>>> multi
>>> set age 10
>>> set age 20
>>> exec 
>>> getage
注意;当执行事务上下文的时候,假如事务队列里面的命令有错误,执行后会发现事务不能回滚。此为redis的事务处理很简单

乐观锁:基于数据库版本的提供一个version字段,记录数据更新版本。
redis乐观锁 : 假如有一个age的key 打开2个session对age进行赋值吵嘴哦,我们看一下结果如何
1) session 1
>>> get age
>>> watch age //监控age是否修改
>>> multi
2)session 2
>>> set age 30
>>> get age
3) session 1 在开启事务后
>>> set age 40
>>> exec
>>> get age
持久化机制:
Redis支持两种持久化方式:
1、snapshotting(快照)也是默认方式
2、Append-Only(缩写aof)的方式

快照方式;
将内存中的数据以快照的方式写到二进制文件。默认文件名dump.rdb
可以通过配置设置自动做快照持久化的方式.
可以配置redis在n秒内如果超过m个key被修改就自动做快照
save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内如果超过10个可以被修改,则发起快照保存
save 60 10000

Aof方式:
由于快照方式有一定的时间建个,aof比快照方式有更好的持久化性,
由于使用aof时候,redis会将每一个接受到的写命令通过write函数追加到文件中,
当redis重启后后通过重新执行文件中保存的写命令来在内存中重建整个数据库内容。

由于os会在内核中write做的修改,所以不是立即写到磁盘上,通过配置文件告诉redis
通过fsync函数强制os写入磁盘的时机
appendonly yes //启用aof持久化方式
#appendfsync always //收到写命令立即写入磁盘、最慢、但是保证完整的持久化
appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中
#appendfsync no //完全依赖os,性能最好,持久化没保证

发布订阅消息:
pub/sub是一种消息通信模式,主要目的解除消息发布者和消息订阅者之间的耦合,
Redis作为pub/sub的server,在订阅者和发布者之间起到消息路由的功能。
订阅者可以通过subscribe和psubscribe命令项redis server订阅自己感兴趣的消息类型
Redis将消息类型称为通道 channel,当发布者通过publish命令向 redis Server 发送特定类型的信息时候,
该信息类型的全部client都会收到此消息。



虚拟内存的使用:
Redis的虚拟内存,将不经常使用的数据从内存交换到磁盘中。
配置 VM:
vm-enabled yes     # 开启VM功能
vm-swap-file  /temp/redis.swap # 交换出来的value保存的文件路径
vm-max-memory 1000000 # redis使用的最大内存上限
vm-page-size 32 #每个页面的大小32字节
vm-pages 134217728 #最高使用多少页面
vm-max-threads 4 #用于执行value对象换入换出的工作线程数量



转载于:https://my.oschina.net/exit/blog/353021

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go kegg_GO,KEGG富集分析工具——DAVID

DAVID(https://david.ncifcrf.gov/home.jsp)是一个生物信息数据库&#xff0c;整合了生物学数据和分析工具&#xff0c;为大规模的基因或蛋白列表(成百上千个基因ID或者蛋白ID列表)提供系统综合的生物功能注释信息&#xff0c;帮助用户从中提取生物学信息。DAVID目前的工具可以…

更轻易地实现 Jwt Token

更轻易地实现一个 Jwt ServerIntro最近在多个项目中都有用到 Jwt Token 认证&#xff0c;就想着把之前项目里 Jwt Token 的使用封装一下&#xff0c;以便于之后集成起来更加地方便&#xff0c;不用再拷贝代码了JWTJWT 是 JSON Web Token 的缩写&#xff0c;是目前最流行的基于 …

android之实现各个组件点击事件处理

android之实现各个组件点击事件处理&#xff1a;注意&#xff1a;&#xff08;TextView这个组件要点击产生效果的话&#xff0c;要设置&#xff0c;android:clickable"true"这个属性&#xff09;布局&#xff1a;layout/activity_main.xml<LinearLayout xmlns:and…

Android开发最佳实践《IT蓝豹》

Android开发最佳实践 移动开发Android经验分享应用GoogleMaterial Design摘要&#xff1a;前 段时间&#xff0c;Google公布了Android开发最佳实践的一系列课程&#xff0c;涉及到一些平时开发过程中应该保持的良好习惯以及如何使用最新的Android Design Support Library来快速…

.NET MAUI 已在塔架就位 ,4月份发布RC

最美人间三月天&#xff0c;春光不负赶路人。在充满无限希望的明媚春天里&#xff0c;一路风雨兼程的.NET 团队正奋力实现新的突破。根据计划&#xff0c;新一代移动开发平台MAUI 将于4月份 发布RC。目前&#xff0c;MAUI的测试工作和火箭发射前各项准备工作在github 上按计划有…

如何把照片正面变成反面_没有锁边机如何做衣服(五种方法)

这么多年一直没有锁边机&#xff0c;但是也做了很多衣服&#xff0c;今天给大家分享一些我曾经用过的方法。来去缝来去缝适合缝制轻薄面料&#xff0c;如雪纺、真丝、欧根纱等。反反相对&#xff0c;缝份0.5厘米把缝份剪掉0.2厘米翻过来使正面相对&#xff0c;留0.5厘米的缝份车…

linux线程池资料

2019独角兽企业重金招聘Python工程师标准>>> http://www.360doc.com/content/13/0728/13/13308646_303116654.shtml http://blog.csdn.net/turkeyzhou/article/details/8755976 http://blog.csdn.net/zhoubl668/article/details/8927090 http://blog.csdn.net/zypue…

Xamarin效果第二篇之公众号App

前面简单摸索一下Xamarin然后简单做了一个时间轴;这不这几天再次基于Xamarin实现了一下公众号App;我也就是瞎折腾,闲话不多扯,上效果:主Page直接用TabbedPage(类似WPF中的TabControl)然后后台添加内容Page:”互动“页使用CollectionView和模板选择器&#xff1a;"发表&quo…

K8S原来如此简单(一)K8S核心组件与基本原理

k8s视频课程K8S核心组件与工作原理k8s官方文档&#xff1a;https://kubernetes.io/zh/docs/home/前提掌握容器技术&#xff1a;Docker&#xff0c;Containerd等K8S优势使用简单&#xff0c;少量人/小团队可以轻松维护大型分布式系统全面拥抱微服务架构&#xff0c;快速迭代&…

docker supervisor管理进程

Supervisor管理进程Docker容器在启动的时候开启单个进程&#xff0c;比如&#xff0c;一个ssh或者apache的daemon服务。但我们经常需要在一个机器上开启多个服务&#xff0c;这可以有很多方法&#xff0c;最简单的就是把多个启动命名放到一个启动脚本里面&#xff0c;启动的时候…

理解Linux系统中的load average

一、什么是load average&#xff1f;linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount of work that a computer system is doing)。也有简单的说是进程队列的长度。Load Average 就是一段时间 (1 分钟、5分钟、15分钟) 内平均…

【贯穿】.NET6结合Docker傻瓜式实现容器编排

常规开发部署的痛点一个项目的开发上线有很多纷繁复杂的问题&#xff0c;例如&#xff1a;操作系统运行环境以及各种应用配置、集群环境搭建等等。特别是各种版本的迭代导致的不兼容&#xff0c;这些对于曾经的架构师而言也十分苦恼。而Docker的出现实现了从“蚂蚁搬家”到“乾…

bootstrapt 表格自适应_一起聊B端设计 - 如何设计表格?

一、 数据查看让我们先来回顾一下表格的基本构成&#xff0c;最上面的为表头&#xff0c;横为行&#xff0c;纵为列&#xff0c;内容区每一组展示数据区域为单元格。 表格的设计&#xff0c;虽然看似简单&#xff0c;但是作为用户最常用的组件之一&#xff0c;我们需要对视觉和…

.NET 6 攻略大全(二)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;15分钟)接上篇内容&#xff0c;本篇文章将介绍&#xff1a;Arm64、容器、支持 OpenTelemetry 指标、Windows Forms 的相关攻略。 Arm64这些天来&#xff0c;对于笔记本电脑、云硬件和其他设备来说&#xff0c;Arm64 令…

ubuntu 开启 apache mod_rewrite

2019独角兽企业重金招聘Python工程师标准>>> ci里需要隐藏index.php的输入需要使用apache的rewrite模块,按照下面的步骤开启mod_rewrite http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/ 转载于:https://my.oschina.net/u/1177171/blog/354202

composer切换源_Composer具体安装方法

composer 作为依赖管理工具&#xff0c;使用频率还是挺高的。特别是对于我这种比较懒的程序猿&#xff0c;有现成轮子的时候坚决不自己重复造轮子。它主要有三部分构成&#xff1a;命令行工具&#xff0c;包仓库&#xff0c;代码库。包仓库就是我们常说的 composer 源&#xff…

C# 操作FireBird 附源码

写了一个C#操作firebird数据库的小Demo&#xff0c;有需要的可以研究研究, 步骤&#xff1a; 1.创建数据库 2.建数据表&#xff0c;插入数据&#xff0c;并读取、 写的时候碰到N多奇葩问题&#xff0c;记录了一些 解决方案&#xff1a; 程序集-生成-目标平台 改成 x86 源码地址…

.NET 6 攻略大全(三)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;15分钟).NET 6 继续与大家相约周日啦。本篇文章将介绍&#xff1a;单文件应用、IL 修整、System.Text.Json、源代码构建、库AIP的相关攻略。 单文件应用 在 .NET 6中&#xff0c;已为 Windows 和 macOS 启用内存中单文…

测试眉形的有哪个软件_这五款自动化软件测试工具,你最喜欢用哪个?

对测试自动化的依赖性增加导致大量自动化软件测试工具的出现&#xff0c;使得很难确定哪些是最好的。为了帮助您完成自动化工作&#xff0c;我们根据自己和他人的经验创建了五大最佳自动化软件测试工具列表。1. SeleniumSelenium可以说是web开发人员和测试人员中最受欢迎的自动…

本科 8年经验,20k的Offer,接还是不接?

伴随着疫情的此起彼伏&#xff0c;今年的金三银四跳槽季比往年要低沉很多&#xff0c;近日一条朋友圈火遍社区&#xff0c;“坐标一线城市&#xff0c;本科毕业&#xff0c;8年经验&#xff0c;15天仅5场面试&#xff0c;最终接了20k的offer&#xff0c;今年真难&#xff01;”…