一篇文章让你快速入门Redis(含安装使用客户端)

声明:文章内容皆取于学习黑马课程、若想了解原版内容请去B站了解黑马程序员Redis课程

1.Redis入门篇

1.什么是Redis

Redis全称为Remote Dictionary Server,远程词典服务器,基于内存的键值型NoSQL数据库

NoSQL(Not only SQL)是对不同于传统的关系数据库的数据库管理系统的统称,即广义地来说可以把所有不是关系型数据库的数据库统称为NoSQL。

特征:

1.键值型,value支持多种不同数据结构

2.单线程,每个命令具有原子性

3.低延迟,速度快(基于内存、IO多路复用、良好编码)

4.支持数据持久化(RDB AOF)什么是RDB、AOF后面会提及

5.支持主从集群、分片集群

6.支持多语言客户端

2.安装Redis(基于Linux)

1.单机安装
1.单机安装Redis

Redis基于c语言编写所以安装gcc依赖

yum install -y gcc tcl
2.上传安装包

我个人使用的是Xftp传的就不作展示了

3.解压redis

解压到当前目录

tar -zxvf redis-6.2.6.tar.gz 
4.编译安装

安装并编译

make && make install 
5.安装成功

我们默认安装成功的路径 /usr/local/bin

如果安装成功那么就会有很多命令例如redis server、redis-cli等等

3.指定启动方式

1.默认启动
redis-server

没有配置启动就是默认启动

2.配置文件启动

进入redis软件目录

我个人是放在/opt/module

cd /opt/module/redis-6.2.6

我们先cp一下配置文件并备份

cp redis.conf redis.conf.bak
1.修改配置

我个人改了一些配置例如

bind 0.0.0.0
# 监听地址,允许所有ip访问(这玩意云服务器和生产别这样搞除非有密码)
daemonize yes
# 后台运行
requirepass simon0414
#密码
maxmemory 512mb
#最多512mb
logfile "redis.log"
#日志目录(默认是"",也就是不记录)
2.运行
redis-server redis.conf
3.查看进程
ps -ef |grep redis
3.开机自启动
1.去新建一个系统服务文件
vim /etc/systemd/system/redis.service
2.内容如下

注意那个配置文件填你自己的解压地址

[Unit]
Description=redis-server
After=network.target[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /opt/module/redis-6.2.6/redis.conf
PrivateTmp=true[Install]
WantedBy=multi-user.target
3.重载系统服务
systemctl daemon-reload
4.设置自启动
systemctl enable redis
4.客户端访问
1.命令行客户端
-a 指定密码
-p 端口
-h ip地址
redis-cli -a simon0414
后续验证
auth simon0414
2.图形化客户端

按个人喜好

3.编程api

后续补充

4.常见命令

1.Redis的数据结构(基本类型)
1.String
2.Hash
3.List
4.Set
5.SortedSet
2 Redis的数据结构(特殊类型)
6.GEO
7.BitMap
8.HyperLog

以及等等其他特殊类型(消息队列)

3.通用命令(常用)

1.help

help @组名 | help 具体命令

作用:帮助文档

2.keys

作用:找到符合要求的key

keys 表达式

?代表一个字符、*代表多个字符

查找以a开头的key

keys a*

我们知道redis是一个单线程的程序,我们的keys后面是表达式自然就是模糊搜素引擎效率不高,如果查找时间过长就会长时间

阻塞我们的业务,所以生成环境最好别用

3.del

del key的名称 | del key1 key2 

作用:删除一个key值、删除多个key值

即便是不存在的key也没关系(返回的是有效的删除数)

4.exists

exists key 

key是否存在

5.expire、ttl

作用:给key设置有效时间,ttl查看key的有效时间

expire age 20
ttl age

给age设置20秒有效时间并查看age的有效时间

4.String类型(常用命令)

字符串类型,是Redis最基础的类型,也就是value是字符串

我们可以又能细分我们的value的类型为三种(最大512mb)

string、int、float

无论这三种什么格式,底层均采用字节数组来存储

在 Redis 中,字符串是一个字节数组。一个数字型字符串类型的数据占用的内存空间取决于其存储的文本长度。当一个字符串类型存储的是数字时,采用二进制的形式存储会降低存储和处理数字型字符串的空间和时间开销。基于这个原因,Redis对于数字型字符串类型进行了特殊处理,采用了一种称为整数编码的方式来优化存储效率。

整数编码包括三种形式:

  • int:采用 8 个字节的有符号整数存储。
  • embstr:采用较小的编码存储数值,这个编码长度只能存储值在 0 ~ 4 个字节范围内的整数类型。这种方式又分为 16 位和 32 位两种,采用 6 bit 的前缀来表示。例如,如果前缀为 110,则接下来的 14 bit 就是这个整数的数值。
  • raw:直接采用字符串方式存储。

1.set

set key value

作用:添加或者修改key的value

2.get

get key

作用:获取key的值

3.mset

mset k1 v1 k2 v2

作用:设置多个key的值

4.mget

mget k1 k2

作用:获取多个key值的一个数组

5.Incr

incr key

作用:给整型的key自增1

6.incrby

incrby key 步长

作用:给整型的key自增指定步长(可以为负数)

7.incrbyfloat

incrbyfloat key 步长

作用:给浮点型的key自增步长

浮点数没有默认增长

8.setnx

setnx key value

作用:若不存在则设置值、若存在则不设置值

9.setex

setex key expire value

作用:设置一个key的值并设置有效期

可以分为增改查模块1234、自增模块567、组合模块89来记忆

5.key的层次结构

与HashMap很类似

Redis的key允许有多个单词形成层级结构,多个单词之间用":"隔开

例如:

simonstudy:user:1

这个就是二级结构

那么我们如果想要存储一个用户id为1的java对象数据怎么办呢

我们可以将我们的用户的对象变为json字符串序列化来存储到我们的value

6.Hash类型(常用命令)

Hash类型也叫散列,其value是一个无序字典,类似于java中的HashMap结构

String结构是将对象序列化后转化为json字符串后存储,当需要修改对象某个字段时很不方便

Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做crud

也就是我们的value又拆分成了两个字段

一个是field,一个是value

keyfieldvalue
simonstudy:user:1namesimon
simonstudy:user:1age18

常见命令

1.hset

hset key field value

作用:给key的某个字段field添加值value

2.hget

hget key field

作用:获取key的某个字段field的值

3.hmset

hset key1 field1 value1 filed2 value2

作用:给一个key设置多个field的值

4.hmget

hget key1 field1  filed2

作用:返回key的多个字段的值数组

5.hgetall

hgetall key

作用:返回key的所有filed和value的数组

6.hkeys

hkeys key

作用:返回key所有的field值

7.hvals

hvals key

作用:返回key所有的value值

8.hincrby

hincrby key field 步长

作用:给key的字段的值增长指定步长

9.hsetnx

hsetnx key field value

作用:判断key的字段filed值是否存在,如果存在则不设置,如果不存在则设置

7.List类型(常用命令)

Redis中的List和LinkedList类似,可以看作一个双向链表来操作

特点:

1.有序

2.元素可以重复

3.插入和删除快

4.查询速度一般

常用来保存有序的一个列表

常见命令

1.lpush

lpush key ele1 ele2 ele3

作用:将数据从左边push进去(上面的顺序自然就是ele3<->ele2<->ele1)

2.lpop

lpop key

作用:取出最左边的元素

3.rpush

rpush key ele1 ele2 ele3

作用:将数据从右边push进去(上面的顺序自然就是ele1<->ele2<->ele3)

4.rpop

rpop key

作用:取出最右边的元素

5.lrange

lrange key index1 index2

作用:取出范围为index1-index2的元素(从0开始)

blpop和brpop

blpop key time
broop key time

作用:阻塞等待获取

思考:

如何利用List结构模拟一个栈?

同向存取

如何利用List结构模拟一个队列

异向存取

如何利用List结构模拟一个阻塞队列

异向存阻塞取

8.Set类型(常用命令)

与java中的HashSet类似

特点:

1.无序

2.元素不可重复

3.查找快

4.支持交集、并集、差集

常见命令:

1.sadd

sadd key member1 member2

作用:向set中添加一个或多个元素

2.srem

srem key a

作用:删除key集合中的某个元素

3.sismember

sismember key a

作用:key集合中是否存在a元素

4.scard

scard key

作用:返回set中元素的个数

5.smembers

smembers key

作用:获取set这种所有元素

6.sinter

sinter key1 key2

作用:获取key1和key2两个集的交集

7.sdiff

sdiff key1 key2

作用:获取key1和key2两个集的差集

8.sunion

sunion key1 key2

作用:获取key1和key2两个集的并集

练习:

1.张三的好友有:李四、王五、赵六

2.李四的好友有:王五、麻子、二狗

利用set命令完成下列功能

sadd zs  ls ww zl 
sadd ls  ww mz eg

1.计算张三的好友有几个人

scard zs

2.计算张三和李四有哪些共同好友

求交集

sinter zs ls

3.查询哪些人是张三的好友而不是李四的

求差集

sdiff zs ls

4.查询张三和李四好友共有哪些人

求并集

sunion zs ls

5.判断李四是否是张三的好友

sismember zs ls

6.判断张三是否是李四的好友

sismember ls zs

7.将李四从张三的好友泪飙移除

srem zs ls
9.SortedSet类型(常用命令)

类似于java中的treeset类似,但是底层的数据结构差别很大,SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现

是一个调表skiplist+hash表

它具有一下特性:

1.可排序

2.元素不重复

3.查询速度快

因为可排序,所以经常被用来实现排行榜这样的功能

1.zadd

zadd key score member

作用:添加一个或多个元素到sorted set,如果已经存在就更新其score值

2.zrem

zrem key member

作用:删除sorted set中指定的一个元素

3.zscore

zscore key memeber

作用:获取指定元素的score

4.zrank

zrank key memeber

作用:获取指定元素的排名

5.zcard

zcard key

作用:获取sorted set中的个数

6.zcount

zcount key min max

作用:获取score值范围的所有元素个数

7.zincrby

zincrby key increment member

作用:给指定元素增加步长

8.zrange

zrange key min max

作用:按照score排序后获取指定排名范围的元素

9.zrangebyscore

zrangebyscore key min max

作用:按照score排序后获取指定score范围的元素

10.zdiff、zinter、zunion

交、差、并集

11.反转

z后面加上rev 表示reverse反转(默认升序)

练习:

jack 85 lucy 89 rose 82 tom 98 jerry 78 amy98 miles 76

zadd grade 85 jack 89 lucy 82 rose 95 tom 78 jerry 92 amy 76 miles

1.删除tom同学的

zrem grade tom

2.获取amy同学分数

zrem grade tom

3.获取rose同学排名

zrevrank grade rose 

4.查询80分以下几个学生

zcount grade 0 80

5.给Amy同学加2分

zincrby grade 2 amy

6.查出成绩前3名同学

zrevrange grade 0 2

7.查出成绩80分以下同学

zrangebyscore grade 0 80

5.Redis客户端

1.客户端介绍

Java客户端最常见的三个客户端

1.Jedis

以Redis命令作为方法名称简单适用,但是Jedis实例是线程不安全的,多线程环境需要基于连接池来使用

2.lettuce

Lettuce是基于Netty实现,支持同步、异步或者响应式编程方式,并且是线程安全。支持哨兵模式、集群

模式和管道模式

3.Redisson

基于Redis实现的分布式、可伸缩的Java数据结构集合。包含了诸如Map、Queue、Lock、Semaphore、

AtomicLong等强大功能

4.特注

我们的Spring Data Redis定义的一套API既可以通过jedis实现也可以通过lettuce实现,所以我们后期会学

习Spring Data Redis

2.Jedis客户端

1.引入核心依赖

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency>
<!-- 测试 -->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.1</version><scope>test</scope>
</dependency>

2.编写连接操作释放代码

package com.simon.test;import com.simon.JedisConnectionFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;import java.util.HashMap;
import java.util.Map;public class JedisTest {private Jedis jedis;@BeforeEachvoid setUp(){//建立连接jedis = new Jedis("192.168.11.100",6379);//设置密码jedis.auth("simon0414");jedis.select(0);}@Testvoid testString() throws InterruptedException {String result = jedis.set("name", "simon");System.out.println(result);String value = jedis.get("name");System.out.println(value);}@Testvoid testHash(){HashMap<String,String> map = new HashMap<>();map.put("name","simon");map.put("age","18");String result = jedis.hmset("user:1", map);System.out.println(result);Map<String, String> stringStringMap = jedis.hgetAll("user:1");System.out.println(stringStringMap);}@AfterEachvoid tearDown(){if (jedis != null){jedis.close();}}
}
3.Jedis客户端连接池优化

JedisConnectionFactory

package com.simon;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** @author Simon*/
public class JedisConnectionFactory {private static final JedisPool JEDIS_POOL;static {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//最大连接jedisPoolConfig.setMaxTotal(8);//最大空闲连接jedisPoolConfig.setMaxIdle(8);//最小空闲连接jedisPoolConfig.setMinIdle(8);//最长等待时间jedisPoolConfig.setMaxWaitMillis(1000);JEDIS_POOL = new JedisPool(jedisPoolConfig,"192.168.11.100",6379,1000,"simon0414");}public static Jedis getJedis(){return JEDIS_POOL.getResource();}
}

JedisTest

package com.simon.test;import com.simon.JedisConnectionFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;import java.util.HashMap;
import java.util.Map;public class JedisTest {private Jedis jedis;@BeforeEachvoid setUp(){
//        //建立连接
//        jedis = new Jedis("192.168.11.100",6379);
//        //设置密码
//        jedis.auth("simon0414");
//
//        jedis.select(0);jedis = JedisConnectionFactory.getJedis();}@Testvoid testString() throws InterruptedException {String result = jedis.set("name", "simon");System.out.println(result);String value = jedis.get("name");System.out.println(value);}@Testvoid testHash(){HashMap<String,String> map = new HashMap<>();map.put("name","simon");map.put("age","18");String result = jedis.hmset("user:1", map);System.out.println(result);Map<String, String> stringStringMap = jedis.hgetAll("user:1");System.out.println(stringStringMap);}@AfterEachvoid tearDown(){if (jedis != null){jedis.close();}}
}
4.Spring Data Redis
1.Spring Data Redis介绍

我们使用Spring Data Redis有什么好处呢?

1.提供对不同Redis客户端的整合

2.提供了同一的RedisTemplate统一api来操作Redis

3.支持Redis的发布订阅模型

4.支持Redis哨兵和Redis集群

5.支持基于Lettuce响应式编程

6.支持基于JDK、Json、字符串、Spring对象的数据序列化和反序列化

7.支持基于Redis的JDKCollection实现(基于Redis实现的分布式的集合)

2.API分组

我们知道我们Redis中对命令做了分组

同样我们的Spring Data Redis也做了

1.redisTemplate 通用命令

redisTemplate.opsForValue 对String类型的命令

redisTemplate.opsForHash 对Hash类型的命令

redisTemplate.opsForList 对List类型的命令

redisTemplate.opsForSet 对Set类型的命令

redisTemplate.opsForSortedSet 对SortedSet类型的命令

3.快速入门

因为我们SpringBoot对starter依赖做好了自动装配,所以我们使用SpringBoot快速整合

1.导入依赖(其实还有类似于lombok和SpringBootStarterTest依赖这里只展示核心的)

 		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 连接池依赖 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>

这两个是依赖一个是SpringBoot的data-redis的起步依赖

第二个是连接池依赖

注意:我们SpringDataRedis默认的客户端是Lettuce奥,这一点我们看spring-boot-starter-data-redis里面包含的依赖也是可以发现的

2.配置我们的yml文件(当然你也可以写配置类非常麻烦)

我个人就上yml了

spring:redis:host: 192.168.11.100port: 6379password: "simon0414"#我们的spring data redis 默认使用的是Lettuce奥,如果使用jedis就要引入jedis依赖lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100 #连接等待时间ms

写你自己的连接数据

3.编写测试类

package com.simon;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;@SpringBootTest
public class RedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString(){redisTemplate.opsForValue().set("name","ximeng");//获得String数据Object name = redisTemplate.opsForValue().get("name");System.out.println(name);}}

测试成功

4.注意问题

但其实是有问题的

我们发现我们原有的name并没有被覆盖

反而多了一个很奇怪的key

\xAC\xED\x00\x05t\x00\x04name

他的value为\xAC\xED\x00\x05t\x00\x06ximeng

我们之间说过我们的SpringDataRedis会给我们自动进行序列化,我们传入set的时候都可以接受Object对象

这个时候它会将我们传入的String作为对象来处理,通过ObjectOutputStream输出的所以说就变成了这样

我们可以点进去看看

    @Nullableprivate RedisSerializer keySerializer = null;@Nullableprivate RedisSerializer valueSerializer = null;@Nullableprivate RedisSerializer hashKeySerializer = null;@Nullableprivate RedisSerializer hashValueSerializer = null;public void afterPropertiesSet() {super.afterPropertiesSet();boolean defaultUsed = false;//当我们的defaultSerializer为null时,那么就会将赋值为JdkSerializationRedisSerializer,而它序列化采用就是ObjectOutputStream//可以打断点去看,我这里就不深入了if (this.defaultSerializer == null) {this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());}if (this.enableDefaultSerializer) {if (this.keySerializer == null) {this.keySerializer = this.defaultSerializer;defaultUsed = true;}if (this.valueSerializer == null) {this.valueSerializer = this.defaultSerializer;defaultUsed = true;}if (this.hashKeySerializer == null) {this.hashKeySerializer = this.defaultSerializer;defaultUsed = true;}if (this.hashValueSerializer == null) {this.hashValueSerializer = this.defaultSerializer;defaultUsed = true;}}if (this.enableDefaultSerializer && defaultUsed) {Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");}if (this.scriptExecutor == null) {this.scriptExecutor = new DefaultScriptExecutor(this);}this.initialized = true;}

我们总结下来我们如果想采用我传入啥值就用什么序列化器

我们发现我们的RedisSerializer的序列化器接口实现类有很多其他的实现类

例如:OxmSerializer、ByyeArrayRedisSerializer、GenericJackson2JsonRedisSerializer、GenricToStringSerializer、StringRedisSerializer、JdkSeializationRedisSerializer、Jackson2JsonRedisSerializer

倘若我们的key为String类型、值为对象

我们该如何去修改这个序列化器呢?

很简单,我们只需要写配置类就行了

package com.simon.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;/*** @author Simon*/@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){//创建RedisTemplate对象RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();//设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);//创建Json序列化工具GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();//设置key的序列化//单例对象redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());//设置value的序列化redisTemplate.setValueSerializer(valueSerializer);redisTemplate.setHashValueSerializer(valueSerializer);//返回return redisTemplate;}
}

我们针对RedisTemplate<String,Object>上述的情形的redisTemplate注入了我们自己的序列化器以及连接池

然后执行我们的测试代码,有的同学可能有问题会报错

即Jackson依赖的ClassNotFind的错误(我们都知道我们SpringMvc中有JackSon的依赖,因为处理对象请求体也会用到)

我们这里没有引入我们的SpringMvc所以我们就自然引入一下JackSon的依赖

		<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>

然后执行测试代码成功

5.测试对象写入

我们知道我们配置的是key为String而value为对象的RedisTemplate,所以我们可以测试一下写入User

package com.simon.pojo;import lombok.Data;/*** @author Simon*/@Data
public class User {private String name;private Integer age;}
 @Testvoid testUser(){User user = new User();user.setName("simon");user.setAge(18);redisTemplate.opsForValue().set("user:1",user);User user1 = (User) redisTemplate.opsForValue().get("user:1");System.out.println(user1);}

不仅写入了User的Json字符串,还可以反序列化我们的数据

怎么做到的呢?

我们来看看存储的数据

{"@class": "com.simon.pojo.User","name": "simon","age": 18
}

原来把我们的类写入了,所以自动化地反序列化我们的数据了但是我们这样会浪费我们的内存空间

使用起来确实很方便,但是我们不太希望这样,如果我们的每一个对象都存储了这个信息就会多占

用浪费很多空间无法接受,所以我们基本不会使用JSON序列化器来处理value,所以统一使用String

序列化器,要求只能存取String类型的key和value,当需要存储Java对象时,我们手动完成对象的序

列化和反序列化。

6.StringRedisTemplate

我们为了解决问题,我们Spring默认提供了一个StringRdisTemplate类,它的key和value的序列化

方式默认为String,我们自动使用即可

1.配置连接池

 @Beanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();stringRedisTemplate.setConnectionFactory(redisConnectionFactory);return stringRedisTemplate;}

2.测试

@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final ObjectMapper MAPPER = new ObjectMapper();@Testvoid TestStringUser() throws JsonProcessingException {User user = new User();user.setName("StringSimon");user.setAge(18);//手动序列化String userJson = MAPPER.writeValueAsString(user);stringRedisTemplate.opsForValue().set("user:1",userJson);//手动反序列化String userGetJson = stringRedisTemplate.opsForValue().get("user:1");User userGet = MAPPER.readValue(userGetJson, User.class);System.out.println(userGet);}//Hash类似的只是改成了Put

测试成功

7.总结

RedisTemplate序列化实践方案

一.

1.自定义RedisTemplate

2.修改RedisTemplate的序列化器为GennericJack2JsonRedisSerializer

二.

1.使用StringRedisTemplate

2.手动序列化和反序列化对象

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

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

相关文章

芸鹰蓬飞:抖店的运营技巧是什么?

抖店&#xff0c;作为抖音平台上的电商业务&#xff0c;为商家提供了一个全新的销售渠道。然而&#xff0c;要成功运营抖店&#xff0c;商家需要掌握一定的方法和技巧。下面&#xff0c;我们就来详细介绍一下抖店的运行方式。 商品选择&#xff1a;首先&#xff0c;商家需要选择…

单片稳压集成电路78LXX系列——固定的电压输出,适用于需100mA电源供给的应用场合(网络产品,声卡和电脑主板等产品)

78LXX系列是一款单片稳压集成电路&#xff0c;它们有一系列固定的电压输出&#xff0c;适用于需100mA电源供给的应用场合。78LXX系列采用T0-92和SOT-89-3L的封装形式。 主要特点&#xff1a; ● 最大输出电流为100mA ● 输出电压为3.3V. 5V. 6V. 8V、9V、10V、 12V和15V ● 热…

网络面试题总结

url从输入到渲染页面的全过程 URL 从输入到页面渲染可以分为以下步骤&#xff1a; 输入 URL&#xff1a;在浏览器地址栏中输入 URL&#xff08;统一资源定位符&#xff09;。DNS 解析&#xff1a;浏览器通过 DNS&#xff08;域名系统&#xff09;将 URL 解析成 IP 地址&#…

美易官方:美联储FOMC声明重点

美联储FOMC声明重点 美联储FOMC声明是美联储货币政策的重要文件&#xff0c;其重点内容主要包括以下几个方面&#xff1a; 1. 利率政策 美联储FOMC声明中最重要的内容之一是利率政策。声明会明确美联储的利率目标区间&#xff0c;以及未来可能的调整方向。利率政策是美联储调节…

git查看commit提交记录详情

相关的命令 git log&#xff1a;查看所有的commit提交记录&#xff1b;git show&#xff1a; 查看提交的详情&#xff1b; 首先&#xff0c;需要通过git log显示所有commit记录&#xff1a; 查看最新的commit&#xff1a;git show查看指定commit的所有修改&#xff1a;git s…

Zxing库的使用⭐️实现给自己的博客主页生成一张二维码链接,有源码可以直接复制到本地执行

目录 前言 一、简介 二、本地实现 2.1 引入依赖&#xff08;根据自己springboot项目来&#xff09; 2.2 实现类 三、运行一次 前言 小伙伴们大家好&#xff0c;自从地铁上刷到Zxing库的使用后&#xff0c;一直想本地部署玩一玩 一、简介 ZXing&#xff08;全称为 Zebra Cr…

Mac搭建Frida逆向开发环境

一、简介 Frida是一种基于Python+JavaScript的动态分析工具,可以用于逆向开发、应用程序的安全测试、反欺诈技术等领域,本质是一种动态插桩技术。Frida主要用于在已安装的应用程序上运行自己的JavaScript代码,从而进行动态分析、调试、修改等操作,能够绕过应用程序的安全措…

nodejs使用express框架启动服务操作mysql数据库

描述: 首先在本地搭建mysql数据库,配置:host: ‘192.168.3.249’,user: ‘mkx’,password: ‘123456’,database: ‘gg’.测试连接正常.使用express写两个接口, 1.查询所有学生的接口,使用的get请求,无参数. 2.插入一条学生信息,使用post请求,body是一个json的学生信息{name:“…

土壤科学灌溉CG-36 土壤水势传感器

土壤科学灌溉CG-36 土壤水势传感器产品概述 土壤水势传感器可以很方便地插入到土壤剖面坑中&#xff0c;在其周围包裹上湿土即可。测定和记录非常简单。免维护、无需校准即可测量较大范围的土壤水势&#xff1b;无需灌水&#xff0c;大量程使得它成为测量自然系统水势的理想传…

十个Vue3实用但是冷门的API

文章目录 一、前言二、readonly三、shallowRef四、shallowReactive五、toRef & toRefs5.1、 toRef5.2、toRefs 六、toRaw & markRaw & unref6.1、toRaw6.2、markRaw6.3、unref 七、effectScope & onScopeDispose7.1、收集副作用7.2、全局状态管理 八、provide …

Docker - Android源码编译与烧写

创建源代码 并挂载到win目录 docker run -v /mnt/f/android8.0:/data/android8.0 -it --name android8.0 49a981f2b85f /bin/bash 使用 docker update 命令动态调整内存限制&#xff1a; 重新运行一个容器 docker run -m 512m my_container 修改运行中容器 显示运行中容器 d…

【1day】复现I Doc View系统upload接口任意文件读取漏洞

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现

【剑指offer|图解|二分查找】点名 + 统计目标成绩的出现次数

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;剑指offer每日一练 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️点名1.1 题目1.2 示例1.3 限制1.4 解题思路一c代码 1.5 解题思路二c代码 二. ⛳️统计目标成绩…

开发信的基本要点有哪些?如何撰写开发信?

开发信的关键要素是什么&#xff1f;外贸开发信的写作技巧方法&#xff1f; 开发信是一种至关重要的沟通工具&#xff0c;无论是初创企业还是已经建立的公司&#xff0c;开发信都是与潜在客户、合作伙伴或投资者建立联系的关键步骤。蜂邮将讨论开发信的基本要点&#xff0c;以…

(NeRF学习)3D Gaussian Splatting Instant-NGP环境配置

学习参考&#xff1a; 3D gaussian splatting 安装步骤拆解23.9月3D Gaussian Splatting入门指南【五分钟学会渲染自己的NeRF模型&#xff0c;有手就行&#xff01;】 三维重建instant-ngp环境部署与colmap、ffmpeg的脚本参数使用 一、3D Gaussian Splatting &#xff08;一&…

快看!AI竟然可以这样……

自从ChatGPT诞生之后&#xff0c;还有谁不知道AI的名号吗&#xff1f;我相信只有极少部分人吧。人工智能技术在21世纪粉墨登场&#xff0c;拉开了信息化时代的蓝图&#xff0c;被广泛应用于各个产业&#xff0c;来实现产业赋能&#xff0c;推动了经济社会的快速发展。 5G使用还…

PyPDF2库对PDF实现读取的应用

目录 一、PyPDF2 库的使用 1. 文档打开和页面读取 2. 文本提取功能 3. 示例代码

java获取字符串最后一个字符

要获取字符串的最后一个字符&#xff0c;你可以使用以下方法之一&#xff1a; 方法1&#xff1a;使用 charAt() 方法 String str "Hello World"; char lastChar str.charAt(str.length() - 1); System.out.println("最后一个字符是&#xff1a;" last…

【数据结构】什么是堆?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 堆的概念及结构 堆的定义如下: n个元素的序列{k1,k2,...,kn}当且仅当满足以下关系时,称之为堆. 或 把这个序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个…

基于springBoot + Vue电影售票系统分前后台【完整源码+数据库】

一、项目简介 本项目是一套基于springBoot Vue的电影售票系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#xff0c;确…