C# List 一般用法详解:从底层扩容机制到性能优化与避坑实践
1. 从一次线上事故说起List 为什么值得单独聊很多人看到“C# List 的一般用法”这个标题第一反应是这有什么好讲的不就是Add、Remove、Count吗我一开始也这么想。直到有一次一个跑了半年都没出过问题的数据处理服务在数据量从几万涨到几百万之后内存直接飙到几个 GGC 频繁触发接口响应从几十毫秒涨到好几秒。排查了半天罪魁祸首就是一个看起来人畜无害的ListT——初始化的时候没给容量几百万条数据一条条Add进去底层数组反复扩容、反复复制内存碎片和 GC 压力全来了。这件事让我意识到ListT是 C# 里使用频率最高的集合类型没有之一。它简单到几乎每个初学者第一天就会用但也正因为它太顺手很多人用了好几年都没真正搞清楚它背后的机制。什么时候该用ListT什么时候该换Dictionary或者HashSet容量该怎么预估遍历的时候能不能删元素Remove和RemoveAt到底差在哪Sort的默认行为有什么坑——这些问题平时不显山不露水一旦踩中就是线上事故。这篇内容我打算把ListT从里到外捋一遍。不是那种 API 手册式的罗列而是结合我这些年实际踩过的坑、做过的优化把“一般用法”讲透。适合刚接触 C# 的新手建立正确认知也适合用了几年的老手查漏补缺。核心关键词就一个C# List 的一般用法但我会把每个用法背后的“为什么”都讲清楚让你不只是会调 API而是知道什么时候该调、怎么调才不出事。2. List 的底层结构它到底是个什么东西2.1 本质是一个会自动扩容的数组ListT的内部其实就维护了一个T[]数组加上一个int类型的_size字段记录当前元素个数。你调用Add的时候如果数组还有空位就直接往_size位置塞进去然后_size加一如果数组满了它会创建一个更大的新数组把旧数据复制过去再塞新元素。这个“更大”是多大默认情况下如果当前容量是 0第一次Add会分配容量 4之后每次扩容新容量是旧容量的2 倍。这个 2 倍策略是性能和内存的折中——扩容太频繁会拖慢速度一次扩太大又浪费内存。理解这一点非常关键因为它解释了很多现象。比如为什么ListT的索引访问list[i]是 O(1) 的因为它就是数组下标访问为什么在中间插入元素Insert是 O(n) 的因为要把后面所有元素往后挪一位为什么预估容量能显著提升性能因为省掉了扩容和复制。2.2 容量和元素个数是两码事新手最容易混淆的就是Capacity和Count。Count是当前实际存了多少个元素Capacity是底层数组能装多少个而不触发扩容。举个例子var list new Listint(); Console.WriteLine(list.Count); // 0 Console.WriteLine(list.Capacity); // 0 list.Add(1); Console.WriteLine(list.Count); // 1 Console.WriteLine(list.Capacity); // 4你看只加了一个元素容量就变成了 4。这就是前面说的首次分配策略。如果你继续加到第 5 个元素容量会变成 8然后是 16、32以此类推。这里有个实操建议如果你明确知道要装多少数据一定要在构造的时候指定容量。// 不推荐会经历多次扩容 var list1 new Listint(); for (int i 0; i 100000; i) { list1.Add(i); } // 推荐一次分配到位 var list2 new Listint(100000); for (int i 0; i 100000; i) { list2.Add(i); }我实测过10 万条数据的场景下预分配容量能省掉十几次扩容和数组复制耗时差距在数据量大的时候非常明显。这不是微优化是实打实的性能差异。2.3 值类型和引用类型在 List 里的差异ListT是泛型T 可以是值类型也可以是引用类型但两者在内存布局上差别很大。如果 T 是int、struct这类值类型数据是直接连续存储在数组里的访问效率极高对 CPU 缓存友好。如果 T 是class这类引用类型数组里存的是引用指针实际对象在堆上访问的时候多一次间接寻址。这个差异在数据量大的时候会影响性能。比如你有一个ListPointPoint 是结构体遍历求和会非常快因为数据是连续的。但如果是ListPointClass每个对象散落在堆上缓存命中率低速度会慢不少。所以如果你的场景对性能敏感优先考虑用结构体。不过要注意值类型放在List里每次取出都是复制一份。如果你取出后要修改改的是副本原 List 里的值不变var points new ListPoint { new Point(1, 1) }; var p points[0]; p.X 100; // 改的是副本 Console.WriteLine(points[0].X); // 还是 1要改原值得用索引赋值回去points[0] p;。这个坑我见过不少人踩。3. 增删改查那些你以为会但其实会出错的用法3.1 Add、Insert、AddRange 的取舍Add是往末尾加O(1)均摊。Insert是往指定位置插O(n)因为要挪动后面的元素。AddRange是批量加比循环Add快因为它会一次性检查容量不够就扩一次而不是每个元素都检查。var list new Listint { 1, 2, 3 }; list.Add(4); // [1, 2, 3, 4] list.Insert(0, 0); // [0, 1, 2, 3, 4] list.AddRange(new[] { 5, 6, 7 }); // [0, 1, 2, 3, 4, 5, 6, 7]这里有个经验如果你需要频繁在头部或中间插入ListT不是好选择。每次Insert(0, x)都要把整个数组往后挪数据量一大就是灾难。这种场景应该考虑LinkedListT或者QueueT/StackT具体看你的访问模式。3.2 Remove、RemoveAt、RemoveAll 的区别和陷阱这三个方法名字像行为差别很大Remove(item)删除第一个等于 item 的元素需要遍历查找O(n)。RemoveAt(index)删除指定索引的元素O(n)因为要挪动后面的元素。RemoveAll(predicate)删除所有满足条件的元素一次遍历搞定。var list new Listint { 1, 2, 3, 2, 4 }; list.Remove(2); // [1, 3, 2, 4]只删第一个 2 list.RemoveAt(0); // [3, 2, 4] list.RemoveAll(x x 2); // [2]Remove有个坑它只删第一个匹配项。如果你想删所有匹配的得用RemoveAll或者循环删。但循环删的时候千万别用for正序遍历// 错误示范会漏删 var list new Listint { 1, 2, 2, 3 }; for (int i 0; i list.Count; i) { if (list[i] 2) list.RemoveAt(i); } // 结果[1, 2, 3]第二个 2 被跳过了原因是删掉索引 1 的 2 之后后面的元素前移原来的索引 2 变成了索引 1但循环变量 i 已经加到 2 了正好跳过。正确做法是倒序遍历或者用RemoveAll// 正确倒序删 for (int i list.Count - 1; i 0; i--) { if (list[i] 2) list.RemoveAt(i); } // 更推荐一行搞定 list.RemoveAll(x x 2);这个坑我敢说每个 C# 开发者都踩过至少一次面试也经常考。3.3 遍历时修改集合会抛异常ListT有个版本号机制每次增删改都会让版本号加一。foreach遍历的时候会记录当前版本号每次MoveNext都检查版本号有没有变变了就抛InvalidOperationException。var list new Listint { 1, 2, 3 }; foreach (var item in list) { if (item 2) list.Remove(item); // 抛异常 }这个设计是为了防止遍历过程中集合结构变化导致不可预期的行为。如果你确实需要在遍历时删除用倒序for循环或者先收集要删的元素再统一删var toRemove list.Where(x x 2).ToList(); foreach (var item in toRemove) list.Remove(item);注意修改元素的值比如list[i] 10不会改变版本号foreach里改值是允许的但改的是引用类型对象的属性也没问题。只有改变集合结构增删才会触发异常。4. 查找与排序默认行为里藏着的坑4.1 Contains、IndexOf、Find 的性能差异查找类方法有好几个性能特征不一样方法说明复杂度Contains(item)是否包含某元素O(n)IndexOf(item)返回第一个匹配的索引O(n)Find(predicate)返回第一个满足条件的元素O(n)FindAll(predicate)返回所有满足条件的元素O(n)Exists(predicate)是否存在满足条件的元素O(n)它们都是线性查找数据量大时都慢。如果你需要频繁查找应该考虑用DictionaryTKey, TValue或HashSetT查找是 O(1) 的。ListT适合的是“存了之后偶尔查”或者“数据量不大”的场景。Find和FirstOrDefault功能类似但Find是ListT自己的方法FirstOrDefault是 LINQ 扩展方法。性能上Find略快因为它不需要经过 LINQ 的迭代器封装。小数据量无所谓大数据量高频调用时这个差异会累积。4.2 Sort 的默认行为和自定义比较ListT.Sort()默认使用ComparerT.Default对于实现了IComparableT的类型比如int、string、DateTime可以直接排序var nums new Listint { 3, 1, 4, 1, 5 }; nums.Sort(); // [1, 1, 3, 4, 5] var names new Liststring { banana, apple, cherry }; names.Sort(); // [apple, banana, cherry]但对于自定义类型如果你没实现IComparableT直接Sort()会抛异常。这时候需要传一个比较器public class Person { public string Name { get; set; } public int Age { get; set; } } var people new ListPerson { new Person { Name A, Age 30 }, new Person { Name B, Age 25 } }; // 按年龄排序 people.Sort((x, y) x.Age.CompareTo(y.Age));这里有个重要的点ListT.Sort()是不稳定排序。也就是说年龄相同的两个人排序后谁在前谁在后是不确定的。如果你需要稳定排序相同键的元素保持原有相对顺序得用 LINQ 的OrderByvar sorted people.OrderBy(p p.Age).ToList();OrderBy是稳定排序但性能比Sort差一些因为它会创建中间集合。选择哪个看你的需求要稳定就用OrderBy要性能就用Sort。还有一个坑Sort的比较委托如果写得不严谨可能违反比较的传递性导致排序结果错乱甚至抛异常。比如你写(x, y) x.Age y.Age ? 1 : -1相等的时候返回 1 而不是 0就会出问题。正确的写法是用CompareTo它会正确处理相等情况返回 0。4.3 用 BinarySearch 的前提条件ListT.BinarySearch是二分查找O(log n)比线性的IndexOf快得多。但它有个硬性前提列表必须已经排好序。如果没排序就用结果是未定义的可能找到也可能找不到完全不靠谱。var list new Listint { 1, 3, 5, 7, 9 }; int index list.BinarySearch(5); // 2 // 没排序的列表结果不可预测 var unsorted new Listint { 5, 1, 9, 3, 7 }; int bad unsorted.BinarySearch(5); // 别这么干另外如果元素不存在BinarySearch返回的是个负数它是目标元素应该插入位置的按位取反。这个设计有点反直觉用的时候要注意int index list.BinarySearch(4); if (index 0) { int insertPos ~index; // 按位取反得到插入位置 Console.WriteLine($4 应该插在索引 {insertPos}); }5. 性能优化从能用到底层跑得快5.1 预分配容量是性价比最高的优化前面提过预分配容量这里再展开说一下怎么预估。如果你是从数据库查一批数据通常能提前知道大概数量直接new ListT(count)。如果是动态增长的可以给个合理的初始值比如预计最多几千条就new ListT(1024)避免从 4 开始反复翻倍。翻倍的代价是什么假设最终要装 100 万条从 4 开始扩容会经历 4→8→16→...→1048576总共约 18 次扩容每次都要复制已有数据。累计复制的元素数量大约是最终数量的 2 倍也就是 200 万次复制操作。预分配直接省掉这些。5.2 用 CollectionsMarshal 直接操作底层数组.NET 5 之后提供了一个CollectionsMarshal类可以拿到ListT底层的SpanT直接操作避免复制using System.Runtime.InteropServices; var list new Listint { 1, 2, 3 }; Spanint span CollectionsMarshal.AsSpan(list); span[0] 100; // 直接改底层数组 Console.WriteLine(list[0]); // 100这个用法适合高性能场景比如批量修改、批量计算。但要注意拿到 Span 之后如果对 List 做增删操作Span 可能失效因为扩容会换数组。所以 Span 的生命周期要短拿到就用用完就丢。还有一个CollectionsMarshal.GetValueRefOrAddDefault是给Dictionary用的这里不展开。List这边主要就是AsSpan。5.3 避免装箱值类型集合优先用泛型 List老式的ArrayList是非泛型的存值类型会装箱取出会拆箱性能差且产生垃圾。ListT是泛型的存int就是int没有装箱。所以除非你在维护上古代码否则永远用ListT而不是ArrayList。// 别用这个 var oldList new ArrayList(); oldList.Add(1); // 装箱 int x (int)oldList[0]; // 拆箱 // 用这个 var newList new Listint(); newList.Add(1); // 无装箱 int y newList[0]; // 无拆箱5.4 批量操作优先用 AddRange、RemoveAll单个Add每次都要检查容量AddRange只检查一次。RemoveAll一次遍历完成删除比循环RemoveAt快得多因为循环删除每次都要挪动数组。// 慢每次 RemoveAt 都挪数组 for (int i list.Count - 1; i 0; i--) { if (list[i] 0) list.RemoveAt(i); } // 快一次遍历一次压缩 list.RemoveAll(x x 0);RemoveAll的内部实现是双指针法遍历一遍把保留的元素往前挪最后一次性调整_size。复杂度 O(n)而循环RemoveAt最坏是 O(n²)。6. 线程安全与并发List 不是线程安全的6.1 多线程同时写 List 会发生什么ListT没有任何锁机制多个线程同时Add会导致数据丢失、索引越界、甚至内部数组状态错乱。我见过一个真实案例多个线程往同一个 List 里塞日志跑一段时间后 List 的Count比实际写入的条数少有些日志莫名其妙消失了。原因就是两个线程同时判断“还有空位”然后同时往同一个位置写互相覆盖。如果你需要线程安全的集合有几个选择lock手动加锁简单粗暴但锁粒度大并发性能差。ConcurrentQueueT/ConcurrentBagT适合生产者消费者场景。ImmutableListT不可变集合每次修改返回新集合适合读多写少。private readonly object _lock new object(); private readonly Listint _list new Listint(); public void AddSafe(int item) { lock (_lock) { _list.Add(item); } }6.2 读多写少场景的替代方案如果你的场景是“初始化后基本不改多线程频繁读”那ListT其实是安全的因为只读操作不会改变内部状态。但前提是初始化完成后再发布给其他线程并且之后不再修改。这种“发布后不可变”的模式很常用配合IReadOnlyListT接口暴露出去private Listint _data; public IReadOnlyListint Data _data;这样外部只能读不能改避免了误操作。注意IReadOnlyListT只是个接口约束如果外部拿到实际引用强转回ListT还是能改所以更严格的做法是返回副本或者用ImmutableList。7. 那些年我踩过的 List 坑7.1 在 foreach 里删元素这个前面提过但值得再强调因为它太常见了。除了抛异常还有一种更隐蔽的情况你用for循环删但没注意索引变化导致漏删。这两种坑我都踩过后来养成的习惯是只要涉及删除优先用RemoveAll如果非要用循环一律倒序。7.2 把 List 当队列用有人图省事用ListT当队列Add入队RemoveAt(0)出队。数据量小的时候没问题数据量一大每次出队都要挪动整个数组性能急剧下降。这种场景应该用QueueT入队出队都是 O(1)。// 别这么干 var list new Listint(); list.Add(1); list.RemoveAt(0); // O(n) // 用这个 var queue new Queueint(); queue.Enqueue(1); queue.Dequeue(); // O(1)7.3 忽略了 List 的初始容量导致内存碎片回到开头那个事故。几百万条数据从容量 4 开始反复翻倍每次扩容都分配新数组、复制旧数据、旧数组等待 GC。这个过程产生了大量临时大对象直接进了大对象堆GC 压力巨大。后来改成预分配容量内存曲线立刻平稳了。这个教训是数据量可预估时永远预分配。7.4 用 比较引用类型元素List.Contains、IndexOf、Remove这些方法判断相等用的是EqualityComparerT.Default。对于引用类型默认比较的是引用地址不是内容。所以两个内容相同的对象Contains会返回 falsepublic class Item { public int Id { get; set; } } var list new ListItem { new Item { Id 1 } }; var target new Item { Id 1 }; Console.WriteLine(list.Contains(target)); // False因为是不同对象要按内容比较要么重写Equals和GetHashCode要么用Exists配合自定义条件bool exists list.Exists(x x.Id target.Id); // True这个坑在业务代码里很常见尤其是从数据库查出来的对象和手动 new 的对象比较时。8. 什么时候不该用 ListListT很好用但不是万能的。以下几种情况应该考虑别的集合频繁按 key 查找用DictionaryTKey, TValueO(1) 查找。需要去重用HashSetT自动去重且查找快。频繁头部插入删除用LinkedListT或QueueT/StackT。多线程并发读写用ConcurrentBagT、ConcurrentQueueT或加锁。需要保持插入顺序且频繁删除LinkedListT删除是 O(1)前提是已有节点引用。选择集合的核心是看操作模式读多还是写多按索引访问还是按 key 访问是否多线程。ListT的强项是索引访问和尾部追加其他场景都有更合适的工具。9. 几个容易被忽略的实用细节9.1 ToArray 和 ToList 的区别ToArray返回T[]ToList返回ListT。两者都会复制一份数据原集合的修改不影响新集合。性能上ToArray略快因为它知道最终长度一次分配到位ToList内部也是类似机制。选择哪个看后续用途需要索引访问和增删就用ToList只需要遍历或传递就用ToArray。9.2 Clear 不会释放容量list.Clear()只是把_size设为 0底层数组还在容量不变。如果你清空后想释放内存得手动list.Clear(); list.TrimExcess(); // 把容量缩到实际元素数TrimExcess在元素数远小于容量时有用但它本身也有开销要复制数组所以别频繁调。一般是在大批量删除后调一次。9.3 用 Capacity 属性手动调整除了构造时指定也可以随时设置Capacityvar list new Listint(); list.Capacity 1000; // 直接扩到 1000如果设置的值小于当前Count会抛异常。设置的值大于当前容量会扩容小于当前容量会缩容复制到新数组。这个属性一般用得少预分配在构造时做就够了。9.4 List 的相等性比较两个ListT用比较比的还是引用不是内容。要比较内容是否相同得用SequenceEqualvar a new Listint { 1, 2, 3 }; var b new Listint { 1, 2, 3 }; Console.WriteLine(a b); // False Console.WriteLine(a.SequenceEqual(b)); // TrueSequenceEqual会逐个比较元素顺序也要一致。这个在单元测试里特别常用断言两个列表内容相同。10. 我个人的使用习惯和收尾建议用了这么多年ListT我总结下来几条自己的习惯分享出来供参考。第一能预分配就预分配。不管是构造时传容量还是用AddRange批量加都比一条条Add强。这个习惯一旦养成很多性能问题根本不会出现。第二删除一律用RemoveAll。除非有特殊需求否则不用循环删。RemoveAll又安全又快代码还短。第三对外暴露用IReadOnlyListT。方法返回值如果是给外部用的返回只读接口避免调用方误改。内部该用ListT还是用只是接口层面收窄。第四多线程场景先想清楚再动手。ListT不是线程安全的别心存侥幸。要么加锁要么换并发集合要么用不可变集合。这个没有中间地带。第五选集合先看操作模式。按索引访问多就List按 key 查就Dictionary去重就HashSet队列就Queue。别拿List硬扛所有场景。最后说个小事。ListT的ForEach方法和foreach关键字容易混。list.ForEach(x ...)是List自己的方法foreach (var x in list)是语言层面的遍历。两者功能类似但ForEach内部就是普通for循环不涉及版本号检查所以理论上在ForEach里改集合不会抛异常——但这是未定义行为别依赖它。老老实实用foreach或者for该抛异常就让它抛至少能帮你发现代码问题。这些细节平时不起眼但真到了排查性能问题或者线上故障的时候往往就是这些地方在作祟。把ListT用明白C# 里一大半的集合相关问题就都不会找上你了。

