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

2.Spring MVC与WebFlux响应式编程

目录

一、Spring MVC核心机制与工作原理

请求处理流程:DispatcherServlet分发机制、HandlerMapping与HandlerAdapter • 核心组件:ViewResolver、ModelAndView、拦截器(Interceptor) • 注解驱动开发@Controller@RequestMapping@RequestBody/@ResponseBodyRESTful支持@RestController@PathVariable@RequestParam异常处理@ControllerAdvice@ExceptionHandler、全局异常响应


二、WebFlux响应式编程模型

响应式核心概念:Reactive Streams规范、背压(Backpressure)机制 • WebFlux vs MVC:非阻塞IO、事件驱动模型、适用场景对比 • 核心组件:RouterFunction、HandlerFunction、WebFilter • 响应式类型MonoFlux操作符(mapflatMapzip) • 响应式数据访问:R2DBC(关系型数据库)、Reactive MongoDB


三、同步与异步处理对比

阻塞式处理(MVC):Servlet线程模型、Tomcat线程池配置 • 非阻塞式处理(WebFlux):EventLoop线程模型、Netty性能优势 • 性能压测对比:1000并发下MVC(Tomcat) vs WebFlux(Netty)吞吐量 • 混合应用场景:MVC同步接口与WebFlux异步接口共存策略


四、实战:构建混合应用(MVC+WebFlux)

项目架构设计:Spring Boot多模块配置(MVC模块 + WebFlux模块) • 接口兼容性:统一返回格式(JSON)、全局跨域配置 • 异步接口开发:基于WebFlux的文件上传/下载、SSE(Server-Sent Events)实时推送 • 灰度发布策略:通过网关(Spring Cloud Gateway)动态路由流量


五、性能优化与生产调优

MVC优化:Tomcat线程池参数(maxThreadsacceptCount)、静态资源缓存 • WebFlux优化:Netty事件循环组配置、响应式超时控制 • 内存泄漏排查:堆内存分析(MAT工具)、阻塞操作检测(BlockHound) • 监控告警:Micrometer集成Prometheus、WebFlux链路追踪(Sleuth + Zipkin)


六、常见问题与面试题精选

高频面试题: • Spring MVC如何处理HTTP请求?DispatcherServlet的作用是什么? • WebFlux的背压机制如何解决数据消费速度不匹配问题? • 为什么WebFlux默认使用Netty而不是Tomcat? • 实战场景题: • 设计一个支持10万并发的实时股票报价接口(WebFlux + SSE)。 • 优化一个Spring MVC接口从200ms延迟降低到50ms以下。 • 陷阱题: • 在WebFlux中调用阻塞代码(如JDBC)会导致什么问题?如何解决? • 为什么WebFlux的Mono返回类型不能直接序列化为XML?



一、Spring MVC核心机制与工作原理

1. 请求处理全流程剖析

Spring MVC的请求处理流程围绕DispatcherServlet展开,其核心流程如下:

  1. HTTP请求接收DispatcherServlet作为前端控制器,接收所有HTTP请求。

  2. 处理器映射(HandlerMapping): • 根据请求URL匹配对应的控制器方法(如@RequestMapping定义的路径)。 • 支持多种匹配策略(路径通配符、正则表达式)。

    @GetMapping("/users/{id}")  
    public User getUser(@PathVariable Long id) { ... }  
  3. 处理器适配(HandlerAdapter): • 调用目标控制器方法,处理参数绑定(如@RequestBody解析JSON)。 • 支持多种参数类型(HttpServletRequestModel、自定义POJO)。

  4. 视图解析(ViewResolver): • 根据逻辑视图名(如return "userList";)解析为物理视图(如userList.jsp)。 • 支持模板引擎(Thymeleaf、FreeMarker)。


2. 核心组件详解

2.1 ViewResolver与模板渲染

视图解析流程

// 配置Thymeleaf视图解析器  
@Bean  
public ThymeleafViewResolver viewResolver() {  ThymeleafViewResolver resolver = new ThymeleafViewResolver();  resolver.setTemplateEngine(templateEngine());  return resolver;  
}  

动态数据传递:通过Model对象传递数据到视图。

@GetMapping("/profile")  
public String profile(Model model) {  model.addAttribute("user", userService.getCurrentUser());  return "profile";  
}  
2.2 拦截器(Interceptor)实战

自定义拦截器:实现HandlerInterceptor接口,完成日志、权限等操作。

public class AuthInterceptor implements HandlerInterceptor {  @Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {  if (!checkToken(request.getHeader("token"))) {  response.sendError(401, "Unauthorized");  return false;  }  return true;  }  
}  

配置拦截路径

@Configuration  
public class WebConfig implements WebMvcConfigurer {  @Override  public void addInterceptors(InterceptorRegistry registry) {  registry.addInterceptor(new AuthInterceptor())  .addPathPatterns("/api/**");  }  
}  

3. 注解驱动开发

3.1 控制器层注解

@Controller vs @RestController: • @Controller:用于传统MVC模式,配合视图解析器返回HTML页面。 • @RestController:用于RESTful API,所有方法默认添加@ResponseBody,返回JSON/XML数据。

3.2 请求映射注解

多条件匹配

@RequestMapping(  value = "/search",  method = RequestMethod.GET,  params = "keyword",  headers = "Content-Type=application/json"  
)  
public List<Product> searchProducts() { ... }  
3.3 参数绑定注解

@RequestBodyHttpMessageConverter: • JSON反序列化流程: 1. 请求头Content-Type: application/json触发MappingJackson2HttpMessageConverter。 2. 将请求体JSON转换为Java对象。

@PostMapping("/users")  
public ResponseEntity<User> createUser(@RequestBody User user) {  User savedUser = userService.save(user);  return ResponseEntity.created(URI.create("/users/" + savedUser.getId())).body(savedUser);  
}  

4. RESTful接口设计规范

4.1 资源操作语义化

HTTP方法对应CRUD

HTTP方法操作示例
GET查询资源GET /users/123
POST创建资源POST /users
PUT全量更新PUT /users/123
PATCH部分更新PATCH /users/123
DELETE删除资源DELETE /users/123
4.2 HATEOAS实现

Spring HATEOAS集成

@GetMapping("/users/{id}")  
public EntityModel<User> getUser(@PathVariable Long id) {  User user = userService.findById(id);  return EntityModel.of(user,  linkTo(methodOn(UserController.class).getUser(id)).withSelfRel(),  linkTo(methodOn(UserController.class).getUserOrders(id)).withRel("orders")  );  
}  

响应示例

{  "id": 123,  "name": "John",  "_links": {  "self": { "href": "http://localhost:8080/users/123" },  "orders": { "href": "http://localhost:8080/users/123/orders" }  }  
}  

5. 全局异常处理

5.1 统一异常响应

自定义异常类

public class ResourceNotFoundException extends RuntimeException {  public ResourceNotFoundException(String message) {  super(message);  }  
}  

全局异常处理器

@ControllerAdvice  
public class GlobalExceptionHandler {  @ExceptionHandler(ResourceNotFoundException.class)  public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {  ErrorResponse error = new ErrorResponse(404, ex.getMessage());  return ResponseEntity.status(404).body(error);  }  
}  

错误响应体

{  "code": 404,  "message": "User not found with id 123"  
}  

总结 本章深入解析了Spring MVC的核心机制,从请求处理流程到RESTful接口设计,覆盖了控制器开发、参数绑定、异常处理等关键内容。后续章节将对比WebFlux响应式编程模型,帮助开发者根据业务场景选择最佳技术方案。


二、WebFlux响应式编程模型

1. 响应式核心概念

1.1 Reactive Streams规范

Reactive Streams是响应式编程的标准化规范,定义了以下核心接口: • Publisher<T>:数据生产者,发布数据流。 • Subscriber<T>:数据消费者,订阅并处理数据。 • Subscription:订阅关系,控制数据请求(如request(n))。 • Processor<T, R>:同时充当生产者和消费者的中间处理节点。

代码示例(简单Publisher)

Flux<Integer> flux = Flux.range(1, 10)  .delayElements(Duration.ofMillis(100));  
flux.subscribe(  value -> System.out.println("Received: " + value),  error -> System.err.println("Error: " + error),  () -> System.out.println("Completed")  
);  
1.2 背压(Backpressure)机制

问题场景:生产者速度 > 消费者速度,导致内存溢出。 • 解决方案:通过Subscription动态控制数据流速。

Flux.range(1, 1000)  .onBackpressureBuffer(10)  // 缓冲区大小为10,超出后丢弃旧数据  .subscribe(new BaseSubscriber<Integer>() {  @Override  protected void hookOnSubscribe(Subscription subscription) {  request(5);  // 初始请求5个元素  }  @Override  protected void hookOnNext(Integer value) {  process(value);  request(1);  // 每处理完1个元素,再请求1个  }  });  

2. WebFlux vs MVC:模型对比与适用场景

2.1 非阻塞IO与事件驱动

MVC(阻塞式): • 每个请求占用一个线程(Tomcat线程池默认200线程)。 • 高并发时线程资源耗尽,导致性能瓶颈。 • WebFlux(非阻塞): • 基于事件循环(EventLoop),单线程处理数千连接。 • 适用I/O密集型场景(如微服务网关、实时推送)。

2.2 性能对比
指标Spring MVC(Tomcat)WebFlux(Netty)
吞吐量(req/s)5k15k
内存占用高(每个线程1MB)低(共享线程池)
适用场景CRUD、同步逻辑高并发、实时流
2.3 混合应用场景

用例:电商系统同时提供管理后台(MVC)和实时订单推送(WebFlux)。 • 配置示例

# application.yml  
server:  port: 8080  servlet:  context-path: /mvc  
spring:  webflux:  base-path: /reactive  

3. 核心组件详解

3.1 函数式端点(RouterFunction & HandlerFunction)

路由定义:使用RouterFunctions.route()组合请求谓词和处理器。

@Bean  
public RouterFunction<ServerResponse> userRoutes() {  return route()  .GET("/users/{id}", this::getUser)  .POST("/users", this::createUser)  .build();  
}  
private Mono<ServerResponse> getUser(ServerRequest request) {  Long id = Long.parseLong(request.pathVariable("id"));  return ServerResponse.ok().body(userService.findById(id), User.class);  
}  
3.2 响应式过滤器(WebFilter)

日志记录示例

@Component  
public class LoggingWebFilter implements WebFilter {  @Override  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {  long startTime = System.currentTimeMillis();  return chain.filter(exchange)  .doOnTerminate(() -> {  long duration = System.currentTimeMillis() - startTime;  System.out.println(  exchange.getRequest().getURI() + " - " + duration + "ms"  );  });  }  
}  

4. 响应式类型与操作符

4.1 Mono与Flux核心操作
操作符用途示例
map同步转换元素Flux.just(1,2).map(i -> i*2)
flatMap异步转换(返回Publisher)Flux.just(1,2).flatMap(i -> Mono.just(i*2))
zip合并多个流(按元素顺序配对)Mono.zip(monoA, monoB, (a,b) -> a + b)
merge合并多个流(按元素到达顺序)Flux.merge(fluxA, fluxB)

代码示例(实时数据流处理)

Flux<StockPrice> prices = WebClient.create()  .get()  .uri("http://stock-service/prices")  .retrieve()  .bodyToFlux(StockPrice.class)  .filter(price -> price.getValue() > 100)  .bufferTimeout(10, Duration.ofSeconds(1))  .flatMap(batch -> saveBatchToDB(batch));  

5. 响应式数据访问

5.1 R2DBC(关系型数据库)

核心依赖

<dependency>  <groupId>io.r2dbc</groupId>  <artifactId>r2dbc-postgresql</artifactId>  
</dependency>  

CRUD示例

public Flux<User> findAll() {  return databaseClient.sql("SELECT * FROM users")  .map(row -> new User(row.get("id", Long.class), row.get("name", String.class)))  .all();  
}  
5.2 Reactive MongoDB

查询与订阅

public Flux<User> streamUsers() {  return mongoTemplate.changeStream(User.class)  .watchCollection("users")  .listen()  .map(ChangeStreamEvent::getBody);  
}  

总结 WebFlux通过非阻塞IO和响应式编程模型,为高并发场景提供了高效的解决方案。结合R2DBC和Reactive MongoDB,开发者可以构建端到端的响应式应用。下一章将深入探讨同步与异步处理的性能差异及混合应用架构设计。


三、同步与异步处理对比


1. 阻塞式处理(Spring MVC)

1.1 Servlet线程模型与Tomcat配置

线程模型: • 每个HTTP请求占用一个独立线程(Tomcat默认线程池大小为200)。 • 线程从接收请求到返回响应的全流程中,若遇到阻塞操作(如数据库查询、远程调用),线程会被挂起,直到操作完成。 • 配置优化

# application.yml  
server:  tomcat:  max-threads: 200      # 最大工作线程数  accept-count: 100     # 等待队列容量  min-spare-threads: 10 # 最小空闲线程数  

性能瓶颈: • 当并发请求超过max-threads + accept-count时(如300并发),Tomcat直接拒绝请求(返回503)。 • 长耗时操作(如文件导出)可能导致线程池耗尽,影响其他请求。

1.2 典型同步接口示例
@RestController  
public class BlockingController {  @GetMapping("/blocking/users/{id}")  public User getUser(@PathVariable Long id) {  // 模拟耗时1秒的数据库查询(阻塞线程)  try { Thread.sleep(1000); } catch (InterruptedException e) {}  return new User(id, "User" + id);  }  
}  

2. 非阻塞式处理(WebFlux)

2.1 EventLoop线程模型与Netty优势

EventLoop机制: • 单线程(EventLoop)通过事件驱动处理多个连接(如1000并发)。 • 所有I/O操作(如网络请求、数据库调用)均为非阻塞,通过回调通知结果。 • Netty核心参数

# application.yml  
spring:  webflux:  server:  max-in-memory-size: 10MB    # 请求体内存缓冲大小  thread-pool:  max-threads: 4            # 事件循环线程数(通常设为CPU核数)  

性能优势: • 高并发下内存占用稳定(无线程上下文切换开销)。 • 适用于实时流处理(如股票行情推送、物联网设备数据采集)。

2.2 典型异步接口示例
@RestController  
public class ReactiveController {  @GetMapping("/reactive/users/{id}")  public Mono<User> getUser(@PathVariable Long id) {  // 模拟异步数据库查询(不阻塞线程)  return Mono.delay(Duration.ofSeconds(1))  .map(delay -> new User(id, "User" + id));  }  
}  

3. 性能压测对比(MVC vs WebFlux)

3.1 压测环境与参数

工具:Apache JMeter(1000并发,持续10秒)。 • 接口逻辑:模拟1秒延迟的查询操作。 • 服务器配置:4核CPU,8GB内存,Spring Boot 3.0。

3.2 压测结果
指标Spring MVC(Tomcat)WebFlux(Netty)
吞吐量(req/s)200950
平均响应时间1000ms1050ms
最大内存占用1.2GB300MB
线程占用数2004

结论: • WebFlux在高并发场景下吞吐量提升近5倍,内存占用降低75%。 • MVC的响应时间更稳定,但受限于线程池容量。


4. 混合应用场景与共存策略

4.1 技术选型原则

使用MVC的场景: • 依赖阻塞式组件(如JDBC、JPA)。 • 简单CRUD接口,无需高并发(如管理后台)。 • 使用WebFlux的场景: • 高并发、低延迟需求(如API网关、实时推送)。 • 依赖非阻塞数据源(如R2DBC、Reactive MongoDB)。

4.2 混合架构实现

项目配置

// build.gradle  
dependencies {  implementation 'org.springframework.boot:spring-boot-starter-web'      // MVC  implementation 'org.springframework.boot:spring-boot-starter-webflux'  // WebFlux  
}  

路由策略:通过@Order控制处理器优先级。

@Configuration  
public class WebConfig implements WebFluxConfigurer {  @Bean  @Order(-1)  // WebFlux优先处理  public RouterFunction<ServerResponse> reactiveRoutes() {  return route()  .GET("/reactive/**", request -> ServerResponse.ok().build())  .build();  }  
}  
4.3 线程池隔离

MVC线程池:Tomcat默认线程池处理同步请求。 • WebFlux线程池:Netty EventLoop处理异步请求。 • 关键配置

spring:  task:  execution:  pool:  core-size: 10  # 异步任务线程池(避免阻塞EventLoop)  

总结

同步模型(MVC):适合简单业务、阻塞式数据源,开发门槛低。 • 异步模型(WebFlux):适合高并发、实时流,但需重构为全响应式链路。 • 混合架构:通过路由和线程池隔离,平衡开发效率与性能需求。

生产建议: • 核心服务(如支付回调)使用WebFlux保证高可用。 • 复杂事务操作(如库存扣减)优先选择MVC+JDBC。 • 使用BlockHound检测阻塞调用,确保响应式代码纯净性。

// BlockHound配置(检测阻塞操作)  
public class BlockHoundConfig {  @PostConstruct  public void init() {  BlockHound.builder()  .allowBlockingCallsInside("com.example.MyService", "safeBlockingMethod")  .install();  }  
}  

四、实战:构建混合应用(MVC+WebFlux)


1. 项目架构设计

1.1 多模块工程配置

模块划分: • mvc-module:处理同步请求(依赖spring-boot-starter-web)。 • webflux-module:处理异步请求(依赖spring-boot-starter-webflux)。 • common-module:共享DTO、工具类、异常处理。

Maven/Gradle配置

// build.gradle(根项目)  
subprojects {  apply plugin: 'org.springframework.boot'  dependencies {  implementation project(':common-module')  }  
}  
// mvc-module/build.gradle  
dependencies {  implementation 'org.springframework.boot:spring-boot-starter-web'  
}  
// webflux-module/build.gradle  
dependencies {  implementation 'org.springframework.boot:spring-boot-starter-webflux'  
}  

启动类隔离

// MVC模块启动类  
@SpringBootApplication  
@EnableAutoConfiguration(exclude = {ReactiveWebServerFactoryAutoConfiguration.class})  
public class MvcApplication { ... }  // WebFlux模块启动类  
@SpringBootApplication  
@EnableAutoConfiguration(exclude = {ServletWebServerFactoryAutoConfiguration.class})  
public class WebfluxApplication { ... }  

2. 接口兼容性与统一规范

2.1 统一JSON响应格式

全局响应封装common-module中定义):

public class ApiResponse<T> {  private int code;  private String message;  private T data;  // Getter/Setter  
}  

MVC统一返回@ControllerAdvice):

@ControllerAdvice  
public class MvcResponseWrapper implements ResponseBodyAdvice<Object> {  @Override  public boolean supports(MethodParameter returnType, Class converterType) {  return !returnType.getGenericParameterType().equals(ApiResponse.class);  }  @Override  public Object beforeBodyWrite(Object body, MethodParameter returnType,  MediaType selectedContentType, Class selectedConverterType,  ServerHttpRequest request, ServerHttpResponse response) {  return new ApiResponse<>(200, "Success", body);  }  
}  

WebFlux统一返回(全局过滤器):

@Component  
public class WebfluxResponseFilter implements WebFilter {  @Override  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {  return chain.filter(exchange)  .then(Mono.defer(() -> {  ServerHttpResponse response = exchange.getResponse();  if (response.getStatusCode() == HttpStatus.OK) {  Object body = response.getBody();  return response.writeWith(Mono.just(  response.bufferFactory().wrap(  new ApiResponse<>(200, "Success", body).toString().getBytes()  )  ));  }  return Mono.empty();  }));  }  
}  
2.2 全局跨域配置

MVC跨域配置

@Configuration  
public class MvcCorsConfig implements WebMvcConfigurer {  @Override  public void addCorsMappings(CorsRegistry registry) {  registry.addMapping("/**")  .allowedOrigins("*")  .allowedMethods("GET", "POST");  }  
}  

WebFlux跨域配置

@Configuration  
public class WebfluxCorsConfig {  @Bean  public CorsWebFilter corsFilter() {  CorsConfiguration config = new CorsConfiguration();  config.addAllowedOrigin("*");  config.addAllowedMethod("*");  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  source.registerCorsConfiguration("/**", config);  return new CorsWebFilter(source);  }  
}  

3. 异步接口开发实战

3.1 文件上传与下载

WebFlux文件上传

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)  
public Mono<String> uploadFile(@RequestPart("file") FilePart filePart) {  Path path = Paths.get("/tmp/" + filePart.filename());  return filePart.transferTo(path).thenReturn("Upload success");  
}  

WebFlux文件下载

@GetMapping("/download/{filename}")  
public Mono<Resource> downloadFile(@PathVariable String filename) {  return Mono.fromSupplier(() -> new FileSystemResource("/tmp/" + filename));  
}  
3.2 SSE实时推送

服务端实现

@GetMapping(value = "/stream/prices", produces = MediaType.TEXT_EVENT_STREAM_VALUE)  
public Flux<StockPrice> streamPrices() {  return Flux.interval(Duration.ofSeconds(1))  .map(sequence -> new StockPrice("AAPL", 150 + sequence * 0.5));  
}  

客户端订阅

const eventSource = new EventSource('/stream/prices');  
eventSource.onmessage = (e) => console.log(JSON.parse(e.data));  

4. 灰度发布与动态路由

4.1 Spring Cloud Gateway配置

路由规则(按Header分流):

spring:  cloud:  gateway:  routes:  - id: mvc-route  uri: http://localhost:8081  predicates:  - Header=X-Gray, v1  - id: webflux-route  uri: http://localhost:8082  predicates:  - Header=X-Gray, v2  
4.2 金丝雀发布策略

按权重分流

spring:  cloud:  gateway:  routes:  - id: canary-route  uri: lb://my-service  predicates:  - Path=/api/**  filters:  - name: Weight  args:  group: canary  weight: v1, 90  weight: v2, 10  

5. 混合应用监控与调优

线程池隔离配置

# WebFlux线程池(避免阻塞EventLoop)  
spring:  task:  execution:  pool:  core-size: 10  max-size: 20  

监控集成

management:  endpoints:  web:  exposure:  include: health,metrics,threaddump  metrics:  tags:  application: ${spring.application.name}  

总结

通过混合架构设计,开发者既能保留MVC的简单易用性,又能利用WebFlux处理高并发场景。关键点包括:

  1. 模块隔离:通过多模块工程避免依赖冲突。

  2. 统一规范:全局处理响应格式与跨域配置。

  3. 动态路由:结合Spring Cloud Gateway实现灰度发布。

  4. 监控保障:线程池隔离与全链路监控确保稳定性。

适用场景: • 核心交易系统(MVC保证事务一致性)。 • 实时通知服务(WebFlux支持高并发推送)。 • 逐步迁移旧系统(通过灰度策略平滑过渡)。


五、性能优化与生产调优


1. Spring MVC性能优化

1.1 Tomcat线程池参数调优

核心参数

server:  tomcat:  max-threads: 200       # 最大工作线程数(建议值:CPU核数 * 200)  accept-count: 100      # 等待队列容量(超出后拒绝请求)  min-spare-threads: 20  # 最小空闲线程数(快速响应突发流量)  

调优原则: • CPU密集型场景max-threads设为CPU核数 * 1.5。 • I/O密集型场景max-threads可适当增大(如200~400)。

1.2 静态资源缓存

HTTP缓存头配置

@Configuration  
public class MvcCacheConfig implements WebMvcConfigurer {  @Override  public void addResourceHandlers(ResourceHandlerRegistry registry) {  registry.addResourceHandler("/static/**")  .addResourceLocations("classpath:/static/")  .setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS));  }  
}  

Nginx缓存加速

location /static/ {  expires 30d;  add_header Cache-Control "public";  
}  

2. WebFlux性能优化

2.1 Netty事件循环组配置

线程模型优化

# application.yml  
spring:  webflux:  server:  # EventLoop线程数(默认:CPU核数 * 2)  thread-pool:  max-threads: 8  

参数调优: • Linux系统:启用Epoll传输(减少线程切换开销)。 java @Bean public NettyReactiveWebServerFactory nettyFactory() { return new NettyReactiveWebServerFactory( builder -> builder.option(ChannelOption.SO_BACKLOG, 1024) .childOption(ChannelOption.TCP_NODELAY, true) ); }

2.2 响应式超时控制

全局超时配置

@Bean  
public WebClient webClient() {  return WebClient.builder()  .clientConnector(new ReactorClientHttpConnector(  HttpClient.create()  .responseTimeout(Duration.ofSeconds(5))  ))  .build();  
}  

接口级超时

@GetMapping("/reactive/data")  
public Mono<Data> getData() {  return externalService.fetchData()  .timeout(Duration.ofSeconds(3))  .onErrorResume(e -> Mono.just(new Data("fallback")));  
}  

3. 内存泄漏排查与阻塞检测

3.1 堆内存分析(MAT工具)

生成堆转储文件

# 通过jmap生成  
jmap -dump:format=b,file=heapdump.hprof <pid>  # 或JVM参数触发OOM时自动生成  
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof  

MAT分析步骤

  1. 打开heapdump.hprof,查看“Dominator Tree”找到占用内存最大的对象。

  2. 检查可疑对象的GC Root路径(如未关闭的数据库连接、静态集合缓存)。

3.2 阻塞操作检测(BlockHound)

集成BlockHound

public class BlockHoundConfig {  @PostConstruct  public void init() {  BlockHound.builder()  .allowBlockingCallsInside("com.example.Class", "methodName")  .install();  }  
}  

检测结果示例

Blocking call! java.lang.Thread.sleep  
at com.example.Service.blockingMethod(Service.java:20)  

4. 监控告警与链路追踪

4.1 Micrometer集成Prometheus

配置依赖

<dependency>  <groupId>io.micrometer</groupId>  <artifactId>micrometer-registry-prometheus</artifactId>  
</dependency>  

暴露指标端点

management:  endpoints:  web:  exposure:  include: health, prometheus  metrics:  tags:  application: ${spring.application.name}  

自定义指标

@Bean  
public MeterRegistryCustomizer<PrometheusMeterRegistry> metrics() {  return registry -> registry.config().commonTags("region", "us-east");  
}  
4.2 WebFlux链路追踪(Sleuth + Zipkin)

配置依赖

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-sleuth</artifactId>  
</dependency>  
<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-sleuth-zipkin</artifactId>  
</dependency>  

Zipkin服务端配置

spring:  zipkin:  base-url: http://zipkin-server:9411  sleuth:  sampler:  probability: 1.0  # 采样率(生产环境设为0.1)  

追踪效果

{  "traceId": "3e6f3b7e6d6d6d6d",  "spanId": "6d6d6d6d6d6d6d6d",  "parentSpanId": null,  "name": "GET /reactive/data",  "tags": {  "http.method": "GET",  "http.status_code": "200"  }  
}  

总结

MVC调优重点:线程池容量、静态资源缓存、避免内存泄漏。 • WebFlux调优重点:非阻塞线程模型、响应式超时、全链路监控。 • 生产保障:通过BlockHound确保响应式代码纯净性,结合Prometheus+Zipkin实现可观测性。

推荐工具链: • 监控:Prometheus(指标) + Grafana(看板) + ELK(日志)。 • 压测:JMeter(全链路压测) + Gatling(高并发模拟)。 • 调优:Arthas(动态诊断) + VisualVM(JVM分析)。

# Arthas快速诊断命令示例  
$ ./arthas-boot.jar  
arthas> dashboard  # 实时监控线程/内存  
arthas> thread -n 5  # 查看最忙线程  

六、常见问题与面试题精选


高频面试题

1. Spring MVC如何处理HTTP请求?DispatcherServlet的作用是什么?

答案

  1. 请求处理流程: • DispatcherServlet作为前端控制器,接收所有HTTP请求。 • 通过HandlerMapping解析请求URL,找到对应的控制器方法(如@GetMapping)。 • HandlerAdapter调用控制器方法,处理参数绑定(如@RequestBody)。 • 结果通过ViewResolver解析视图(如返回JSON或HTML页面)。

  2. DispatcherServlet的核心作用: • 统一入口:集中管理请求分发,解耦请求处理与业务逻辑。 • 组件协调:集成HandlerMappingViewResolver等组件,实现松耦合架构。 • 扩展支持:支持拦截器(Interceptor)、异常处理(@ControllerAdvice)。

代码示例

@RestController  
public class UserController {  @GetMapping("/users/{id}")  public User getUser(@PathVariable Long id) {  return userService.findById(id);  }  
}  

2. WebFlux的背压机制如何解决数据消费速度不匹配问题?

答案

  1. 背压核心原理: • 消费者通过Subscription动态控制数据流速(如request(n)请求n个元素)。 • 生产者根据消费者的处理能力调整数据发送速率。

  2. WebFlux实现方式: • Flux缓冲策略:使用onBackpressureBuffer缓存溢出数据。 • 流量控制limitRate()限制生产者速率。

代码示例

Flux.range(1, 1000)  .onBackpressureBuffer(10)  // 缓冲区容量为10  .subscribe(  value -> process(value),  error -> log.error("Error", error),  () -> log.info("Completed"),  subscription -> subscription.request(5)  // 初始请求5个元素  );  

3. 为什么WebFlux默认使用Netty而不是Tomcat?

答案

  1. 架构差异: • Tomcat:基于Servlet API,每个请求占用一个线程(阻塞式)。 • Netty:基于事件循环(EventLoop),单线程处理多个连接(非阻塞)。

  2. 性能优势: • 高并发:Netty的EventLoop模型支持数万并发连接。 • 低延迟:非阻塞I/O减少线程切换开销。

适用场景: • Tomcat:传统同步逻辑(如JDBC事务)。 • Netty:实时推送、高并发接口(如API网关)。


实战场景题

1. 设计一个支持10万并发的实时股票报价接口(WebFlux + SSE)

实现方案

  1. 技术选型: • WebFlux:非阻塞处理高并发连接。 • SSE(Server-Sent Events):通过长连接推送实时数据。

  2. 核心代码

    @GetMapping(value = "/stocks", produces = MediaType.TEXT_EVENT_STREAM_VALUE)  
    public Flux<StockPrice> streamStockPrices() {  return Flux.interval(Duration.ofMillis(100))  .map(seq -> new StockPrice("AAPL", 150 + seq * 0.1));  
    }  
  3. 优化策略: • 背压控制onBackpressureDrop()丢弃无法处理的实时数据。 • 集群部署:通过Kafka分发数据到多个实例。


2. 优化一个Spring MVC接口从200ms延迟降低到50ms以下

优化步骤

  1. 性能分析: • 使用jstack或Arthas定位线程阻塞点(如慢SQL、外部API调用)。

  2. 优化手段: • 缓存:Redis缓存查询结果(减少数据库压力)。 • 异步化:将非关键逻辑(如日志记录)改为异步处理。

    @Async  
    public void logAccess(Long userId) {  // 异步记录访问日志  
    }  

    SQL优化:添加索引、避免全表扫描。

  3. 效果验证: • 通过JMeter压测确认延迟降低至50ms以下。


陷阱题

1. 在WebFlux中调用阻塞代码(如JDBC)会导致什么问题?如何解决?

答案: • 问题:阻塞操作(如JDBC)会占用EventLoop线程,导致整个应用吞吐量骤降。 • 解决方案

  1. 异步驱动:使用R2DBC(响应式关系数据库驱动)。

  2. 线程池隔离:将阻塞操作调度到独立线程池。

Mono.fromCallable(() -> blockingJdbcCall())  .subscribeOn(Schedulers.boundedElastic())  // 切换到弹性线程池  .subscribe(result -> ...);  

2. 为什么WebFlux的Mono返回类型不能直接序列化为XML?

答案: • 原因:默认的HttpMessageConverter可能未注册XML的响应式序列化器。 • 解决方案

  1. 添加Jackson XML依赖:

<dependency>  <groupId>com.fasterxml.jackson.dataformat</groupId>  <artifactId>jackson-dataformat-xml</artifactId>  
</dependency>  
  1. 配置内容协商:

spring:  mvc:  contentnegotiation:  media-types:  xml: application/xml  

总结

Spring MVC:适合传统同步场景,注重开发效率。 • WebFlux:适合高并发、实时流处理,需严格避免阻塞操作。 • 核心考点:背压机制、线程模型、性能优化、生产问题排查。

相关文章:

2.Spring MVC与WebFlux响应式编程

目录 一、Spring MVC核心机制与工作原理 • 请求处理流程&#xff1a;DispatcherServlet分发机制、HandlerMapping与HandlerAdapter • 核心组件&#xff1a;ViewResolver、ModelAndView、拦截器&#xff08;Interceptor&#xff09; • 注解驱动开发&#xff1a;Controller、…...

【重走C++学习之路】16、AVL树

目录 一、概念 二、AVL树的模拟实现 2.1 AVL树节点定义 2.2 AVL树的基本结构 2.3 AVL树的插入 1. 插入步骤 2. 调节平衡因子 3. 旋转处理 4. 开始插入 2.4 AVL树的查找 2.5 AVL树的删除 1. 删除步骤 2. 调节平衡因子 3. 旋转处理 4. 开始删除 结语 一、概念 …...

蓝桥杯 19.合根植物

合根植物 原题目链接 题目描述 W 星球的一个种植园被分成 m n 个小格子&#xff08;东西方向 m 行&#xff0c;南北方向 n 列&#xff09;。每个格子里种了一株合根植物。 这种植物有个特点&#xff0c;它的根可能会沿着南北或东西方向伸展&#xff0c;从而与另一个格子的…...

爆改 toxml 组件 支持数据双向绑定 解决数据刷新问题

GGGGGGGGGGGGGGGGGithub地址自行研究 sbfkcel/towxml: 微信小程序HTML、Markdown渲染库https://github.com/sbfkcel/towxml原组件是以导入数据渲染信息为目的、本文以AI数据返回小程序为模拟效果演示 默认情况只在ready 环节进行渲染静态资源 1、对传入数据容器的位置做处理 …...

6.分布式数据库与分库分表

目录 一、分库分表核心概念 • 核心目标&#xff1a;突破单库性能瓶颈&#xff0c;应对海量数据与高并发 • ​​垂直拆分​​&#xff1a;按业务模块拆分&#xff08;用户库、订单库、商品库&#xff09; • ​​水平拆分​​&#xff1a;单表数据分片&#xff08;用户ID取模…...

基于javaweb的SSM+Maven小区失物招领系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

Kubernetes finalize | namespace卡Terminatingfinalizers删除失败

目录 1、为什么会卡住&#xff1f;2、强制删除卡住的 Namespace&#xff1a;操作步骤1&#xff1a;导出当前 namespace 信息2&#xff1a;启动代理&#xff08;另一个终端&#xff09;以便使用 Kubernetes API Server3&#xff1a;使用 curl 强制删除 finalize 3、进阶排查&…...

Java数组

目录 一、定义 二、使用 2.1遍历数组 2.2获取数组长度 三、Arrays类 3.1数组填充 3.2数组排序 3.3数组转为字符串 3.4数组比较 3.5二分搜索 3.6数组复制 二维数组 一、定义 数组表示一个相同类型元素的集合 对于一个数组&#xff0c;可以有以下几种定义方法 int[…...

高级java每日一道面试题-2025年4月22日-基础篇[反射篇]-如何通过反射创建一个对象实例?

如果有遗漏,评论区告诉我进行补充 面试官: 如何通过反射创建一个对象实例&#xff1f; 我回答: 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的工具&#xff0c;允许程序在运行时检查和操作类、接口、字段和方法。反射不仅用于检查类的结构&#…...

Spring开发系列教程(26)——异步处理

在Servlet模型中&#xff0c;每个请求都是由某个线程处理&#xff0c;然后&#xff0c;将响应写入IO流&#xff0c;发送给客户端。从开始处理请求&#xff0c;到写入响应完成&#xff0c;都是在同一个线程中处理的。 实现Servlet容器的时候&#xff0c;只要每处理一个请求&…...

【2025最新Java面试八股】如何理解MySQL的MVCC机制?

面试回答要点 当面试官问及MySQL的MVCC机制时&#xff0c;可以这样组织回答&#xff1a; "MVCC(Multi-Version Concurrency Control&#xff0c;多版本并发控制)是MySQL实现高并发事务的一种重要机制&#xff0c;它通过保存数据在某个时间点的快照来实现非阻塞读操作。I…...

使用FreeRTOS解决单片机串口异步打印

单片机串口异步打印 文章目录 单片机串口异步打印前言设计思路准备队列创建完整代码 总结 前言 &#x1f30a;在单片机开发中串口的异步打印异步打印允许单片机在执行其他任务的同时进行打印操作&#xff0c;无需等待打印完成后再继续执行后续代码&#xff0c;避免了在多处调用…...

飞算 JavaAI 与 Spring Boot:如何实现微服务开发效率翻倍?

微服务架构凭借其高内聚、低耦合的特性&#xff0c;成为企业构建复杂应用系统的首选方案。然而&#xff0c;传统微服务开发流程中&#xff0c;从服务拆分、接口设计到代码编写、调试部署&#xff0c;往往需要耗费大量时间与人力成本。Spring Boot 作为 Java 领域最受欢迎的微服…...

Python 列表与元组深度解析:从基础概念到函数实现全攻略

在 Python 编程的广袤天地中&#xff0c;列表&#xff08;List&#xff09;和元组&#xff08;Tuple&#xff09;是两种不可或缺的数据结构。它们如同程序员手中的瑞士军刀&#xff0c;能高效地处理各类数据。从简单的数值存储到复杂的数据组织&#xff0c;列表和元组都发挥着关…...

vue 修改路由动态选择路由 改文件位置

vue 修改路由动态选择路由 改文件位置 main.jspermission.js...

Nginx openresty web服务 与 Go 原生web服务性能对比

1 概述 Nginx采用的是IO复用模型&#xff0c;能处理超高并发。 Go语言采用协程&#xff0c;能轻量级的处理超高并发。 那么在不考虑业务逻辑复杂的前提下&#xff0c;即假如将Nginx和Go都提供一个/test接口&#xff0c;并在接口逻辑中都只是让其做20毫秒的耗时操作&#xff0c…...

【音视频】FFmpeg解封装

解封装 复用器&#xff0c;比如MP4/FLV 解复用器&#xff0c;MP4/FLV 封装格式相关函数 avformat_alloc_context(); 负责申请一个AVFormatContext结构的内存,并进行简单初始化avformat_free_context(); 释放该结构里的所有东西以及该结构本身avformat_close_input();关闭解复…...

autohue.js - 基于 JavaScript 开发的图片背景色提取开源库,能让图片和背景融为一体

图片提取主题色的工具库&#xff0c;可以实现一些酷炫的界面效果。 本文不是 AI 生成&#xff0c;大部分文字都是我自己敲键盘&#xff0c;部分文字摘自 autohue.js 作者主页&#xff0c;请各位放心舒适阅读。 autohue.js 是一个图片背景色提取库&#xff0c;基于提出来的颜色…...

bgp实验.包括联盟,隧道相关,以及一个低级错误

实验拓扑 低级错误 在配置隧道时,目标的单词是destination,我自动补全为description了,这个问题花了我40分钟 划分ip AS2内骨干网,一个网段需要两个地址,主机位2位,掩码30 需要6个 172.16.0.000000 00 172.16.0.0/30 172.16.0.000001 00 172.16.0.4/30 172.16.0.000010 00 1…...

科普动画短视频制作:角色塑造的魅力法则

宝子们&#xff0c;在科普动画短视频的世界里&#xff0c;角色塑造可是让作品出彩的关键&#xff01;今天就来和大家唠唠那些超实用的角色塑造法则&#xff0c;还会给大家推荐一款超好用的工具哦~ 一、独特外形&#xff0c;吸睛第一步 在科普动画短视频制作中&#xff0c;角色…...

【飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南】

飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南 前言 本教程详细记录了飞渡科技的数字孪生平台CloudMaster的配置过程&#xff0c;以及如何将三维数字孪生场景集成到前端项目中。数字孪生技术能够在虚拟环境中精确复现物理实体的数据、特性和行为&#xff0c…...

MongoDB 集合名称映射问题

项目场景 在使用 Spring Data MongoDB 进行开发时&#xff0c;定义了一个名为 CompetitionSignUpLog 的实体类&#xff0c;并创建了对应的 Repository 接口。需要明确该实体类在 MongoDB 中实际对应的集合名称是 CompetitionSignUpLog 还是 competitionSignUpLog。 问题描述 …...

禁止ubuntu自动更新

由于ubuntu server和desktop版本都默认 启动了&#xff0c;自动更新内核的操作。这对于生 产环境来说是不友好的。容易导致亿赛通 无法启动 默认开启了内核自动更新所以我们关闭自 动内核更新。 1.禁止更新执行 sudo apt-mark hold linux-image-generic linux-headers-generic…...

【C++】——入门基础(一)

前言 这是我C的第一篇文章&#xff0c;如果你想从事入门C行业&#xff0c;可以看看这幅漫画 当然&#xff0c;这只是一个玩笑&#xff0c;但如过你真的想学习C&#xff0c;和我一起学习吧 本人其他博客;恋风诗 本文出现的代码见gitte:mozhengy 这里写目录标题 前言1. C发展历史…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]:在Mac App Store外创建、部署与公证

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

美乐迪电玩客户端打包与资源替换实战教程

本篇为《美乐迪电玩全套系统搭建》系列的第二篇&#xff0c;聚焦客户端层的实战操作&#xff0c;主要面向前端开发者、美术资源替换人员及整体项目的打包部署人员。教程将涵盖安卓客户端的构建、资源目录说明、动画素材替换方式及常见适配问题处理等。 一、客户端项目结构说明&…...

多态以及多态底层的实现原理

本章目标 1.多态的概念 2.多态的定义实现 3.虚函数 4.多态的原理 1.多态的概念 多态作为面对三大特性之一,它所指代的和它的名字一样,多种形态.但是这个多种形态更多的指代是函数的多种形态. 多态分为静态多态和动态多态. 静态多态在前面已经学习过了,就是函数重载以及模板,…...

描述城市出行需求模式的复杂网络视角:大规模起点-目的地需求网络的图论分析

描述城市出行需求模式的复杂网络视角&#xff1a;大规模起点-目的地需求网络的图论分析 原文&#xff1a; A complex network perspective for characterizing urban travel demand patterns: graph theoretical analysis of large-scale origin–destination demand networks…...

文件操作函数

本文是小编巩固自身而作&#xff0c;如有错误&#xff0c;欢迎指出&#xff01; 1.使用文件的原因 我们编写的程序都是有生命周期的&#xff0c;储存在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就会丢失&#xff0c;等程序再次运行&#xf…...

Java高频面试之并发编程-05

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;线程有哪些调度方法&#xff1f; 在Java中&#xff0c;线程的调用方法主要包括以下几种方式&#xff0c;每种方式适用于…...

LeetCode 1292 元素和小于等于阈值的正方形的最大边长

最大正方形边长问题详解 一、问题描述 给定一个大小为 mn 的矩阵 mat 和一个整数阈值 threshold&#xff0c;要求返回元素总和小于或等于阈值的正方形区域的最大边长&#xff1b;如果没有这样的正方形区域&#xff0c;则返回 0。 二、解题思路 前缀和矩阵的概念与构建 前缀…...

测试开发 - Java 自动化测试核心函数详解

目录 1. 元素定位 1.1 By.xpath 1.1.1 //* 1.1.2 //[指定节点] 1.1.3 / 1.1.4 /.. 1.1.5 [...] 1.1.6 指定索引获取对应元素 1.2 By.cssSelector 1.2.1 # 1.2.2 . 1.2.3 > 1.2.4 标签名:nth-child(n) 2. 获取元素 2.1 findElement 2.2 findElements 3. 操…...

【HarmonyOS】ArKUI框架

目录 概述 声明式开发范式 基于ArKUI的项目 • 1&#xff0e;创建资源文件 • 2&#xff0e;引用资源 • 3&#xff0e;引用系统资源&#xff1a; • 系统资源有哪些 • 4. 在配置和资源中引用资源 声明式语法 UI描述规范 UI组件概述 组件化 组件渲染控制语法 修改…...

【MQ篇】RabbitMQ之简单模式!

目录 引言一、 初识 RabbitMQ 与工作模式二、 简单模式 (Simple Queue) 详解&#xff1a;最直接的“点对点快递” &#x1f4ee;三、 Java (Spring Boot) 代码实战&#xff1a;让小兔子跑起来&#xff01; &#x1f430;&#x1f3c3;‍♂️四、 深入理解&#xff1a;简单模式的…...

K8S节点出现Evicted状态“被驱逐”

在Kubernetes集群中&#xff0c;Pod状态为“被驱逐&#xff08;evicted&#xff09;”表示Pod无法在当前节点上继续运行&#xff0c;已被集群从节点上移除。 问题分析&#xff1a; 节点磁盘空间不足 &#xff0c;使用df -h查看磁盘使用情况 可以看到根目录 / 已100%满&#x…...

NumPyro:概率编程的现代Python框架深度解析

引言 概率编程作为统计学与机器学习的交叉领域&#xff0c;正在重塑我们构建不确定性模型的方式。在众多概率编程语言&#xff08;PPL&#xff09;中&#xff0c;NumPyro凭借其简洁的语法、强大的性能和与PyTorch生态系统的无缝集成&#xff0c;已经成为研究者和数据科学家的首…...

java进阶之git

git git介绍git常用命令代码回滚操作 git 介绍 工作区 改动&#xff08;增删文件和内容&#xff09;暂存区 输入命令&#xff1a;git add改动的文件名&#xff0c;此次改动就放到了"暂存区“本地仓库 输入命令&#xff1a;git commit 此次修改的描述&#xff0c;此次改动…...

负载阻尼效应及其作用解析

负载阻尼效应是指负载&#xff08;如电路、机械系统或控制系统中连接的设备&#xff09;对系统动态变化&#xff08;如电压波动、机械振动等&#xff09;产生的抑制或衰减作用。 其核心是通过消耗或吸收能量&#xff0c;减少系统中的振荡、波动或瞬态响应&#xff0c;从而提高…...

面向组织的网络安全措施

一、安全措施概述 在一个组织中&#xff0c;技术人员可以利用一系列强大的网络安全工具进行安全检测和防范&#xff0c;以保护组织的网络基础设施、数据和资产免受各种威胁。这些工具通常涵盖了从主动防御、威胁检测、漏洞管理到事件响应和安全分析的各个方面。 以下是一些关…...

Unity 跳转资源商店,并打开特定应用

需求&#xff1a; 打开资源商店&#xff0c;并定位到特定应用. 代码&#xff1a; #if UNITY_ANDROIDApplication.OpenURL("market://details?idcom.tencent.mm"); #elif UNITY_IPHONEApplication.OpenURL(“itms-apps://apps.apple.com/app/id333903271”); #end…...

2025年五大ETL数据集成工具推荐

ETL工具作为打通数据孤岛的核心引擎&#xff0c;直接影响着企业的决策效率与业务敏捷性。本文精选五款实战型ETL解决方案&#xff0c;从零门槛的国产免费工具到国际大厂企业级平台&#xff0c;助您找到最适合的数据集成利器。 一、谷云科技ETLCloud&#xff1a;国产数据集成工…...

基于 PaddleOCR对pdf文件中的文字提取

一、基于 PaddleOCR 提取 PDF 文件中的文字流程 1. 安装必要的依赖库&#xff1a;包括 PaddleOCR 和 PyMuPDF pip install paddlepaddle paddleocr pymupdf 2. 将 PDF 转换为图像&#xff1a;使用 PyMuPDF 将 PDF 的每一页转换为图像 3. 使用 PaddleOCR 进行文字识别&a…...

鸿蒙移动应用开发--渲染控制实验

任务&#xff1a;使用“对象数组”、“ForEach渲染”、“Badge角标组件”、“Grid布局”等相关知识&#xff0c;实现生效抽奖卡案例。如图1所示&#xff1a; 图1 生肖抽奖卡实例图 图1(a)中有6张生肖卡可以抽奖&#xff0c;每抽中一张&#xff0c;会通过弹层显示出来&#xf…...

【漫话机器学习系列】215.处理高度不平衡数据策略(Strategies For Highly Imbalanced Classes)

处理高度不平衡数据的四大策略详解 在机器学习与数据挖掘任务中&#xff0c;“类别不平衡”问题几乎无处不在。无论是信用卡欺诈检测、医疗异常诊断&#xff0c;还是网络攻击识别&#xff0c;正负样本的比例往往严重失衡。比如一个欺诈检测数据集中&#xff0c;可能只有不到 1…...

在离线 Ubuntu 环境下部署双 Neo4j 实例(Prod Dev)

在许多开发和生产场景中&#xff0c;我们可能需要在同一台服务器上运行多个独立的 Neo4j 数据库实例&#xff0c;例如一个用于生产环境 (Prod)&#xff0c;一个用于开发测试环境 (Dev)。本文将详细介绍如何在 离线 的 Ubuntu 服务器上&#xff0c;使用 tar.gz 包部署两个 Neo4j…...

Windows下Golang与Nuxt项目宝塔部署指南

在Windows下将Golang后端和Nuxt前端项目打包&#xff0c;并使用宝塔面板部署的步骤如下 一、Golang后端打包 交叉编译为Linux可执行文件 在Windows PowerShell中执行&#xff1a; powershell复制下载 $env:GOOS "linux" $env:GOARCH "amd64" go build…...

基于贝叶斯优化的Transformer多输入单输出回归预测模型Bayes-Transformer【MATLAB】

Bayes-Transformer 在机器学习和深度学习领域&#xff0c;Transformer模型已经广泛应用于自然语言处理、图像识别、时间序列预测等多个领域。然而&#xff0c;在一些实际应用中&#xff0c;我们面临着如何高效地优化模型超参数的问题。贝叶斯优化&#xff08;Bayesian Optimiz…...

ibus输入法微软词库分享

链接: https://pan.baidu.com/s/1aC-UvV-UDHEpxg5sZcAS2Q?pwddxpq 提取码: dxpq --来自百度网盘超级会员v8的分享 链接: https://pan.baidu.com/s/1aC-UvV-UDHEpxg5sZcAS2Q?pwddxpq 提取码: dxpq --来自百度网盘超级会员v8的分享 # 更改ibus输入法字体大小 sudo apt insta…...

Sharding-JDBC 系列专题 - 第五篇:分布式事务

Sharding-JDBC 系列专题 - 第五篇:分布式事务 本系列专题旨在帮助开发者全面掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第五篇文章,将深入探讨 分布式事务(Distributed Transactions),包括其概念、支持的事务类型、配置方法、工作原理以及实战…...

力扣每日打卡17 49. 字母异位词分组 (中等)

力扣 49. 字母异位词分组 中等 前言一、题目内容二、解题方法1. 哈希函数2.官方题解2.1 前言2.2 方法一&#xff1a;排序2.2 方法二&#xff1a;计数 前言 这是刷算法题的第十七天&#xff0c;用到的语言是JS 题目&#xff1a;力扣 49. 字母异位词分组 (中等) 一、题目内容 给…...