JavaScript数组核心方法详解:push/pop/shift/unshift/slice/splice实战指南
1. 数组操作从“仓库管理员”到“数据魔术师”的思维转变刚接触JavaScript那会儿我总觉得数组操作函数就是一堆需要死记硬背的API名字。push、pop、shift、unshift... 这些词听起来像某种神秘的咒语。直到有一次我在做一个简单的待办事项列表需要动态添加、删除任务并且还要能调整顺序我才真正意识到理解这些函数不是在背单词而是在掌握一套处理有序数据的“核心心法”。你可以把数组想象成一个长长的、带编号的储物柜或者一列火车车厢。而这些函数就是你作为“数据管理员”或“列车调度员”所使用的工具。它们决定了数据从哪里进、从哪里出、如何截取一段、又如何替换中间的部分。今天我们就抛开枯燥的文档用最贴近实战的场景把这几个最常用也最核心的数组方法——push()、pop()、shift()、unshift()、slice()、splice()——彻底讲透让你不仅会用更能理解其设计哲学和适用场景从此面对数组操作游刃有余。2. 增删之道理解数组的“头尾”操作数组最基本、最高频的操作无非就是增删元素。而增删的位置无外乎数组的尾部和头部。JavaScript非常贴心地为我们提供了两对“镜像”操作的方法分别针对这两个位置。2.1 尾部操作push()与pop()—— 后进先出的“栈”我们先看尾部。push()和pop()这一对是操作数组尾部最直观的方法。push()向数组的末尾添加一个或多个元素。它的行为就像你在排队新来的人总是站到队伍的最后面。push()方法会修改原数组并返回数组新的长度。let todoList [买菜, 写代码]; let newLength todoList.push(健身, 看书); console.log(todoList); // 输出: [买菜, 写代码, 健身, 看书] console.log(newLength); // 输出: 4这里有个很实用的技巧push()可以一次性添加多个元素用逗号隔开即可。这在需要批量添加数据时非常方便比如从接口拿到一个列表数据直接arr.push(...newData)就能合并进去。pop()删除数组的最后一个元素。与push()相反pop()是移除队伍最后面的人。它同样会修改原数组并返回被删除的那个元素。如果数组为空则返回undefined。let lastTask todoList.pop(); console.log(lastTask); // 输出: 看书 console.log(todoList); // 输出: [买菜, 写代码, 健身]push()和pop()的组合完美实现了“后进先出”LIFO的**栈Stack**数据结构。想象一下一摞盘子你总是把新盘子放在最上面push也总是从最上面拿走盘子pop。浏览器历史记录的前进后退、函数调用栈都是栈的典型应用。实操心得在处理需要“撤销”功能的场景时push()和pop()是绝配。你可以用一个数组作为操作历史记录栈用户每做一个操作就把操作信息push进去点击撤销时就pop出最近的一次操作并执行反向操作。2.2 头部操作shift()与unshift()—— 先进先出的“队列”接下来看头部。shift()和unshift()是操作数组头部的一对方法。unshift()向数组的开头添加一个或多个元素。这就像有人插队到了队伍的最前面。它也会修改原数组并返回数组新的长度。let highPriorityLength todoList.unshift(紧急会议); console.log(todoList); // 输出: [紧急会议, 买菜, 写代码, 健身] console.log(highPriorityLength); // 输出: 4shift()删除数组的第一个元素。移除站在队伍最前面的人。它修改原数组并返回被删除的那个元素。空数组调用返回undefined。let firstTask todoList.shift(); console.log(firstTask); // 输出: 紧急会议 console.log(todoList); // 输出: [买菜, 写代码, 健身]shift()和push()的组合则实现了“先进先出”FIFO的**队列Queue**数据结构。就像现实中的排队先来的人先得到服务shift新来的人排到队尾push。消息队列、打印任务排队等都是队列的应用。注意事项unshift()和shift()操作数组头部意味着它们移动了所有现有元素的索引。对于一个超大型数组比如数十万条数据频繁在头部进行增删操作性能开销会远大于尾部操作。因为每次操作引擎都需要重新计算并移动后面所有元素的内存位置。在性能敏感的场景下需要慎重考虑。2.3 头尾操作对比与选择为了更清晰地对比这四兄弟我们列个表方法操作位置操作类型返回值类比数据结构性能影响大型数组push()尾部添加新长度栈配合pop小常数时间O(1)pop()尾部删除被删除元素栈配合push小常数时间O(1)unshift()头部添加新长度队列配合shift大线性时间O(n)shift()头部删除被删除元素队列配合push大线性时间O(n)如何选择默认优先使用尾部操作除非有明确需求否则添加删除数据尽量使用push()和pop()性能最好。明确“顺序”含义时使用队列当你的数据有严格的“先来后到”的处理顺序时使用push()入队和shift()出队。处理“最近”相关时使用栈当你的逻辑关心“最近一个”时如撤销、路由历史使用push()压栈和pop()弹栈。unshift()用于高优先级插入当你需要把一个元素提到最前面处理时使用但要意识到性能成本。3. 截取与手术slice()与splice()的精妙差异如果说push/pop/shift/unshift是负责进出口的“门卫”那么slice()和splice()就是深入数组内部的“外科医生”。它们功能更强大也更容易混淆。记住一个核心区别slice()是“复印机”而splice()是“手术刀”。3.1slice()安全无副作用的“切片”与“复制”slice()方法用于浅拷贝数组的一部分到一个新数组不会改变原数组。它的名字很形象就像从蛋糕上切下一片原来的蛋糕完好无损。它接受两个可选参数slice(start, end)。start开始截取的索引包含该位置。如果为负数则表示从末尾开始计算例如-1指最后一个元素。end结束截取的索引不包含该位置。如果省略则截取到数组末尾。如果为负数同样从末尾计算。let fruits [Apple, Banana, Orange, Mango, Kiwi]; // 场景1复制整个数组浅拷贝 let fruitsCopy fruits.slice(); console.log(fruitsCopy); // [Apple, Banana, Orange, Mango, Kiwi] console.log(fruitsCopy fruits); // false是两个不同的数组 // 场景2截取中间一段 let citrus fruits.slice(2, 4); // 从索引2开始到索引4不包含 console.log(citrus); // [Orange, Mango] // 场景3从末尾开始截取 let lastTwo fruits.slice(-2); // 从倒数第2个开始到末尾 console.log(lastTwo); // [Mango, Kiwi] // 场景4原数组丝毫未变 console.log(fruits); // [Apple, Banana, Orange, Mango, Kiwi]保持不变浅拷贝的陷阱slice()创建的是浅拷贝。如果数组元素是对象那么新数组中的对象元素和原数组中的对象元素引用的是同一个内存地址。let people [{name: Alice}, {name: Bob}]; let peopleCopy people.slice(); peopleCopy[0].name Alex; console.log(people[0].name); // 输出: Alex原数组也被修改了避坑技巧当你需要一份完全独立的、包括内部对象都全新的数组副本时slice()是不够的。你需要使用“深拷贝”比如JSON.parse(JSON.stringify(arr))仅限可序列化数据或者使用Lodash库的_.cloneDeep方法。3.2splice()功能强大的“原位手术”splice()是数组方法中的“瑞士军刀”功能极其强大可以删除、插入、替换数组中的元素并且直接修改原数组。它的名字来源于“拼接”。它的参数形式更灵活splice(start, deleteCount, item1, item2, ...)。start开始修改的索引。负数从末尾计算。deleteCount要删除的元素个数。如果为0则表示不删除仅插入。item1, item2, ...要添加到数组的新元素从start位置开始插入。它的返回值是由被删除的元素组成的数组。如果没有删除则返回空数组。let numbers [1, 2, 3, 4, 5]; // 场景1删除元素 —— 当“手术刀” let removed numbers.splice(2, 2); // 从索引2开始删除2个元素 console.log(removed); // [3, 4] console.log(numbers); // [1, 2, 5] 原数组被修改 // 场景2插入元素 —— 当“插入器” numbers.splice(1, 0, a, b); // 从索引1开始删除0个插入a,b console.log(numbers); // [1, a, b, 2, 5] // 场景3替换元素 —— 删除旧的同时插入新的 let replaced numbers.splice(2, 2, x, y, z); // 从索引2开始删除2个插入3个 console.log(replaced); // [b, 2] 被删除的 console.log(numbers); // [1, a, x, y, z, 5] 原数组被修改splice()的威力在于它的“原位操作”能力。比如在不借助新变量的情况下交换数组中的两个元素let arr [10, 20, 30, 40]; // 交换索引1和索引2的元素 let temp arr.splice(1, 1)[0]; // 删除20temp20 arr.splice(2, 0, temp); // 在索引2的位置插入20 console.log(arr); // [10, 30, 20, 40] // 更优雅的现代写法是解构赋值[arr[1], arr[2]] [arr[2], arr[1]];实操心得splice()的start参数支持负数这在处理“从末尾开始第N个位置”进行操作时非常方便。例如arr.splice(-2, 1)可以删除倒数第二个元素。但务必注意splice()会直接修改原数组这在React、Vue等状态不可变的框架中可能是禁忌需要先创建副本再操作。3.3slice()vssplice()核心区别总结特性slice()splice()核心作用截取/复制删除/插入/替换是否修改原数组否纯函数是副作用返回值新数组截取的部分新数组被删除的元素参数语义(start, end)表示范围(start, deleteCount, ...items)表示操作常用场景获取子数组、复制数组动态修改数组内容、批量操作一句话记忆想要一份数据的“快照”或“副本”用slice想要对数据本身“动手术”用splice。4. 实战演练综合运用解决经典问题理解了每个方法的特性我们通过几个实战场景来融会贯通。这些场景都是前端开发中真实遇到的。4.1 场景一实现一个简单的任务队列管理器假设我们有一个异步任务队列需要按顺序执行并且支持在队首添加高优先级任务。class TaskQueue { constructor() { this.queue []; } // 普通任务入队尾部 enqueue(task) { this.queue.push(task); console.log(任务入队: ${task.name}当前队列:, this.queue.map(t t.name)); } // 高优先级任务插队头部 enqueueHighPriority(task) { this.queue.unshift(task); console.log([高优先级]任务入队: ${task.name}当前队列:, this.queue.map(t t.name)); } // 执行下一个任务从头部取出 async runNext() { if (this.queue.length 0) { console.log(队列已空); return; } const nextTask this.queue.shift(); // 从头部取出 console.log(开始执行: ${nextTask.name}); await nextTask.execute(); console.log(执行完毕: ${nextTask.name}剩余队列:, this.queue.map(t t.name)); } } // 模拟任务 const tasks [ { name: 发送邮件, execute: () new Promise(resolve setTimeout(() { console.log(邮件已发); resolve(); }, 1000)) }, { name: 备份数据, execute: () new Promise(resolve setTimeout(() { console.log(备份完成); resolve(); }, 500)) }, ]; const manager new TaskQueue(); tasks.forEach(t manager.enqueue(t)); manager.enqueueHighPriority({ name: 紧急漏洞修复, execute: () new Promise(resolve setTimeout(() { console.log(漏洞修复完成); resolve(); }, 300)) }); // 模拟执行 (async () { while (manager.queue.length 0) { await manager.runNext(); } })();这个例子清晰地展示了push/unshift用于入队shift用于出队构成了一个完整的队列管理逻辑。4.2 场景二分页加载数据与列表局部更新在无限滚动或分页加载时我们经常需要将新数据追加到列表末尾或者替换某一页的数据。// 模拟初始数据 let dataList Array.from({ length: 20 }, (_, i) 项目 ${i 1}); // 模拟加载第2页数据每页10条 function loadPage(pageNum, pageSize 10) { // 使用 slice 安全地获取当前页应该显示的数据 const start (pageNum - 1) * pageSize; const end start pageSize; const currentPageData dataList.slice(start, end); console.log(第${pageNum}页数据:, currentPageData); return currentPageData; } // 用户在第2页修改了第15条数据索引14 function updateItem(index, newValue) { // 错误做法直接赋值如果index越界会改变数组长度且不符合不可变思想 // dataList[index] newValue; // 正确做法1使用 splice 进行原位替换直接修改原数组 // dataList.splice(index, 1, newValue); // 正确做法2推荐尤其在前端框架中创建新数组体现不可变性 dataList [ ...dataList.slice(0, index), // 前半部分 newValue, // 新值 ...dataList.slice(index 1) // 后半部分 ]; console.log(更新索引${index}后的完整列表:, dataList); } // 模拟加载 loadPage(2); // 输出第2页数据: (10) [项目 11, 项目 12, ..., 项目 20] updateItem(14, 项目 15已修改); loadPage(2); // 再次加载能看到修改已生效这里综合运用了slice进行安全的数据截取和数组拆分再通过扩展运算符...组合成新数组这是一种非常函数式且安全的做法在React的setState或Vue的响应式更新中很常见。4.3 场景三数组去重与洗牌算法虽然ES6的Set可以轻松去重但理解其原理离不开基础方法。洗牌算法则是对splice的巧妙运用。// 方法1使用 filter 和 indexOf (依赖 indexOf 的查找) function uniqueBasic(arr) { return arr.filter((item, index) arr.indexOf(item) index); } // 方法2利用对象键值唯一性传统方法对非字符串键需处理 function uniqueByObject(arr) { let seen {}; return arr.filter(item { // 注意对象和数组等引用类型直接作为键会有问题 let key typeof item JSON.stringify(item); return seen.hasOwnProperty(key) ? false : (seen[key] true); }); } // 现代最简单方法使用 Set 和扩展运算符 function uniqueModern(arr) { return [...new Set(arr)]; } // 洗牌算法 (Fisher-Yates shuffle) —— splice 的经典应用 function shuffleArray(array) { const shuffled [...array]; // 先复制一份不修改原数组 for (let i shuffled.length - 1; i 0; i--) { const j Math.floor(Math.random() * (i 1)); // 随机生成一个 [0, i] 的整数 // 交换 shuffled[i] 和 shuffled[j] [shuffled[i], shuffled[j]] [shuffled[j], shuffled[i]]; // 如果用 splice 实现交换会非常低效因为 splice 是 O(n) 操作 // let temp shuffled.splice(j, 1)[0]; // shuffled.splice(i, 0, temp); // temp shuffled.splice(i1, 1)[0]; // 需要额外步骤调整 } return shuffled; } let testArr [1, 2, 2, 3, 3, 3, a, a, {x:1}, {x:1}]; console.log(基础去重:, uniqueBasic([1,2,2,3])); console.log(现代去重:, uniqueModern(testArr)); // 注意两个 {x:1} 对象会被视为不同的 console.log(洗牌结果:, shuffleArray([1, 2, 3, 4, 5, 6, 7, 8, 9]));在洗牌算法的注释里我特意展示了一个错误的splice用法。虽然splice能实现元素交换但在循环中多次调用splice进行插入删除其时间复杂度会变得很高O(n²)而直接通过索引交换元素是O(1)操作性能天差地别。5. 性能考量、常见坑点与最佳实践了解了怎么用我们还得知道怎么用得“好”。尤其是在处理大规模数据时细节决定成败。5.1 性能对比与选择策略我们通过一个简单的测试来看看不同操作在大数组下的性能差异以下为概念性说明实际时间因环境而异// 假设有一个包含10万个元素的数组 let largeArray new Array(100000).fill().map((_, i) i); // 场景A频繁在头部插入 (unshift) console.time(unshift 1000次); for (let i 0; i 1000; i) { largeArray.unshift(i); // 每次操作都导致后续10万元素索引重排 } console.timeEnd(unshift 1000次); // 耗时可能非常长 // 场景B频繁在尾部插入 (push) let largeArray2 new Array(100000).fill().map((_, i) i); console.time(push 1000次); for (let i 0; i 1000; i) { largeArray2.push(i); // 仅在尾部追加效率极高 } console.timeEnd(push 1000次); // 耗时极短 // 场景C使用 slice 复制大数组 console.time(slice 复制); let copy largeArray.slice(); // 浅拷贝需要遍历所有元素 console.timeEnd(slice 复制); // 场景D使用 splice 删除中间大量元素 console.time(splice 删除5000个); largeArray.splice(50000, 5000); // 需要删除元素并移动其后约45000个元素 console.timeEnd(splice 删除5000个);性能结论与策略尾部操作 (push/pop) 远快于头部操作 (unshift/shift)。在需要队列行为且性能敏感时可以考虑用两个指针模拟队列而不是直接操作数组头部。slice()复制大数组有成本。它需要遍历原数组的所有元素进行浅拷贝。如果只是需要迭代或许直接遍历原数组更好。splice()在中间进行大量删除/插入成本高。因为它需要移动大量元素。如果业务需要频繁在数组中间增删或许该考虑换用链表Linked List数据结构虽然JavaScript没有原生链表但可以用对象模拟。5.2 你必须绕开的常见“坑”混淆slice和splice的返回值这是新手最常犯的错误。记住slice返回你要的那部分新数组splice返回它删掉的那些元素组成的数组。写代码时多问自己一句“我想要的是结果还是被删除的部分”忽略splice的“原地修改”特性在React、Vue或Redux等强调“不可变性”的体系中直接修改状态数组是禁忌会导致视图不更新或状态管理混乱。正确的做法是总是先创建副本。// Vue/React 中错误的做法 this.list.splice(index, 1); // 直接修改可能不会触发响应式更新 // 正确的做法 this.list this.list.slice(0, index).concat(this.list.slice(index 1)); // 方法1 this.list [...this.list.slice(0, index), ...this.list.slice(index 1)]; // 方法2 (推荐) // 或者使用数组的 filter 方法 this.list this.list.filter((_, i) i ! index);splice第二个参数deleteCount的误用如果你想插入而不删除必须显式地将deleteCount设为0。splice(2, 1, ‘new’)表示“删除索引2的一个元素并在该位置插入‘new’”而splice(2, 0, ‘new’)才表示“在索引2的位置插入‘new’不删除任何元素”。对稀疏数组的操作结果出乎意料稀疏数组就是含有empty项的数组如let arr [1, , 3];。push、pop、shift、unshift通常表现正常但slice和splice的行为可能需要留意slice会保留空洞而splice在插入时可能会改变空洞的位置。unshift一次性插入多个元素的顺序arr.unshift(‘a‘, ’b‘, ’c‘)的结果是[’c‘, ’b‘, ’a‘]吗不参数列表是从左到右依次插入头部的所以’a‘最先插入反而被挤到了后面最终结果是[’a‘, ’b‘, ’c‘]。记住unshift整体参数列表作为一个块插入头部。5.3 现代JavaScript的补充与替代ES6之后我们有了更多操作数组的优雅方式它们通常更声明式、更易读。扩展运算符...可以替代concat和某些slice场景用于连接数组或复制数组。// 复制数组 const copied [...originalArray]; // 连接数组 const merged [...arr1, ...arr2]; // 配合 slice 实现不可变更新如前文所示Array.from()和...用于类数组转换将NodeList、arguments等类数组对象转为真实数组然后就可以愉快地使用上述所有方法了。const nodeList document.querySelectorAll(div); const divArray Array.from(nodeList); // 或 [...nodeList] divArray.push(newDiv); // 现在可以用了高阶函数filter,map,reduce对于复杂的查找、转换、聚合逻辑这些方法比手动循环加splice等命令式操作更清晰、更不易出错。例如删除满足条件的元素用filter比用splice在循环中倒序删除要安全直观得多。然而这并不意味着我们今天讲的这些基础方法过时了。在需要精确控制索引位置进行增删替换或者实现栈、队列这种基础数据结构时push、pop、shift、unshift、splice依然是最高效、最直接的工具。slice则是进行安全拷贝和截取的标配。工具没有绝对的好坏只有合不合适的场景。真正的高手是清楚每一个工具的特性然后在具体的需求面前做出最恰当的选择。当你再看到push、pop、shift、unshift、slice、splice这些名字时希望它们在你脑中不再是冰冷的API而是一个个有性格、有特长的伙伴随时准备帮你优雅地解决数组处理的各种难题。

相关新闻

Windows Defender保护历史记录清理指南:三种方法详解

Windows Defender保护历史记录清理指南:三种方法详解

1. 项目概述:为什么需要清理“病毒和威胁防护”历史记录? 如果你和我一样,是个对系统整洁度有点“强迫症”的Windows用户,或者你的工作环境对数据隐私和磁盘空间有严格要求,那你一定不止一次打开过Windows安全中心&…

2026/10/21 2:50:35 阅读更多 →
深入解析操作系统文件管理:从FCB、Inode到VFS与性能调优

深入解析操作系统文件管理:从FCB、Inode到VFS与性能调优

1. 从一次文件操作故障说起:为什么需要理解文件管理?最近在帮一个朋友排查一个奇怪的软件问题。他新买的移动硬盘,在Mac上格式化成exFAT格式,用来存放一些设计素材。在Mac上读写一切正常,但当他回到Windows电脑上&…

2026/10/18 7:27:18 阅读更多 →
基于Python监听个人微信收款,实现自动化资金入账与业务处理

基于Python监听个人微信收款,实现自动化资金入账与业务处理

1. 项目概述与核心价值最近在折腾一个个人小项目,需要实现一个自动化的资金入账识别系统。简单来说,就是当有人通过微信给我扫码付款后,我的电脑能立刻知道这笔钱到了,并且自动触发后续的业务流程,比如给用户的账户充值…

