我是美国达特茅斯学院计算机专业本科生,2010年毕业。达特茅斯学院位于美国东北部新英格兰地区新罕布什尔州,一年中冬季长达近五个月。从学校往北开车三个小时可以到加拿大大都市蒙特利尔练习说法语,往南开车三个小时可以到马萨诸塞州的港口城市波士顿吃羊肉火锅。达特茅斯学院始建于1769年,是美国常春藤盟校之一,在2016年US News美国本科院校排名中位列第11位。
从对计算机的好奇开始
上大学之前,我对计算机科学知之甚少。我唯一记得的事情是在中学计算机课上用 Visual Basic 编写了几个小程序。用我父母的话来说,我离成为一名程序员还差得很远。但我当时并不知道这一切。
达特茅斯学院每年有四个学期,也就是美国俗称的“季度制”。每个季度大约持续 10 周,学生通常选修三门课程,每门课程 1 个学分。要毕业,每个学生必须修满 36 个学分,其中三分之一的课程(12 个学分)是专门针对某一专业的。
达特茅斯学院与其他七所常春藤盟校不同,它属于文理学院。
我非常喜欢文理学院的一点是,你可以在大学前两年自由选择不同领域的课程,探索你的兴趣爱好,找到适合自己的专业。然后,你必须在大二结束前决定专业,并利用大学剩下的两年时间主修你的专业课程。
每年春季学期都会有一门计算机入门课,叫CS5 计算机科学入门。出于对计算机的好奇,我在大一春季选修了这门课。因为CS5是计算机入门课,所以报名的学生还是很多的,大概有70人,这是我在计算机系选修过的学生最多的一门课。
CS5 更注重实践,其中一半是学习 Java 编程语言,另一半是通过 Java 编程学习递归、模块化编程和面向对象编程的概念。它还涉及一些用户界面实现内容。一个学期有 10 周,每周 3 节课,包括 11 个简短作业、5 个实验室作业、2 次期中考试和 1 次期末考试。简短作业的概念是可以在 1 到 2 小时内完成的编程作业。实验室作业是相当于完成 3 到 4 个简短作业的任务,涉及编写相对较大的程序,大约有 500-1000 行代码。考试是一小时的试卷。该课程还配有一名助教 (TA) 和多名部门负责人 (SL)。
TA 每周都会在固定时间安排 Office Hours,学生可以在 Office Hours 时间向 TA 提问,了解课堂上不懂的内容。Section Leader 会负责向学生讲解小作业和实验作业的要求,并给作业打分。TA 主要为计算机系的研究生,SL 主要为修过该课程并当时获得 A 的本科高年级学生。
现在回想起来,我对助教没什么印象,可能是因为从来没去过office hour吧。不过我记得SL,一个学长叫Luke,经常迟到早退,一副无精打采的样子,批改作业也经常出错,所以我经常要他批改成绩。说到成绩,不得不解释一下,美国大学是按照Grade Point Average也就是俗称的GPA来算成绩的,A的分数是4.0,A-是3.66,B+是3.33,B是3,以此类推。我大学四年毕业的时候,满分是4.0,也就是全A,用现在时髦的话来说,我是一个优等生。
对于CS5这门课,如果总分为100分的话,需要92分以上才能拿到A,因为这门课的学生成绩普遍较高,学生对每一分都很在意,包括10%的出勤率,所以他们不能容忍作业或者考试被扣错分,这大概也是我至今还记得上过这门课的SL的原因吧。
高级:定义功能需求和开发实施
虽然整个学习 CS5 的经历有些不愉快,但我还是被如何用计算解决问题所启发,并产生了学习更多知识的热情。于是,在大二的第一个秋季学期,我选修了第二门计算机课程 CS 8。CS 8 也是一门入门课程,但它的课程内容在当时是全新的。它是用 Haskell 编程来学习函数式编程。学习别人没有学过的东西总是令人兴奋的。课程内容也很丰富,包括用函数式编程实现动画、分析生物序列、搜索社交网络、解析和操作 HTML、识别数据簇、解决数独谜题、编写俄罗斯方块游戏等。我记得第一个 Lab 任务是用递归的方式绘制雪花分形。如图所示,仅用 50 行 Haskell 代码就可以在界面上绘制出如此复杂但逻辑清晰的图形。当时感觉非常酷。

经过一个学期的磨合,最后一个 Lab 完成了一个俄罗斯方块游戏从 UI 设计到代码编写,如图所示。这次 Lab 给我的印象比较深刻,因为我花了不少心思去定制并完成了加分功能,从而获得加分。我扮演产品经理的角色定义功能需求,同时也负责这些功能的开发和实现。同时,我也第一次深刻理解了 80:20 法则。做一个产品可能只需要 20% 的努力就能实现基本的功能,但要把这个产品做好、做得精彩,却需要 80% 甚至更多的努力。一路走来,保持谦虚谨慎的态度很重要。

我在读CS8的时候,经常会去计算机实验室,在那里我认识了Douglas Mcllroy,一位著名的数学家和工程师,他在Unix系统中开发了很多命令行工具。还有《算法导论》一书的作者之一Thomas Cormen。Douglas是一个非常安静的人,每次我经过他的办公室,都能看到他安静地写着一些代码。Tom非常幽默,喜欢和学生们谈论美食。每年夏季学期,他都会在自家的院子里举办盛大的烧烤聚会,他和妻子一起烹饪美食,邀请计算机系的所有老师和学生来品尝。我开始喜欢计算机系的氛围了。
大二冬季学期,我同时选修了两门计算机课程,CS19计算机科学中的离散数学和CS 23软件设计与实现。CS 19是一门理论课,是一门以计算机为导向的离散数学课。而CS 23则是一门注重实践的软件设计与开发课。CS 23让我接触到了C语言,10周的时间让我从菜鸟变成了C语言专家。上半学期,我写了一个Web Search引擎,包括三个部分:网络爬虫、文档索引器和查询引擎。下半学期,我写了一个Robotics应用程序,它与安装在电动玩具车上的无线传感器API进行通信,从而控制玩具车并打开摄像头沿途拍照。
人工智能、拓扑学、算法思维
整个冬季学期印象最深刻的,就是晚上下课后去计算机实验室写程序,凌晨1、2点左右离开实验室,看着大雪纷纷扬扬,给整个校园披上了一层新的银色。那时候,我的头脑会感觉特别清醒,如果恰好程序运行成功了,我就会特别开心,会去附近的兄弟会喝酒、社交。
我提到了 CS 19,这是一门计算机理论课程。在这门课上,我遇到了 Afra,她是我接下来两年的计算机“导师”。
大三的时候我跟随 Afra 学习,选修了他的 CS 44 人工智能、CS 85 计算拓扑学,以及毕业论文课程。CS 44 依然保持了对编程的关注,写了多个程序,用于偏向搜索、逻辑、概率推理和通过神经网络进行人脸识别。CS 85 非常难,我记得当时班上只有五名学生,如果少了一名学生,课就没法开了。我也支持我最喜欢的教授选修了这门课。我不记得那个学期是怎么度过的。有很长一段时间,我看着桌上的咖啡杯,觉得那是一个非常美味的甜甜圈,想一口吃掉它。
随后的两年大学生活,我选修了算法导论、计算理论、操作系统、机器学习、统计数据分析等课程,学会了用算法思维综合考虑时间复杂度和空间复杂度来寻找解决问题的最优方案,判断哪些问题是NP-Hard,并编写了简单的操作系统,用一些机器学习的方法和模型做一些数据预测和分类等,那是一段非常快乐又有些孤独的时光。
如果有人告诉你美国大学生不在乎成绩,那绝对是一个笑话。
选修的课程越高级,需要付出的努力就越多,思维逻辑和编程能力也会越强。但与此同时,同年级的同学也会越来越少。从一开始的CS 5班有70名学生,到大二之后,基本上每个计算机班的学生人数都不会超过15人。达特茅斯每年招收大约1000-1200名本科生,但每年毕业的计算机专业学生不超过20人。淘汰率显而易见。
大多数美国大学都会对想留下来继续攻读硕士的学长给予一定的优惠,Dartmouth也不例外。一般本科四年学习结束后,只需要再学习一年完成4+1项目,就可以获得计算机专业的硕士学位。其他学校的申请者则至少要花两年时间。尽管如此,Dartmouth的本科生中愿意留下来攻读计算机专业的硕士学位的却寥寥无几。原因一是大家在计算机系实验室里四年写程序已经快到极限了,迫不及待地想加入Google、Oracle这样的同行,愉快地工作。二是Dartmouth的硕士项目规模很小,学校本身注重本科生的教育。与MIT、Stanford等注重研究生教育的学校不同,硕士生在校园里的归属感没有那么强。
考上任何一所美国顶尖大学四年都不会轻松,如果选择了计算机专业,那就更要努力了。每一门课的成绩很重要,大学四年结束时的GPA也很重要。如果有人告诉你美国大学生不在乎成绩,那绝对是笑话。我大三的时候给一个CS19的教授当批改老师,给学生的作业和试卷批改,每周都会有学生来找我,希望可以扣错题的分数。因为每年大部分一流公司只招一流大学的学生,对学生都会有一个GPA cutoff标准,如果GPA成绩不够,那么简历就会被丢弃,连电话面试的机会都没有。但不管成绩有多重要,既然选择了计算机专业,还是要尽量多找点乐子,无论是听教授讲课的时候,还是TA office hour寻求帮助的时候,还是深夜和同学在实验室写程序的时候。只有喜欢,才会有动力坚持下去,学计算机如此,生活中很多事情也一样。
最后附上达特茅斯2017届校友日历封面图片,祝愿CSDN和大家在新的一年里一切顺利,也祝愿大家的程序员职业道路越来越好。

计算机科学毕业生应具备的核心能力
在ACM制定的最新计算机科学课程标准《计算机科学课程2013》(CS2013)中(注:CS2013已由ACM中国教育委员会和教育部计算机科学专业教学指导委员会翻译,本文内容亦源于此,在此表示感谢),对计算机专业毕业生应具备的核心能力进行了概括和总结如下:
计算机科学专业的毕业生应该对计算机科学知识体系的各个领域(参见 ACM CS2013)有基本的了解,尤其是核心知识中列出的知识领域,并具备这些领域所需的基本能力。他们还应该具备一些知识体系中没有明确列出的基本能力,因为该领域的专业人士往往表现出独特的思维和解决问题的风格,这些风格往往是通过特定的学习和工作经验获得的。下面描述的特征或核心能力是我们认为计算机科学毕业生至少应该具备的基本水平。这些特征将使他们能够在计算领域取得成功,拥有更好的职业生涯。当然,其中一些特征和技能也适用于其他领域,但我们将它们包括在这里,是因为应该明确鼓励学生在计算机科学专业中努力培养这些技能和特征。以下列表基于 CC2001 和 CS2008 中出现的类似列表,但新列表还包括一些实质性更改,这些更改是 CS2013 指导委员会进行研究的结果。
从广义上讲,计算机科学专业的毕业生应具备以下特征(核心竞争力):
对计算机科学的技术理解
毕业生应该掌握计算机科学,体现在知识体系的核心部分。
熟悉常见主题和原则
毕业生需要对一些反复出现的知识点有一定的了解,比如抽象、复杂性、增量变化等,同时也要掌握一些一般的原则,比如共享资源、安全性、并发性等。毕业生应该意识到,虽然这些知识点和原则是在介绍某个特定的知识领域时介绍的,但它们在计算机科学领域有广泛的应用,并不局限于这些特定的知识领域。
了解理论与实践之间的相互作用
计算机科学的一个基本特征是理解理论与实践之间的相互作用以及它们之间的根本联系。计算机科学毕业生需要了解理论和实践如何相互作用。
系统层次视图
计算机科学毕业生需要在多个细节和抽象层面上思考。这种思维方式可以超越每个组件的实现细节,了解计算机系统的整体结构,并了解其构建和分析的过程。他们还需要了解计算机系统将在其中运行的环境以及它将如何与人类用户和物理世界交互。
解决问题的能力
毕业生应该懂得如何将所学知识应用于解决实际问题,而不仅仅是编写代码或移动比特。他们应该能够对系统的功能性、实用性、性能等进行定量和定性的评估,并能够设计和改进系统。他们应该意识到给定问题可能有多种解决方案,做出合理的选择并不是一个纯粹的技术问题,因为这些解决方案将对人们的生活产生真正的影响。毕业生还应该能够清楚地向他人解释他们的解决方案,解释为什么某种解决方案可以解决给定的问题,它如何解决问题,以及它在什么假设下解决了问题。
项目经验
为了确保毕业生能够成功应用所学知识,所有计算机科学毕业生都应参与至少一个主要项目。在大多数情况下,这将是一个软件开发项目,但在特殊情况下,其他项目也可能是合适的。这些项目应侧重于激发学生的综合能力,要求学生评估潜在的解决方案,并且规模应比一般课程中的项目更大。作为项目体验的一部分,学生应借此机会培养和练习人际沟通技巧。
致力于终身学习
毕业生应该认识到,计算领域的进步步伐可谓是飞速的,毕业生必须拥有坚实的基础,使他们能够跟上步伐,并在该领域的进步过程中保持相关技能。编程语言和技术平台会随着时间而变化,因此毕业生需要认识到,他们必须在整个职业生涯中不断学习和调整自己的技能。为了获得这种能力,学生应该接触各种编程语言、工具、范式和技术,并在整个教育过程中始终坚持学习底层基础知识。此外,与他们的前辈不同,今天的毕业生需要管理自己的职业发展和晋升。在寻求职业发展时,毕业生往往需要参与专业活动,如获得认证、参加管理培训和获取其他领域的知识。
承担专业责任
毕业生应该意识到计算所固有的社会、法律、伦理和文化问题,还必须意识到不同国家有不同的社会、法律和道德标准。他们应该意识到伦理问题、技术问题和审美价值观的交织将在计算系统的发展中发挥非常重要的作用。从业者必须了解他们个人和集体的责任以及系统故障可能造成的严重后果,但他们也必须了解他们自身的局限性以及他们使用的工具的局限性。
沟通和组织能力
毕业生应能够向各种受众解释技术问题及其解决方案,这可能涉及面对面、书面和电子交流。他们应准备好作为团队的一员有效地工作,并能够管理自己的学习和发展,包括时间管理、优先顺序设定和进度管理。
承认计算的广泛适用性
计算平台从嵌入式微传感器到高性能集群、分布式云计算中心,计算机应用几乎影响到现代生活的各个方面,毕业生应了解计算技术所有可能的应用方向。
对特定领域知识的欣赏
毕业生应理解计算机技术涉及许多不同领域,解决许多特定领域的问题需要计算机技能和领域特定知识。因此,毕业生应能够在整个职业生涯中与不同领域的专家交流和学习。
注:ACM,即美国计算机协会,成立于1947年,是世界上历史最悠久、规模最大的计算机教育和研究组织。目前,ACM为100多个国家提供服务,拥有涵盖工业界、学术界和政府的8万多名会员,近1000个机构会员。
