大连海事大学吧 关注:199,484贴子:4,211,476

每个计算机学生都应该知道的事

只看楼主收藏回复

本文翻译自What every computer science major should know (might.net)如果想看原文自己去看,我这个英语菜鸡翻译的可能有所偏差,我在文章中也斗胆加入了一些自己的经验,放在了(注:)里面,你可以认为文章中括号里的注是我的私货,文章中有很多链接,但是贴吧发链接会被吞,所以完整版请移步鼠鼠之前发的自己写的求生笔记的网站
那么现在开始:
鉴于该领域的迅猛发展,如何辨别现代计算机科学的内容已有些困难。
我所在的院系正在进行这场争论,因此我将自己的想法整理出来,作为对 "计算机科学专业的学生应该掌握哪些知识 "这一问题的回答。
我试图从以下四个方面来回答这个问题:
1.为了找到一份好工作,每个学生都应该知道些什么? 2.每个学生应该知道什么才能保持终身就业? 3.每个学生应该知道什么才能进入研究生? 4.每个学生应该知道什么才能造福社会? 我的以下想法既包括一般原则,也包括与现代计算机领域相关的具体建议。
计算机科学专业:请将此作为自学指南。
请通过电子邮件或推特提出增删建议。
更新:感谢您的建议和提醒!我会将收到的建议和提醒纳入本指南,使其成为一份有生命力的文档。


IP属地:辽宁1楼2023-10-06 14:29回复
    作品集与简历
    计算机科学专业脱胎于工学和数学,因此在招聘毕业生时会以简历为基础。
    简历并不能完全说明程序员的能力。
    每个计算机科学专业的学生都应该建立一个作品集。
    作品集可以像个人博客一样简单,为每个项目或成就撰写一篇文章。更好的作品集应包括每个项目的页面,以及可公开浏览的代码(也许托管在 github 或 Google code 上)。(注:GitHub一定要会,至于个人博客国内可以使用博客园或者CSDN等等,甚至知乎)
    对开放源代码的贡献应加以链接和记录。
    代码项目可以让雇主直接判断你的能力。
    而 GPA 和简历则不一定。
    教授应设计课程项目,使学生对作品集留下深刻印象,学生也应在每门课程结束时花时间更新作品集。(注:我们学校就别指望了)


    IP属地:辽宁2楼2023-10-06 14:30
    回复
      技术交流
      计算机科学领域很少有 "孤狼 "。
      现代计算机科学家必须努力向非程序员清晰、有说服力地传达自己的想法。
      在规模较小的公司,程序员能否将自己的想法传达给管理层,可能决定公司的成败。
      遗憾的是,这并不是一门课就能解决的问题(当然,扎实的技术交流课程也无妨)。
      更多的课程需要为学生提供展示自己作品的机会,并通过口头报告为自己的想法辩护。
      具体建议 我建议学生掌握一种演示工具,如 PPT 或(我最喜欢的)Keynote。(抱歉,虽然我很喜欢它们,但基于 LaTeX 的演示工具实在是太静态了)。
      在制作精美的数学文档方面,LaTeX 无与伦比。技术课程中的所有书面作业都应使用 LaTeX 提交。


      IP属地:辽宁3楼2023-10-06 14:30
      回复
        工程学核心
        计算机科学并不完全是工程学。(注:在国内是工科之一)
        但是,它已经足够接近了。
        计算机科学家会发现自己在与工程师一起工作。
        计算机科学家和传统工程师需要说同一种语言–一种植根于实分析、线性代数、概率论和物理学的语言。
        计算机科学家应该通过电磁学来学习物理学。但是,要做到这一点,他们还需要学习多元微积分(以及微分方程)。
        概率和(通常情况下的)线性代数的扎实的基础在构建合理的模拟时是非常重要的。在解释结果时,对统计学的扎实理解也是无可替代的。


        IP属地:辽宁4楼2023-10-06 14:30
        回复
          Unix 理念
          (注:你现在最好还是学Linux,至于Linux和unix的关系自己去查)
          计算机科学家应熟练掌握并实践 Unix 计算哲学。
          Unix 哲学(相对于 Unix 本身)强调通过语言抽象和组合来实现计算。
          在实践中,这意味着要熟练掌握命令行计算、文本文件配置和无集成开发环境软件开发的概念。
          具体建议 鉴于 Unix 系统的普遍性,当今的计算机科学家应熟练掌握基本的 Unix 操作,包括以下能力:
          浏览和操作文件系统; 使用管道组成进程(注:也就是Unix中将左边输出作为右边输入的一种命令) 熟练使用 emacs 和 vim 编辑文件;(注:只用vin也行) 为软件项目创建、修改和执行 Makefile; 编写简单的 shell 脚本。 学生如果不了解 Unix 的强大功能,就会拒绝接受 Unix 理念。因此,最好的办法是让学生完成 Unix 具有相对优势的有用任务,例如:
          查找指定目录中占用空间最大的五个文件夹。 报告计算机上重复的 MP3(按文件内容而非文件名)。 列出名字和姓氏小写的人名表,并正确重写。 找出所有以 x 为第二个字母、以 n 为倒数第二个字母的英文单词。 通过网络将麦克风输入直接连接到另一台电脑的扬声器。 用下划线替换指定目录下文件名中的所有空格。 报告最近十次从特定 IP 地址对网络服务器的错误访问。


          IP属地:辽宁5楼2023-10-06 14:31
          回复
            数据结构与算法
            学生当然应该看到常见(或罕见但不合理的有效)数据结构和算法。
            但是,比了解具体算法或数据结构(通常很容易查到)更重要的是,计算机科学家必须了解如何设计算法(如贪心、动态规划),以及如何跨越理想中的算法与实现算法的细枝末节之间的鸿沟。
            具体建议 寻求长期稳定就业的计算机科学家至少应了解以下所有知识:
            哈希表 链表 树 二叉搜索树 有向和无向图。 计算机科学家应能实现或扩展对这些数据结构进行操作的算法,包括搜索元素、添加元素和删除元素的能力(也就是增删改查)。
            为完整起见,计算机科学家应了解每种算法的命令式和函数式版本。


            IP属地:辽宁7楼2023-10-06 14:31
            回复
              理论
              掌握理论是开展研究的前提。
              (注:一般来说,理论是一种对现象或概念的抽象和系统的描述和解释,它可以用数学或逻辑的方法来表达和证明。理论可以帮助我们理解计算机的本质、能力和限制,以及设计和分析有效的算法和程序。)
              当理论为问题提供了明确的界限时(或者当理论提供了规避最初看似明确界限的方法时),理论就显得弥足珍贵。
              计算复杂性是计算机 "科学 "中为数不多的真正具有预测性的理论之一。
              计算机科学家必须知道可操作性和可计算性的界限在哪里。如果忽视这些界限,轻则造成挫折,重则导致失败。
              具体建议:
              在本科阶段,理论至少应涵盖计算模型和计算复杂性。
              计算模型应涵盖有限状态自动机、正则表达式(和正则表达式)、下推自动机、无上下文语言(注:比正则表达式还离谱的东西)、形式化语法、图灵机、lambda 微积分和不可判定性。
              在本科阶段,学生至少应学习足够的复杂性知识,以了解 P、NP、NP-Hard 和 NP-Complete 之间的区别。
              为避免留下错误印象,学生应通过还原到 SAT 和使用现代 SAT 求解器来解决一些 NP 中的大型问题。
              (注:我也不会)


              IP属地:辽宁8楼2023-10-06 14:32
              回复
                计算机体系结构
                对计算机体系结构的扎实了解是无可替代的。
                计算机科学家应该从晶体管开始了解计算机。
                对体系结构的理解应包括标准的抽象层次:晶体管、门、加法器、复用器、触发器、ALU、控制单元、缓存和 RAM。
                在可预见的未来,了解高性能计算的 GPU 模型将非常重要。
                具体建议 充分了解缓存、总线和硬件内存管理对于在现代系统上实现良好性能至关重要。
                为了很好地掌握机器架构,学生应该设计和模拟一个小型 CPU。
                (注:其实就是模电数电)


                IP属地:辽宁9楼2023-10-06 14:32
                回复
                  操作系统
                  任何足够大的程序最终都会成为操作系统。
                  因此,计算机科学家应该了解内核如何处理系统调用、分页、调度、上下文切换、文件系统和内部资源管理。
                  对操作系统的充分了解仅次于对编译器和架构的了解,这样才能实现高性能。
                  在对没有操作系统的嵌入式系统进行编程时,了解操作系统(我将其理解为包括运行时系统)变得尤为重要。
                  具体建议:
                  让学生亲自动手操作真正的操作系统非常重要。有了 Linux 和虚拟机,这比以往任何时候都要容易。
                  为了更好地了解内核,学生可以
                  在启动过程中打印 "hello world"; 设计自己的调度程序 修改页面处理策略 创建自己的文件系统。


                  IP属地:辽宁10楼2023-10-06 14:32
                  回复
                    网络
                    鉴于网络无处不在,计算机科学家应充分了解网络堆栈和网络内的路由协议。
                    对计算机科学家来说,在不可靠的传输协议(如 IP)之上构建高效、可靠的传输协议(如 TCP)的机制不应该是魔法。它应该是核心知识。
                    计算机科学家必须了解协议设计中的权衡取舍–例如,何时选择 TCP,何时选择 UDP。(程序员在大规模使用 UDP 时,也需要了解拥塞所带来的更大社会影响)。
                    具体建议 鉴于现代程序员频繁接触网络编程,了解现有标准的协议很有帮助,例如
                    802.3 和 802.11; IPv4 和 IPv6;以及 DNS、SMTP 和 HTTP。 计算机科学家应了解数据包碰撞解决中的指数退避和拥塞控制中的加-增-乘-减机制。
                    每位计算机科学家都应掌握以下内容:
                    HTTP 客户端和守护进程 DNS 解析器和服务器;以及 命令行 SMTP 邮件程序。 没有一个学生应该在没有用wireshark嗅探到他们的老师的Google搜索请求的情况下通过网络入门课程。
                    要求所有学生从头开始在 IP 上实现一个可靠的传输协议可能有些过了,但我可以说,作为一名学生,这对我个人来说是一次脱胎换骨的经历。
                    (注:如果你想当刻板印象里的黑客,请在这方面努力,顺便把你个人信息私发给我)


                    IP属地:辽宁11楼2023-10-06 14:32
                    回复
                      安全学
                      安全问题的可悲之处在于,大多数安全漏洞都来自于粗心大意的编程。更可悲的是,许多学校在培训程序员如何确保代码安全方面做得很差。
                      计算机科学家必须了解程序如何被被破坏的。
                      他们需要培养一种防御性编程意识–一种思考自己的代码如何可能受到攻击的意识。
                      安全培训最好贯穿整个课程:每个学科都应提醒学生注意自身的漏洞。
                      具体建议 每个计算机科学家至少需要了解
                      社会工程 缓冲区溢出 整数溢出 代码注入漏洞 竞赛条件;以及 权限混乱。 一些读者指出,计算机科学家还需要了解基本的 IT 安全措施,如如何选择合法的好密码,如何使用 iptables 正确配置防火墙。


                      IP属地:辽宁12楼2023-10-06 14:33
                      回复
                        密码学
                        密码学使我们的数字生活成为可能。
                        计算机科学家应该理解并能够实现以下概念,以及在此过程中常见的误区:
                        对称密钥密码系统; 公钥密码系统 安全散列函数 挑战-响应验证 数字签名算法 阈值密码系统。 由于随机数是密码系统实现过程中的常见故障,每个计算机科学家都应该知道如何获取足够的随机数来完成手头的任务。
                        至少,正如几乎所有数据泄露事件所表明的那样,计算机科学家需要知道如何对密码进行加盐和哈希存储。
                        具体建议 每位计算机科学家都应享受使用前现代密码系统和手卷统计工具破解密码的乐趣。
                        RSA 很容易实现,每个人都应该这样做。
                        每个学生都应该创建自己的数字证书,并在 apache 中设置 https。(要做到这一点,难度可想而知)。
                        学生还应该编写一个通过 SSL 进行连接的控制台网络客户端。
                        严格来说,计算机科学家应该知道如何使用 GPG;如何在 ssh 中使用公钥验证;以及如何对目录或硬盘加密。
                        (注:一些名词解释:
                        GPG是GNU Privacy Guard的缩写,它是一种实现了OpenPGP标准的免费软件,可以用来加密和签名数据和通信,具体去看MIT的missing-semester。
                        加盐是一种密码学中的技术,它是指在密码的任意固定位置插入一些特定的字符串,使得密码的散列值(hash)和原始密码的散列值不同,从而增加破解密码的难度)。加盐可以防止攻击者通过使用预先计算的散列值表或暴力破解来猜测原始密码加盐的字符串通常是随机生成的,和用户的密码一起存储在数据库中)


                        IP属地:辽宁13楼2023-10-06 14:33
                        回复
                          软件测试
                          软件测试必须贯穿整个课程。
                          软件工程课程可以涵盖测试的基本方式,但实践是不可替代的。
                          应根据学生提交的测试用例给他们打分。
                          我使用学生上交的测试用例与所有其他学生的测试用例进行对比。
                          学生们似乎不太在乎编写防御性的测试用例,但是他们却会在降低同学的水平方面使出浑身解数。


                          IP属地:辽宁14楼2023-10-06 14:33
                          回复
                            用户体验设计
                            (注:也就是前端)
                            程序员经常为其他程序员编写软件,或者更糟糕的是,为自己编写软件。
                            用户界面设计(或更广义的用户体验设计)可能是计算机科学中最不被重视的方面。
                            甚至在教授中也有一种误解,认为用户体验是一种 "软 "技能,是无法教授的。
                            实际上,现代用户体验设计的基础是人因工程学和工业设计中的经验主义原则。
                            如果不出意外,计算机科学家应该知道,界面需要使执行任何任务的难易程度与任务的频率乘以其重要性成正比。
                            从实际出发,每个程序员都应熟练掌握用 HTML、CSS 和 JavaScript 设计可用的网页界面。


                            IP属地:辽宁15楼2023-10-06 14:33
                            回复
                              可视化
                              良好的可视化就是要以人类能够感知到信息的方式呈现数据。要做到这一点并不容易。
                              现代世界是数据的海洋,利用人类感知的局部最大值是理解数据的关键。


                              IP属地:辽宁16楼2023-10-06 14:33
                              回复