知乎被万人称赞,这是我在公司见过的最好的编程指南。回想起来,这些年我确实踩了不少坑。刚开始学习编程的时候,我也想一口咬成一个胖子,想快点做起来,但有时却不尽如人意。回顾了这几年学习编程的过程,整理了一些我认为需要注意的方面,分享给大家。希望编程初学者能少走一些弯路。文章可能比较长,但真心希望编程初学者能够仔细阅读。至少,我认为如果我在刚开始学习编程的时候读到这篇文章,对我会有很大的帮助。这或多或少是有帮助的。我个人是一名计算机科学专业的学生,??很多人可能认为我是在课堂上学习编程的,事实并非如此。我认为专业背景的学生和非专业背景的学生最大的区别是,专业背景的学生知道要学什么,每门课程是干什么的;还有一些必须完成的作业和小项目,促使他们做一些实际的事情Coding练习,除此之外,真的都是自学的。对于自学编程,我觉得首先要讲的是如何避免一些陷阱,这样可能会节省很多时间。下面我将以提问的形式分享一些我认为重要的方面。1.我应该选择什么编程语言?或许初学者最头疼的问题之一就是【我应该学习什么编程语言】或者【我需要学习哪些课程来制作一个网络或一个应用程序】。许多人一直在为这个问题而苦苦挣扎并陷入困境。在向东学一点,向西看一点的死循环中,到头来什么都没学好,浪费时间。大一的时候,我也纠结过应该选择什么编程语言。问了很多人,上网查了资料,得到的答案都很片面。他们大多对这个问题回答得不着边际,总是回答“某某编程语言难”、“某某编程语言性能好”。其实作为初学者,我们对计算机系统了解不多,所以不要太担心性能,或者难度等因素。原因我以后再说。如果你有明确的方向,那么它是一个不错的选择。如果你想做算法和机器学习,那么python是最好的选择。如果你想做web开发,java、php等都可以。如果你想做一些更底层的工作,那么你可以选择c。当然,这是基于你明确的方向。然而,很多人从来没有接触过计算机行业,尤其??是像我一样转学计算机专业的人。对于这些学生来说,每一种编程语言都只是一个名字。除了名字不同,你根本不知道它们之间的区别。所以不用担心,让我为您选择一个。如果你是大学生,那么你有很多连续的时间,先学c,再学c++。我个人学习c作为入门。可能很多人不明白我为什么推荐学c,因为c和c++都比较难,比较复杂,看起来不太适合入门。然而,正是它们的难度和复杂性,让你更好地理解计算机系统【计算机系统不是指操作系统】。学习编程不是学习编程语言,而是学习一个计算机生态,即一个庞大的知识体系。只懂编程语言,不了解整个计算机系统,就像只会写字,却写不出好文章一样。理解c/c++和理解计算机系统是极其契合的。它可以帮助您更轻松地了解操作系统、编译原理、计算机网络和计算机组成原理。为什么?因为很多底层的东西都是用c实现的,与系统的契合度极高,所以很多教材源码甚至教程在讲述这些知识的时候都是以c或者c++为媒介。而向上,c++的面向对象机制也可以让一些应用,比如五子棋游戏等,也不会显得那么枯燥。花半年时间去了解c和c++,然后你会觉得看书看资料容易多了。如果你是上班族,但只是学习编程,学习c和c++对你来说可能有点复杂和困难,因为学习它们真的很花时间。你不像在校生那样有很多连续的时间,零碎的时间学一个比较复杂的东西效果可能没那么好,所以你可以先学一些【更容易有效】的编程语言,我们从蟒蛇开始。至少可以快速做出一些小应用,以免失去兴趣,但是如果真的想入门编程,还是得看计算机系统相关的书籍,这样才能更深层次地编程,比如【深入理解计算机系统】这篇文章这本书可以多看几遍。本书将整个计算机系统串联起来。2.学习编程,需要学习哪些课程?我必须学习哪些课程?为什么要学习高等数学、离散数学、线性代数、概率论等课程?这个问题也是困扰我很久的问题。但我现在想通了。对于【高等数学、离散、线性代数、概率论】等课程,讲解起来很容易。做算法的同学肯定知道为什么要学这些课程。上面提到的课程在机器学习中会大量使用,所以会比较容易理解。对于现在的学生来说,学校开设的很多课程我们都不知道为什么要学。我们很迷茫,不知道学了它们有什么用。这个时候,我们会很纠结,会有抗拒。这很正常,因为我们对它们的研究还不够深入,无法理解它们的用处。在我看来,本科更多的是“面对面”的教学,就是教你一些课程,但是没有那么深入;而工作或研究生更“以点为本”。“学习,用到的知识比较专业。你本科的时候,学校不知道你以后会不会从事算法、架构、服务器开发,甚至是硬件,所以学校要求你学一个很多课程,起码要有一个了解。对于学生来说,一方面可以选择自己感兴趣的点,另一方面也可以启发一些未来的就业方向。所以即使像digital这样的课程以后可能不需要电和模拟电了,还是得学,而且要花很多时间,虽然最后不一定非要搞硬件,但这些课程也会让你更轻松为你了解一些知识,比如cpu中的逻辑器件。如果你大一定位明确,知道自己以后想从事什么样的工作,可以调整课程之间的优先级。但是喜欢大学物理,这kind当然对编程真的没什么帮助,但是我之前说过,大学教育更注重广度,bigthings之类的课程可能是为了给你普及生活常识。事实上,大学教育的问题无处不在。我觉得我们在学习一门技能的时候,应该采用项目驱动的学习方式,也就是需要用到什么东西的时候,以后再去学,而不是先去死记硬背。都塞进了我们的脑子里,在学习的过程中不知道有什么用。当我们以后使用它时,我们甚至不记得我们已经学会了。反而我们在查资料的时候会想到:哦,原来我以前学过xx。科目就是为了这个目的,但我当时没有好好学习。在很多情况下,学生时间的浪费可能仍旧归咎于老师和学校。他们一开始没有给我们足够的课程介绍。因此,经过更多的编程和项目实践,我认为更好的学习方法是改进版的项目驱动学习法。即:学习一段时间,做一个小项目,把项目中遇到的问题记下来,有针对性的学习相关知识,然后实践,再学习一段时间的理论,让知识以类似网络的方式变大。当然,项目驱动学习有一个缺点,就是每次学习的知识都是项目所需要的,非常零散和不系统,所以需要改进,就是在采用项目驱动学习方式的时候,取每天花一段时间把它读完。一本书,或者对一个相关问题的完整介绍,这样很容易把一些知识系统地串起来。经过这样一段时间,慢慢的,你就会知道为什么我们要学那么多科目,学了这些科目我们能做什么。为了表达的更形象,举个小例子,是我最近遇到的。我自己的工作是做LinuxC++,但不限于此。我个人对python、数据分析和机器学习很感兴趣。你可以看到我最近在我的专栏里发表了很多文章。我先从数据获取说起,说说我这两个月做了什么。说到数据获取,爬虫可能是最容易想到的。爬虫是知乎上一直被吐槽的话题,具体是什么我也不想多说。很多时候有人觉得爬虫很简单,为什么呢?因为有现成的框架,更容易获取少量数据。但是当你需要爬取的数据非常大的时候(比如我之前抓取过500万用户的数据,下班时间用家里的普通PC,电脑性能就没那么好了,不如作为服务端,而且要在不被IP屏蔽的情况下抓取这么大的数据,然后清洗数据,最后可视化),用现成的爬虫框架可没那么容易。而且,我需要掌握大量的数据来源,也不是一蹴而就的。所以我选择了开发一个系统,也就是在现有的框架下进行二次开发,搭建一个自己的爬虫系统,植入一些算法。我在系统中加了很多中间件,到现在可以部署一个10分钟内抓取大量数据的爬虫应用。当然,这个过程也遇到了很多麻烦,所以我就简单说说每个问题是如何克服的。下面是树状图。从上到下的每个圆圈代表学习过程中遇到的困难。如果你现在不明白,没关系。我想告诉大家的是一种知识梳理的方法:如上图所示,是一个项目驱动学习的例子。我们的目的是获取数据,所以我们选择了爬虫:爬虫可以理解为一个简单的过程:发送请求,得到响应,然后提取数据。这个过程会涉及到网络,是发送http还是https请求;目标网站是否需要登录,是post请求还是get请求,从这一行衍生出一条了解网络的路径。获取到网页后,如果不是结构化数据,可能会返回一个html源码,那么你可能需要懂dom,或者html页面解析的知识,甚至是前端开发。在爬取的过程中,经常会遇到数据中途爬取不到的情况。一般IP被封了,可能又要用代理了。什么是代理?http和https代理可以混合使用吗?如何建立代理池?这里也有很多东西要学。也可能出现抓取数据加密的情况,需要通过js解密。这时候就需要了解js,以及如何使用爬虫模拟浏览器进行爬取。另外,如果抓取的频率不对,很多数据源会给你虚假的数据。这是经验问题。这篇文章不是技术文章,就不多说了。解决了上面的问题之后,我们貌似可以拿到一些数据了,但是当数据变大的时候,问题就变得复杂了,可能就需要用到分布式爬取了。这个时候你可能需要学习一下redis。当请求产生的速度大于它的消费速度后,你的任务队列可能会爆炸,所以这里又涉及到算法和数据结构的应用。数据量变大后,往文件里写数据就不靠谱了。这时候就涉及到存储。使用关系数据库和非关系数据库有什么区别?如何对存储的数据进行去重?为什么插入操作会卡住?为什么电脑越来越热?什么是索引,应该在什么时候建立?这就涉及到数据库原理相关的知识。遇到一些比较难的网站,比如验证码识别怎么办?其实很多纯数字和字母的验证码很容易解,可以用深度学习自己训练。在TensorFlow的Demo中,需要生成自训练验证码的教程,然后制定一个中间件放到爬虫系统中,就解决了这个问题。但什么是深度学习?这里再举一个探索深度学习的例子,我在学校的时候也自学了半年的机器学习。有了一定的基础之后,我就可以比较轻松的上手TensorFlow框架了。再往下,就更深了。以上六点简单说了下项目驱动学习的介绍。事实上,你看到的每一个小圈子都有很多值得挖掘的地方。我们现在看到的只是冰山一角。任何学习路径都没有尽头。我们学不完,但是项目驱动学习最大的好处就是让你知道自己应该学什么,而不是先学一大块。积累知识,然后做一个项目。严格来说,项目驱动学习的视觉路径是一张网,而不是一棵树。这里画树形是为了方便大家理解。除了获取数据,还有数据清洗、数据分析,甚至数据挖掘,最后是数据的可视化和展示。这里就不一一介绍了。你可以看到下面的图片。如果你想看我的一些成品,你可以看看我的其他文章。3.学习编程需要制定计划吗?学习编程需要制定计划吗,应该制定什么样的计划?我觉得不仅编程需要做计划,其他任何学习和工作都需要做计划。从2013年上大学开始,我就开始定期为自己制定计划,这个习惯一直坚持到现在,让我受益匪浅。当然,不仅仅是制定一个学习计划,你还可以列出一些其他你需要做的事情。最近在整理笔记的时候,还发现了一些以前记录的方案和清单,可以给大家看一下。比如下图是我2014年写的笔记,最后一次打开的时候留在了笔记上。列了一些自己需要看的文章,因为当时对策划了解不多,所以比较乱。到我16岁的时候,我的计划更有条理了。下图是2016年10月30日的plan,那时候我已经是大四了,已经找到工作,签了一份满意的offer,没有课。按理说可以松口气了,不过还是做了一些打算。学习计划,11月份选择去百度实习。从内容上看,主要是学习英语和计算机专业课,因为大一和大二的时候真的不明白为什么要上专业课。这很重要!学完这些教训,会让你以后的学习和工作变得更轻松:除了大四做的计划外,我大二的时候也做了更详细的学习计划(如下图),并随身携带出需要学习的内容。以表格形式编号存放,让您生活有条不紊。当然,很难完全按照计划执行,但是制定计划会让你清楚地知道你应该做什么。所以,如果你是学生,制定一个计划,因为你有很多时间。当然毕业了也没关系,我现在也在工作,我也把最近要学的内容罗列一下,如下图(2月27日更新),包括短期和长期学习内容:4.编程需要做笔记和写博客吗?在我看来,写不写博客并不重要,因为博客是写给大家看的。可能要保证格式漂亮,语法尽量准确,最好文艺一点。而做笔记是必须的,做笔记是一个长期的过程。在学习的过程中,我们一直追求最高效的学习方法。比如同班同学用他的学习方法考上清华,你用同样的方法就不行。为什么?因为他的方法是为他自己定制的,大概率不一定适合你。比如,你可能看不懂他的笔记,因为他可能自己设计了一套符号。就编程而言,很多同学都说好好利用搜索引擎是对的,但是搜索引擎找到的都是别人的答案。如果你把它复制过来,它可能还能用,但你不记得了。这些知识不属于你。后面可能遇到同样的问题,又得重新搜索。可能很难找到以前的答案。但是记笔记是不同的。笔记是定制的。您可以为自己定制它。你可以用你最好的表达方式描述问题。这是你为自己写的东西。多读几遍,你就会很快理解。如果以后遇到同样的问题,可以通过查找笔记快速解决。例如下图是我记录的一些使用gdb【linux下c++调试工具】的笔记。我只记录了一些我最常用的内容。也许你看得一头雾水,我却很容易看懂。这是我的定制。你必须坚持记笔记的习惯。一两年后,这将是你的巨大财富,因为这是只有你自己才能理解的东西。记录了4年多,1G多的内容,现在笔记基本形成了一个体系,可以给大家看一些。专业知识相关的笔记:开发相关的笔记:部分分类:5.什么是比较好的编程方式?除了上面分享的一些方法外,我觉得你不应该同时学习太多类型的课程。比如可以同时学习python和html/css,但是不要同时学习python、操作系统、编译原理、计算机组成、数据结构等,网络,之前试过,没过多久就学会了下一个。事实上,我根本没有学到任何实用知识。因为记忆知识符合艾宾浩斯记忆曲线。对于一门课程,尤其是比较难的专业课,比如操作系统,如果每天看半小时,效果比较差,可能要预热半小时。所以我宁愿一天学两科,然后每科多花一点时间,比如两个小时。【毕竟学校有课,每节课两个小时】,切忌贪吃,吃多了也不会胖。6.需要刷oj吗?我觉得刚开始编程的时候应该刷一下,但是一定要注意不要被身边的“X大神”给误导了。因为我上大学的时候,总是有很多人在搞电脑竞赛,他们都互相称呼为“X大神”,而某位大神用强大的算法把程序时间从1秒缩短到1秒第二。0.999秒。奉劝大家的是,刷题不是为了这个目的,并不代表一定要在比赛中拿奖。除非你真的喜欢,否则,没必要死记硬背代码。我们刷题的目的是为了适应写代码的感觉。在这个过程中,你会遇到编译错误。你会慢慢记住一些语法,关键字,理解一些概念。自己也可以用,比如实现数据结构。慢慢的你就会有经验,知道一些错误的原因。我也慢慢的来到了这里。现在上班和下班写代码的时候基本不用IDE。比如写C++,要么是vim,要么是sublime,我用前面提到的工具gdb调试。也就是说,您可以使用文本编辑器编写代码,摆脱IDE的束缚。写了一段时间oj,熟练之后,不用再做小考了,可以去github等网站找一些项目,然后跟着自己写,编程能力会逐渐提高提升。就计算机专业而言,很多同学在大一上了编程课之后就很少写代码了,这是很糟糕的。除了锻炼编程能力,刷题对于求职前的惊喜也是非常有用的。比如我之前申请的是华为的研发岗位,校招的时候就有笔试题。2016年国庆刷了华为的oj,??记得当时笔试总分是600分。如果我通过了100分,我将获得面试机会。轻松拿了500分,当时才20分很多华为题。7.看书还是看视频?网上很多人鄙视看视频学习的学生。我不知道为什么,因为我认为看视频是一种很好的学习方式。但是我们要明白看??书看视频的好处和坏处。其实我更推荐看视频入门,因为现在网上的面向应用的【非学术:比如清华大学的操作系统,很难】的视频都很简单,很多都是针对初学者的,而且视频可以相对容易地使用。在短时间内告诉你,你现在正在学习的技术可以做什么,你可能需要先学习哪些知识,可以帮助我们构建一个项目驱动的学习网络。但是视频也有缺点:知识非常复杂,没有系统性。虽然现在很多教学网站都提供了学习路径,但是这些路径中的视频往往不是同一位老师录制的,而是按照知识依赖的顺序排列的。因此,如果想通过视频系统地学习一门知识,是比较困难的。【当然,还是推荐一些学术类的视频,比如斯坦福的机器学习,清华的操作系统,数据结构等课程,如果能一直看下去,一定会受益匪浅】。应用性的知识,比如web开发,还是得看书。书籍等功能系统化,由浅入深,可以自定义自己的薄弱章节。所以更好的学习方式是:看视频入门,看书进阶。8.学习编程需要多长时间?事实上,这个问题是没有答案的。如果你只是想做一个小应用,2个月就够了。个人认为学习编程不是学习一门编程语言,而是学习一个生态,一个计算机系统,学无止境。9、应该选择哪些资料和书籍?其实这个问题也是很多编程初学者容易迷惑的问题。网上有我们一辈子都看不完的教程和资料,所以现在应该没有找不到视频教程或书籍看的问题了。问题是我们不知道该看什么视频或该读什么书。自从开始学习编程以来,我买了几百本书,但真正适合自己的好书并不多。视频教程的问题就更严重了。如果东张西望,很难将知识组织成一个网络。所以在学习编程的过程中,我们遇到的最大的问题就是:遇到问题的时候,在大量的信息面前,我们不知道该选择什么样的信息来学习。虽然我们是用project-drivenlearning的方法找到方向的,但是同一个路径下有很多资料。在上面列出的项目驱动学习的图中,我们从上到下发现问题,然后解决问题。如果有人能帮我们整理一下学习路径,然后自底向上学习,效率可能会提高很多。
