跳至主要内容

【转】编程,乐趣何在?

作者:  来源于:  发布时间:2008-10-13 12:16:00

1.   什么是软件开发?

软件最基本的目标是让计算机硬件(运算/存储/输入输出)按照人们预想的规则来工作。我们又管软件叫程序,软件工程师定制编写一个"顺序、序列",机器就按照这个序列来执行。软件开发,就是这个定制编写序列的过程。

2. 原本的乐趣:挑战和控制欲

解数学题,很多理科学生都很喜欢的一项活动。特别是在高中时期,证明出一道立体几何或者在模拟考试中第一个交卷儿都是非常令人羡慕的,虚荣心和满足感也会随之飘飘然。同时,多数中学的老师和一些大学老师,喜欢把软件开发归于数学的范畴。按这个推理,喜欢数学的都应该喜欢编程。但事实并非如此。

无论男性还是女性,我们都有控制的欲望。在控制不了""这种活物的情况下,能够控制一台机器让他按照我们的意愿来运行,会带来极大的快感。我30多岁了还喜欢玩遥控汽车,但一直羞于去玩具店购买,直到我儿子2岁以后。玩跑车,用手臂和脚尖控制一台400马力的怒吼的发动机当然更加过瘾,但显然太昂贵了。编程则可能是达到这一目标最廉价又最冠冕堂皇的一种方式。而且编程这种活动似乎在发挥创造力和满足自我陶醉心理上有更大的空间。同样,现在的情况也非如此,越来越多的程序员开始不喜欢他的职业了。

3.   为什么软件开发越来越无趣?

3.1. 首先,软件开发并不是数学

我们在学校的时候,那些老师们把软件开发归于数学的范畴,这没错,但过于狭隘。在30年前数学或许是软件的80%,但今天我们更倾向于把软件开发称为"工程"。工程与数学是不同的范畴,尽管在工程中我们会用到数学,但并不是全部,而且在软件工业的逐步发展的过程中,由于行业的分工进一步细化,数学的应用在软件工程中的比例越来越小。

       算法是数学在编程中最基基本的一种表现方式,但在80%的软件开发项目数百万行代码中,能真正让你去思考"算法"的部分寥寥无几。来自于"解题"的快感,自然无从寻觅。没有挑战,哪来成就感?

3.2. 第二,软件工程技术的发展,限制了施展的空间

       算机给程序员提供了一个广阔的思维空间,但计算机工业则根据自己的发展需求将这个空间切分成非常细小的片断。位于产业链上游和技术前沿的厂商、团体和个人通过中间件产品(如数据库、应用服务器)、开发工具、设计理念、框架、宣传等方式则各自独占了软件技术链上最"有趣"的一部分。多数现代程序员,则随流进入其它一个一个狭小的片断中。那些所谓技术含量较低的管理软件(广义的业务软件)领域,更是集中了大多数的从业者。

       平台、数据库、应用服务器、开发工具、现代软件设计理念、软件框架、技术宣传,这些产品和理念在推动软件工业成熟和发展的同时,一方面在宏观上提高了整个行业的生产率,降低了技术门槛,吸引了更多的从业者;另一方面则在微观上剥夺了多数程序员享受编程乐趣的环境。你应用EJB或者SSH(struts/spring/hibernate)开发项目的过程中,由衷地体会到编程的乐趣了吗?我反正没有。

3.3. 第三,VBPHPJava

       C语言是有趣的,因为它是"计算机科学"发展的产物。

       PythonRuby是有趣的,因为它是"天才"的产物。

       Delphi是有趣的,因为他是史上"最优美的结构化编程教学语言Pascal"的延伸。

与之不同的是多数的资深程序员认为VB/PHPJava是无趣的――

PHP是快速WEB生产需求催化的产物。VBJava则是软件工程发展的产物。

       "编程"遇上"快速生产""工程"的时候,乐趣就开始退化了。然而与乐趣无关的是,他们三个却成为了现代软件工业中最成功的三把斧头。一把能快速的砍出一个WEB论坛;一把能跨速的砍出Client界面;一把则通过理念、框架、规范、中间件等等等等,使得软件开发更加模式化和规范化,令软件行业向大规模工业化生产方式向前迈进了一大步。

       VBPHPJava本身都是成功的,而陷于三者的程序员则多半难以成功。我们现在常常赞赏地说:XX技术XX框架让程序员更关注于业务逻辑。我们在享受他们所带来的便捷的同时,也正在慢慢丧失程序员的天性――创造力。

4.   寻找新乐趣之旅

我们不能选择放弃,那么就让我们开始去寻找新的乐趣吧!

4.1.创新:用户UI体验的乐趣

20年前不同,当年的软件更接近"底层",而今天我们所开发的软件则更多地接近用户的感官和操作。把成就感从底层的挖掘移向UI层的体验,显得顺理成章。

同时,当今的UI技术和硬件渲染能力非20年前可比。以我们目前接触最多的WEB应用为例,最为普通的HTML/CSS/Ajax/JS/Flex等技术为我们提供了全所未有界面表现能力。我一直坚信优秀的用户体验是成功的一半。最近几年的Web创新很多都集中在表现方式上,如AjaxFlex

一些小型的用户体验提升方式已经普及到了"标配"的程度。比如,5年前如果你在一个Web表单中输入了错误的数据,必须在提交后的下一个页面中被提示出错;而今天不能在Input框的右边提供实时交验信息的界面则是令人恼火的经历。

UI上的创新远不止这些。在AjaxFlash令界面表现的丰富程度达到VB/Delphi望尘莫及的今天,我们追捧着gmail,研究着google map,效仿着flickr,甚至崇拜着finsGT Grid。一旦有人能够向UI体验发出挑战性的创新,就会给开发者赢来众多赞赏的目光和追随者的效仿,伴随而来的是开发人员极大的快乐。

4.2. 探险:扒开"框架"的乐趣

使用Hibernete谈不上乐趣,至少是乐趣有限。但如果你扒开Hibernate的代码,跟着作者的思路在数十万行代码迷宫中探险的时候,当你拨开一层层迷雾,为一段思路一行程序一种理念一个技巧而拍案叫绝的时候,你可能会得到前所未有的乐趣:

这种乐趣可能,

来自于"发现"的惊喜,

来自于"理解"的激动,

来自于"学习"的充实,

来自于"顿悟"的爽快!

来自于"英雄所见略同"的自豪感!

       在咱们软件圈儿,大师用书说话,大侠则用代码说话。"书上得来终觉浅,绝知此事要躬行"。转进大侠的代码里去吧,那里有无穷的乐趣等着我们。

4.3. 拓展:扩展眼界的乐趣

我一直鼓励身边共事的开发人员多学习一些编程语言,不一定在工作中用,但起码能够见识一下另一种思维方式。这不仅能扩宽眼界,我们更能从中体会到这个职业的乐趣。

出于管理上的效率和能力,5年来我们的团队一直以Java为主,但从编程艺术的角度,我不喜欢Java。尽管我早就开始认识到软件跟艺术风马牛不相及,但有时还会以这种欺骗自己的方式自我陶醉一把。

       我不喜欢Java的原因是,这种一无是处而又无处不在的编程语言养成了我的惰性,让我在工作中找不到去触碰和学习PythonRuby"官方"理由。

       有幸的是在过去的1年里我经历的三件事情重新点燃了我学习新的编成语言的激情:

       * 12个月前,我因项目需要花费了整整1个月的时间钻研Java

       * 5个月前,我因项目需要重新拾回了C语言(之前我已经4年没碰过make了)。

       * 一星期前的一天,我无聊到把JERuby论坛里的精华良好帖全部看了一遍。

       试试吧,多学一种,我们一起学。

4.4.协作:大制作的乐趣

大师令我们敬仰,大侠令我们敬畏。那些底层的、抽象地、框架性的、被称为无法重造得更好的轮子的作品,似乎只与他们有缘,给我100个脑袋,我也没有信心去挑战他们的领域。那么,好吧,没骨气就没骨气了,我们还有我们取得成就感的办法――协作。

钢琴王子的独奏固然经典,气势磅礴的交响乐同样能博得喝彩。跟交响乐一样,软件工程演奏的关键同样是配合。

大制作的软件产品是任何独行侠无法完成的,一个人的精力有限兴趣狭隘,不可能达到面面俱到,也懒于照顾上至UI体验下至数据库优化的每一个细节。这正是我等发挥的乐园。

然而我不得不承认,在从树上的猴子进化到键盘前的你我他的过程中,"协作"是我们退化得最迅速的优良品质。

如何在协作中取得成就感,获得乐趣,正是我们现在不断尝试和孜孜追求的东西,它需要我们共同的努力。

评论

此博客中的热门博文

【转】AMBA、AHB、APB总线简介

AMBA 简介 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP复用的SoC设计中,片上总线设计是最关键的问题。为此,业界出现了很多片上总线标准。其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。   AMBA 片上总线        AMBA 2.0 规范包括四个部分:AHB、ASB、APB和Test Methodology。AHB的相互连接采用了传统的带有主模块和从模块的共享总线,接口与互连功能分离,这对芯片上模块之间的互连具有重要意义。AMBA已不仅是一种总线,更是一种带有接口模块的互连体系。下面将简要介绍比较重要的AHB和APB总线。 基于 AMBA 的片上系统        一个典型的基于AMBA总线的系统框图如图3所示。        大多数挂在总线上的模块(包括处理器)只是单一属性的功能模块:主模块或者从模块。主模块是向从模块发出读写操作的模块,如CPU,DSP等;从模块是接受命令并做出反应的模块,如片上的RAM,AHB/APB 桥等。另外,还有一些模块同时具有两种属性,例如直接存储器存取(DMA)在被编程时是从模块,但在系统读传输数据时必须是主模块。如果总线上存在多个主模块,就需要仲裁器来决定如何控制各种主模块对总线的访问。虽然仲裁规范是AMBA总线规范中的一部分,但具体使用的算法由RTL设计工程师决定,其中两个最常用的算法是固定优先级算法和循环制算法。AHB总线上最多可以有16个主模块和任意多个从模块,如果主模块数目大于16,则需再加一层结构(具体参阅ARM公司推出的Multi-layer AHB规范)。APB 桥既是APB总线上唯一的主模块,也是AHB系统总线上的从模块。其主要功能是锁存来自AHB系统总线的地址、数据和控制信号,并提供二级译码以产生APB外围设备的选择信号,从而实现AHB协议到APB协议的转换。 ====================================

【转】GPIO编程模拟I2C入门

ARM编程:ARM普通GPIO口线模拟I2C  请教个问题: 因为需要很多EEPROM进行点对点控制,所以我现在要用ARM的GPIO模拟I2C,管脚方向我设 置的是向外的。我用网上的RW24C08的万能程序修改了一下,先进行两根线的模拟,SDA6, SCL6,但是读出来的数不对。我做了一个简单的实验,模拟SDA6,SCL6输出方波,在示波 器上看到正确方波,也就是说,我的输出控制是没问题的。 哪位大哥能指点一下,是否在接收时管脚方向要设为向内?(不过IOPIN不管什么方向都可 以读出当前状态值的阿) 附修改的RW24C08()程序: #define  SomeNOP() delay(300); /**/ /* *********************************  RW24C08   **************************************** */ /**/ /* ----------------------------------------------------------------------------- ---  调用方式:void I2CInit(void)   函数说明:私有函数,I2C专用 ------------------------------------------------------------------------------- -- */ void  I2CInit( void ) ... {  IO0CLR  =  SCL6;      // 初始状态关闭总线  SomeNOP();  // 延时   I2CStop();  // 确保初始化,此时数据线是高电平 }   /**/ /* ---------------------------------------------------------------------------- ----  调用方式:void I2CStart(void)   函数说明:私有函数,I2C专用 ------------------------------------------------------------------------------- -- */ void  I2CStart( void )

【转】cs8900网卡的移植至基于linux2.6内核的s3c2410平台

cs8900网卡的移植至基于linux2.6内核的s3c2410平台(转) 2008-03-11 20:58 硬件环境:SBC-2410X开发板(CPU:S3C2410X) 内核版本:2.6.11.1 运行环境:Debian2.6.8 交叉编译环境:gcc-3.3.4-glibc-2.3.3 第一部分 网卡CS8900A驱动程序的移植 一、从网上将Linux内核源代码下载到本机上,并将其解压: #tar jxf linux-2.6.11.1.tar.bz2 二、打开内核顶层目录中的Makefile文件,这个文件中需要修改的内容包括以下两个方面。 (1)指定目标平台。 移植前:         ARCH?= $(SUBARCH) 移植后: ARCH            :=arm (2)指定交叉编译器。 移植前: CROSS_COMPILE ?= 移植后: CROSS_COMPILE   :=/opt/crosstool/arm-s3c2410-linux-gnu/gcc-3.3.4-glibc-2.3.3/bin/arm-s3c2410-linux-gnu- 注:这里假设编译器就放在本机的那个目录下。 三、添加驱动程序源代码,这涉及到以下几个方面。(1)、从网上下载了cs8900.c和cs8900.h两个针对2.6.7的内核的驱动程序源代码,将其放在drivers/net/arm/目录下面。 #cp cs8900.c ./drivers/net/arm/ #cp cs8900.h ./drivers/net/arm/ 并在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下两条语句: __raw_writel(0x2211d110,S3C2410_BWSCON); __raw_writel(0x1f7c,S3C2410_BANKCON3); 注:其原因在"第二部分"解释。 (2)、修改drivers/net/arm/目录下的Kconfig文件,在最后添加如下内容: Config ARM_CS8900    tristate "CS8900 support" depends on NET_ETHERNET && A