我应该知道哪些计算机科学概念?[关闭]


95

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

我的学位是机械工程学,所以最终以一名程序员的身份开始工作,但我在基础知识方面有些欠缺。我最近学到了一些标准的CS概念,这些概念使我对自己正在做的事情有了更深入的了解:

语言特征

  • 指针与递归(感谢乔尔!)

数据结构

  • 链表
  • 哈希表

演算法

  • 气泡排序

显然,此列表目前很短,所以我希望就以下方面提出建议:

  1. 我应该了解什么概念
  2. 任何正确理解它们的好资源(因为Wikipedia有时可能有点密集和学术性)。

5
气泡排序?尽可能远离他们!而是了解quicksort / heapsort如何工作。
卡拉

18
是的,学习bubblesort。了解为什么它可怕。了解快速排序,合并排序以及所有其他内容,包括它们各自的弱点。但是不要在生产代码中编写它们:调用您所使用的平台上提供的排序功能。
Brian Ensink 09年

@Roger Pate-为您+1,您应该知道一种算法或数据结构对什么都有好处,以及它有什么用。Quicksort和Bubblesort都具有相同的最差情况性能[O(n ^ 2)],但对于非常不同的输入,Bubblesort的最佳情况性能为O(n),其中QS仍为O(n log n)。当然,如果您正在考虑Bubblesort,那么您可能想要进行插入排序。
Andre Artus 2010年

Answers:


60

看看Steve Yegge(以前是Amazon,现在在Google)的博客文章:

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

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

好的链接。有点侧重于Unix方面(完全缺少.NET),但仍然不错。
Toon Krijthe 09年

很棒的链接-我需要做很多工作,我只是希望它有一些指向解释这些问题的好页面的链接。
乔恩·阿图斯

该链接对我进行自我检查并掌握基本知识将非常有用。谢谢..
rpr

同意,很好的联系。尽管已确定的许多可能的解决方案都是基于Unix的,但涉及的总体概念与语言/平台无关。对于大多数程序员而言,诸如递归,编写ADT(例如树)和按位操作之类的事情很少见,但它们是重要的基础。
Zach Burlingame,2009年

4
除了正则表达式,我都会同意。这是一个不错的奖励,但是大多数内容是基础知识,是所有内容的基础……正则表达式很棒,但是我知道很多很棒的程序员从来没有使用过它们,也不需要使用它们。
Beska

35

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


1
您可以从我链接到的Wikipedia文章开始-它既简单又在数学上是正确的。
sharptooth

3
您必须对高级数学有相当低的评价。我在大学的第一年就了解了这一点,当时我只是微积分的一部分。
GoatRider

1
不要忘了NP的概念,当其中包含问题时,开发人员试图将TSP(旅行推销员)编码到每个数据库事务中以进行搜索或其他类似的习惯,这是一个主要问题=]
Ed詹姆斯

2
您还应该知道,大O不会告诉您哪种算法花费的时间更少。大多数CS毕业生无法掌握的东西
Martin Beckett

3
有点。它告诉您哪一个是最坏的情况,而不必告诉您哪个“更快”,这取决于输入集。
Ed James

30

我在找计算机科学专业有点可笑,但是维基百科太学术了:D

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


2
+1是因为您提到过数据库,这些类型的列表通常会忽略它们,但是对于任何全面的CS毕业生来说,这都是一个非常重要的概念。
Brian Ensink 2009年

14

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

  • 乐兴,解析,字符串匹配,正则表达式
  • 记忆化
    • 封装/作用域/封闭
    • 快取
  • 递归
  • 迭代器/生成器
  • 函数式编程-John Hughes的精彩文章使我感到“为什么”

这些是离散数学的整个领域,但是对于CS来说,需要进行认真的介绍:

  • 矩阵/线性代数
  • 图论

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


10

我要说的是,即使您不需要每天使用它,对面向对象编程的理解也是必须的。

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


10

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

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

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


1
如果我只选一个,那将是离散数学。几乎是CS101。我很难想到DM不会以某种方式触及的一般编程领域或范式。
Andre Artus 2010年

7

程序员能力矩阵对此进行了详细介绍,但我将重点介绍以下几点:

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

5

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


4

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

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

尽快取消对气泡的排序。说真的 所有现代语言(Java,Python等)都具有实现比冒泡排序更好的排序的集合类。绝对没有任何情况下应该对任何内容使用冒泡排序。您应该在寻找一个包含排序方法的集合类。更好的是,您应该寻找一种避免完全排序的算法。

您必须学习几种语言。

  • 编程语言(Java,Python等)

  • 外壳语言。

  • 数据库语言(SQL)

  • 表示语言(HTML和CSS)

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

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

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

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

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

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

  • 套装

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


作为记录,我从不真正使用冒泡排序!我刚刚发现学习它的工作方式是一次有趣的经历,并发现还有其他一些这样的算法,人们应该足够理解才能使用自己选择的语言编写。
乔恩·阿图斯

有无数种算法。他们大多数不好。其中一些很好。冒泡排序根本不好。买任何有关算法的书,然后继续。
S.Lott

只是挑选而已,但是Quicksort最差的情况是O(n ^ 2)。我仅指出这一点,是因为我认为在研究基本算法时了解为什么这样做是正确的。
Brian Ensink 2009年

对于快速排序,是的-一个重要的练习。对于冒泡排序,唯一的办法就是查看算法的确有多糟糕。通常,了解典型情况与最坏情况很重要。
S.Lott

4

蠕虫的罐子现在开放了!:)
我刚开始从事电气工程。

关系数据库设计: 跟踪数据就像《幼稚园警察》中的Arnold。
可能是完全混乱。必须对其进行控制。
如何将数据保存在最少的位置,信息的重复最少。如何使您的数据保持明亮且易于访问。如何控制数据增长和完整性。

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

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

并行处理-多线程: 许多处理器使工作速度更快!
并行计算机已经存在了数十年。他们已经在我们的桌面上呆了一段时间了。对于“云计算”,大规模并行处理不仅是必不可少的,而且也是可取的。它非常强大!并行开发人员有很多工作潜力。

了解业务规则: 这可以帮助您基于表创建许多逻辑。
许多IFblock条件可以放在业务规则表中。要更改逻辑,只需更改表中的信息。很少/不需要重新编码。很少/不需要重新编译。

事件监督...方法可以完成工作:
将代码中的各个部分分开。它使其他人将来更容易进行更新。它还在某种程度上类似于Model / View / Controller(MVC)框架。

睡衣


3

对我来说,大学以下课程让我受益匪浅

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

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

  • 编译器构造
  • 设计模式
  • 自动机理论

3

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

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


3

我认为对编译器的工作原理有很好的了解。Aho拥有关于创建编译器的概念的经典书籍。标题为“编译器:原理,技术和工具”。它的绰号是《龙书》。为了真正理解这本书,您应该对正式语言有所了解。霍普克罗夫特(Hopcroft)有一本关于这方面的好书-自动机理论,语言和计算入门。



2

这里已经提到了很多好的响应,但是我想添加一些重要的内容,但是到目前为止还没有涉及。

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

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

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


2

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

我还想补充一下S.Lott关于语言的内容。学习一堆类型的语言也很重要。不只是编译还是脚本。但是功能性(ML,Lisp,Haskell)逻辑(Prolog)面向对象(C ++,Java,Smalltalk)势在必行(C,Pascal,甚至FORTRAN)。

您知道的编程范例越多,当新的热门语言问世时,就越容易选择新的语言!


2

一些操作系统概念

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

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

计算机网络基础知识

[一本好书 Tanenbaum的

OOPS概念

有限自动元

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

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

[一本不错的算法介绍书]


自动中继?-按照第一次编辑,肯定是“自动机”。
汤姆·达克林09年

糟糕!我想陷入困境拼写检查。我会纠正的。谢谢。
aJ。


1

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

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


1

算法。

学习以下降的方式使用编程语言是您可以随时学到的东西,但实际上不可能自己发明所有广泛使用的算法。有一些问题。

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

总结一下-看一下算法介绍

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



1

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

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

我建议您获得一些不错的OOP书籍,并开始选择像C#或Java这样的丰富语言。

OOP,格雷迪·布奇(Grady Booch)

(PHP,红宝石们,请不要对我投反对票,我只是给他一些例子,您可以在此处提供自己的答案和建议)



1

我不会告诉您要学习的任何特定概念,而是建议您对广泛的主题进行大量的阅读。不必担心对阅读的每个主题都有深入的了解-此时,更重要的是,您能够识别哪种类型您正在寻找的问题,这样就可以做一些只是-真正面对面时及时学习。换句话说,如果您不知道如何解决组合问题,只要知道的程度足以查找“组合”,就可以了,因为您需要了解可以用多少种方式排列一组对象或选择一个子集。

Wikipedia是进行此类广泛浏览的不错的资源,尤其是如果您只是略读而已。C2 wiki是一个更好的选择,尤其是如果您发现Wikipedia太学术或难以访问时。(有趣的是,这是Ward Cunningham发明原始Wiki)。


0

我认为了解多线程背后的基本理论是至关重要的,否则,直到您在星期天凌晨4点在正在运行的服务器上调试时,甚至很难看到有问题。

信号灯,关键部分和事件。


0

不,不是冒泡排序,快速排序。这是大O事物-气泡排序平均值为O(n ^ 2),快速排序为O(n * log(n))。


0

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

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

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


0

我将从报价开始:

“如果您仅有的工具是锤子,您将像钉子一样对待一切”。(亚伯拉罕·马斯洛)

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

否则,您将像某些程序员一样拼命尝试以他们专用的1种语言来完成某些工作,而在不同的编程环境中解决该问题可能是微不足道的。

该建议与当今多语言项目的发展趋势保持一致(例如,Web应用程序,它可能在单个应用程序中涉及多种语言,例如C#,JS,CSS,XPath,SQL,XML,HMTL,RegExp ....甚至不同的编程范例(例如,C#最近从功能编程范例lambda中引入了一些概念)。

因此,基本的东西就是永远的不断学习 :)


0

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

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

在我读完3D图形学之前,我还没有完全理解线性代数,即使我们的老师很差,这也是我参加过的最好的课程之一。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.