零基础鸿蒙应用开发第三十节:从同步阻塞到异步Promise并发 - 鸿蒙

news/2026/1/25 12:15:53/文章来源:https://www.cnblogs.com/san-xiu/p/19529117

零基础鸿蒙应用开发学习计划表

【学习目标】

  1. 理解同步与异步的核心差异,明确异步的适用场景(耗时操作必用)。
  2. 识别回调地狱的弊端,知晓Promise诞生的核心目的。
  3. 掌握Promise的三种状态及不可逆流转规则,能通过resolve/reject控制异步状态。
  4. 熟练使用then/catch/finally处理Promise结果与错误,实现链式调用。
  5. 理解异步的本质(单线程+事件循环+微/宏任务调度),明确当前学习的是异步并发而非多线程。
  6. 会用Promise.all/Promise.race实现异步并发,处理多个独立异步任务。

【学习重点】

  1. Promise的三种状态(pending/fulfilled/rejected)及不可逆流转逻辑。
  2. then/catch/finally的链式调用用法。
  3. 微任务与宏任务的优先级差异,事件循环的执行流程。
  4. Promise.allPromise.race的适用场景及代码实操。
  5. 异步并发(单线程)与多线程并发的核心区别,多线程工具的初步认知。
  6. 回调地狱的解决思路(Promise链式调用替代嵌套)。

一、工程准备

本节工程名称为PromiseAsyncBasicDemo,基于 鸿蒙5.0(API12) 创建,推荐使用 DevEco Studio 6.0+ 开发工具。

PromiseAsyncBasicDemo/
└── ets/├── pages/│   └── Index.ets        // 核心页面:5个按钮+点击事件,手动触发示例└── utils/               // 工具目录(手动创建)└── PromiseUtil.ets  // Promise核心逻辑:所有示例封装为静态方法

二、先搞懂:同步和异步到底是什么?

2.1 核心概念:并发的两种实现方式

并发指在同一时间内多个任务的执行机制,主要分为两种类型:

  • 异步并发:异步代码执行到一定阶段后暂停,未来某个时间点继续执行,同一时间只有一段代码执行(单线程模型)。适用于单次I/O任务(网络请求、文件读写、定时器等)、轻量无CPU阻塞的任务、逻辑依赖清晰的任务。
  • 多线程并发:允许同时执行多段代码,UI主线程响应用户操作,后台线程执行耗时任务。适用于CPU密集型、长时任务、常驻任务等场景,后续章节将通过TaskPool和Worker工具详细讲解。

重要说明:本节及下一节学习的是异步并发,基于单线程模型,依赖事件循环调度任务;而非多线程并发,多线程涉及线程创建、数据通信等复杂逻辑,将在后续专门章节深入讲解。

2.2 用生活例子秒懂同步vs异步

类型 生活场景(银行办事/日常做事) 代码中的对应逻辑
同步 排队办事,必须等前一个人办完你才能办,期间只能站着等;
吃饭→写作业→睡觉,必须做完一个才能做下一个
代码按顺序执行,上一行代码没执行完,下一行绝对不执行,主线程被阻塞
异步 取号后坐着等叫号,取号后可以玩手机,到号了再去办事;
煮开水的同时玩手机,水开了再泡茶
代码发起任务后立即返回,主线程继续执行其他代码,任务完成后触发回调函数执行(单线程内调度,非多线程并行)

2.3 同步与异步:阻塞 vs 非阻塞

示例1:同步/异步对比

① 同步模式:一步等一步,阻塞主线程
// ets/utils/PromiseUtil.ets
export class PromiseUtil {/*** 同步示例:吃饭→写作业→睡觉,必须做完一个才能做下一个*/static syncSimpleDemo(): void {console.log("===== 【同步模式】开始 =====");// 1. 吃饭(耗时5秒,模拟同步耗时操作)const eat = (): void => {console.log("开始吃饭(预计耗时5秒)");const start = Date.now();while (Date.now() - start < 5000) {} // 空循环模拟耗时5秒console.log("吃饭完成✅");};// 2. 写作业(耗时5秒)const doHomework = (): void => {console.log("开始写作业(预计耗时5秒)");const start = Date.now();while (Date.now() - start < 5000) {}console.log("写作业完成✅");};// 按顺序执行:吃饭→写作业→输出结束(一步等一步)eat(); // 必须等吃饭完成,才会执行下一行doHomework(); // 必须等写作业完成,才会执行下一行console.log("===== 【同步模式】结束(总耗时10秒) =====\n");}/*** 异步示例:煮开水(异步5秒)→同时玩手机(5秒)→水开了泡茶(直观体现并行)*/static asyncSimpleDemo(): void {console.log("===== 【异步模式】开始 =====");// 1. 煮开水(异步任务:用setTimeout模拟,耗时5秒)const boilWater = (): void => {console.log("开始煮开水(发起异步任务,5秒后完成)");setTimeout(() => {// 异步回调:水开了才会执行console.log("水开了✅→开始泡茶");}, 5000);};// 2. 玩手机(同步任务:耗时5秒,和异步任务时长一致)const playPhone = (): void => {console.log("开始玩手机(主线程继续做事,预计耗时5秒)");const start = Date.now();while (Date.now() - start < 5000) {}console.log("玩手机完成✅");};// 执行顺序:发起煮开水→立即玩手机→输出结束(不用等水开)boilWater(); // 发起异步任务后,立即返回,不阻塞playPhone(); // 主线程马上执行,不用等水开console.log("===== 【异步模式】结束(总耗时5秒) =====\n");}
}

执行结果(同步)

===== 【同步模式】开始 =====
开始吃饭(预计耗时5秒)
// 等待5秒
吃饭完成✅
开始写作业(预计耗时5秒)
// 等待5秒
写作业完成✅
===== 【同步模式】结束(总耗时10秒) =====

执行结果(异步)

===== 【异步模式】开始 =====
开始煮开水(发起异步任务,5秒后完成)
开始玩手机(主线程继续做事,预计耗时5秒)
// 等待5秒(异步任务和同步任务同时完成)
水开了✅→开始泡茶
玩手机完成✅
===== 【异步模式】结束(总耗时5秒) =====

核心结论:同步任务阻塞主线程,总耗时是所有任务时间相加(5+5=10秒),期间程序无法做其他事;异步任务不阻塞主线程(单线程内调度),总耗时是最长任务的时间(5秒),通过事件循环实现“伪并行”,直观体现异步的效率优势。

2.4 异步适用场景

只要涉及“耗时操作”(尤其是超过1秒的操作),都必须用异步,否则程序会卡死或出现界面卡顿:

  1. I/O非阻塞操作:网络请求(调用后端接口、获取远程数据)、本地文件/数据库读写(读配置文件、存数据到SQLite);
  2. 定时器操作:延迟执行、定时任务(setTimeout/setInterval);
  3. 轻量无CPU阻塞任务:单次执行时间短、无长时间循环的操作;
  4. 逻辑依赖清晰的任务:有明确顺序或并行关系的异步操作。

三、回调地狱:异步嵌套的坑(Promise的诞生原因)

3.1 看代码:依赖型异步任务的嵌套痛点

// ets/utils/PromiseUtil.ets(继续补充静态方法)
export class PromiseUtil {// (已包含syncSimpleDemo、asyncSimpleDemo,此处补充)/*** 回调地狱演示*/static callbackHellDemo(): void {console.log("===== 回调地狱演示开始 =====");// 模拟异步获取用户ID(网络请求,延迟1秒)const getUserId = (callback: (id: string) => void) => {setTimeout(() => callback("user_1001"), 1000);};// 模拟异步获取用户详情(依赖用户ID,延迟1秒)const getUserDetail = (id: string, callback: (detail: string) => void) => {setTimeout(() => callback(`ID:${id},姓名:鸿蒙开发者`), 1000);};// 模拟异步格式化详情(依赖用户详情,延迟1秒)const formatDetail = (detail: string, callback: (result: string) => void) => {setTimeout(() => callback(`【用户信息】${detail}`), 1000);};// 执行:3层嵌套形成“回调地狱”(嵌套层级越多,代码越往右偏)getUserId((id) => {getUserDetail(id, (detail) => {formatDetail(detail, (result) => {console.log("最终结果:", result);console.log("===== 回调地狱演示结束(总耗时3秒) =====\n");});});});}
}

3.2 回调地狱的三个致命问题

  1. 代码可读性差:嵌套层级越多,代码越像“金字塔”,逻辑难以梳理;
  2. 错误处理麻烦:每个回调里都要写错误判断,冗余且容易遗漏;
  3. 维护性差:新增步骤需要在嵌套最深处修改,容易引发bug。

核心诉求:Promise的出现就是为了解决这个问题——把“往右长”的嵌套代码,变成“往下长”的链式代码,同时统一错误处理机制,让异步逻辑更清晰。

四、Promise:解决回调地狱的核心方案

4.1 Promise的核心定位

Promise是一种用于处理异步操作的对象,核心价值在于将异步操作转换为类似同步操作的风格,通过状态机制管理异步流程,避免回调嵌套,同时提供统一的结果处理和错误捕获接口。

4.2 Promise的核心:三种状态与流转规则

Promise只有三种状态,且状态一旦变更,永远不可逆

  1. pending(进行中):异步任务还在执行,初始状态;
  2. fulfilled(已完成,又称resolved):异步任务完成,调用resolve(结果)触发状态变更;
  3. rejected(已拒绝):异步任务出错,调用reject(错误)触发状态变更。

流转逻辑

graph TDA[创建Promise] --> B[pending]B --> C[fulfilled]B --> D[rejected]C --> E[then获取结果]D --> F[catch捕获错误]C --> G[finally收尾]D --> G[finally收尾]

4.3 代码实操:链式调用替代嵌套

// ets/utils/PromiseUtil.ets(继续补充静态方法)
export class PromiseUtil {// (已包含syncSimpleDemo、asyncSimpleDemo、callbackHellDemo,此处补充)/*** Promise链式调用解决回调地狱*/static promiseSolutionDemo(): void {console.log("===== Promise解决方案演示开始 =====");// 封装:异步获取用户ID(返回Promise对象,延迟1秒)const getUserIdPromise = (): Promise<string> => {// Promise构造函数接收一个执行器函数,参数是resolve和rejectreturn new Promise((resolve, reject) => {setTimeout(() => {// 模拟10%的失败概率(比如网络波动)const isSuccess = Math.random() > 0.1;if (isSuccess) {resolve("user_1001"); // 成功:传递结果数据} else {reject(new Error("获取用户ID失败")); // 失败:传递错误信息}}, 1000);});};// 封装:异步获取用户详情(依赖ID,返回Promise对象,延迟1秒)const getUserDetailPromise = (id: string): Promise<string> => {return new Promise((resolve, reject) => {setTimeout(() => {const isSuccess = Math.random() > 0.1;if (isSuccess) {resolve(`ID:${id},姓名:鸿蒙开发者`);} else {reject(new Error("获取用户详情失败"));}}, 1000);});};// 封装:异步格式化详情(依赖详情,返回Promise对象,延迟1秒)const formatDetailPromise = (detail: string): Promise<string> => {return new Promise((resolve, reject) => {setTimeout(() => {const isSuccess = Math.random() > 0.1;if (isSuccess) {resolve(`【用户信息】${detail}`);} else {reject(new Error("格式化详情失败"));}}, 1000);});};// 链式调用:替代嵌套(代码从上到下执行,逻辑清晰)getUserIdPromise().then((id) => {// 第一个任务成功:执行第二个任务,返回新的Promisereturn getUserDetailPromise(id);}).then((detail) => {// 第二个任务成功:执行第三个任务,返回新的Promisereturn formatDetailPromise(detail);}).then((result) => {// 第三个任务成功:处理最终结果console.log("最终结果:", result);}).catch((error: Error) => {// 统一捕获:任意一个步骤失败,都会触发这里(无需每个步骤写错误处理)console.log("错误:", error.message);}).finally(() => {// 无论成功/失败,都会执行(比如清理资源、隐藏加载动画)console.log("异步任务流程结束(可清理资源)");console.log("===== Promise解决方案演示结束(总耗时3秒) =====\n");});}
}

4.5 易错点提醒(重点)

⚠️ 易错点1:忘记调用resolve/reject → Promise会一直停留在pending状态,结果永远无法处理;
⚠️ 易错点2:认为状态可以修改 → 比如先调用resolve再调用reject,后续调用会直接失效;
⚠️ 易错点3:忘记添加catch → 异步错误会变成“未捕获错误”,导致程序报错崩溃;
⚠️ 易错点4:在Promise执行器里写同步耗时代码(如10秒长循环)→ 会阻塞主线程,失去异步意义;执行器内应放异步操作(如setTimeout、网络请求)。

五、异步的本质:单线程+事件循环

5.1 核心概念:调用栈 + 任务队列 + 事件循环

异步的实现依赖单线程模型下的事件循环机制,可类比为“餐厅后厨”的工作流程:

  1. 调用栈:相当于后厨的“操作台”,同步代码依次入栈执行,执行完出栈(一次只能处理一个任务);
  2. 任务队列:相当于后厨的“订单队列”,存放异步任务的回调函数,分为两种类型:
    • 微任务:优先级高,比如Promise的then/catch/finallyqueueMicrotask
    • 宏任务:优先级低,比如setTimeoutsetInterval、网络请求、UI事件;
  3. 事件循环:相当于后厨的“调度员”,不停循环执行以下步骤:
    • 执行调用栈里的所有同步代码,直到栈空;
    • 执行微任务队列里的所有回调,直到队列空;
    • 从宏任务队列里取第一个回调执行;
    • 重复上述步骤。

5.2 代码验证:微任务比宏任务先执行

// ets/utils/PromiseUtil.ets(继续补充静态方法)
export class PromiseUtil {// (已包含上述方法,此处补充)/*** 事件循环(微/宏任务)验证*/static eventLoopDemo(): void {console.log("===== 事件循环(微任务/宏任务)验证开始 =====");console.log("1. 同步代码开始");// 宏任务:setTimeout(普通单,延迟0秒)setTimeout(() => {console.log("4. 宏任务(setTimeout)执行");}, 0);// 微任务:Promise.then(加急单)Promise.resolve().then(() => {console.log("3. 微任务(Promise.then)执行");});console.log("2. 同步代码结束");console.log("===== 事件循环验证结束 =====\n");}
}

执行结果(看顺序:1→2→3→4)

===== 事件循环(微任务/宏任务)验证开始 =====
1. 同步代码开始
2. 同步代码结束
===== 事件循环验证结束 =====
// 同步代码执行完毕,先清空所有微任务
3. 微任务(Promise.then)执行
// 微任务执行完毕,再执行第一个宏任务
4. 宏任务(setTimeout)执行

关键结论

异步不是多线程并行执行,而是通过事件循环机制,在单线程内调度异步任务的回调执行,从而实现“非阻塞”效果。真正的多线程需要通过专门工具实现,当前阶段仅需理解单线程下的异步调度逻辑。

六、Promise异步并发:处理多个独立任务

6.1 核心方法对比

方法 作用 特点
Promise.all 等待所有任务完成 所有任务成功才返回结果数组(顺序与传入一致),一个失败则立即返回失败
Promise.race 取第一个完成的任务 无论成功/失败,只要有一个任务完成就返回结果,后续任务忽略

6.2 代码实操:Promise.all/Promise.race

// ets/utils/PromiseUtil.ets(继续补充静态方法)
export class PromiseUtil {// (已包含上述方法,此处补充)/*** Promise.all/race 异步并发演示*/static promiseConcurrentDemo(): void {console.log("===== Promise并发演示开始 =====");// 模拟:异步获取商品列表(延迟2秒)const getGoodsList = (): Promise<string[]> => {return new Promise((resolve) => {setTimeout(() => {resolve(["商品1", "商品2", "商品3"]);}, 2000);});};// 模拟:异步获取用户购物车(延迟1.5秒)const getCart = (): Promise<string[]> => {return new Promise((resolve) => {setTimeout(() => {resolve(["购物车商品1", "购物车商品2"]);}, 1500);});};// 模拟:超时控制任务(延迟3秒,仅失败)const timeoutTask = (): Promise<never> => {return new Promise((_, reject) => {setTimeout(() => {reject(new Error("请求超时(3秒未响应)"));}, 3000);});};// 1. Promise.all:等待所有任务完成(总耗时2秒,取最长任务时间)Promise.all([getGoodsList(), getCart()]).then((result: Array<string[]>) => {const goods = result[0];const cart = result[1];console.log("Promise.all 成功结果:");console.log("商品列表:", goods);console.log("购物车:", cart);})// 2. Promise.race:取第一个完成的任务(1.5秒后返回购物车结果)Promise.race([getGoodsList(), getCart(), timeoutTask()]).then((result) => {console.log("Promise.race 第一个完成的结果:", result);}).catch((error:Error) => {console.log("Promise.race 失败:", error.message);});console.log("===== Promise并发演示结束(代码已发起,等待异步结果) =====\n");}
}

6.3 关键语义说明:为什么不用Promise<Error>

从代码语法上,const timeout: Promise<Error> 是合法的,但存在语义偏差

  1. Promise的泛型参数表示resolve的返回类型,而非reject的错误类型;
  2. Promise<Error>会导致.then()里需要写result: string | Error,但实际timeout永远不会走.then()result不可能是Error类型;
  3. Promise<never>是语义最精准的选择:明确表示该Promise永远不会有成功结果,不会影响Promise.race的返回类型推断,让.then()里的result只需标注string

6.4 注意点

  • Promise.all的结果数组顺序严格对应传入的Promise数组顺序,与任务完成顺序无关;总耗时按最长任务时间计算,而非相加;
  • Promise.race只响应第一个完成的任务,后续任务的结果/错误都会被忽略;适合超时控制场景(比如接口请求5秒没响应就提示超时);
  • 处理Promise.race的超时场景时,推荐用Promise<never>标注超时任务(语义精准),避免类型推断冗余;
  • 如果需要处理“所有任务无论成败都要获取结果”的场景,可关注下节的Promise.allSettled方法。

附:入口文件代码(Index.ets)

// ets/pages/Index.ets - 程序入口文件
import { PromiseUtil } from '../utils/PromiseUtil';@Entry
@Component
struct Index {build() {Column({ space: 15 }) {Text("Promise异步并发基础示例(直观演示同步/异步差异)").fontSize(20).fontWeight(FontWeight.Bold).margin(20);// 1. 同步/异步对比按钮Button("1. 同步 vs 异步 对比").width('80%').height(50).onClick(() => {PromiseUtil.syncSimpleDemo();PromiseUtil.asyncSimpleDemo();});// 2. 回调地狱演示按钮Button("2. 回调地狱演示").width('80%').height(50).onClick(() => PromiseUtil.callbackHellDemo());// 3. Promise 链式调用按钮Button("3. Promise 链式调用").width('80%').height(50).onClick(() => PromiseUtil.promiseSolutionDemo());// 4. 微/宏任务 验证按钮Button("4. 微/宏任务 验证").width('80%').height(50).onClick(() => PromiseUtil.eventLoopDemo());// 5. 异步并发演示按钮Button("5. Promise.all/race 并发").width('80%').height(50).onClick(() => PromiseUtil.promiseConcurrentDemo());}.width('100%').height('100%').justifyContent(FlexAlign.Center);}
}

七、内容总结

  1. 同步与异步:同步阻塞主线程(总耗时相加),异步非阻塞主线程(总耗时为最长任务时间),耗时操作必须用异步避免界面卡顿;
  2. Promise核心:三种状态(pending/fulfilled/rejected)不可逆,通过then/catch/finally实现链式调用,统一处理结果与错误,解决回调地狱;
  3. 异步本质:基于单线程模型,依赖事件循环调度,微任务优先级高于宏任务,非多线程并行;
  4. 异步并发Promise.all等待所有任务完成(适合依赖所有结果),Promise.race取第一个完成的任务(适合超时控制);超时场景推荐用Promise<never>标注超时任务,保证类型语义精准;
  5. 多线程说明:多线程并发适用于CPU密集型、长时任务,需通过TaskPool和Worker工具实现,后续章节将详细讲解。

八、代码仓库

  • 工程名称:PromiseAsyncBasicDemo
  • 仓库地址:https://gitee.com/juhetianxia321/harmony-os-code-base.git

九、下节预告

通过本节的学习,我们已经掌握了 Promise 的基础语法、then/catch/finally链式调用,以及Promise.all/Promise.race的基础并发方案。但在复杂业务场景中,链式调用仍有冗余,且错误处理不够直观,同时还有批量任务统计、多源容错等场景未覆盖。下一节将解决这些问题,系统学习:

