欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot線程池配置使用示例詳解

 更新時(shí)間:2025年07月07日 14:51:14   作者:ldwtxwh  
Spring?Boot集成@Async注解,支持線程池參數(shù)配置(核心數(shù)、隊(duì)列容量、拒絕策略等)及生命周期管理,結(jié)合監(jiān)控與任務(wù)裝飾器,提升異步處理效率與系統(tǒng)穩(wěn)定性,本文給大家介紹SpringBoot線程池配置使用示例詳解,感興趣的朋友一起看看吧

一、核心特性

Springboot 集成
支持 @Async 注解,簡(jiǎn)化異步方法調(diào)用。
參數(shù)可配置化

核心線程數(shù)、最大線程數(shù)、隊(duì)列容量、拒絕策略等均可通過配置調(diào)整。
生命周期管理

實(shí)現(xiàn) Lifecycle 接口,支持線程池的啟動(dòng)和關(guān)閉(如應(yīng)用關(guān)閉時(shí)優(yōu)雅終止任務(wù))。
任務(wù)裝飾器

支持通過 TaskDecorator 對(duì)任務(wù)進(jìn)行裝飾(如傳遞上下文信息)

二、添加依賴

pom.xml 文件中添加 Spring Boot Starter AOP 依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

三、參數(shù)詳解

通過 Spring 配置文件或 @Bean 定義線程池時(shí),需設(shè)置以下關(guān)鍵參數(shù):

參數(shù)名稱說明默認(rèn)值
corePoolSize核心線程數(shù),即使空閑也不會(huì)被回收1
maxPoolSize最大線程數(shù),當(dāng)隊(duì)列滿時(shí)創(chuàng)建新線程直到達(dá)到此值Integer.MAX_VALUE
queueCapacity任務(wù)隊(duì)列容量(使用 LinkedBlockingQueue 或 ArrayBlockingQueue)Integer.MAX_VALUE
keepAliveSeconds非核心線程的空閑存活時(shí)間(秒)60
threadNamePrefix線程名前綴,便于日志追蹤"task-executor-"
allowCoreThreadTimeOut是否允許核心線程超時(shí)回收false
rejectedExecutionHandler拒絕策略(如 AbortPolicy、CallerRunsPolicy)AbortPolicy(直接拋出異常)

四、配置線程池

@Configuration
@EnableAsync
public class ExecutorConfig {
    private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.prefix}")
    private String namePrefix;
    @Bean(name = "asyncServiceExecutor")
    public Executor asyncServiceExecutor() {
        logger.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心線程數(shù)
        executor.setCorePoolSize(corePoolSize);
        //配置最大線程數(shù)
        executor.setMaxPoolSize(maxPoolSize);
        //配置隊(duì)列大小
        executor.setQueueCapacity(queueCapacity);
        //配置線程池中的線程的名稱前綴
        executor.setThreadNamePrefix(namePrefix);
        // rejection-policy:當(dāng)pool已經(jīng)達(dá)到max size的時(shí)候,如何處理新任務(wù)
        // CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //執(zhí)行初始化
        executor.initialize();
        return executor;
    }
}

@Value是我配置在 application.yml,可以參考配置,自由定義 

# 異步線程配置
# 配置核心線程數(shù)
async.executor.thread.core_pool_size = 5
# 配置最大線程數(shù)
async.executor.thread.max_pool_size = 5
# 配置隊(duì)列大小
async.executor.thread.queue_capacity = 99999
# 配置線程池中的線程的名稱前綴
async.executor.thread.name.prefix = async-service-

五、應(yīng)用實(shí)踐

1、異步任務(wù)處理

創(chuàng)建一個(gè)服務(wù)類 AsyncService,并在其方法上使用 @Async 注解來定義異步任務(wù):

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
    private static final Logger logger = LoggerFactory.getLogger(AsyncService.class);
    @Async("taskExecutor")
    public void asyncTask(String taskName) {
        logger.info(Thread.currentThread().getName() + " 開始執(zhí)行任務(wù): " + taskName);
        try {
            Thread.sleep(2000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("任務(wù)執(zhí)行被中斷", e);
        } finally {
            logger.info(Thread.currentThread().getName() + " 任務(wù)執(zhí)行完成: " + taskName);
        }
    }
}

