让编程再次伟大#5 | 那些年,那些学了也没用的知识
链表与数组的现实较量
标签
媒体详情
- 上传日期
- 2025-06-07 11:54
- 处理状态
- 已完成
- 转录状态
- 已完成
- Latest LLM Model
- gemini-2.5-pro-preview-06-05
转录
speaker 1: 大家好,这里是原子能哥的一个春节,实在是不好意思。 话不多说,植物正题。 speaker 2: 今天的话题从链表开始。 链表应该是大家学到的第一个高级的数据结构,它的设计很巧妙,每一个数据指向下一个数据,环环相扣。 在链表里面插入一个数据,你永远只需要改动三个地方。 而与此相比,同样是把数据串起来的数组结构,运气不好的时候你可能甚至要重写整一个数组。 所以在数据写入的这个时间复杂度上,数组是on链表是O一肉眼可见的,不在一个级别上。 而在软件设计中,数据的完整性拥有了最高的优先度,所以写入速度比读取速度更难优化。 因为你可以允许几千万人同时读取一个数据,但是你只能够让一个人写入以上的知识。 很容易让你得出一个结论,那就是拥有O一写入速度的链表应该就是最好的数据结构之一,应该是软件设计中的首选。 但现实是恰恰相反,因为在现实世界里面,链表是很慢很慢的。 首先在现实中写入数据之前有一个非常重要的步骤,那就是找到要写入的地方。 因为计算机是个笨蛋,他找地址只会沿着源头一步一步的找,先找到这个变量的地址,然后在这个地方发现第一个数据,沿着它指向的地址再来到第二个数据,以此类推,一直到他来到他要改动的这个数据的家里。 而数组结构,无论这个数组有多长,它都只有一个地址。 所以寻址的动作永远就只有一次。 说到这里就可能会有聪明的小伙伴猜到了,这个寻指的动作是很耗时的,它实际上是比写入动作的耗时至少高两个数量级。 那么在这个量级上写入时间就是可以完全忽略的。 现在我们再回去算这个时间复杂度的话,你就会发现数组才是O 1,链表才是那个O N。 而因为cpu缓存的出现,链表的问题在现代计算机上面被进一步的放大。 Cpu缓存的工作原理很简单,cpu要找什么数据,它就会把那整个片区的内存数据都复制过来,放到缓存里面之后,cpu就可以直接从缓存里面获取整一个数据,而不需要再去找问内存。 根据等级的不同,缓存的读取速度会比内存快大约100倍。 而数组结构的数据因为都在同一个地址里,所以运气好的时候缓存会把它整个复制过来,直接获得100倍的提速。 但链表在设计上就和cpu缓存八字不合,因为链表的每一个数据节点它都会随机的分布在内存的各个角落。 每一个节点地址的跳转对于cpu缓存来说都是一个无法预测的命运舞台。 对于任何的缓存机制,不可预测性是最致命的,它代表着你大部分时间缓存都无法命中,你一直都在更新缓存,但是你又一直都用不上缓存。 所以在现实世界里面,除了极个别极特定的场景适合使用链表结构,绝大部分情况下数组都是更好的选择。 其实我们会经常陷入类似链表那样的情况。 在很多的领域我们都会特意打造这么一个与外部隔绝的温室。 我们在这个温室里面去培育知识,投入无数的精力去深入挖掘它、优化它,却很少有考虑这朵花离开了这个温室之后还能不能存活。 这种做法的初衷是好的,它能够让大家的精力更集中,目标更明确,更能做出成绩。 但只是在实际操作中,人们往往无法把握好这个度。 一个很经典例子就是2006年的奈飞百万美元大赛。 这是奈飞为了提升自家推荐系统的准确度,想到一个省钱的小妙招。 比赛内容很简单,奈飞提供了1亿条用户给电影的打分记录,其中有100万条抹去了分数,参赛选手要做的就是猜这百万条记录实际上都打了多少分。 比赛使用的是m1作为评判的标准,奈飞自家的推荐系统,他的ms一误差值是0.9525,谁能够第一个做到误差值比他低10%,就能够拿到100万美元,超过4万个团队参加了比赛。 然后三年之后,一个名叫bcrave programatic chaos的团队第一个突破10%,拿下百万大奖,结束了比赛。 这个团队是确实是很厉害的,因为他们刚开始提交的模型就比奈飞的准确度高了7%,剩下了3%他们花了整整三年。 根据官方的说明,他们是融入了上百个数据模型,进行了各种的排列组合和融合。 这个团队拿了钱,奈飞拿到了模型,这本该是一个皆大欢喜的结局。 反转出现在了三年之后,奈飞的官方宣布他们当年根本就没有用这个模型,而是保留了自家的推荐系统。 而他们给的理由也很简单,他们研究了一番之后发现这个模型的结构太复杂,投产成本太高了。 这也很好理解,毕竟是上百个模型合并起来的融合怪。 而他们自家的现有的推荐系统呢,就是一个非常普通的线性模型,非常容易维护。 而在这个故事里面的奈菲就犯了我之前提到的错误。 他们知道自己的推荐系统在生产环境里面需要应对哪些挑战,对于准确度、速度、扩容能力、开发成本和运营成本等等有哪些需求。 但是基于不知道什么原因,可能是为了简化这个比赛规则吧,他们只是选取了M S一作为评判标准。 那就等于是打造了一个和现实完全不一致的温室,结果就是花了100万买了一朵出了温室就死的花。 这一类的事件在学术界呢跟的是家常便饭。 如果有见过别人怎么水论文,或者是亲自参与过水论文的人,应该都能够理解我说的话。 当然业界也跑不掉啊,类似的问题一样存在。 我们计算机行业的每一个产品,每一个业务,它都是处处紧密相连的一个复杂机器。 但是呢我们的企业就特别自信满满的把每一个角色,每个步骤都拆分成一个独立的温室。 从企业管理的角度来说,这种做法其实也算合理。 因为角色的定位越精准,工作范围划分越明确,你就越容易对这个人进行管理。 但是工作内容可以拆分,工作影响无法拆分。 每个人的每个决策都会对其他人的工作造成影响,而每一个影响都可能会造成连锁反应。 我见过很多失败的产品,在后续的追溯的时候就发现好像大家都没有犯错,每个人都完成了自己的ki找都找不出一个背锅的。 那是因为每个人都被安排在自己的那个温室里面,只需做自己被委派的事情,而忽略了外面的世界。 其实打破温室间的壁垒并不难,只要你找到问题的所在,做一些职务上面的调整,就能够得到很好的效果。 比如说你让项目经理和项目的技术负责人一起进行项目管理,尤其是在早期的筹备阶段,项目管理很多经验都来自于制造业。 我见过不少没有技术背景的项目经理,都很机械的照搬这些经验。 但我们不像制造业那样可以精准的衡量一切的行为。 软件开发是一个具有极大的不确定性的一个生产流程,这是它的本质,是没办法用一些指标给硬压下来的。 所以让项目经理在筹备的阶段就能更多的获得技术负责人的输入,能够更好的让他们对整个项目的落地难度有一个更清晰的认识。 而对于技术负责人更多的参与项目高层建设,能够让他们更好的理解项目的源头、他的目的,他在业务中的定位,也能够帮他们在开发中做出更理性的决策。 另一个我推荐的做法就是开发团队管理自己产品的运维。 在自动化框架满地跑了今天系统运维不再是天书,你的开发团队更有能力自己负责自己产品的运维。 表面上看这是能够提升运维的响应能力,毕竟谁都不会比造产品的人更懂自己的bug在哪里。 但更重要的是能够让开发团队感受到他们的开发决策是如何影响到生产环境的效果的。 俗话说不当家不知柴米贵,当你的程序员在周六凌晨收到告警通知要爬起来处理生产环境的bug时候,他们在下一个开发周期就会更加三思而后行。 而DevOps团队能够把他们宝贵的人生从每一个系统的日常维护里面抽出来,就能够让他们接待更多的系统、更多的项目,有更多的经验去总结、去挖掘,他们作为一个运维可以做出了具有更高价值的贡献。 我在很多地方看到过DevOps的困境,不仅是大公司的运维团队,还有专门搞运维的初创公司,他们每天都是在各种客户的小问题、小细节里面奔波,永远都有处理不完的ticket,永远都在泥场里面打滚。 作为de只有ops没有de一辈子都是古二仔。 speaker 1: 我见过很多人一辈子都在温室里,在读书的时候,他们的探索止步于考试的范围,考完就是永别。 在做研究的时候,他们的课题只针对一个特定的参数。 只要观察到这个参数达标就教论文,后续爱咋咋的。 在工作的时候,上级委派他们做什么他们就做什么,对其他事情毫不关心,我不反对他们过得很舒服。 有些人也喜欢这样的生活,但如果你对计算机有一点热爱,有一点点的追求。 那我鼓励你去尝试打破自己所在的温室,让自己做的事情更有现实价值,让编程再次伟大。
最新摘要 (详细摘要)
概览/核心摘要 (Executive Summary)
本内容的核心论点是,在学术和职业领域中普遍存在一种“温室效应”,即知识和技能在与现实世界隔绝的理想化环境中被学习和优化,导致其在面对复杂的实际应用时变得低效甚至无用。发言人通过两个核心案例——链表与数组的性能悖论和奈飞百万美元大赛——来阐释这一观点。理论上,链表因其O(1)的写入复杂度看似优越,但在现实中,由于寻址耗时和与CPU缓存机制的“八字不合”,其性能远不如理论上写入更慢的数组。同样,奈飞大赛产出的“最精确”推荐算法,因其结构过于复杂、投产成本高昂,最终被奈飞弃用,成了一项“出了温室就死的花”。
报告指出,这种“温室”现象源于为了管理或教学便利,将复杂问题过度简化,并设立孤立的评价标准(如单一的KPI或考试范围)。在企业中,这表现为职能壁垒和部门墙,每个角色在自己的“温室”里完成任务,却忽略了决策对整个系统的连锁影响,导致“每个人都对,但项目却失败了”的困境。为打破这一困局,报告提出了具体的组织性建议:1. 让项目经理与技术负责人从早期就共同管理项目,以确保决策的现实可行性;2. 推行真正的DevOps文化,让开发团队负责自己产品的运维,使其亲身感受决策对生产环境的影响。最终,报告倡议从业者,尤其是对技术有追求的人,应主动打破自身所处的“温室”,让工作创造出更具现实意义的价值。
核心观点:“温室效应”——理论与现实的脱节
发言人(speaker 2)提出了一个核心概念,即许多知识和技能是在一个与外部隔绝的“温室”中被培育的。在这种理想化环境中,人们投入大量精力进行挖掘和优化,但却忽略了这些成果在真实、复杂环境下的生存能力。
- 初衷与问题:这种做法的初衷是好的,能让精力更集中、目标更明确。但问题在于,人们往往无法把握好理论与现实之间的“度”,导致创造出的成果脱离实际。
- 表现形式:
- 学术界:研究课题只针对特定参数,一旦达标就发表论文,不考虑后续的实际应用价值,被比喻为“水论文”。
- 企业界:将复杂的业务流程拆分成独立的、目标单一的岗位(温室),虽然便于管理,但割裂了工作之间的内在联系。
案例一:链表(Linked List)——理论最优与现实最慢的悖论
这是阐述“温室效应”的第一个技术案例,对比了数据结构中链表和数组在理论与现实中的性能差异。
-
理论上的优势(“温室”内的认知):
- 写入速度:链表的写入操作时间复杂度为 O(1),因为只需改动三个指针。
- 对比数组:数组在插入数据时,最坏情况下需要移动所有后续元素,时间复杂度为 O(n)。
- 初步结论:基于“数据写入比读取更难优化”的原则,链表似乎是软件设计中的首选数据结构。
-
现实中的性能瓶颈:
- 寻址成本被忽略:在写入前,必须先找到目标位置。
- 链表寻址:需要从头节点开始,一步步遍历,寻址时间复杂度为 O(n)。
- 数组寻址:通过基地址和索引直接计算,寻址时间复杂度为 O(1)。
- 关键数据:发言人强调,
寻指的动作是很耗时的,它实际上是比写入动作的耗时至少高两个数量级。因此,在总耗时中,写入时间几乎可以忽略,寻址时间占主导。
- 与CPU缓存机制的冲突:
- CPU缓存原理:CPU读取数据时,会将其附近的一整片内存区域加载到高速缓存(Cache)中,后续读取速度可提升约100倍。
- 数组的优势:数组的元素在内存中是连续存储的,很容易被整个加载到缓存中,从而获得巨大性能提升。
- 链表的劣势:链表的节点在内存中是随机分布的,每次跳转到下一个节点都可能导致缓存未命中(Cache Miss)。
对于任何的缓存机制,不可预测性是最致命的,这使得链表无法有效利用现代计算机的缓存优势。
- 寻址成本被忽略:在写入前,必须先找到目标位置。
-
结论:综合考虑寻址和缓存后,现实世界中数组的时间复杂度接近 O(1),而链表则是 O(n)。因此,除了极少数特定场景,
绝大部分情况下数组都是更好的选择。
案例二:奈飞百万美元大赛——脱离生产环境的“完美模型”
这个商业案例进一步说明了在更宏观的层面,“温室”思维如何导致资源浪费。
-
比赛背景 (2006年):
- 目标:奈飞(Netflix)希望将其电影推荐系统的准确度提升10%。
- 评判标准:仅使用均方根误差(RMSE,原文误称为M S一)作为唯一评判标准。
- 奖金:100万美元。
-
比赛结果:
- 一个名为
bcrave programatic chaos的团队历时三年,通过融入了上百个数据模型的复杂方法,成功将误差降低了10%,赢得大奖。
- 一个名为
-
反转与教训:
- 奈飞的决定:三年后,奈飞官方宣布根本没有使用这个获奖模型。
- 原因:
他们研究了一番之后发现这个模型的结构太复杂,投产成本太高了。相比之下,奈飞自家的线性模型虽然准确度稍低,但维护和部署都非常简单。 - 核心错误:奈飞在设计比赛时,创造了一个与现实生产环境脱节的“温室”。他们只关注“准确度”这一个指标,忽略了开发成本、运营成本、系统扩容能力、可维护性等关键的现实因素。
- 最终评价:
花了100万买了一朵出了温室就死的花。
“温室效应”在企业与学术界的普遍性
发言人将上述案例中的问题推广到更广泛的组织环境中。
- 企业管理的困境:
- 企业为了管理的便利性,倾向于将每个角色和步骤拆分成独立的“温室”,
角色的定位越精准,工作范围划分越明确,你就越容易对这个人进行管理。 - 根本矛盾:
工作内容可以拆分,工作影响无法拆分。每个人的决策都会产生连锁反应,影响到其他人。 - 失败的根源:很多失败的项目在复盘时,发现
好像大家都没有犯错,每个人都完成了自己的ki[KPI]。失败的原因是每个人都只在自己的“温室”里工作,忽略了外部世界的变化和影响。
- 企业为了管理的便利性,倾向于将每个角色和步骤拆分成独立的“温室”,
解决方案:打破“温室”壁垒,促进跨职能协作
发言人提出了两个具体的、可操作的建议来打破组织内的“温室”。
-
建议一:项目经理(PM)与技术负责人(Tech Lead)共同管理项目
- 问题现状:很多没有技术背景的PM机械地照搬制造业的项目管理经验,而
软件开发是一个具有极大的不确定性的一个生产流程,无法用硬性指标压制。 - 协同优势:
- 对PM:技术负责人的早期介入,能帮助PM更清晰地认识项目的落地难度和技术风险。
- 对技术负责人:参与高层规划,能让他们更好地理解业务目标,从而在开发中做出更理性的技术决策。
- 问题现状:很多没有技术背景的PM机械地照搬制造业的项目管理经验,而
-
建议二:开发团队管理自己产品的运维(DevOps)
- 表面价值:提升运维响应速度,因为
谁都不会比造产品的人更懂自己的bug在哪里。 - 深层价值:让开发团队亲身感受其决策对生产环境的实际影响。
俗话说不当家不知柴米贵,当程序员不得不在凌晨处理自己代码引发的生产事故时,他们未来的开发决策会更加审慎。 - 对运维团队的解放:专业的运维(DevOps)团队可以从琐碎的日常维护中解放出来,去总结和挖掘更高价值的跨系统、跨项目经验,避免陷入
永远都有处理不完的ticket的泥潭,成为真正的DevOps,而不是只有Ops的“古二仔”[原文如此,可能指苦力]。
- 表面价值:提升运维响应速度,因为
结论与倡议:打破个人温室,创造真实价值
发言人(speaker 1)在结尾部分发出倡议,鼓励听众反思自己的工作和学习状态。
- “温室”中的人生状态:
- 读书时:探索止步于考试范围。
- 做研究时:课题只关注特定参数达标,然后发表论文。
- 工作时:只做上级委派的事,对其他毫不关心。
- 最终倡议:虽然这种生活可能很“舒服”,但对于
对计算机有一点热爱,有一点点的追求的人来说,应该主动尝试打破自己所在的温室,让自己做的事情更有现实价值。 - 结束语:
让编程再次伟大。