  1. try/catch/finally错误处理基础:掌握同步/异步场景的错误捕获逻辑,为async/await铺垫;
  2. async/await语法糖的核心使用:将Promise异步代码“同步化”书写,彻底摆脱链式调用的冗余;
  3. Promise进阶并发方案:Promise.allSettled/Promise.any的使用场景与实操,覆盖批量任务统计、多源数据容错获取等场景;
  4. Promise开发避坑:解决await滥用导致的并发变串行问题,优化异步任务执行性能。

下一节将让异步编程更直观、更高效,同时完善错误处理和并发逻辑,为复杂场景的异步开发打下坚实基础~

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

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

相关文章

深入浅出Activity工作流:从理论到实践,让业务流转自动化 - 指南

深入浅出Activity工作流:从理论到实践,让业务流转自动化 - 指南2026-01-25 12:15 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !im…

如何搭建公司网站?网站建设公司搭建网站有哪些步骤呀?

作为一名经历过网站建设诸多挑战的过来人&#xff0c;我将结合自身经验与行业常见流程&#xff0c;系统梳理公司网站建设的步骤与注意事项&#xff0c;帮助大家厘清实际需求&#xff0c;减少不必要的弯路。 一、明确需求与目标&#xff08;核心起点&#xff09; 1、确定网站类型…

Python 使用 subprocess 检测 Linux 用户是否存在,不存在则自动创建

一、背景说明 在 Linux 服务器自动化运维、初始化脚本或容器环境中&#xff0c;经常需要判断某个系统用户是否存在&#xff1a; 如果存在&#xff1a;直接使用如果不存在&#xff1a;自动创建用户 本文介绍如何使用 Python 的 subprocess 模块&#xff0c;调用系统命令 id 和…

全网最全10个AI论文软件,专科生轻松搞定毕业论文!

全网最全10个AI论文软件&#xff0c;专科生轻松搞定毕业论文&#xff01; AI 工具让论文写作不再难 对于专科生来说&#xff0c;撰写毕业论文往往是一个令人头疼的任务。从选题到开题&#xff0c;再到撰写和降重&#xff0c;每一个环节都可能让人感到压力山大。而随着 AI 技术…

超详细版Batocera游戏整合包配置步骤(新手友好)

以下是对您提供的博文《超详细版 Batocera 游戏整合包配置技术解析》的 深度润色与工程化重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹(无模板化句式、无空洞总结、无机械连接词) ✅ 摒弃“引言/概述/核心特性/原理解析/实战指南/总结”等刻板结构 ✅ …

Qwen-Image-Edit-2511保姆级教程:从下载到出图全流程

Qwen-Image-Edit-2511保姆级教程&#xff1a;从下载到出图全流程 你是不是也遇到过这些情况&#xff1a;想把商品图里的背景换成纯白&#xff0c;结果边缘发灰&#xff1b;想给海报加一句中文标语&#xff0c;字体却和原图不搭&#xff1b;想让两张人物照片风格统一&#xff0…

深度剖析usb_burning_tool支持设备类型与兼容性

以下是对您提供的博文内容进行 深度润色与结构重构后的专业级技术文章 。整体遵循“去AI化、强人设、重实战、轻模板”的原则,摒弃所有刻板标题与套路化表达,以一位深耕嵌入式烧录领域十年的工程师口吻娓娓道来——有经验、有踩坑、有思辨、有温度,同时确保技术细节精准、…

2026山东优秀的污水提升器实力厂家

一、 核心结论 在2026年的市场环境下,地下室改造、商业空间升级及环保标准提升,共同驱动了污水提升器市场的专业化与精细化发展。为帮助山东及全国用户精准选型,本报告建立了一套涵盖产品技术、市场表现、服务能力、…

零基础也能用!YOLOv9官方镜像保姆级教程,快速实现图像识别

零基础也能用&#xff01;YOLOv9官方镜像保姆级教程&#xff0c;快速实现图像识别 你是不是也遇到过这样的情况&#xff1a;刚下载完一个目标检测镜像&#xff0c;打开终端却卡在“conda activate”命令上&#xff1f;或者复制粘贴了一堆训练命令&#xff0c;结果报错说Module…

为什么Qwen3-14B能省事?128k长文单卡推理部署解析

为什么Qwen3-14B能省事&#xff1f;128k长文单卡推理部署解析 1. 它不是“小模型”&#xff0c;而是“刚刚好”的大模型守门员 很多人看到“14B”就下意识划走——觉得参数不够大、性能不够强、跑不起来新任务。但Qwen3-14B恰恰打破了这个惯性认知&#xff1a;它不是在参数规…

Qwen3-4B-Instruct-2507企业部署:高可用架构设计案例

Qwen3-4B-Instruct-2507企业部署&#xff1a;高可用架构设计案例 1. 为什么需要企业级部署方案&#xff1f; 你可能已经试过在单卡上跑通 Qwen3-4B-Instruct-2507——输入几行提示词&#xff0c;模型秒回一段逻辑清晰、语言自然的文本&#xff0c;体验确实流畅。但当它真正走…

直播带货新玩法:用Live Avatar做AI代言人

直播带货新玩法&#xff1a;用Live Avatar做AI代言人 数字人技术正从实验室快速走向直播间。当传统直播依赖真人出镜、固定时段、高人力成本时&#xff0c;一种更灵活、可复用、全天候在线的AI代言人正在改变电商内容生产方式。Live Avatar——由阿里联合高校开源的数字人模型…

2026年成都打印纸市场:实力厂商价格对比与选型全攻略

随着2026年的到来,四川成都的企业采购者们正面临新的挑战与选择:在竞争日益激烈的办公用品市场中,如何筛选出技术扎实、效果可视的打印纸实力厂商?面对市场上林林总总的品牌与服务商,不同规模和发展阶段的企业应如…

2026年国内知名的测水流量计工厂电话,一体式电磁流量计/超声波液位计/醇类流量计/威力巴流量计,测水流量计产品推荐榜

在工业自动化与环保监测领域,测水流量计作为核心计量设备,其精度与稳定性直接影响生产效率与资源管理。近年来,随着国家对水资源保护的重视及工业4.0的推进,市场对高质量测水流量计的需求持续攀升。然而,行业内部…

pwn入门(一)

moectf2025 目录syslockxdulakerezpivotezprotectionfmt_thardpivot迁移到bss段输出puts@gotret2libcexpshellboxNo way to leakelf相关结构延迟绑定_dl_fixupret2dlresolveexpcall_it syslock import ctypes from pwn…

阅读文献的方法

阅读文献的方法Posted on 2026-01-25 12:07 steve.z 阅读(0) 评论(0) 收藏 举报阅读文献的方法 一、一篇文献一般会包含的几部分title - 标题 abs - 导言 intro - 介绍 method - 你提出的算法 exp - 实验 conclus…

2025年AI超级员工使用体验排行榜,AI超级员工/AI企业员工供应商排行榜单

智能营销新纪元:企业数字化转型的关键利器 随着人工智能技术的快速发展,AI超级员工正成为企业数字化转型的重要推动力。据最新市场调研数据显示,2025年全球AI超级员工市场规模预计将达到千亿级别,越来越多的企业开…

机械行业CKEDITOR导入CAD图纸如何PHP自动转存?

广州软件公司技术负责人&#xff1a;Word粘贴与多格式文档导入功能开发实录 一、需求分析与技术规划 作为技术负责人&#xff0c;我主导了客户需求的技术可行性评估与方案规划。核心需求包括&#xff1a; 富文本粘贴功能&#xff1a;支持Word/微信公众号内容粘贴&#xff0c…

2026年市面上评价高的层板货架订做厂家口碑推荐榜,仓库货架/重型货架/自动化立体库货架,层板货架厂商口碑排行榜

行业背景:层板货架市场如何选型? 随着制造业、物流业及电商行业的快速发展,层板货架作为仓储系统的核心设备,其选型需求正从“标准化”向“定制化”“智能化”加速转型。据第三方调研机构统计,2025年国内层板货架…

2026年初国内AI获客系统服务商竞争力深度解析

一、 核心结论 在存量竞争与增量探索并存的2026年,AI获客已成为企业实现增长破局的必备“利器”。本报告旨在拨开市场迷雾,通过一套严谨的四维评估框架——技术能力、市场表现、客户成功、生态建设,对国内主流AI获客…