springboot项目集成,项目流程概述

一、项目介绍

二、项目设计原则

2.1整体原则 

2.2持久层

 

 2.3业务逻辑层

具体分析

 三、实战

3.1项目搭建

 <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.19.2</version></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-launcher</artifactId><scope>test</scope></dependency>

3.2yml配置

spring:datasource:url: 'jdbc:mysql://'username: rootpassword: sql:init:mode: alwaysjackson: #表示在序列化过程中,只有非空的属性才会被包含在JSON输出中。default-property-inclusion: non_nulljpa:show-sql: truehibernate:ddl-auto: updateproperties:hibernate:dialect: org.hibernate.dialect.MySQL8Dialectlogging:level:sql: debugcom:example: debugpattern:console: '%-5level %C.%M[%line] - %msg%n'
server:port: 8080my:secretkey: R28K42ZEJ8LWRHU5salt: 636eac2534bcfcb0

3.3创建业务码VO

package com.yanyu.vo;public enum Code {LOGIN_ERROR(400, "用户名密码错误"),BAD_REQUEST(400, "请求错误"),UNAUTHORIZED(401, "未登录"),TOKEN_EXPIRED(403, "过期请重新登录"),FORBIDDEN(403, "无权限");private final int code;private final String message;Code(int code, String message) {this.code = code;this.message = message;}public int getCode() {return code;}public String getMessage() {return message;}
}
NoArgsConstructor
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResultVO {// 定义状态码字段private int code;// 定义消息字段private String message;// 定义数据字段,用于存储返回给前端的数据private Map<String, Object> data;// 用于构建成功的结果对象public static ResultVO success(Map<String, Object> data) {// 使用Builder模式构建ResultVO对象,并设置状态码为200,以及传入的数据return ResultVO.builder().code(200).data(data).build();}// 用于构建错误的结果对象public static ResultVO error(int code, String msg) {// 使用Builder模式构建ResultVO对象,并设置状态码和错误信息return ResultVO.builder().code(code).message(msg).build();}// 用于构建错误的结果对象,传入的参数为枚举类型Codepublic static ResultVO error(Code code) {// 使用Builder模式构建ResultVO对象,并设置状态码和错误信息,从Code枚举中获取return ResultVO.builder().code(code.getCode()).message(code.getMessage()).build();}
}

3.4创建自定义异常

package com.yanyu.exception;import com.yanyu.vo.Code;
import lombok.Builder;
import lombok.Getter;@Getter
@Builder
public class XException extends RuntimeException{private final Code code;public XException(Code code) {this.code = code;}
}
package com.yanyu.exception;import com.yanyu.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;@Slf4j
@RestControllerAdvice
public class ExceptionController {@ExceptionHandler(XException.class)public ResultVO handleValidException(XException exception) {return ResultVO.error(exception.getCode());}@ExceptionHandler(Exception.class)public ResultVO handleException(Exception exception) {return ResultVO.error(400, "请求错误: " + exception.getMessage());}
}

3.5创建基础工具

配置密码编码器 

package com.example.backendjdbcexamples.component;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;// 配置类,用于定义密码编码器的 Bean
@Configuration
public class PasswordEncoderConfig {// 声明一个名为 getPasswordEncoder 的 Bean,用于提供密码编码器@Beanpublic PasswordEncoder getPasswordEncoder() {// 返回一个 BCryptPasswordEncoder 实例作为密码编码器return new BCryptPasswordEncoder();}
}

JWT编码

@Component // 将该类标记为Spring组件,使其能够被自动扫描并注入到其他类中
public class JWTComponent {// 私钥,从配置文件中获取@Value("${my.secretkey}")private String secretkey;// 编码方法,将传入的map转换为JWT字符串public String encode(Map<String, Object> map) {LocalDateTime time = LocalDateTime.now().plusMonths(1); // 设置过期时间为一个月后return JWT.create() // 创建一个新的JWT对象.withPayload(map) // 设置载荷(payload).withIssuedAt(new Date()) // 设置签发时间.withExpiresAt(Date.from(time.atZone(ZoneId.systemDefault()).toInstant())) // 设置过期时间.sign(Algorithm.HMAC256(secretkey)); // 使用HMAC256算法和私钥进行签名}// 解码方法,验证并解析JWT字符串public DecodedJWT decode(String token) {try {return JWT.require(Algorithm.HMAC256(secretkey)).build().verify(token); // 验证并解析JWT字符串} catch (TokenExpiredException | SignatureVerificationException | JWTDecodeException e) {Code code = e instanceof TokenExpiredException ? Code.TOKEN_EXPIRED : Code.FORBIDDEN; // 根据异常类型设置错误码throw XException.builder().code(code).build(); // 抛出自定义异常}}
}

JWT(JSON Web Token)是一种基于JSON的开放标准,用于在网络上安全地传输信息。它通常用于身份验证和授权。一个JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

  1. 头部(Header):包含描述JWT的元数据,如加密算法。
  2. 载荷(Payload):包含所需要传递的数据,如用户ID、过期时间等。
  3. 签名(Signature):用于验证发送者的身份,防止数据被篡改。

 雪花算法

@Configuration // 标记为配置类
@EnableJdbcAuditing // 启用Jdbc审计功能
public class SnowflakeGenerator {@Bean // 定义一个Bean,用于生成AuditorAware实例AuditorAware<String> auditorAware() {Snowflake s = new Snowflake();return () -> Optional.of(String.valueOf(s.nextId()));}private static class Snowflake {private static final int UNUSED_BITS = 1; // 未使用的位数,始终设置为0private static final int EPOCH_BITS = 41; // 时间戳位数private static final int NODE_ID_BITS = 10; // 节点ID位数private static final int SEQUENCE_BITS = 12; // 序列号位数private static final long maxNodeId = (1L << NODE_ID_BITS) - 1; // 最大节点ID值private static final long maxSequence = (1L << SEQUENCE_BITS) - 1; // 最大序列号值// 自定义纪元(2015年1月1日午夜UTC)private static final long DEFAULT_CUSTOM_EPOCH = 1420070400000L;private final long nodeId; // 节点IDprivate final long customEpoch; // 自定义纪元private volatile long lastTimestamp = -1L; // 上一次的时间戳private volatile long sequence = 0L; // 当前序列号// 使用节点ID和自定义纪元创建Snowflake实例public Snowflake(long nodeId, long customEpoch) {if(nodeId < 0 || nodeId > maxNodeId) {throw new IllegalArgumentException(String.format("NodeId must be between %d and %d", 0, maxNodeId));}this.nodeId = nodeId;this.customEpoch = customEpoch;}// 使用节点ID创建Snowflake实例public Snowflake(long nodeId) {this(nodeId, DEFAULT_CUSTOM_EPOCH);}// 让Snowflake生成一个节点IDpublic Snowflake() {this.nodeId = createNodeId();this.customEpoch = DEFAULT_CUSTOM_EPOCH;}// 生成下一个IDpublic synchronized long nextId() {long currentTimestamp = timestamp();if(currentTimestamp < lastTimestamp) {throw new IllegalStateException("Invalid System Clock!");}if (currentTimestamp == lastTimestamp) {sequence = (sequence + 1) & maxSequence;if(sequence == 0) {// 序列号耗尽,等待到下一个毫秒currentTimestamp = waitNextMillis(currentTimestamp);}} else {// 重置序列号,以便下一个毫秒从零开始sequence = 0;}lastTimestamp = currentTimestamp;long id = currentTimestamp << (NODE_ID_BITS + SEQUENCE_BITS)| (nodeId << SEQUENCE_BITS)| sequence;return id;}// 获取当前时间戳(毫秒)并调整为自定义纪元private long timestamp() {return Instant.now().toEpochMilli() - customEpoch;}// 阻塞并等待到下一个毫秒private long waitNextMillis(long currentTimestamp) {while (currentTimestamp == lastTimestamp) {currentTimestamp = timestamp();}return currentTimestamp;}// 生成节点IDprivate long createNodeId() {long nodeId;try {StringBuilder sb = new StringBuilder();Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();while (networkInterfaces.hasMoreElements()) {NetworkInterface networkInterface = networkInterfaces.nextElement();byte[] mac = networkInterface.getHardwareAddress();if (mac != null) {for(byte macPort: mac) {sb.append(String.format("%02X", macPort));}}}nodeId = sb.toString().hashCode();} catch (Exception ex) {nodeId = (new SecureRandom().nextInt());}nodeId = nodeId & maxNodeId;return nodeId;}// 解析ID,返回包含时间戳、节点ID和序列号的数组public long[] parse(long id) {long maskNodeId = ((1L << NODE_ID_BITS) - 1) << SEQUENCE_BITS;long maskSequence = (1L << SEQUENCE_BITS) - 1;long timestamp = (id >> (NODE_ID_BITS + SEQUENCE_BITS)) + customEpoch;long nodeId = (id & maskNodeId) >> SEQUENCE_BITS;long sequence = id & maskSequence;return new long[]{timestamp, nodeId, sequence};}@Overridepublic String toString() {return "Snowflake Settings [EPOCH_BITS=" + EPOCH_BITS + ", NODE_ID_BITS=" + NODE_ID_BITS+ ", SEQUENCE_BITS=" + SEQUENCE_BITS + ", CUSTOM_EPOCH=" + customEpoch+ ", NodeId=" + nodeId + "]";}}
}

