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

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");
}

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

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

相关文章

6-47选择整数计算

整数计算&#xff1a; 用swing组件来实现整数计算&#xff0c;需要对整数计算的值进行校验。 import javax.swing.*; import java.awt.*; import java.awt.event.*;public class IntegerCalculator extends JFrame implements ActionListener {private JCheckBox[] checkBoxe…

老杨说运维 | 基于业务全链路的端到端排障分析(文末附现场视频)

前言 青城山脚下的滔滔江水奔涌而过&#xff0c;承载着擎创一往无前的势头&#xff0c;共同去向未来。2024年6月&#xff0c;双态IT成都用户大会擎创科技“数智化可观测赋能双态运维”专场迎来了完满的收尾。 本期回顾来自擎创科技产品总监殷传旺的现场演讲&#xff1a;云原生…

封装了一个iOS联动滚动效果

效果图 实现逻辑和原理 就是在 didEndDisplayingCell 方法中通过indexPathsForVisibleItems 接口获取当前可见的cell对应的indexPath&#xff0c; 然后获取到item最小的那一个&#xff0c;即可&#xff0c;同时&#xff0c;还要在 willDisplayCell 方法中直接设置标题的选中属…

代码随想录算法训练营第三十四天|56. 合并区间、738.单调递增的数字、968.监控二叉树

56. 合并区间 题目链接&#xff1a;56. 合并区间 文档讲解&#xff1a;代码随想录 状态&#xff1a;无语&#xff0c;这题从右边界排序做不了&#xff01; 思路&#xff1a; 排序&#xff1a;按照区间的起始位置进行排序&#xff0c;这样后面处理时可以顺序合并重叠区间。合并…

Cortex-M Fault

Cortex-M CPU 会在系统发生故障时引发异常。非法内存写入和读取、访问未通电的外设、执行无效指令、除以零以及其他问题都可能导致此类异常。通常在所有情况下都会引发 HardFault 异常。对于某些故障&#xff0c;可以启用不同的异常来专门处理这些情况。 Cortex-M 故障异常 …

剪画小程序:视频文案提取神器:制作爆款视频的第一步!

在这个信息爆炸的时代&#xff0c;视频成为了我们获取知识和娱乐的重要途径。 但有时候&#xff0c;我们想要的不仅仅是观看视频&#xff0c;而是能够将其中精彩的文案提取出来&#xff0c;为自己的创作添砖加瓦。 现在&#xff0c;有一款神奇的工具应运而生&#xff0c;为您…

Linux-笔记 全志T113移植正点4.3寸RGB屏幕笔记

目录 前言 线序整理 软件 显示调试 触摸调试 背光调试 前言 由于手头有一块4.3寸的RGB屏幕(触摸IC为GT1151)&#xff0c;正好开发板上也有40Pin的RGB接口&#xff0c;就想着给移植一下&#xff0c;前期准备工作主要是整理好线序&#xff0c;然后用转接板与杜邦线连接验证好…

Vitis Accelerated Libraries 学习笔记--Vision 库的组织结构

1. 简介 Vision 库的组织结构如下&#xff1a; ├── L1/ │ ├── README.md │ ├── examples/ │ ├── include/ │ ├── lib/ │ └── tests/ ├── L2/ │ ├── README.md │ ├── examples/ │ └── tests/ ├── L3/ │ ├── R…

突破架构瓶颈:克服软件系统中的漂移和侵蚀

一种常见但不完美的比喻是将软件系统中的架构漂移和侵蚀与物理建筑的架构相比。虽然这个比喻很直观&#xff0c;但它存在一个根本性的误解&#xff0c;这也常常引发软件开发中的架构问题。 试想一下&#xff0c;一个设计良好的摩天大楼或房屋建成后&#xff0c;我们期望它基本保…

本地电脑配置不足,对工业仿真计算有哪些影响?

工业仿真计算对电脑的要求相对较高&#xff0c;这主要是因为仿真过程涉及到大量的数据处理和复杂的计算任务。一个高效的工业仿真系统需要强大的计算能力和稳定的运行环境&#xff0c;以确保仿真的准确性和实时性。 工业仿真对电脑配置有哪些要求 首先&#xff0c;工业仿真计算…

Prompt 提示词工程:翻译提示

近期在对计算机学习时&#xff0c;许多内容需要看原始的英文论文&#xff0c;对于我这种学渣来说特别不友好&#xff0c;&#x1f937;&#x1f3fb;‍♀️无奈只能一边看翻译&#xff0c;一边学习。 之前有搜到过专门的翻译工具&#xff0c;无奈都是按照字数算费用的&#xf…

都2024年了,现在互联网行情怎样?

都2024年了&#xff0c;互联网行情是怎样的&#xff1f; 很直白的说&#xff0c;依旧是差得很&#xff0c;怎么说&#xff1f; 我刚在掘金上看到一个掘友写的文章&#xff0c;他是四月领了大礼包&#xff0c;据他的描述如下&#xff1a; 互联网行情依旧是差得很&#xff0c;很…

自编码器笔记

编码器解码器自编码器 先压缩特征&#xff0c;再通过特征还原。 判断还原的和原来的是否相等 encode data 在一个“潜在空间”里。它的用途是“深度学习”的核心-学习数据的特征并简化数据表示形式以寻找模式。 变分自编码器&#xff1a; 1. 首先、假设输入数据是符合正态分布…

DDL-表操作-数据类型

一.DDL-表操作-数据类型 MySQL中的数据类型有很多,主要分为三类:数值类型,字符串类型,日期类型。 二.关系表 注意: 无符号和有符号的取值范围不是一样的,无符号需要加上UNSIGNED范围。 BLOB&#xff1a;用来描述二进制数据 TEXT:用来描述字符串 三.定长字符串和变长字符串 c…

【UE5.3】笔记1

内容浏览器&#xff1a;存放项目中所有的资源&#xff1a;关卡、蓝图类...... 关卡--Map 至少有一个关卡&#xff0c;可以有多个关卡 -漫游 视野漫游&#xff1a;鼠标右键WASD QE 鼠标滑轮控制摄像机速度 运行&#xff0c;ESC退出运行,快捷键F8不停止运行单独弹出功能 -创…

2024年第十五届蓝桥杯青少组大赛8月24日开启

据蓝桥杯青少组官网显示&#xff0c;2024年第十五届蓝桥杯青少组大赛8月24日开启。 蓝桥杯青少组历届题库地址&#xff1a;http://www.6547.cn/question/cat/2 蓝桥杯青少组历届真题下载&#xff1a;http://www.6547.cn/wenku/list/10

统一视频接入平台LntonCVS视频共享交换平台智慧景区运用方案

随着夏季的到来&#xff0c;各地景区迎来了大量游客&#xff0c;而景区管理面临的挑战也愈加严峻&#xff0c;尤其是安全问题显得格外突出。 视频监控在预防各类安全事故方面发挥着重要作用&#xff0c;不论是自然景区还是人文景区&#xff0c;都潜藏着诸多安全隐患&#xff0…

第三十篇——等价性:如何从等价信息里找答案?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 知道了等价性的逻辑&#xff0c;通过等价性去衡量事物&#xff0c;像是给…

H5、Vue3、UniApp实现抖音短视频功能

H5、Vue3、UniApp实现抖音短视频功能 ml-swiper https://ext.dcloud.net.cn/plugin?id18973 可 0 配置&#xff0c;高性能、低代码、全端兼容 APP端效果图 微信小程序端效果图 Vue网页端效果图 ml-swiper 可 0 配置&#xff0c;高性能、低代码、全端兼容 APP端效果图 …

mybatis-plus 实体中空字段更新不上

FieldStrategy 是一个枚举类型&#xff0c;它定义了字段的几种策略&#xff1a; IGNORED&#xff1a;忽略判断&#xff0c;所有字段都进行更新操作 NOT_NULL&#xff1a;非 NULL 判断&#xff08;默认策略&#xff09;&#xff0c;字段非 NULL 才进行更新 NOT_EMPTY&#xff…