Java List 全面解析:从 ArrayList 扩容到 LinkedList 选型
写Java写了快十年List大概是我用过最多的集合接口没有之一。但真正让我把这玩意儿彻底想明白的不是业务代码写了多少遍new ArrayList()而是某次面试候选人时我顺口问了一句ArrayList 的扩容机制了解吗对面支支吾吾半天说不出个所以然。那一刻我突然意识到很多人用了好几年 List其实只停留在会用的层面底层是什么、为什么这么设计、哪些场景该换哪种实现并没有系统捋过。这篇文章就是把我对 Java List 的理解从头到尾梳理一遍包括接口设计、两个核心实现类的源码差异、日常使用中的高频坑、遍历和排序的性能真相还有面试里常被追问的那几个点。适合刚学 Java 基础的人用来建立完整认知也适合写了两三年业务代码、想回头补一补底层原理的开发者。看完之后你至少能回答清楚ArrayList 和 LinkedList 到底该怎么选循环里删元素为什么老报 ConcurrentModificationException这类问题并且能讲出背后的原因。1. 从数组到 ListJava 集合框架里的动态数组到底解决了什么要理解 List得先回到数组。数组是 Java 里最基础的数据结构它有一个很纯粹的特点连续内存 定长。这两个特性带来了两个直接后果——随机访问极快因为通过首地址加偏移量就能算出元素位置但一旦长度定死了想扩容就得自己折腾一个新数组然后把旧元素一个个拷过去。更麻烦的是增删元素时如果保持顺序不变后面的元素全得跟着挪位置。1.1 数组的痛点与 List 的诞生想象一下这个场景你写一个学生管理系统从数据库查出来的学生数量不确定今天 100 个明天可能 5000 个。用数组的话你得先猜一个上限比如new Student[500]结果后天来了 600 个学生直接数组越界你猜大了呢5000 的数组只用 500内存浪费得离谱。这只是个静态问题更折磨人的是增删在数组中间插一个人后面所有人的下标都要后移一位删一个人后面的人又要前移。每次都要写循环手动搬元素代码丑陋不说还特别容易下标越界。List 接口就是冲着解决这些问题来的。它把自动扩容按位置插删迭代遍历这些通用能力抽象成了接口方法让使用者不用关心底层到底是数组还是链表只管add、remove、get。这也体现了 Java 集合框架的一个核心设计思想面向接口编程。你写业务代码的时候依赖List这个接口哪天发现ArrayList性能不合适了换一个实现类就能切走上层代码几乎不用改。1.2 List 接口的方法清单与设计逻辑List 继承了Collection接口所以add(E)、remove(Object)、contains(Object)、iterator()、size()这些方法它都有。但它跟 Set 和 Queue 最大的区别在于两点有序和带索引。有序意味着元素按照插入的顺序排列你在 index 0 放了一个 A那遍历的时候 A 永远在第一位除非你主动改。带索引意味着它能通过下标精确操作所以 List 额外定义了一批和位置相关的方法add(int index, E element)在指定位置插入元素后面的元素自动后移get(int index)/set(int index, E element)按下标取值 / 修改值remove(int index)删除指定位置的元素indexOf(Object o)/lastIndexOf(Object o)查找元素第一次 / 最后一次出现的下标subList(int fromIndex, int toIndex)截取子视图这套方法设计很符合直觉因为下标这个概念来自数组而数组是几乎所有程序员最早接触的数据结构。List 的常见实现类里ArrayList是拿动态数组实现的LinkedList是拿双向链表实现的Vector是老古董加了把锁的数组。三者各有侧重后面我会逐个拆开看。2. ArrayList 与 LinkedList同一个爹两种活法面试里问ArrayList 和 LinkedList 的区别大多数人能背出数组 vs 链表随机访问快 vs 插入删除快。但真到选型的时候很多人又含糊了——因为背的是结论不知道结论背后的场景边界。这一节我们就从源码设计的角度把事情彻底掰扯清楚。2.1 ArrayList 源码级拆解动态数组的扩容与随机访问ArrayList 本质上就是一个会自己长大的数组。它内部维护了一个Object[] elementData所有的元素都存在这个数组里。如果你用无参构造创建new ArrayList()JDK 8 及之后版本里它并不会立刻分配一个容量为 10 的数组而是先给一个空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA直到第一次add才真正分配 10 个位置。这个优化叫懒加载目的是省下那些创建了却不用的对象内存。真正有意思的是扩容逻辑。当数组满了再add一个新元素时ArrayList 会计算新容量int newCapacity oldCapacity (oldCapacity 1)也就是每次扩容到原来的 1.5 倍。然后Arrays.copyOf把旧数组的内容搬进新数组。举个例子默认容量 10第 11 个元素进来时扩容到 15第 16 个元素进来时扩容到 22再往后 33、49、73……每次扩容都会发生一次 O(n) 的数组拷贝。但从摊还分析的角度看因为扩容是倍增的均摊下来每次add的时间复杂度依然是 O(1)。这也是为什么我们常说ArrayList 尾部添加很快。为什么扩容倍数选 1.5而不是 2 倍或者 1.2 倍这是空间和时间的一个折中。扩容倍数越大扩容次数越少但浪费的空间越多倍数太小扩容频率太高拷贝开销变大。1.5 倍意味着每次扩容后数组里有大约三分之一的空余位置既能扛住后续的继续添加又不会像 2 倍那样动不动就浪费一半内存。这个设计跟 HashMap 的 0.75 负载因子一样都是工程上的平衡。至于随机访问get(int index)的源码其实就是一行return elementData[index];靠的是数组连续内存的特性直接走偏移量寻址所以是 O(1)。但add(int index, E)和remove(int index)就没那么痛快了你得先把 index 位置之后的元素全部往前或往后搬一格源码里对应一句System.arraycopy时间复杂度是 O(n)。2.2 LinkedList 的双向链表结构插入删除真的更快吗LinkedList 的名字很直白底层就是一个双向链表。它内部定义了一个Node类包含三个字段item存数据next指向下一个节点prev指向上一个节点。整个链表靠一个first指针和一个last指针维护头和尾不要求连续内存每个节点是独立分配的。因为持有头尾指针LinkedList 在addFirst(E)、addLast(E)、removeFirst()、removeLast()这些端点操作上都是 O(1) 的。它实现了Deque接口所以也能当队列和双端队列用——这个能力 ArrayList 是没有的。但是很多人都背过LinkedList 插入删除比 ArrayList 快这句话其实只在头部和尾部成立。如果你要在中间位置插入或删除LinkedList 得先从头或者尾开始沿着链表找到那个下标位置的节点这个查找是 O(n) 的。源码里有一个node(int index)方法做了个小优化先判断 index 离头部近还是离尾部近然后选择从哪头开始遍历时间复杂度是 O(n/2)。所以当你执行list.add(3, element)真正的大头开销在找节点插入本身只是改几个引用。此外LinkedList 的内存开销也更扎眼。每个元素除了数据本身还要额外存两个引用。在 64 位 JVM 开启压缩指针的情况下一个 Node 对象头 12 字节 int 对齐后 4 字节 两个引用 8 字节 数据引用 4 字节算下来单节点常驻 30 字节起步。存一万个元素光链表结构本身就有几十万字节的额外开销。相比之下ArrayList 虽然会有扩容留下的空位但在元素密集的场景里整体内存往往更省。2.3 实战选择建议与基准测试思路实际业务里怎么选我个人的结论很干脆如果你的操作模式是尾部追加 随机访问比如缓存一批查询结果、组装返回给前端的 DTO 列表无脑用 ArrayList。如果你的操作模式是频繁在头部插入/删除并且数据量还不少比如维护一个最近的浏览记录那 LinkedList 作为队列或者双端队列是有意义的。如果你以为我要在中间频繁插入所以用 LinkedList最好先想想能不能改成尾部追加或直接换数据结构。中间插入对 LinkedList 一点都不友好因为查找节点是 O(n)这跟 ArrayList 的搬元素 O(n)是同一量级的再加上 LinkedList 的节点分配和内存访问不连续实际跑起来往往更慢。我之前帮人优化过一个模块原本数据量两三万代码里到处是list.add(pos, item)用的就是 LinkedList结果接口耗时要 800 多毫秒。改成 ArrayList 之后只降到了 200 多毫秒因为 ArrayList 的System.arraycopy是 JVM 内置的块拷贝操作底层调用的是内存搬运指令比逐节点遍历要快得多。要是你还犹豫可以在本地写个基准测试固定数据量分别测尾部 10 万次 add中间 1 万次 add10 万次 get(i)三种场景用System.nanoTime()对比就清楚了。实践出真知别光背结论。3. 那些年我用 List 踩过的坑subList、Arrays.asList 与 removeList 用起来不难但坑是真不少。这几个坑几乎每个 Java 开发者都踩过而且踩完之后往往一脸懵——代码看起来没问题为什么就报错或者行为诡异了我按自己的踩坑经历一次说清楚。3.1 Arrays.asList 的三宗罪第一宗罪很多人以为Arrays.asList(1, 2, 3)返回的是一个ArrayList然后放心地调用add结果运行时报UnsupportedOperationException。原因是这个方法返回的是Arrays类内部的一个私有静态类Arrays$ArrayList它虽然也叫 ArrayList但不是java.util.ArrayList。这个内部类继承自AbstractList压根没重写add和remove所以这两个方法直接走父类的默认实现——抛异常。第二宗罪用Arrays.asList包出来的 List 是固定大小的不能增不能删但可以set修改元素。这就很憋屈你拿到的像是一个加了壳的数组。第三宗罪这个 List 和原始数组共享内存。你改了数组里的元素List 里的对应元素跟着变反过来你setList 里的元素原数组也会变。这个行为如果没意识到排查数据不一致的问题时会非常抓狂。正确的替代方案很简单如果你要一个真正独立的、可以随意增删的 ArrayList写new ArrayList(Arrays.asList(...))把固定列表作为构造参数传进去它会拷贝一份。如果你用的是 JDK 9 之后的版本也可以考虑List.of(1, 2, 3)它返回一个真正不可变的 Listset、add、remove全是UnsupportedOperationException反而把语义表达得更清楚——我要的就是一个不可变的集合。3.2 subList 的视图陷阱subList(from, to)返回的不是一个新的独立 List而是原 List 的视图。这意味着你对 subList 做add、remove、set原 List 会同步变化对原 List 做结构性修改subList 也会感受到。痛点在于结构性修改之后如果你再继续操作 subList会抛出ConcurrentModificationException。原因在源码里写得明明白白。每个AbstractList维护了一个modCount字段记录结构被修改的次数add、remove、clear都会让它自增。你创建 subList 的时候它会把当时的modCount记下来之后 subList 的每次操作都会先校验如果原 List 的modCount变了说明结构被动了subList 已经不可信直接抛异常。这是 Java 集合框架经典的 fail-fast 机制的体现——宁可快速失败也不在脏数据上继续操作。正确的姿势是如果你只是想取一个独立的子列表用完就丢那就new ArrayList(list.subList(1, 4))拷贝一份彻底和原 List 断开关系。如果你确实要操作视图就时刻记住视图和原列表是连体的别操作完原列表回头又去动视图。3.3 remove 的重载选择与循环安全删除有个经典的代码陷阱ListInteger list new ArrayList(Arrays.asList(1, 2, 3)); list.remove(2);你以为你要删值为 2 的元素但实际上匹配到的是remove(int index)删掉的是下标为 2的元素——也就是数字 3。因为 Java 的重载解析在int和Object之间会优先选择更精确的基本类型int。想删值为 2 的那个元素得手动装箱list.remove(Integer.valueOf(2))。再说循环里删元素。新手最常犯的错是这种for (int i 0; i list.size(); i) { if (条件) { list.remove(i); } }这个写法有两个隐患一是删掉元素后后面的元素前移下标 i 对应的对象已经变了但你循环的 i 还在照常递增会跳过本该判断的元素二是如果你用的是 foreach 或者 Iterator 遍历删完再继续遍历就会触发ConcurrentModificationException原因跟 subList 一样都是modCount对不上。正确姿势有三种用 Iterator 的 removeIterator自己维护了expectedModCount调用iterator.remove()时它会同步更新所以不会报错。用 removeIfJava 8 之后的终极写法一行搞定list.removeIf(x - x % 2 0);倒序 fori 删除从size()-1往 0 遍历删了后面的元素不会影响前面的下标这种写法的好处是原地操作、不用迭代器但也有人不爱读。我个人推荐removeIf语义清晰、性能也不差它底层就是用 Iterator 实现的。4. 随机访问与遍历性能真相与正确的打开姿势List 的遍历看起来是个再简单不过的事但不同的遍历方式在不同实现类上的性能差异有时候能差出几个数量级。搞清楚这件事不是为了让你天天做极致优化而是为了在真正需要优化的时候不会毫无头绪地乱撞。4.1 三种遍历方式的速度对比Java 里遍历一个 List常规手段有四种经典 fori、增强 foreach、显式 Iterator、Java 8 的 Stream。它们之间的关系并不复杂foreach 语法糖编译之后其实就是 Iterator所以 foreach 和 Iterator 性能基本一致fori 是纯下标访问能不能用取决于 List 的实现类Stream 走的是 Spliterator 的 trySplit 路线对 ArrayList 来说底层还是随机访问但多了一层流式处理的开销。对 ArrayList 来说fori 和 foreach 差距不大因为get(i)就是数组取下标而已。对 LinkedList 来说fori 就是一个灾难每次get(i)都要从头或尾遍历链表这意味着遍历 N 个元素的时间复杂度变成了 O(n²)。不信你可以自己跑一个测试给 LinkedList 塞 10 万个元素然后for (int i 0; i list.size(); i) { list.get(i); }你会清晰地感受到什么叫卡顿。这背后的原因就是 LinkedList 的get(int)方法需要node(int)方法从头遍历——O(n) 的单次查找叠加 n 次循环就是 O(n²)。4.2 如何选择遍历方式与性能测试方法我自己实际测过一次数据量 10 万级别ArrayList fori耗时极低毫秒级ArrayList foreach和 fori 差不多LinkedList fori直接飙到几百毫秒甚至更多LinkedList foreach几十毫秒因为 Iterator 是沿着 next 指针走的每个节点只访问一次总体 O(n)LinkedList Stream和 foreach 接近略慢一点这个结果告诉我们一件非常实用的事如果你拿到一个 List不确定它到底是 ArrayList 还是 LinkedList虽然绝大多数时候是前者最稳妥的遍历方式是 foreach 或 Iterator而不是 fori。因为 foreach 对两种实现都是 O(n)fori 对 LinkedList 是灾难。另外提醒一下如果做基准测试别用System.out.println包在循环里打印那会彻底淹没真实的性能差异。正确的做法是把待测代码先预热几轮让 JIT 编译生效然后用System.nanoTime()在方法外计时跑完多次取平均值。工程上不需要每个细节都较真但如果你在写一个接口时发现某个遍历很慢至少要知道从哪里开始排查。Stream 在日常业务代码里我用得很多因为配filter、map、collect(Collectors.toList())写起来确实舒服。但如果你是在写一个热点链路比如每秒要跑几十次的批量处理Stream 的开销还是比 foreach 稍高的。我的习惯是数据量小、逻辑复杂、追求可读性用 Stream数据量大、性能敏感用 foreach。5. 排序、去重与线程安全List 在工程里的高频玩法单讲 List 接口本身没那么多花样但它和排序、去重、并发这几个话题结合起来就能覆盖业务开发里很大一片场景。这一节聊的都是日常能用上的硬功夫。5.1 List 排序Collections.sort 背后与 ComparatorJava 给 List 排序有老、新两代姿势。老的Collections.sort(list)。新的list.sort(comparator)。两者底层其实一样JDK 8 之后都走List.sort方法里面用的是Arrays.sort对对象数组来说排序算法是TimSort——一种结合了归并排序和插入排序的稳定排序。稳定排序意味着两个相等元素的相对顺序不会被改变这在多字段排序时特别重要。自定义排序规则时核心就是Comparator。Java 8 之后用链式调用写多条件排序非常舒服list.sort( Comparator.comparing(User::getAge) .thenComparing(User::getName) .reversed() );这段代码的意思是先按年龄升序排年龄相同的按姓名升序排最后把整体结果反转成降序。注意.reversed()的位置——它对整个比较器生效而不仅仅是最后一个字段。想单独让某个字段降序就写Comparator.comparing(User::getAge).reversed().thenComparing(User::getName)。再说一个很常见的坑如果你用Collections.sort(list)而不传 ComparatorList 里的元素必须实现Comparable接口也就是要能自己比较自己。像Integer、String这些基础类型都实现了Comparable所以排起来没毛病但你自定义的User类默认是没有比较能力的不传 Comparator 直接编译报错。所以我的建议是不管你的类有没有实现 Comparable排序时都显式传一个 Comparator这样语义最清楚也不容易踩坑。5.2 List 去重从 Set 到 Stream distinctList 去重也是高频需求。最简单的方式借助 Set 的特性把 List 扔进去自动去重再转回 List。ListInteger newList new ArrayList(new LinkedHashSet(list));这里用LinkedHashSet而不是HashSet为的是在去重的同时保留原来元素的顺序。HashSet不保证顺序处理完你的列表顺序就乱了LinkedHashSet额外维护了一个双向链表来记录插入顺序所以能保持原序。这段代码很短但它背后是 Set 的基于 equals 和 hashCode 判重机制。Java 8 之后另一种常见姿势是list.stream().distinct().collect(Collectors.toList())distinct()底层也是一个LinkedHashSet所以同样保持顺序。两种写法效果基本一样看团队代码风格取舍。不过要特别留神如果你的 List 里装的是自定义对象那去重结果依赖你重写的equals和hashCode。没重写的话比较的是对象引用——两个字段完全一样的 User只要不是同一个对象就会被当作不同元素保留。这算是自以为去了重实际上什么都没去的典型场景。所以自定义对象的去重第一步永远是确认 equals/hashCode 是否覆写正确。5.3 线程安全什么时候需要 Vector、synchronizedList 和 CopyOnWriteArrayListList 的三个线程安全相关的实现类很多人一上来就懵Vector、Collections.synchronizedList、CopyOnWriteArrayList到底有什么区别什么时候用哪个先说 Vector。它是 JDK 1.0 时代的遗产——每个方法都用synchronized修饰读和写都带锁结果就是并发性能差得离谱而且在复合操作比如先判断再添加上并不能保证原子性。它唯一的价值就是面试会问但业务代码不要用。你几乎找不到一个正当理由在 2026 年去 new 一个 Vector。Collections.synchronizedList(new ArrayList())是把你的 ArrayList 包装一层内部用一个 mutex 锁住所有方法。它解决了单方法原子性问题但有个大坑迭代的时候必须自己手动加锁否则还是可能抛ConcurrentModificationException。源码注释里写得很清楚遍历 synchronizedList 要这么写synchronized (list) { IteratorString iterator list.iterator(); while (iterator.hasNext()) { ... } }很多人只记住了synchronizedList忽略了迭代时加锁这个步骤用着用着就出并发问题。CopyOnWriteArrayList是另一种思路写操作时加锁并把底层数组复制一份在副本上修改然后替换引用读操作不加锁直接读当前数组。所以它特别适合读多写极少的场景比如缓存黑名单、维护监听器列表。它的缺点是每次写都要复制整份数组写频繁的话内存和耗时都不划算。但注意它返回的 Iterator 是弱一致性的——你在迭代过程中别的线程修改了 List迭代器看到的是修改前的快照不会抛异常。这在某些场景里是优点在某些场景里是隐患用它之前要想清楚是否需要强一致性。说到底大部分业务场景里 List 都是线程私有的根本不存在并发访问那你最该做的就是老老实实用 ArrayList别过度设计。6. 面试与实战List 的常见考点和我个人的一点使用习惯到了这一节前面讲的源码和坑其实已经可以串成一张知识网了。面试官问 List 相关的问题万变不离其宗基本都从下面这几个角度出招。我顺便附上我自己的答题思路和日常使用习惯算是给文章收个尾。6.1 面试官爱问的 List 问题第一个高频问题ArrayList 的扩容机制回答要点默认容量 10懒加载每次扩容到原来的 1.5 倍底层Arrays.copyOf拷贝。如果再被追问为什么是 1.5 倍就往空间与时间的权衡展开。这个点能带出你对源码细节的熟悉程度比干巴巴背一道题生动得多。第二个高频问题ArrayList 和 LinkedList 的区别回答要点分三层底层结构动态数组 vs 双向链表、时间复杂度的差异随机访问 / 尾部插入 / 中间插入、内存占用差异。别只说ArrayList 查询快LinkedList 插入快——要能准确说出LinkedList 在中间插入也是 O(n)在有头尾指针的前提下头尾节点操作才是 O(1)。第三个高频问题ArrayList 为什么线程不安全回答要点所有方法都没有加锁多线程同时写会踩到索引越界更严重的是可能把一个线程写的值覆盖掉。典型例子两个线程同时add底层数组同一时刻被两个线程操作各写各的 elementData导致 elementData 大小判断错乱抛ArrayIndexOutOfBoundsException或者丢数据。第四个高频问题fail-fast 机制是什么回答要点modCount记录结构修改次数迭代器创建时记录当时的 modCount每次迭代校验不一致就抛ConcurrentModificationException。再补一句Iterator 自己的 remove 会同步更新 expectedModCount所以迭代中删除要用它。如果面试官再追问 fail-safe你可以顺带提一下CopyOnWriteArrayList的弱一致性迭代器正好把前面讲的并发知识串起来。6.2 我日常使用 List 的几个习惯养成下面这几个习惯能少踩很多坑第一个习惯是创建 ArrayList 时尽可能指定初始容量。如果能预估数据规模比如知道必然要装 200 个元素就写new ArrayList(200)省掉扩容产生的多次数组拷贝。数据量小的时候没感觉数据量上了十万扩容拷贝的开销会非常明显。第二个习惯是对外返回 List 时用Collections.unmodifiableList包一层。这样能防止调用方偷偷改你的内部数据语义也更清晰我只给你读你别动我的东西。注意它返回的不可变是浅层的——里面的元素对象如果是可变对象还是能改这一点要跟团队讲清楚。第三个习惯是使用 removeIf 代替循环删除。循环里删元素这操作不管怎么仔细写都容易在代码评审里被多盯几眼。而removeIf一行写完意图明确底层还替你把 fail-fast 的问题处理好了。Java 8 的项目我找不到不用它的理由。第四个习惯是对 LinkedList 保持警惕优先用队列接口。如果业务场景真的需要频繁在头部加元素我通常会在接口上声明成Deque而不是直接暴露LinkedList这个类这样语义更准确以后想换ArrayDeque也容易。ArrayDeque其实在很多场景下能替代 LinkedList它用循环数组实现头部插入也能达到均摊 O(1)而且内存更紧凑、性能更好。最后一个习惯也当是给大家的建议别怕看源码。Java 的集合框架源码是我见过最容易读的源码之一类不多、命名清晰、注释充分。把 ArrayList 和 LinkedList 两个类翻一遍你之前背过的所有面试题都不用背了因为答案全在代码里。我每次复盘这些基础知识都能发现以前理解不准确的地方这大概就是基础永不嫌旧的道理吧。

相关新闻

JSON Schema验证器实战:从选型到排错,打造稳定的数据校验体系

JSON Schema验证器实战:从选型到排错,打造稳定的数据校验体系

做后端接口也好,做中台数据接入也好,只要系统需要和别人交换 JSON 数据,就一定绕不开一个问题:这份数据到底符不符合约定?我见过太多项目前期图省事,把校验逻辑散落在业务代码里,今天写一个 if&…

2026/10/9 3:08:57 阅读更多 →
Linux信号机制从产生到递送:进程异步通知与信号处理实战

Linux信号机制从产生到递送:进程异步通知与信号处理实战

1. 信号不是玄学:先搞懂它在Linux里的定位1.1 从硬件中断到软件信号的映射关系很多人在初学Linux编程时,对"信号"这个概念总有一种说不清道不明的感觉。程序跑着跑着被CtrlC干掉了,子进程退出时父进程收到一个SIGCHLD,段…

2026/10/9 3:08:56 阅读更多 →
Flutter for OpenHarmony实战:Visibility组件解析与最佳实践

Flutter for OpenHarmony实战:Visibility组件解析与最佳实践

去年我把一个原本跑在 Android 上的 Flutter 应用迁移到 OpenHarmony 开发板上,最让我意外的不是插件兼容清单有多长,而是一个被大多数人当成“if/else 语法糖”的组件——Visibility。当时前端同事看我代码时问了一句:“你这块为啥包个 Visi…

2026/10/9 3:08:56 阅读更多 →

最新新闻

oneTBB concurrent_hash_map 非成员二元比较运算符(operator== / operator!=)详解

oneTBB concurrent_hash_map 非成员二元比较运算符(operator== / operator!=)详解

并发编程高性能计算 【免费下载链接】oneTBB oneAPI Threading Building Blocks (oneTBB) 项目地址: https://gitcode.com/gh_mirrors/on/oneTBB 点击查看 免费下载 导读 本文聚焦 oneAPI Threading Building Blocks(oneTBB)中 oneapi::tbb…

2026/10/9 4:49:04 阅读更多 →
Claude Code 命令速查手册:高频命令、快捷键与高效工作流

Claude Code 命令速查手册:高频命令、快捷键与高效工作流

1. 为什么需要一个命令速查手册刚接触 Claude Code 的人,十有八九会经历这么一个阶段:装好了,敲了个claude进去,然后对着那个闪烁的光标发呆——接下来该干嘛?官方文档当然有,但文档是线性的,从…

2026/10/9 4:49:04 阅读更多 →
ESP32 SoC与模组选型指南:从芯片架构到量产料号

ESP32 SoC与模组选型指南:从芯片架构到量产料号

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

2026/10/9 4:49:04 阅读更多 →
Claude Code Mods扩展开发:工具挂载与终端界面渲染实战

