鸠集遗失,鉴玩整理,昼夜精勤,每获一卷,遇一画,毕孜孜葺缀,竟日宝玩,可致者必货敝衣, 减粮食。妻子童仆切切嗤笑,或曰:终日为无益之事何补哉。既而叹曰:若复不为无益之事,则安能悦有涯之生。 
--- 唐 张彦远 《历代名画记》 1 编程的要素
编程有3个要素:语言、环境和思想。 1.1 语言
有人喜欢争论语言的优劣。其实,除了汇编语言,各种语言、脚本、标准库、类库、框架都蕴含着大量成熟的编程经验和思想。程序员应该多熟悉一些语言,特别是有代表性的语言。 个人觉得,一个程序员应该掌握一两种汇编语言(CISC的X86、RISC的ARM)、一种面向过程语言(C)、两、三种面向对象语言(C++、Java、Delphi)、一两种脚本语言(perl、python、ruby)。如果有时间,可以再学习一些学术性较强的语言,例如Scheme。 学习新的语言,不仅可以吸收语言中蕴含的设计理念,还可以打开连接新空间的大门,使我们可以学习、复用使用该语言的各种资源,例如源代码、文章、书籍。 1.2 环境
1.2.1 开发时和运行时
环境可以被理解为程序所有外界环境的总和,包括开发时环境、运行时环境。我们在写一段程序时,应该对该程序的相关环境有清楚的了解。 开发时环境包括我们使用的编译(链接)环境、复用的代码(框架、类库、控件等),系统的逻辑结构、代码的文件组织、需要的工具软件、调试环境等等。 运行时环境包括程序运行时环境中所包含、发生的一切,特别是与我们的程序相关的部分。从小处看,我们应该知道如何确定每段代码运行的context(线程和堆栈),每个变量所使用的空间的信息。从大处看,我们应该了解系统运行的来龙去脉,各个模块(逻辑概念)如何相互配合,各个线程(调度单位)如何相互通信,什么时候可能发生调度,系统中有哪些不确定的因素等等。 1.2.2 软件类型
比较“典型”的软件类型包括: 
Windows操作系统; Linux操作系统; 编译器; 虚拟机; 调试器; Windows的单机应用程序; Windows的驱动程序; Linux的应用程序和驱动程序; 基于socket的客户端-服务器程序; 数据库应用程序; 使用数据库的Web应用程序; 使用RTOS的嵌入式软件; 不使用RTOS的单片机程序; DSP程序; 嵌入式环境的第三方程序(J2ME应用、BREW应用、symbian的应用程序等等); 各种中大型程序的脚本环境,插件的开发、运行环境; Office应用程序开发; flash编程; 
软件的种类实在太多,所谓“典型”只是我个人的理解,肯定还有很多软件类型没有被列出来。程序员应该了解开发和运行这些软件时,究竟发生了什么。 对于Windows、Linux操作系统,我们应该有个概要的了解:从BIOS程序读Master Boot Record,到系统的装载运行;应用程序或动态连接库(Linux的SO)的装载;操作系统的基本模块(包括内核)的功能;Windows如何通过COM机制将各个功能模块组合起来等等。这些内容是PC程序的基本运行环境。 嵌入式环境相对PC环境要简单一些,特别是用NOR flash,代码直接从ROM运行的系统。一方面,程序员通常可以看到系统运行的所有代码;另一方面,嵌入式环境有时不提供第三方程序运行机制,有时提供比较简单的机制,有时用java虚拟机当作第三方程序运行机制。不过,智能手机的应用处理器一般使用NAND flash,从BIOS运行一小段启动代码,将系统装载到RAM运行,同时支持应用程序装载运行,已经很接近PC环境。 编写单机应用程序,除了语言外,主要要熟悉各种库、框架、组件。一些通用库提供了常用函数、各种容器和算法、GUI、典型的程序框架,系统API的封装等等,例如: 移植性比较好的C标准库、STL、boost、TK等; Windows上的MFC、VCL(Delphi/C++ Builder); Linux上的ncurses、X Windows、GTK、Qt等; 访问数据库:VC++的ODBC、DAO、ADO,Borland的BDE等; Borland做了一些在源代码级跨平台的库:Delphi/Kylix的CLX、dbExpress; CPAN上的大量perl模块、java的类库等等; 
上面列出的是一些比较通用的库。还有用于各种语言的大量专用库,各种提供二进制接口的组件、控件。 编译器、虚拟机也是单机应用程序(在嵌入式环境,虚拟机可能是系统软件的一个模块)。不过它们的地位比较特殊。作为程序员,我们应该了解编译器、集成开发环境、软件框架、虚拟机、操作系统分别为我们做了什么。 作为程序员,我们同样应该理解调试器也是一个应用程序,调试器的基本原理,它能做什么,有什么限制。如果调试器与目标程序运行在不同的CPU上,调试是如何实现的,有哪些不同的实现方式?例如JTAG调试利用了目标CPU的调试接口直接调试目标程序;串口调试要求将一段调试代码和目标程序链接在一起下到目标CPU中,由嵌入的调试代码与PC机的调试器通信实现调试。不同的实现手段决定了调试器的能力和限制。 目前最热门的软件类型就是使用数据库的Web应用了,例如各种网站、网络游戏、各种企业、行业、政府机构的管理系统,在这个领域集中了处于食物链不同环节的大量厂商,各种Web服务器、基础平台、应用开发框架。随便列一下,也能列出一堆名词: HTML/CSS和CGI; java applet、java script、ActiveX控件; php、asp、jsp、servlet; .net家族:asp.net、ado.net等; J2EE with/without EJB、Spring、Struts、Hibernate; Ruby on Rails、Plone等; 在一种软件类型上,集中了这么多开发技术、框架、模式,也可以称得上蔚为壮观了。不过,这个领域里确实是各种最新的编程思想、方法、设计模式的演武厅,如同当年的编译器,值得所有程序员研究、学习。 1.3 思想
COM可以被看作OLE发展的衍生品。但它的重要性远远超过了OLE。它首被独立出来,成为OLE、ActiveX的基础,然后逐步成为在Windows进行二进制集成的基础。COM和RPC的结合产生了DCOM。DCOM和MTS的结合产生了COM+。虽然这些技术都是用于Windows平台的,但组件技术的基本思想是独立于具体环境的。也就是说,对程序员而言,存在着独立于语言和环境之外的领域,这就是编程的思想。 例如看看Qualcomm的BREW,就会发现它从COM中学习了多少东西。嵌入式平台的程序员使用PC平台的技术,这就是编程思想的价值。对于程序员来说,各种编程思想、设计模式,是最为宝贵的东西。这里所说的设计模式并不局限于GOF的《设计模式》,任何惯用的手法都可以被看作模式。