当前位置: 首页 > news >正文

基于 Spring Boot 实现图片的服务器本地存储及前端回显

??导读:本文探讨了在网站开发中图片存储的各种方法,包括本地文件系统存储、对象存储服务(如阿里云OSS)、数据库存储、分布式文件系统及内容分发网络(CDN)。文中详细对比了这些方法的优缺点,并针对不同规模的应用推荐了相应的存储策略。此外,还提供了一个基于SpringBoot框架实现服务器本地图片存储与回显的具体示例,涵盖了从图片上传到通过网关服务安全访问图片的全过程。

文章目录
  • 前言
    • 文件存储分类
      • 本地文件系统存储
      • 对象存储服务(OSS)
      • 数据库存储
      • 分布式文件系统
      • 内容分发网络(CDN)
      • 总结
  • 服务器本地图片存储实现
    • 图片上传实现
      • Gateway 服务
        • 将图片访问链接添加到白名单,跳过登录验证
        • 过滤器
      • Admin 服务
        • 依赖
        • 配置文件
        • Controller
        • Service
          • impl
        • 错误码枚举类
        • 工具类
    • 图片回显
      • 静态资源处理
    • 功能测试

前言

在开发网站时,存储图片是常见的需求之一,尤其对于社交平台、电子商务网站等应用。例如社交平台要存储用户头像,要存储用户发布的朋友圈图片,聊天记录图片等等

文件存储分类

为了满足不同场景下的需求,图片存储有多种常见的方式,每种方式都有其适用场景和特点。以下是几种常用的图片存储方式及其优缺点分析

本地文件系统存储

描述:将图片直接保存在Web服务器的本地文件系统中,通常会有一个固定的目录用于存放这些图片文件。

优点

  • 简单易用:实现起来非常简单,适合小型项目快速搭建或者图片较少的项目。
  • 成本低廉:初期成本较低,不需要额外支付存储费用。

缺点

  • 扩展性差:随着图片数量的增加,服务器存储空间会变得紧张,需要频繁地扩容。
  • 备份困难:需要手动进行备份,且容易出现单点故障。
  • 安全性低:服务器直接暴露在互联网上,存在安全隐患。
  • 访问速度受限:图片访问速度受限于服务器带宽,如果有多人同时访问,部分用户需要等待。
对象存储服务(OSS)

描述:使用云服务商提供的对象存储服务,如阿里云OSS、AWS S3、Google Cloud Storage等,将图片存储在云端。

优点

  • 高可用性和持久性:提供多副本冗余,确保数据的高可用性和持久性。
  • 易于扩展:可以根据实际需求动态调整存储空间,无需担心物理存储限制。
  • 安全性高:提供多种安全机制,如访问控制、数据加密等。
  • 全球分布:支持全球多区域部署,提高用户访问速度。
  • 成本效益:按需付费,适合业务量波动较大的应用。

缺点

  • 成本随业务增长而增加:随着存储和带宽的增加,费用也会相应增加。
  • 访问速度受网络影响:网络状况不佳时,图片加载速度可能变慢。
  • 依赖第三方服务:需要考虑服务商的服务质量和稳定性。
  • 需要严格控制图片安全:如果没有严格做好防控措施,图片一旦被有心之人频繁刷量,会造成巨大的费用
数据库存储

描述:将图片以二进制形式存储在数据库中,通常会使用BLOB(Binary Large Object)字段。

优点

  • 事务一致性:图片和相关数据可以保持事务一致性,适合需要强一致性的应用场景。
  • 便于管理:图片和元数据可以集中管理,方便查询和操作。

缺点

  • 性能较差:读取和写入大文件时性能较差,可能会影响数据库的整体性能。
  • 存储成本高:数据库存储成本较高,不适合大量图片的存储。
  • 备份和恢复复杂:数据库备份和恢复过程较为复杂,且占用较多资源。
分布式文件系统

描述:使用分布式文件系统(如Hadoop HDFS、GlusterFS等)来存储图片,适合大规模分布式存储需求。

优点

  • 高可用性和扩展性:支持横向扩展,可以通过增加节点来提升存储能力和访问性能。
  • 容错能力强:具有良好的容错能力,可以自动处理节点故障。
  • 成本效益:相对于传统存储方式,成本更低,适合大规模数据存储。

缺点

  • 复杂度高:实现和维护相对复杂,需要专业的运维团队。
  • 访问速度受网络影响:网络状况不佳时,访问速度可能受影响。
  • 学习曲线陡峭:需要一定的学习成本和技术积累。
内容分发网络(CDN)

描述:结合对象存储服务和CDN,将图片存储在云存储中,并通过CDN加速分发,提高全球用户的访问速度。

优点

  • 全球加速:通过CDN缓存,提高全球用户的访问速度。
  • 高可用性和持久性:结合对象存储服务,确保数据的高可用性和持久性。
  • 成本效益:按需付费,适合业务量大的应用。

缺点

  • 成本较高:使用CDN会增加一定的成本。
  • 配置复杂:需要配置CDN和对象存储服务,相对复杂。
  • 也要严格做好防控措施,否则钱包非常危险
总结

选择合适的图片存储方式需要综合考虑项目的规模、预算、性能要求和未来的扩展性。对于小型项目或初创团队,可以先从本地文件系统存储开始,随着业务的增长逐步迁移到对象存储服务或分布式文件系统。对于大型应用或全球用户较多的场景,建议使用对象存储服务结合CDN,以确保高性能和高可用性。

服务器本地图片存储实现

对于个人开发的小网站,如果图片不多,网站访问量也不多,使用服务器本地存储的方式是比较适合的,本文主要讲解SpringBoot项目如何实现图片如何存储到服务器本地以及前端要怎样才能显示服务器中的图片资源

演示项目说明:该项目使用微服务架构开发,请求首先需要通过Gateway网关,然后转给对应的Admin服务,Admin服务中再处理图片的存储和回显

图片上传实现

Gateway 服务
将图片访问链接添加到白名单,跳过登录验证
spring:profiles:active: damWinapplication:name: vrs-gatewaycloud:gateway:routes:- id: vrs-adminuri: lb://vrs-admin/admin/**predicates:- Path=/admin/**filters:- name: TokenValidateargs:whitePathList:- /admin/user/v1/login- /admin/user/v1/has-username- /admin/user/v1/register- /admin/pic/
过滤器

拦截请求,将网关服务的访问域名放置到请求头中,这样Admin服务就可以在请求头中拿到网关服务的访问域名了

package com.vrs.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.net.InetAddress;
import java.net.UnknownHostException;/*** @Author dam* @create 2024/11/21 20:55*/@Component
public class CustomGlobalFilter {@Value("${server.port}")private int serverPort;/*** 将网关服务的域名端口放到请求头中,方便其他服务使用* @return*/@Bean(name = "customGlobalFilter1")public GlobalFilter customGlobalFilter() {return (exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();String hostAndPort = getHostAndPort(request);ServerHttpRequest modifiedRequest = request.mutate().header("X-Gateway-Host", hostAndPort).build();ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();return chain.filter(modifiedExchange);};}/*** 获取网关服务的访问域名端口* @param request* @return*/private String getHostAndPort(ServerHttpRequest request) {try {// 获取请求的主机名和端口String host = request.getURI().getHost();if (host == null) {// 如果请求中没有主机名,使用本地主机名host = InetAddress.getLocalHost().getHostName();}// 获取请求的协议(HTTP或HTTPS)String scheme = request.getURI().getScheme();return scheme + "://" + host + ":" + serverPort;} catch (UnknownHostException e) {return "unknown";}}
}
Admin 服务
依赖
<!-- 图片压缩工具 -->
<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version>
</dependency>
配置文件

设置上传的文件大小限制,请求的大小限制

spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB
Controller

注意:里面有一步是从请求头中获取网关的访问域名,后面再基于网关的访问域名来拼接图片访问路径,不能直接将Admin服务的域名暴露出去,不然用户可能直接绕过网关的登录验证来访问Admin服务

package com.vrs.controller;import com.vrs.convention.result.Result;
import com.vrs.service.PictureService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.util.Map;/*** @Author dam* @create 2024/11/21 17:00*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/pic/")
public class PictureController {private final PictureService pictureService;/*** 通用上传请求(单个)*/@PostMapping("/upload")public Result<Map<String, Object>> uploadFile(MultipartFile file, HttpServletRequest request) throws Exception {String gatewayHost = request.getHeader("X-Gateway-Host");return pictureService.uploadFile(file, gatewayHost);}
}
Service
package com.vrs.service;import com.vrs.convention.result.Result;
import org.springframework.web.multipart.MultipartFile;import java.util.Map;/*** @Author dam* @create 2024/11/21 17:12*/
public interface PictureService {Result<Map<String, Object>> uploadFile(MultipartFile file, String request);
}
impl
package com.vrs.service.impl;import com.vrs.common.utils.PictureUploadUtil;
import com.vrs.convention.exception.ClientException;
import com.vrs.convention.result.Result;
import com.vrs.convention.result.Results;
import com.vrs.service.PictureService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.util.HashMap;
import java.util.Map;import static com.vrs.common.enums.ErrorCodeEnum.PICTURE_UPLOAD_FAIL;/*** @Author dam* @create 2024/11/21 17:12*/
@Service
public class PictureServiceImpl implements PictureService {@Overridepublic Result<Map<String, Object>> uploadFile(MultipartFile file, String gatewayDomain) {// 上传并返回新文件名称String fileName = PictureUploadUtil.upload(file);String url = gatewayDomain + "/admin" + fileName;Map<String, Object> resultMap = new HashMap<>();resultMap.put("url", url);resultMap.put("fileName", fileName);resultMap.put("originalFileName", file.getOriginalFilename());return Results.success(resultMap);}
}
错误码枚举类
package com.vrs.common.enums;import com.vrs.convention.errorcode.IErrorCode;/*** 用户错误码*/
public enum ErrorCodeEnum implements IErrorCode {PICTURE_UPLOAD_FAIL("B000301", "图片上传失败"),PICTURE_NAME_EXCEED_LENGTH("B000302", "图片名超出长度"),PICTURE_SUFFIX_ERROR("B000302", "图片名没有携带正常后缀名"),PICTURE_TYPE_ERROR("B000302", "图片格式不对,仅限于 .png .jpg .jpeg .gif"),;private final String code;private final String message;ErrorCodeEnum(String code, String message) {this.code = code;this.message = message;}@Overridepublic String code() {return code;}@Overridepublic String message() {return message;}
}
工具类

该工具类主要完成对图片的校验,然后将图片存储到服务器本地,最后返回图片的访问路径

package com.vrs.common.utils;import com.vrs.convention.exception.ClientException;
import com.vrs.convention.exception.ServiceException;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.Objects;
import java.util.UUID;import static com.vrs.common.enums.ErrorCodeEnum.*;/*** @Author dam* @create 2024/11/21 17:18*/
public class PictureUploadUtil {/*** 资源映射路径 前缀*/public static final String PIC_PREFIX = "/pic";/*** 图片存储的根路径*/public static final String UPLOAD_PATH = System.getProperty("user.dir") + File.separator + "upload";/*** 默认的文件名最大长度 100*/public static final int DEFAULT_FILE_NAME_LENGTH = 100;public static final String upload(MultipartFile file) {int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();if (fileNameLength > DEFAULT_FILE_NAME_LENGTH) {// --if-- 如果图片名称过程,抛异常throw new ClientException(PICTURE_NAME_EXCEED_LENGTH);}String name = file.getOriginalFilename();if (!name.contains(".")) {// --if-- 如果图片没有正常后缀throw new ClientException(PICTURE_SUFFIX_ERROR);} else if (!(name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".gif"))) {// --if-- 校验文件是否为图片类型throw new ClientException(PICTURE_TYPE_ERROR);}String[] split = name.split("\.");// 图片名称String fileName = split[0];// 图片后缀String fileSuffix = split[1];// 获取当前日期LocalDate date = LocalDate.now();// 获取年份int year = date.getYear();// 获取月份int month = date.getMonthValue();// 获取日期int day = date.getDayOfMonth();String dir = File.separator + year + File.separator + month + File.separator + day;File dirFile = new File(UPLOAD_PATH + dir);if (!dirFile.exists()) {// 创建相应日期文件夹dirFile.mkdirs();}// 生成一个唯一IDString uuid = UUID.randomUUID().toString().replace("-", "");// 相对路径String relativePath = dir + File.separator + fileName + "-" + uuid + "." + fileSuffix;// 生成图片要上传到的绝对路径String absPath = UPLOAD_PATH + relativePath;// 压缩存储
//        try (InputStream is = file.getInputStream()) {
//            // 设置目标文件
//            File targetFile = new File(absPath);
//
//            // 使用Thumbnails库调整图片分辨率
//            Thumbnails.of(is)
//                    // 设置最大宽度和高度,保持原始比例
//                    .size(1920, 1080)
//                    .toFile(targetFile);
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new ServiceException(e.getMessage());
//        }// 直接保存文件(不压缩)try (InputStream is = file.getInputStream()) {File targetFile = new File(absPath);// 将输入流中的数据复制到目标文件中java.nio.file.Files.copy(is, targetFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {e.printStackTrace();throw new ServiceException(e.getMessage());}return PIC_PREFIX + "/" + year + "/" + month + "/" + day + "/" + fileName + "-" + uuid + "." + fileSuffix;}}

图片回显

图片回显的实现比较简单,添加一个配置类即可

静态资源处理

这段代码的作用是:把网站上显示图片的URL路径(比如 /pic/**)映射到服务器上的一个实际文件夹路径。这样设置后,用户通过浏览器访问这些URL时,就能直接看到存储在服务器指定文件夹里的图片

import com.vrs.common.utils.PictureUploadUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 通用配置** @author dam*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 将图片请求路径映射到对应的本地图片路径registry.addResourceHandler(PictureUploadUtil.PIC_PREFIX + "/**").addResourceLocations("file:" + PictureUploadUtil.UPLOAD_PATH + "/");}}

功能测试

使用Apifox软件发起一个Post请求,带上要上传的图片

在这里插入图片描述

通过链接访问图片,测试通过

在这里插入图片描述

相关文章:

基于 Spring Boot 实现图片的服务器本地存储及前端回显

??导读&#xff1a;本文探讨了在网站开发中图片存储的各种方法&#xff0c;包括本地文件系统存储、对象存储服务&#xff08;如阿里云OSS&#xff09;、数据库存储、分布式文件系统及内容分发网络&#xff08;CDN&#xff09;。文中详细对比了这些方法的优缺点&#xff0c;并…...

深入 TCP VJ-Style

接着 TCP 的文化内涵 继续扯一会儿。 自 30 instruction TCP receive 往前追溯&#xff0c;论文 Jacobson88 源自第一次拥塞崩溃&#xff0c;这篇著名文档在同时期的另一个缘起是另一篇考古文献 [Zhang86] Why TCP Timers Don’t Work Well&#xff0c;后面这篇文献提出了 TCP…...

go高性能单机缓存项目

代码 // Copyright 2021 ByteDance Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apach…...

数据结构绪论

文章目录 绪论数据结构三要素算法 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;数据结构专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月12日01点09分 绪论 数据是信息的载体&#xff0c;描述客观事物属性的数、字符及所有能输入…...

前端开发常用四大框架学习难度咋样?

前端开发常用四大框架指的是 jQuery vue react angular ‌jQuery‌&#xff1a; ‌学习难度‌&#xff1a;相对较低‌特点‌&#xff1a;jQuery 是一个快速、小巧、功能丰富的 JavaScript 库。它使得 HTML 文档遍历和操作、事件处理、动画和 Ajax 交互更加简单。‌适用场景‌&a…...

OWASP 十大安全漏洞的原理

1. Broken Access Control&#xff08;访问控制失效&#xff09; 原理&#xff1a;应用程序未正确实施权限检查&#xff0c;导致攻击者通过篡改请求、强制浏览或权限提升等手段绕过访问控制。 攻击手段&#xff1a; 修改 URL、HTML、或 API 请求以访问未经授权的资源。 删除…...

论文 | ChunkRAG: Novel LLM-Chunk Filtering Method for RAG Systems

本文详细介绍了一种新颖的检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;系统方法——ChunkRAG&#xff0c;该方法通过对文档的分块语义分析和过滤显著提升了生成系统的准确性和可靠性。 1. 研究背景与问题 1.1 检索增强生成的意义 RAG系统结合…...

ORACLE SQL思路: 多行数据有相同字段就合并成一条数据 分页展示

数据 分数表&#xff1a; 学号&#xff0c;科目名&#xff08;A,B,C&#xff09;&#xff0c;分数 需求 分页列表展示&#xff0c; 如果一个学号的科目有相同的分数&#xff0c; 合并成一条数据&#xff0c;用 拼接 科目名 ORACLE SQL 实现 SELECT Z.*, SUBSTR(DECODE(f…...

SpringBoot 手动实现动态切换数据源 DynamicSource (中)

大家好&#xff0c;我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource &#xff08;上&#xff09;-CSDN博客 在上一篇博客中&#xff0c;我带大家手动实现了一个简易版的数据源切换实现&#xff0c;方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…...

y3编辑器教学5:触发器2 案例演示

文章目录 一、探索1.1 ECA1.1.1 ECA的定义1.1.2 使用触发器实现瞬间移动效果 1.2 变量1.2.1 什么是变量1.2.2 使用变量存储碎片收集数量并展现 1.3 if语句&#xff08;魔法效果挂接&#xff09;1.3.1 地形设置1.3.2 编写能量灌注逻辑1.3.3 编写能量灌注后&#xff0c;实现传送逻…...

数值分析——插值法(二)

文章目录 前言一、Hermite插值1.两点三次Hermite插值2.两点三次Hermite插值的推广3.非标准型Hermite插值 二、三次样条插值1.概念2.三弯矩方程 前言 之前写过Lagrange插值与Newton插值法的内容&#xff0c;这里介绍一些其他的插值方法&#xff0c;顺便复习数值分析. 一、Hermi…...

杨振宁大学物理视频中黄色的字,c#写程序去掉

先看一下效果&#xff1a;&#xff08;还有改进的余地&#xff09; 写了个程序消除杨振宁大学物理中黄色的字 我的方法是笨方法&#xff0c;也比较刻板。 1&#xff0c;首先想到&#xff0c;把屏幕打印下来。c#提供了这样一个函数&#xff1a; Bitmap bmp new Bitmap(640, 48…...

uni-app 设置缓存过期时间【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…...

微信小程序base64图片与临时路径互相转换

1、base64图片转临时路径 /*** 将base64图片转临时路径* param {*} dataurl* param {*} filename* returns*/base64ImgToFile(dataurl, filename "file") {const base64 dataurl; // base64码const time new Date().getTime();const imgPath wx.env.USER_DATA_P…...

蓝桥杯刷题——day2

蓝桥杯刷题——day2 题目一题干题目解析代码 题目二题干解题思路代码 题目一 题干 三步问题。有个小孩正在上楼梯&#xff0c;楼梯有n阶台阶&#xff0c;小孩一次可以上1阶、2阶或3阶。实现一种方法&#xff0c;计算小孩有多少种上楼梯的方式。结果可能很大&#xff0c;你需要…...

5.删除链表的倒数第N个节点

19.删除链表的倒数第N个节点 题目&#xff1a; 19. 删除链表的倒数第 N 个结点 - 力扣&#xff08;LeetCode&#xff09; 分析&#xff1a; 要删除倒数第几个节点&#xff0c;那么我们需要怎么做呢&#xff1f;我们需要定义两个指针&#xff0c;快指针和慢指针&#xff0c;…...

自己总结:selenium高阶知识

全篇大概10000字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间30min 一、等待机制 如果有一些内容是通过Ajax加载的内容&#xff0c;那就需要等待内容加载完毕才能进行下一步操作。 为了避免人为操作等待&#xff0c;会遇到的问题&#xff0c; selenium将等待转换…...

前端怎么预览pdf

1.背景 后台返回了一个在线的pdf地址&#xff0c;需要我这边去做一个pdf的预览&#xff08;需求1&#xff09;&#xff0c;并且支持配置是否可以下载&#xff08;需求2&#xff09;&#xff0c;需要在当前页就能预览&#xff08;需求3&#xff09;。之前我写过一篇预览pdf的文…...

activemq 的安装部署

下载 https://activemq.apache.org/components/classic/download/# 在/opt目录下载 wget https://dlcdn.apache.org//activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz解压 tar -zxvf apache-activemq-5.18.6-bin.tar.gz配置java环境 vim /opt/apache-activemq-5.18.6/b…...

【H3CNE邓方鸣】配置链路聚合+2024.12.11

文章目录 链路聚合作用负载分担分类静态聚合动态聚合 链路聚合作用 定义&#xff1a;把连接到统一交换机上的多个物理端口捆绑为一个逻辑端口 增加链路带宽&#xff1a;聚合组内只要还有物理端口存活&#xff0c;链路就不会中断 提供链路可靠性&#xff1a;避免了STP计算&…...

开源清理工具OpenClearn:透明可控的数字垃圾管理方案

1. 项目概述&#xff1a;一个开源的“清洁工”如何重塑你的数字生活如果你和我一样&#xff0c;是个在数字世界里摸爬滚打了十几年的老鸟&#xff0c;那你电脑里肯定也有一堆“数字垃圾”。这些垃圾不是指那些过时的文件&#xff0c;而是那些你明明已经删除了&#xff0c;但操作…...

STM32H743 FDCAN实战:手把手教你调试CAN节点错误计数器与Bus_Off状态

STM32H743 FDCAN实战&#xff1a;从寄存器到代码的Bus_Off恢复指南 当你的STM32H743项目突然出现CAN通信中断&#xff0c;调试器里FDCAN_PSR寄存器的BOFF位亮起红灯时&#xff0c;真正的挑战才刚刚开始。这不是普通的通信故障&#xff0c;而是触发了CAN协议中最严厉的惩罚机制—…...

C++/Qt项目内存问题排查:除了Valgrind,这些工具和技巧你也该知道

C/Qt项目内存问题排查&#xff1a;除了Valgrind&#xff0c;这些工具和技巧你也该知道 在开发中等复杂度的Qt桌面或嵌入式应用时&#xff0c;内存问题往往是最难缠的"隐形杀手"。我曾参与过一个医疗影像处理系统的开发&#xff0c;项目后期突然出现随机崩溃&#xff…...

数字电路小白也能懂:用Logisim搞定LED计数电路,从真值表到封装测试保姆级教程

数字电路零基础实战&#xff1a;用Logisim构建LED计数器的完整指南 从困惑到清晰&#xff1a;为什么选择Logisim作为数字电路入门工具 第一次接触数字电路时&#xff0c;面对密密麻麻的逻辑门和抽象的真值表&#xff0c;大多数初学者都会感到无从下手。传统教材中复杂的公式推导…...

AbMole丨CL 316243:β3-肾上腺素受体激动剂,在代谢调控与能量消耗研究中的应用

CL 316243是一种高选择性的β3-肾上腺素受体&#xff08;β3-AR&#xff09;激动剂&#xff0c;其对β3-AR的选择性远高于β1-AR和β2-AR[1]。CL 316243&#xff08;CAS No.&#xff1a;138908-40-4&#xff09;通过激活β3-AR&#xff0c;刺激腺苷酸环化酶&#xff08;AC&…...

基于Playwright的Instagram自动化技能包:原理、实现与智能体集成

1. 项目概述与核心价值最近在折腾个人智能助理&#xff0c;想让它能帮我处理一些社交媒体上的琐事&#xff0c;比如自动查看Instagram上的新动态、给特定帖子点赞或者保存一些有趣的图片。在网上搜了一圈&#xff0c;发现了一个叫adamanz/instagram-skill的开源项目&#xff0c…...

企业私有化AI训练推理一体工作站/自动化AI算法训练服务器DLTM让企业AI自主可控

在企业智能化转型的浪潮中&#xff0c;AI模型开发始终是横亘在多数企业面前的一道“技术鸿沟”。一边是熟悉行业场景、深谙业务痛点的业务团队&#xff0c;却因不懂代码、不熟悉算法&#xff0c;难以将实际需求转化为可用的AI能力&#xff1b;一边是掌握专业开发技能的技术团队…...

AI LED调光控制器智能功率 MOSFET 完整选型方案

2026年随着 AI 技术在智能照明与调光控制中的深度渗透&#xff08;如自适应色温、场景联动、人因节律照明&#xff09;&#xff0c;调光控制器对功率 MOSFET 提出更高要求&#xff1a;高精度PWM响应、超低导通损耗、高散热密度。微碧半导体&#xff08;VBsemi&#xff09;基于S…...

Go语言集成Ollama本地大模型:gollama库实战指南

1. 项目概述&#xff1a;当Go语言遇上本地大模型如果你是一名Go语言开发者&#xff0c;同时又对本地运行的大型语言模型&#xff08;LLM&#xff09;感兴趣&#xff0c;那么你很可能已经感受到了两者之间的“次元壁”。一方面&#xff0c;Go以其简洁、高效和强大的并发能力&…...

Allegro中Route Keepout、Design Outline和Cutout到底怎么用?一张图讲清PCB布局中的‘禁区’设置

Allegro中三大边界工具实战指南&#xff1a;Route Keepout、Design Outline与Cutout的精准运用 在PCB设计领域&#xff0c;边界定义如同城市规划中的红线&#xff0c;既决定了板卡的物理形态&#xff0c;又影响着电气性能的发挥。Cadence Allegro作为行业标准工具&#xff0c;提…...