• [技术干货] Java中Deflater和GZIP的压缩/解压实现
    一、Deflater实现(原始DEFLATE格式)1. 压缩方法 public static String compress(String rawData) { Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true); // nowrap=true try { deflater.setInput(rawData.getBytes(StandardCharsets.UTF_8)); deflater.finish(); try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { byte[] buffer = new byte[8192]; while (!deflater.finished()) { int compressedBytes = deflater.deflate(buffer); bos.write(buffer, 0, compressedBytes); } return Base64.getUrlEncoder().withoutPadding() .encodeToString(bos.toByteArray()); } } finally { deflater.end(); } }2. 解压方法 public static String decompress(String compressedData) { Inflater inflater = new Inflater(true); try { byte[] compressedBytes = Base64.getUrlDecoder().decode(compressedData); inflater.setInput(compressedBytes); try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { byte[] buffer = new byte[8192]; while (!inflater.finished()) { try { int decompressedBytes = inflater.inflate(buffer); bos.write(buffer, 0, decompressedBytes); } catch (DataFormatException e) { throw new RuntimeException("数据损坏", e); } } return bos.toString(StandardCharsets.UTF_8); } } finally { inflater.end(); } }二、GZIP实现(标准gzip格式)1. 压缩方法 public static String compress(String rawData) throws IOException { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(bos)) { gzip.write(rawData.getBytes(StandardCharsets.UTF_8)); gzip.finish(); return Base64.getEncoder().encodeToString(bos.toByteArray()); } }2. 解压方法 public static String decompress(String compressedData) throws IOException { byte[] compressedBytes = Base64.getDecoder().decode(compressedData); try (ByteArrayInputStream bis = new ByteArrayInputStream(compressedBytes); GZIPInputStream gzip = new GZIPInputStream(bis); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { byte[] buffer = new byte[8192]; int len; while ((len = gzip.read(buffer)) > 0) { bos.write(buffer, 0, len); } return bos.toString(StandardCharsets.UTF_8); } }三、优缺点对比特性Deflater (DEFLATE)GZIP压缩率≈95%(无头部,极限压缩)≈93%(含18字节头部)速度稍快(无头部开销)稍慢(需处理头部)兼容性需特殊解析器通用解压工具支持典型应用场景网络传输、内存敏感型应用文件存储、通用数据交换头部开销无18字节(含时间戳等元数据)校验和无有(CRC32)流式处理需手动管理缓冲区支持流式API四、选型建议优先选GZIP的场景:需要与其他系统交互时处理文件存储或日志压缩时需要内置校验和验证数据完整性时优先选Deflater的场景:追求极限压缩率时进行网络传输(尤其对延迟敏感时)需要自定义协议格式时通用原则:短文本(<1KB)建议直接存储中等长度文本(1KB-1MB)优先GZIP大文本(>1MB)可结合缓冲流处理实际测试显示,对于典型英文文本,Deflater比GZIP压缩率高约2-5%,但解压速度慢约10-15%。
  • [技术干货] java递归获取部门数方法
    前言递归(Recursion)在编程中是一个非常重要的概念。简单来说,递归指的是一个函数在其定义中直接或间接调用自身。这种调用机制允许函数通过分解问题为更小的相似子问题来解决复杂问题。‌递归的定义‌:递归是一种在函数定义中调用函数自身的方法。它通常包含一个或多个基准情况(base case),用于结束递归调用链,以及一个或多个递归步骤,用于将问题分解为更小的子问题。‌递归的原理‌:1.基准情况‌:这是递归调用的终止条件。当满足基准情况时,函数将不再调用自身,而是返回结果。2.递归步骤‌:在递归步骤中,函数会调用自身来解决一个规模更小的相似问题。这个过程会一直持续,直到达到基准情况。递归的示例‌:现在我将获取部门树作为示例1.示例数据准备/* Navicat Premium Data Transfer Source Server         : localhost-本地 Source Server Type    : MySQL Source Server Version : 80036 Source Host           : localhost:3306 Source Schema         : test Target Server Type    : MySQL Target Server Version : 80036 File Encoding         : 65001 Date: 22/04/2025 01:41:05*/SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for sys_dept-- ----------------------------DROP TABLE IF EXISTS `sys_dept`;CREATE TABLE `sys_dept`  (  `dept_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '部门id',  `parent_id` bigint(0) NULL DEFAULT 0 COMMENT '父部门id',  `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '祖级列表',  `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称',  `order_num` int(0) NULL DEFAULT 0 COMMENT '显示顺序',  `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '负责人',  `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话',  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱',  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)',  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',  PRIMARY KEY (`dept_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 210 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic;-- ------------------------------ Records of sys_dept-- ----------------------------INSERT INTO `sys_dept` VALUES (100, 0, '0', '中国移动', 0, '张三', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', 'admin', '2025-03-04 10:15:38');INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (103, 100, '0,100', '研发部门', 1, '若依', '', '', '0', '0', 'admin', '2025-02-17 08:58:32', 'admin', '2025-03-12 10:26:18');INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-02-17 08:58:32', '', NULL);2.获取组装的部门树:public List<SysDept> selectDeptList(SysDept dept) {        // 最终的部门树结果        List<SysDept>  deptTree = new ArrayList<>();        try {            // 1.获取所有部门信息            List<SysDept> sysDebts = sysDeptMapper.selectDeptList(dept);            // 2.获取根节点的部门信息(parentId=0的部门为根节点)            List<SysDept> rootDept = sysDebts.stream().filter(s-> s.getParentId().equals(0L))                    .collect(Collectors.toList());            for (SysDept root : rootDept) {                // 3.递归获取子节点                SysDept tree = getChildren(root, sysDebts);                // 4.添加到部门树中                deptTree.add(tree);            }            return deptTree;        } catch (Exception e) {            throw new RuntimeException(e);        }    }3.递归获取子部门:/**     * 递归获取子节点     * @param rootDept 根节点     * @param sysDepts 所有部门信息     * @return 树形结构的部门信息     */    private SysDept getChildren(SysDept rootDept, List<SysDept> sysDepts) {        ArrayList<SysDept> children = new ArrayList<>();        for (SysDept dept : sysDepts) {            if (rootDept.getDeptId().equals(dept.getParentId())){                children.add(getChildren(dept, sysDepts));            }        }        rootDept.setChildren(children);        return rootDept;    }4.接口数据返回:[    {        "deptId": 100,        "parentId": 0,        "ancestors": "0",        "deptName": "中国移动",        "orderNum": 0,        "leader": "张三",        "phone": "15888888888",        "email": "ry@qq.com",        "status": "0",        "delFlag": "0",        "parentName": null,        "children": [            {                "deptId": 101,                "parentId": 100,                "ancestors": "0,100",                "deptName": "深圳总公司",                "orderNum": 1,                "leader": "若依",                "phone": "15888888888",                "email": "ry@qq.com",                "status": "0",                "delFlag": "0",                "parentName": null,                "children": [                    {                        "deptId": 104,                        "parentId": 101,                        "ancestors": "0,100,101",                        "deptName": "市场部门",                        "orderNum": 2,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    },                    {                        "deptId": 105,                        "parentId": 101,                        "ancestors": "0,100,101",                        "deptName": "测试部门",                        "orderNum": 3,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    },                    {                        "deptId": 106,                        "parentId": 101,                        "ancestors": "0,100,101",                        "deptName": "财务部门",                        "orderNum": 4,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    },                    {                        "deptId": 107,                        "parentId": 101,                        "ancestors": "0,100,101",                        "deptName": "运维部门",                        "orderNum": 5,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    }                ],                "createBy": "admin",                "createTime": "2025-02-17 00:58:32",                "updateBy": null,                "updateTime": null            },            {                "deptId": 103,                "parentId": 100,                "ancestors": "0,100",                "deptName": "研发部门",                "orderNum": 1,                "leader": "若依",                "phone": "",                "email": "",                "status": "0",                "delFlag": "0",                "parentName": null,                "children": [],                "createBy": "admin",                "createTime": "2025-02-17 00:58:32",                "updateBy": null,                "updateTime": null            },            {                "deptId": 102,                "parentId": 100,                "ancestors": "0,100",                "deptName": "长沙分公司",                "orderNum": 2,                "leader": "若依",                "phone": "15888888888",                "email": "ry@qq.com",                "status": "0",                "delFlag": "0",                "parentName": null,                "children": [                    {                        "deptId": 108,                        "parentId": 102,                        "ancestors": "0,100,102",                        "deptName": "市场部门",                        "orderNum": 1,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    },                    {                        "deptId": 109,                        "parentId": 102,                        "ancestors": "0,100,102",                        "deptName": "财务部门",                        "orderNum": 2,                        "leader": "若依",                        "phone": "15888888888",                        "email": "ry@qq.com",                        "status": "0",                        "delFlag": "0",                        "parentName": null,                        "children": [],                        "createBy": "admin",                        "createTime": "2025-02-17 00:58:32",                        "updateBy": null,                        "updateTime": null                    }                ],                "createBy": "admin",                "createTime": "2025-02-17 00:58:32",                "updateBy": null,                "updateTime": null            }        ],        "createBy": "admin",        "createTime": "2025-02-17 00:58:32",        "updateBy": null,        "updateTime": null    }]注意事项‌‌效率问题‌:递归可能引发栈溢出或重复计算(如斐波那契数列的朴素递归),需结合尾递归优化或动态规划改进。‌理解难度‌:需通过“递进+回归”过程分析,如阶乘的逐步展开与回溯。‌总结‌:递归是一种强大的编程范式,适用于问题可分解为自相似结构的场景,但需谨慎设计终止条件和优化性能。转载自https://www.cnblogs.com/songweipeng/p/18830967
  • [技术干货] flowable任务监听器和java-service依赖注入问题
    前言1. Flowable中Java服务任务的依赖注入方法,比如使用Spring的@Autowired或构造函数注入,并确保服务任务类由Spring管理。2. 流程引擎配置中启用依赖注入和表达式解析的相关设置。3. 异步任务执行器的配置,确保其与Spring上下文集成,处理依赖注入的Bean。4. 常见问题排查,如检查Bean的作用域、是否正确使用delegateExpression等。5. 可能的示例代码或配置片段,帮助用户理解如何正确配置。另外,可能需要提醒用户注意流程定义文件中的服务任务配置是否正确,比如是否使用了expression或delegateExpression来引用Spring Bean,或者是否直接指定了Java类导致Spring的依赖注入不生效。最后,如果有必要,可以比较一下在非Spring环境下如何手动处理依赖注入,但大部分情况下用户可能在使用Spring,所以重点放在Spring集成方面。一、Java服务任务依赖注入场景:在实现JavaDelegate的类中注入Spring管理的Bean(如Service、Repository)。正确配置方法:步骤1:将服务类注册为Spring Bean@Component("myServiceTask") // 使用名称便于流程中引用public class MyServiceTask implements JavaDelegate {        private final MyService myService;    @Autowired // 构造器注入推荐    public MyServiceTask(MyService myService) {        this.myService = myService;    }    @Override    public void execute(DelegateExecution execution) {        myService.businessMethod();    }}步骤2:在流程定义中引用Bean使用delegateExpression指向Spring Bean的名称:<serviceTask id="serviceTask1" name="My Task" flowable:delegateExpression="${myServiceTask}" />常见问题解决:Bean注入为null:确保类被Spring扫描(位于@ComponentScan路径下)。检查流程定义中是否错误使用class属性而非delegateExpression。确认流程引擎配置启用了Spring集成。表达式解析失败:在FlowableConfig中启用表达式解析和Spring注入:@Beanpublic SpringProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager) {    SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();    config.setDataSource(dataSource);    config.setTransactionManager(transactionManager);    config.setDatabaseSchemaUpdate(Flowable.DB_SCHEMA_UPDATE_TRUE);    config.setAsyncExecutorEnabled(true); // 启用异步执行器    config.setExpressionManager(new SpringExpressionManager(applicationContext, null)); // 启用Spring表达式    return config;}二. 异步任务执行器配置当服务任务标记为异步(flowable:async="true")时,任务由异步执行器处理。配置异步执行器:@Beanpublic AsyncExecutor asyncExecutor(DataSource dataSource) {    DefaultAsyncExecutor asyncExecutor = new DefaultAsyncExecutor();    asyncExecutor.setDataSource(dataSource);    asyncExecutor.setCorePoolSize(5); // 核心线程数    asyncExecutor.setMaxPoolSize(10); // 最大线程数    asyncExecutor.setQueueSize(100); // 任务队列大小    return asyncExecutor;}在processEngineConfiguration中启用:config.setAsyncExecutor(asyncExecutor);config.setAsyncExecutorEnabled(true);异步任务依赖注入要点:Bean作用域:异步任务可能在新线程中运行,确保注入的Bean是线程安全的或使用@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)。事务管理:若异步任务涉及数据库操作,需配置@Transactional并确保事务传播正确。三、通过ApplicationContextAware接口的方式获取ApplicationContext对象实例可能的错误情况包括:没有在流程引擎配置中设置asyncExecutorEnabled为true,或者在服务任务中没有正确使用表达式导致注入失败。另外,Bean的作用域问题也可能导致依赖注入失败,例如,如果Bean的作用域是原型(prototype),但在注入时可能需要不同的处理方式。以下是我通过ApplicationContextAware接口的方式获取ApplicationContext对象实例,再通过applicationContext.getBean("myService")方法获取对应的bean代码示例:@Componentpublic class MyListener implements TaskListener, ApplicationContextAware {    private static  ApplicationContext applicationContext;    @Override    public void setApplicationContext(ApplicationContext arg0) throws BeansException {        applicationContext = arg0;    }    @Override    public void notify(DelegateTask delegateTask) {        String processInsId = delegateTask.getProcessInstanceId();        MyService myService = (MyService) applicationContext.getBean("myService");        // TODO 执行service方法                System.out.println("==========执行监听器======");    }}四. 常见问题排查错误:无法解析表达式${myServiceTask}检查Bean名称是否匹配。确认流程引擎配置中设置了SpringExpressionManager。异步任务不执行检查asyncExecutor是否启动:调用asyncExecutor.start()。查看日志中是否有任务提交异常。事务不生效确保异步执行器配置了事务管理器:asyncExecutor.setTransactionManager(transactionManager);五. Spring Boot集成若使用flowable-spring-boot-starter,简化配置如下:(1) application.yml:flowable:  async-executor-enabled: true  database-schema-update: true  async-executor:    core-pool-size: 5    max-pool-size: 10    queue-size: 100(2) 服务任务类:@Componentpublic class EmailServiceTask implements JavaDelegate {    private final EmailService emailService;    public EmailServiceTask(EmailService emailService) {        this.emailService = emailService;    }    @Override    public void execute(DelegateExecution execution) {        String recipient = (String) execution.getVariable("email");        emailService.send(recipient, "流程通知", "您的任务已处理完成。");    }}(3) 流程定义XML:<serviceTask id="sendEmail" flowable:delegateExpression="${emailServiceTask}" />六.总结依赖注入:确保服务任务类为Spring Bean,流程中使用delegateExpression引用。异步执行:配置AsyncExecutor并启用,注意线程安全和事务。ApplicationContextAware接口的方式获取ApplicationContext对象实例Spring集成:正确配置SpringProcessEngineConfiguration以支持表达式和Bean解析。转载自https://www.cnblogs.com/songweipeng/p/18820536
  • [互动交流] CodeArts构建maven的springcloud项目失败,jdk17 jansi-2.4.1 权限被阻止
    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba</artifactId> <version>2023.0.1.2</version> <relativePath/> </parent> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-backend</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>intelligent-teaching-commons</module> <module>intelligent-teaching-user</module> <module>intelligent-teaching-chat</module> <module>intelligent-teaching-exam</module> <module>intelligent-teaching-chat/intelligent-teaching-chat-api</module> <module>intelligent-teaching-chat/intelligent-teaching-chat-shared</module> <module>intelligent-teaching-exam/intelligent-teaching-exam-api</module> <module>intelligent-teaching-exam/intelligent-teaching-exam-shared</module> <module>intelligent-teaching-oss</module> <module>intelligent-teaching-job</module> <module>intelligent-teaching-search</module> <module>intelligent-teaching-ai</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring-ai.version>1.0.3</spring-ai.version> </properties> <repositories> <repository> <id>aliyunmaven</id> <url>https://maven.aliyun.com/repository/public</url> </repository> </repositories> <dependencies> <!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-commons</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.2.4</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2023.0.1.2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2023.0.1</version> <type>pom</type> <scope>import</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.34</version> <scope>compile</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId> <version>3.5.9</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-annotation</artifactId> <version>3.5.9</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <version>1.2.23</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.33</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.5.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.17.0</version> </dependency> <!-- https://mvnrepository.com/artifact/io.minio/minio --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.13</version> </dependency> <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.115.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.43.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --> <dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.4.2</version> </dependency> <!-- https://mvnrepository.com/artifact/co.elastic.clients/elasticsearch-java --> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.17.1</version> </dependency> <dependency> <groupId>com.luhuiguo</groupId> <artifactId>aspose-words</artifactId> <version>23.1</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>3.0.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-core --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-core</artifactId> <version>9.1.0</version> <type>pom</type> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.12.1</version> </dependency> <dependency> <groupId>io.springboot.ai</groupId> <artifactId>spring-ai-core</artifactId> <version>${spring-ai.version}</version> </dependency> <dependency> <groupId>io.springboot.ai</groupId> <artifactId>spring-ai-ollama</artifactId> <version>${spring-ai.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.32.0</version> </dependency> <!-- https://mvnrepository.com/artifact/io.milvus/milvus-sdk-java --> <dependency> <groupId>io.milvus</groupId> <artifactId>milvus-sdk-java</artifactId> <version>2.5.10</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-oss</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-job</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-search</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-ai</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-chat-shared</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-exam-shared</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cn.cat</groupId> <artifactId>intelligent-teaching-user-shared</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.9</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.4</version> </dependency> </dependencies> </dependencyManagement> </project>
  • java Map<String, Object> remove一个key
    在Java中,当你尝试从Map<String, Object>中移除一个不存在的键时,不会抛出异常。Map接口的remove方法被设计为安全地处理这种情况 - 如果键不存在,方法会简单地返回null(或指定的默认值,如果使用remove(Object key, V defaultValue)方法),而不会抛出任何异常。示例代码:import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String, Object> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", 123); // 尝试移除存在的键 Object removedValue = map.remove("key1"); System.out.println("Removed value: " + removedValue); // 输出: Removed value: value1 // 尝试移除不存在的键 Object nonExistentValue = map.remove("nonExistentKey"); System.out.println("Removed value: " + nonExistentValue); // 输出: Removed value: null // 使用Java 8+的remove方法,可以指定默认值 Object defaultValue = map.remove("anotherNonExistentKey", "default"); System.out.println("Removed value with default: " + defaultValue); // 输出: Removed value with default: default } } 关键点:标准remove方法:map.remove(key) - 如果键存在,返回对应的值;如果键不存在,返回null。带默认值的remove方法(Java 8+):map.remove(key, defaultValue) - 如果键存在,返回对应的值;如果键不存在,返回指定的默认值。不会抛出异常:无论键是否存在,remove方法都不会抛出异常。因此,你可以安全地尝试移除任何键,而不必担心会因为键不存在而导致程序抛出异常。
  • [技术干货] hutool 生成随机顺序的从0-10的数组
    要使用Hutool生成一个包含0到10的随机顺序的数组,你可以按照以下步骤操作:首先创建一个包含0到10的有序数组然后使用ArrayUtil.shuffle方法打乱数组顺序以下是完整的代码示例:import cn.hutool.core.util.ArrayUtil; public class Main { public static void main(String[] args) { // 创建0-10的有序数组 Integer[] array = ArrayUtil.range(0, 11); // 包含0和10 // 打乱数组顺序 ArrayUtil.shuffle(array); // 输出结果 System.out.println(ArrayUtil.toString(array)); } } 代码说明:ArrayUtil.range(0, 11) 创建一个包含0到10(包括0和10)的Integer数组ArrayUtil.shuffle(array) 打乱数组的顺序ArrayUtil.toString(array) 将数组转换为字符串形式输出输出示例:每次运行程序都会得到不同的随机顺序,例如:[5, 2, 9, 0, 7, 10, 3, 1, 4, 6, 8] 注意事项:确保项目中已经引入了Hutool的依赖如果你使用的是基本类型数组(如int[]),需要先转换为Integer[]或使用其他方法ArrayUtil.range方法在Hutool 5.x版本中可用,如果你使用的是较旧版本,可以手动创建数组:Integer[] array = new Integer[11]; for (int i = 0; i < 11; i++) { array[i] = i; } ArrayUtil.shuffle(array);
  • [技术干货] Java打乱数组顺序的几种方案
    方法一:使用ArrayUtil.shuffle方法import cn.hutool.core.util.ArrayUtil; public class Main { public static void main(String[] args) { Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 打乱数组顺序 ArrayUtil.shuffle(array); // 输出打乱后的数组 System.out.println(ArrayUtil.toString(array)); } } 方法二:使用ArrayUtil.shuffle方法并指定随机数生成器import cn.hutool.core.util.ArrayUtil; import java.util.Random; public class Main { public static void main(String[] args) { String[] array = {"A", "B", "C", "D", "E"}; Random random = new Random(); // 使用指定的随机数生成器打乱数组 ArrayUtil.shuffle(array, random); System.out.println(ArrayUtil.toString(array)); } } 方法三:对于基本类型数组Hutool也支持基本类型数组的打乱操作:import cn.hutool.core.util.ArrayUtil; public class Main { public static void main(String[] args) { int[] intArray = {1, 2, 3, 4, 5}; // 打乱基本类型数组 ArrayUtil.shuffle(intArray); System.out.println(ArrayUtil.toString(intArray)); } } 注意事项ArrayUtil.shuffle方法会直接修改原始数组,而不是返回一个新的数组对于对象数组和基本类型数组都适用默认使用Random类作为随机数生成器,但可以自定义替代方案如果你不想使用Hutool,也可以使用Java标准库实现:import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; public class Main { public static void main(String[] args) { Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 转换为List后打乱顺序 List<Integer> list = Arrays.asList(array); Collections.shuffle(list); list.toArray(array); // 如果需要,可以转换回数组 System.out.println(Arrays.toString(array)); } } Hutool的ArrayUtil.shuffle方法提供了更简洁的方式来实现数组乱序操作。
  • [技术干货] Java虚拟线程 VS Go语言Goroutine
    Java 引入虚拟线程(Virtual Threads)后,确实显著提升了高并发 I/O 密集型任务的性能,使其在并发编程模型上更接近 Go 的 Goroutine,但性能是否与 Go 相当仍需从多个维度综合分析。以下是两者的对比和关键差异:一、虚拟线程 vs. Goroutine:相似性轻量级线程模型虚拟线程:由 JVM 管理,用户态线程,依赖少量操作系统线程(通过协作式调度)。Goroutine:由 Go 运行时管理,用户态线程,依赖 M:N 调度器(用户态线程与操作系统线程的动态映射)。共同点:两者均通过减少线程栈大小和优化调度,支持高并发(数百万级)。同步编程模型虚拟线程:保持同步代码风格(如 try-with-resources 管理执行器)。Goroutine:同样支持同步风格(通过 go 关键字启动协程)。共同点:开发者无需显式处理异步回调,代码更简洁。阻塞行为优化虚拟线程:阻塞时释放底层操作系统线程,避免闲置。Goroutine:类似机制,阻塞时调度器将协程挂起,切换到其他就绪协程。共同点:两者均通过协作式调度减少线程切换开销。二、性能差异分析尽管虚拟线程和 Goroutine 在设计上类似,但实际性能可能因以下因素存在差异:1. 调度器实现Java 虚拟线程:基于 JVM 的调度器,依赖操作系统线程池(如 ForkJoinPool 的变种)。调度策略可能不如 Go 运行时精细(Go 的调度器经过多年优化,对协程的调度效率极高)。Go Goroutine:内置的 M:N 调度器直接集成在运行时中,对协程的挂起、恢复和负载均衡有更精细的控制。调度器能动态调整协程与操作系统线程的映射关系,适应不同场景。2. 内存占用虚拟线程:默认栈大小可通过 -XX:VirtualThreadStackSize 配置(默认 1MB,但可动态压缩)。栈内存占用可能略高于 Goroutine(Go 的栈初始大小通常为 2KB,动态扩展)。Goroutine:极小的初始栈大小(2KB)和高效的动态扩展机制,进一步降低内存开销。3. 启动与销毁开销虚拟线程:创建和销毁速度较快,但仍需 JVM 层面的调度开销。Goroutine:创建和销毁几乎无开销(通过运行时直接管理)。4. 垃圾回收(GC)影响Java:虚拟线程与 JVM 的 GC 紧密集成,GC 暂停可能影响高并发任务的响应时间。Go:并发垃圾回收(Concurrent GC)设计更轻量,对协程的干扰较小。5. 生态与工具链Java:虚拟线程是 Java 21 的新特性,生态工具(如监控、调试)可能需要时间适配。Go:Goroutine 是 Go 的核心特性,生态工具(如 pprof、trace)对其支持完善。三、性能对比的结论I/O 密集型任务虚拟线程:性能接近 Goroutine,尤其在 Java 21 优化后(如减少调度开销、优化栈内存)。Goroutine:仍可能略胜一筹,因其调度器更成熟、内存占用更低。CPU 密集型任务Java:普通线程仍是更优选择(虚拟线程无法直接提升 CPU 计算效率)。Go:Goroutine 适合并发 CPU 任务,但需注意 Goroutine 的调度开销可能影响密集计算。综合性能Go:在轻量级协程、调度效率和生态工具链上仍有优势。Java:虚拟线程显著缩小了差距,尤其在需要与现有 Java 生态(如 Spring、数据库驱动)集成的场景中。四、何时选择 Java 虚拟线程 vs. Go?场景推荐选择原因高并发 I/O 密集型Java 虚拟线程需与现有 Java 生态集成,或团队熟悉 Java。超轻量级协程需求Go Goroutine需要极致的并发性能和更低的内存占用。CPU 密集型任务Java 普通线程Java 的 JIT 优化和原生线程对 CPU 密集型任务更高效。跨平台与生态JavaJava 生态更丰富(如企业级应用、大数据工具)。快速开发与部署GoGo 的编译速度、部署简单性和内置工具链更适合微服务和小型项目。五、总结Java 虚拟线程的引入确实让 Java 在高并发 I/O 密集型场景中具备了与 Go 竞争的能力,但**性能是否“差不多”**取决于具体场景:优势场景:Java 虚拟线程在需要与现有 Java 生态集成的场景中表现优异。Go 的优势:在超轻量级协程、调度效率和生态工具链上仍有领先。未来,随着 JVM 对虚拟线程的进一步优化(如减少调度开销、改进 GC),两者性能差距可能会进一步缩小。但目前,选择仍需根据团队技能、项目需求和生态兼容性综合决定。
  • [技术干货] java虚拟线程和普通线程的区别
    Java 虚拟线程(Virtual Threads)是 Java 19 引入的一项重大特性(预览版,Java 21 正式发布),旨在简化高并发编程。它与普通线程(也称为平台线程,Platform Threads)在实现机制、资源占用和使用场景上有显著区别。以下是两者的详细对比:一、核心区别维度虚拟线程(Virtual Threads)普通线程(Platform Threads)实现机制由 JVM 管理,用户态线程(User-Mode Threads),依赖操作系统线程池调度。直接映射到操作系统线程(OS Threads),由内核调度。资源占用每个虚拟线程仅占用少量内存(KB 级别),可创建数百万甚至更多。每个普通线程占用大量内存(MB 级别,默认栈大小通常为 1MB),数量受限(通常数千)。调度方式协作式调度(Cooperative Scheduling),由 JVM 调度器在阻塞操作时挂起/恢复。抢占式调度(Preemptive Scheduling),由操作系统内核调度。阻塞行为阻塞时释放底层操作系统线程,避免线程闲置。阻塞时操作系统线程被占用,无法执行其他任务。使用场景高并发 I/O 密集型任务(如 Web 服务器、微服务)。CPU 密集型任务或需要直接操作系统资源的场景。二、深入对比1. 资源占用与并发能力普通线程:每个线程需要独立的操作系统线程,占用大量内存(如栈空间、线程局部存储等)。线程数量受限于操作系统和硬件(通常数千个线程会导致性能下降)。虚拟线程:每个虚拟线程仅占用少量内存(栈大小可通过 -XX:VirtualThreadStackSize 配置,默认 1MB,但可动态压缩)。可轻松创建数百万个虚拟线程,适合高并发场景。2. 调度与阻塞行为普通线程:阻塞操作(如 I/O、网络请求)会导致操作系统线程被占用,无法执行其他任务。线程池(如 ThreadPoolExecutor)通过复用线程缓解此问题,但需手动管理线程池大小。虚拟线程:阻塞时自动释放底层操作系统线程,允许其他虚拟线程复用。阻塞操作完成后,JVM 调度器恢复虚拟线程的执行。3. 性能与吞吐量普通线程:高并发时,线程切换开销大,可能导致 CPU 资源浪费(如线程等待 I/O 时仍占用 CPU)。虚拟线程:减少线程切换开销,提高吞吐量(尤其在 I/O 密集型任务中)。示例:一个普通线程池可能因线程阻塞导致吞吐量下降,而虚拟线程可充分利用 CPU。4. 编程模型普通线程:需显式管理线程生命周期(如 start()、join())。异步编程(如 CompletableFuture)需回调或协程,代码复杂。虚拟线程:保持同步编程模型(如 try (var executor = Executors.newVirtualThreadPerTaskExecutor()))。无需异步回调,代码更简洁。三、代码示例1. 普通线程示例// 使用线程池管理普通线程 ExecutorService executor = Executors.newFixedThreadPool(10); // 线程数量受限 for (int i = 0; i < 1000; i++) { executor.submit(() -> { try { Thread.sleep(1000); // 阻塞操作 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); } executor.shutdown(); 问题:线程池大小固定,高并发时需排队或拒绝任务。2. 虚拟线程示例// 使用虚拟线程执行器(Java 21+) try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 0; i < 1_000_000; i++) { // 轻松创建百万级线程 executor.submit(() -> { try { Thread.sleep(1000); // 阻塞时释放底层线程 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); } } // 自动关闭执行器 优势:无需管理线程池大小,阻塞时自动释放资源。四、适用场景虚拟线程:高并发 I/O 密集型任务(如 Web 服务器、微服务、爬虫)。需要简化异步编程的场景。普通线程:CPU 密集型任务(如科学计算、图像处理)。需要直接操作系统资源(如文件锁、硬件设备)。五、总结特性虚拟线程普通线程资源占用低(KB 级别)高(MB 级别)并发能力高(数百万级)低(数千级)调度方式协作式(JVM 调度)抢占式(内核调度)阻塞行为释放底层线程占用线程编程模型同步(类似单线程)显式线程管理或异步回调适用场景I/O 密集型CPU 密集型或直接操作系统资源六、为什么选择虚拟线程?简化高并发编程:无需异步回调,代码更简洁。资源高效利用:减少线程切换开销,提高吞吐量。弹性扩展:轻松应对突发流量(如 Web 请求)。虚拟线程是 Java 对高并发编程的重大改进,尤其适合现代云原生和微服务架构。然而,对于 CPU 密集型任务,普通线程仍是更优选择。
  • [互动交流] 鸿蒙PCCodeArts IDE配置tomcat显示 文件catalina.sh必须可执行
    显示文件catalina.sh 必须可执行
  • [互动交流] 为什么obs文件上传 BrowserJS语法返回值没有版本id参数,其他像是java、nodejs都有这个参数?
    我使用vue直接前端调用华为云obs上传文件服务传参,在文件管理里面我们需要用到版本控制的功能,需要拿到当前文件的versionId参数,但是我看到了BrowserJS语法没有返回这个参数,其他的都有,这是怎么回事,什么时候能更新一下返回值,或者有什么其他解决办法?
  • smartassist如何在setting.json里面配置
    smartassist.additionalSettings这个有什么属性可以自己设置的。
  • [专题汇总] FAQ—2025年5月份论坛问题求助合集
    推送镜像到SWR失败cid:link_0构建任务的日志链接可以对外提供吗?cid:link_1我想问下华为云的这个CodeArts支持CICD吗cid:link_2 CodeArts Snap插件支持哪些客户端和语言cid:link_3CodeArts看板项目如何按照自定义字段进行检索cid:link_4代码托管中组的访问级别如何修改cid:link_5麒麟V10X86架构安装ambari-2.7.5后,利用ambari构建大数据平台报错RuntimeError: Failed to execute command '/usr/bin/yum -y install hadoo cid:link_6麒麟V10安装ambari-server-2.7.5执行ambari-server setup报错Unexpected error Ambari repo file path not set for current OScid:link_7 
  • Nacos配置中心自动加载JSON配置
    在项目配置中,有个别场景需要通过nacos配置中心来维护一些项目中非spring上下文中的配置,比如:第三方特殊配置、一些非标准化的配置,想通过nacos来实现灵活管理与实时更新。这种需求场景下,我们可以通过Nacos中提供的两个注解来非常简单的实现我们需求。@NacosConfig:需要声明在,由spring管理的bean中,比如:bean的属性上,或者bean的类上。当应用启动时,会将声明了该注解的属性或类,进行赋值。@NacosConfigListener:需要声明在,由spring管理的bean中。作用于Bean的方法上,当Nacos中的配置发生变化时,会以方法入参形式将最新配置内容传入,且支持基本数据类型、对象、泛型类。版本要求:2023.x 系列需升级版本至2023.0.3.22022.x 系列需升级版本至2022.0.0.22021.x 系列需升级版本至2021.0.6.22.2.x 系列需升级至2.2.11@NacosConfig注解用法介绍此注解可作用于bean属性上和类上,前提是需要声明由spring进行管理。支持多种数据类型:基本类型、List、Map等List集合,接收JSON格式配置@Componentpublic class NacosConfigData { @NacosConfig(dataId = "list_demo.json",group = "default_group") private List<MyDemo> myDemoList;}Map泛型,接收JSON格式配置@Componentpublic class NacosConfigData { @NacosConfig(dataId = "map_demo.json",group = "default_group") private Map<Long,MyDemo> myDemoMap;}@NacosConfigListener 注解用法介绍此注解主要作用于方法上,在方法上进行声明,当配置发生变化时,会触发声明了此注解的方法,将最新的配置内容以入参方式传入。自定义bean 接收最新配置@Componentpublic class NacosConfigData { @NacosConfig(dataId = "list_demo.json",group = "default_group") private List<MyDemo> myDemoList; @NacosConfigListener(dataId = "list_demo.json",groupId = "default_group") private void myDemoListChanged(List<MyDemo> myDemoList){ this.myDemoList = myDemoList; } @NacosConfig(dataId = "map_demo.json",group = "default_group") private Map<Long,MyDemo> myDemoMap; @NacosConfigListener(dataId = "map_demo.json",groupId = "default_group") private void myDemoMapChanged(List<MyDemo> myDemoList){ this.myDemoList = myDemoList; }}更为详实介绍,可以查看,参考来源:https://sca.aliyun.com/blog/sca-gvr7dx_awbbpb_xr9f0v45pxz9ubnu/?spm=5176.29160081.0.0.74805c721Hvyc4&source=blog/
  • [技术干货] 算法的时间复杂度
    时间复杂度O是表示算法运行时间与输入数据规模(通常用 n 表示)之间的关系。算法执行时间随输入数据规模增长的变化趋势。1、O(1) — 常数时间无论输入数据多大,执行时间固定不变。典型场景:数组按索引访问、哈希表查询。2、O(log n) — 对数时间执行时间随数据量增长,但增速远慢于线性增长。典型场景:二分查找、平衡二叉搜索树操作。3、O(n) — 线性时间执行时间与数据量成正比。典型场景:遍历数组/链表、线性搜索。4、O(n log n) — 线性对数时间比线性慢,但比平方快,常见于高效排序算法。典型场景:快速排序、归并排序、堆排序。5、O(n²) — 平方时间执行时间与数据量的平方成正比,数据量大时性能急剧下降。典型场景:冒泡排序、选择排序、暴力搜索(如两数之和的暴力解法)。6、O(2ⁿ) — 指数时间执行时间呈指数级增长,仅适用于极小规模数据典型场景:暴力穷举、未优化的递归(如斐波那契数列原始递归)。7、O(n!) — 阶乘时间最慢的时间复杂度,通常用于全排列问题。典型场景:全排列生成。排序从最优到最差:O(1) < O(log n) < O(n) < O(n log n) < O(n^2) < O(2^n) < O(n!)。空间复杂度的表示与时间复杂度的表示基本一致。时间复杂度关注的是运行时间,空间复杂度关注的是内存消耗。现在内存比以前便宜,大家更追求时间的优化了。转载自https://www.cnblogs.com/yanshajiuzhou/p/18829902
总条数:739 到第
上滑加载中