CS教育的幻觉:当"科学家培养计划"遇上"工程师荒" James Hague 2025-10-31 0 浏览 0 点赞 长文 一篇2015年的博客文章突然在Hacker News上"诈尸",引发了一场关于计算机教育本质的激烈论战。James Hague的《那些不存在但本该存在的CS课程》用戏谑的笔调列出了一系列"脑洞课程"——从"反-面向对象编程"到"程序员精神执念"——却意外戳中了整个行业的痛点。这不是一场关于课程设置的技术讨论,而是一次对"我们到底在培养什么人"的集体反思。 ## 那些"不正经"但该死实用的课程 Hague的课程清单读起来像是对学术界的恶搞,但每一条都精准命中现实: **CSCI 2100: 反-面向对象编程。** 课程描述充满讽刺:"教你如何使用那些不在对象层次结构里的变量,以及一种叫'函数'的东西——它像方法,但更有用。"这门课的存在前提是:许多开发者被OOP洗脑太深,已经忘记了编程还有其他范式。 **CSCI 3300: 古典软件研究。** 解剖VisiCalc、Zork和MacPaint等"古董"产品,重点不是怀旧,而是研究它们在极端硬件限制下催生的用户界面创新和工程智慧。这门课暗示:今天的开发者在资源充裕的环境中,反而失去了创造力。 **CSCI 4020: 用慢语言写快代码。** 让Python性能媲美甚至击败C++。这不是玩笑——在真实世界中,算法优化和架构设计往往比语言选择更重要,但没有课程教这个。 **PSYC 4410: 程序员精神执念。** 研究开发者为何对代码格式、命名分类、类型系统等"破事"耿耿于怀。这门课触及了一个禁忌话题:程序员文化中的强迫症倾向,以及它如何影响技术决策。 这些课程的共同特征是:它们都不在任何CS课程大纲里,但每个从业者都曾在职业生涯中痛苦地自学过。Hague用幽默包装了一个严肃的控诉:大学教育与行业需求之间存在巨大鸿沟。 ## 第一战场:历史是财富还是包袱? "古典软件研究"课程点燃了第一场论战。支持者以计算机先驱Alan Kay为精神领袖,认为今天90%的工作都是在"重新发明70年代就已解决的轮子"。一位用户分享了他大学时选修"软件考古学"的经历——重写70年代的编译器练习,当时觉得毫无用处,后来发现"那门课教给我的系统设计知识,比任何现代框架都多"。 但反对声音更加尖锐。一位高赞评论者(PaulDavisThe1st)提出了"基材依赖论":CS和艺术史没有可比性。艺术和哲学的历史跨越千年,而计算机的有效历史不过"三代人的寿命"。更关键的是,艺术对"物质基材"的依赖很小——莎士比亚用鹅毛笔写作,我们用键盘,但文学原理不变。而"计算则完全依赖于其物理基材的性能"——CPU速度、内存大小、网络带宽。 这个论点几乎要终结讨论:1970年在几十KB内存上解决问题的经验,对于今天在几十GB内存上工作的我们,有什么"戏剧性"的教训可言?好比你无法用青铜器时代的冶炼经验来指导如何造航天飞机。 然而"反-反方"的反击更加精彩。一位用户(wanderingjew)立刻反驳:谁说艺术不依赖基材?世纪中期现代家具的标志性"弯曲胶合板",源于二战期间的新胶水技术;19世纪中期颜料的爆发,因为合成染料被发明;荷兰大师们的油画成就,离不开当时荷兰盛产的亚麻籽油。艺术史从来不是纯粹的"思想史",而是"材料、技术与创意的三重奏"。 更深刻的综合观点来自kragen:"基材依赖"论在1970年是对的,但在今天"基本是错的"。对于我们现在99%的应用(比如你正在看的这个网页),限制我们的早已不是硬件,而是"程序员的想象力"。但这恰恰是我们要学习历史的原因——历史中有大量因为当时"基材限制"而失败的绝妙点子(比如50年代的感知机),它们在今天"基材管够"的时代,可能就是下一个金矿。 这场辩论揭示了一个悖论:我们既需要历史视角来避免重复造轮子,又不能被历史束缚而忽视技术环境的根本性变化。关键不在于"学不学历史",而在于"如何提取跨时代的智慧"。 ## 第二战场:OOP是万恶之源还是企业基石? "反-OOP"课程引发了更激烈的意识形态冲突。一个阵营(zkmon)是坚定的"OOP捍卫者",他们的论点直指现实:"企业级Java运行着全世界银行和大型组织的业务骨干。OOP完美地镜像了商业实体和自然的层次结构,而Python在运维就绪和集成方面还是个婴儿。" 这番"企业级"辩护简直是火上浇油。反对者(globular-toast, freetonik)立刻群起而攻之:"用银行来当'把事情搞定'的正面例子,简直是天大的笑话。"许多大型企业软件"质量极其糟糕",它们之所以还在用,不是因为OOP有多好,纯粹是"历史包袱"。一位自称"在银行维护Java垃圾代码"的内部人士(m_rpn)现身说法:银行用这些,不是因为"选择",而是因为"偶然",以及2000年代"OOP咨询顾问"们横行霸道的"遗毒"。 当争论从"Java好不好用"转向"OOP本身"时,全场最精华的评论出现了。用户ninetyninenine发表了一篇堪称"函数式编程宣言"的雄文,将OOP与FP的区别提升到哲学层面: **OOP的核心是"将行为绑定到可变的状态上"。** 一个方法属于一个对象,这个对象承载着不断变化的状态。这导致整个程序变成一张"隐藏依赖的网",牵一发而动全身。你修改一个类,可能影响继承它的十几个子类;你调用一个方法,不知道它会改变哪些内部状态。最终,"重构不再是创造,而是损害控制"。 **FP的核心则是"切断这条锁链"。** 它拒绝将行为绑定到可变状态上。函数只依赖输入和输出,使其变得透明、可预测、可移植。你可以随意组合函数,因为它们之间没有隐藏的耦合。"你的代码库不再像一栋联锁的堡垒,而像一箱乐高积木。" 他总结道:OOP是"把复杂性隐藏在墙后",而FP是"把复杂性分解成足够小、足够透明的部件,以至于复杂性本身变成了可选的"。 当然,也有中间派(GuB-42)指出,问题不在于OOP,而在于我们根本没"真正学懂"它。如果深究底层,方法就是个隐式传递self的函数,继承只是组合的一种特例。正如那句禅宗公案(chuckadams引用)所言:"对象是穷人的闭包","闭包是穷人的对象"。 这场论战的真正价值不在于分出胜负,而在于暴露了一个事实:大多数CS教育只教"如何使用OOP",从不教"何时不该使用OOP",更不会教"OOP与其他范式的权衡"。学生们被灌输了一种范式,却没有获得选择范式的判断力。 ## 第三战场:那些血泪换来的"实战课" 在嘲讽完原作的课程后,社区开始贡献他们自己"血泪中换来的"课程清单。这些课程完美地反映了开发者在现实中真正的"痛"。 **模拟真实世界的"恶意":** - **CSCI 4810: 拒绝实验室**(kelseyfrog提出):模拟越来越不道德的产品需求和不切实际的Deadline。唯一的及格方式是拒绝,并用专业标准来捍卫你的拒绝。这门课教的不是技术,而是职业尊严。 - **CSCI 4812: 职业实验室**(LPisGood补充):作为"拒绝Lab"的对照组,这门课让你观看你的同学如何接受那些不道德的需求、过度承诺,然后抢走你的功劳、先一步升职,而你只能在原地收拾残局。这是对职场政治的残酷模拟。 - **管理层PUA模拟课**(epalm等人提出):当客户(或你的经理)开始疯狂移动"球门"(即改需求)时,你该如何管理自己的反应和项目规格。一位用户(ekidd)分享了Dartmouth大学一门课的真实经历:教授总是在项目截止日期前一周(期末考试前)发邮件"更新"项目规格,以模拟真实世界的混乱。他称之为"一门极其有效的课程"。 **"数字侦探"与"屎山求生":** - **调试101**:这是社区呼声最高的课程之一。许多人(omosubi)抱怨,大学四年没人教过他们"如何调试",以至于很多高级工程师的调试能力还停留在"到处插print"。系统化的调试方法论——从二分查找到时间旅行调试——从未出现在课堂上。 - **化学实验课式的"代码盲盒"**(patrickmay提出):就像化学课上第一天发给你一小瓶"白色粉末"让你去鉴定,CS课应该第一天发给你一个"塞满了Bug和性能问题的遗留代码库"。当你能让所有单元测试和集成测试通过时,这门课就结束了。 - **软件考古学**(NBJack提出):这门课专门教你"数字侦探工作"——如何在拥有大量遗留代码的公司里,通过追踪bug/tickets、翻阅半死不活的旧Wiki、分析版本控制历史,来搞清楚"这坨代码到底在干嘛"。 **那些本该是"基础"的课:** 最令人震惊的是,大量评论者指出,许多现代CS毕业生甚至缺乏最基本的"常识": - **Unix 101**:别光学理论,教教学生怎么用grep、sed、awk去查日志。 - **CI/CD 101**:几乎没有大学课程会提到CI/CD、Jenkins、Docker或Kubernetes。学生们在真空中编写代码,对"代码如何被部署和运维"一无所知。 - **版本控制实战**:不是教Git命令,而是教如何在团队中使用Git——如何写commit message、如何做code review、如何处理merge conflict。 这些课程的共同特征是:它们都关注"软件如何在混乱的现实世界中生存",而非"软件如何在理想环境中被创造"。 ## 核心矛盾:科学家 vs 工程师 这场从2015年延续至今的讨论,最终汇聚到了一个核心问题上:我们一直在混淆"计算机科学(Computer Science)"和"软件工程(Software Engineering)"。 正如评论者abdullahkhalids尖锐指出的,原作中提到的所有"神仙课程"——反OOP、快代码、命令行UX——全都是"工程"(Engineering)、"历史"(History)或"设计"(Design),没有一个是"科学"(Science)。 这正是HN社区怨念的根源:大学的"CS学位"正在培养"科学家",而业界急需的是"工程师"。两者的区别是什么? **科学家关心"为什么"**:为什么这个算法的时间复杂度是O(n log n)?为什么这个协议能保证一致性?为什么这个类型系统是健全的? **工程师关心"怎么办"**:怎么在遗留代码库中添加新功能而不破坏现有系统?怎么在deadline压力下做出技术权衡?怎么说服产品经理某个需求不合理? 一位资深从业者(jillesvangurp)总结得很好:指望CS学位能让你成为合格的软件工程师,这本身就是一种"误解"。学术界教授大多没有一线的工程背景,他们培养的是未来的研究者,而非未来的从业者。一个CS学位真正能证明的,也许只是"你拥有一个能正常运转的大脑"以及"你知道如何学习"。 但问题在于:绝大多数CS毕业生不会成为研究者,他们会进入工业界。这种错配导致了双重浪费——学生花四年学习可能永远用不上的理论,入职后又要花数年自学本该在学校掌握的工程技能。 ## 被忽视的第三条路:设计思维 在"科学"与"工程"的二元对立之外,讨论中还浮现出一个被严重低估的维度:设计。 多位评论者提到,现代软件开发越来越像"设计学科"而非"工程学科"。一位用户(skrebbel)指出,他职业生涯中最重要的技能不是算法或架构,而是"如何设计让用户不会搞砸的界面"和"如何设计让同事能看懂的API"。 这种"设计思维"在CS教育中几乎完全缺失。学生们学习如何实现一个排序算法,但从不学习如何设计一个排序API——它应该是原地排序还是返回新数组?应该接受比较函数还是要求元素可比较?应该稳定排序还是允许不稳定? 更深层的设计问题涉及"约束的艺术"。Hague原文中提到的"古典软件研究"课程,其真正价值不在于学习旧技术,而在于学习"在极端约束下如何创新"。VisiCalc在64KB内存中实现了电子表格,MacPaint用黑白像素创造了直觉的绘图体验——这些案例教授的是"设计智慧",而非"技术技巧"。 一位评论者(pjmlp)提出了一个发人深省的观点:也许我们需要的不是"更好的CS教育",而是"独立的软件工程学位"和"独立的交互设计学位"。就像土木工程从物理学中分离,工业设计从艺术中分离,软件开发也需要找到自己的学科定位。 ## 真正的问题:我们在为谁培养人才? 讨论的最后,一个更根本的问题浮出水面:大学到底应该为谁负责? 一派观点(代表:学术界)认为,大学不是职业培训所,它的使命是培养"完整的人"和"未来的思想者"。CS教育应该教授永恒的原理——算法、数据结构、计算理论——而非转瞬即逝的工具和框架。今天教Docker,明天Docker可能就过时了;但教好算法分析,学生终身受用。 另一派观点(代表:业界)认为,这是学术界的自我陶醉。学生(和他们的家长)花费巨额学费,期待的是"就业能力"而非"思想深度"。当一个CS毕业生连Git都不会用、不知道什么是REST API、看到生产环境的日志就懵逼时,你跟他谈"计算理论"有什么意义? 中间派(代表:务实主义者)提出了一个折中方案:分层教育。本科前两年教"科学"——打好理论基础,培养抽象思维;后两年教"工程"——通过实际项目学习工具、流程和协作。研究生阶段再分化为"学术路线"(深入理论)和"专业路线"(精进工程)。 但这个方案面临一个现实障碍:谁来教"工程"?大学教授大多没有工业界经验,而有经验的工程师又不愿意(或没有资格)进入学术界。这种人才流动的单向性,导致了教育与实践的永久性脱节。 一些评论者提到了"学徒制"模式——学生在学习理论的同时,在真实公司中实习,由资深工程师指导。这种模式在欧洲部分国家(如德国)已经成熟,但在美国和其他地区仍然边缘化。 ## 结语:教育的本质是什么? 这场讨论最终没有给出答案,但提出了更好的问题。也许真正的问题不是"CS教育缺了什么",而是"我们期待教育给予什么"。 如果你期待大学把你变成"即插即用"的程序员,你会失望——因为技术栈变化太快,任何具体技能都会过时。 如果你期待大学把你变成"思想家",你也会失望——因为大多数工作不需要证明NP完全性,而需要在凌晨三点修复生产环境的bug。 也许教育的真正价值在于:它给你一个"学习如何学习"的机会。CS理论教你如何分解问题、如何抽象思考;工程实践教你如何在约束下交付、如何与人协作。两者都不是"答案",而是"工具"——真正的答案,需要你在职业生涯中自己去寻找。 正如讨论中一位老程序员(已退休)所说:"我1985年学的COBOL和汇编,现在一行都不写了。但我学到的'如何面对未知'和'如何在混乱中找到秩序',至今仍在使用。也许这才是教育的意义。" Hague那篇2015年的文章之所以在2025年仍然引发共鸣,不是因为它提出了解决方案,而是因为它用幽默的方式说出了一个残酷的真相:我们都在摸索,没有人真正知道"正确的CS教育"应该是什么样子。而这种诚实的困惑,也许比任何确定的答案都更有价值。 原文:Classes I Wish I Had Taken James Hague 2015年的原始博客文章 Hacker News 讨论串 超过500条评论的深度讨论 《人月神话》 Fred Brooks 关于软件工程的经典著作 Alan Kay: The Real Computer Revolution Hasn't Happened Yet Alan Kay 关于计算机历史重要性的演讲 #CS教育 #Hacker News #OOP #函数式编程 #技术债 #编程范式 #职业发展 #软件工程