2026/10/20 15:06:29 阅读更多 →

最新新闻

知网AIGC检测原理与降AI工具实测:从标红到通过的完整攻略

知网AIGC检测原理与降AI工具实测:从标红到通过的完整攻略

去年有一阵子,实验室里的几位同学轮流来找我,说同一个问题:初稿明明是自己熬夜搭出来的框架,再用AI润了一轮,结果往知网AIGC检测系统一放,直接标红一片,相似度干到百分之四五十,要求…

2026/10/21 2:51:01 阅读更多 →
论坛系统全栈开发实战:从数据模型到安全部署的完整复盘

论坛系统全栈开发实战:从数据模型到安全部署的完整复盘

论坛这种项目,乍一看像是给学生练手的“增删改查”,真想从头到尾做完并且顺利上线,你会发现它把全栈开发里比较麻烦的地方都串起来了:账号体系、内容管理、权限控制、搜索通知、安全防护、性能优化、部署备份,一个都不…

2026/10/21 2:51:01 阅读更多 →
从零搭建论坛全流程:PHP+数据库实战指南

从零搭建论坛全流程:PHP+数据库实战指南

做综合练习项目,论坛是我见过最划算的选题,没有之一。它不像电商系统那样堆满订单状态机,也不像博客那样功能单一,论坛刚好卡在“麻雀虽小五脏俱全”的位置:用户注册、发帖、回帖、权限、搜索、管理后台,每…

2026/10/21 2:51:01 阅读更多 →
塘沽到临港海岸线骑行攻略:路线规划、装备清单与GPS码表数据记录指南

塘沽到临港海岸线骑行攻略:路线规划、装备清单与GPS码表数据记录指南

骑行是一项很适合用数据和装备来提升体验的活动。这篇文章不写骑行本身的速度与激情,而是从技术分享的角度,把塘沽到临港这条海岸线骑行路线拆解成一份可以照着操作的攻略:如何规划路线、需要准备什么装备、如何用手机或码表记录数据、遇到问…

2026/10/21 2:51:01 阅读更多 →
关于图像验证码问题,解决方案

关于图像验证码问题,解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 2:51:01 阅读更多 →
基于Django的爬虫与大数据二手房信息采集系统实战解析

基于Django的爬虫与大数据二手房信息采集系统实战解析

做毕设最怕什么?不是不会写代码,而是代码写完了,老师问你“你这个系统架构是怎么设计的”“数据怎么保证不重复”“可视化图表背后的接口是怎么组织的”,你支支吾吾答不上来。今天聊的这个项目——基于Django的爬虫与大数据二手房…

2026/10/21 2:50:01 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →