me-sa

如何学习一门编程语言?

    下面是我很早以前的一段思考,关于编程语言学习的.编程语言要学习什么呢?首先看一下编程语言的学习包含哪些方方面:

 
 
编程语言学习的范畴:
以Erlang为例
  • 基础语法   基本运算 特殊的语法
  • 基础类库   字符串处理 数学函数 时间日期函数
  • 高级类库    Erlang OTP
  • 开发框架:产品/应用级内容 比如Asp.net ADO.net Ruby on rails
  • 开发工具:编译工具 调试工具 性能分析工具 项目管理工具 
  • 部署

上面罗列的内容,继续分析:
 
          哪些是可以忽略掉的?
  • 语言基础语法和类库不必浪费时间的,注意一下有点印象就可以,留下整体印象,需要的时候RTM就可以了;但是作为一个开发者重要有一种或者两种语言可以不看手册就可以写代码的;编程语言的熟练增强对语言的敏感度;
  • 语言的惯用法 命名规范也是不用太多时间的 这个会在实际的练习中得到强化;几乎每一种语言都会有自己的编程规范; 
  • 阅读资料过程中,如果已经掌握了一个功能代码的写法,那么对这个方法如何使用的文字可以忽略 但是对其机制的推演不可忽略


  •   什么是不可以忽略的?
  • 这个语言最本质的东西是什么?区别于其它语言的地方?
  • 这种本质上的差异化,它是怎样做到?
  • 它所遵循的设计原则是什么?
  • 它最成功的开发框架是什么?
 
分析一下不可以忽略的东西
 
     语言的本质区别是在范式上,范式代表着一种思维方式,分析问题解决问题的方式方法;
     范式(paradigm)的概念和理论是美国著名科学哲学家托马斯·库恩(Thomas,Kuhn) 提出并在《科学革命的结构》(The Structure of Scientific Revolutions)(1962)中系统阐述的,它指的是一个共同体成员所共享的信仰、价值、技术等等的集合。指常规科学所赖以运作的理论基础和实践规范是从事某一科学的研究者群体所共同遵从的世界观和行为方式。
    范式所代表的思维方式,思维方式的固有路径,成为原则;什么是原则:原则是行动的所依据的准则;只要你是OOP你就要遵守DRP DIP SRP等等原则,不遵守原则的后果就是脱离的最佳实践,工具用在用在错误的场景或者在正确的场景用错误的方式使用正确的工具,无论是质量还是开发速度都会受到影响,最终影响的是时间和精力的无意义消耗;这个问题的回答可以在一般性的介绍中就可以获得,比如介绍这门语言的第一章,或者网络的科普文章,以及官网;一句话:"是什么让你如此与众不同?"
    比如Erlang的设计原则就是:进程抽象和速错;
     
   现在回答:学习什么语言?
    像学习.net之后再学习java这就不太对了,两种语言的定位是何其的相似,甚至在语言层面java的设计都要差好多,所以根本没有任何意义去学习这样一门语言;甚至学习js都会比学习java收获的要多;学习的是语言的范式,范式是什么?是思维方式,是思考问题的方式,比如泛型编程,强调的是对算法的抽象;函数式编程是把行为做成抽象,可以传递的不仅仅是数值型的参数还可以是传参数;这大大的拓宽了我们的思路,所有的数据在内存中都会有地址,函数只是一种特殊的数据而已,所以能够传递函数没有什么奇怪的,但是在以前的应用中,我们几乎不会这样用,更不会这样去思考问题.从这个角度去看,.net实际上是居功甚伟的,在每一次framework的版本升级,都会有语言范式方面的尝试;
      如果在范式上没有区别就要用实践标准对语言进行一个比较,看有什么优势:在实践方面它体现为领域优势,性能优势,成本优势;
      领域优势有的是垄断型的比如安卓和IOS的开发,Mono Touch这种产品实际上就是通过语言的领域优势来体现产品优势;Erlang的领域优势就是在高并发;在领域中使用恰当的语言实际上是在增加成功的几率;
     性能优势,比如有的语言门槛很高,工具也不到位但是有那么多的人在用为什么?其实就是看中它的性能比如C C++;成本优势有两种:开发的时间和开发者需要的成本;有人会问题到为什么京东为什么使用.net架构,为什么用C#开发,答案其实很简单,为了开发速度和成本一开始选择了c#,然后路径依赖就一直没有调整架构;
      一本书描述这些重要的东西往往是在前面的几章,总结性特别的强,这个要反复的读.所以我们之前的看书方式是存在严重问题的,一看开始就感觉没有意思,或者障碍特别大就直接放弃了,而实际上恰恰是这部分内容难度最大.

     这种本质上的差异化它是怎么做到的?
     这个答案又会有不同层面的回答;比如Erlang,回答这个问题就可以说是"变量不变,没有副作用,没有共享内存就没有锁;进程之间通过消息传递;"当然这样已经给出了答案,但这种答案仍然太浅薄,太像"宣传手册"上的解释,甚至HR都可以说上两句的解释;我们还要继续追问下去:没有副作用,副作用是什么?上面说的理由在别的语言中实践可以么(如果在其它语言里面也可以同样实践,那还能算得上是本质区别么?)?变量不变对编程实践的影响是什么?变量不变的这样设计的根本目的是什么?消息传递本质上又是在做一件什么事情呢?
     对于本质化差异要往语言最底层去探索,往往更容易得到答案,比如Erlang的探索过程中,直到了解了Erlang的垃圾回收机制之后我才对语言层面会什么那样做,以及语言层面那样做底层是怎么支持的有了一个更深的理解;
 
 
     它最成功的开发框架/产品?
  语言层面的最佳实践以及编程范式的应用都可以在开发框架里面找到,在阅读这样一个产品的时候,需要关注的是:这个框架或者产品是如何解决这个问题的?设计上的特点?语言层面的应用?可以看到关注点不同收获也不同,没有意识去理解设计层面的东西只是关注语言上的小技巧收获也只有这点技巧;
 

       回顾一下我之前是怎么学习语言的?就拿学习Python,就是一个非常典型的例子
       我甚至无法回答第一个问题"为什么要学习Python?"是为了炫耀么?是为了要把它当作脚本工具来使用么?还是为了解动态语言编程范式?都没有想到目的地是哪里,只是盲目的走,走到哪里是一站呢?路上哪些东西是你要的呢?就是因为没有想好为什么要学,要获得什么,所以投入的精力就比较盲目,忽左忽右,偶尔强迫自己学习了也很只是熟练掌握某一个类库而已;没有回报,没有回报就更不愿意学,学了也没有用,所以自然的就忘掉了;这样反复了几次,每一次都无功而返;不是我没有毅力,而是我把宝贵的精力浪费在了没有意义的地方;最终也的确是没有什么收获;还不断的责备自己"2006年就叫嚣着要学习Python,可是现在已经2010年了 效果呢?这么久的时间干什么去了?"愚蠢就是使用同样的方法去做同样的事情,还期待不同的结果;我2010年上半年的目标还是将.net基础知识抓牢,这个无可厚非,将一种语言投入足够的精力去做到纯熟是非常重要的,对技术的敏感度,应用层面的实践能力;
 
 
怎么学,以及什么资料怎么用

 学习一个技术的我们都要问,学习的目的是什么?
 学习到什么程度?
 可以利用的手段有哪些?
 我遇到的问题有哪些?
 我解决问题的手段有哪些?
 
我现在要学习Erlang 
学习的目的是扎实掌握Erlang的设计和类库,为以后的项目做准备,和其它语言要求不一样;重要有那么一种或者两种语言是可以熟练到不需要看M的.
学到什么程度? 精深 掌握Erlang设计方法 熟练掌握类库 如无必要,不往下挖;Erlang的学习和其它技术的学习还是有点差别,就是这个语言本身希望熟练掌握,其中包括对类库的细节;不看文档写代码的能力;
可以利用的手段有哪些? Learn you some erlang ; 官方文档和开源项目 从开源项目中学习设计
我遇到的问题有哪些?我解决问题的手段有哪些? 
  现在遇到的问题就是缺少驱动或者说线索,能够沿着线索一直进行下去;其实这个问题以前也存在,做项目只是通过遇到一个又一个问题去增强自己的能力罢了;那样旷日持久,效果并不明显;常规开发哪里有那么多的难题?所以无论是不是在Erlang项目中,都必须要找到一个驱动线索,现在我学习Erlang的线索有:
1. 门槛最低,最容易切入的是Learn you some erlang 这个课程有足够的广度,并没有足够的深度,但是留下了足够多的线索
2. 门槛中等 Erlang 官方类库的熟悉,这个需要地毯式的过一遍,但是由于缺少应用场景可以预见到效果会非常差,所以要通过搜索引擎看看类库是怎么被使用的
3. 难度最高的是 开源项目 设计思路 编程技巧都会包括
 
标准是什么:拿过来一个事情可以快速搭建起来一个可以运行的代码框架,能够对设计进行抽象,能够快速编码;
 
 
我现在要学习Redis
 
学习Redis的目的是什么? 掌握Nosql的设计方法,Reids本身具有极强的代表性;
我要掌握到什么程度? 目的是理解它运行机制能为最佳实践提供理论基础
可以利用的手段有哪些?  Nosql的分析文章 Redis源代码阅读  博客分析文章
我遇到的问题有哪些? 遇到的问题就是阅读C语言代码的障碍非常大,这个问题在阅读Erlang底层代码的时候也显现出来了
 
C语言要学,但是要求非常低;就Redis这个问题本身来看,通过分析文章更容易达到目标;
 

我现在在做的事情是分析Redis的源代码,数据结构和处理逻辑,这件事情对我的意义有多大呢?
如果仅仅是知道数据结构所占用的字节数,是没有什么意义的,对实践的指导意义有限
对我有意义的是数据结构和算法,具体的处理细节并没有意义;
我今天可以通过Redis的数据结构分析,看看哪些是我需要掌握的本质知识,哪些是RTM
 
 
 
 
学习的深度和广度
 
   深度和广度的关系:没有足够的广度,深度也会受到眼界的限制;没有足够的深度,单纯广度上的拓宽并没有意义,不断攻城略地但是打下一个丢掉一个.首先公共部分的深度知识是需要扎实掌握的,比如数据结构和算法,网络通信的基础知识,比如源代码阅读的方法;无论在数据库还是在语言的类库里面都会涉及到这方面的知识;也就是本质的知识,本质的知识是需要长期积累,没有显示可以应用的.
 
对于一个开发者,哪些知识是本质上的?或者说是基本功?
  1. 数据结构和算法 数据结构上我需要知道 B-tree HASH 堆
  2. 网络基础 网络我需要知道gen_tcp 实践,细节 而且需要熟练
  3. 计算机系统的机制 基本上就是Linux windows是没有必要了
  4. 代码阅读分析能力
 
我现在需要学习C语言么?这是问题的最源头么?你现在遇到的根本困难是什么?有更好的方法么?
有没有一种方法可以把口香糖的胶溶解?
问题的源头是什么?口香糖粘在了衣服上
根本困难是如何把口香糖完整拿下来
有更好的方法么? 在冰箱冷冻一下就可以拿下来
 
 
怎么把握学习的深度和广度?
   其实是缺少一个停下来的标准,有标准了就可以某一个位置判断距离终点还有多远;在开始的最初完成对界结束标准的设定;
设定了标准之后,紧接着思考的问题是:达到这个目标可以有哪些方法?最优的方法是哪个?你在一个小路上是不是走的太远了????

比如C语言学习
客观价值标准:它能赚钱吗?你愿意用它赚钱吗?它能帮助你什么? 
它能赚钱,但是显然用它赚钱的门槛太高了我不愿意用它赚钱,那我为什么要学习它呢?我实际遇到的问题是什么?
能帮到我的就是能看懂C语言的代码,能够了解一些开源项目和Erlang的运行机制
它是有助于我职业能力提高的,但是这个要求不高,能看懂语法,知道在做什么就可以;所以一些非常基础的PPT和大陆边上的教程反而非常受用
 
 
 我之前的认知仅仅认识到了哪些知识是有价值的,是符合我的长远目标的,但是没有对如何掌握这些知识做一个最优化的思考和选择;
 
 

 

发表于 2012-05-03 15:12  坚强2002  阅读(267)  评论(0编辑  收藏  举报
 

分类:

技术点:

相关文章: