从0到1构建自己的短链接系统

news2024/7/4 4:27:34

1. 短链系统简介

1.1 短链系统的定义与用途

短链系统是指将一个较长的URL地址,通过特定的算法生成一个较短的、具备唯一性的URL地址。这种系统广泛应用于社交网络、短信、邮件营销等场景,它能帮助用户在字数受限的情况下分享链接,并且还具有一定的数据统计与分析功能。

1.2 短链系统的核心功能

一个完善的短链系统通常包括以下核心功能:

  • 短链接生成:将长链接转换成短链接,并保证短链接的唯一性与高效性。
  • 短链接访问:通过短链接重定向到原始长链接,保证用户能访问到目标地址。
  • 数据统计:统计每个短链接的点击次数、IP、来源等数据,方便后续的分析和优化。
  • 链接管理:提供接口或后台系统,便于用户管理和查看生成的短链接。

1.3 短链系统的架构设计概述

为了实现上述功能,我们需要对系统的架构进行详细设计,系统各部分的职责与协作模式需要明确。总体上,短链系统的架构可以分为以下几个部分:

  • API层:提供生成短链接和解析短链接的接口。
  • 服务层:处理短链接的生成与解析逻辑。
  • 数据层:负责长链接与短链接的存储及管理,可以使用数据库或者缓存系统。
  • 缓存层:提高系统性能,常用缓存系统如Redis可以在短链频繁被访问时减少直接数据库查询的压力。

2. 系统设计

在设计一个短链系统时,我们需要考虑到短链接的生成算法、数据存储方案以及短链接的访问与解析流程。合理的设计能确保系统的稳定性和高效性。

  • 短链接生成时序图

file

  • 短链接解析时序图

file

2.1 短链接生成算法

短链接的生成是短链系统的核心功能之一,设计一个高效的生成算法至关重要。在这里我们介绍两种常用的算法:哈希算法和Base62编码。

2.1.1 哈希算法

哈希算法通过对长链接进行哈希计算,生成一个固定长度的字符串。常用的哈希算法有MD5、SHA-1等。哈希算法简单高效,但由于哈希比特位较长而不适用于直接生成短链接。为了获得更短的链接,我们通常需要结合Base62编码使用。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashUtil {
    public static String getMD5(String url) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(url.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : array) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

2.1.2 Base62编码

Base62编码是一种将字节数组转换为可读字符串的技术,它使用62个字符(0-9, a-z, A-Z)表示不同的值。Base62编码生成的字符串较短,非常适合作为短链接。
以下是Base62编码的示例代码:

public class Base62 {
    private static final String BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static String encode(long value) {
        StringBuilder sb = new StringBuilder();
        while (value != 0) {
            sb.append(BASE62.charAt((int) (value % 62)));
            value /= 62;
        }
        return sb.reverse().toString();
    }

    public static long decode(String shortLink) {
        long result = 0;
        for (char c : shortLink.toCharArray()) {
            result = result * 62 + BASE62.indexOf(c);
        }
        return result;
    }
}

2.2 数据存储方案

选择合适的数据存储方案对于短链系统的性能和稳定性至关重要。常用的存储方案有关系数据库和NoSQL数据库。

2.2.1 NoSQL数据库选择

考虑到短链系统需要高并发和快速读写的特性,NoSQL数据库是一个不错的选择。常用的NoSQL数据库有Redis、MongoDB等。
在这里,我们选择Redis作为存储方案,因其高效的读写性能和丰富的数据类型支持。

2.2.2 数据库表设计

在设计数据库表时,我们需要考虑到短链接与长链接的映射关系。一个简单的设计如下:

  • 短链接表 (ShortLink):用于存储短链接与长链接的映射关系。
  • id:自增主键
  • short_link:短链接
  • long_link:长链接
  • create_time:创建时间
  • expire_time:过期时间(可选)
CREATE TABLE ShortLink (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    short_link VARCHAR(10) NOT NULL,
    long_link TEXT NOT NULL,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expire_time TIMESTAMP
);

2.3 短链接访问与解析

短链系统在生成短链接后,还需处理短链接的访问与解析。

2.3.1 短链访问流程

当用户访问一个短链接时,系统需要解析该短链接并重定向到对应的长链接。流程如下:

  • 1.接收到短链接访问请求。
  • 2.查找短链接对应的长链接(缓存优先,缓存未命中则访问数据库)。
  • 3.将请求重定向到长链接。

2.3.2 缓存机制

为提升访问速度和减轻数据库压力,我们可以引入缓存机制。常用缓存系统如Redis 允许我们快速查找短链接。缓存机制的设计包括:

  • 缓存策略:使用设置超时时间的LRU策略。
  • 缓存更新:生成短链接时将映射关系写入缓存。
public class ShortLinkService {
    private final RedisTemplate<String, String> redisTemplate;
    private final ShortLinkRepository shortLinkRepository; // 假设有一个Repository处理数据库操作

    public ShortLinkService(RedisTemplate<String, String> redisTemplate, ShortLinkRepository shortLinkRepository) {
        this.redisTemplate = redisTemplate;
        this.shortLinkRepository = shortLinkRepository;
    }

    public String getLongLink(String shortLink) {
        String longLink = redisTemplate.opsForValue().get(shortLink);
        if (longLink == null) {
            // 缓存未命中,从数据库查找
            longLink = shortLinkRepository.findLongLinkByShortLink(shortLink);
            if (longLink != null) {
                // 更新缓存
                redisTemplate.opsForValue().set(shortLink, longLink);
            }
        }
        return longLink;
    }
}

3. 系统实现

在这一章节中,我们将详细讲解如何在Java中设计并实现一个短链系统。从项目初始化到各个功能模块的具体实现,都会详细阐述。

3.1 项目初始化与环境搭建

首先,我们需要创建一个新的Spring Boot项目,并进行基本的环境配置。

  • 项目目录结构
short-url/
├── src/
│   ├── main/
│   │   ├── java/com/example/shorturl/
│   │   │   ├── controller/
│   │   │   ├── entity/
│   │   │   ├── repository/
│   │   │   ├── service/
│   │   │   ├── ShortUrlApplication.java
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   ├── schema.sql
│   │   │   ├── data.sql
└── pom.xml
  • 依赖管理

在pom.xml文件中添加必要的依赖,包括Spring Boot、Spring Data JPA、Redis等。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>
  • 配置文件

在application.properties中配置数据库和Redis连接信息:

spring.datasource.url=jdbc:mysql://localhost:3306/short_url?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=yourpassword

spring.redis.host=localhost
spring.redis.port=6379

3.2 实体类设计

设计短链接与长链接映射的实体类。

package com.example.shorturl.entity;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "short_link")
public class ShortLink {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "short_link", nullable = false, unique = true)
    private String shortLink;

    @Column(name = "long_link", nullable = false)
    private String longLink;

    @Column(name = "create_time", nullable = false)
    private LocalDateTime createTime;

    @Column(name = "expire_time")
    private LocalDateTime expireTime;

    // Getters and Setters
}

3.3 服务层实现

服务层负责核心业务逻辑的实现,包括短链接的生成和解析。

3.3.1 短链接生成服务

实现短链接生成服务,包括长链接输入、短链接生成以及数据存储。

package com.example.shorturl.service;

import com.example.shorturl.entity.ShortLink;
import com.example.shorturl.repository.ShortLinkRepository;
import com.example.shorturl.util.Base62;
import com.example.shorturl.util.HashUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class ShortLinkService {

    @Autowired
    private ShortLinkRepository shortLinkRepository;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public String createShortLink(String longLink) {
        String md5Hash = HashUtil.getMD5(longLink);
        String shortLink = Base62.encode(md5Hash.hashCode());

        ShortLink link = new ShortLink();
        link.setShortLink(shortLink);
        link.setLongLink(longLink);
        link.setCreateTime(LocalDateTime.now());

        shortLinkRepository.save(link);

        redisTemplate.opsForValue().set(shortLink, longLink);
        
        return shortLink;
    }

    public String getLongLink(String shortLink) {
        String longLink = redisTemplate.opsForValue().get(shortLink);
        
        if (longLink == null) {
            ShortLink link = shortLinkRepository.findByShortLink(shortLink);
            if (link != null) {
                longLink = link.getLongLink();
                redisTemplate.opsForValue().set(shortLink, longLink);
            }
        }
        
        return longLink;
    }
}

3.3.2 短链接解析服务

短链接解析服务负责通过短链接获取对应的长链接,并实现缓存机制。

package com.example.shorturl.service;

import com.example.shorturl.entity.ShortLink;
import com.example.shorturl.repository.ShortLinkRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class ShortLinkService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ShortLinkRepository shortLinkRepository;

    public String getLongLink(String shortLink) {
        // 从Redis缓存中获取长链接
        String longLink = redisTemplate.opsForValue().get(shortLink);
        if (longLink == null) {
            // 缓存未命中,从数据库查找
            ShortLink link = shortLinkRepository.findByShortLink(shortLink);
            if (link != null) {
                longLink = link.getLongLink();
                // 将长链接存放到缓存中,有效期为24小时
                redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);
            }
        }
        return longLink;
    }
}

3.4 控制层实现

控制层负责处理HTTP请求,将请求数据传递给服务层,并返回结果。

3.4.1 创建短链接的API

实现创建短链接的API,将长链接转化为短链接并返回。

package com.example.shorturl.controller;

import com.example.shorturl.service.ShortLinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ShortLinkController {

    @Autowired
    private ShortLinkService shortLinkService;

    @PostMapping("/shorten")
    public String createShortLink(@RequestParam String longLink) {
        return shortLinkService.createShortLink(longLink);
    }
}

3.4.2 访问短链接的API

实现访问短链接的API,通过短链接获取长链接并重定向。

package com.example.shorturl.controller;

import com.example.shorturl.service.ShortLinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/s")
public class RedirectController {

    @Autowired
    private ShortLinkService shortLinkService;

    @GetMapping("/{shortLink}")
    public void redirect(@PathVariable String shortLink, HttpServletResponse response) throws IOException {
        String longLink = shortLinkService.getLongLink(shortLink);
        if (longLink != null) {
            response.sendRedirect(longLink);
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
    }
}

3.5 缓存层实现

使用Redis实现缓存,提升系统性能。

3.5.1 使用Redis进行缓存

在服务层使用Redis对长链接进行缓存。

@Autowired
private RedisTemplate<String, String> redisTemplate;

3.5.2 缓存策略

采用LRU策略,实现缓存有效期设置为24小时。

redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);

4. 系统测试与优化

在完成短链系统的设计与实现之后,接下来需要对系统进行全面的测试和优化,确保系统的稳定性和高效性。

4.1 单元测试

单元测试是保证系统稳定性的重要环节。通过对各个模块进行单元测试,我们可以验证每个模块的功能是否符合预期。

4.1.1 服务层测试

写一个简单的测试类,对短链接生成服务和解析服务进行测试。

package com.example.shorturl;

import com.example.shorturl.service.ShortLinkService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ShortLinkServiceTests {

    @Autowired
    private ShortLinkService shortLinkService;

    @Test
    public void testCreateShortLink() {
        String longLink = "https://www.example.com";
        String shortLink = shortLinkService.createShortLink(longLink);
        Assertions.assertNotNull(shortLink);
    }

    @Test
    public void testGetLongLink() {
        String longLink = "https://www.example.com";
        String shortLink = shortLinkService.createShortLink(longLink);
        String retrievedLongLink = shortLinkService.getLongLink(shortLink);
        Assertions.assertEquals(longLink, retrievedLongLink);
    }
}

4.1.2 控制层测试

使用MockMvc对控制层进行测试,确保API的正确性。

package com.example.shorturl;

import com.example.shorturl.controller.ShortLinkController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
public class ShortLinkControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testCreateShortLink() throws Exception {
        mockMvc.perform(post("/api/shorten")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param("longLink", "https://www.example.com"))
                .andExpect(status().isOk());
    }

    @Test
    public void testRedirect() throws Exception {
        String shortLink = mockMvc.perform(post("/api/shorten")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param("longLink", "https://www.example.com"))
                .andReturn()
                .getResponse()
                .getContentAsString();

        mockMvc.perform(get("/s/" + shortLink))
                .andExpect(status().is3xxRedirection());
    }
}

4.2 性能优化

在完成基本功能和测试之后,我们需要对系统进行性能优化,以提高其在高并发环境下的响应速度和稳定性。

4.2.1 数据库优化

针对数据库的优化,可以考虑以下几种方法:

  • 索引优化:为短链接和长链接表添加合适的索引,提高查询效率。
CREATE INDEX idx_short_link ON short_link(short_link);
CREATE INDEX idx_long_link ON short_link(long_link);
  • 读写分离:使用主从复制和读写分离技术,将读操作分散到从库,从而减轻主库压力。

4.2.2 缓存优化

缓存是提升系统性能的重要手段,通过合理利用缓存,可以减少数据库查询次数,提高系统的响应速度。

  • 缓存穿透:对每个访问短链接的请求进行缓存,防止缓存穿透。如果短链接不存在,可以缓存一个特殊的值(如空字符串),并设置合理的过期时间。
public String getLongLink(String shortLink) {
    String longLink = redisTemplate.opsForValue().get(shortLink);
    if (longLink == null) {
        longLink = shortLinkRepository.findByShortLink(shortLink);
        if (longLink != null) {
            redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);
        } else {
            // 缓存空结果,防止缓存穿透
            redisTemplate.opsForValue().set(shortLink, "", 1, TimeUnit.HOURS);
        }
    }
    return "".equals(longLink) ? null : longLink;
}
  • 缓存雪崩:通过设置不同的缓存过期时间,避免大量缓存同时失效导致的缓存雪崩问题。
random = new Random();
long expireTime = 24 + random.nextInt(12); // 设置24-36小时的随机有效时间
redisTemplate.opsForValue().set(shortLink, longLink, expireTime, TimeUnit.HOURS);
  • 热点缓存:对于访问频率高的短链接,可以采用更长的缓存有效时间,减少缓存的频繁刷新。
if (isHotLink(shortLink)) {
    redisTemplate.opsForValue().set(shortLink, longLink, 72, TimeUnit.HOURS); // 热点链接缓存72小时
} else {
    redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS); // 普通链接缓存24小时
}

// 判断是否为热点链接的简单实现
private boolean isHotLink(String shortLink) {
    // 这里可以根据访问频率或其他指标来判断
    return shortLink.startsWith("hot");
}

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

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

相关文章

【干货】【全网最全】【全网最详细】 javaWeb关于Thymeleaf+SpringBoot 的学习教程,看这一篇就够了。

大家好&#xff0c;我是DX3906 第一部分&#xff1a;介绍 Thymeleaf 简介 1.什么是Thymeleaf Thymeleaf是一个用于Java和Java EE平台的服务器端模板引擎&#xff0c;它可以用来在服务端生成HTML、XML、JavaScript、CSS甚至纯文本的输出。Thymeleaf适用于需要快速开发和维护Web…

设备智能化:中国星坤线缆组件的解决方案!

在当今快速发展的电子行业中&#xff0c;产品小型化和成本效益是制造商追求的两大目标。中国星坤端子电缆组件以其灵活性和高效性&#xff0c;为电子设备制造商提供了一种理想的解决方案。本文将探讨星坤端子电缆组件的优势以及其在不同电子设备中的应用。 端子线&#xff1a;小…

Linux命令学习2

一.文件基础命令 1.alias-给某个命令取别名 使用方式&#xff1a;alias cl ls -la 说明&#xff1a;将ls -la命令取别名为cl,使用这种方式只是临时将命令取别名&#xff0c;重启中断后&#xff0c;就会失效。 问题1&#xff1a;如何永久性的设置命令的别名&#xff1f; 答…

简过网:专科生可以考的编制岗位有哪些?这5个铁饭碗要抓住了!

专科生可以考的编制岗位有哪些&#xff1f;以下这几种可以考的&#xff0c;尤其是应届毕业生&#xff0c;一定要抓住机会哦&#xff01; ​ 一、三支一扶&#xff1a;专科生可报考&#xff0c;期满可转编。 三支一扶&#xff1a;支农、支医生、支教、扶贫 工作时间一般为2年&…

车载双向认证框架设计

最近工作需要&#xff0c;手写了一个双向认证库&#xff0c;可以用在Java、Android上&#xff0c;不限于PC/手机、车载平台。首先我们来看看双向认证的原理机框架设计思路&#xff0c;最后会给出下载链接大家可以体验或者源码参考。 因为可以和FlexNet网络库&#xff08;参考我…

实现高效写入:Schemaless 写入性能优化指南

物联网应用常常需要收集大量的数据&#xff0c;用以支持智能控制、业务分析和设备监控等功能。然而&#xff0c;应用逻辑的更新或硬件的调整可能会导致数据采集项频繁变化&#xff0c;这是时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;面临的一大挑…

Mybatis-映射文件中select标签resultType属性的使用

数据库的最最基本操作“增删改查”&#xff0c;“查”是最复杂的&#xff0c;有各种各样的查询&#xff0c;所以对应到Mybatis中的select标签也是这四个操作中最复杂的 resultType属性的使用 1.返回的结果是List集合的类型 select标签里的resultType类型设置为List集合里的元…

CCAA:认证通用基础 7(认证的基本概念)

7认证的基本概念 7.1认证类型(产品认证、管理体系认证、服务认证)及基本特征 第一节 认证 1.认证的定义和本质 1.1认证的定义 (1)认证:与产品、过程、体系或人员有关的第三方证明。 ①”产品&#xff0c;过程&#xff0c;体系或人员”是认证的对象&#xff0c;认证是对“产…

Rust: duckdb和polars读csv文件比较

一、文件准备 样本内容&#xff0c;N行9列的csv标准格式&#xff0c;有字符串&#xff0c;有浮点数&#xff0c;有整型。 有两个csv文件&#xff0c;一个大约是2.1万行&#xff1b;一个是64万行。 二、toml文件 [package] name "my_duckdb" version "0.1.0&…

Linux文件IO深入剖析

目录 一、文件IO引发的项目血案 1、分析 一、Linux文件系统基本概念 1、文件系统接口 2、文件系统缓存 二、文件IO 访问方式概述 1、标准文件访问方式 2、直接IO 3、实现方式 4、缓存同步 5、Linux 文件IO流程图 6、血案解决 一、文件IO引发的项目血案 事件经过&am…

甲骨文(Oracle)云AI专家级证书免费获取攻略

这次分享的是甲骨文云(Oracle)2024年最新最热门的AI专家级证书&#xff0c;活动截止日期7/31。 考试为闭卷监考形式&#xff0c;但小李哥已经把题库准备好&#xff0c;分享给大家。 甲骨文Oracle☁️云计算凭借其Oracle原生产品(数据库、ERP等)在云计算市场中具有一定地位。目前…

Kafka入门-分区及压缩

一、生产者消息分区 Kafka的消息组织方式实际上是三级结构&#xff1a;主题-分区-消息。主题下的每条消息只会保存在某一个分区中&#xff0c;而不会在多个分区中被保存多份。 分区的作用就是提供负载均衡的能力&#xff0c;或者说对数据进行分区的主要原因&#xff0c;就是为…

【已解决】Pycharm:卡顿解决方案汇总

可能原因&#xff1a; 1、内存少 2、加载慢 3、文件多 4、硬件老 解决方案&#xff1a; 本机测试在 MAC&#xff0c;Windows、Linux也有相应的设置&#xff0c;请自行查询。 一、调整Pycharm使用内存 Help - Change Memory Settings 二、取消勾选 重复打开上次项目 Pych…

渗透测试之网络基础

文章目录 1. TCP/IP体系结构2. 什么是IP地址2.1 内网IP2.2 公网IP2.3 公网IP与内网IP的关系2.4 判断IP地址是公网或内网 3. 什么是TCP逻辑端口3.1 端口的定义3.2 查看开启的端口 4. HTTP超文本传输协议4.1 什么是HTTP4.2 HTTP协议特点4.3 请求消息——request4.4 HTTP的请求方式…

【研究】大模型应用场景分类与硬件升级

大模型应用#1&#xff1a;从Chatbot到AI Agent&#xff0c;个人助理重塑手机应用生态 AI大模型的能力进步推动Chatbot在C端广泛“出圈”。Chatbot&#xff08;聊天机器人&#xff09;通过自动化方式来处理和回复用户输入&#xff0c;可以模拟人类对话&#xff0c;通过文字或语…

软考系统架构师考试考点整理就看这一篇

软考系统架构师考试考点整理就看这一篇 最近软考成绩出来了不少同学与笔者沟通&#xff0c;聊到软考现在越来越难了&#xff0c;考了两三次都没过&#xff0c;也有不少新同学咨询软考考试的一些福利政策&#xff0c;投入大量的物力&#xff0c;财力&#xff0c;精力&#xff0c…

MySQL笔记——索引

索引 SQL性能分析使用原则SQL提示覆盖索引前缀索引单列索引和联合索引索引设计原则 学习黑马MySQL课程&#xff0c;记录笔记&#xff0c;用于复习。 查询建表语句&#xff1a; show create table account;以下为建表语句&#xff1a; CREATE TABLE account (id int NOT NULL …

反弹shell 纯干货版 --D--K--盾

本文主要讲解我已知的CTF中对VPS的利用的教程模块&#xff0c;所以本篇文章将会持续更新并且有改动 解密base64会解锁新大陆&#xff1a; REvnm77lrpjmlrnnvqTvvJo3MjcwNzcwNTU弹shell 弹shell有很多种类 NC nc ip port -e /bin/sh nc -e /bin/sh ip port //这种版…

从中序与后序遍历序列构造二叉树-二叉树题型

106. 从中序与后序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; right要再left前面 如下如&#xff0c;后序为第一行&#xff0c;最后一个是根&#xff1b; 中序为第二行&#xff0c;中间的为根&#xff1b; 通过后序的最后一个元素从中序中找到根&#xff0…

NodeJs 使用中间件实现日志生成功能

写在前面 今天我们实现一个记录 nodejs 服务请求日志的功能&#xff0c;大概的功能包括请求拦截&#xff0c;将请求的信息作为日志文件的内容写入到 txt 文件中&#xff0c;然后输出到指定的日志到当天日期目录中&#xff0c;从而实现后续查找用户请求信息的功能&#xff0c;下…