相关新闻

fable-advisor进阶技巧:Luna对Sol同题竞速与并行委派,架构师如何挑出更强的diff

fable-advisor进阶技巧:Luna对Sol同题竞速与并行委派,架构师如何挑出更强的diff

【免费下载链接】fable-advisor Claude Fable as an orchestrator for Opus, GPT and Grok 项目地址: https://gitcode.com/gh_mirrors/fa/fable-advisor 点击查看 免费下载 fable-advisor 是一个 Claude Code 插件,它把当前会话变成"架构师"…

2026/10/15 10:07:04 阅读更多 →
Excel方差分析入门:从数据整理到结果解读

Excel方差分析入门:从数据整理到结果解读

1. 为什么需要Excel做方差分析?第一次接触方差分析(ANOVA)时,我被那些统计软件复杂的界面吓退了。直到发现Excel这个办公软件就能完成基础分析,才真正跨入统计学大门。对于非统计专业的研究者、学生党或职场人来说&…

2026/10/15 10:07:04 阅读更多 →
MATLAB光学衍射模拟:衍射积分与傅里叶变换的双路径实现

MATLAB光学衍射模拟:衍射积分与傅里叶变换的双路径实现

简介:一份基于MATLAB的光学衍射模拟学习文档,面向物理专业学生、光学实验爱好者以及需要借助MATLAB进行科学计算与仿真的人员。文档以衍射积分与傅立叶变换两条技术路线为核心:衍射积分部分从单缝出发,逐步扩展到杨氏双缝干涉和黑…

2026/10/15 10:07:04 阅读更多 →

最新新闻

Teable多维表格如何优化企业运营效率

Teable多维表格如何优化企业运营效率

1. 多维表格在现代运营中的核心价值 运营流程优化一直是企业提升效率的关键课题。传统电子表格在处理复杂业务逻辑时往往捉襟见肘——数据孤岛、版本混乱、权限管理困难等问题长期困扰着运营团队。Teable这类现代多维表格数据库的出现,正在彻底改变这一局面。 我亲…

2026/10/15 11:47:34 阅读更多 →
华为云码道代码智能体实战:从IDE接入到MCP协议配置全解析

华为云码道代码智能体实战:从IDE接入到MCP协议配置全解析

1. 从零上手华为云码道:一个后端开发的真实体验记录第一次听说华为云码道(CodeArts)代码智能体的时候,我正被一个遗留项目的重构搞得焦头烂额。那是个跑了快五年的老服务,代码里到处是复制粘贴的痕迹,命名风…

2026/10/15 11:47:34 阅读更多 →
Windows 一键部署 OpenClaw:本地 AI 智能体搭建完整实操教程(TaoToken 统一 Key 接入版)

Windows 一键部署 OpenClaw:本地 AI 智能体搭建完整实操教程(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/15 11:47:34 阅读更多 →
CLI工具开发与安全实践指南

CLI工具开发与安全实践指南

我无法根据当前输入生成符合要求的博文。 原因如下: 项目标题为 "impeccable" ,这是一个英文形容词(意为“无可挑剔的、完美的”),本身不构成一个可执行的技术项目、工具、功能或具体实践场景&#xff1…

2026/10/15 11:47:34 阅读更多 →
在 OpenCode 中集成 SkillLite:为 AI 代码执行加上一道“原生沙箱防火墙”

在 OpenCode 中集成 SkillLite:为 AI 代码执行加上一道“原生沙箱防火墙”

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

2026/10/15 11:47:34 阅读更多 →
SpringBoot游戏周边商城实战:电商系统开发全解析

SpringBoot游戏周边商城实战:电商系统开发全解析

1. 项目概述与核心价值 作为一名在Java全栈开发领域摸爬滚打多年的老手,我见过太多毕业设计项目沦为"玩具级"演示品。但这个基于SpringBoot的游戏周边商城设计,却是个能真实锻炼工程能力的实战项目。它完整覆盖了电商系统核心模块:…

2026/10/15 11:46:34 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →