Redis学习笔记(基础篇)

Redis基础

    • 1 Redis是什么?
      • 1.1 键值型
      • 1.2 NoSQL
        • 1.2.1 NoSQL与SQL的区别是什么
        • 1.2.2 总结
      • 1.3 Redis的特点是什么?
    • 2 Redis怎么用?
      • 2.1 Redis的基本命令
      • 2.2 Key的层级结构
      • 2.3 Redis的基本数据类型有哪些?
        • 2.1.1 String类型
        • 2.1.2 Hash类型
        • 2.1.3 List
        • 2.1.4 Set类型
        • 2.1.5 SortedSet类型
    • 3 Redis的java客户端有哪些?
      • 3.1 Jedis客户端
        • 3.1.1 快速入门
      • 3.2 SpringDataRedis客户端
        • 3.2.1 快速入门
        • 3.2.2 StringRedisTemplate

本文是参考黑马程序员Redis课程而做的笔记,根据本文可以快速了解什么是Redis以及Redis的几种基本数据类型和相关操作,在练习基础操作时,如果你还没有下载安装redis,可以在redis在线测试工具网站上操作。

1 Redis是什么?

Redis是一种键值型NoSQL数据库。

1.1 键值型

键值型指Redis中存储的数据都是以Key-Value键值对的形式存储,而value的形式多种多样,可以是字符串,数值甚至json

1.2 NoSQL

NoSQL是相对与传统关系型数据库而言,有很大差异的一种数据库。下面会详细对比。

1.2.1 NoSQL与SQL的区别是什么

1、结构化与非结构化

  • 传统关系型数据库结构化数据,每张表在创建时都有严格的约束条件,如字段名,字段数据类型,字段约束等。

  • NoSQL则对数据库格式没有约束,可以是键值型,也可以是文档型,甚至是图格式,总之是非结构化的。

2、关联与非关联

  • 传统数据库的表与表之间往往存在关联,例如外键约束。

  • 而非关系型数据库不存在关联关系,要维护关系的话要么靠代码中的业务逻辑,要么靠数据之间的耦合,比如要维护张三和两个手机订单的关系,就不得不冗余的将这两个商品保存在张三的订单的文档中,如下,不够简洁漂亮,所以建议使用业务逻辑来维护关联关系。

{
  id: 1,
  name: "张三",
  orders: [
    {
       id: 1,
       item: {
	 id: 10, title: "荣耀6", price: 4999
       }
    },
    {
       id: 2,
       item: {
	 id: 20, title: "小米11", price: 3999
       }
    }
  ]
}

3、查询方式

  • 传统关系型数据库会基于SQL语句做查询,语法有统一的标准
select id,age from tb_user where id = 1;
  • 而不同的非关系型数据库查询语法差异极大
Redis:  get user:1
MongoDB: db.user.find({_id: 1})
elasticsearch:  GET http://localhost:9200/users/1

4、事务

  • 传统关系型数据库满足事务的ACID原则(原子性、一致性、独立性及持久性)

  • 非关系型数据库往往不支持事务,只能实现基本的一致性

5、存储方式

  • 传统关系型数据库基于磁盘进行存储,会有大量的磁盘IO,对性能有一定的影响
  • 非关系型数据库的操作依赖于内存,内存的读写速度相对于磁盘非常快,性能更好

6、扩展性

  • 传统关系型数据库通常采用垂直扩展的方式,数据库集群一般是主从,主从数据一致,起到备份的作用。
  • 非关系型数据库通常采用水平扩展,它可以将数据拆封存储在不同的机器上,可以保存海量的数据,解决内存大小有限的问题。
1.2.2 总结
SQLNoSQL
数据结构结构化非结构化
数据关联关联的无关联
查询方式SQL查询非SQL
事务特性ADIDBASE
存储方式磁盘内存
扩展性垂直水平
使用场景1)数据结构固定 2)对一致性、安全性要求较高1)数据结构不稳定 2)相关业务对数据安全性、一致性要求不高 3)对性能有要求

1.3 Redis的特点是什么?

特征:

  • 键值型(Key-Value),Value支持多种不同的数据结构,功能丰富
  • 单线程,每个命令具有原子性
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码)
  • 支持数据持久化
  • 支持主从集群、分片集群
  • 支持多语言客户端

2 Redis怎么用?

要知道怎么用最好的方法肯定是到官网查看。

2.1 Redis的基本命令

命令描述
KEYs pattern查找所有符合给定模式(pattern)的key(不建议在生产环境用,因为Redis是单线程的,执行查询时会阻塞其他命令,当数据量很大的时候,效率很差)
EXISTs key检查给定的key是否存在(如果存在返回1,不存在返回0)
TYPE key返回key所存储的值的类型
TTL key返回给定key的剩余生存时间(TTL,time to live)以秒为单位(返回-1则说明这个数据永久有效)
DEL key该命令用于在key存在时删除key

2.2 Key的层级结构

我们已经知道Redis没有类似于MySQL中table的概念,那么我们应该如何区分不同类型的key呢?

如,我们现在有用户和商品,有个用户的id为1,同时有个商品的id也为1,如果它们都用id作为key,那么我们如何才能区分它们呢,直接存的话,都不说区分,会有覆盖的问题。所以我们是不是可以通过给key添加前缀来区分呢?

Redis的key其实时允许由多个单词形成层级结构的,多个单词使用:隔开,例如项目名:业务名:类型:id

当然这个格式并非固定的,可以按自己的需求来。这样我们就可以把不同类型的数据区分开了,从而避免key的冲突问题。

通过redis的图形界面,可以很直观的感受到层级结构:
在这里插入图片描述

2.3 Redis的基本数据类型有哪些?

2.1.1 String类型

String类型,也就是字符串类型,是Redis中最简单的存储类型,其value字符串,根据字符串的格式不同,可以分为3类:

  • String:普通字符串
  • int:整数类型,可以做自增、自减操作
  • float:浮点类型,也可以做自增自减操作,不过必须要指定自增自减的值
    不管是那种格式,底层都是以字节数组形式存储,只不过是编码方式不同,字符串类型的最大空间不能超过512M.

String常用命令

命令描述
SET添加一个String类型的键值对,如果原本存在则覆盖
GET根据key获取String类型的value
MSET批量的添加多个String类型的键值对
MGET根据多个key获取多个String类型的value
INCR让一个整形的key自增1
INCRBY让一个整形的key自增指定步长 incrby key 步长
INCRBYFLOAT让一个浮点类型的数字自增指定步长
SETNX添加一个String类型键值对,当前仅当这个key不存在时,否则不执行
SETEX添加一个String类型的键值对,并指定有效期
2.1.2 Hash类型

Hash类型,也叫散列,其中value是一个无序字典,类似于Java中HashMap结构(存储的内容是键值对映射)

当我们使用String类型去存一个数组的时候,我们需要将对象序列化为JSON字符串后存储,当我们要修改对象的某个属性值的时候会很不方便。这个时候用Hash类型就很合适了。Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD,并且在空间上更为节省,少了很多符号。
在这里插入图片描述
Hash常用命令

命令描述
HSET key field value添加或者修改hash类型key的field的值
HGET key field获取一个hash类型key的field的值
HMSET批量添加多个hash类型的key的field的值
HMGET批量获取hash类型多个key的field的值
HGETALL获取一个hash类型的key中所有的field和value
HKEYS获取一个hash类型key中所有field
HINCRBY让一个hash类型key的字段自增并指定步长
HSETNX添加一个hash类型的key的field的值,当且仅当这个field不存在,否则不执行
2.1.3 List

List类型与Java中的LinkedList类似,可以看作是一个双向链表结构,既可以支持正向检索也可以支持反向检索。

特征也与LinkedList类似:

  • 有序
  • 元素可以重复
  • 插入和删除快
  • 查询速度一般
    适合用来存储一些有序数据,例如:朋友圈点赞列表,评论列表等。

List常见命令

命令描述
LPUSH key element像列表左侧插入一个或多个元素
LPOP key移除并返回列表左侧的第一个元素,没有返回nil
RPUSH key像列表右侧插入一个或多个元素
RPOP key移除并返回列表右侧的第一个元素,没有返回nil
LRANGE key star返回一段角标范围内的所有元素
BLPOP和BRPOP与LPOP和RPOP类似,只不过在没有元素的时候会等待指定的时间,而不是直接返回nil
2.1.4 Set类型

Set类型与Java中的Hash类似,可以看作是一个value为null的HashMap(也可以看作数学上的集合),因为它也是一个hash表,因此具备和HashSet类似的特征:

  • 无序
  • 元素不可重复
  • 查找快
  • 支持交集、并集、差集等功能
    Set常见命令
命令描述
SADD key member向set中添加一个或多个元素
SREM key member移除set中指定元素
SCARD key返回set中元素的个数
SISMEMBER key menber判断一个元素是否存在于set中
SMEMBERS获取set中的所有元素
SINTER key1 key2求key1与key2的交集
SUNION key1 key2求key1与key2的并集
SDIFF key1 key2求key1与key2的差集

练习题
1、将下列数据用Redis的set集合来存储

  • 张三的好友有:李四、王五、赵六
  • 李四的好友有:王五、麻子、二狗

2、计算张三的好友有几人
3、计算张三和李四有哪些共同好友
4、查询哪些人是张三的好友却不是李四的好友
5、查询张三和李四的好友总共有哪些人
6、判断李四是否是张三的好友
7、判断张三是否是李四的好友
8、将李四从张三的好友列表中移除

2.1.5 SortedSet类型

SortedSet类型是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于scoer属性对元素排序,底层的实现是一个跳表(SkipList)加hash表。Sorted具备下列特性:

  • 可排序
  • 元素不重复
  • 查询速度快

SortedSet的value类似于一个排行榜,其中每个成员都有一个与之相关的分数,并且根据这个分数进行排序。

由于SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

SortedSet常见命令

命令描述
ZADD key score member添加一个或多个元素到sorted set ,如果已经存在则更新其score值
ZREM key member删除sorted set中的一个指定元素
ZSCORE key member获取sorted set中的指定元素的score值
ZRANK key member获取sorted set 中的指定元素的排名
ZCARD key获取sorted set中的元素个数
ZCOUNT key min max统计score值在给定范围内的所有元素的个数
ZINCRBY key increment member让sorted set中的指定元素自增,步长为指定的increment值
ZRANGE key min max按照score排序后,获取指定排名范围内的元素
ZRANGEBYSCORE key min max按照score排序后,获取指定score范围内的元素
ZDIFF、ZINTER、ZUNION求差集、交集、并集

注意:
所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可,例如

  • 升序获取sortedset中指定元素的排名:ZRANK key member
  • 降序获取sortedset中指定元素的排名:ZREVRANK key member

练习题

1、将班级的下列学生得分存入Redis的SortedSet中:Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
2、删除Tom同学
3、获取Amy同学的分数
4、获取Rose同学的排名
5、查询80分以下有几个学生
6、给Amy同学加2分
7、查出成绩前3名的同学(注意:默认升序)
8、查出成绩80分以下的所有同学

3 Redis的java客户端有哪些?

目前主流的Redis的Java客户端有三种:
- JedisLettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringData来学习
- Redisson:在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map、Queue等,而且支持跨进程的同步机制:Lock、Semaphore等待,比较适合用来实现特殊的功能需求。

3.1 Jedis客户端

3.1.1 快速入门
  1. 导入Jedis的maven坐标
<!--jedis-->
<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.0</version>
    <scope>test</scope>
</dependency>
  1. 建立连接
private Jedis jedis;

@BeforeEach
void setUp() {
    //1. 建立连接
    jedis = new Jedis("你的ip", 6379);
    //2. 设置密码
    jedis.auth("你的密码");
    //3. 选择库
    jedis.select(0);
}
  1. 测试
@Test
void testString(){
    jedis.set("name","Kyle");
    String name = jedis.get("name");
    System.out.println("name = " + name);
}

@Test
void testHash(){
    jedis.hset("reggie:user:1","name","Jack");
    jedis.hset("reggie:user:2","name","Rose");
    jedis.hset("reggie:user:1","age","21");
    jedis.hset("reggie:user:2","age","18");
    Map<String, String> map = jedis.hgetAll("reggie:user:1");
    System.out.println(map);
}
  1. 释放资源
@AfterEach
void tearDown(){
    if (jedis != null){
        jedis.close();
    }
}

连接池

由于Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损失,因此我们可以是使用Jedis连接池代替Jedis的直连方式,这种池化思想可以实现资源复用,提升性能等。

我们可以编写一个工具类,来使用连接池获取Jedis:

public class JedisConnectionFactory {

    private static JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);
        poolConfig.setMaxIdle(8);
        poolConfig.setMinIdle(0);
        poolConfig.setMaxWaitMillis(1000);
        // 创建连接池对象,参数:连接池配置、服务端ip、服务端端口、超时时间、密码
        jedisPool = new JedisPool(poolConfig, "你的ip", 6379, 1000, "你的密码");
    }

    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

之后就可以这样获取jedis了

private Jedis jedis = JedisConnectionFactory.getJedis();

3.2 SpringDataRedis客户端

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫SpringDataRedis。它:

  • 提供了对Redis客户端的整合
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

API返回值类型说明
redisTemplate.opsForValue()ValueOperations操作String类型数据
redisTemplate.opsForHash()HashOperations操作Hash类型数据
redisTemplate.opsForList()ListOperations操作List类型数据
redisTemplate.opsForSet()SetOperations操作Set类型数据
redisTemplate.opsForzSet()ZSetOperations操作SortedSet类型数据
redisTemplate通用的命令
3.2.1 快速入门

这里看一下理解就好,重点是3.2.2。

  1. 导入依赖
<!--redis依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--common-pool-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!--Jackson依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
  1. 配置Redis
spring:
  redis:
    host: 你的服务器ip
    port: 6379
    password: 你的密码
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms
  1. 注入RedisTemplate,因为有SpringBoot的自动装配,所以我们拿来就用就可以了
@Autowired
private RedisTemplate redisTemplate;
  1. 测试
@Test
void test(){
    redisTemplate.opsForValue().set("username","David");
    String username = (String) redisTemplate.opsForValue().get("username");
    System.out.println(username);
}
  • RedisTemplate可以接受任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果都类似于下面的形式

\xAC\xED\x00\x05t\x00\x06\xE5\xBC\xA0\xE4\xB8\x89

这样的话,可读性很差,而且内存占用较大

我们可以自定义RedisTemplate的序列化方式,这里采用了JSON序列化来代替默认的JDK序列化方式。如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer =
                new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }
}

我们编写一个实体类,并将他存入Redis看是什么效果

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
}
@Test
void test(){
    redisTemplate.opsForValue().set("userdata",new User("张三",18));
}

结果:

{
  "@class": "com.blog.entity.User",
  "name": "张三",
  "age": 18
}

这样可读性就好了很多,并且存的时候能将Java对象自动序列化成JSON字符串,并且查询时能自动把JSON字符串反序列化成Java对象。不过,为了实现这样的效果,必须在其中记录对应的class名称,这样就带来了额外的内存开销。

所以,为了节省内存,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。我们可以采用手动实现对象的序列化和反序列化的方式,这样class信息就不会被写入Redis了。

3.2.2 StringRedisTemplate

对此,SpringDataRedis就提供了RedisTemplate的子类StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

@Test
void stringTest() throws JsonProcessingException {
    //创建对象
    User user = new User("张三", 18);
    //手动序列化
    String json = mapper.writeValueAsString(user);
    //写入数据
    stringRedisTemplate.opsForValue().set("userdata", json);
    //获取数据
    String userdata = stringRedisTemplate.opsForValue().get("userdata");
    //手动反序列化
    User readValue = mapper.readValue(userdata, User.class);
    System.out.println(readValue);
}

结果:

{
  "name": "张三",
  "age": 18
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb:vue、AJax、ELement、maven、SpringBoot、、Http、Tomcat、请求响应、分层解耦

1 Vue 1.1 Vue介绍 VUE是前端框架&#xff0c;基于MVVM&#xff0c;实现数据双向绑定 框架是半基础软件&#xff0c;可重用的代码模型 1.2 Vue指令 <script src"js/vue.js"></script></head> <body><div id"id"><!--…

【鸿蒙HarmonyOS开发笔记】常用组件介绍篇 —— 弹窗组件

简介 弹窗是移动应用中常见的一种用户界面元素&#xff0c;常用于显示一些重要的信息、提示用户进行操作或收集用户输入。ArkTS提供了多种内置的弹窗供开发者使用&#xff0c;除此之外还支持自定义弹窗&#xff0c;来满足各种不同的需求。 下面是所有涉及到的弹窗组件官方文档…

边缘计算+WEB端应用融合:AI行为识别智能监控系统搭建指南 -- 云端系统数据库设计(五)

专栏目录 边缘计算WEB端应用融合&#xff1a;AI行为识别智能监控系统搭建指南 – 整体介绍&#xff08;一&#xff09; 边缘计算WEB端应用融合&#xff1a;AI行为识别智能监控系统搭建指南 – 边缘设备图像识别及部署&#xff08;二&#xff09; 边缘计算WEB端应用融合&#xf…

研究生总结

Note:本博客更多是关于自己的感悟&#xff0c;没有翻阅文件详细查证&#xff0c;如果存在错过&#xff0c;也请提出指正。 1. 半监督回归 相比于半监督分类&#xff0c;半监督回归相对冷门。回归和分类之间有着难以逾越的天谴&#xff0c;预测精度。分类中的类别是可数的&…

网络学习:ICMPV6报文

目录 前言&#xff1a; 一、ICMPV6的报文内容 二、ICMPv6差错报文分类 1、目的不可达错误报文&#xff08;type1) 2、数据包过大错误报文(type2) 3、超时报文(type3) 4、参数错误报文 三、ICMPv6信息报文的分类 1、回送请求报文&#xff1a; 2、回送应答报文&#xf…

IDEA系列软件设置自动换行

以pycharm软件为例&#xff0c;我们在编程的时候常常会遇到这种情况&#xff0c;内容过长导致超出pycharm的界面&#xff0c;导致我们阅读浏览起来非常的不方便&#xff0c;对于这种情况&#xff0c;我们可以通过给IDEA软件设置自动换行来解决 首先打开setting&#xff0c;找到…

ElasticSearch:数据的魔法世界

​ 欢迎来到ElasticSearch的奇妙之旅&#xff01;在这个充满魔法的搜索引擎世界中&#xff0c;数据不再是沉闷的数字和字母&#xff0c;而是变得充满活力和灵动。无论你是刚刚踏入数据探索的小白&#xff0c;还是已经对搜索引擎有所了解的行者&#xff0c;本篇博客都将为你揭示…

ThingsBoard Edge 设备控制

文章目录 一、RPC 功能1.服务端 RPC2.客户端 RPC3.MQTT RPC API3.1.服务端RPC3.2.客户端RPC 二、设备控制1.环境准备2.创建设备3.服务端PRC3.1.RPC消息主题3.2.程序源码3.3.创建仪表板3.4.边缘分配仪表板3.5.测试 4.客户端RPC4.1.RPC消息主题4.2.程序源码4.3.规则链4.4.测试 Th…

十四、GPT

在GPT-1之前&#xff0c;传统的 NLP 模型往往使用大量的数据对有监督的模型进行任务相关的模型训练&#xff0c;但是这种有监督学习的任务存在两个缺点&#xff1a;预训练语言模型之GPT 需要大量的标注数据&#xff0c;高质量的标注数据往往很难获得&#xff0c;因为在很多任务…

Qt for Mac阻止MacOS系统休眠

Qt开发的应用程序如果电脑休眠了会影响软件的使用&#xff0c;因此在软件的使用过程中需要防止电脑休眠&#xff0c;在Win上有专门的API进行处理&#xff0c;在Mac上也必需使用Mac平台自身的API&#xff0c;本篇介绍在Mac平台下使用Qt阻止Mac系统休眠。 要调用Mac系统的API&am…

vulhub中GitLab 任意文件读取漏洞复现(CVE-2016-9086)

GitLab是一款Ruby开发的Git项目管理平台。在8.9版本后添加的“导出、导入项目”功能&#xff0c;因为没有处理好压缩包中的软连接&#xff0c;已登录用户可以利用这个功能读取服务器上的任意文件。 环境运行后&#xff0c;访问http://your-ip:8080即可查看GitLab主页&#xff0…

PC电脑如何使用HDMI连接小米电视当显示屏

使用HDMI连接好当时和电脑&#xff0c;HDMI2.0会更清晰&#xff1b;小米电视会自动弹窗提示你有HDMI 接口连接&#xff0c;或者你进入信号源进行选择即可&#xff1b;需要平时我们电脑的显示器正常连接&#xff0c;然后按 win p &#xff0c;选择 扩展 屏幕&#xff1b; 进入设…

27-2 文件上传漏洞 - 前端绕过

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 前端绕过思路 - 禁用 JavaScript: 背景: 当前开发行业大多采用前后端分离模式,后端使用多种开发语言如 PHP、Java 等,而前端主要使用 JavaScript(JS)。因此,禁用 JavaScrip…

开设新量子计算中心!IonQ 全力加速量子商业化

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨浪味仙 沛贤 深度好文&#xff1a;1000字丨8分钟阅读 近日&#xff0c;量子计算公司IonQ对外宣布&#xff0c;将在华盛顿开设一家新量子中心。公告里还提出&#xff0c…

html5黑色大气的个人博客全屏滚动个人主页源码HTML+JS+CSS

html5黑色大气的个人博客全屏滚动个人主页源码HTMLJSCSS

软件测试 自动化测试selenium 基础篇

文章目录 1. 什么是自动化测试&#xff1f;1.1 自动化分类 2. 什么是 Selenium &#xff1f;3. 为什么使用 Selenium &#xff1f;4. Selenium 工作原理5. Selenium 环境搭建 1. 什么是自动化测试&#xff1f; 将人工要做的测试工作进行转换&#xff0c;让代码去执行测试工作 …

【Frida】04_Frida中使用TypeScript脚本(采坑)

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境演示目标 1️⃣ 操作步骤安装node 20.10.0在 VSCode 中打开项目目录初始化一个 NodeJS 项目安装 TypeScript初始化 TypeScript 项目安装依赖配置 TypeScript编写代码编译设置编译脚本运行&#xff0c;查看结果 2️⃣ 采坑frida-compi…

旧华硕电脑开机非常慢 电脑开机黑屏很久才显示品牌logo导致整体开机速度非常的慢怎么办

前提条件 电池需要20&#xff05;&#xff08;就是电池没有报废&#xff09;且电脑接好电源&#xff0c;千万别断电&#xff0c;电脑会变成砖头的 解决办法 更新bios即可解决&#xff0c;去对应品牌官网下载最新的bios版本就行了 网上都是一些更新驱动啊

深度学习 精选笔记(12)卷积神经网络-理论基础1

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

JS原型和原型链的理解

原型链图&#xff0c;图中Parent是构造函数&#xff0c;p1是通过Parent实例化出来的一个对象 前置知识 js中对象和函数的关系&#xff0c;函数其实是对象的一种 函数、构造函数的区别&#xff0c;任何函数都可以作为构造函数&#xff0c;但是并不能将任意函数叫做构造函数&…