3.6设计数据库表‘

-- 全部角色用户的公共表
-- ID/role需经常使用的信息加密置于token
create table if not exists user
(id bigint(19) not null primary key ,name varchar(8) not null ,number varchar(12) not null ,password varchar(65) not null ,role int not null default 1,create_time datetime not null default current_timestamp,update_time datetime not null default current_timestamp on update current_timestamp,-- 对number字段添加唯一约束,确保每个用户的number值都是唯一的UNIQUE (number),-- 对number字段添加索引,提高查询效率INDEX (number)
);
-- 与user一对一,因此使用共用主键。非组合关系,利于维护
-- 即,添加一个教师时,先提取出user数据加入user表,并获取返回的id;再将id和其他信息存教师表
create table if not exists teacher
(id bigint(19) not null primary key ,title varchar(8),create_time datetime not null default current_timestamp,update_time datetime not null default current_timestamp on update current_timestamp
);
-- 与user为共用主键
create table if not exists student
(id bigint(19) not null primary key ,clazz varchar(8),create_time datetime not null default current_timestamp,update_time datetime not null default current_timestamp on update current_timestamp
);
-- 每门可以有1位授课教师,索引非外键
create table if not exists course
(id bigint(19) not null primary key ,name varchar(45) not null ,teacher_id bigint(19) not null ,create_time datetime not null default current_timestamp,update_time datetime not null default current_timestamp on update current_timestamp,index (teacher_id)
);
-- 学生课程双向多对多。中间表
create table if not exists student_course
(id bigint(19) not null primary key ,student_id bigint(19) not null ,course_id bigint(19) not null ,create_time datetime not null default current_timestamp,update_time datetime not null default current_timestamp on update current_timestamp,index (course_id),index (student_id)
);

3.7实体类

package com.yanyu.dox;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.ReadOnlyProperty;import java.time.LocalDateTime;@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {public static final int USER = 1;public static final int ADMIN = 9;@Id@CreatedByprivate String id;private String name;private String number;@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)private String password;private Integer level;@ReadOnlyPropertyprivate LocalDateTime createTime;@ReadOnlyPropertyprivate LocalDateTime updateTime;}

@JsonProperty 是一个 Java 注解,用于指定 JSON 对象属性的名称。它通常与 Jackson 库一起使用,以便在将 Java 对象转换为 JSON 字符串或将 JSON 字符串转换为 Java 对象时,自定义属性名称。

该属性将仅在序列化(将 Java 对象转换为 JSON 字符串)过程中使用,而在反序列化(将 JSON 字符串转换为 Java 对象)过程中将被忽略。

@CreatedBy

`@CreatedBy` 注解用于自动设置创建对象的用户名称。当使用此注解时,在将对象保存到数据库时,会自动将当前用户的用户名设置为该对象的 `createdBy` 属性值。这样可以避免手动设置创建者的名称,提高代码的可维护性和可读性。 

3.8持久层

@Repository
public interface UserRepository extends CrudRepository<User, String> {User findByNumber(String number);@Modifying@Query("update user u set u.password=:password where u.id=:uid")void updatePassword(String uid, String password);
}

 测试

@SpringBootTest
@Slf4j
class UserRepositoryTest {@Autowiredprivate UserRepository userRepository;@Testvoid findByNumber() {User u = userRepository.findByNumber("admin");log.debug("{}", u.getId());}@Testvoid updatePassword() {userRepository.updatePassword("1120010882327330816", "aaa");}
}

 3.9业务逻辑层

@Service
@RequiredArgsConstructor
public class UserService {private final UserRepository userRepository;private final PasswordEncoder passwordEncoder;public User getUserByNumber(String number) {return userRepository.findByNumber(number);}public User getUser(String uid) {return userRepository.findById(uid).orElse(null);}
}

模拟数据@MockBean

@SpringBootTest
@Slf4j
public class UserServiceMockTest {@Autowiredprivate UserService userService;// 会在测试容器注入模拟组件,不能与整合测试用例混用@MockBeanprivate UserRepository userRepositoryMock;@Testpublic void getUserByNumberTest() {Mockito.when(userRepositoryMock.findByNumber("admin")).thenReturn(User.builder().number("admin").id("101").name("aaa").build());User user = userService.getUserByNumber("admin");log.debug("{}", user.getId());}}

@MockBean 是 Spring Boot 测试框架中的一个注解,用于在单元测试中创建模拟对象(mock objects)。它通常与 @SpringBootTest@WebMvcTest 等注解一起使用,以便在测试环境中自动注入模拟对象。

3.10控制层组件

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/")
@Slf4j
public class LoginController {private final UserService userService; // 用户服务private final PasswordEncoder passwordEncoder; // 密码编码器private final JWTComponent jwtComponent; // JWT组件@PostMapping("login")public ResultVO postLogin(@RequestBody User user, HttpServletResponse response) {User u = userService.getUserByNumber(user.getNumber()); // 根据用户编号获取用户信息if (u == null || !passwordEncoder.matches(user.getPassword(), u.getPassword())) { // 验证用户名和密码return ResultVO.error(Code.LOGIN_ERROR); // 登录失败,返回错误信息}String code = switch(u.getLevel()) { // 根据用户等级生成对应的codecase User.USER -> "Yo87M";case User.ADMIN -> "nU0vt";default -> "";};String token = jwtComponent.encode(Map.of("uid", u.getId(), "role", u.getLevel())); // 生成JWT令牌response.addHeader("role", code); // 将code添加到响应头中response.addHeader("token", token); // 将token添加到响应头中return ResultVO.success(Map.of()); // 登录成功,返回成功信息}
}

@RequiredArgsConstructor

@RequiredArgsConstructor 是 Lombok 库中的一个注解,用于自动生成一个包含所有 final@NonNull 字段的构造函数。

 3.11拦截器组件

@Component // 将该类标记为Spring组件,使其能够被自动扫描并实例化
@Slf4j // 使用Lombok提供的日志功能,简化日志记录操作
@RequiredArgsConstructor // 使用Lombok提供的构造器生成器,自动生成包含final字段的构造函数
public class LoginInterceptor implements HandlerInterceptor { // 实现Spring MVC中的拦截器接口private final JWTComponent jwtComponent; // JWT组件,用于处理JWT令牌的编码和解码private final ResponseHelper responseHelper; // 响应助手,用于构建响应结果@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前执行,返回true则继续处理,返回false则中断请求处理String token = request.getHeader("token"); // 从请求头中获取tokenif (token == null) {responseHelper.response(response, Code.UNAUTHORIZED); // 如果token为空,返回未授权错误return false;//throw XException.builder().code(Code.UNAUTHORIZED).build();}String uid = jwtComponent.decode(token).getClaim("uid").asString(); // 解密token,获取用户IDint role = jwtComponent.decode(token).getClaim("role").asInt(); // 解密token,获取用户角色// 拦截解密出用户真实数据后,置于request供后续使用request.setAttribute("uid", uid);request.setAttribute("role", role);return true; // 继续处理请求}
}

3.12路由

@Configuration // 表示这是一个配置类
@RequiredArgsConstructor // 自动生成包含所有 final 和 @NonNull 字段的构造函数
public class WebMvcConfig implements WebMvcConfigurer { // 实现 WebMvcConfigurer 接口,用于自定义 Spring MVC 的配置private final LoginInterceptor loginInterceptor; // 登录拦截器private final AdminInterceptor adminInterceptor; // 管理员拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) { // 重写 addInterceptors 方法,添加自定义拦截器registry.addInterceptor(loginInterceptor) // 添加登录拦截器.addPathPatterns("/api/**") // 拦截以 /api/ 开头的所有请求路径.excludePathPatterns("/api/login", "/api/welcome"); // 排除登录和欢迎页面的请求路径registry.addInterceptor(adminInterceptor) // 添加管理员拦截器.addPathPatterns("/api/admin/**"); // 拦截以 /api/admin/ 开头的所有请求路径}
}

3.13管理员注入

@Service // 表示这是一个服务类,用于处理业务逻辑
@RequiredArgsConstructor // 自动生成包含所有 final 和 @NonNull 字段的构造函数
public class InitialService {private final UserRepository userRepository; // 用户仓库,用于操作数据库中的用户数据private final PasswordEncoder passwordEncoder; // 密码编码器,用于对密码进行加密@EventListener(classes = ApplicationReadyEvent.class) // 监听应用程序启动完成事件@Transactional // 开启事务支持public void onApplicationEvent() { // 当应用程序启动完成后执行该方法long count = userRepository.count(); // 查询数据库中用户的数量if (count == 0) { // 如果用户数量为0,即数据库中没有用户数据User user = User.builder() // 使用建造者模式创建用户对象.name("admin") // 设置用户名为 admin.level(9) // 设置用户等级为 9.number("admin") // 设置用户编号为 admin.password(passwordEncoder.encode("admin")) // 对密码进行加密后设置用户密码.build(); // 构建用户对象userRepository.save(user); // 将用户对象保存到数据库中}}
}

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

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

相关文章

双链表的实现(数据结构)

链表总体可以分为三大类 一、无头和有头 二、单向和双向 三、循环和不循环 从上面分类得知可以组合成8种不同类型链表&#xff0c;其中单链表最为简单&#xff0c;双联表最为复杂&#xff0c;两种链表都实现后其余链表都不成问题。 我们前期博客已将完成了单向无头不循环链表…

基于PHP的景点数据分析系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 关键理论与技术 3 1.1 框架技术 3 1.1.1 QueryList 3 1.1.2 ThinkPHP 3 1.1.3 Amaze UI 3 1.2 数据可视化技术 4 1.3 数据库技术 4 1.4 本章小结 4 2 需求分析 5 2.1 业务流程分析 5 2.2 功能需求分析 5 2.3 用例分析 7 2.4 非功能性需求…

it-tools工具箱

it-tools 是一个在线工具集合&#xff0c;包含各种实用的开发工具、网络工具、图片视频工具、数学工具等 github地址&#xff1a;https://github.com/CorentinTh/it-tools 部署 docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-tools:lat…

yolov8多batch推理,nms后处理

0. 背景 在高速公路监控视频场景下&#xff0c;图像分辨率大都是1920 * 1080或者2560 * 1440&#xff0c;远处的物体&#xff08;车辆和行人等&#xff09;都比较小。考虑需要对图像进行拆分&#xff0c;然后把拆分后的数据统一送入模型中&#xff0c;推理的结果然后再做nms&am…

【微前端乾坤】 vue2主应用、vue2+webpack子应用,vue3+webpack子应用、vue3+vite子应用的配置

因公司需求 需要将原本vue2iframe 形式的项目改成微前端乾坤的方式。 之前iframe都是直接嵌套到vue2项目的二级目录或者三级目录下的(反正就是要随处可嵌) 用乾坤的原因&#xff1a; 1、iframe嵌套的方式存在安全隐患&#xff1b; 2、项目是联合开发的&#xff0c; 乾坤的方便…

Hack The Box-Crafty

目录 信息收集 rustscan whatweb WEB 漏洞利用 漏洞说明 漏洞验证 提权 get user.txt get Administrator 总结 信息收集 rustscan ┌──(root㉿ru)-[~/kali/hackthebox] └─# rustscan -a 10.10.11.249 --range0-65535 --ulimit5000 -- -A -sC [~] Automatically…

NLP:自定义模型训练

书接上文&#xff0c;为了完成指定的任务&#xff0c;我们需要额外训练一个特定场景的模型 这里主要参考了这篇博客&#xff1a;大佬的博客 我这里就主要讲一下我根据这位大佬的博客一步一步写下时&#xff0c;遇到的问题&#xff1a; 文中的cfg在哪里下载&#xff1f; 要不…

Fastjson漏洞利用合集

0x01 Fastjson 概述 1.应用场景 接口返回数据 Ajax异步访问数据RPC远程调用前后端分离后端返回的数据开放API(一些公司开放接口的时候&#xff0c;我们点击请求&#xff0c;返回的数据是JSON格式的)企业间合作接口(数据对接的时候定义的一种规范&#xff0c;确定入参&#x…

BUUCTF-MISC-[HDCTF2019]信号分析1

题目链接&#xff1a;BUUCTF在线评测 (buuoj.cn) 下载附件是一个WAV的文件&#xff0c;题目又叫做信号分析&#xff0c;用Adobe Audition 打开分析了 发现有很多长短不一样的信号&#xff0c;只需要分析一段 猜测长的是一短的为0 最后得到0101010101010101000000110 百度得知…

vscode如何远程到linux python venv虚拟环境开发?(python虚拟环境、vscode远程开发、vscode远程连接)

文章目录 1. 安装VSCode2. 安装扩展插件3. 配置SSH连接4. 输入用户名和密码5. 打开远程文件夹6. 创建/选择Python虚拟环境7. 安装Python插件 Visual Studio Code (VSCode) 提供了一种称为 Remote Development 的功能&#xff0c;允许用户在远程系统、容器或甚至 Windows 子系统…

【致逝去的青春】《龙珠》作者鸟山明逝世,享年68岁

鸟山明工作室&#xff08;BIRD STUDIO&#xff09;于3月8日发布讣告&#xff1a;鸟山明已于2024年3月1日因急性硬膜下血肿逝世&#xff0c;享年68岁。 《龙珠》从 1984 年开始于《周刊少年Jump》连载&#xff0c;过后曾改编曾多部动画、剧场版、游戏&#xff0c;相关周边商品也…

opengl 学习(二)-----你好,三角形

你好&#xff0c;三角形 分类demo效果解析 分类 opengl c demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>using namespace std;/** * 在学习此节之前&#xff0c;建议将这…

Alveo 概念拓扑结构

在 Alveo 加速卡中,涉及到的概念拓扑结构主要包括 Alveo 卡上的各个关键组件以及与主机系统之间的通信结构。以下是对这些概念拓扑结构的简要介绍: 1.DDR 即双数据率内存(Double Data Rate memory),是一种常见的计算机内存类型,用于存储和提供处理器所需的数据和指令。…

macos m1 arm芯片 使用jpype报错 FileNotFoundError: [Errno 2] JVM DLL not found

startJVM(jpype.getDefaultJVMPath()) 报错 Traceback (most recent call last):File "/Users/thomas990p/PycharmProjects/tuya/volcano-biz-scripts/WenKongFa/FinalCode/java2python/CallJavaAPI.py", line 12, in <module>startJVM(jpype.getDefaultJVMPa…

基于springboot实现大学生兼职网站系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现大学生兼职系统演示 摘要 现代化的市场中&#xff0c;人们日常的工作、生活都在不断的提速&#xff0c;而人们在工作与生活中与互联网的结合也越来越紧密&#xff0c;通过与互联网紧密的结合可以更好地实现日常工作的线上化、信息化、便捷化。现如今的各行各…

ebpf入门---监听所有新进程

什么是ebpf eBPF 全称 extended Berkeley Packet Filter&#xff0c;中文意思是 扩展的伯克利包过滤器。一般来说&#xff0c;要向内核添加新功能&#xff0c;需要修改内核源代码或者编写 内核模块 来实现。而 eBPF 允许程序在不修改内核源代码&#xff0c;或添加额外的内核模…

鸿蒙App基础

像素单位 .1、基础单位 为开发者提供4种像素单位&#xff0c;框架采用vp为基准数据单位。 PS&#xff1a;个人建议使用lpx&#xff0c;配置好配置文件&#xff0c;这里就可以按照UI设计稿实际的来&#xff0c;可以更好的实现设计效果 名称描述px屏幕物理像素单位vp屏幕密度相…

一拖二快充线独特优势

在现代社会&#xff0c;手机已成为我们生活中不可或缺的一部分。随着科技的不断进步&#xff0c;手机的功能越来越强大&#xff0c;从通讯工具逐渐转变为工作、学习和娱乐的得力助手。然而&#xff0c;手机的电量问题一直是困扰着我们的难题。为了解决这个问题&#xff0c;市场…

3•8向女同胞致敬|营销枢纽SaaS厂商乐通达(ltd.com)正式更名枢纽云

为了向女同胞致敬&#xff0c;我们特地选择3月8日女神节变更公司名称&#xff0c;因为《如果SaaS有性别&#xff0c;那 TA一定是女性 》。 2024年3月8日&#xff0c;“杭州乐通达网络有限公司”名称正式变更为“杭州枢纽云计算有限公司”&#xff08;简称&#xff1a;营销枢纽&…

测试常用的Linux命令

前言 直接操作硬件 将把操作硬件的代码封装成系统调用&#xff0c;供程序员使用 虚拟机软件 可以模拟的具有完整硬件系统的功能 可以在虚拟机上安装不同的操作系统 Linux内核只有一个&#xff0c;发行版有很多种 内核来运行程序和管理像磁盘和打印机等硬件设备的核心程序 终端…