告别混乱!【Java Web】项目分层架构全指南:核心三层 + 关键辅助包详解


目录

1.前言

2.正文

2.1为什么要分层

2.2核心三层详解

2.2.1Controller层(表现层/API层)

2.2.2Service层(业务逻辑层)

2.2.3DAO层(持久层)

2.3. 核心关系与数据流转:分层架构的交互逻辑

2.3.1. 依赖方向控制

2.3.2数据对象转换

2.3.3. 异常处理机制

2.3.4分层交互的黄金法则

2.4.关键辅助包讲解

2.4.1 model/entity/domain 包

2.4.2 dto/vo 包

2.4.3 repository 包

2.4.4 config 包

2.4.5 util 包

2.4.6 common 包

2.4.7 exception/advice 包

2.4.8 interceptor/filter/aop 包

2.4.9 constant 包

3.小结


1.前言

当你打开一个全新的Java项目,面对空白的IDE窗口时,第一个技术决策将决定整个项目的命运。这个决策不是选择Spring Boot还是Quarkus,不是用MyBatis还是JPA,甚至不是确定数据库类型——而是如何组织你的代码结构

当所有代码混沌地堆砌在一起,项目便注定走向"屎山"的命运。而分层架构,正是对抗这种混沌的最有力武器。

本文将深入剖析Java项目分层的核心逻辑:

  • 解剖分层价值:直面混沌代码的五大痛点

  • 解构三层模型:Controller-Service-DAO的精准职责边界

  • 透视数据流转:DTO/Entity的优雅转换之道

  • 搭建支撑体系:9大关键辅助包构建健壮生态

现在,让我们揭开分层架构的面纱,掌握构建可持续Java应用的基石法则。


插播一条消息~

🔍 十年经验淬炼 · 系统化AI学习平台推荐

系统化AI学习平台 https://www.captainbed.cn/scy/

✅ 为什么值得投入?

  • 📚 完整知识体系:从数学基础 → 工业级项目(人脸识别/自动驾驶/GANs),内容由浅入深

  • 💻 实战为王:每小节配套可运行代码案例(提供完整源码)

  • 🎯 零基础友好:用生活案例讲解算法,无需担心数学/编程基础

🚀 特别适合

  • 想系统补强AI知识的开发者

  • 转型人工智能领域的从业者

  • 需要项目经验的学生


2.正文

2.1为什么要分层

在软件开发中,随着功能增加和业务逻辑复杂化,代码的组织方式直接影响项目的可持续性。未分层架构的典型表现是关注点混杂:一个类或模块同时承担了数据访问、业务规则处理、用户界面交互等多种职责。这种结构会迅速引发一系列可维护性和扩展性问题:

核心痛点分析:

  1. 高耦合性 (High Coupling)

    • 不同功能的代码物理上相邻且逻辑上相互依赖。

    • 后果:修改数据库访问逻辑可能迫使业务层和表示层同步调整;更换前端技术需要重写包含业务逻辑的代码块。

    • 影响:变更成本指数级增长,系统僵化。

  2. 低内聚性 (Low Cohesion)

    • 单一模块承担多个不相关的职责,违反单一职责原则 (SRP)。

    • 后果:理解模块功能需要梳理无关代码;定位特定逻辑(如价格计算)效率低下。

    • 影响:代码可读性差,认知负担加重。

  3. 可测试性障碍 (Testability Barriers)

    • 业务逻辑与数据库、UI 紧耦合。

    • 后果:单元测试需要启动数据库、模拟 HTTP 请求等环境。

    • 影响:测试编写困难、执行缓慢,导致测试覆盖率低下。

  4. 可维护性恶化 (Maintainability Degradation)

    • 功能代码分散或冗余。

    • 后果:修复缺陷需在多处相似逻辑中定位;添加新功能缺乏明确插入点。

    • 影响:开发效率下降,错误率上升。

  5. 复用性缺失 (Lack of Reusability)

    • 通用逻辑(如数据查询)与特定上下文绑定。

    • 后果:相同功能需重复实现,修改时需多处同步。

    • 影响:代码冗余,一致性难以保障。

分层架构:系统化的解决方案

分层架构的核心是通过职责分离构建逻辑边界。每一层聚焦特定功能域,并通过定义良好的接口与相邻层交互:

  • 解耦核心价值:层间依赖单向流动(如Controller->Service->DAO)。修改数据访问层实现(如从JDBC迁移至JPA)只需调整DAO层,Service层接口不变则无需修改。

  • 高内聚实现:每层/模块职责明确(DAO层仅处理数据持久化,Service层封装业务规则)。

  • 可测试性提升:业务逻辑可脱离数据库进行单元测试;数据访问层可通过接口模拟测试。

  • 可维护性增强:问题定位更精准(数据问题查DAO层,逻辑错误查Service层);功能扩展路径清晰。

  • 复用性改善:通用能力(如基础数据访问)可封装为独立层供多业务复用。

分层思维的类比

  • 建筑学:地基(基础设施层)- 承重结构(核心业务层)- 室内装修(用户交互层)。各层独立演进,维护地基不影响居住空间。

  • 计算机体系:硬件层 - 操作系统层 - 应用层。应用开发无需关注硬件指令细节。

2.2核心三层详解

项目分层架构中,Controller-Service-DAO是最基础的模型。明确各层职责与交互边界是架构设计的关键。下面进行逐层解析:

2.2.1Controller层(表现层/API层)

定位:系统与外部交互的入口,处理HTTP协议通信。

核心职责

  • 请求解析:接收HTTP请求,解析URL路径、请求参数(@PathVariable@RequestParam)、Header及请求体(@RequestBody)。

  • 基础校验:执行参数格式校验(如使用JSR 303注解 @NotNull@Valid)。

  • 服务调度:调用对应的Service层方法执行业务逻辑。

  • 异常处理:捕获Service层抛出的业务异常,或交由全局异常处理器处理。

  • 响应封装:将Service层返回的数据转换为客户端所需格式(JSON/XML/视图模型)。

技术实现

@RestController // 声明为REST控制器
@RequestMapping("/api/orders") // 基础路径映射
public class OrderController {@Autowiredprivate OrderService orderService; // 依赖业务层接口@PostMappingpublic ResponseEntity<OrderDTO> createOrder(@RequestBody @Valid OrderCreateRequest request) {// 1. 接收并校验请求体// 2. 调用Service执行业务OrderDTO order = orderService.createOrder(request); // 3. 封装HTTP响应return ResponseEntity.status(HttpStatus.CREATED).body(order); }
}

关键原则

  • 保持精简:仅处理协议转换,业务逻辑零侵入。

  • 无状态性:不存储业务状态,依赖Service层管理。

  • 单一入口:每个Controller聚焦一个业务域(如OrderController)。

常见误区

  • 业务逻辑泄露:在Controller中进行价格计算、状态判断等业务操作。

  • 跨层访问:直接调用DAO层操作数据库,绕过Service层。

  • 过度转换:在Controller内实现复杂的数据结构转换(应使用专用转换器)。


2.2.2Service层(业务逻辑层)

定位:系统的核心领域逻辑处理器,保障业务一致性。

核心职责

  • 业务规则实现:执行具体的业务逻辑(如订单计价、库存校验)。

  • 事务管理:通过@Transactional声明事务边界,确保原子性操作。

  • 资源协调:组合调用多个DAO方法或微服务接口(如支付服务)。

  • 业务校验:执行复杂规则校验(如“用户积分是否足够”)。

  • 领域模型转换:将DAO层实体(Entity)转换为业务DTO。

技术实现

@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderDao orderDao; // 依赖数据层接口@Autowiredprivate PaymentServiceClient paymentClient; // 依赖外部服务@Transactional // 声明事务边界@Overridepublic OrderDTO createOrder(OrderCreateRequest request) {// 1. 业务校验(如库存检查)validateStock(request.getItems());// 2. 构建领域对象Order order = buildOrderDomain(request);// 3. 调用DAO持久化数据orderDao.save(order);// 4. 调用外部服务(如支付)paymentClient.processPayment(order.getId(), order.getTotalAmount());// 5. 返回业务DTOreturn OrderMapper.toDTO(order); }
}

关键原则

  • 业务焦点:所有核心业务规则集中在此层实现。

  • 接口隔离:通过接口(OrderService)暴露能力,隐藏实现细节。

  • 事务控制:事务声明在Service层,避免分布式事务碎片化。

  • 可复用设计:业务方法应独立于调用方(Controller/定时任务)。

常见误区

  • 持久化逻辑泄露:在Service中直接编写SQL或JPA条件查询。

  • 协议耦合:处理HTTP状态码、响应头等协议层细节。

  • 上帝服务:单个Service类过度膨胀(应拆分为OrderValidationServiceOrderCalculationService等子域服务)。


2.2.3DAO层(持久层)

定位:数据存储的技术抽象层,封装底层存储访问细节。

核心职责

  • CRUD操作:提供数据的创建、查询、更新、删除基础能力。

  • 数据映射:实现数据库表结构与领域对象的双向转换。

  • 技术封装:隐藏具体存储实现(SQL/NoSQL/文件系统)。

  • 连接管理:处理数据库连接池、事务会话等底层资源。

技术实现

@Repository // Spring组件注解(含异常转换)
public interface OrderDao extends JpaRepository<Order, Long> { // Spring Data JPA 自动实现接口// 自定义查询方法@Query("SELECT o FROM Order o WHERE o.userId = :userId AND o.status = :status")List<Order> findByUserAndStatus(@Param("userId") Long userId, @Param("status") OrderStatus status);
}// MyBatis实现
@Mapper
public interface OrderMapper {@Insert("INSERT INTO orders(...) VALUES(...)")@Options(useGeneratedKeys = true, keyProperty = "id")void insert(Order order);
}

关键原则

  • 技术专注:只关注数据存取,不包含业务规则。

  • 接口抽象:通过接口(OrderDao)暴露操作,支持实现替换。

  • 存储无关:上层不感知使用MySQL还是MongoDB(依赖倒置)。

  • 性能优化:负责SQL调优、二级缓存等存储层性能问题。

常见误区

  • 业务逻辑入侵:在SQL语句或存储过程中实现业务规则(如CASE WHEN status='PAID' THEN ...)。

  • 领域对象暴露:将数据库实体(Entity)直接返回给Controller层(应通过Service转换为DTO)。

  • 接口设计失衡:方法粒度不合理(如saveUserAndUpdateOrder违反单一职责)。

关键约束

  1. 单向调用:Controller → Service → DAO

  2. 禁止跨层访问(如Controller直接调用DAO)

  3. 实体对象不出Service层(DAO返回Entity,Service转换为DTO)

2.3. 核心关系与数据流转:分层架构的交互逻辑

分层架构的核心价值体现在各层之间的协作关系和数据流转机制上。以下是关键交互流程的解析:

数据流转全流程图解

2.3.1. 依赖方向控制

  • 严格单向依赖

    • Controller ➔ Service ➔ DAO

    • 禁止反向依赖:DAO 层不得调用 Service 方法

    • 禁止跨层调用:Controller 不得直接访问 DAO

  • 设计价值

    • 符合依赖倒置原则(DIP)

    • 下层变更不影响上层(如更换ORM框架只需修改DAO实现)

    • 各层可独立测试和演进

2.3.2数据对象转换

不同层级使用不同数据对象,实现职责隔离:

层级输入对象输出对象转换说明
DAO层Entity / 查询参数Entity / 值对象直接操作数据库实体
Service层Entity / DTODTO / 业务对象Entity→DTO转换
Controller层DTO / 请求对象VO(View Object)DTO→VO转换

转换示例: 

// DAO层返回数据库实体
@Repository
public interface UserDao {UserEntity findById(Long id); // 返回Entity
}// Service层进行转换
@Service
public class UserService {public UserDTO getUser(Long id) {UserEntity entity = userDao.findById(id);return UserMapper.INSTANCE.toDTO(entity); // Entity->DTO}
}// Controller层适配视图
@RestController
public class UserController {@GetMapping("/users/{id}")public UserVO getUser(@PathVariable Long id) {UserDTO dto = userService.getUser(id);return new UserVO(dto.getId(), dto.getName()); // DTO->VO}
}

2.3.3. 异常处理机制

异常按层级分类处理:

  • DAO层异常

    • 类型:DataAccessException(Spring封装)

    • 示例:SQL语法错误、连接超时

    • 处理:向上抛出,不处理业务语义

  • Service层异常

    • 类型:自定义BusinessException

    • 示例:余额不足、库存校验失败

    • 特点:携带业务错误码和友好消息

  • Controller处理

    @RestControllerAdvice
    public class GlobalExceptionHandler {// 处理业务异常@ExceptionHandler(BusinessException.class)public ResponseEntity<ErrorResponse> handleBusinessEx(BusinessException ex) {return ResponseEntity.badRequest().body(new ErrorResponse(ex.getCode(), ex.getMessage()));}// 处理系统异常@ExceptionHandler(DataAccessException.class)public ResponseEntity<ErrorResponse> handleDataAccessEx() {return ResponseEntity.internalServerError().body(new ErrorResponse("DB_ERROR", "数据库服务异常"));}
    }

2.3.4分层交互的黄金法则

  1. 数据隔离原则

    •  Entity 只在 DAO-Service 层流转

    • DTO 在 Service-Controller 层传递

    • VO 仅用于 Controller-Client 交互 

  2. 异常传递规范

    • DAO 异常 → Service 层转换业务异常

    • Service 异常 → Controller 统一处理

    • 禁止在 DAO 层捕获业务异常

  3. 接口契约约束

    • 层间通过接口交互(Service接口、DAO接口)

    • 实现可替换(如JDBC实现替换为JPA实现)

关键认知:分层不是简单的目录划分,而是通过规范的数据流转和接口契约,构建可维护、可扩展的代码生态系统。这种约束看似增加了转换成本,实则是应对复杂性的必要投资。

2.4.关键辅助包讲解

2.4.1 model/entity/domain 包

定位:领域模型的核心容器
职责

  • 存放数据库映射实体类(UserEntityOrderEntity

  • 定义领域驱动设计(DDD)中的聚合根、值对象

  • 封装核心业务属性与行为

最佳实践

// 实体类示例(JPA注解)
@Entity
@Table(name = "t_user")
public class UserEntity {@Id@GeneratedValue(strategy = IDENTITY)private Long id;@Column(nullable = false, length = 32)private String name;@Column(unique = true, updatable = false)private String email;// 领域行为方法public boolean isVip() {return this.vipLevel > 0;}
}

关键约束

  • 禁止直接暴露:Controller层不应直接返回Entity对象

  • 贫血模型规避:实体类应包含领域行为方法(如calculateTotal()

  • 持久化解耦:领域模型与数据库表结构非强绑定(可用DTO转换)


2.4.2 dto/vo 包

定位:层间数据传输的契约载体
核心类型

类型用途示例
Request DTO接口入参UserCreateRequest
Response DTOService层出参UserDetailDTO
VOController最终响应对象UserVO

转换示例

public class UserDTO {// 不暴露敏感字段private Long id;private String displayName;private Integer vipLevel;// 转换逻辑集中管理public static UserDTO fromEntity(UserEntity entity) {return new UserDTO(entity.getId(),entity.getName() + "(" + entity.getCode() + ")",entity.getVipLevel());}
}

设计价值

  • 安全隔离:屏蔽passwordsalary等敏感字段

  • 协议适配:VO可包含前端专用的字段(如formattedDate

  • 版本兼容:实体变更不影响接口契约


2.4.3 repository 包

定位:持久层的现代接口抽象
Spring Data JPA范式

@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {// 方法名自动推导查询List<UserEntity> findByStatusAndVipLevelGreaterThan(UserStatus status, int minLevel);// 自定义SQL查询@Query("SELECT u FROM UserEntity u WHERE u.lastLogin < :expireDate")List<UserEntity> findInactiveUsers(@Param("expireDate") LocalDate date);
}

技术选型对比

实现方式适用场景特点
Spring Data JPA快速CRUD开发接口自动实现
MyBatis Mapper复杂SQL优化XML/注解双模式
JdbcTemplate极致性能控制原生SQL操作

2.4.4 config 包

定位:系统组件的装配中心
典型配置类

@Configuration
public class AppConfig {// 数据源配置@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource dataSource() {return DruidDataSourceBuilder.create().build();}// MVC消息转换器@Beanpublic HttpMessageConverters customConverters() {FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();return new HttpMessageConverters(converter);}// 线程池配置@Bean("taskExecutor")public Executor asyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setQueueCapacity(200);return executor;}
}

配置管理原则

  1. 环境隔离:通过application-{profile}.yml管理多环境配置

  2. 密钥安全:敏感信息使用jasypt加密或注入Vault

  3. 组件可见性:使用@ConditionalOnProperty控制Bean加载条件


2.4.5 util 包

定位:通用技术能力工具箱
工具类设计规范

public final class DateUtils {// 禁止实例化private DateUtils() {}// 线程安全的日期格式化private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// 日期转字符串public static String format(LocalDateTime date) {return date.format(FORMATTER);}// 解析日期public static LocalDateTime parse(String dateStr) {return LocalDateTime.parse(dateStr, FORMATTER);}
}

工具类分类

  • 字符串处理StringUtils

  • 集合操作CollectionUtils

  • 加解密EncryptUtils

  • IO操作FileUtils

  • 校验工具ValidationUtils

禁忌:避免在util包中存放业务相关的工具方法(应放入业务模块)


2.4.6 common 包

定位:项目全局基础设施
核心内容

// 统一响应体
public class ApiResponse<T> {private int code;private String msg;private T data;public static <T> ApiResponse<T> success(T data) {return new ApiResponse<>(200, "OK", data);}
}// 业务异常基类
public class BusinessException extends RuntimeException {private final ErrorCode errorCode;public BusinessException(ErrorCode code) {super(code.getMessage());this.errorCode = code;}
}

最佳实践

  • 使用枚举管理错误码:

    public enum ErrorCode {USER_NOT_FOUND(1001, "用户不存在"),BALANCE_INSUFFICIENT(2001, "余额不足");private final int code;private final String message;
    }

2.4.7 exception/advice 包

定位:异常处理的统一防线
全局异常处理器

@RestControllerAdvice
public class GlobalExceptionHandler {// 处理业务异常@ExceptionHandler(BusinessException.class)public ApiResponse<Void> handleBusinessEx(BusinessException ex) {return ApiResponse.fail(ex.getErrorCode());}// 处理参数校验异常@ExceptionHandler(MethodArgumentNotValidException.class)public ApiResponse<Void> handleValidEx(MethodArgumentNotValidException ex) {String errorMsg = ex.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.joining("|"));return ApiResponse.fail(ErrorCode.INVALID_PARAM, errorMsg);}
}

异常处理策略

  1. 业务异常:转换为友好提示(HTTP 200 + 错误码)

  2. 参数异常:返回具体校验失败字段(HTTP 400)

  3. 系统异常:记录日志并返回通用错误(HTTP 500)


2.4.8 interceptor/filter/aop 包

定位:横切关注点解决方案
技术对比

组件作用域典型场景
FilterServlet容器级别字符编码/跨域处理
InterceptorSpring MVC级别登录验证/权限检查
AOP方法级别日志/事务/缓存/性能监控

AOP实践示例

@Aspect
@Component
public class PerformanceMonitor {// 监控Service层方法性能@Around("execution(* com.example..service.*.*(..))")public Object logTime(ProceedingJoinPoint pjp) throws Throwable {long start = System.currentTimeMillis();Object result = pjp.proceed();long cost = System.currentTimeMillis() - start;if (cost > 300) { // 慢方法预警logger.warn("Method {} executed in {} ms", pjp.getSignature(), cost);}return result;}
}

2.4.9 constant 包

定位:项目常量管理的核心中枢
常量管理范式

public final class OrderConstants {// 状态枚举public static final int STATUS_CREATED = 10;public static final int STATUS_PAID = 20;// 缓存键模板public static final String CACHE_KEY_ORDER = "order:%s";// 配置项键名public static final String CONFIG_MAX_QUANTITY = "order.max.quantity";
}

升级方案:使用枚举强化类型安全

public enum OrderStatus {CREATED(10, "已创建"),PAID(20, "已支付");private final int code;private final String desc;// 通过code获取枚举public static OrderStatus fromCode(int code) { ... }
}

3.小结

今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,你的支持就是对我最大的鼓励,大家加油!

另外最后的最后,欢迎大家加入我的社区哦,初创社区难免经验不足,请大家多多包涵,也欢迎大家前来多多交流。

爱吃烤鸡翅的酸菜鱼社区-CSDN社区云 https://bbs.csdn.net/forums/aaa1f71356f6475db42ea9ea09a392bc?spm=1001.2014.3001.6685

 

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

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

相关文章

解决Docker Compose报错

解决Docker Compose报错&#xff1a;exec ./entrypoint.sh: no such file or directory在使用Docker Compose部署应用时&#xff0c;你是否遇到过exec ./entrypoint.sh: no such file or directory这个令人头疼的错误&#xff1f;本文将深入分析错误原因并提供多种解决方案&…

【element plus】el-select,allow-create不需要点回车键

<el-selectv-model"row.expertName"filterableremoteallow-createdefault-first-optionreserve-keywordplaceholder"请输入姓名":remote-method"remoteMethod":loading"loadingName"change"(val) > handleNameChange(row, …

RK3588 HDMI-RX 驱动、RGA 加速与 OpenCV GStreamer 支持完整指南

一、环境检测与前置依赖 确认内核与 HDMI-RX 节点&#xff1a; uname -a # 输出&#xff1a;6.1.0-1025-rockchip ...dmesg | grep -i hdmirx # 应能看到 hdmirx-controller 节点&#xff1a; # fdee0000.hdmirx-controller driver probe ok!如果仅出现&#xff1a; rockchi…

AS32A601芯片QSPI 调试技术解析与与实战经验分享

一、概述&#xff08;一&#xff09;QSPI 简介QSPI&#xff08;Quad Serial Peripheral Interface&#xff09;是一种高速串行通信接口&#xff0c;在标准 SPI&#xff08;Serial Peripheral Interface&#xff09;的基础上扩展至 4 条数据线&#xff08;Quad Mode&#xff09;…

TDengine 转化函数 TO_TIMESTAMP 用户手册

TDengine TO_TIMESTAMP 函数用户使用手册 函数概述 TO_TIMESTAMP 是 TDengine 中的标量函数&#xff0c;用于将字符串按照指定格式转换为时间戳。该函数在数据导入、时间格式转换、以及处理各种时间字符串格式时非常有用。 语法 TO_TIMESTAMP(ts_str_literal, format_str_liter…

关于我司即将对商业间谍行为进行法律诉讼的通知

最后警告我司所属社交媒体中所有友商间谍&#xff1a;请于2025年7月26日上午十点前&#xff0c;自行删除我方好友&#xff0c;并停止通过欺诈行为&#xff08;包括但不限于冒充客户等&#xff09;盗取我司商业秘密的行为。十点后&#xff0c;我司将开始进行逐一排查&#xff0c…

【打怪升级 - 03】YOLO11/YOLO12/YOLOv10/YOLOv8 完全指南:从理论到代码实战,新手入门必看教程

引言&#xff1a;为什么选择 YOLO&#xff1f; 在目标检测领域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列模型一直以其高效性和准确性备受关注。作为新版本&#xff0c;YOLO系列的新版本总能在前辈的基础上进行了多项改进&#xff0c;包括更高的检测精度…

JMeter每次压测前清除全部以确保异常率准确(以黑马点评为例、详细图解)

目录 一、前言 二、未清除全部会出现的情况(以乐观锁解决超卖问题为例) 三、清除全部就能得到准确的结果 一、前言 在学习黑马点评之前我并没有接触过JMeter这个压测软件&#xff0c;然后在黑马点评视频中老师也是直接拿起JMeter就开始使用&#xff0c;所以我一直在不断搜索…

关于新学C++编程Visual Studio 2022开始,使用Cmake工具构建Opencv和SDK在VS里编译项目开发简介笔记

1. C 项目build文件夹 2. VS解决方案管理器Solution——.sln文件 3. CMake 自动化构建工具 4. SDK软件开发工具包作为初学者&#xff0c;从工程项目开始接触完整一套流程工具和编译&#xff0c;有助于快速上手。 一、C 项目build文件夹在 VS2022 中打开 C 项目后&#xff0c;在…

测试ppyoloe的小样本few-shot能力,10张图片精度达到69.8%

近期公司有个项目&#xff0c;需要解决长尾样本的问题&#xff0c;所以测试了一下paddlepaddle小样本的能力。 环境&#xff1a;&#xff1a;T4 、ubuntu 、cuda-11.6 、py3.9、 paddlepaddle-gpu2.6.0、pip install opencv-python4.5.5.64 -i https://pypi.tuna.tsinghua.…

结构化布线系统详解

1. 结构化布线系统概述 结构化布线系统(Structured Cabling System, SCS)是一种标准化、模块化的建筑物或建筑群内信息传输基础设施&#xff0c;它为语音、数据、图像等多媒体业务提供了统一的物理传输介质。与传统的点对点布线方式不同&#xff0c;结构化布线采用层次化、标准…

【Java学习】匿名内部类的向外访问机制

目录 一、方法局部变量的访问 1.生命周期 1.1方法生命周期 1.2匿名实例生命周期 1.3生命超时性 2.变量捕获 2.1按值捕获 2.1.1值捕获优势 2.1.1.1生命及时访问 2.1.1.2线程安全 2.1.2常量值捕获优势 2.2按引用捕获 引用捕获风险 (1)生命超时访问 (2)线程不安全 …

LinkedList的模拟实现+LinkedList和ArrayList的区别

目录 LinkedList的模拟实现 什么是双向链表 增加数据 头插法&#xff1a; 尾插法&#xff1a; 指定的下标插入&#xff1a; 删除数据 删除双向链表中出现的第一个key 置空所有数据 LinkedList和ArrayList的区别 顺序表对应的集合类是ArrayList&#xff1b;链表对应的集…

Vue + WebSocket 实时数据可视化实战:多源融合与模拟数据双模式设计

在现代交通大屏项目中&#xff0c;实时数据的采集和可视化尤为重要。本文结合 Vue3 和 ECharts&#xff0c;分享一个支持多 WebSocket 数据源实时合并、模拟数据调试、自动重连的完整设计方案&#xff0c;帮助你快速搭建健壮的数据可视化组件。一、项目背景与核心需求实时接收多…

C#索引器、接口、泛型

以下是对提供的 C# 代码中涉及的核心知识点的梳理和总结&#xff0c;涵盖索引器、接口、泛型三大核心内容&#xff0c;以及相关实践要点&#xff1a;一、索引器&#xff08;Indexer&#xff09;索引器是一种允许类或结构体像数组一样通过[]语法访问成员的特殊成员&#xff0c;本…

界面组件DevExpress WPF中文教程:Grid - 如何过滤节点?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Excel——INDEX和MATCH傻傻分不清?

核心逻辑​先用 MATCH 找到目标姓名在表格中的 ​行号&#xff0c;再用 INDEX 根据行号 ​提取对应信息。就像查字典&#xff1a;先用拼音找到字的页码&#xff08;MATCH 找行号&#xff09;再翻到该页看具体解释&#xff08;INDEX 取数据&#xff09;​分步拆解&#xff08;以…

制造业低代码平台实战评测:简道云、钉钉宜搭、华为云Astro、金蝶云·苍穹、斑斑低代码,谁更值得选?

上回聊了斑斑和简道云&#xff0c;不少同行私信问我其他几个低代码平台怎么样&#xff0c;今天就给大家来个"五大门派"终极对决&#xff01; 一、先说痛点 制造业搞数字化最怕三件事&#xff1a; 1.钱花了没效果&#xff08;大平台用不起&#xff0c;小工具不够用&…

Jenkins中HTML文件显示样式问题解决方案

Jenkins中HTML文件显示样式问题解决方案 问题描述 在Jenkins中归档的HTML文件显示格式失效&#xff0c;样式无法正常显示&#xff0c;但在本地浏览器中打开却能正常显示。 问题原因 Jenkins为了安全考虑&#xff0c;默认设置了严格的内容安全策略(Content Security Policy, CSP…

四、配置文件

文章目录1. 文件类型1.1 properties1.2 yaml1.2.1 简介1.2.2 基本语法1.2.3 数据类型1.2.4 示例2. 配置提示1. 文件类型 1.1 properties 同以前的properties的用法 1.2 yaml 1.2.1 简介 YAML 是 “YAML Ain’t Markup Language”&#xff08;YAML 不是一种标记语言&#x…