每天都看到很多对编程感兴趣的人在问是不是可以自学软件开发,或者应该怎么自学 编程才能入门。在这篇文章里,我将尝试重现一个初学者在学习计算机编程时可能会 碰到的问题,并尽量提供相应的解决思路,希望对初学者有所帮助。如果你在看完 这篇文章后还是有些疑惑,欢迎点击 这里 咨询我, 或者扫码加入这个编程学习群 和其他学习者一起交流。
目录
- 编程可以自学吗?
- 学习编程需要什么基础?
- 什么是编程语言?什么是程序?
- 我应该学习哪种编程语言?
- 编程的核心思维是什么?
- 应该按什么步骤学习编程语言?
- 学习编程有什么方法吗?
1、编程可以自学吗?
答案是肯定的,而且自学是学习软件编程极其重要的一个途径。不过最好的方式是 自学的同时,有一个可以帮助解决问题的同事或者老师,这样可以避免卡在一个问题上 太长时间。
现在有很多途径可以自学,例如IT图书,或者在线视频教程,我们的网站 也提供一些面对初学者的免费的在线互动课程,可以边学习边实践, 你也可以尝试一下:
2、学习编程需要什么基础?
简单地说,只要具备正常的思维能力,就可以学习编程。
让我们从一个实际的梗来理解这一点:如何把大象装进冰箱里?
你也许知道这个搞笑问题的搞笑答案:
这就是编程所需要的最基本的思维能力:把一个大的问题分解为若干个小的问题, 解决了小的问题,大的问题就解决了,这种分而治之的思考方法是一种相当工程化 的思维,也是科学技术在过去的两百年里的统治性思维。
回忆一下,你在生活中难道不就是这么做的吗?编程实际上就是把生活中 常见的思维活动用编程语言表达出来的一个过程。
3、什么是编程语言?什么是程序?
如果把计算机看成一个人,编程语言就是你和计算机对话的语言,你需要用计算机 能听懂的语言才能和计算机对话,就像你需要用当地的语言才能和老外沟通一个 道理。
不过由于发明一种新的编程语言的成本相当低,而成就感相当高,因此目前已经 出现了太多的编程语言。即有针对娃娃的图形化编程语言,也有中文的编程语言, 更有针对不同计算平台的编程语言,试图学习所有的编程语言是不明智的,也是 毫无必要的,因为编程最重要的是思维,语言只是向计算机表达你的思维的 一个手段而言。
在和计算机沟通时,一次说一句话是比较低效的,因为它会处理的非常快,大量的 时间浪费在等待我们的输入上。所以通常是写很多句话一并告诉计算机照着做,这 就是我们常说的计算机程序。例如,对于前面说到的把大象放进冰箱这个任务,可 以编写如下包含三句话的计算机程序:
1 | openFrigDoor |
基本上就是我们的操作步骤的翻译,对吧?
4、我应该学习哪种编程语言?
虽然编程语言不重要,但是初学者选择合适的编程语言却非常重要,因为它会 影响你的学习效果和成就感的达成,而且,你终归需要选择一种编程语言才能 开始学习编程。
就像大家都喜欢学英语而不是非洲某个国家的法语变种一样,通常你选择一个 大家都在用的编程语言是不会有大的问题的,例如看一下权威的 TIOBE编程语言排行榜2019年3月的统计:
Mar 2019 | Mar 2018 | Change | Programming Language | Ratings | Change |
---|---|---|---|---|---|
1 | 1 | Java | 14.880% | -0.06% | |
2 | 2 | C | 13.305% | +0.55% | |
3 | 4 | Python | 8.262% | +2.39% | |
4 | 3 | C++ | 8.126% | +1.67% | |
5 | 6 | Visual Basic .NET | 6.429% | +2.34% | |
6 | 5 | C# | 3.267% | -1.80% | |
7 | 8 | JavaScript | 2.426% | -1.49% | |
8 | 7 | PHP | 2.420% | -1.59% | |
9 | 10 | SQL | 1.926% | -0.76% | |
10 | 14 | Objective-C | 1.681% | -0.09% | |
11 | 18 | MATLAB | 1.469% | +0.06% | |
12 | 16 | Assembly language | 1.413% | -0.29% | |
13 | 11 | Perl | 1.302% | -0.93% | |
14 | 20 | R | 1.278% | +0.15% | |
15 | 9 | Ruby | 1.202% | -1.54% | |
16 | 60 | Groovy | 1.178% | +1.04% | |
17 | 12 | Swift | 1.158% | -0.99% | |
18 | 17 | Go | 1.016% | -0.43% | |
19 | 13 | Delphi/Object Pascal | 1.012% | -0.78% | |
20 | 15 | Visual Basic | 0.954% | -0.79% |
不过贸然地从众选择并不适合所有的情况,每种编程语言都有它特定的优势领域和优势生态, 我尝试根据你学编程的目的以及特定领域从业企业的主流选择给出适合初学者的几种选择, 但更细化地分析远远超出了本文的范围:
学习目的 | 推荐编程语言 | 推荐理由 |
---|---|---|
只是玩玩 | JavaScript | 随处可以找到运行环境,容易获得成就感 |
开发网页应用或网站 | JavaScript | 只有JavaScript可以支持单一语言前后端全栈开发 |
开发安卓应用 | kotlin、java | Kotlin是趋势,Java更通用 |
开发苹果应用 | Swift、Object-C | Swift是趋势,初学者不要选Object-C |
开发游戏 | C#、JavaScript、C/C++ | C#是因为Unity的存在,JavaScript更适合网页游戏,C/C++更适合网络端游 |
开发数据分析或机器学习应用 | Python、Julia、R | Python是这一领域当之无愧的王者,Julia是值得关注的趋势语言,R在数据分析上有自己的价值 |
开发企业应用 | Java、C# | 去偏传统的IT公司工作的最佳语言是Java和C#,工作机会非常多 |
开发嵌入应用 | C、Assembly Language | 穿戴设备或IOT软件的运行环境受限,需要这种底层的语言 |
开发服务端应用 | JavaScript、Go | JavaScript是因为NodeJS的存在,Go是因为它为网络服务应用开发专门进行了优化 |
如果你目前还没有明确的学习目的或者倾向性,我推荐两种语言:JavaScript和Python。 这两种语言都有很好的生态,意思是当你需要帮助或者需要使用第三方代码时比较容易获取。 如果你有意向数据分析/机器学习/人工智能方向发展,那么选择Python,其他情况,选择JavaScript。
无论如何,还是建议你首先考虑自己学习编程的目的是什么,有哪个方向是自己感兴趣 并且愿意付出时间和努力的,毕竟,兴趣是最好的老师。
5、编程的核心思维是什么?
在机器学习成为显学之前,传统的编程思维只有一条主线,就是逻辑的表达:把你解决问题 的思维,用特定的编程语言表达出来,整理出程序让计算机去执行。这需要你把目标 问题分解成一个一个的已经解决的小问题,然后再把这些小问题的解决方案整合成最终 的完整解决方案。
理论上只需要三种整合手段就可以实现任何计算任务:顺序、条件判断和跳转:
第一种就是我们解决大象问题时用到的,顺序整合逻辑,依次执行分解后的解决方案就 可以得到最终的解决方案。顺序执行是最基本的整合逻辑,它为程序的编写奠定了基础。
第二种关键的整合手段是条件判断,意思是需要根据执行时的实际情况判断是执行 方案A还是执行方案B,这个看起来极其简单的判断逻辑事实上是程序展现出千变万化 的核心所在。你可以在很多软件里观察到条件判断的存在,例如高铁的烟感探测软件只有 在检测到有人在车厢内抽烟时才会报警,而游戏只有在你击杀大BOSS之后才会通关,或者 12306检测到你成功识别了它相当有情趣的验证码之后才允许你登录…
第三种整合手段是跳转,这使得程序可以改变执行的先后流程,从而改变程序的 运行效果。实际上条件判断之后执行的就是一种规范化的跳转,例如跳过方案A的片段或者 跳过方案B的片段。
循环则是另一种常见的规范化跳转,它可以让我们将一个方案重复执行若干次,而不是在程序 中将这个方案复制若干次。例如,当需要我们编写程序实现猴子吃香蕉的任务时,可以看到使用 朴素的顺序整合与循环整合的区别:
因此,在传统意义上的编程,其核心思维就是目标任务的分解与解决方案的整合,将目标任务 分解细化到你已有的解决方案层面,再使用以上三种手段进行整合。
软件2.0
在机器学习兴盛之前,几乎所有的软件都是规则逻辑的表达,开发者需要对任务进行分解, 理清每一个细节的解决方案,然后再整合到一起。虽然技术不断地更迭,也不断出现新的 开发语言和领域模型,但是这一基本的思路是从来没有变化过的。
不过机器学习尤其是最近十年深度学习的兴起,已经逐渐产生了一种新的软件开发范式, 这种新的范式被Tesla的AI主管Andrej Karpathy称为 软件2.0 。 如果你学习编程的目的是要进入人工智能领域,希望这部分的内容对你有所帮助。
在传统的编程中,开发者是规则的制定者,这些规则以程序的形式存在,而计算机则仅仅 负责执行,也许由于开发者的某个疏忽可能会导致程序的运行出人意料,但整体上来讲 开发者是程序的强力操控者,所有的执行逻辑是开发者的思维的展示。
但是在软件2.0中,开发者只是实现一个基准的程序,而大量具体化的处理规则是这个 基准程序通过对大量数据的处理而得出的,也就是说,程序执行的规则一部分由开发者设定 (被称为模型的超参数),而另一部分规则却是由程序自己通过与数据的磨合优化出来的。
例如,人脸识别已经从早期的手工设计用于识别的特征进化到由深度神经网络自动从大量 标注数据中提取特征:
在软件2.0中的基准程序需要更高层级的抽象,而不局限在一事一议的具体问题解决 的逻辑表述上。在目前这一层主要是利用人工神经网络来实现的,程序自主学习的规则体现 在神经元的连接权重调整上。因此软件2.0的开发范式,其核心思维就是设计适合 问题领域的模型,然后用数据来优化出模型的参数。
软件2.0还处于极其早期的萌芽阶段,但非常值得初学者关注,它的发展也许会最终 改变软件开发的模式,虽然我确信在相当长的时间内编程作为一种工作而言都不会消失。
6、应该按什么步骤学习编程语言?
编程是需要熟练的掌握一些基本技能的,因为需要用这些基本技能来组合出来针对特定 问题的解决方案。当你还是一张白纸的时候,即使了解了顺序、条件判断或者跳转、循环 之类的思维也解决不了具体问题,因为分解到最后还是找不到可用的武器。
编程语言是你的第一个武器,要用好这个武器,就需要尽可能多的了解一个编程语言 的能力。可以参考下面的问题探索编程语言的能力:
1、这个编程语言怎么定义变量、函数或者类?
变量是让同一段程序能够适应各种执行环境的必备品,在程序中顺利地使用变量意味着 你有了初步的抽象能力。几乎所有的编程语言都支持变量,那么先了解一个编程语言如何 定义变量、如何给变量赋初值是理所应当的。
例如,你要编写的程序可能有很多个注册用户,而你的程序核心逻辑并不需要根据用户的不同 而区别对待,那么将注册用户抽象成一个变量来编写你的程序逻辑就是合理的选择:
函数(或者过程)是组织可复用代码的一种常用手段。如果有一个功能你会在多个地方使用, 那么把这个功能封装到一个函数里是常见的代码复用手段,这样就避免了同样的实现代码 在程序的不同地方重复出现,优化了代码,也更容易维护。
如果说函数是对计算机原生的顺序过程化思维的一种优化组合方法,那么类则是面向 对象的软件设计思维的优化组合方式,不妨简单地把面向对象视为对现实世界中的 实体对象以及相互关系的模拟,例如可以把所有的用户视为一个类,因为在我们的程序 中这些用户有一些共同的特性和方法。
2、这个编程语言怎么表达顺序、条件判断、跳转或循环逻辑?
就像前面说到的,这些组合手段用来把程序的各部分拼装在一起,因此是必须掌握的。
3、这个编程语言提供了哪些基准解决方案?
所谓基准解决方案就是可以解决某个单一问题的方案,例如:怎么输出一句话、显示一个图片 或者访问服务器上的数据库。通常一个编程语言都会提供一些内置的基准解决方案,以 函数或者类的形式提供给开发者,这些函数或者类,就是我们常说的API —— 应用开发接口。
因此在了解了编程语言的基础语法之后,需要学习的就是编程语言提供的API的使用方法。 虽然不需要逐个验证每个API的功能,但是强烈建议你设定一些问题,然后带着这些问题 找出可以解决这些问题的API进行练习 —— 这些API是你解决具体问题的基础。
4、这个编程语言有哪些优秀的第三方开发包?
大多数的编程语言都采用开发包的形式支持第三方提供扩展解决方案,以便开发者可以根据 自己的领域需求进行选择。了解你选择的编程语言有哪些常用的开发包是非常重要的一件事, 这可以避免你重新发明轮子,提高学习效率。
例如,同样是学习Python,如果你的目标是要开发Web应用,那么需要了解的就是Flask 之类的Web开发包,而如果你的目标是要开发机器学习/深度学习应用,那么需要了解的就是 numpy、scikit-learn这些开发包了:
7、学习编程有什么方法吗?
毋庸置疑,和学习其他知识或技能一样,学习编程也需要掌握正确的方法。
1、多实践基准API
第一个学习方法就是多实践,只有思路是远远不够的。过于强调看书看视频而忽略实践 的结果就是眼高手低。你看到一个问题,思路上觉得行得通,但是却怎么也实现不出来。 这是因为编程需要精确地考虑并实现每一个细节,如果只是粗线条的理解,是很难达到 学习目标的。
那么怎么才能多实践?应该多模拟一些实战项目吗?
不是这样的。在早期的学习中,不应该参与复杂的实战项目,而是应该尽可能多的 了解编程语言的能力,比如练习它的基础API的使用方法、练习它的扩展包的API的使用方法。 一个实践任务一定不要包含太多的代码,最好聚焦于一个API,尽可能地理解 它的用法,以及它对应的抽象模型的内在机制。
有的时候一个API用起来很简单,但是它有对应的抽象模型存在,这个模型并不容易一下理解。 例如当你学习JavaScript操作网页的时候,就会接触到文档对象模型、Flex盒模型等诸多 抽象,在这种情况下,建议你先遵循黑盒法则,就是先了解这个模型的作用,掌握API 的使用方法,而暂时忽略其内部运行机制,然后将这个不理解的问题暂且记到小本本上, 留待日后解决。
所以,我们说的多实践,不是实战项目的实践,而是在很细粒度上的实践,理想 的粒度是在单一API上完成一个实践,因为API本身就体现了编程语言或开发包的设计者 的初衷。
2、多问自己为什么
第二个学习方法就是在学习的过程中,多问自己一些为什么,有意识地设计一些问题 挑战自己,把一时解决不了的问题记录下来,带着问题继续学习。
第一种问题是在学习过程中自发产生的,比如前面提到的,现在学习的某个知识点可能 涉及到了另一个之前不了解的知识点,如果那是一个比较难理解的知识点,那么还是先 记录下来,不要打断当前的学习思路。
第二种问题是有意识的发问。例如当你练习一个API的使用时,不妨考虑一下这几个问题: 这个API可能在什么场景下能用到?为什么这个API需要这些参数?这个API和之前学的哪些 API经常一起用?
能够主动地向自己提出问题是很了不起的进步,这意味着你真正进入了主动思考的状态。
3、设定分级目标,继续实践
在实践API的时候,我们的目标就是理解并掌握这个API的使用方法。当初步熟悉了编程 语言的API之后,就可以设定下一级的目标,尝试着用已经掌握的知识去实现这个目标。 不需要完成一个大程序,对于大多数情况而言,这时候试着编写一个诸如贪吃蛇这样 的小游戏是合适的:
当然这种阶段性的目标也是与你的最终学习目标相关的,例如,如果你的学习动力是要开发 网页应用,那么这个阶段试着实现一个简单的图片分享或者博客系统都是可以的;而如果 你的目标是人工智能,那么这个阶段可以试着用神经网络解决一下文本分类的问题。总之 阶段性的分级目标的设定是为了给自己一个前进的动力,过高或者过低都不好。
4、在战斗中学习战斗
学习编程的目标是不是学习,而是开发出有价值的程序。因此完全脱产的学习终究会告一段落, 你可能会投入到繁忙的编程工作中去。不过这并不意味着你不再需要学习,事实上, 技术的演变是极其快速甚至剧烈的,因此别忘了:
保持积极学习的心态和敏锐的好奇心,在战斗中学习战斗!
5、交流
三人行,必有我师。和有经验的开发者或其他处于同样学习阶段的同学一起交流也是非常必要的。 手机QQ扫描下方二维码马上加入编程学习交流群:
汇智网原创,转载请标明出处