今天继续计算机速成课Crash Course的系列讲解。
更多技术文章,全网首发公众号 “极客之昂” 锁定 -上午11点 - ,感谢大家关注、转发、点赞!
16. 软件工程
之前花了很多时间讲排序,也写了些 10 行左右的排序代码,对1个程序员来说很容易写,而且代码很短,不必用专门工具 - 记事本就够了。
但排序算法很少会是独立程序,更可能是大项目的一小部分。举个例子,微软的 Office 大约有 4000 万代码,太多了,一个人不可能做到。
为了写大型程序,程序员用各种工具和方法,所有这些形成了"软件工程"学科 - 这个词由工程师 Margaret Hamilton 创造。
她帮助 NASA 在阿波罗计划中避免了严重问题,她曾说过:"有点像牙根管治疗:你总是拖到最后才做,但有些事可以预先做好,有点像预防性体检, 只不过是预防软件出错。"
第 12 集提过,把大项目分解成小函数,可以让多人同时工作,不用关心整个项目,关心自己的函数就好了。
如果你的任务是写排序算法,你只需要确保高效和正确就可以了,然而把代码打包成函数依然不够,如果只是这样,微软 Office 会有几十万个函数。
虽然比 4000 万行代码要好一些,但还是太多了。解决办法是:把函数打包成层级,把相关代码都放在一起,打包成对象(objects)。
例如,汽车软件中 可能有几个和定速巡航有关的函数。比如设定速度,逐渐加速减速,停止定速巡航。因为这些函数都相关,可以包装成一个"定速巡航对象"。
但不止如此,我们还可以做更多。"定速巡航"只是引擎软件的一部分,可能还有 "火花塞点火" "燃油泵" 和 "散热器",我们可以做一个"引擎对象" 来包括所有"子"对象。
除了子对象,"引擎对象"可能有自己的函数,比如开关引擎,它也会有自己的变量,比如汽车行驶了多少英里。
总的来说,对象可以包其它对象,函数和变量。
当然,"引擎对象"只是"汽车对象"的一部分,还有传动装置,车轮,门,窗等。
作为程序员,如果想设"定速巡航",要一层层向下,从最外面的对象往里找,最后找到想执行的函数:
Car. Engine. CruiseControl. setCruiseSpeed(55)
编程语言经常用类似这样的语法,把函数打包成对象的思想叫 "面向对象编程",这种思想和之前类似,通过封装组件,隐藏复杂度、之前把晶体管打包成了逻辑门,现在软件也这样做。
又提升了一层抽象!
把大型软件(如汽车软件)拆成一个个更小单元,适合团队合作,一个团队负责定速巡航系统,团队里的一位程序员负责其中一些函数。
类似建摩天大楼,有电工装电线,管道工配管,焊接工焊接,油漆工涂油漆,还有成百上千人做其他事情,在不同岗位同时工作,各尽其能,直到整栋楼完成。
回到定速巡航的例子,定速巡航要用到引擎的其它函数,来保持车速,定速巡航团队不负责这些代码,另一个团队负责,因为是其他团队的代码,定速巡航团队需要文档,帮助理解代码都做什么,以及定义好的 "程序编程接口" -简称 API。
API 帮助不同程序员合作,不用知道具体细节,只要知道怎么使用就行了。
例如"点火控制"对象中,可能有"设置发动机转数"函数,"检查火花塞电压"函数,"点燃单个火花塞"函数,"设置发动机转速"非常有用。
"定速巡航"团队要用到这个函数,但他们对点火系统不怎么了解,让他们调用"点燃单个火花塞"函数,不是好主意,引擎可能会炸!
API 控制哪些函数和数据让外部访问,哪些仅供内部,"面向对象"的编程语言,可以指定函数是 public 或 private,来设置权限。
如果函数标记成 private,意味着只有同一个对象内的其他函数能调用它,在这个例子里,只有内部函数比如 setRPM,才能调用 fireSparkplug 函数。
而 setRPM 函数是 public,所以其它对象可以调用它,比如 定速巡航。
"面向对象编程"的核心是隐藏复杂度,选择性的公布功能,因为做大型项目很有效,所以广受欢迎。
计算机上几乎所有软件,游戏机里几乎所有游戏,都是 "面向对象" 编程语言写的,比如 C++, C#, Objective-C 等,其他流行 OO 语言,你可能听过 Python 和 Java,有一点很重要:代码在编译前就只是文字而已。
前面提过,你可以用记事本或任何文字处理器,有人确实这样做。但一般来说,现代软件开发者会用专门的工具来写代码,工具里集成了很多有用功能,帮助写代码,整理,编译和测代码。
因为集成了所有东西,因此叫集成开发环境,简称 IDE(Integrated Development Environments)。
所有 IDE 都有写代码的界面,还带一些有用功能,比如代码高亮,来提高可读性,许多 IDE 提供实时检查,比如拼写,大型项目有很多源代码文件,IDE 帮助开发者整理和看代码,很多 IDE 还可以直接编译和运行代码。
如果程序崩了,因为你还没写完呢,IDE 可以定位到出错代码,还会提供信息帮你解决问题,这叫调试(debug)。
调试很重要,大多数程序员会花 70%~80% 时间调试,而不是在写代码。
好工具能极大帮助程序员防止和解决错误,很多开发者只用一款 IDE,但承认吧,VIM 才是最棒的编辑器,如果你知道怎么退出的话。
除了写代码和调试,程序员工作的另一个重要部分是给代码写文档,文档一般放在一个叫 README 的文件里,告诉其他程序员,看代码前先看这个文件,文档也可以直接写成"注释",放在源代码里,注释是标记过的一段文字。
编译代码时,注释会被忽略,注释存在的唯一作用,就是帮助开发者理解代码。好文档能帮助开发者,几个月后理解自己的代码,对其他人也很重要。
我想花一秒,再强调一下注释很重要。
最糟糕的就是拿到一堆代码,没有任何注释和文档,结果得逐行读代码,理解到底干嘛的。
文档还可以提高复用性,与其让程序员一遍遍写同样的东西,可以直接用别人写好的来解决问题,读文档看怎么用就行,不用读代码。
除了 IDE,还有一个重要软件帮助团队协作,源代码管理,也叫"版本控制"。苹果或微软这样的大型软件公司,会把代码放到一个中心服务器上,叫"代码仓库",程序员想改一段代码时,可以 check out,有点像从图书馆借书,一般这种操作,可以直接在 IDE 内完成,然后开发者在自己的电脑上编辑代码,加新功能,测试,如果代码没问题了,所有测试通过了,可以把代码放回去,这叫提交 (commit)。
当代码被 check out,而且可能被改过了,其他开发者不会动这段代码,防止代码冲突和重复劳动,这样多名程序员可以同时写代码,建立庞大的系统。
重要的是,你不希望提交的代码里有问题,因为其他人可能用到了这些代码,导致他们的代码崩溃,造成困惑而且浪费时间。代码的主版本 (master),应该总是编译正常,尽可能少 bug,但有时 bug 还是会出现。
幸运的是,源代码管理可以跟踪所有变化,如果发现 bug,全部或部分代码,可以"回滚"到之前的稳定版。"源代码管理" 也记录了谁改了什么代码,所以同事可以给你发讨厌的,我是说"有帮助的" 邮件给写代码的人。
写代码和测代码密不可分,测试一般由个人或小团队完成,测试可以统称 "质量保证测试",简称 QA(Quality Assurance testing),严格测试软件的方方面面,模拟各种可能情况,看软件会不会出错,基本上就是找 bug,解决大大小小的错误需要很多工作,但对确保软件质量至关重要,让软件在各种情况下按预期运行。
你可能听过 "beta 版" 软件,意思是软件接近完成,但不是 100% 完全测试过,公司有时会向公众发布 beta 版,以帮助发现问题,用户就像免费的 QA 团队。
你听过比较少的是beta 版之前的版本:alpha 版本。alpha 版一般很粗糙,错误很多,经常只在公司内部测试。
以上只是软件工程师用的工具和技巧的冰山一角,它们帮助软件工程师制作令人喜爱的软件,如 YouTube,GTA5 和 PPT 等等。
如你所料,这些代码要强大的处理能力才能高速速度运行。
所以下集讨论,计算机怎么发展到如今这么快。
以上内容就是 16. 软件工程 的内容,感兴趣的同学记得点赞、关注、转发、收藏哦!
我会不定期发布课程的讲解!
更多技术文章,全网首发公众号 “极客之昂” 锁定 -上午11点 - ,感谢大家关注、转发、点赞!