1. 我写了二叉树的周游算法实现,在这里,二叉树是数据结构,周游的实现细节是算法。我写的C 程序就是结果。但是我这个程序有什么用呢?在Java 和其他一些语言中,似乎没有指针,那我可以不必了解二叉树么?
2. 我找到了工作,成了一名程序员, 但是我发现所有的算法别人已经实现了,我只要调用就可以了。似乎我公司的软件和数据结构,算法的关系都不大。那我当初辛辛苦苦学习的数据结构和算法有用么? 如何区分一个好的程序员和不好的程序员呢?
3. 我来到软件公司上班后,发现公司以前同事写的程序真是垃圾,根本无法维护。我要推翻重写!后来一个老员工笑嘻嘻地告诉我,我们现在看到的程序,就是去年的新员工愤怒地推翻重写之后的结果,大家反映还没有以前的版本好用呢。
那么我们软件行业赖以生存的“软件”, 我们程序员用来安生立命的“程序” 是什么?
举一个生活中的例子, 移山公司程序员二柱的小孩上了小学二年级, 老师让家长每天出30道四则运算题目给小学生做。二柱立马就想到写一个小程序来做这件事。 这个事情可以用很多语言或者工具来实现:
Excel, C/C++, C#, VB, Unix Shell, Emacs, Powershell/Vbscript, Javascript, Perl, Python, …
请大家估计写好这个程序需要的时间.
我想程序员用自己最擅长的工具, 一袋烟的功夫就搞定了。
二柱一下打印出好多份不同的题目, 让孩子做了。老师看了作业之后, 对二柱赞许有加。 别的老师闻讯, 问二柱能否扩大他的影响力, 编个软件, 给二年级到四年级都用, 多了一些小小的要求:
· 题目避免重复
· 可定制(数量/打印方式)
· 可以控制下列参数:
o 是否有乘除法
o 是否有括号
o 数值范围
o 加减有无负数
o 除法有无余数
o 是否支持分数 (真分数, 假分数, …)
o 是否支持小数 (精确到多少位)
o 打印中每行的间隔可调整
小同学兴高采烈地拿着需求回来了, 跟老爸说 – “老师明天就想要!” 现在大家估计做好这个软件需要多长时间。
我们假设二柱熬夜做出了这个软件的一个初始版本, 交给老师了。 过几天老师又问: 能否把这个程序放到学校的网站去, 再多一点点要求, 支持二元一次方程, 能开根号, 并且让所有人可以通过网页订制各种类型的四则运算作业. 二柱同志可能会想– 这是多复杂的一个工程哪! 他花了两个周末, 做出了一个版本.
学校老师又有要求, 既然已经做得这么好了, 再多一点点要求, 让同学直接在上面做题好了。
不久学校说:干脆我们推广到全国, 老师给学生布置作业, 学生做作业, 老师批阅, 家长通过手机获得学生的进展... 都在网上搞定!
现在请大家估计做好这个软件服务需要多长时间。
说完这两个例子, 我们来看看一些概念:
程序,在这里指的是源程序,就是一行一行的代码。仔细看过去,它们的确是建立在数据结构上的一些算法。但是光有代码还是不行的,这些一行一行的代码不会自己运行,得有人编译成机器能懂的目标代码,而编译不仅仅是 cc 和 link 命令,对于一个复杂的软件,我们不但要有合理的软件架构(Software Architecture), 软件设计和实现 (Software Design & Implementation), 我们还要用各种文件来描述各个程序文件之间的依赖关系,编译参数,链接参数,等等。这些都是软件的构建。
软件团队的各个人员每天都在不断地修改各种源代码,怎么保证软件在不断的修改中能保证质量,不至于崩溃? 有些时候,我们要为某个需求写一些特殊功能,然后不久要把这些功能再合并回主要版本。有些程序还有32 位版本, 64位版本, 等等。 这是源代码管理 (Source Code Control) 的问题 – 有时候也叫配置管理 (Software Configuration Management)。我们还有一系列的工具和程序来保证程序的正确性,这些工具和程序本身应该更正确,才能保证别的软件的质量,对么? 这质量保证的工作叫Quality Assurance,也叫软件测试 (Testing).
一个软件要有人买,就得先找到顾客,顾客有各种需求,有些靠谱,有些不靠谱,我们要把这些靠谱的需求都实现了,一群人要从需求分析 (Requirement Analysis) 开始,忙碌各种事情, 例如设计(软件架构),实现(写数据结构和算法),测试,到最后发布软件, 软件在运行过程中还会出这样那样的问题, 也许我们要时不时给软件打一个补丁, 这叫软件的维护(Software Maintenance)。这一系列过程就是软件的生命周期 (Software Life Cycle, SLC), 有人得负责软件项目的管理 (Software Project Management)。
一个好的软件,即使功能和同类软件区别不大,但是会让人感觉到非常好用。这就是软件的“用户体验” (User Experience) 特别好。用户体验和数据结构,算法没什么关系,但是很多非常成功的软件就赢在这个方面。
有了软件,我们就要卖出去赚钱,有很多种赚钱的方式,
· 有立马交钱买断,
· 有“先试用再交钱”,
· 有送硬件, 赚软件的钱;
· 有送软件, 赚硬件的钱;
· 也有“免费用,看广告”;
· 也有“免费用,程序也不是我写的,如果有问题,付我钱,我就来咨询…”
当然还有在用户不知道的情况下就安装了软件,然后用户怎么也摆脱不掉。最近还出现了 A公司要挟用户必须卸载 B公司的软件, 然后才能运行... 等等。这些都是软件赚钱的商业模式。有些做法是合情合理也合法, 有些看似合情合理, 但是不怎么合法. 有些做法不合理, 但是还没有相关法律。 在相关法律完善之前, 软件行业还有一个行规, 软件工程师应该有一个职业道德来约束 IT 人的行为。有学生提到, 在大学公开选课的时候, 是否可以写一个 “刷课机” 的程序, 利用学校选课系统的弱点或漏洞, 帮助某些用户选到自己想要的课程。这个程序/软件合法么? 符合道德规范么? 值得探讨。
上面的这些和软件开发活动(构建管理,源代码管理,软件设计, 软件测试,项目管理)是软件工程的核心部分。广泛意义上的软件工程也包用户体验 (User Experience), 用户界面设计 (User Interface Design) 等。所以,我觉得:
软件 = 程序 + 软件工程
一个扩展的推论是:
软件企业 = 软件 + 商业模式
当然, 软件企业还要加上人员的招聘, 绩效评估, 升迁, 淘汰等人力资源方面的工作.
弄清楚这些问题,是进行所有和程序,软件,企业等相关讨论的基础。
不消说,商业模式也会影响软件的需求,例如有人要开发社会网络软件,同时提供丰富的API 让别人能在上面开发,这个对API的支持会成为这个软件一个重要的特征。
回到本文开头的疑惑,答案就很清楚了 - 程序是基本功,但是除了程序之外,软件工程决定了软件的命运。
出此之外, 软件的商业模式决定一个软件企业的成败。软件从业人员和软件企业的道德操守会极大地影响软件用户和社会。这两点不会在这门课里深入探讨。
软件产业还是一个相对年轻的产业,软件工程的概念是1969年第一次提出来的。下面用历史更长的航空产业做一个比较。
玩具阶段:
100个小孩里有99 个叠过纸飞机,像下面这样:
"设计/制造纸飞机" 的过程, 看起来技术含量不高, 但是也有很多窍门。 有些小孩在飞行前, 会用嘴对着纸飞机哈一口气, 这里面也许有深奥的道理, 也许只是迷信。 在跟着这些飞机奔跑,欢呼的时候,这些小孩心里一定有“我长大了要在天上飞”的想法。纸飞机,航模飞机和真飞机一样,都体现了某些基本的理论。我不懂这些理论,我就不多谈“空气动力学”之类的了.
业余爱好阶段: