AI大模型编写多线程并发框架(六十三):监听器优化·上

news2024/9/28 0:40:31

系列文章目录


文章目录

  • 系列文章目录
  • 前言
    • 一、项目背景
    • 二、第七轮对话-补充异步执行代码
    • 三、第八轮对话-增加累计完成等字眼
    • 四、第九轮对话-线程安全优化
    • 五、第十轮对话-增加运行时数据
    • 七、参考文章


前言

在这个充满技术创新的时代,AI大模型正成为开发者们的新宠。它们可以帮助我们完成从简单的问答到复杂的编程任务,所以AI编程将会是未来的主流方向,利用AI大模型的能力,本文将介绍从零到一用AI大模型编写一个多线程并发框架。

一、项目背景

经过上两篇文章和AI的对话,我们基本捣鼓出来了多线程并发框架的雏形,接下来是比较重要的监控模块,本文将会通过比较长的篇幅来叙述。

本多线程框架使用示例如下:源码地址
1、引入依赖。

<dependency>
    <groupId>io.github.vipjoey</groupId>
    <artifactId>mmc-juc</artifactId>
    <version>1.0</version>
</dependency>

2、使用示例。


// 创建一个MmcTaskExecutor实例,用于执行单次长耗时任务
// 下面是创建一个计算从1加到100的任务,总共100个任务,采用fork分治算法,阈值为10,总共任务为100 / 10 * 2 = 20个大任务,执行速率约为10/s
MmcTaskExecutor<Integer, Integer> mmcTaskExecutor = MmcTaskExecutor.<Integer, Integer>builder()
        .taskSource(IntStream.rangeClosed(1, 100).boxed().collect(Collectors.toList())) // 设置任务源
        .taskProcessor(x -> x.stream().reduce(0, Integer::sum)) // 设置任务处理方法
        .taskMerger(Integer::sum) // 设置结果处理方法(可选)
        .threshold(10) // 设置任务处理阈值(可选)
        .taskName("mmcTaskExample") // 设置任务名称
        .rateLimiter(10, 20)  // 设置速率限制,容量为10,每秒产生令牌为20,休眠时间为10ms
        .forkJoinPoolConcurrency(4) // 设置ForkJoinPool的并发度为4
        .build();

// 同步执行并打印结果        
System.out.println("result: " + mmcTaskExecutor.execute());

// 任务执行过程监控
[mmcTaskExample] Tasks submitted. Total tasks: 100
[mmcTaskExample] Task started. Completed tasks: 14, remaining tasks: 86
[mmcTaskExample] Task started. Completed tasks: 14, remaining tasks: 86
[mmcTaskExample] Task started. Completed tasks: 20, remaining tasks: 80
[mmcTaskExample] Task started. Completed tasks: 26, remaining tasks: 74
[mmcTaskExample] Task started. Completed tasks: 33, remaining tasks: 67
[mmcTaskExample] Task started. Completed tasks: 40, remaining tasks: 60
[mmcTaskExample] Task started. Completed tasks: 46, remaining tasks: 54
[mmcTaskExample] Task started. Completed tasks: 52, remaining tasks: 48
[mmcTaskExample] Task started. Completed tasks: 58, remaining tasks: 42
[mmcTaskExample] Task started. Completed tasks: 64, remaining tasks: 36
[mmcTaskExample] Task started. Completed tasks: 70, remaining tasks: 30
[mmcTaskExample] Task started. Completed tasks: 76, remaining tasks: 24
[mmcTaskExample] Task started. Completed tasks: 82, remaining tasks: 18
[mmcTaskExample] Task started. Completed tasks: 88, remaining tasks: 12
[mmcTaskExample] Task started. Completed tasks: 94, remaining tasks: 6
[mmcTaskExample] Task started. Completed tasks: 100, remaining tasks: 0
[mmcTaskExample] Tasks completed. Elapsed time: 1107 ms 
result: 5050

二、第七轮对话-补充异步执行代码

1、参考限流器的对话,我们知道AI是不会主动帮忙抽象公共接口的,所以这里我们干脆要求AI给我们定义好监听器接口,方便后续扩展。
在这里插入图片描述

2、下面是AI给的回复。

  • 【为了实现监听器功能,我们首先需要创建一个监听器接口MmcTaskListener,然后在MmcTaskExecutor类中使用它。我们还将提供一个默认实现DefaultMmcTaskListener,并允许用户通过Builder类替换监听器。首先,我们创建一个MmcTaskListener接口。】
public interface MmcTaskListener {
    void onTaskStarted(int totalTasks, int remainingTasks);

    void onTaskCompleted(int totalTasks, int remainingTasks, long elapsedTime);
}
  • 【接下来,我们创建一个默认的监听器实现DefaultMmcTaskListener。】
public class DefaultMmcTaskListener implements MmcTaskListener {
    @Override
    public void onTaskStarted(int totalTasks, int remainingTasks) {
        System.out.println("Task started. Total tasks: " + totalTasks + ", remaining tasks: " + remainingTasks);
    }

    @Override
    public void onTaskCompleted(int totalTasks, int remainingTasks, long elapsedTime) {
        System.out.println("Task completed. Total tasks: " + totalTasks + ", remaining tasks: " + remainingTasks + ", elapsed time: " + elapsedTime + " ms");
    }
}
  • 【然后,我们修改MmcTaskExecutor类以使用MmcTaskListener接口。】
import java.util.List;
import java.util.concurrent.ForkJoinPool;

public class MmcTaskExecutor<T, R> {
    // ...省略其他成员变量
    private MmcTaskListener taskListener;

    private MmcTaskExecutor(Builder<T, R> builder) {
        // ...省略其他初始化代码
        this.taskListener = builder.taskListener;
    }

    // ...省略其他方法

    public static class Builder<T, R> {
        // ...省略其他成员变量
        private MmcTaskListener taskListener = new DefaultMmcTaskListener(); // 默认使用DefaultMmcTaskListener

        // ...省略其他方法

        public Builder<T, R> taskListener(MmcTaskListener taskListener) {
            this.taskListener = taskListener;
            return this;
        }

        // ...省略其他方法
    }
}
  • 【最后,我们需要修改MmcTask类以调用监听器的方法。】
import java.util.List;
import java.util.concurrent.RecursiveTask;

public class MmcTask<T, R> extends RecursiveTask<R> {
    // ...省略其他成员变量
    private MmcTaskListener taskListener;

    public MmcTask(List<T> taskSource, MmcTaskProcessor<T, R> taskProcessor, MmcTaskMerger<R> taskMerger, int threshold, int start, int end, RateLimiter rateLimiter, MmcTaskListener taskListener) {
        // ...省略其他初始化代码
        this.taskListener = taskListener;
    }

    @Override
    protected R compute() {
        // ...省略其他代码

        // 在处理任务之前调用onTaskStarted方法
        taskListener.onTaskStarted(taskSource.size(), end - start);

        // ...省略其他代码

        // 在任务完成后调用onTaskCompleted方法
        long elapsedTime = System.currentTimeMillis() - startTime;
        taskListener.onTaskCompleted(taskSource.size(), end - start - 1, elapsedTime);

        // ...省略其他代码
    }
}

本轮AI的回复有些欠缺,它并没有GET到我的诉求,可能跟我的提问方式有关。实际上我需要监控的是TaskSource集合被执行完成的进度,AI只是监控了compute方法,也就是监控每个阈值下的小任务的执行,这明显是错的。

三、第八轮对话-增加累计完成等字眼

1、由于上一轮对话,可能是提问方式不对,我重新增加【首次】、【累计】这些字眼,希望AI能理解我的意思。
在这里插入图片描述

2、下面是AI大模型给的回复。

  • 【为了满足您的要求,我们需要修改MmcTaskListener接口以添加新的事件方法,然后修改DefaultMmcTaskListener以实现这些方法。接下来,我们将在MmcTaskExecutor类和MmcTask类中调用这些方法。首先,我们修改MmcTaskListener接口以添加新的事件方法。】
public interface MmcTaskListener {
    void onTasksSubmitted(int totalTasks, long startTime);

    void onTaskStarted(int completedTasks, int remainingTasks);

    void onTasksCompleted(long elapsedTime, long endTime);
}
  • 【接下来,我们修改DefaultMmcTaskListener以实现新的事件方法。】
public class DefaultMmcTaskListener implements MmcTaskListener {
    @Override
    public void onTasksSubmitted(int totalTasks, long startTime) {
        System.out.println("Tasks submitted. Total tasks: " + totalTasks + ", start time: " + startTime);
    }

    @Override
    public void onTaskStarted(int completedTasks, int remainingTasks) {
        System.out.println("Task started. Completed tasks: " + completedTasks + ", remaining tasks: " + remainingTasks);
    }

    @Override
    public void onTasksCompleted(long elapsedTime, long endTime) {
        System.out.println("Tasks completed. Elapsed time: " + elapsedTime + " ms, end time: " + endTime);
    }
}
  • 【然后,我们需要修改MmcTaskExecutor类以调用onTasksSubmitted和onTasksCompleted方法。】
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicInteger;

public class MmcTaskExecutor<T, R> {
    // ...省略其他成员变量和方法
    private AtomicInteger completedTasks = new AtomicInteger(); // 添加一个原子整数以跟踪已完成的任务数量

    // 同步执行并返回结果
    public R execute() {
        MmcTask<T, R> mmcTask = new MmcTask<>(taskSource, taskProcessor, taskMerger, threshold, 0, taskSource.size(), rateLimiter, taskListener, completedTasks);

        // 调用onTasksSubmitted方法
        taskListener.onTasksSubmitted(taskSource.size(), System.currentTimeMillis());

        R result = forkJoinPool.invoke(mmcTask);

        // 调用onTasksCompleted方法
        taskListener.onTasksCompleted(mmcTask.getElapsedTime(), System.currentTimeMillis());

        return result;
    }

    // ...省略其他方法
}
  • 【最后,我们需要修改MmcTask类以调用onTaskStarted方法。】
import java.util.List;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.atomic.AtomicInteger;

public class MmcTask<T, R> extends RecursiveTask<R> {
    // ...省略其他成员变量和方法
    private AtomicInteger completedTasks;

    public MmcTask(List<T> taskSource, MmcTaskProcessor<T, R> taskProcessor, MmcTaskMerger<R> taskMerger, int threshold, int start, int end, RateLimiter rateLimiter, MmcTaskListener taskListener, AtomicInteger completedTasks) {
        // ...省略其他初始化代码
        this.completedTasks = completedTasks;
    }

    @Override
    protected R compute() {
        // 在处理任务之前调用onTaskStarted方法
        taskListener.onTaskStarted(completedTasks.get(), end - start);

        // ...省略其他代码

        // 在任务完成后更新已完成任务的计数
        completedTasks.incrementAndGet();

        // ...省略其他代码
    }
}

从本次AI大模型的回复来看,存在以下问题:

  • 它似乎不理解任务拆分前后计数的区别,实际上后续我尝试了N种问法,它都不理解,它理解的任务累计完成个数就是completedTasks.incrementAndGet();而不是我想要的taskRuntime.getCompletedTasks().addAndGet(end - start);
  • 它不会主动发现线程安全问题,这个跟我们提问的要求有关,毕竟是生成式AI,所以它不会考虑任务提交时需要重置AtomicInteger。
  • 同理,它的剩余任务个数的计算方式也是错误的,它的答案是end - start,而不是我想要的taskSource.size() - 累计完成任务个数

不过,这些都是小问题,不用太纠结,我们继续提诉求去优化。

四、第九轮对话-线程安全优化

1、从AI大模型给出的代码来看,是没有考虑线程安全问题的,我们需要补充一下诉求:
在这里插入图片描述

2、下面是AI的回复。

  • 【为了满足您的要求,我们将对MmcTaskExecutor类进行修改以确保线程安全,并在每次提交任务时重置计数器。我们将使用原子整数AtomicInteger来实现线程安全的计数器。首先,我们将修改MmcTaskExecutor类以添加一个原子整数completedTasks以跟踪已完成的任务数量。我们还将在每次执行任务时重置completedTasks。】
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicInteger;

public class MmcTaskExecutor<T, R> {
    // ...省略其他成员变量和方法
    private AtomicInteger completedTasks = new AtomicInteger(); // 添加一个原子整数以跟踪已完成的任务数量

    // 同步执行并返回结果
    public R execute() {
        completedTasks.set(0); // 重置已完成任务的计数器

        MmcTask<T, R> mmcTask = new MmcTask<>(taskSource, taskProcessor, taskMerger, threshold, 0, taskSource.size(), rateLimiter, taskListener, completedTasks);

        // 调用onTasksSubmitted方法
        taskListener.onTasksSubmitted(taskSource.size(), System.currentTimeMillis());

        R result = forkJoinPool.invoke(mmcTask);

        // 调用onTasksCompleted方法
        taskListener.onTasksCompleted(mmcTask.getElapsedTime(), System.currentTimeMillis());

        return result;
    }

    // ...省略其他方法
}
  • 【接下来,我们将修改MmcTask类以确保线程安全并调用监听器的方法。】
import java.util.List;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.atomic.AtomicInteger;

public class MmcTask<T, R> extends RecursiveTask<R> {
    // ...省略其他成员变量和方法
    private AtomicInteger completedTasks;

    public MmcTask(List<T> taskSource, MmcTaskProcessor<T, R> taskProcessor, MmcTaskMerger<R> taskMerger, int threshold, int start, int end, RateLimiter rateLimiter, MmcTaskListener taskListener, AtomicInteger completedTasks) {
        // ...省略其他初始化代码
        this.completedTasks = completedTasks;
    }

    @Override
    protected R compute() {
        // 在处理任务之前调用onTaskStarted方法
        taskListener.onTaskStarted(completedTasks.get(), end - start);

        // ...省略其他代码

        // 在任务完成后更新已完成任务的计数
        int completed = completedTasks.incrementAndGet();

        // 调用onTaskStarted方法,以便在每个小任务完成时更新已完成任务的计数
        taskListener.onTaskStarted(completed, end - start - completed);

        // ...省略其他代码
    }
}

这次AI大模型的回复也是不尽人意,如果多个MmcTask任务同时执行的话,计数器是不准确的,我们继续耐心优化一下我们的提示词。

五、第十轮对话-增加运行时数据

1、由于我们设计的初衷,任务可以多次提交的。所以每个任务运行时应该产生运行时数据,我们监控的也是运行时数据,运行时数据需要一个唯一标识,也就是任务名称来与之关联。另外,由于MmcTask的构造函数过长,我在其它对话中让它优化过了,这里就不详细讲述。
在这里插入图片描述

2、以下是AI的回复。

  • 【为了满足您的要求,我们可以创建一个新的类TaskRuntime,它将包含任务名称、任务源总数、已完成任务数和剩余任务数等信息。然后,我们将修改MmcTask和MmcTaskListener以使用TaskRuntime。首先,我们创建一个新的类TaskRuntime。】
public class TaskRuntime {
    private String taskName;
    private int totalTasks;
    private AtomicInteger completedTasks;
    private AtomicInteger remainingTasks;

    public TaskRuntime(String taskName, int totalTasks) {
        this.taskName = taskName;
        this.totalTasks = totalTasks;
        this.completedTasks = new AtomicInteger();
        this.remainingTasks = new AtomicInteger(totalTasks);
    }

    // ...省略getter和setter方法
}
  • 【接下来,我们修改MmcTaskListener接口以使用TaskRuntime。】
public interface MmcTaskListener {
    void onTasksSubmitted(TaskRuntime taskRuntime, long startTime);

    void onTaskStarted(TaskRuntime taskRuntime);

    void onTasksCompleted(TaskRuntime taskRuntime, long elapsedTime, long endTime);
}
  • 【然后,我们修改MmcTask以使用TaskRuntime。】
import java.util.List;
import java.util.concurrent.RecursiveTask;

public class MmcTask<T, R> extends RecursiveTask<R> {
    // ...省略其他成员变量和方法
    private TaskRuntime taskRuntime;

    public MmcTask(Builder<T, R> builder) {
        // ...省略其他初始化代码
        this.taskRuntime = new TaskRuntime(builder.taskName, builder.taskSource.size());
    }

    @Override
    protected R compute() {
        // 在处理任务之前调用onTaskStarted方法
        taskListener.onTaskStarted(taskRuntime);

        // ...省略其他代码

        // 在任务完成后更新已完成任务的计数
        taskRuntime.getCompletedTasks().incrementAndGet();
        taskRuntime.getRemainingTasks().decrementAndGet();

        // ...省略其他代码
    }
}
  • 【最后,我们修改MmcTaskExecutor类以使用TaskRuntime。】
import java.util.List;
import java.util.concurrent.ForkJoinPool;

public class MmcTaskExecutor<T, R> {
    // ...省略其他成员变量和方法

    // 提交新任务
    public R submitTask(MmcTask<T, R> mmcTask) {
        // 调用onTasksSubmitted方法
        taskListener.onTasksSubmitted(mmcTask.getTaskRuntime(), System.currentTimeMillis());

        R result = forkJoinPool.invoke(mmcTask);

        // 调用onTasksCompleted方法
        taskListener.onTasksCompleted(mmcTask.getTaskRuntime(), mmcTask.getElapsedTime(), System.currentTimeMillis());

        return result;
    }

    // 同步执行并返回结果
    public R execute() {
        MmcTask<T, R> mmcTask = new MmcTask.Builder<T, R>()
                // ...省略其他方法调用
                .build();

        return submitTask(mmcTask);
    }
}

这轮AI的回答还是有问题,例如下面:

    public MmcTask(Builder<T, R> builder) {
        // ...省略其他初始化代码
        this.taskRuntime = new TaskRuntime(builder.taskName, builder.taskSource.size());
    }

它在MmcTask来初始化运行时数据,这明显是不对的,继续让它修改。下一篇,继续优化监听器 - -

七、参考文章

  • 《AI大模型编写多线程并发框架(六十一):从零开始搭建框架》
  • 《AI大模型编写多线程并发框架(六十二):限流和并发度优化》
  • 《AI大模型编写多线程并发框架(六十三):监听器优化·上》
  • 《AI大模型编写多线程并发框架(六十四):监听器优化·下》
  • 《AI大模型编写多线程并发框架(六十五):发布和应用》

加我加群(备注csdn)一起交流学习!更多干货下载、项目源码和大厂内推等着你

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

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

相关文章

SpringBoot+Vue的图书管理系统【包含运行步骤】

SpringBootVue图书管理系统 一、项目介绍1. 图书信息管理2. 图书类型管理3. 图书借阅管理4. 用户管理 二、技术选型后端技术选型前端技术选型 三、运行步骤后端启动前端启动 四、项目演示源码获取方式 五、总结与展望 大家好&#xff0c;这里是程序猿代码之路&#xff01;随着信…

Linux基础1-基本指令7(其他常用指令,shell简介)

目录 1.uname 2.常用小指令 3.查看系统信息的其他指令 4.shell命令及其原理 4.1这里我们简单了解一下shell 4.2 shell存在的意义&#xff1f; 1.uname 如何查看计算机体系架构&#xff1f; uname -a,查看详细信息 uname -r 查看简要信息 2.常用小指令 TAB&#x…

Socket编程---UDP篇

目录 一. UDP协议 二. Socket编程 2.1 sockaddr家族 2.2 接口介绍 三. 服务端实现 四. 服务端调用实现 五. 客户端实现 六. 效果展示 一. UDP协议 何为UDP协议的含义&#xff0c;上篇粗略提及了一下TCP与UDP的区别&#xff1a; TCP&#xff1a; •…

将军百战死,程序十年成

将军百战死&#xff0c;程序十年成 十年前的 2014.8.3 我释出了动词算子式通用代码生成器的第一个完整版本 InfinityGPGenerator 0.6.5&#xff0c;即无垠式通用代码生成器 0.6.5。这是一个重大的里程碑。十年后&#xff0c;通用代码生成器已经是一个大家族。昨天&#xff0c;…

插入排序的动画展示与实现

排序学习思路&#xff1a;先实现单趟逻辑&#xff0c;在实现整体逻辑&#xff1b;先解决普遍情况&#xff0c;再解决特殊情况。 什么是插入排序 回忆下自己玩扑克牌的时候是怎么把手上的牌理顺的吧&#xff01;其实那就是插入排序&#xff0c;从左边往右边&#xff0c;把一张张…

强烈推荐!大模型辅助软件开发

图书推荐 作者介绍 很喜欢作者在书上的这句话了&#xff1a;是人类工程师的能力&#xff0c;而不是大模型的能力&#xff0c;决定了大模型协作式开发的上限。 本书内容 软件开发正在经历一场前所未有的范式变革。人工智能的飞速发展&#xff0c;特别是大型语言模型所取得的成…

【Python篇】Python 类和对象:详细讲解(上篇)

文章目录 Python 类和对象&#xff1a;详细讲解1. 什么是类&#xff08;Class&#xff09;类的定义 2. 什么是对象&#xff08;Object&#xff09;创建对象 3. 属性和方法属性&#xff08;Attributes&#xff09;方法&#xff08;Methods&#xff09;在类中定义属性和方法使用对…

使用facebook开源prophet模型预测上证指数etf股价

