软件工程/实现简介
计算机编程(通常缩写为编程或编码)是设计、编写、测试、调试/故障排除以及维护计算机程序源代码的过程。该源代码是用编程语言编写的。编程的目的是创建表现出某些期望行为的程序。编写源代码的过程通常需要许多不同领域的专业知识,包括应用程序领域知识、专门算法和形式逻辑。
Hoc 和 Nguyen-Xuan 将计算机编程定义为“将用熟悉术语表达的思维计划转换为与计算机兼容的计划的过程”。[1] 换句话说,编程就是将需求转化为计算机可以执行的程序的技巧。
在软件工程中,编程(实现)被视为软件开发过程中的一个阶段。
关于程序编写在多大程度上是一门艺术、一门手艺还是一门工程学科,一直存在着争论。[2] 一般来说,良好的编程被认为是这三者的衡量应用,其目标是产生高效且可演进的软件解决方案(“高效”和“可演进”的标准差异很大)。该学科与许多其他技术职业不同,因为程序员通常不需要获得许可证或通过任何标准化(或政府监管)的认证考试才能称自己为“程序员”甚至“软件工程师”。但是,在世界许多地方,自称为“专业软件工程师”而没有来自认证机构的许可证是非法的。然而,由于该学科涵盖了许多领域,这些领域可能包含也可能不包含关键应用程序,因此关于该学科整体是否需要许可证存在争议。在大多数情况下,该学科由需要编程的实体自行管理,有时会定义非常严格的环境(例如美国空军使用 AdaCore 和安全许可)。
另一个持续的争论是,编写计算机程序所使用的编程语言在多大程度上影响着最终程序的形式。这场争论类似于围绕语言学中的萨皮尔-沃尔夫假设[3]的争论,该假设认为,一种特定的口头语言的性质会影响其使用者的习惯性思维。不同的语言模式会产生不同的思维模式。这个想法挑战了用语言完美地表达世界的可能性,因为它承认任何语言的机制都会影响其使用者社区的思维。
来自古希腊的安提基特拉机械是一个利用各种尺寸和配置的齿轮进行计算的计算器,[4]它跟踪了月球-太阳历中仍然使用的默冬周期,并且与计算奥林匹克运动会日期相一致。[5] 阿尔-贾扎里在 1206 年建造了可编程的自动机。这些设备中使用的一种系统是在木制鼓上的特定位置放置钉子和凸轮。这些钉子和凸轮会依次触发杠杆,进而操作打击乐器。该设备的输出是一个演奏各种节奏和鼓模式的小鼓手。[6][7] 约瑟夫·玛丽·雅卡尔在 1801 年研发的雅卡尔提花机使用了一系列带有穿孔的纸板。孔的图案代表提花机在编织布料时必须遵循的图案。提花机可以使用不同的卡片组来生产完全不同的编织物。查尔斯·巴贝奇在 1830 年左右采用了穿孔卡来控制他的分析机。数字计算、预先确定的操作和输出的综合,以及以一种相对容易让人类理解和生成的方式组织和输入指令的方法,导致了现代计算机编程的发展。计算机编程的发展在工业革命期间加速。
在 19 世纪 80 年代后期,赫尔曼·何乐礼发明了将数据记录在机器可以读取的介质上的方法。以前对机器可读介质的使用,如上所述,是为了控制而不是数据。“经过对纸带的一些初步尝试,他最终选择了穿孔卡……”[8]为了处理这些穿孔卡,最初被称为“何乐礼卡”,他发明了制表机和打孔机。这三项发明是现代信息处理行业的基石。1896 年,他创立了制表机公司(后来成为 IBM 的核心)。在他的 1906 年 I 型制表机上添加一个控制面板(插板)使其能够执行不同的工作,而无需进行物理改造。到 1940 年代后期,已经出现了各种各样的插板可编程机器,称为单元记录设备,用于执行数据处理任务(读卡)。早期的计算机程序员使用插板来执行为新发明的机器请求的各种复杂的计算。
冯·诺依曼体系结构的发明允许计算机程序存储在计算机内存中。早期的程序必须使用特定机器的指令(基本操作)精心制作,通常使用二进制表示法。每种型号的计算机都可能使用不同的指令(机器语言)来完成相同的任务。后来,汇编语言应运而生,它允许程序员以文本格式指定每个指令,输入每个操作码的缩写而不是数字,并以符号形式指定地址(例如,ADD X, TOTAL)。使用汇编语言输入程序通常比使用机器语言更方便、更快且更不容易出现人为错误,但由于汇编语言只是机器语言的不同表示法,因此任何两个具有不同指令集的机器也具有不同的汇编语言。
1954 年,FORTRAN 诞生了;它是第一个具有功能实现的高级编程语言,而不是仅仅停留在纸面上的设计。[9][10](广义上讲,高级语言是任何允许程序员用比汇编语言指令更抽象的术语编写程序的编程语言,即比汇编语言的抽象级别“更高”。)它允许程序员通过直接输入公式来指定计算(例如 Y = X*2 + 5*X + 9)。程序文本或称为源代码,通过一个称为编译器的专用程序转换为机器指令,该编译器将 FORTRAN 程序翻译成机器语言。事实上,FORTRAN 这个名字代表“公式翻译”。许多其他语言也应运而生,包括一些用于商业编程的语言,例如 COBOL。程序主要仍然通过打孔卡或纸带输入。(参见打孔卡时代的计算机编程)。到 1960 年代后期,数据存储设备和计算机终端变得足够便宜,以至于程序可以通过直接在计算机上输入来创建。文本编辑器的开发使得对程序进行修改和更正比使用打孔卡更加容易。(通常,在打孔卡中出错意味着必须丢弃这张卡,并打一张新的卡来替换它。)
随着时间的推移,计算机在处理能力方面取得了巨大的进步。这催生了更抽象的编程语言,它们与底层硬件更加独立。虽然这些高级语言通常会产生更高的开销,但现代计算机速度的提高使得这些语言的使用比过去更加实用。这些日益抽象的语言通常更容易学习,并且允许程序员更有效率地、用更少的源代码开发应用程序。然而,对于一些程序而言,高级语言仍然不切实际,例如那些需要低级硬件控制或需要最大处理速度的程序。
在整个二十世纪下半叶,编程在大多数发达国家都是一个有吸引力的职业。一些形式的编程越来越多地受到离岸外包的影响(从其他国家进口软件和服务,通常以更低的工资),这使得在发达国家进行编程职业决策变得更加复杂,同时又增加了欠发达地区经济机会。目前尚不清楚这种趋势将持续多久,以及它将对程序员的工资和机会产生多大的影响。[需要引用]
无论采用何种软件开发方法,最终程序都必须满足一些基本属性。以下属性是最相关的属性之一。
- 效率/性能:程序消耗的系统资源量(处理器时间、内存空间、慢速设备,如磁盘、网络带宽,在一定程度上甚至包括用户交互):消耗越少越好。这也包括正确处理一些资源,例如清理临时文件和防止内存泄漏。
- 可靠性:程序结果正确的频率。这取决于算法的概念正确性,以及将编程错误降到最低,例如资源管理错误(例如,缓冲区溢出和竞争条件)和逻辑错误(例如,除以零或越界错误)。
- 健壮性:程序在非程序员错误的情况下预料问题的程度。这包括一些情况,例如数据错误、不适当或损坏,所需资源不可用,例如内存、操作系统服务和网络连接,以及用户错误。
- 可用性:程序的人机工程学:一个人使用程序执行其预期目的的难易程度,或者在某些情况下甚至包括未预期的目的。这些问题甚至可以决定程序的成功与否,而与其他问题无关。这涉及广泛的文本、图形,有时还包括硬件元素,这些元素可以提高程序用户界面的清晰度、直观性、一致性和完整性。
- 可移植性:程序源代码可以在其上编译/解释和运行的计算机硬件和操作系统平台范围。这取决于不同平台提供的编程功能的差异,包括硬件和操作系统资源、硬件和操作系统的预期行为,以及平台特定编译器(有时还有库)对源代码语言的可用性。
- 可维护性:程序由其当前或未来的开发人员修改以进行改进或定制、修复错误和安全漏洞或使其适应新环境的难易程度。在初始开发期间的良好实践在这方面起着至关重要的作用。这种质量可能不会对最终用户直接显现,但它会从长远角度对程序的命运产生重大影响。
计算机编程的学术领域和工程实践都很大程度上关注于发现和实现针对特定问题类别最有效的算法。为此,算法使用所谓的 Big O 符号(O(n))进行分类,该符号用输入的大小来表示资源使用情况,例如执行时间或内存消耗。经验丰富的程序员熟悉各种成熟的算法及其各自的复杂度,并利用这些知识来选择最适合特定情况的算法。
大多数正式软件开发项目的第一步是需求分析,然后是测试以确定价值建模、实现和错误消除(调试)。每个任务都存在许多不同的方法。用例分析是一种流行的需求分析方法。如今,许多程序员使用敏捷软件开发的形式,其中正式软件开发的各个阶段更加紧密地集成在一起,形成持续几周而不是几年的短周期。软件开发过程有很多方法。
流行的建模技术包括面向对象分析与设计(OOAD)和模型驱动架构(MDA)。统一建模语言(UML)是一种用于 OOAD 和 MDA 的表示法。
数据库设计中使用的一种类似技术是实体关系建模(ER 建模)。
实现技术包括命令式语言(面向对象或过程式)、函数式语言和逻辑语言。
很难确定哪些是现代最流行的编程语言。一些语言对于特定类型的应用程序非常流行(例如,COBOL 在企业数据中心中仍然很强大,通常是在大型大型机上,FORTRAN 在工程应用中,脚本语言在 Web 开发中,C 在嵌入式应用程序中),而另一些语言则被定期用于编写许多不同类型的应用程序。
衡量编程语言流行度的几种方法包括:统计提及该语言的招聘广告数量、[11] 教授该语言的书籍的销售数量(这高估了新语言的重要性),以及对用该语言编写的现有代码行数量的估计(这低估了 COBOL 等商业语言的用户数量)。
调试是软件开发过程中一项非常重要的任务,因为错误的程序会对用户产生重大影响。一些语言更容易出现某些类型的故障,因为它们的规范不要求编译器执行与其他语言一样多的检查。使用静态分析工具可以帮助检测一些潜在的问题。
调试通常使用 Eclipse、Kdevelop、NetBeans 和 Visual Studio 等 IDE 进行。gdb 等独立调试器也被使用,它们通常提供较少的可视化环境,通常使用命令行。
不同的编程语言支持不同的编程风格(称为编程范式)。语言选择的考虑因素很多,例如公司政策、任务的适用性、第三方软件包的可用性或个人偏好。理想情况下,将选择最适合当前任务的编程语言。与这种理想情况的权衡包括找到足够多的了解该语言的程序员来组建团队、该语言的编译器的可用性以及用该语言编写的程序执行的效率。语言形成了从“低级”到“高级”的近似谱系;“低级”语言通常更面向机器,执行速度更快,而“高级”语言更抽象,更易于使用,但执行速度较慢。
艾伦·唐尼在他的著作《像计算机科学家一样思考》中写道
- 尽管在不同的语言中,细节看起来有所不同,但一些基本指令几乎出现在所有语言中。
- 输入: 从键盘、文件或其他设备获取数据。
- 输出: 在屏幕上显示数据或将数据发送到文件或其他设备。
- 算术运算: 执行基本的算术运算,如加法和乘法。
- 条件执行: 检查某些条件,并执行相应的语句序列。
- 重复: 重复执行某些操作,通常伴随着一些变化。
许多计算机语言提供了一种机制来调用库提供的函数。只要库中的函数遵循相应的运行时约定(例如,参数传递方式),那么这些函数就可以用任何其他语言编写。
计算机程序员是编写计算机软件的人。他们的工作通常包括
- 编码
- 编译
- 调试
- 文档化
- 集成
- 维护
- 需求分析
- 软件架构
- 软件测试
- 规格说明
- ↑ Hoc, J.-M. 和 Nguyen-Xuan, A. 语言语义、心理模型和类比。J.-M. Hoc 等人,编。编程心理学。学术出版社。伦敦,1990 年,139–156,引用自 Brad A. Myers, John F. Pane, Andy Ko, 自然编程语言和环境,ACM 通讯,第 47 卷第 9 期,2004 年 9 月
- ↑ Paul Graham (2003)。"黑客与画家". 检索时间 2006-08-22.
{{cite journal}}
: Cite journal 需要|journal=
(帮助) - ↑ APL 编程语言的创始人 Kenneth E. Iverson 认为,萨丕尔-沃尔夫假说适用于计算机语言(但没有实际提到假说名称)。他获得图灵奖的演讲“符号作为思考工具”就是围绕这个主题展开的,他认为更强大的符号有助于思考计算机算法。Iverson K.E.,"符号作为思考工具",ACM 通讯,23: 444-465 (1980 年 8 月)。
- ↑ "古代希腊计算机的内部运作被破译"。国家地理新闻。2006 年 11 月 29 日。
- ↑ Freeth, Tony (2008 年 7 月 31 日)。"安提基特拉机械中的日历,显示奥运会日期并预测日食". 自然. 454 (7204): 614–617. doi:10.1038/nature07130. PMID 18668103.
{{cite journal}}
: 未知参数|coauthors=
被忽略 (|author=
建议) (帮助) - ↑ 13 世纪的可编程机器人,谢菲尔德大学
- ↑ Fowler, Charles B. (1967 年 10 月)。"音乐博物馆:机械乐器的历史". 音乐教育者杂志. 音乐教育者杂志,第 54 卷第 2 期. 54 (2): 45–49. doi:10.2307/3391092.
- ↑ "哥伦比亚大学计算历史 - 赫尔曼·何乐礼". Columbia.edu. 检索时间 2010-04-25.
- ↑ 12:10 p.m. ET (2007 年 3 月 20 日)。"Fortran 创建者约翰·巴克斯去世 - 科技与小工具 - msnbc.com". MSNBC. 检索时间 2010-04-25.
- ↑ "CSC-302 99S : 课堂 02: 编程语言简史". Math.grin.edu. 检索时间 2010-04-25.
- ↑ 提及特定语言的招聘广告调查>
- Weinberg, Gerald M.,计算机编程心理学,纽约:范·诺斯特兰德·莱因霍尔德,1971 年
- 如何像计算机科学家一样思考 - 由 Jeffrey Elkner、Allen B. Downey 和 Chris Meyers 撰写