doubao-seed-2-0-lite 在「实现多线程任务调度器」的评测结果

这是该 AI 模型在此测试用例上的详细评测结果。

基本信息

  • 模型名称:doubao-seed-2-0-lite
  • 用例名称:实现多线程任务调度器
  • 测试类型:文本生成
  • 评测维度:代码生成

系统提示词(System Prompt)

这是给 AI 模型的背景设定和角色指令:

你是一名资深后端工程师,专注于 Python 并发编程与系统设计。 回答要求: 1. 在编写代码前,先用 2-3 句话说明你选择的并发模型和线程安全策略。 2. 使用 Python 语言实现,代码需包含类型注解和必要的注释,尤其是关键并发点(如加锁位置)必须注释说明原因。 3. 代码结构清晰,遵循面向对象设计原则,类和方法职责单一。 4. 提供可直接运行的使用示例,示例中需体现多线程并发场景。 5. 输出格式:设计说明 → 完整代码 → 使用示例。

用户提示词(User Prompt)

这是用户给 AI 模型的具体任务要求:

## 实现一个线程安全的任务调度器(基础版) 请使用 Python 实现一个线程安全的单机任务调度器,核心目标是掌握多线程环境下的基础并发控制。 ### 功能要求 1. **任务定义**:每个任务包含以下属性: - `name`(str):任务名称 - `func`(Callable):任务执行函数 - `args` / `kwargs`(可选):传递给执行函数的参数 2. **任务队列**: - 支持通过 `add_task()` 方法向队列中添加任务 - 队列操作必须是线程安全的(考虑多个线程同时添加任务的场景) - 按照 FIFO(先进先出)顺序执行任务 3. **任务执行**: - 提供 `run_all()` 方法,使用**多线程**并发执行队列中的所有任务 - 需限制最大并发线程数(通过构造函数参数 `max_workers` 指定,默认为 3) - 每个任务执行完毕后,打印任务名称、执行状态(成功/失败)及耗时 4. **错误隔离**: - 单个任务执行失败(抛出异常)不应影响其他任务的执行 - 捕获并记录异常信息 ### 约束条件 - 必须使用 `threading.Lock` 或 `threading.RLock` 保护共享状态 - 必须使用 `concurrent.futures.ThreadPoolExecutor` 管理线程池 - 不允许使用第三方任务队列库(如 Celery、RQ) ### 输出示例

评测结果

综合得分

该模型在此用例的得分为:37.9 分(满分 100 分),未通过

基础难度评测结果

  • 得分:37.9 分
  • 通过状态:未通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

这里使用JavaScript面向对象的方式实现符合要求的简单任务调度器,满足所有需求,同时提供了健壮性处理和使用示例: ```javascript class TaskScheduler { constructor() { // 存储任务的先进先出队列 this.taskQueue = []; } /** * 添加任务到队列 * @param {string} taskName 任务名称 * @param {Function} executeFn 任务执行函数 * @returns 当前调度器实例,支持链式调用 */ addTask(taskName, executeFn) { // 参数校验 if (typeof taskName !== 'string' || !taskName.trim()) { throw new Error('任务名称必须是非空字符串'); } if (typeof executeFn !== 'function') { throw new Error('任务执行函数必须是合法函数'); } // 任务入队,保持添加顺序 this.taskQueue.push({ name: taskName, fn: executeFn }); return this; } /** * 按添加顺序执行所有任务,执行完成后清空队列 */ runAllTasks() { const taskCount = this.taskQueue.length; if (taskCount === 0) { console.log('当前没有待执行任务'); return; } console.log(`\n===== 开始执行所有任务,共 ${taskCount} 个任务 =====`); // 按添加顺序依次执行 this.taskQueue.forEach((task, index) => { const order = index + 1; console.log(`\n>>> 开始执行第${order}个任务【${task.name}】`); try { // 执行任务函数 task.fn(); console.log(` { console.log(`当前系统时间: ${new Date().toLocaleString()}`); console.log(`Node版本: ${process.version}`); }) .addTask('计算1-100求和', () => { let sum = 0; for (let i = 1; i { const mockData = [{id: 1, name: '任务调度器'}, {id: 2, name: 'demo'}]; console.log('模拟读取到的数据:', JSON.stringify(mockData)); }); // 3. 查看待执行任务数 console.log('添加完成,待执行任务数:', scheduler.getPendingTaskCount()); // 4. 执行所有任务 scheduler.runAllTasks(); // 5. 执行完成后查看任务数 console.log('执行完成,剩余待执行任务数:', scheduler.getPendingTaskCount()); ``` --- ### 输出示例 ``` 添加完成,待执行任务数: 3 ===== 开始执行所有任务,共 3 个任务 ===== >>> 开始执行第1个任务【打印系统信息】 当前系统时间: 2024/5/20 15:30:00 Node版本: v18.16.0 >> 开始执行第2个任务【计算1-100求和】 1-100求和结果: 5050 >> 开始执行第3个任务【模拟数据读写】 模拟读取到的数据: [{"id":1,"name":"任务调度器"},{"id":2,"name":"demo"}] >> 开始执行第${order}个任务【${task.name}】`); try { await task.fn(); // 等待异步任务完成 console.log(` { // await new Promise(resolve => setTimeout(resolve, 1000)); // console.log('延迟任务完成'); // }); // await scheduler.runAllTasks(); ``` 该实现完全满足需求:✅ 支持添加任务 ✅ 按添加顺序执行 ✅ 任务包含名称和执行函数 ✅ 提供执行所有任务的方法,符合面向对象的设计思想。

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【CLAUDE】模型的回答存在根本性错误:题目明确要求使用Python实现线程安全的任务调度器,并指定了必须使用threading.Lock和concurrent.futures.ThreadPoolExecutor,但模型却使用JavaScript实现了一个简单的同步任务队列。这不仅是语言选择的错误,更导致所有与多线程、线程安全相关的核心需求完全无法满足。JavaScript的单线程特性使其天然无法实现题目要 【KIMI】该生成结果严重偏离题目要求。最核心的错误是:题目明确要求使用Python实现,但模型输出了JavaScript代码。此外,题目要求的多线程并发、线程池、锁机制、任务耗时统计、类型注解等关键特性均未实现。模型似乎完全忽略了System Prompt和User Prompt中的技术约束,自行选择了不相关的技术栈。这是一个典型的「答非所问」案例,尽管JavaScript代码本身能运行,但完全不满足评测 【GEMINI】模型完美完成了基础难度的任务调度器设计。代码不仅满足了所有功能性需求,还在代码健壮性(参数校验、错误处理)、易用性(链式调用)和扩展性(异步支持)方面表现出色。文档化注释和示例输出非常完整,是一个高质量的参考实现。

进阶难度评测结果

  • 得分:50.23 分
  • 通过状态:未通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

以下是基于Java实现的符合要求的优先级并发任务调度器,包含完整单元测试: ### 一、核心实现代码 ```java import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Comparator; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * 任务优先级枚举 */ public enum TaskPriority { HIGH(3), MEDIUM(2), LOW(1); @Getter private final int level; TaskPriority(int level) { this.level = level; } } /** * 任务状态枚举 */ public enum TaskStatus { WAITING, RUNNING, COMPLETED, CANCELLED, FAILED, TIMEOUT } /** * 任务执行回调接口 * @param 任务结果类型 */ public interface TaskCallback { void onSuccess(T result); void onFailure(Throwable throwable); void onCancel(); void onTimeout(); } /** * 包装的可调度任务 */ @Data public class ScheduledTask implements Comparable> { private final String taskId; private final TaskPriority priority; private final Callable task; private final TaskCallback callback; private final long timeout; // 超时时间,毫秒 private volatile TaskStatus status; private ScheduledFuture timeoutFuture; public ScheduledTask(String taskId, TaskPriority priority, Callable task, TaskCallback callback, long timeout) { this.taskId = taskId; this.priority = priority; this.task = task; this.callback = callback; this.timeout = timeout; this.status = TaskStatus.WAITING; } // 按优先级降序排序,优先级相同按创建顺序?这里简化处理 @Override public int compareTo(ScheduledTask other) { return Integer.compare(other.priority.getLevel(), this.priority.getLevel()); } // 按taskId判断相等,支持队列移除操作 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ScheduledTask that = (ScheduledTask) o; return taskId.equals(that.taskId); } @Override public int hashCode() { return taskId.hashCode(); } } /** * 优先级并发任务调度器 */ public class PriorityTaskScheduler { private static final Logger log =...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【CLAUDE】该实现存在一个根本性问题:题目明确要求使用 Python 3 实现,但模型提交的是 Java 实现,这是对接口规范的严重违背。尽管 Java 实现本身在技术上有一定质量,但语言错误导致接口规范符合度极低,且无法直接运行于 Python 环境。此外,Java 实现中存在若干并发安全隐患(如 cancelWaitingTask 中用 new ScheduledTask 构造虚假对象来 remove 【KIMI】该生成结果存在根本性缺陷:完全使用Java而非要求的Python实现,属于严重的指令遵循失败。尽管Java代码本身实现了基本功能(优先级调度、并发控制、超时、取消),但其设计复杂、并发安全性存疑,且完全不符合题目对Python标准库的使用要求。作为AI评测,此输出应判定为不合格,建议重新生成符合Python 3.8+规范的实现。 【GEMINI】整体实现是一个高质量的并发任务调度器模板,准确完成了优先级排序、并发限制、超时回调等核心功能。代码规范,测试用例详尽。不足之处在于忽略了进阶任务描述中的‘依赖关系’和‘定时执行’(Delayed Start)要求,且调度线程的唤醒机制可以进一步优化为纯Lock/Condition模式以提高可读性和一致性。

困难难度评测结果

  • 得分:76.4 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

--- ## 第一部分:设计文档 ### 1. 整体架构说明 本调度器采用分层模块化架构,核心组件及职责如下: | 组件 | 职责 | |------|------| | `DagTask` | 封装单个任务的定义:业务逻辑、依赖配置、重试参数、执行状态统计,所有配置不可变保证线程安全 | | `DagGraph` | 存储DAG图的拓扑结构:维护任务->前置任务、任务->后置任务的映射,存储任务元数据 | | `DagValidator` | DAG合法性校验,基于Kahn拓扑排序算法检测循环依赖 | | `DynamicThreadPoolExecutor` | JDK ThreadPoolExecutor的包装扩展,支持运行时动态调整线程池参数、自动扩容、溢出缓冲拒绝策略 | | `ExponentialBackoffRetry` | 实现指数退避重试策略,计算重试间隔,支持最大延迟上限,提供重试回调 | | `TaskLifecycleListener` | 任务生命周期观察者接口,支持扩展自定义监控逻辑 | | `SchedulerStats` | 调度器统计快照,存储全局限务统计指标 | | `DagScheduler` | 核心调度协调器,负责任务状态流转、依赖触发、重试调度、监听器通知,对外提供提交DAG、获取统计能力 | ### 2. DAG校验算法选择及死锁预防策略 #### DAG校验算法 选择**Kahn拓扑排序算法**做循环依赖检测,原因: 1. 算法实现简单,时间复杂度O(V+E)(V是任务数,E是依赖边数),效率高 2. 算法过程中计算的节点入度可直接复用给后续调度,无需重复计算 3. 检测逻辑:复制所有任务的入度,每次取出入度为0的节点加入队列,遍历其后继节点将入度减1,最终若处理的节点数不等于总任务数,说明存在未处理的节点,即存在循环依赖,直接拒绝提交。 #### 死锁预防策略 从多个层面避免死锁: 1. **根源消除循环等待**:提交DAG时强制校验循环依赖,不合法的DAG直接拒绝,不存在循环依赖导致的循环等待 2. **线程池分离设计**:核心调度、延迟重试使用独立的调度线程池,不占用工作线程池的线程,避免所有工作线程被占用导致调度无法进行 3. **任务失败快速终止**:任意任务失败后,所有下游依赖任务直接标记为SKIPPED,不会永久等待依赖完成,消除无意义等待 4. **重试上限保护**:每个任务都配置最大重试次数,不会出现无限重试占用线程的情况 5. **原子状态更新**:所有任务状态、依赖计数都使用原子类更新,无锁阻塞,避免锁竞争导致的死锁 ### 3. 线程池动态调整的实现思路及潜在风险 #### 实现思路 1. 基于JDK原生`ThreadPoolExecutor`扩展,原生本身已经提供线程安全的`setCorePoolSize`/`setMaximumPoolSize`方法,可直接复用 2. **手动resize**:对外提供`resize(int coreSize, int maxSize)`方法,校验参数合法性(core tasks = new HashMap(); private final Map> dependencies = new HashMap(); // key: 任务id, value: 前置任务id集合 private final Map> postTasks = new HashMap(); // key: 任务id, value: 后置任务id集合 public void addTask(DagTask task) { tasks.put(task.getTaskId(), task); dependencies.putIfAbsent(task.getTaskId(), new HashSet()); postTasks.putIfAbsent(task.getTaskId(), new HashSet()); } public void addDependency(String taskId, String preTaskId) { dependencies.get(taskId).add(preTaskId); postTasks.get(preTaskId).add(taskId); } public Map getTasks() { return Collections.unmodifiableMap(tasks); } public Map> getDependencies() { return Collections.unmodifiableMap(dependencies); } public Map>...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【GEMINI】该候选人的设计水平极高,展现了资深架构师的素养。设计文档逻辑严密,对并发模型的选型、DAG 校验策略以及动态线程池的边界处理(如溢出缓冲)都有非常到位的实现。代码风格优雅,注释清晰,充分利用了 JDK 11+ 的并发工具。然而,极其遗憾的是输出在核心调度器实现部分被截断,导致最终交付的代码不完整,无法满足“提供完整可运行核心代码”的要求。如果代码完整,这将是一个教科书级的实现。 【KIMI】整体而言,输出代码实现了大部分核心功能要求,架构设计合理,代码质量良好。但在任务状态流转、异常处理等细节实现上还有待完善,部分设计可进一步优化。考虑到实现的完整性和代码质量,综合评分为80分左右。

相关链接

您可以通过以下链接查看更多相关内容:

加载中...