可以图个乐&#xff0c;没有那么准确&#xff0c;可能还需要更深入的研究分析 蓝线是预测的2024年的走势&#xff0c;绿线是实际走势&#xff0c;红线是历史和未来的分界线。结果上有蛮多差异的。 # 测试预测2024年 coded by luke 伊玛目的门徒 import akshare as ak impor…

基于Java的心灵治愈交流平台

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java语言&#xff1b;Spring Boot框架 工具&#xff1a;IDEA/Eclipse、Navicat 系统展示 首页 心…

美畅物联丨实时通信新篇章:Spring Boot与WebSocket的深度融合实践

在当今 Web 应用开发领域&#xff0c;实时通信功能已跃升为不可或缺的基石&#xff0c;特别是在即时消息传递、沉浸式在线游戏体验以及精准实时数据监控等关键领域。WebSocket协议&#xff0c;凭借其独特的全双工通讯机制&#xff0c;在单个持久连接上实现了服务器与客户端之间…

软件测试面试题「值得收藏」

1、B/S架构和C/S架构区别&#xff1f; 1、架构不同&#xff1a;B/S架构是浏览器/服务器架构&#xff0c;C/S架构是客户端/服务器架构。 2、客户端不同&#xff1a;B/S架构的客户端是浏览器&#xff0c;C/S架构的客户端是客户端程序。 3、功能不同&#xff1a;B/S架构主要用于…

PhpStorm2024版设置自动换行(软换行)

Settings > Editor > General > Soft Wraps 选中并加上对应的文件

链动2+1小程序定制开发在餐饮品牌重塑中的应用探索——以“妈妈饺子馆”为例

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;餐饮业正经历着前所未有的变革。传统餐饮企业如何在激烈的市场竞争中脱颖而出&#xff0c;成为行业关注的焦点。本文以“妈妈饺子馆”为例&#xff0c;探讨链动21小程序定制开发在餐饮品牌重塑中的应用&#xff0c;特别是…

8 大模型微调

大部分接触大模型的同学大家可能都受限于资源的限制&#xff0c;无法对大模型重新训练。那么如何解决这一困境&#xff1f;我们暂且假定大模型为通用化模型&#xff0c;但是在某一方面的专业领域知识却不强&#xff0c;如果使用专业领域知识重新训练调整&#xff0c;这对资源还…

如何选到好的宠物空气净化器?有没有推荐的品牌?

从最初的手忙脚乱、对宠物养护知识一无所知的新手小白&#xff0c;到如今能够游刃有余地处理各种宠物问题、养宠多年的资深铲屎官&#xff0c;这么久&#xff0c;我也积累了不少的经验&#xff0c;就是希望能为自家的毛孩子提供最健康、最适合的生活。 这么久的养猫历程遇见的…

tcp/udp 可视化 调试工具; tcp/udp 发送客户端;查看tcp连接;netassist;packet sender;tcp view;

前言 最近对接物联设备&#xff0c;物联设备会往java端传送数据&#xff0c;在联调前&#xff0c;问厂商要来了样例数据&#xff0c;然后就找到了netassist和packetsender两款tcp发送工具&#xff0c;来模拟请求&#xff1b;还用tcpview来查看建立的连接。 netassist netass…

BERT:Pre-training of Deep Bidirectional Transformers forLanguage Understanding

个人觉着BERT是一篇读起来很爽的论文 摘要 我们引入了一种新的语言表示模型BERT&#xff0c;它代表Bidirectional Encoder Representations from Transformers。与最近的语言表示模型不同(Peters et al.&#xff0c; 2018a;Radford et al.&#xff0c; 2018)&#xff0c; BER…

52.x86游戏实战-XXX获取房间坐标

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

【Docker】个人笔记

文章目录 Docker三个基本概念镜像(Image)容器(Container)仓库(Repository) Docker命令基础命令查看版本信息显示详细信息从仓库拉取镜像列出本地存储的镜像删除一个或多个镜像列出所有运行中的容器运行一个新的容器停止一个运行中的容器启动一个已停止的容器重启一个容器删除一…

论文泛读: DETRs Beat YOLOs on Real-time Object Detection

[toc[ DETRs Beat YOLOs on Real-time Object Detection 论文地址: https://openaccess.thecvf.com/content/CVPR2024/html/Zhao_DETRs_Beat_YOLOs_on_Real-time_Object_Detection_CVPR_2024_paper.html 代码地址: https://zhao-yian.github.io/RTDETR 动机 现状 YOLO系列因…