96

您认为计算机科学中的哪些概念使您成为更好的程序员?

我的学位是机械工程,所以最终成为一名程序员,我有点缺乏基础知识。我最近学到了一些标准的 CS 概念,这些概念让我对自己正在做的事情有了更深入的了解,特别是:

语言特点

  • 指针和递归(感谢 Joel!)

数据结构

  • 链表
  • 哈希表

算法

  • 冒泡排序

显然,目前该列表有点短,所以我希望得到以下建议:

  1. 我应该理解哪些概念,
  2. 任何可以正确理解它们的好资源(因为维基百科有时可能有点密集和学术性)。
4

33 回答 33

62

看看 Steve Yegge(以前在亚马逊,现在在谷歌)的这篇博文:

它详细介绍了开发人员应该了解的五个最重要的概念:

  1. 基本编程(包括递归、文件 I/O、格式化输出、循环等)
  2. 面向对象的设计(包括设计模式等)。您应该能够产生明智的 OO 设计以及理解这些概念。
  3. 脚本和正则表达式。
  4. 数据结构——列表、集合、哈希表、树、图等等——以及大 O 表示法和算法复杂性。
  5. 位、字节和二进制数——数字在计算机中的表示方式,以及如何操作它们。
于 2009-04-14T12:31:25.893 回答
36

您绝对应该了解算法的Big-O表示法和 Big-O 估计 - 它是什么、如何使用、为什么重要、如何根据 Big-O 估计比较两种算法、如何构建 Big-O 估计对于简单的算法。

于 2009-04-14T12:31:58.637 回答
30

我觉得你在寻找计算机科学科目有点好笑,但觉得维基百科太学术了:D

无论如何,这里没有特别的顺序:

于 2009-04-14T12:38:09.993 回答
14

一些帮助我发展的概念(智力和代码):

  • 词法分析、解析、字符串匹配、正则表达式
  • 记忆
    • 封装/范围/封闭
    • 缓存
  • 递归
  • 迭代器/生成器
  • 函数式编程——John Hughes 的精彩文章让我明白了“为什么”

这些是离散数学的整个领域,但 CS 需要认真介绍:

  • 矩阵/线性代数
  • 图论

尽管Mark Jason-Dominus的讲座和文章经常针对 Perl 黑客,但我认为任何程序员都会从他清晰的演示文稿和真实代码中受益,尤其是在高阶 Perl中。

于 2009-04-14T13:25:22.517 回答
10

我想说的是,现在必须了解面向对象编程,即使您不需要每天都使用它。

由此,我还想说了解最常见的模式也有帮助。

于 2009-04-14T12:32:00.463 回答
10

我看到了几个很好的 CS 概念,但很少谈论数学。

我建议你研究离散数学。它有很多有用的问题,从逻辑证明开始,可以帮助您在代码中编写条件。图论和组合学也有助于解决复杂问题和优化算法。

当我们讨论数学时,线性代数通常是高级计算机图形课程的先决条件。

于 2009-04-14T13:21:01.483 回答
7

程序员能力矩阵详细介绍了这一点,但我会强调几个:

  • 数据结构
    • 高级数据结构,如 B 树、二项式和斐波那契堆、AVL/红黑树、展开树、跳过列表、尝试等。
  • 算法
    • Tree, Graph, 简单的贪心和分治算法,能够理解这个矩阵层级的相关性。
  • 系统编程
    • 了解整个编程堆栈、硬件(CPU + 内存 + 缓存 + 中断 + 微码)、二进制代码、汇编、静态和动态链接、编译、解释、JIT 编译、垃圾收集、堆、堆栈、内存寻址……</li>
  • 源代码版本控制
    • 了解分布式 VCS 系统。已试用 Bzr/Mercurial/Darcs/Git
  • 构建自动化
    • 可以设置脚本来构建系统以及文档、安装程序、生成发行说明并在源代码控制中标记代码
  • 自动化测试
    • 了解并能够设置自动化功能、负载/性能和 UI 测试
  • 问题分解
    • 使用适当的数据结构和算法,并提出通用/面向对象的代码,这些代码封装了问题的各个方面,这些方面可能会发生变化。
  • 系统分解
    • 能够可视化和设计具有多个产品线并与外部系统集成的复杂系统。还应该能够设计运营支持系统,如监控、报告、故障转移等。
于 2009-04-14T14:53:10.450 回答
5

我发现图表和一些应用算法,如深度优先、呼吸优先搜索、最短路径等非常有用。面向对象也是一个非常普遍的概念。

于 2009-04-14T12:30:17.737 回答
4

规则 1:软件是知识获取。软件意味着什么。如果您不清楚含义,请花更多时间与用户交谈以了解他们的工作。

算法和数据结构是同一枚硬币的两个方面。算法取决于数据结构,数据结构取决于算法。

尽快忘记冒泡排序。严重地。所有现代语言(Java、Python 等)都有实现比冒泡排序更好的排序的集合类。绝对没有任何情况下您应该对任何事情使用冒泡排序。您应该寻找一个包含排序方法的集合类。更好的是,您应该寻找一种完全避免排序的算法。

你必须学习几种语言。

  • 编程语言(Java、Python 等)

  • 外壳语言。

  • 数据库语言 (SQL)

  • 演示语言(HTML 和 CSS)

  • 其他数据表示语言(XML、JSON)

您必须学习几种数据结构。

  • 序列(列表、元组、文件)

  • 分层(如 XML 和 HTML 文档,以及基本文件系统)

  • 关系型(如数据库,以及带有硬链接和软链接的文件系统)

  • 映射(或索引或​​关联数组),包括哈希映射和树映射

加上一些算法复杂度分析。有时称为“大 O”。为什么冒泡排序不好,因为它是O ( n ^ 2 ),而快速排序是O ( n log n )。

于 2009-04-14T12:38:26.703 回答
4

那么蠕虫罐现在打开了!:)
我从电气工程开始。

关系数据库设计: 跟踪数据就像《幼儿园警察》中的阿诺德。
这可能是完全的混乱。必须加以控制。
如何以最少的重复信息将数据保存在最少的位置。如何让您的数据轻松且易于访问。如何控制数据增长和完整性。

用户界面 (UI) 设计: 这是用户必须访问我们正在跟踪的数据的方式。
大多数 UI 都是由开发人员设计的。因此,不幸的是,大多数 UI 与数据库设计并行。用户根本不关心数据设计。他们只是想要,他们想要什么。他们想轻松获得它。通常这需要与数据设计和用户界面有很大的分离。学会将“工程”的你与“南方的热情好客”的你分开。

面向对象编程: 许多语言归结为这种格式。

并行处理 - 多线程: 许多处理器使工作变得更快!
并行计算机已经存在了几十年。它们已经在我们的桌面上使用了一段时间了。随着“云计算”的兴起,海量并行处理不仅是强制性的,也是可取的。它非常强大!并行开发人员有很多工作潜力。

了解业务规则: 这可以帮助您将大量逻辑基于表。
许多 IFblock 条件可以位于业务规则表中。要更改逻辑,只需更改表中的信息。很少/没有重新编码。很少/没有重新编译。

事件监督...方法完成工作:
在代码中保持独立。它使其他人将来更容易进行更新。它也与模型/视图/控制器 (MVC) 框架有些相似。

PJ

于 2009-04-14T17:01:16.837 回答
3

对我来说,我从大学的以下课程中得到了很多

  • 项目管理
  • 人机交互(帮助我们极客制作更用户友好的屏幕)
  • 数据库设计(包括数据库如何工作、事务日志、锁定等)
  • 数据仓库
  • 图形(OpenGL)
  • 高级算法
  • 数据结构

我希望我在大学里做过的事情

  • 编译器构造
  • 设计模式
  • 自动机理论
于 2009-04-14T12:34:40.987 回答
3

逻辑——我只是夸大了逻辑在编程中的重要性。你说你做过机械工程,所以你必须知道数学可以让你的生活更轻松。

命题逻辑一阶逻辑二阶逻辑:这些都是非常强大的工具。可能是我在大学学到的最(也是唯一)重要的东西。逻辑就像程序员的重炮——许多非常复杂的问题(以及不太复杂的问题)一旦你把它们变成有组织的逻辑形式,就会变得简单得多。就像机械工程师的线性代数一样。

于 2009-04-14T16:03:01.423 回答
3

我认为很好地了解编译器是如何工作的。Aho 有一本关于创建编译器所用概念的经典书籍。标题是编译器:原理、技术和工具。它的别称是龙书。为了真正理解那本书,你应该了解形式语言。Hopcroft 有一本关于这方面的好书 - 自动机理论、语言和计算导论。

于 2009-04-14T16:19:21.570 回答
2

这里已经提到了很多好的回应,但我想添加一个重要的子集,但到目前为止还没有被覆盖。

经过 15 年的本科后专业软件开发,我发现我经常使用学校中的以下一些概念:

  • 一般 OO 概念和现代编程语言特性(类、数据隐藏等)。
  • 算法性能指标(大 O 表示法)。在设计算法时,执行大 O 分析以确定算法的成本,并在瓶颈区域寻找更有效的替代方案。
  • 链表和其他复杂的数据结构。
  • 快速排序,以及不同的排序概念。
  • 树和快速的树操作。

如果您的语言/平台不支持垃圾收集,内存分配和清理至关重要,并将被添加到列表中。

于 2009-04-14T13:48:44.943 回答
2

一些操作系统概念

 ( memory, IO, Scheduling, process\Threads, multithreading )

[一本好书“现代操作系统,第 2 版,Andrew S. Tanenbaum”]

计算机网络基础知识

[塔南鲍姆的一本好书

OOPS 概念

有限自动机

一种编程语言(我先学了 C,然后学了 C++)

算法(时间\空间复杂度、排序、搜索、树、链表、堆栈、队列)

[一本好书《算法导论》]

于 2009-04-14T12:33:56.493 回答
2

我赞成离散数学。计算机科学是抽象的。学习像数学家一样思考是非常有帮助的。

我还想补充一下 S.Lott 关于语言的说法。学习一堆语言类型也很重要。不仅仅是编译 vs 脚本。但是函数式(ML、Lisp、Haskell)逻辑(Prolog)面向对象(C++、Java、Smalltalk)命令式(C、Pascal、FORTRAN 甚至)。

你知道的编程范式越多,当热门的新语言出现时,学习新语言就越容易!

于 2009-04-14T14:59:08.300 回答
2

力求低耦合、高内聚

低耦合、高内聚

(我从上面链接的网站上偷了这张图片)

于 2009-08-25T20:08:13.767 回答
1

尝试了解所有级别的编程。从最低级别(装配)到最高级别。

以递归为例,这是一个简单的功能:) 尝试学习汇编并创建一个将在汇编中使用递归的程序。

于 2009-04-14T12:34:38.257 回答
1

这显然是对面向对象编程的良好理解、良好的指导原则(如SOLID 原则)以及遵循既定模式和实践。

如果您查看 SOA 或 DDD,它们最终都会退回到某种形式的 OOP 概念。

我建议你买一些好的 OOP 书籍,然后选择一门丰富的语言,比如 C# 或 Java

Grady Booch 的 OOP

(PHP、ruby 的人请不要投我的票,我只是举一些例子让他开始,你可以在这里提供你自己的答案和建议)

于 2009-04-14T12:37:36.440 回答
1

算法。

学习以一种下降的方式使用编程语言是你可以边做边学的东西,但是你自己发明所有广泛使用的算法几乎是不可能的。一个人至少应该知道什么可以做,什么不能做有一些问题。

例如,一个人根本无法编写一些带有冒泡排序的程序并期望它被认为是好的,无论代码多么好。

总结一下 - 看看算法简介

不需要掌握它,只要知道发生了什么...

于 2009-04-14T12:44:24.537 回答
1

作为计算机科学学位的应届毕业生,我建议以下内容:

于 2009-04-14T12:49:25.803 回答
1

计算机程序的结构和解释。如果你理解了这本书,那么其他一切都可以轻松地建立在这个基础上。如果你对书中的概念有疑问,你可能是一名软件开发人员,但不是计算机科学家。

于 2009-04-14T13:08:15.897 回答
1

我不会告诉你任何要学习的具体概念,而是建议你对广泛的主题进行大量的轻读。不要担心对你读到的每个主题有深入的理解——在这一点上,更重要的是你能够识别出你在看什么的问题,这样你就可以做一些只是——当你真正面对它时,及时学习。换句话说,如果您不知道如何解决组合数学问题,那也没关系,只要您知道的足够多,以便在需要查看可以排列一组对象或选择子集的方式时查找“组合数学” .

对于这种广泛的浏览,维基百科是一个很好的资源,特别是如果你只是开始浏览。一个更好的,特别是如果你觉得 Wikipedia 太学术或难以访问,是C2 wiki。(有趣的是,这是Ward Cunningham 发明原始 wiki)。

于 2009-04-14T14:51:16.680 回答
0

软件开发生命周期——需求收集、设计和分析、实施、测试、支持和维护序列。这与将这些步骤付诸实践的方法论(如瀑布和敏捷)一起也是学习的重要内容。

于 2009-04-14T14:05:29.363 回答
0

我认为理解多线程背后的基本理论是很重要的,如果没有这些,甚至很难看出可能存在问题,直到您在周日早上 4 点在实时服务器上进行调试。

信号量、关键部分和事件。

于 2009-04-14T12:53:23.063 回答
0

不,不是冒泡排序,而是快速排序。这是大 O 的事情 - 冒泡排序平均 O(n^2),快速排序是 O(n*log(n))。

于 2009-04-14T12:55:31.903 回答
0

我会说下面是最重要的东西

  • 面向对象编程
  • 操作系统概念
    • 进程和线程
    • 调度算法
  • 数据结构
    • 数据存储和收集的类型,类型(链表、哈希、数组等)
    • 排序算法
    • 算法的复杂性

然后转到特定语言相关的东西。我希望这是有帮助的!!

于 2009-04-14T13:15:42.010 回答
0

我将从引用开始:

“如果你拥有的唯一工具是一把锤子,那么你将一切都视为钉子”。(亚伯拉罕·马斯洛)

IMO 最重要的原则是了解许多不同的编程范式、语言,并充分了解您可以使用的工具。几乎可以用您选择的任何语言解决任何问题,无论是具有庞大默认库的成熟主流语言,还是像 AutoHotKey 这样的小型专业语言。程序员的首要工作是根据问题的规范确定使用什么。一些概念提供了更好的主题方法,无论您的主要目标是什么 - 复杂性、混淆、性能、可移植性、维护性、小代码量......

否则你会像一些程序员一样拼命尝试用他们专门的语言做某事,而在不同的编程环境中解决问题可能很简单。

这个建议符合当今多语言项目的趋势(以 Web 应用程序为例,它可能在单个应用程序中涉及多种语言,如 C#、JS、CSS、XPath、SQL、XML、HMTL、RegExp ......甚至不同的编程范式(例如,C# 最近从函数式编程范式中引入了一些概念,lambdas)。

所以,基本的事情是不断学习,永远:)

于 2009-04-14T13:15:59.123 回答
0

我认为3D-Graphics是每个人都应该学习的东西。或者至少如何正确使用齐次向量和矩阵变换。

它不仅有助于创建 3d 应用程序,而且还有助于机械领域,如机器人的逆运动学、计算力矩和许多其他东西。

直到我读了 3d 图形,我才完全理解线性代数,这是我上过的最好的课程之一,尽管我们的老师很糟糕。

于 2009-04-14T13:16:18.810 回答
0

由于具有多核(CPU 和 GPU)的机器正在成为标准,我想说包括分布式算法(从多线程到多台机器)。了解多线程和分布式处理至关重要。抱歉,该链接并没有真正提供很多帮助。

于 2009-04-14T13:17:30.073 回答
0

除了冒泡排序之外的任何东西:

  • 堆排序
  • 快速排序

最重要的是:大 O 表示法,因此您知道为什么应该使用其中一种而不是冒泡排序。

于 2009-04-14T14:48:06.967 回答
0

如果你要教 big-O,至少要解释一下它描述了算法的时间如何随着更大的输入而扩展——这并不意味着算法会花费更少的时间。
例如,建造金字塔是 O(n),而对它们的照片进行排序最多是 O(n ln n)。因此,建造另一个金字塔比整理假期照片要快。

学生需要了解寄存器、缓存、主存、磁盘和网络上的操作需要多长时间。许多只教授非常高级语言的人没有概念。

(这是有人想讨论的评论)

于 2009-04-14T19:16:37.150 回答