創(chuàng)建一個(gè)控制器類 AsyncController,用于觸發(fā)異步任務(wù)(線程安全的)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;
@RestController
public class AsyncController {
    private static final Logger logger = LoggerFactory.getLogger(AsyncController.class);
    @Autowired
    private AsyncService asyncService;
    @GetMapping("/trigger")
    public String triggerAsyncTasks() {
        logger.info("開始觸發(fā)異步任務(wù)");
        for (int i = 0; i < 10; i++) {
            asyncService.asyncTask("任務(wù) " + i);
        }
        return "異步任務(wù)已觸發(fā)";
    }
}

創(chuàng)建一個(gè)監(jiān)控組件 ThreadPoolMonitor,用于定期監(jiān)控線程池的狀態(tài)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ThreadPoolMonitor {
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolMonitor.class);
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Scheduled(fixedRate = 60000) // 每分鐘執(zhí)行一次
    public void monitorThreadPool() {
        int activeCount = taskExecutor.getActiveCount();
        int poolSize = taskExecutor.getPoolSize();
        int corePoolSize = taskExecutor.getCorePoolSize();
        int maxPoolSize = taskExecutor.getMaxPoolSize();
        int queueSize = taskExecutor.getThreadPoolExecutor().getQueue().size();
        int completedTaskCount = taskExecutor.getThreadPoolExecutor().getCompletedTaskCount();
        logger.info("線程池狀態(tài) - 活動(dòng)線程數(shù): {}, 當(dāng)前線程數(shù): {}, 核心線程數(shù): {}, 最大線程數(shù): {}, 隊(duì)列大小: {}, 已完成任務(wù)數(shù): {}",
                activeCount, poolSize, corePoolSize, maxPoolSize, queueSize, completedTaskCount);
        // 檢查線程池是否接近飽和
        if (activeCount >= maxPoolSize * 0.8 || queueSize >= taskExecutor.getQueueCapacity() * 0.8) {
            logger.warn("線程池負(fù)載過高!請(qǐng)考慮優(yōu)化配置或檢查任務(wù)執(zhí)行情況");
        }
    }
}

 確保在啟動(dòng)類上添加 @EnableAsync 注解,以啟用異步任務(wù)支持

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class AsyncDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(AsyncDemoApplication.class, args);
    }
}

測(cè)試:

啟動(dòng) Spring Boot 應(yīng)用后,訪問 http://localhost:8080/trigger,即可看到異步任務(wù)在線程池中執(zhí)行的情況,同時(shí)線程池的狀態(tài)也會(huì)定期輸出到日志中。

代碼說明

  • @EnableAsync 注解 :用于啟用 Spring 的異步方法執(zhí)行支持,確保 Spring 容器能夠識(shí)別和處理帶有 @Async 注解的方法。

  • @Async 注解 :用于標(biāo)注希望異步執(zhí)行的方法,需指定所使用的線程池 Bean 的名稱,在本例中為 “taskExecutor”。當(dāng)該方法被調(diào)用時(shí),Spring 會(huì)將其提交到指定的線程池中執(zhí)行。

  • ThreadPoolTaskExecutor :是 Spring 提供的一個(gè)線程池任務(wù)執(zhí)行器,通過設(shè)置核心線程數(shù)、最大線程數(shù)、隊(duì)列容量等參數(shù),可以根據(jù)應(yīng)用的需求靈活地配置線程池。

  • 異步任務(wù)失敗處理 :通過自定義的拒絕策略,在線程池滿時(shí)記錄詳細(xì)信息并拋出異常,以便及時(shí)發(fā)現(xiàn)任務(wù)執(zhí)行失敗的情況。

  • 線程池監(jiān)控 :使用 @Scheduled 注解定期監(jiān)控線程池的狀態(tài),包括活動(dòng)線程數(shù)、當(dāng)前線程數(shù)、核心線程數(shù)、最大線程數(shù)、隊(duì)列大小和已完成任務(wù)數(shù)等,幫助開發(fā)者了解線程池的運(yùn)行情況,以便及時(shí)進(jìn)行優(yōu)化和調(diào)整

2、高并發(fā)請(qǐng)求處理

在 Web 應(yīng)用中處理大量并發(fā)請(qǐng)求,避免阻塞主線程

@RestController
public class MyController {
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @GetMapping("/process")
    public CompletableFuture<String> handleRequest() {
        return CompletableFuture.supplyAsync(() -> {
            // 耗時(shí)操作
            return "Result";
        }, taskExecutor);
    }
}

3、定時(shí)任務(wù)調(diào)度

@EnableScheduling
@Configuration
public class SchedulerConfig {
    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);
        scheduler.setThreadNamePrefix("Scheduler-");
        return scheduler;
    }
}
@Service
public class ScheduledService {
    @Scheduled(fixedRate = 5000)
    public void scheduledTask() {
        // 定時(shí)任務(wù)邏輯
    }
}

拒絕策略(Rejected Policies)

當(dāng)線程池和隊(duì)列均滿時(shí),處理新任務(wù)的策略:

策略類行為描述
AbortPolicy直接拋出 RejectedExecutionException(默認(rèn))
CallerRunsPolicy由提交任務(wù)的線程直接執(zhí)行任務(wù)(同步阻塞提交者)
DiscardPolicy靜默丟棄新任務(wù),不拋異常
DiscardOldestPolicy丟棄隊(duì)列中最舊的任務(wù),然后重試提交新任務(wù)

如下給出不同拒絕策略的配置類,請(qǐng)結(jié)合上面的配置類整合使用

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class ThreadPoolConfig {
    @Bean(name = "abortPolicyExecutor")
    public ThreadPoolTaskExecutor abortPolicyExecutor() {
        return createExecutor(new ThreadPoolExecutor.AbortPolicy());
    }
    @Bean(name = "callerRunsPolicyExecutor")
    public ThreadPoolTaskExecutor callerRunsPolicyExecutor() {
        return createExecutor(new ThreadPoolExecutor.CallerRunsPolicy());
    }
    @Bean(name = "discardPolicyExecutor")
    public ThreadPoolTaskExecutor discardPolicyExecutor() {
        return createExecutor(new ThreadPoolExecutor.DiscardPolicy());
    }
    @Bean(name = "discardOldestPolicyExecutor")
    public ThreadPoolTaskExecutor discardOldestPolicyExecutor() {
        return createExecutor(new ThreadPoolExecutor.DiscardOldestPolicy());
    }
    private ThreadPoolTaskExecutor createExecutor(ThreadPoolExecutor.RejectedExecutionHandler rejectedExecutionHandler) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); // 核心線程數(shù)
        executor.setMaxPoolSize(10); // 最大線程數(shù)
        executor.setQueueCapacity(100); // 隊(duì)列容量
        executor.setThreadNamePrefix("Task-Executor-"); // 線程名前綴
        executor.setRejectedExecutionHandler(rejectedExecutionHandler);
        executor.initialize();
        return executor;
    }
}

創(chuàng)建一個(gè)服務(wù)類 TaskService,用于執(zhí)行任務(wù)

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class TaskService {
    @Async("abortPolicyExecutor")
    public void executeWithAbortPolicy(String taskName) {
        executeTask(taskName);
    }
    @Async("callerRunsPolicyExecutor")
    public void executeWithCallerRunsPolicy(String taskName) {
        executeTask(taskName);
    }
    @Async("discardPolicyExecutor")
    public void executeWithDiscardPolicy(String taskName) {
        executeTask(taskName);
    }
    @Async("discardOldestPolicyExecutor")
    public void executeWithDiscardOldestPolicy(String taskName) {
        executeTask(taskName);
    }
    private void executeTask(String taskName) {
        try {
            System.out.println(Thread.currentThread().getName() + " 開始執(zhí)行任務(wù): " + taskName);
            Thread.sleep(2000); // 模擬任務(wù)執(zhí)行時(shí)間
            System.out.println(Thread.currentThread().getName() + " 任務(wù)執(zhí)行完成: " + taskName);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("任務(wù)執(zhí)行被中斷: " + taskName);
        }
    }
}

創(chuàng)建一個(gè)控制器類 TaskController,用于觸發(fā)任務(wù)執(zhí)行

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TaskController {
    @Autowired
    private TaskService taskService;
    @GetMapping("/trigger/abort")
    public String triggerAbortPolicy(@RequestParam String taskName) {
        taskService.executeWithAbortPolicy(taskName);
        return "任務(wù)已提交到使用 AbortPolicy 的線程池";
    }
    @GetMapping("/trigger/caller")
    public String triggerCallerRunsPolicy(@RequestParam String taskName) {
        taskService.executeWithCallerRunsPolicy(taskName);
        return "任務(wù)已提交到使用 CallerRunsPolicy 的線程池";
    }
    @GetMapping("/trigger/discard")
    public String triggerDiscardPolicy(@RequestParam String taskName) {
        taskService.executeWithDiscardPolicy(taskName);
        return "任務(wù)已提交到使用 DiscardPolicy 的線程池";
    }
    @GetMapping("/trigger/discardoldest")
    public String triggerDiscardOldestPolicy(@RequestParam String taskName) {
        taskService.executeWithDiscardOldestPolicy(taskName);
        return "任務(wù)已提交到使用 DiscardOldestPolicy 的線程池";
    }
}

啟動(dòng) Spring Boot 應(yīng)用后,分別訪問以下 URL 來測(cè)試不同拒絕策略的行為:

  • http://localhost:8080/trigger/abort?taskName=任務(wù)1

  • http://localhost:8080/trigger/caller?taskName=任務(wù)2

  • http://localhost:8080/trigger/discard?taskName=任務(wù)3

  • http://localhost:8080/trigger/discardoldest?taskName=任務(wù)4

  • 代碼說明

  • 線程池配置

    • 使用 ThreadPoolTaskExecutor 創(chuàng)建線程池。

    • 配置了 4 個(gè)不同的線程池,每個(gè)線程池使用不同的拒絕策略。

    • 每個(gè)線程池的核心線程數(shù)為 5,最大線程數(shù)為 10,隊(duì)列容量為 100。

  • 拒絕策略

    • AbortPolicy:直接拋出 RejectedExecutionException

    • CallerRunsPolicy:由提交任務(wù)的線程直接執(zhí)行任務(wù)。

    • DiscardPolicy:靜默丟棄新任務(wù),不拋異常。

    • DiscardOldestPolicy:丟棄隊(duì)列中最舊的任務(wù),然后重試提交新任務(wù)。

    • 任務(wù)執(zhí)行

      • TaskService 類中的每個(gè)方法都使用 @Async 注解,并指定使用的線程池。

      • executeTask 方法模擬任務(wù)執(zhí)行,包含一個(gè) 2 秒的睡眠時(shí)間。

      • 通過這個(gè)示例,你可以觀察不同拒絕策略在任務(wù)被拒絕時(shí)的行為。例如,當(dāng)線程池滿時(shí),AbortPolicy 會(huì)拋出異常,CallerRunsPolicy 會(huì)讓提交任務(wù)的線程執(zhí)行任務(wù),DiscardPolicy 會(huì)靜默丟棄任務(wù),而 DiscardOldestPolicy 會(huì)丟棄最舊的任務(wù)并嘗試提交新任務(wù)

    • 6、最佳配置

    • · 合理設(shè)置線程池參數(shù)
      CPU 密集型任務(wù):核心線程數(shù) ≈ CPU 核心數(shù)
      I/O 密集型任務(wù):核心線程數(shù) ≈ CPU 核心數(shù) * 2,并增大隊(duì)列容量。
      · 避免隊(duì)列無限堆積
      設(shè)置合理的 queueCapacity,防止內(nèi)存溢出(OOM)。
      · 統(tǒng)一異常處理
      通過 AsyncUncaughtExceptionHandler 捕獲異步任務(wù)中的異常:

    • @Configuration
      public class AsyncConfig implements AsyncConfigurer {
          @Override
          public Executor getAsyncExecutor() {
              ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
              // ... 配置參數(shù)
              return executor;
          }
          @Override
          public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
              return (ex, method, params) -> {
                  // 處理異常
              };
          }
      }

      應(yīng)用退出時(shí),調(diào)用 shutdown() 并等待剩余任務(wù)執(zhí)行完畢

    • executor.shutdown();
      try {
          if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
              executor.shutdownNow();
          }
      } catch (InterruptedException e) {
          executor.shutdownNow();
      }

      總結(jié):

    • ThreadPoolTaskExecutor 是 Spring 生態(tài)中管理線程任務(wù)的利器,通過靈活的配置和與 Spring 的無縫集成,能夠高效處理異步任務(wù)、高并發(fā)請(qǐng)求和定時(shí)調(diào)度。合理設(shè)置參數(shù)、選擇拒絕策略,并結(jié)合監(jiān)控手段,可顯著提升系統(tǒng)性能和穩(wěn)定性。

到此這篇關(guān)于SpringBoot線程池配置使用詳解的文章就介紹到這了,更多相關(guān)SpringBoot線程池配置使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java IO之序列化與反序列化詳解

    Java IO之序列化與反序列化詳解

    這篇文章主要為大家介紹了Java IO之序列化與反序列化,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • java 并發(fā)編程之共享變量的實(shí)現(xiàn)方法

    java 并發(fā)編程之共享變量的實(shí)現(xiàn)方法

    這篇文章主要介紹了java 并發(fā)編程之共享變量的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Springboot+MyBatist實(shí)現(xiàn)前后臺(tái)交互登陸功能方式

    Springboot+MyBatist實(shí)現(xiàn)前后臺(tái)交互登陸功能方式

    這篇文章主要介紹了Springboot+MyBatist實(shí)現(xiàn)前后臺(tái)交互登陸功能方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • @ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn)

    @ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn)

    這篇文章主要介紹了@ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • MyBatis 數(shù)據(jù)封裝全攻略(告別空值與映射混亂問題)

    MyBatis 數(shù)據(jù)封裝全攻略(告別空值與映射混亂問題)

    本文系統(tǒng)介紹MyBatis數(shù)據(jù)封裝的常見問題及解決方案,涵蓋resultType、resultMap、駝峰轉(zhuǎn)換、嵌套處理、懶加載等核心機(jī)制,并推薦MyBatis-Plus簡(jiǎn)化開發(fā),提升效率與可維護(hù)性,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • 2018年java技術(shù)面試題整理

    2018年java技術(shù)面試題整理

    小編為大家整理了2018年最新的關(guān)于java技術(shù)相關(guān)的面試題,以及給出了最簡(jiǎn)簡(jiǎn)答方式,學(xué)習(xí)下吧。
    2018-02-02
  • java讀取圖片并轉(zhuǎn)化為二進(jìn)制字符串的實(shí)現(xiàn)方法

    java讀取圖片并轉(zhuǎn)化為二進(jìn)制字符串的實(shí)現(xiàn)方法

    這篇文章主要介紹了java讀取圖片并轉(zhuǎn)化為二進(jìn)制字符串的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • 解決SpringBoot application.yaml文件配置schema 無法執(zhí)行sql問題

    解決SpringBoot application.yaml文件配置schema 無法執(zhí)行sql問題

    這篇文章主要介紹了解決SpringBoot application.yaml文件配置schema 無法執(zhí)行sql問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java大話之創(chuàng)建型設(shè)計(jì)模式教程示例

    java大話之創(chuàng)建型設(shè)計(jì)模式教程示例

    這篇文章主要為大家介紹了java大話之創(chuàng)建型設(shè)計(jì)模式教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java面試之SQL語句題經(jīng)典案例

    Java面試之SQL語句題經(jīng)典案例

    本文詳細(xì)討論了如何將行數(shù)據(jù)轉(zhuǎn)化為列數(shù)據(jù),并提供了多種SQL查詢練習(xí)題,包括查詢特定條件的學(xué)生信息、課程成績(jī)比較、學(xué)生成績(jī)排名等,文章還解釋了在SQL中使用Union、UnionAll和pivot的方法,以及如何處理復(fù)雜的SQL查詢問題,需要的朋友可以參考下
    2024-10-10

最新評(píng)論