如何确保我实际上在学习编程而不是简单地学习语言的细节?[关闭]


82

我经常听到一个真正的程序员可以在一周内轻松学习任何语言。有人告诉我,语言只是完成任务的工具。编程是必须学习和掌握的最终技能。

如何确保我实际上在学习编程而不是简单地学习语言的细节?以及我如何开发可应用于所有语言而不仅仅是一种语言的编程技能?


25
尝试学习另一种语言。尝试解决您已经知道如何用新语言使用第一语言解决的问题。一开始这并不容易。但是,一旦以新的方式解决旧问题变得明显容易,您就会知道自己正在学习(注意:这可能需要一些时间)。
FrustratedWithFormsDesigner

42
另外,声称能够在一周内学习一种语言的人需要定义其说“学习”的含义。"What do you mean you're not an expert in LanguageX?!? I can learn a language in a Week!"。1周后:"See, I've learnt the language, and here's a Hello World example I copied from Wikipedia to prove it!"
JohnL

9
需要提出一个问题。您是使用语法构造逻辑还是使用更快,更高效的思维模型?我发现新手程序员倾向于使用语法。
ChaosPandion

10
@PaulR:我花了10,000个小时来学习如何骑自行车。还是游泳吧。
罗伯特·哈维

7
@PaulR这句话是关于掌握一项技能要花费1万小时,而不仅仅是“学习”它
Tobias Kienzler 2013年

Answers:


96

不必担心遇到一些荒谬的“技能”概念,这些概念在诸如此类的语句中经常被听到:

  • 所有编程语言都基本相同。
  • 一旦很好地选择了一种语言,就可以快速,轻松地选择其他任何一种语言。
  • 语言只是工具,实际上有一些不可思议的大脑魔术使软件得以制造。

这些陈述都是基于有缺陷的前提,并且背叛了缺乏广泛编程语言经验的想法。它们是非常常见的语句,并且得到了一大批程序员的强烈相信,我不会对此表示怀疑,但是我会质疑它们的准确性。

这很简单地证明了:花一个星期(或实际上是大于两天的任何时间)尝试学习HaskellPrologAgda的基础知识。您很快就会开始听到芝麻街上的旧歌在脑海中弹奏,“其中之一与其他不一样……”。

事实证明,有一大堆编程语言,技术和方法与我们95%的工作或曾经做过的工作完全不同。许多人完全不知道甚至存在任何其他这些概念,这很好,并且这些概念对于成为受雇甚至有效的程序员来说不是必需的。

但是事实仍然存在:这些技术和方法的确存在,它们对许多不同的事物都有好处,并且可能非常有用,但是它们不仅仅像您惯用的那样,而且人们不能简单地花一个下午的时间来学习它们。

此外,我想说的是,大多数情况下,人们声称他们一周之内就能拥有或能够如此迅速地学习到诸如编程语言之类的复杂事物,因此他们遭受了Dunning Kruger效应(维基百科)的困扰:

邓宁-克鲁格效应是一种认知偏见,在这种偏见中,非技术人员遭受虚幻的优势,错误地将其能力评定为远远高于平均水平。这种偏见归因于未熟练人员认识到自己的错误的元认知能力。

我想请人们参考彼得·诺维格(Peter Norvig)关于编程学习的概念的更富有经验的观点:十年内学习编程

研究人员(Bloom(1985),Bryan&Harter(1899),Hayes(1989),Simmon&Chase(1973))显示,在象棋,音乐等众多领域中发展专业知识大约需要十年的时间。写作,电报操作,绘画,钢琴演奏,游泳,网球以及神经心理学和拓扑学研究。关键是深思熟虑的实践:不仅要一遍又一遍地做,还要挑战一项超越您当前能力的任务来挑战自己,尝试一下,分析执行前后的表现,并纠正任何错误。然后重复。再重复一次。


当然,有一套总体原则可以使所有语言都易于学习!

也许吧,但是我认为这套原则是如此之大,以至于几乎所有语言都将在您一周的接触范围之内。当您将新概念添加到您熟悉和熟悉的列表中时,此范围之外的语言列表可能会缩小,但是我很难相信它将永远消失。从连接语言基于矢量的语言,再到专门用于AI元编程的语言或完全存在以支持正则表达式的语言),从概念到方法的事物列表是如此之多,令人困惑。

十年后,您将可以进行一般编程。这意味着您可以用某种语言或某种语言风格编写一些不错的代码。因此,在十年后,您准备开始应对余生中这些无数广泛的跨领域概念,而除了Edsger W. DijkstraDonald KnuthJohn D. Carmack之外,您将一无所有。其中。


11
恩 “了解”一种语言与足够熟练地发现并修复其中的一个小错误之间是有区别的。一个好的程序员甚至可以使用古老的语言也可以很快地完成后者。
Telastyn

5
@ CharlesE.Grant我想您高估了大多数人在大学里学到的东西,以及高估了半精通Haskell或Prolog等语言所花费的时间。我要说的是,一位熟练的行业经验丰富的工程师(没有任何函数式编程经验)要花大约一个多星期才能修复Haskell程序中的第一个错误。
吉米霍法2013年

11
我仍然认为基本概念非常紧凑。了解术语重写后,您便拥有了用于定义lambda微积分,SK微积分,图灵机,马尔可夫算法等的工具。少量真正的基础思想可以涵盖大多数计算机科学。但是,当然,需要经验才能看到看似复杂的事物中的简单模式。
SK-logic

4
我想说的与其说是邓宁-克鲁格效应,不如说是假设“编程语言” =“ c风格编程语言”。在了解了相当数量的c ++,相当数量的C#,以及一些perl和python的知识之后,我希望我可以在一个星期内熟练使用Java,PHP等。不一定是专家,但至少相当流利。我几天拿到了javascript。那时,主要是要了解它们之间的差异。注:最流行的现实世界的语言 C-等。例如,Prolog并不一定是如此。
neminem 2013年

2
@WayneWerner严重的是,哈斯克尔或序言和ALGOL语言之间的差异这么多比的语法,你只是延续神话。在上面进行我的测试:花一周时间尝试学习Haskell,看看它如何为您工作。老实说,这对您有好处,可以从中学到很多东西。
吉米霍法2013年

51

...我如何开发可以应用于所有语言而不仅仅是一种语言的编程技能?

这个问题的关键是超越语言而思考而不是使用您所编码的语言。

WAT?

有经验的会说多种语言的程序员会在自己的语言思维模型的抽象语法树(AST)中进行思考。一个人不认为“我这里需要一个for循环”,而是“我需要对某个东西进行循环”,并将其转换为该语言的适当的for或while或迭代器或递归。

这类似于在学习口语中所看到的。会说多种语言的人会流利地想到其中的含义,然后它会以给定的语言显示出来。

在一对带有眼动追踪的代码理解视频和眼动追踪代码实验(新手)的一对眼动视频中,可以看到有关此AST的一些线索,在该视频中可以观看初学者和经验丰富的程序员的眼球运动。人们可以看到有经验的程序员将代码“编译”到他们的思维模型中并在脑海中“运行”,而初学者则必须逐关键字遍历代码。

因此,开发适用于所有语言的编程技能问题的关键是学习多种语言,从而使人们可以远离拥有一种语言的思维模型,并具有自行针对问题生成AST的能力。母语,然后将其翻译成给定的语言。

一旦具备了在头部使用AST的能力,就可以在类似的思想流派中学习另一种语言(去Befunge距Java有点远,而距Forth则不那么多)变得容易得多-这就是“正义”将AST转换为一种新的语言,这在完成第三,第四和第五(等等)时间时要容易得多。


有一篇经典文章,《Real Programmers不要使用Pascal》。其中部分内容为:

...确定的Real Programmer可以用任何语言编写Fortran程序

还有一些您不能仅仅使用心理AST的功能-您也需要使用语言进行思考。这需要一些时间才能完成(我仍然被指控用Python 编写Perl代码,并且对我的第一个Lisp代码进行了评论,说“这是一个非常好的C程序。”)。

为此,我必须指出ACM发表的一篇文章,《如何不以任何语言编写Fortran》。本文的第三段(不是引号)直接解决了当前的问题:

良好的编码特性超越了所有通用编程语言。如果您将自己应用于代码,则几乎可以在任何代码中实现良好的设计和透明的样式。仅仅因为编程语言允许您编写错误的代码,并不意味着您必须这样做。如果编码器具有足够的创造力,那么为提高良好的风格和设计而设计的编程语言仍然可以用来编写糟糕的代码。您可以淹没在浴缸中,里面有一英寸深的水,并且可以轻松地编写一种完全没有可读性和维护性的程序,而该程序没有异常或行号,并且具有异常处理和泛型类型以及垃圾回收功能。无论您是编写Fortran还是Java,C ++或Smalltalk,您都可以(并且应该)选择编写优质的代码而不是不良的代码。

拥有AST不仅足够-还需要拥有可以将其翻译成其他语言的AST。掌握Fortran AST并用Java编写Fortran代码不是一件好事。人们还必须对语言及其习语足够熟悉,以便能够用语言进行思考(尽管我在最上面说了什么)。

我看过由不停止编写C代码的人编写的Java代码。有一个对象具有一种主要方法。在此对象中,有一堆由main和调用的静态方法以及具有公共字段(因此看上去很像struts)的私有内部类。这是用Java编写的C代码。所有要做的就是将一种语言的语法翻译成另一种语言。

为了超越这一点,人们需要继续用多种语言编写代码,在设计代码时不要考虑这些语言,而在将设计转换成代码以正确使用语言习语时要考虑它们。

达到此目标的唯一方法-能够开发适用于所有语言的编程技能-是继续学习语言,并使这种思维编程语言保持灵活,而不是链接到一种语言。

(我向ChaosPandion道歉,因为大量借鉴了他提出的想法。)


3
没必要道歉。我想您已经写了一个令人印象深刻的答案。
ChaosPandion

我想向那个让我想到这一点的人写下答案。

3
这是一个非常好的答案。希望我能投票两次。
韦恩·维尔纳

2
实际上,这就是为什么您不应该首先学习OO的原因,因为它会以可想象的最坏的AST之一来格式化您的大脑。
Morg。

1
@JimmyHoffa-你可能是对的。我一开始总是使用一种语言教书,后来慢慢介绍。我仍然认为值得探索,因为我总是可以踩刹车,让他们专注于一种语言。(实际上,SML似乎是一个不错的选择。)
ChaosPandion

12

选择一种语言,然后开始编码。对于初学者来说,Python是一个不错的选择,并且在线提供了可用教程,因此您可以学习如何正确地进行操作。

一切都从此开始。您的兴趣将带您进入可以增加程序复杂性的框架和设计概念。您会发现有一些在线课程可以使您掌握基础知识和理论,并且可以探索各种编程范例,等等。

是的,一旦您在基础知识上有扎实的基础,您就会发现像Haskell这样的语言会教给您一些新知识。

一些程序员可能认为所有语言都是相同的,因为他们没有接触过任何使他们有不同想法的语言。所有最常用的语言都是从Algol派生的(它们本质上是过程语言),其中大多数是类似于C的花括号语言。尽管它们中的某些语言比其他语言更为复杂,但它们都具有相同的功能。


2
这不是真的吗?一些编程语言将所有内容编码为纯函数(包括决策和循环)。可以通过从集合等中推入和弹出对象来建模其他对象
。– jozefg

1
什么不对 您必须学习如何爬行,才能走路或跑步。
罗伯特·哈维

1
嗯,我要指出的是,我的意思是最后一段,我同意其余的答案
jozefg

1
我将最后一段替换为更好地表达我的观点的一段。
罗伯特·哈维

5

编程是关于解决问题的方式,可以以一种受限的语法来表达该解决方案,从而可以使用编程语言来实现。因此,编程的技巧就是解决问题的技巧。

某些语言会邀请其他编程范例,例如面向对象,事件驱动,多线程和基于MVC框架。这些全都是模型和模式,与实现无关。

如果您能够以书面形式解决问题,并且可以轻松地将其转换为代码并与适合您平台的模型相关联,那么您就是程序员。如果您能做得到这些解决方案并以我们选择的语言实现它们,那么这是另一回事。

我已经编程30年了(OMFG!),但php.net由于它不是我的母语,所以仍然使用PHP查找命令。

我要说的是,语言方面的专业知识与您查看手册或堆栈溢出的频率成反比。编程方面的专业知识是您如何轻松地以与计算机编程语言兼容的方式解决问题。

在相关新闻中,我上周学习了Ruby。尽管我不是“专家”,但是我可以为您解决一个可以用Perl编写的问题,然后花一些时间将其翻译成Ruby,同时我还要学习更多。


您的评论是我读到的关于模型和模式的第一条评论!我对您的评论有100%的评价,一件事是获得一种语言并开始编写程序。另一种方法是考虑问题并找到解决问题的合适工具,然后开始寻找语言并开始编程。

3

我认为,与任何事物一样,实践是完美的。只是不要让自己沉迷于总是做相同的事情或总是使用相同的语言,并继续在每个项目中学习事物。

我认为您可以轻松地与学习弹奏吉他之类的东西相提并论。任何优秀的音乐家都可以在很短的时间内学会播放一首新歌,因为他们已经知道所有的和弦以及为什么以这种方式演奏和弦的所有理论。他们如何获得好的?他们演奏的歌曲太多了,所有的模式都融合在一起了,与此同时,他们的知识也得到了有据可查的理论证明,这些模式也同样适用。

因此,也许您可​​以很好地播放几首歌曲,但不能快速偏离或拾取新歌曲。这可能等效于.NET程序员,他继续不断地制作相同的CRUD应用程序,有时尝试一些新的东西,添加一些Web服务调用或高级UI,或者以一种全新的语言编写它。当您遇到麻烦时,看看为什么事情会这样发生,在Stack Exchange上提问,等等。最终,您将看到所有不断出现的模式,并且了解一些基础理论并且学习新语言不会似乎几乎是令人生畏的。


1

我不打算学习一门语言需要多长时间,也不打算学习一种语言,而是要解决您的实际问题:如何确定您是学习编程还是学习编程语言。

如果您已学会将问题分解为离散的过程,然后使用这些过程来解决问题,那么您将学习编程。如果您已经学会了一种编程语言,并且已经学会了一种语言的语法,并且知道在以该语言实现时如何调整流程的工作方式。

这并不是说您在使用Lisp时应该在Fortan中编程,或者使用游标在db的表中添加列的值。只是该语言是实现细节。它可以更改所需的流程,但无需更改标识和创建流程的需求-最终实现了具有输入/输出和所需结果的真实世界实现。


1

我的策略一直是专注于纯技巧而不是特定技巧。

不用花心思去学习Python(或任何语言)的特殊语法,而是花脑子解决抽象问题,例如如何最好地解决该类别中的每个问题。

这样,您将知道无论使用哪种语言都可以做什么,并且大多数人将拥有可用于任何语言编程的永恒技能。

尤其要避免使用充满陷阱的工具(例如MySQL)或专心致志的语言(例如Java),因为使用这些工具所学的内容将具有很大一部分工具特定的知识,这些知识必将很快变得毫无用处。

与许多答案中所说的相反,不要听其他程序员的话,您是菜鸟,而且您无法从真实交易中分辨出假货,因此,最好不要花一小撮盐。

您想一直质疑并且仅在解决方案快速,优雅且可靠时接受。


1
“不要听其他程序员的话” –是的。“-您怎么知道您是否编写了可读性强且易于维护的代码?-同行检查了代码后便告诉您。基本原理:您不能自己确定,因为您作为作者的知识比代码本身所说的要多。计算机不能以相同的理由无法告诉您,因为它不能告诉您绘画是否是艺术品。因此,您需要另一个人-能够维护该软件-查看您所写的内容并给出他或她的意见...” (引述来源
t

@gnat随心所欲。我只是告诉你,由于大多数程序员都无法编写代码,所以他们的反馈可能有害,因此,您应该带上袋子和盐袋来应对。我也相信“白痴可以编辑和阅读”根本不是质量的标志。相信您想要的东西,但不要因为别人不同意您的愿景而绕-1。
Morg。

我的投票表明对职位质量的评价,而不是我是否同意(书面同意,我想你在这里有意思)。我引用了另一种观点,不是因为它相反,而是因为它有明确的解释(请参阅“ RATIONALE”)。如果您可以想到类似的可靠解释来支持您的观点,请考虑编辑该帖子以添加该帖子
2013年

随你。内容>表格。保留您的表格,我保留我的内容。
Morg。

0

有理论上的方法。了解计算机的实际工作原理。基本处理器指令如何串在一起,以使我们在高级编程领域中理所当然地考虑到更复杂的操作和结构。

然后是更实用的编程方法。困扰人们通常被称为“不好的程序员”的主要症结是他们只真正了解一种语言。即使他们认识其他人,他们也可以像使用母语一样在其中编程。如果他们真的想学习编程,那是一个必须打破的循环。对此的默认答案是从每个编程范例中学习至少一种语言。因此,学习一种OOP语言,一种功能性语言,一种脚本语言等。通过学习,我并不意味着学习语法。您可以通过实际使用某种语言来学习某种语言。

就个人而言,当我想学习一种新语言时,我会使用欧拉计画。我想知道我已经用一种OOP语言解决了一个难题(例如),并尝试使用一种功能性的语言来解决它,同时尝试遵循新语言的最佳实践。当您使用两种根本不同的方法来解决同一问题时,您不仅可以看到真正的区别,而且还可以向您展示共同的地方。所有语言共享的这些公共领域是真正的编程,不同之处只是实现它的不同方式。


4
我不会将学习计算机的物理行为称为“理论方法”,“理论方法”将是学习理论,阅读教会讨论的论文以及学习咖喱霍华德同构性,学习lambda演算和数论的基础知识,这些都是理论基础。并不是说您的答案是对还是错,只是说我将其称为是非理论的具体方法,因为它缺乏理论。
2013年

@JimmyHoffa-好点!
系统停机

1
对于初学者来说,“如何将基本的处理器指令串在一起(...)”似乎是个糟糕的主意(OP并没有说他是一个,但是为了论证而假设。它会教“微优化”而不真正教如何进行优化(3-5阶段的体系结构可能有点过时了...)。不要误会我的意思-CA令人着迷-但是“正确”的欣赏需要诸如“乱序”和“多标量”之类的词,而且很可能跟从一些基本的编程经验。
马切伊Piechotka

0

好吧,我想说的大多数事情已经讲完了。我想补充的是一个非常简单的类比。

如果仅将编程语言视为工具,那么即使擅长将一种擅长于另一种也无济于事。

只是考虑一下一群著名的剑客,经过7天的训练,突然放下剑,与长矛作战。会发生什么?他们将被屠杀。

语言通常并不难学,但是要精通它需要耐心和锻炼。此外,没有正确的方法来学习编程。

学习编程就像玩RPG游戏。有时您会使用剑,有时会使用长矛,有时会使用盾牌。杀死每个敌人,您都会获得经验值。一旦有了足够的经验点,就可以升级。现在精通剑术并不能使您的弓箭变得出色。但是,您之前获得的部分经验将提高您的耐力和速度。

学习语言时,您可能需要做以下几件事。

  • 了解有关该语言的信息。如果听起来很有趣,请亲自尝试hello world应用。
  • 阅读一些教程,技巧和博客。
  • 制作简单的应用只是为了好玩。
  • 测试不同的功能。
  • 如果您真的喜欢,请购买一些书籍和/或视频教程。
  • 搜索好的库。
  • 搜索答案,仅在找不到答案时询问。
  • 帮助其他人寻求答案(比这里更好的地方?)
  • 使有用。制作计算器应用程序可能是一个不错的练习,但是如果您制作了TO-DO列表应用程序并且实际上是在PC /电话上使用的,则感觉是100倍令人满意。

体验新语言,探索新图书馆,在空闲时间学习新技巧。在不知不觉中,您会用自己的技能使自己感到惊讶。


0

就我而言,我将学习如何通过以下方式进行实际编程:

  1. 向大师学习。收听编程播客,阅读有关所选编程主题的专业博客,阅读/观看大师的精彩教程,这些教程散布在网络上,最后阅读史诗类的书籍,例如The Pragmatic Programmer。本书有许多编程瑰宝,它们在作者的整个职业生涯中都得到了积累。学习如何实际编码的一种肯定的方法是知道其他成功的程序员是如何做到的。
  2. 做事经验。阅读和了解是一回事,实际上将其付诸实践并使其起作用是另一回事。没有比经验更好的老师了,所以戴上您的编码帽并开始吧。
  3. 问一个知道的人。就像您现在正在做的一样,不要害怕向团队中的前辈询问最佳实践或更好的做事方式,或者如果您不幸地无法与所说的前辈,导师或专家接触,然后还有其余的stackexchange和互联网问。

另外,正如您的评论者所提到的,不要忘记也要精通您的工具。如果您对工具(在这种情况下为编程语言)了解不足,那么学习所有最佳实践和最伟大的理论都是徒劳的,或者实施效果不佳。


0

我认为,如果您可以进行分析性思考,您将有一个良好的开端。

学习学习所需的任何语言,并通过一系列示例来学习自己的知识,例如,几乎每本教编程的书中都有介绍。

接下来尝试解决您自己的问题。尝试找到不同的解决方案并进行比较。速度和内存使用率是重要的常用因素。与其他程序员讨论您的解决方案。

阅读其他程序员的代码,并尝试理解为什么他们以这种方式解决了问题。

您还应该阅读一些有关算法的书,以全面了解标准方法。新问题通常是对旧问题的修改。

在团队中进行大量练习和使用代码也将帮助您逐步提高技能。

希望我的意见至少能回答您的问题。

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.