编程思想才是所有程序的基础

gznr9617 8年前
   <blockquote>     <p>先讲一下我写这篇的目的:</p>     <p>1、最近几天刚开始稍微正规地学习一下编程。</p>     <p>2、整理自己学习编程用到的知识,巩固知识。</p>     <p>3、这个过程肯定有N多漏洞,希望大家指出。</p>     <p>4、顺带帮助大家。</p>    </blockquote>    <p>我是一个不怎么安分的编程学习者,总想学很多东西,然而连最基本的一门语言都没有好好学习,虽然这并不妨碍我对编程的热爱,但在实际编程中的确遇到了很多问题。但我觉得这些问题并不是基础不牢,语法运用得不熟练,这些都可以搜索出语法,用时间解决,但真正决定一个程序好坏的远不止这些。</p>    <p>假设我们学习编程的目标就是写出一个长得像市场上的APP或者网页的话,感觉就算四年学完学校里的东西也不一定能写出来。这其中的差距我觉得并不是由于这些基础的编程语言熟练度决定的。特别对于一个像我这样,仅对编程感兴趣,但可能不会把编程当饭吃的人来说,这篇文章就以新手的视角探索总结了一些目前的一些编程思想。同时我希望有人能认真地看下去并实践,甚至给出一些反馈意见,一起成长。</p>    <p>在我们开始编程前会有一个疑问,编程应该从一门流行的语言开始学起吗?编程应该从最基础的C学起吗?作为一个才入门的小白,我觉得——编程应该从历史学起。只有从全貌理解了编程是怎么发展的,发展出了有哪些编程方式,在我们实际编写代码的过程中才知道自己欠缺哪部分,实际写代码的时候才会知道该补充哪些知识,怎么找到这些知识。</p>    <p>一、编程的历史</p>    <h2>1.1计算机</h2>    <p>最早的编程伴随着计算机的诞生而诞生,计算机是用来计算的,而要用到计算就必须有机器运作的逻辑,而对基于电路的CPU来说,能用来运算的只有两个状态:0和1,分别表示电路开关的“关闭”和“打开”状态,也可以说是“不通电”和“通电”状态。这也就是我们说的二进制,二进制的运算规则是“逢二进一”、“借一当二”,数字2如何在电路中表现出来?电路中有两个开关00,给电路+1,开关变成01,再+1,开关变成10,于是15可以用四个开关表示为1111。二进制对运算的帮助是:不需要用开关数量表示数字,不然那得多少开关。</p>    <p>因此CPU在设计时自然而然地分成了三部分:控制器、逻辑运算、存储器。控制负责CPU要做什么工作,一般会分配4个“开关”,0000到1111共16个操作指令,假设把0000定义为加载,0001定义为储存。然到逻辑部分,指要进行什么运算,假设0001为加法。最后到存储部分,由于存储空间很大,可能会用12位来表示数据所在的地址。</p>    <h2> </h2>    <p><img src="https://simg.open-open.com/show/8deb78afd768147867348ee3304b5888.png"></p>    <p>之前玩的游戏MineCraft里的红石电路就讲了几个逻辑电路的概念:“与门”、“或门”、“非门”,以及由他们组成的高级电路。CPU为了实现这些计算功能,设计了一系列硬电路和指令集,硬电路是与或非,或者更高级的电路,指令集是指导CPU运算优化的方案。</p>    <h2> </h2>    <p>1.2机器语言、汇编语言、高级语言</p>    <p>计算机编程语言共分为三种:机器语言、汇编语言、高级语言。上面讲的其实就是机器语言,人们通过输入不同的二进制数设计程序,而计算机通过这些定义好的规则进行运算。但可以预料到机器语言是多么麻烦,要记不同的数字代表的意思,所以汇编语言应运而生,汇编语言案例:</p>    <blockquote>     <p>操作:寄存器BX的内容送到AX中</p>     <p>1000100111011000              机器指令</p>     <p>mov ax,bx                           汇编指令</p>    </blockquote>    <p>汇编语言也就是将机器语言用英文单词的方式来表现出来,因此非常容易记忆。这样来说,高级语言就好理解了,也就是将汇编语言的集合整理成我们常用的英文逻辑指令,例如高级语言中的“if”判断指令,对应的汇编语言可能就有一大堆代码来进行运算,实现判断功能。</p>    <p>随着编程的发展,高级语言也分成了很多种类型,例如C、C++、VB、JAVA、python、lisp,他们各自有各自的特点,设计概念的不同也导致了运算效率的不同。正因为高级语言的运算方法是各种指令的集合,所以越接近机器语言的语言,效率越高。假设我们要计算从1加到100,有一门语言是直接顺序相加,另一门语言像高斯一样,(1+100)*50,那效率的差别一下子就看出来了。</p>    <p>因此,优秀的语言会吸引来一大堆程序员使用,使用的程序员多了,他们自然也可以在这个基础上设计各种运算的方法,形成高级语言衍生的语言,这样对于其他程序员来说就不需要重复造轮子,直接用别人的代码,省了N多编程的事情。</p>    <p>所以,刚开始学习的时候选择哪种编程语言其实并不重要,只需要对程序最基本的逻辑方法,比如加减乘除、判断循环等熟悉就可以了,每种语言都有自己的编程方式,但这些最基础的是不会变的,在学习新的语言的时候,只要了解他们的语法就可以了。</p>    <p>那到底该选择哪种语言?对于只是业余喜欢编程的人来说,当然是越简单越好,越热门越好。简单意味着不需要学习复杂的语法,热门意味着有很多“轮子”给你使用。这样只需要拼凑起来就能做成一个程序了。看看编程语言排行榜就知道了,Python的语法很简单,比前四名的简单了一倍不止,热门程度高,有很多别人写好的“指令库”可以使用,所以Python是一个很好的入门选择。</p>    <p><img src="https://simg.open-open.com/show/2922776aa5e94cda4c61763efa37152f.png"></p>    <p>二、编程的现状</p>    <p>不同的语言有不同的语法,但不同的语法可以使用相同的软件架构(software architecture)。所谓的软件架构,就是代码的组织结构。举个更具体的例子,最初我开始学习编程的时候,只会用的软件架构就是数据流,就是一种流水账的模式,例如要按顺序实现三个功能ABC,数据流会把ABC的具体实现代码都放在一起顺序执行。当需求改变成ACB的时候,又要把具体代码改成ACB。这样代码就会这样:</p>    <blockquote>     <p>1.选择处理方法:ABC、ACB...,并调用相关代码。</p>     <p>2.ABC代码,输入数据。</p>     <p>3.ACB代码,输入数据。</p>     <p>...</p>     <p>显示结果</p>    </blockquote>    <p>这样就造成了很多代码的重复,换一个软件架构可以编程这样:</p>    <blockquote>     <p>分别定义A、B、C要输入什么,A负责处理什么、输出什么。</p>     <p>输入处理流程:ABC、ACB、BAC等都可以。</p>     <p>处理模块:输入数据,按流程顺序调用ABC(输入并输出到另一个,直到输出最后一个)。</p>     <p>显示结果</p>    </blockquote>    <p>由此,我们就可以理解软件架构是什么东西了,说白了就是一种软件的设计思想,说得更白就是组成系统的各个型号的螺丝钉、马达等零件,你可以设计一个只能用于一种解决方法的一体化的工具,也可以设计成由不同零件组成的可以拆解组装的工具模块。</p>    <p>软件架构设计有三大要点:1、代码复用性高;2、易于测试;3、易于维护;</p>    <p>这几个点不知道总结得对不对,求指正:</p>    <p>复用性高指编写的代码重复的概率极少,一般是通过调用各种功能模块来实现整个程序。直白地说就是分块设计成不同零件,它最大的好处是一次编程,随时可以无成本地ctrl+c,ctrl+v,接下来功能编写完后只需要专注于流程的设计,流程是如何组合的。</p>    <p>易于测试是指编程中可能会出现各种BUG,而现在的编程不需要一行行看代码来修改BUG,可以通过编写测试脚本,让程序来测试程序,模拟用户操作,在各种条件下看看会不会出现漏洞。</p>    <p>易于维护也说明了代码可以被另一个人轻松读懂。于是在代码维护的时候,可以快速了解是哪方面出了问题,出了问题也仅需要对出问题的功能部分进行维护,而不是对整个代码进行分析。</p>    <blockquote>     <p>记得这里有一本好书推荐,关于好代码和差代码的(不知道是不是这个名字):</p>     <p>《代码整洁之道》</p>    </blockquote>    <p>所以,好的架构是软件成功的一半。</p>    <h2>2.1常用的软件架构</h2>    <p>关于软件架构这一部分的历史我并不太了解,但是目前常用的软件架构有:MVC、MVP、MVVM这些,简单地介绍一下:</p>    <h3> </h3>    <p>2.1.1MVC</p>    <blockquote>     <p>M指模型(Model):负责数据保存;</p>     <p>V指视图(View):负责用户界面;</p>     <p>C指控制器(Controller):负责业务逻辑;</p>    </blockquote>    <p>MVC是一种很经典的软件架构,经典到已经快过时了,不过小型软件的架构基本就是如此,一部分代码保存数据,一部分处理业务,一部分显示结果。用户在使用时接触到的是视图部分,当对视图V部分进行操作时,代码执行C控制器的业务流程,流程从M中读取数据,最终返回到V中让用户获得执行结果。</p>    <h3> </h3>    <p>2.1.2MVP</p>    <blockquote>     <p>1.View 传送指令到 Controller</p>     <p>2.Controller 完成业务逻辑后,要求 Model 改变状态</p>     <p>3.Model 将新的数据发送到 View,用户得到反馈</p>    </blockquote>    <h3>2.1.3软件架构总结</h3>    <blockquote>     <p>具体关于MVC、MVP、MVVM的可以参考:</p>     <p><a href="http://www.open-open.com/lib/view/open1422788422283.html">MVC,MVP和MVVM的图示</a></p>    </blockquote>    <p>在实际编程中,要注意自己写的代码该用哪种软件架构,虽然一开始可能不懂,但按着网上搜索的一些简单案例,理解了之后编写自己的程序很有用。</p>    <p>选择了软件架构也就选择了一种程序结构,一种编程风格。我们选择的软件架构可能各有不同,选择软件架构一看项目需求,代码比较多就找分得细点的。网上也有很多不一样的软件架构,我也不太懂,希望留言指教。</p>    <p>另外还有一个要配合的是团队开发流程(这个真不了解),例如TDD的流程,测试驱动开发。先编写测试代码,然后编写程序,需要用到的功能测试可行后,代码才是OK的。</p>    <p> </p>    <h2>2.2开发框架</h2>    <p>软件系统发展到今天已经是相当复杂的了,在实际的编程过程中不再需要也很少有必要自己去写一些最基础的功能逻辑。开发框架就是别人编写的一套成熟的基础功能集合(一般也是在某个软件架构的基础上的),你可以不必实现一些基础功能,而仅需要关注业务逻辑代码的编写,以及在此基础上的一些个性化代码的实现。</p>    <p>这些框架一般是成熟的、稳定的、经过多人使用、测试过多次的,结构和安全性都非常好,可扩展性也强的。从定义上来说,开发框架也可以类比机器语言到高级语言的过程。高级开发框架可能建立在一些基础的开发框架之上(也就是实现这些高级功能依赖某些基础功能),大环套小环。当然,框架之间也可能是平级关系,可以同时使用。</p>    <p> </p>    <p><img src="https://simg.open-open.com/show/df74256dd3d2c8df496247238f2c626c.jpg"></p>    <p>我们可以把开发框架的概念放宽一点以便于理解,计算机硬件是一个最基础的框架,它是通过01来处理数据的。然后是操作系统,例如Linux、Windows、OSX,要开发这些操作系统上的应用,就要遵守他们的编程规则(各种API接口、界面设计规则等),接下来是一些基础的软件框架,比如Windows上的JAVA环境、MYSQL数据库环境、IIS环境,他们也有特定的规则。再接下来就是各种软件,或者互联网应用。每个层级都有他们特定的规则,一般来说,更高级的框架会提供一个API去实现更低层的框架的内容,除非我们要写的软件是这个框架无法实现的,我们才需要了解低层框架的编程规则。</p>    <p> </p>    <p>例如比较常用的网页脚本语言是javascript,javascript下又有jquery、bootstrap等实现更多高级功能的框架,这些框架下面还有更多高级功能的小框架。我们可以用javascript直接写这些框架的功能,但你也可以引入这些框架,直接写一行代码就实现了这个功能。更直白地说就是,别人拍了一堆照片,你只需要挑选几张来用就好,而不需要自己选择相机拍摄,各种PS处理。</p>    <p>框架的发展得益于各种开源项目(提供源代码给你免费用,但一般来说你用这些开源项目做的项目也要开源),github就是一个很好的开源项目集中地,我们可以在上面找到很多有用的开源项目,可以应用到自己项目中。</p>    <p>在我们选用开发框架的时候,要选择尽量少的框架,同时框架能实现的更多自己需要的业务。越少意味着加载越快,功能冗余越少,安全性越高。框架自身也有性能瓶颈等问题,这就是后期考虑的了。</p>    <p>这些框架一般会提供给你功能的API,也就是应用程序编程接口,这些内容可以在框架官方的API文档中找到。你只需要给出一个符合API的参数,就可以调用功能并输出结果。例如假设有个plus(num1,num2)功能,输入plus(3,2),功能就会自动计算3+2,并返回给你“5”。 </p>    <h2>2.3现在的编程</h2>    <p>所以在我的理解中,现在的业余编程只需要学习最基础的通用语句,选择自己的软件架构,选择好各种框架,学习其API文档和编程规则,遵循框架规范,调用这些功能实现想要解决的业务。就目前而言,基本上需要自己编写具体基础功能代码的产品已经很少了。</p>    <p>另外,软件架构其实还有一种比较感性的“软件架构风格”,设计风格而不是标准,只是提供了一组设计原则和约束条件。例如restful框架,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。</p>    <h2>2.4使用各种框架时需要注意的一点</h2>    <p>其实在实际编程中运用框架会出现很多问题,每个框架都有自己设计上的一些逻辑、处理优先级。比如说互联网前端中的CSS框架,有时候明明写了这些代码却没法正常显示,然后你会发现框架中的处理逻辑是不一样的,实际需要应用哪些API,哪些组合可以提升性能,从一个框架传递信息到另一个框架该怎么处理,出错率最少。这些都是优秀程序员在不断编写中积累出来的,也是新手与老手最大的区别。</p>    <p>三、互联网</p>    <p>于是最基础的东西讲完可以继续讲比较基础的了。编程语言一开始其实只是单机使用的,编辑好一个程序后,运行就行了。但是人类又发明了一个改变世界的方法,把计算机用网线连接起来,计算能力不是更强了?而且也能做很多其他的事情,比如把资料从一头传到另一头。但是,因为机器不像人,你给另一个计算机发送一个指令,如果另一个计算机的程序里没有这个指令,那运行后岂不是完全混乱然后死机了?</p>    <p>于是,各种互联网协议产生了,互联网协议是什么?给双方计算机一个约定,我们用什么样的语言进行沟通,最简单的例如,开头部分写清楚发送者、接受者、使用的协议等,然后后面就可以跟着要传输的数据了。</p>    <h2>2.1基础的互联网协议</h2>    <p>当互联网从一台计算机连接到另一台的过程,变为一亿台连接到一亿台计算机,我们不可能用这种最简单的约定实现如此大规模的传播,因此衍生了各种各样的互联网协议,例如TCP/IP协议,约定了我们有一个IP地址,通过什么样的流程进行数据输送。例如PPPOE协议,小区要拉网线的时候就是用这个协议验证用户名和密码,给你提供相应的带宽的。当然,硬件上一个网卡也会有一个MAC地址,来确定机器就是要建立连接的那个机器。</p>    <p>除非你编程的时候需要用到改变协议,否则具体原理可以不用了解,很多程序员发明的“库”(也就是Kit,也就是程序员造好的轮子)已经帮你解决了如何使用这些协议的问题,你可以直接一个sent命令就从一台电脑发送到另一台了。现在的计算机应用或者手机应用,已经很少是一个单机应用了,我们或多或少会用到互联网协议来获得用户的一些信息。</p>    <p>所以,这些协议有很多,需要用到的时候再找就是。但如果是做互联网应用的话,有一些协议是不可避免的:</p>    <h3>2.1.1、HTTP协议(超文本传输协议)</h3>    <p>绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。例如我们常说的网址,就是http://www.xxxxx.xx/,用的就是HTTP协议。由于刚开始学,我也讲不了多少,也许后面会补上。HTTP协议比较基础的部分:</p>    <p>http请求由三部分组成,分别是:请求行、消息报头、请求正文。</p>    <p>请求行包括URI(统一资源标识符)和协议的版本。</p>    <p>消息报头包括普通报头、请求报头、响应报头、实体报头。</p>    <blockquote>     <p>请求报头举例:</p>     <p>GET /form.html HTTP/1.1 (CRLF)</p>     <p>Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/* (CRLF)</p>     <p>Accept-Language:zh-cn (CRLF)</p>     <p>Accept-Encoding:gzip,deflate (CRLF)</p>     <p>If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)</p>     <p>If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)</p>     <p>User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)</p>     <p>Host:www.xxx.com (CRLF)</p>     <p>Connection:Keep-Alive (CRLF)</p>     <p>(CRLF)</p>    </blockquote>    <p>从上面可以稍微看出来,其实HTTP协议其实是一个看起来比较复杂,但能说清楚要传输什么的方法,目前觉得看看是什么就行,实际编程中感觉不会用到这些知识。</p>    <p>然后,服务器和自己的计算机沟通的时候会用到一些请求方法,例如:GET、POST,也就是从服务器获得哪些资源,发送哪些资源。</p>    <p>还要知道的就是,HTTP协议的响应方式,也就是服务器给自己的计算机返回的状态代码:</p>    <blockquote>     <p>1xx:指示信息--表示请求已接收,继续处理</p>     <p>2xx:成功--表示请求已被成功接收、理解、接受</p>     <p>3xx:重定向--要完成请求必须进行更进一步的操作</p>     <p>4xx:客户端错误--请求有语法错误或请求无法实现</p>     <p>5xx:服务器端错误--服务器未能实现合法的请求</p>    </blockquote>    <p>例如经典的404页面,当请求资源不存在,或者输入了错误的URL,就会出现“404错误,您访问的页面不存在”等提示。这个对于web应用来说是比较有用的,你可以了解web应用出现了什么错误,进而想清楚如何解决这些问题。</p>    <h3>2.1.2更多关于协议的东西</h3>    <p>水平有限,目前就知道这个协议比较有用啦,想看更多可以参考:</p>    <blockquote>     <p><a href="http://www.open-open.com/lib/view/open1463552679762.html">阮一峰——互联网协议入门(一)</a></p>    </blockquote>    <h2>2.2基于互联网的开发框架</h2>    <p>就像单机编程会用C++、JAVA这些一样,应用在互联网环境中的编程语言也有好几种(有些可能不叫语言),互联网开发主要分为两部分,前端和后端。</p>    <p>前端: 也就是负责编写Web应用中用户可以看得见点击得着的东西。包括Web页面的结构、Web的外观视觉表现以及Web层面的交互实现。</p>    <p>后端:后端更多的是与数据库进行交互以处理相应的业务逻辑。需要考虑的是如何实现功能、数据的存取、平台的稳定性与性能等。</p>    <p>前端需要学习的框架:</p>    <p>1、HTML——是超文本标记语言,通过对资源定义标记从而加载该资源,显示到页面上。地址里面以.htm或.html结尾的就是用这个语言编写的,例如上面那个地址就是html语言编写的。它是最常用的编写网页的语言。</p>    <p>2、CSS——是能够真正做到网页表现与内容分离的一种样式设计语言。相对于传统HTML的表现而言,CSS能够对网页中的对象的位置排版进行像素级的精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力,并能够进行初步交互设计,是目前基于文本展示最优秀的表现设计语言。</p>    <p>3、Javascript(以及一些衍生的jquery、bootstrap等)——JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。</p>    <p>后端需要学习的框架:</p>    <p>1、后台语言——如Python、Java、PHP等,实现业务逻辑的代码编写。</p>    <p>2、数据库——SQL等,实现数据储存的方式。</p>    <p>这些框架其实有非常多种,我们平时可以多去一些开源网站积累,个人见识较少,这部分大家可以补充。</p>    <h3>2.3不同框架之间如何实现数据传递</h3>    <p>一般来说,网上都有很多案例教你怎么实现数据从后端传输到前端或者其他,用到哪些代码、方法,注意积累就好了。例如可以学习如何在HTML中使用CSS,如何在HTML中使用javascript框架实现一些动态内容。这个得先理清框架之间的包含关系,哪个为基础可以先写哪个。</p>    <h2>四、开始编程</h2>    <p>以上仅是我对于编程不成熟的理解,其中也许有许多错漏,希望大家可以指出来,也欢迎大家留言,指出哪里不太懂的地方,这也许也是我没学到的。概念搞清楚之后,接下来也许就是从新手到老程序员的积累了吧。前路漫漫,也许还有各种未知的困难没有涉及到,希望与大家共勉...</p>    <p> </p>    <p>文/<a href="/misc/goto?guid=4959673327718046201">夜妖黑猫</a>(简书)<br>  </p>    <p> </p>