2023/9/24总结

news2024/10/6 6:03:32

Redis

Redis 是一个基于内存的键值数据库

安装

Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装_明金同学的博客-CSDN博客

出现上面代表安装成功了

redis 一共有 16 个库

安装后 再安装图形化界面

图形界面十分方便去使用

redis数据结构介绍

redis 是 键值对的数据库  key 一般是 string 类型 但是 value 的类型 多种多样

String  类型

  • set  添加或者修改一个已经存在的String类型的键值对
  • get 获取到对应  key  的  value
  • mset  批量添加多个  String  类型的 键值对
  • mget  获取到所有  key  的 value
  • incr  让一个整型的  key  自增  1
  • incrby  让一个整型的  key  自增  并且指定 步长
  • incrbyfloat  让一个 浮点 类型 的数字自增并且指定步长
  • setnx  添加一个String 类型的 键值对  前提时 这个 key 不存在 否则不执行
  • setex  添加一个 String 类型的键值对  并且指定有效期

key 的结构  

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

Hash 类型

类似于  java  中的 HashMap 结构  Hash  结构 可以将对象中的 每个  字段 独立存储  可以针对 单个字段做 CRUD

  • hset key field value 添加或者修改 hash 类型 key 的 field 的值
  • hset key field 获取一个hash类型key 的 field 的值
  • hmset 批量添加多个 hash 类型 key 的 field 的值
  • hmget 批量获取 多个 hash 类型 key 中的 所有 field 和 value
  • hgetall  获取一个hash类型的key中的所有的field 和 value
  • hkeys 获取一个hash 类型 key 中 所有的 field
  • hvals 获取一个hash 类型 的 key 中的 所有的 value
  • hincrby 让一个hash 类型 key 字段值 自增 并 指定步长
  • hsetnx 添加一个 hash 类型的 key 的 field 值 前提是这个 field 不存在 否则不执行

List  类型

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

特征也与 LinkedList 类似 

  • 有序
  • 元素可以重复 
  • 插入和删除快
  • 查询速度一般
  • lpush  向 列表 左侧 插入 一个 或者 多个 元素
  • lpop 移除 并 返回 列表 左侧 第一个元素 没有则返回  nil
  • rpush  向 列表 右侧 插入 一个或者多个 元素
  • rpop 移除 并且 返回 列表 右侧 的 第一个元素
  • lrange  返回一段 下标 范围 内 的 所有 元素
  • blpop 和 brpop  与 lpop 和 rpop 类似 只不过 在 没有 元素 时 等待 指定时间 而不是直接 返回 nil

Set   类型

redis 的 set 结构 与 java 中的 HashSet 类似 可以看作 是一个 value 为 null 的 HashMap 

  • 无序
  • 元素 不可 重复
  • 查找快
  • 支持交集 并集 差集 等 功能
  • sadd 向 set 中 添加 一个多个元素
  • srem  移除 set 中的指定元素
  • scard 返回 set 中元素的个数
  • sismemery 判断 一个元素 是否存在 于 set 中
  • smemers 获取 set 中 所有 元素
  • sinter  求 集合 的 交集
  • sdiff  求 集合 的 差集
  • sunion 求 集合 的并集

SortedSet 类型

redis 中的 SortedSet 是一个可排序 的 set 集合 与 java 中的 TreeSet 有些类似  但是底层 数据结构 却 差别 很大 SortedSet 中 每一个元素 都 带有 一个 score 属性 , 可以基于 score 属性 对元素 排序 。底层 的 实现 是一个 跳表 加 hash 表

  • 可排序
  • 元素 不重复
  • 查询速度快
  • zadd  添加 一个 或 多个元素 到 sortedset 中 如果已经存在 则 更新其 score 值
  • zrem  删除 sortedset 中的一个指定元素
  • zcore  获取 sortedset 中 指定 元素 的score值
  • zrank 获取 sortedset 中的元素个数
  • zcard 获取 sortedset 中元素个数
  • zcount 统计score 值在给定范围 内 所有 元素 的个数
  • zincrby 让sortedset 的指定元素自增  步长 为指定的 increment 值
  • zrange 按照score排序后  获取指定排名 范围内的元素
  • zrangebyscore 按照 score 排序后 获取指定 score 范围内 的 元素
  • zdiff zinter zunion 求差集  交集  并集

默认排名 都是 升序 如果还想要降序 在命令的后面 添加 rev 即可

GEO 类型

BitMap  类型

HyperLog 类型

Redis 通用命令

  • keys  查看符合模板的所有key  不建议在生产环境使用
  • del  删除一个指定的key
  • exists  判断该 key 是否存在
  • expire  设置一个key的有效期  有效期到了后key会自动删除   单位是秒
  • TTL  查看一个key的剩余有效期  当TTL为 -1 时 说明该 数据 永久有效期  为 -2 时表示已经过期

Jedis 的 使用

Jedis 是 redis 在java语言上的 客户端

Java guide | Redis

使用:

新建maven项目

依赖:

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>4.3.1</version>
    </dependency>

测试代码:

package com.lxh;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {
    private Jedis jedis;

    @BeforeEach
    void setUp()
    {
        //建立连接
        jedis=new Jedis("127.0.0.1",6379);
//        如果你有设置密码 就要加下面这句话 我是并没有 设置密码的
//        jedis.auth("123456");
        jedis.select(0);
    }

    @Test
    void testString ()
    {
        String result=jedis.set("name","李泽言");
        System.out.println("result ="+result);

        String name = jedis.get("name");
        System.out.println("name="+name);
    }

    @AfterEach
    void tearDown()
    {
        if (jedis!=null)
        {
            jedis.close();
        }
    }
}

Jedis 连接池

Jedis 本身 是 线程 不安全 的 ,并且 频繁 的 创建 和 销毁 会有性能损耗  因此 我们推荐大家 使用 Jedis 连接池 代替 Jedis 的 直连 方式

代码:

package com.lxh;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {

    private static JedisPool jedisPool = new JedisPool();

    static {
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        //设置最大连接数
        jedisPoolConfig.setMaxTotal(8);
        //设置最大空闲数
        jedisPoolConfig.setMaxIdle(8);
        //设置最小空间数
        jedisPoolConfig.setMinIdle(0);

        jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,1000);

    }

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

运行结果:

SpringDataRedis

SpringDataRedis 是 Spring 中数据 操作 的 模块 包含 各种 对 数据库 的 集成 其中对 Redis 的集成 模块 就叫做 SpringDataRedis 

Spring Data Redis

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

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

SpringDataRedis 使用步骤

新建一个 基于 maven 的 spring 的项目

引入 spring-boot-starter-data-redis 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>redisData-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redisData-demo</name>
    <description>redisData-demo</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>3.0.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>3.1.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.1.4</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

在 application.properties 下 写入这些

#这里是地址 localhost 对应 的 就是 127.0.0.1
spring.data.redis.host=localhost
#这里是端口号
spring.data.redis.port=6379
#如果你需要设置密码,就写这个 否则就不写
#spring.data.redis.password=12345
#当前使用的是哪一个 数据库 一共 是 下标 0 - 15
spring.data.redis.database=1
#是否使用线程池
spring.data.redis.lettuce.pool.enabled=true
#最大活动线程池个数
spring.data.redis.lettuce.pool.max-active=8
#最长等待时间 以毫秒 为单位
spring.data.redis.lettuce.pool.max-wait=2000
#这是最大 空闲 连接池 个数
spring.data.redis.lettuce.pool.max-idle=8

然后就是测试

package com.example.redisdatademo;

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
class RedisDataDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
    }

    @Test
    void testString()
    {
        //写入一条 String 数据
        redisTemplate.opsForValue().set("user","lizeyan");
        String user = (String) redisTemplate.opsForValue().get("user");
        System.out.println("user : "+user);
    }

}

运行 testString  能正确输出即可

SpringDataRedis  的 序列化方式

RedisTemplate 可以 接收任意 Object 作为 值 写入Redis 只不过 写入前会把Object序列化 为字节形式  默认是采用JDK序列化的 ,得到的结构就会变成 这样

缺点  可读性差,内存占用大

我们可以重写方法 来修改 存入 redis 的数据状态

package com.example.redisdatademo;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

@Configuration
public class redisDataConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
    {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置key和hashKey的序列化器为String类型
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // 设置value和hashValue的序列化器为Jackson2JsonRedisSerializer
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;

//
//        //创建 Template
//        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
//        //设置连接工厂
//        redisTemplate.setConnectionFactory(redisConnectionFactory);
//        //设置序列化工具
//        GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
//
//        //key 和 hashKey 采用 string 序列化
//        redisTemplate.setKeySerializer(RedisSerializer.string());
//        redisTemplate.setHashKeySerializer(RedisSerializer.string());
//
//        //value 和 hashValue 采用 string 序列化
//        redisTemplate.setValueSerializer(RedisSerializer.string());
//        redisTemplate.setHashValueSerializer(RedisSerializer.string());
//
//        return redisTemplate;
    }

}

要导入依赖

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

测试输出

如果按照上面这个方式 那么会需要额外的存储空间来存储 这个类的路径  为了节省 内存空间  我们并不会 使用 JSON 序列化 来处理 value 而是 使用 String 序列化 器 。要求 只能存储 String 类型的 key 和 value ,当需要 存储 java 对象 时 手动 完成对象 的序列化 和 反序列化。

Spring 默认提供了一个 StringRedisTemplate 类 它的 key 和 value 的序列化方式 默认就是String 方式 省去了 我们自定义 RedisTemplate 的过程

package com.example.redisdatademo;

import com.example.bean.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootTest
class RedisDataDemoApplicationTests {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //JSON工具
    private static final ObjectMapper mapper=new ObjectMapper();

    @Test
    void contextLoads() {
    }

    @Test
    void testString()
    {
        //写入一条 String 数据
        redisTemplate.opsForValue().set("user","lizeyan");
        String user =(String) redisTemplate.opsForValue().get("user");
        System.out.println("user : "+user);
    }

    @Test
    void testObject()
    {
        redisTemplate.opsForValue().set("user:xm",new User("许墨",26));
        User newUser=(User) redisTemplate.opsForValue().get("user:xm");
        System.out.println(newUser);
    }

    @Test
    void testStringTemplate() throws JsonProcessingException {
        //准备对象
        User user=new User("helios",22);

        //手动序列化
        String json=mapper.writeValueAsString(user);
        //写入一条数据到 redis
        stringRedisTemplate.opsForValue().set("user:zql",json);

        //读取数据
        String val=stringRedisTemplate.opsForValue().get("user:zql");

        //反序列化
        User newUser=mapper.readValue(val,User.class);
        System.out.println("user : "+newUser);
    }

}

运行 testStringTemplate 就可以了 我们可以发现这个是没有类的路径的

 

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

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

相关文章

Java————网络编程

一 、网络编程基础 1. 为什么需要网络编程 用户在浏览器中&#xff0c;打开在线视频网站&#xff0c; 如优酷看视频&#xff0c;实质是通过网络&#xff0c; 获取到网络上的一个视频资源。 与本地打开视频文件类似&#xff0c;只是视频文件这个资源的来源是网络。 相比本地资…

ubuntu20.04部署ntp服务器ntpd(ntpdate )

文章目录 步骤1. 安装NTP2. 配置NTP3. 重启NTP服务4. 检查NTP服务状态5. 验证NTP同步ntpq -p检查本地ntp服务是否正常服务器不能连外网&#xff0c;如何配置&#xff1f; ntpdate -q xxx查询ntp服务器时间 步骤 1. 安装NTP 首先&#xff0c;在终端中更新你的包列表&#xff0…

vue项目 H5 动态设置浏览器标题

1&#xff0c;先将要展示的标题存本地 if (that.PromotionInfo.Title) {localStorage.setItem("AcTitle", that.PromotionInfo.Title)} 2,现在路由meta中设置标题&#xff0c;再在路由守卫中设置 import Vue from vue import Router from vue-router import prom…

游戏录屏软件推荐,教你录制高清游戏视频

“有没有好用的游戏录屏软件推荐呀&#xff0c;最近当上了游戏主播&#xff0c;平台要求每天都要发一个游戏视频&#xff0c;可是我的游戏录屏软件太拉胯了&#xff0c;录制出来的视频非常糊&#xff0c;导致平台审核不通过&#xff0c;所以想问问大家有没有游戏录屏软件推荐一…

机器视觉检测在流水线上的技术应用

机器视觉在流水线上的应用机器视觉系统的主要功能可以简单概括为&#xff1a;定位、识别、测量、缺陷检测等。相对于人工或传统机械方式而言&#xff0c;机器视觉系统具有速度快、精度高、准确性高等一系列优点。随着工业现代化发展&#xff0c;机器视觉已经广泛应用于各大领域…

【Git】轻松学会 Git:实现 Git 的分支管理

文章目录 前言一、对分支的理解二、分支的创建三、分支的切换3.1 切换到 dev 分支3.2 在 dev 分支上进行文件的修改和提交3.2 来回切换 master 和 dev 分支&#xff0c;查看修改的内容 四、分支的合并五、分支的删除六、冲突的合并6.1 模拟制造冲突6.2 解决冲突 七、分支管理策…

openGauss学习笔记-79 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT应用场景

文章目录 openGauss学习笔记-79 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT应用场景79 MOT应用场景 openGauss学习笔记-79 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT应用场景 本节介绍了openGauss内存优化表&#xff08;Memory-Optimized Table&am…

Java基于基于微信小程序的快递柜管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 第一章&#xff1a;简介第二章、***\*开发环境&#xff1a;\******后端&#xff1a;****前端&am…

msvcp110.dll丢失是什么意思?msvcp110.dll丢失的五种修复方法

在现代社会&#xff0c;计算机已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;随着计算机技术的不断发展&#xff0c;我们也会遇到各种各样的问题。其中&#xff0c;msvcp110.dll丢失是许多用户经常遇到的问题之一。本文将详细介绍msvcp110.dll丢失的修复方法&…

基于微信小程序的健身房私教预约平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

echarts学习总结

一、新建一个简单的Echarts 首先新建一个vue2的项目&#xff0c;项目中安装Echarts cnpm install echarts --save1、title标题组件&#xff0c;包含主标题和副标题。 2、tooltip提示框组件 3、 legend图例组件 4、 series

算法通过村第九关-二分(中序遍历)黄金笔记|二叉搜索树

文章目录 前言1. 有序数组转二叉搜索树2. 寻找连个正序数组的中位数总结 前言 提示&#xff1a;有时候&#xff0c;我感觉自己一辈子活在两个闹钟之间&#xff0c;早上的第一次闹钟&#xff0c;以及5分钟之后的第二次闹钟。 --奥利弗萨克斯《意识的河流》 每个专题都有简单题&a…

新能源汽车OBC车载充电机(实物拆解)

需要样件请联&#xff1a;shbinzer 拆车邦 车载OBC简介 从产品/系统角度看OBC及在新能源汽车的作用。如下图&#xff0c;是威迈斯的OBC车载充电机&#xff0c;威迈斯今年刚上市&#xff0c;是OBC和DC/DC的领先企业。 图片来源&#xff1a;威迈斯官网(OBC) …

【简单图论】CF898 div4 H

Problem - H - Codeforces 题意&#xff1a; 思路&#xff1a; 手玩一下样例就能发现简单结论&#xff1a; v 离它所在的树枝的根的距离 < m 离这个根的距离时是 YES 否则就是NO 实现就很简单&#xff0c;先去树上找环&#xff0c;然后找出这个根&#xff0c;分别给a 和…

视频监控系统/视频汇聚平台EasyCVR有下级平台注册时出现断流情况该如何排查解决?

视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等&#xff0c;视频智能分析平台EasyCVR融合性强、开放度…

手把手教你制作登录、注册界面 SpringBoot+Vue.js(cookie的灵活运用,验证码功能)

一、用户登录界面 实现思路&#xff1a;用户在界面输入用户名和密码传入变量。用post方法传输到后端&#xff0c;后端接收整个实体对象。将用户名提取出。在dao层方法中通过select注解查询&#xff0c;返回数据库对应的数据对象。如果返回为空则return false。不为空则通过比对…

Mock快速入门使用及组件构造首页

一.什么是Mock.js Mock.js&#xff08;也称为 Mockjs 或 Mock.js&#xff09;是一个用于前端开发的模拟数据生成和接口模拟工具。它的主要作用是帮助前端开发人员在开发过程中模拟后端 API 的响应数据&#xff0c;以便进行测试和开发&#xff0c;而无需实际后端服务器支持。 模…

进灰的iPhone是印度组装?且慢嘲讽,这是中国制造!

苹果的iPhone15Pro max被拆机发现镜头出现灰尘&#xff0c;一些人士第一时间就说是印度制造&#xff0c;然而这些拆机博主晒出的图片显示却是中国制造&#xff0c;显然这与一些人士的预期有所不同&#xff0c;导致如此结果可能与iPhone的组装工期太紧张有关。 苹果的iPhone15生…

力扣刷题-链表-删除链表的倒数第N个节点

19.删除链表的倒数第N个节点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a;输入&#xff1a;head [1], n 1 输出&…

网络安全自学入门:(超详细)从入门到精通学习路线规划,学完即可就业

很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习&#xff0c;最终也只是会无疾而终&#xff01;黑客是一个大的概念&#xff0c;里面包含了许多方向&#xff0c;不同的方向需要学习的内容也不一样。 算上从学校开始学习&#xff0c;已经在网安这条路上走…