Claude Code Mods扩展开发:工具挂载与终端界面渲染实战

1. 从终端里的AI助手说起:为什么需要给它加装工具和界面很多人第一次接触命令行里的AI编程助手时,感受往往是矛盾的。一方面,它能理解自然语言、能读写文件、能执行命令,确实比传统补全工具强出一大截;另一方面&#x…

2026/10/9 4:49:03 阅读更多 →
SSM框架2025年真实处境与Spring Boot渐进式迁移实战

SSM框架2025年真实处境与Spring Boot渐进式迁移实战

直接开写 说实话,每次在技术群里看到有人问“SSM框架还能打吗”,我就知道问这问题的十有八九是两种人:一种是刚接手了祖传项目、天天被XML配置折磨得想跑路的年轻开发,另一种是还在用SSM做老系统维护、看着外面的技术新闻越来越焦…

2026/10/9 4:49:03 阅读更多 →
LRE框架:重构AI智能体的时间感知与因果记忆机制

LRE框架:重构AI智能体的时间感知与因果记忆机制

1. 这不是“给AI加个备忘录”,而是重构智能体的时间感知能力很多人第一次看到“AI智能体记忆管理”这个词,下意识会想:不就是让大模型多存点上下文、加个向量数据库当外挂硬盘吗?我试过——在某个模拟项目X里,给一个任…

2026/10/9 4:48:03 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26: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/7 13:34:55 阅读更多 →