Hippo4j线程池实现技术

文章目录

  • 🔊博主介绍
  • 🥤本文内容
    • 部署
    • 运行模式
    • 集成
    • 线程池监控配置
    • 参数默认配置
  • 📢文章总结
  • 📥博主目标

🔊博主介绍

🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文专业写手、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、🚀徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📕拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙有过从0到1的项目高并发项目开发与管理经验,对JVM调优、MySQL调优、Redis调优 、ElasticSearch调优、消息中间件调优、系统架构调优都有着比较全面的实战经验。

📘有过云端搭建服务器环境,自动化部署CI/CD,弹性伸缩扩容服务器(最高200台),了解过秒级部署(阿里云的ACK和华为云的云容器引擎CCE)流程,能独立开发和部署整个后端服务,有过分库分表的实战经验。

🎥经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧,与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!


文章目录

  • 🔊博主介绍
  • 🥤本文内容
    • 部署
    • 运行模式
    • 集成
    • 线程池监控配置
    • 参数默认配置
  • 📢文章总结
  • 📥博主目标

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🥤本文内容

CSDN

部署

使用 Docker 运行服务端,默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。

docker run -d -p 6691:6691 --name hippo4j-server \
-e DATASOURCE_MODE=mysql \
-e DATASOURCE_HOST=192.168.3.200 \
-e DATASOURCE_PORT=3306 \
-e DATASOURCE_DB=hippo4j_manager \
-e DATASOURCE_USERNAME=root \
-e DATASOURCE_PASSWORD=root \
hippo4j/hippo4j-server

访问 Server 控制台,路径 http://hadoop3:6691/index.html,默认用户名密码:admin / 123456
在这里插入图片描述

运行模式

Hippo4j 分为两种使用模式:轻量级依赖配置中心以及无中间件依赖版本。
在这里插入图片描述
Hippo4jConfig系统:它提供了极具可行性且灵活的动态线程池管理方案。利用了Nacos、Apollo、Zookeeper、ETCD、Polaris和Consul等多元化的第三方配置中心这些特性,可根据用户需求完成线程池参数的实时调整与更新,从而实现高度智能化的线程池管理功能。此外,该系统还具备实时预警及监控等独特功能,使得整个系统的稳定性得以提高并大幅提升表现效果。

Hippo4jServer服务器:在此基础上进行扩展,并采取了无需借助任何中介软件的全新发布方式,大大降低了系统依赖成本。其主要工作原理是由用户通过直观易懂的Web界面去直接操作线程池的建立、变更以及状态的浏览等任务,由此最大限度地简化了操作流程,减轻了用户负担。虽然Hippo4jServer在各项功能上都远超过Hippo4jConfig,但是在保持稳定性的同时,复杂度也相应有所增加。这就需要在服务器端额外安装一款Java程序以便运行,并且还依赖MySQL数据库作为数据存储设施。

集成

<dependency>
    <groupId>cn.hippo4j</groupId>
    <artifactId>hippo4j-config-spring-boot-starter</artifactId>
    <version>1.5.0</version>
</dependency>

请在应用程序启动类中引入注解@EnablesDynamicThreadPool以实现动态线程池功能。

@SpringBootApplication
@EnableDynamicThreadPool
public class ExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}

请参照示例项目hippo4j-config-nacos-spring-boot-starter-example进行配置调整,具体步骤包括:
1)设定Nacos服务的URL;
2)在Nacos所关联的空间和分组内创建名为hippo4j-nacos.properties的配置文件;
3)将原先在bootstrap.properties文件中的相关配置参数迁移至上述新创配置文件之中。

spring.dynamic.thread-pool.enable=true  # 启用动态线程池
spring.dynamic.thread-pool.banner=true  # 启用线程池横幅
spring.dynamic.thread-pool.check-state-interval=5  # 线程池状态检查间隔(秒)
spring.dynamic.thread-pool.monitor.enable=true  # 启用线程池监控
spring.dynamic.thread-pool.monitor.collect-types=micrometer  # 监控数据收集类型
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web  # 监控的线程池类型
spring.dynamic.thread-pool.monitor.initial-delay=10000  # 监控延迟启动时间(毫秒)
spring.dynamic.thread-pool.monitor.collect-interval=5000  # 监控数据采集间隔(毫秒)
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT  # 通知平台:微信
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff  # 微信通知的令牌
spring.dynamic.thread-pool.notify-platforms[1].platform=DING  # 通知平台:钉钉
spring.dynamic.thread-pool.notify-platforms[1].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55  # 钉钉通知的令牌
spring.dynamic.thread-pool.notify-platforms[2].platform=LARK  # 通知平台:飞书
spring.dynamic.thread-pool.notify-platforms[2].token=2cbf2808-3839-4c26-a04d-fd201dd51f9e  # 飞书通知的令牌
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume  # 线程池ID:消息消费
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume  # 线程名前缀:消息消费
spring.dynamic.thread-pool.executors[0].core-pool-size=4  # 核心线程数
spring.dynamic.thread-pool.executors[0].maximum-pool-size=6  # 最大线程数
spring.dynamic.thread-pool.executors[0].queue-capacity=512  # 队列容量
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue  # 阻塞队列类型
spring.dynamic.thread-pool.executors[0].execute-time-out=800  # 任务执行超时时间(毫秒)
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy  # 拒绝策略
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691  # 空闲线程存活时间(毫秒)
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true  # 是否允许核心线程超时销毁
spring.dynamic.thread-pool.executors[0].alarm=true  # 是否启用告警
spring.dynamic.thread-pool.executors[0].active-alarm=80  # 活跃线程告警阈值(百分比)
spring.dynamic.thread-pool.executors[0].capacity-alarm=80  # 队列容量告警阈值(百分比)
spring.dynamic.thread-pool.executors[0].notify.interval=8  # 告警通知间隔(秒)
spring.dynamic.thread-pool.executors[0].notify.receives=chen.ma  # 告警通知接收人
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce  # 线程池ID:消息生产
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce  # 线程名前缀:消息生产
spring.dynamic.thread-pool.executors[1].core-pool-size=2  # 核心线程数
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4  # 最大线程数
spring.dynamic.thread-pool.executors[1].queue-capacity=1024  # 队列容量
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue  # 阻塞队列类型
spring.dynamic.thread-pool.executors[1].execute-time-out=800  # 任务执行超时时间(毫秒)
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy  # 拒绝策略
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691  # 空闲线程存活时间(毫秒)
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true  # 是否允许核心线程超时销毁
spring.dynamic.thread-pool.executors[1].alarm=true  # 是否启用告警
spring.dynamic.thread-pool.executors[1].active-alarm=80  # 活跃线程告警阈值(百分比)
spring.dynamic.thread-pool.executors[1].capacity-alarm=80  # 队列容量告警阈值(百分比)
spring.dynamic.thread-pool.executors[1].notify.interval=8  # 告警通知间隔(秒)
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma  # 告警通知接收人

在这里插入图片描述
如果是yaml文件,SpringBoot 应用配置文件添加::

server:
  port: 8090
  servlet:
    context-path: /example
spring:
  profiles:
    active: dev
  dynamic:
    thread-pool:
      # 是否开启动态线程池
      enable: true
      # 是否打印 banner
      banner: true
      # 是否开启线程池数据采集,对接 MicrometerESLog 等
      collect: true
      # 检查线程池状态,是否达到报警条件,单位毫秒
      check-state-interval: 3000
      # 通知报警平台,请替换为自己创建的群机器人
      notify-platforms:
        - platform: 'WECHAT'
          token: xxx
        - platform: 'DING'
          token: xxx
          secret: xxx  # 加签专属
        - platform: 'LARK'
          token: xxx
      # NacosApolloZookeeperETCDPolarisConsul 任选其一
      nacos:
        data-id: xxx
        group: xxx
      apollo:
        namespace: xxxx
      # 配置中心文件格式
      config-file-type: yml
      # 支持 tomcat、undertow、jetty 三种容器线程池
      web:
        core-pool-size: 100
        maximum-pool-size: 200
        keep-alive-time: 1000
      # 全局通知配置-是否报警
      alarm: true
      # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警
      active-alarm: 80
      # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警
      capacity-alarm: 80
      # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位秒
      alarm-interval: 8
      # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID
      receives: xxx
      # 动态线程池列表
      executors:
        - thread-pool-id: 'message-consume'
          # 核心线程数
          core-pool-size: 1
          # 最大线程数
          maximum-pool-size: 1
          # 阻塞队列名称,参考 BlockingQueueTypeEnum,支持 SPI
          blocking-queue: 'LinkedBlockingQueue'
          # 阻塞队列大小
          queue-capacity: 1
          # 执行超时时间,超过此时间发起报警,单位毫秒
          execute-time-out: 1000
          # 拒绝策略名称,参考 RejectedPolicyTypeEnum,支持 SPI
          rejected-handler: 'AbortPolicy'
          # 线程存活时间,单位秒
          keep-alive-time: 1024
          # 是否允许核心线程超时
          allow-core-thread-time-out: true
          # 线程工厂名称前缀
          thread-name-prefix: 'message-consume'
          # 是否报警
          alarm: true
          # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警
          active-alarm: 80
          # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警
          capacity-alarm: 80
          # 通知配置,线程池中通知配置如果存在,则会覆盖全局通知配置
          notify:
            # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位分钟
            interval: 8
            # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID
            receives: xxx
        - thread-pool-id: 'message-produce'
          core-pool-size: 1
          maximum-pool-size: 1
          queue-capacity: 1
          execute-time-out: 1000
          blocking-queue: 'LinkedBlockingQueue'
          rejected-handler: 'AbortPolicy'
          keep-alive-time: 1024
          allow-core-thread-time-out: true
          thread-name-prefix: 'message-consume'
          alarm: true
          active-alarm: 80
          capacity-alarm: 80
          notify:
            interval: 8
            receives: xxx

在启动Hippo4j-Config-Nacos-Spring-Boot-Starter-Example工程的 ConfigNacosExampleApplication时,我们需要对Nacos配置中的hippo4j-nacos.properties文件进行一定的修改操作。如此一来,将在控制台上观察到日志输出中包含了有关线程池信息的变动信息。

根据ThreadPoolExecutor的特性,我们必须增加一个新的线程池配置类,并同时使用@DynamicThreadPool注解加以标识。其中,“threadPoolId"字段代表了服务器端所创建的线程池ID。这也是先前在配置文件中设定的参数值,即"spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume”。

个性化定制方面,Hippo4j-Config主要依赖于配置中心实现线程池配置的动态更改。然而,现阶段在这种模式下存在着一些不足之处,例如:当配置文件发生改变时,会导致所有客户端为了适应变更而重新加载数据。因此,我们希望Hippo4j-Config能够具备如同Hippo4j-Server那样,支持客户端集群个性化配置的能力,以便我们能针对单一客户端进行独立的配置变更调整。

ThreadPoolExecutor 适配
添加线程池配置类,通过 @DynamicThreadPool 注解修饰。threadPoolId 为服务端创建的线程池 ID。

import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolConfig {

    @Bean
    @DynamicThreadPool
    public ThreadPoolExecutor messageConsumeDynamicExecutor() {
        String threadPoolId = "message-consume";
        ThreadPoolExecutor messageConsumeDynamicExecutor = ThreadPoolBuilder.builder()
                .threadFactory(threadPoolId)
                .threadPoolId(threadPoolId)
                .dynamicPool()
                .build();
        return messageConsumeDynamicExecutor;
    }

    @Bean
    @DynamicThreadPool
    public ThreadPoolExecutor messageProduceDynamicExecutor() {
        String threadPoolId = "message-produce";
        ThreadPoolExecutor messageProduceDynamicExecutor = ThreadPoolBuilder.builder()
                .threadFactory(threadPoolId)
                .threadPoolId(threadPoolId)
                .dynamicPool()
                .build();
        return messageProduceDynamicExecutor;
    }

}

通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从配置中心拉取。

项目中使用上述定义的动态线程池,如下所示:

@Resource
private ThreadPoolExecutor messageConsumeDynamicExecutor;

messageConsumeDynamicExecutor.execute(() -> xxx);

@Resource
private ThreadPoolExecutor messageProduceDynamicExecutor;

messageProduceDynamicExecutor.execute(() -> xxx);

线程池监控配置

监控前置条件:需要先完成 hippo4j-config 的 接入工作。

接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。

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

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

添加动态线程池监控相关配置:

management:
  metrics:
    export:
      prometheus:
        enabled: true
  server:
    port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port}
  endpoints:
    web:
      exposure:
        include: '*' # 测试使用,开启了所有端点,生产环境不建议 *
spring:
  dynamic:
    thread-pool:
      monitor:
        enable: true # 是否开启采集线程池运行时数据
        collect-interval: 5000 # 采集线程池运行数据频率
        collect-types: micrometer # 采集线程池运行数据的类型。eg:log、micrometer。多个可以同时使用,默认 micrometer
        initial-delay: 10000 # 项目启动后延迟多久进行采集
        thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic

项目启动,访问 http://localhost:29999/actuator/prometheus 出现 dynamic_thread_pool_ 前缀的指标,即为成功。
在这里插入图片描述
配置 Prometheus
通过 Docker 启动 Prometheus 服务。

docker run -d -p 9090:9090 --name prometheus prom/prometheus

添加 Prometheus 抽取数据任务。
进入 prometheus 容器内部,编辑 prometheus 配置文件

docker exec -it prometheus /bin/sh
vi /etc/prometheus/prometheus.yml

scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,{scrape_configs.static_configs.targets} 需要写本机的 IP。

scrape_configs:
  - job_name: 'dynamic-thread-pool-job'
    scrape_interval: 5s
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: [ '127.0.0.1:29999' ]

配置成功后 exit 退出容器,并进行 Prometheus 容器重启 docker restart prometheus。

访问 Prometheus 控制台 http://localhost:9090/graph 路径,能够展示相关指标即为配置成功。
在这里插入图片描述配置 Grafana

docker run -d -p 3000:3000 --name=grafana grafana/grafana

访问 Grafana 地址,http://localhost:3000 用户名密码:admin

Grafana 访问 http://localhost:3000/datasources 导入 Prometheus 数据源。

在这里插入图片描述
如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090

参数默认配置

项目中线程池一多,配置文件中配置就显得很臃肿。为此 hippo4j-config 开发出了动态线程池默认配置。

spring:
  dynamic:
    thread-pool:
      default-executor:
        core-pool-size: 4
        maximum-pool-size: 6
        blocking-queue: ResizableCapacityLinkedBlockingQueue
        queue-capacity: 1024
        execute-time-out: 1000
        keep-alive-time: 9999
        rejected-handler: AbortPolicy
        active-alarm: 90
        capacity-alarm: 85
        alarm: true
        allow-core-thread-time-out: true
        notify:
          interval: 5
          receives: chen.ma
      executors:
        - thread-pool-id: message-produce
        - thread-pool-id: message-consume
          core-pool-size: 80
          maximum-pool-size: 100
          execute-time-out: 1000
          notify:
            interval: 6
            receives: chen.ma

CSDN

📢文章总结

对本篇文章进行总结:

🔔以上就是今天要讲的内容,阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。

以梦为马,不负韶华

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

🚀🎉希望各位读者大大多多支持用心写文章的博主,现在时代变了,🚀🎉 信息爆炸,酒香也怕巷子深🔥,博主真的需要大家的帮助才能在这片海洋中继续发光发热🎨,所以,🏃💨赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD
  • 🎉微信号二维码SeniorRD

📥博主目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本是一个很普通的程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我们必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

🔔有需要对自己进行综合性评估,进行职业方向规划,我可以让技术大牛帮你模拟面试、针对性的指导、传授面试技巧、简历优化、进行技术问题答疑等服务。

可访问:https://java_wxid.gitee.io/tojson/

开发人员简历优化、面试突击指导、技术问题解答

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Java课程选课系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

KIl5:Stm32L071下载出现flash download faild “cortex-m0+“的解决方法

首先看看有没有芯片&#xff0c;没有芯片下载一下 下载并在device选择对应的芯片 选择调试器 选择flash

gpt4.0中文版

我愿把这个网站成为全球最强AI网站&#xff01;弄100多个AI伺候你&#xff1f;&#xff1f; 家人们&#xff0c;你们猜我发现了什么牛逼的AI网站&#xff1f;&#xff1f; 直接上图&#xff1a; 编辑 这个网站&#xff0c;聚合了国内外100多个顶尖的AI&#xff0c;包括了Op…

入门用Hive构建数据仓库

在当今数据爆炸的时代&#xff0c;构建高效的数据仓库是企业实现数据驱动决策的关键。Apache Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;可以轻松地进行数据存储、查询和分析。本文将介绍什么是 Hive、为什么选择 Hive 构建数据仓库、如何搭建 Hive 环境以及如何在 Hi…

我认识的Git-史上最强的版本控制系统

大家好&#xff01; 欢迎大家来一起交流Git使用心得&#xff0c;相信很多同事对Git都很熟悉了&#xff0c;如果下面说的有错误的“知识点”&#xff0c;欢迎批评指正。 初识Git 我认识Git已经很多年了&#xff08;我在有道云笔记里面“Git”文件夹的创建时间是&#xff1a; …

sky06笔记下

1.边沿检测 检测输入信号din的上升沿&#xff0c;并输出pulse module edge_check ( clk, rstn, din, pulse ); input wire clk,rstn; input wire din; output reg pulse;wire din_dly;always (posedge clk or negedge rstn)beginif(!rstn)din_dly < 1b0;elsedin_dly < d…

JS-11A/11时间继电器 板前接线 JOSEF约瑟

系列型号&#xff1a; JS-11A/11集成电路时间继电器&#xff1b;JS-11A/12集成电路时间继电器&#xff1b; JS-11A/13集成电路时间继电器&#xff1b;JS-11A/136集成电路时间继电器&#xff1b; JS-11A/137集成电路时间继电器&#xff1b;JS-11A/22集成电路时间继电器&#…

【C语言】_文件内容操作:随机读写

目录 1. fseek 1.1 随机读文件 1.2 随机写文件 2. ftell 3. rewind 当以读方式打开一个存在且存有内容的文件时&#xff0c;文件指针会默认指向第一个元素。以在test4.txt文件中存储abcdef为例&#xff1a; int main() {//打开文件FILE* pf fopen("E:\\C_文件操作…

数学知识--(质数,约数)

本文用于个人算法竞赛学习&#xff0c;仅供参考 目录 一.质数的判定 二.分解质因数 三.质数筛 1.朴素筛法 2.埃氏筛法 3.线性筛法 四.约数 1.求一个数的所有约数 2.约数个数和约数之和 3.欧几里得算法&#xff08;辗转相除法&#xff09;-- 求最大公约数 一.质数的判定 …

JWT--study

JWT 1、简介 2、结构 头部 载荷 签证 应用 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>Token 生成 解析token package com.wang.utils;import io.…

【QT+QGIS跨平台编译】056:【pdal_lepcc+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、pdal_lepcc介绍二、pdal下载三、文件分析四、pro文件五、编译实践一、pdal_lepcc介绍 pdal_lepcc 是 PDAL(Point Data Abstraction Library)的一个插件,用于点云数据的压缩。它基于 EPCC(Entwine Point Cloud Compression)算法,提供了对点…

Linux-4 gcc和makefile

Linux编译器-gcc/g使用 1.设计样例 c语言&#xff1a;linux中用的stdc99版本--可能会出现其他问题 c&#xff1a;Linux中用的stdc11--使用c11版本 Linux没有文件格式的区分&#xff0c;但是编译器区分 gcc编译器的文件格式是filename.c g编译器的文件格式是filename.cc或者fil…

利用Spark将Kafka数据流写入HDFS

利用Spark将Kafka数据流写入HDFS 在当今的大数据时代&#xff0c;实时数据处理和分析变得越来越重要。Apache Kafka作为一个分布式流处理平台&#xff0c;已经成为处理实时数据的事实标准。而Apache Spark则是一个强大的大数据处理框架&#xff0c;它提供了对数据进行复杂处理…

可行性研究报告模板(套用)

1业务需求可行性分析 2技术可行性分析 2.1规范化原则 2.2高度的兼容性和可移植性 2.3人性化、适用性 2.4标准化统一设计原则 2.5先进安全可扩展性原则 3开发周期可行性分析 4人力资源可行性分析 5成本分析 6收益分析 7结论 所有资料获取进主页或本文末个人名片直接…

【OSTEP】并发:线程与多线程

" A flow of control within a process that consists of a PC, a register set and a stack space" 本章将介绍为单个运行进程提供的新抽象 —— 线程 (thread) 线程是 调度的一个基本单位&#xff08;basic unit of CPU scheduling&#xff09;一个单独的线程至…

RUST语言函数的定义与调用

1.定义函数 定义一个RUST函数使用fn关键字 函数定义语法: fn 函数名(参数名:参数类型,参数名:参数类型) -> 返回类型 { //函数体 } 定义一个没有参数,没有返回类型的参数 fn add() {println!("调用了add函数!"); } 定义有一个参数的函数 fn add(a:u32)…

力扣热题100_链表_21_合并两个有序链表

文章目录 题目链接解题思路解题代码 题目链接 21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例…

InternLM2-lesson2作业

书生浦语大模型趣味 Demo 视频连接&#xff1a;https://www.bilibili.com/video/BV1AH4y1H78d/?vd_source902e3124d4683c41b103f1d1322401fa 目录 书生浦语大模型趣味 Demo一、基础作业二、进阶作业 一、基础作业 第一次执行&#xff1a; 第二次执行&#xff1a; 第一次执…

uni-app 实现仿微信界面【我的+首页聊天列表+长按菜单功能+添加菜单功能】+ 附源码

目录 【微信首页聊天列表】界面 【我的】界面 源代码&#xff1a; 文后附完整代码&#xff0c;支持一键导入 HBuilderX 示例体验 【微信首页聊天列表】界面 仿造【微信首页聊天列表 长按菜单功能 右上角添加按钮弹窗功能】&#xff0c;使用 uni-app 开发&#xff0c; 一…

蓝桥杯真题:路径

import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {int n 2022; //从下标为1开始&#xff0c;方便计算int[] q new int[n]; //存储最短路q[1] 0; //起始条件for (int i 2; i < 202…