回 帖 发 新 帖 刷新版面

主题:[原创]软件工程师应该积累何种经验

软件工程师们早就在如何定义我们所设计和建造的产品——软件上达成了共识。从软件工程师的角度看,软件(或产品)是被称为计算机软件的程序、文档和数据;从用户的角度看,软件(或产品)是能够以某种方式是用户世界变得更好的某种东西。其中软件能够使用户的世界变得更好是软件存在的核心价值,也是软件工程师门的追求。我们一本接一本的阅读砖头书,不断的学习,在工作中定期总结、归纳经验都是为了这个目的。

我们到底应该积累何种经验才能让我们更好的达到这个目的呢?行业应用?如何完成高效的实现?软件开发技术或成果的使用?这三个方面的内容涵盖了几忽所有需要我们积累的经验。都应该有所积累,但只有有所侧重才能成为一个优秀的软件工程师。

软件都需要应用到某一个行业或者说应用到现实生活的某项活动中去才能体现它的价值。比如,我们日常用来编辑文档的office系列软件以及用来处理图像的ps等属于软件在平面设计行业里的应用;杀毒软件、网页安全控件等属于软件信息安全行业的应用;CAD、CorelDRAW等属于软件在工业和建筑设计行业中的应用;ArcGIS、SuperMap等属于软件在地图制图行业里的应用……随着软件在这些行业中应用的成熟又催生出新的软件行业的分支。字处理软件、图像处理软件、矢量图处理软件的成熟促成了计算机辅助设计的出现,数字制图软件的成熟促成了地理信息系统的出现……作为一个软件工程师要向高层次发展必须跳出编写代码的层次而站在行业应用的高度去设计和实现能够有助于提高行业应用效率的软件。所以软件工程师们必须积累行业应用的经验。

上边所列举的都是抽象层次较高的应用,而实际生活中的具体应用上又会有千差万别,行业应用的方案也会随着时间发生变化。这些差别和变化不会是天翻地覆的,但是仍然需要软件工程师们良好的学习能力来适应这些差别和变化。

但不能因此就对“软件工程师们必须积累行业应用的经验”提出异议,学习全新的东西是一件很痛苦的事情,除非你是一个天才,它远远没有掌握微小差别和跟进微小的变化来得容易。所以拥有独立产品的软件企业都侧重于某一个行业,做软件外包的企业也都侧重于某一行业;一些涵盖多个行业的大型软件企业都会让某些职员们只关注某一个行业。有些时候我们不得不面对“退化”情况,当我们经营着一家小软件企业或者在一家小的软件公司就职,我们需要在夹缝中生存;有时公司需要寻求突破,开发新市场,拓展新的行业应用。此时外部条件要求我们不得不去了解一个全新的行业,软件工程学早已将有效的方法告诉我们了。需要做的就是将良好的学习能力发挥出来,将这个过程所花费的时间约束在一个月到半年之间。如果超过这个时间,管理者们就应该审视这个小组是否是由学习能力良好的个人组成的拥有高效协作能力的小组了。

软件不仅要应用到某个行业中去,还要有助于提高行业应用效率,也就是让用户的世界变得更好。这可以说是软件工程师们面对的最困难的问题也是最基本的问题——如何完成高效的实现。现在需要软件工程师们设计出在其上工作的软件以发挥其效能的计算机都电子计算机。它们具有相同的基本原理——电工学中的数电部分(electronic engineering),它们具有相同的体系结构——运算器、控制器、通讯线路、外设接口、存储设备、交互设备组成的系统,运行于其上的是具有相似或相同体系结构的操作系统——分层次分模块地对硬件体系进行管理以提供一个友好的高效的工作环境。这些东西是相对稳定的,除非所谓的量子计算机和生物计算机进入日常生活。对这些东西的熟知是完成高效实现的基础。当然我们还需要对编译原理有所了解。知道这些东西之后,才能对什么是程序、什么是编程、编码是怎么转换为计算机可识别的程序的、为什么相同的编码被不同的编译器编译后会产生不同的效率、为什么不同的编码被相同的编译器编译后会产生不同的效率、为什么要释放申请的资源、为什么编译后的程序会在运行中发生重大错误、为什么这样实现的数值计算的结果不对……这一系列的问题有深入的体会和基本的解答。

这些疑问会使我们进行更进一步的探索,更进一步的学习,让我们认识到数据结构和计算方法的重要性。然后我们懂得了如何根据具体问题选择数据结构和算法。此时我们编写的都是小程序,没有实际的用处,我们也确实看到了这些小程序在解决某个微小问题时凸显出与我们原来的实现的不可比拟的效率。当我们接手一个大课题时,通过我们的精心设计并最终制造出了一堆效率低下的垃圾。此时我们又充满疑问,然后我们认识到设计模式和架构的重要性。慢慢的我们学会了对面临的问题以及问题关联的因素进行建模,还学会了怎么建立更高效的模型。对生产效率的要求使得我们都认可了面向对象的分析方法和对问题建立起面向对象的模型。设计模式和架构中的基础部分和前述的所有关于如何完成高效的实现的知识可以通过学习得来,甚至对这些知识的使用能力也可以通过学习得来。但是设计模式和架构就包含有很大一部分经验了。这里有些经验并不像经验那么简单,因为有些可以通过分析得来的优秀设计只有在实践中才会得到我们的重视。在在理经验还具有强化我们对分析的重视和对知识应用的重视的作用。

比如,现在节约内存不再那么重要了,但是避免内存碎片仍然是十分重要的。如何避免过多的内存碎片呢,那就是避免频繁的分配和释放内存。(注意分配和释放内存不仅仅指C、C++中的alloc、free、new 、delete,C#、Java等语言中创建一个对象和销毁一个对象也应包含在内。)我们可能对内存碎片有所认识,但是对频繁分配和释放内存与内存碎片的关系并没有作更多的思考。在我们完成了一个承受不住压力测试的软件后,就会对此作出思考并在通过设计来避免这种问题。有一种方法就是,将程序中一些很多地方都要使用的辅助性基础对象作为和字符串、图片一样的基本资源看待。辅助性基础对象包括一些提供输入合法性检查的对象、通用的对话框、错误提示对象、操作指导对象等。在系统启动的适当时机全部创建,当需要时由资源管理对象获取这些辅助性对象的引用(指针或者句柄)。如何确定把那些辅助性对象作为资源呢?需要一种量化手段。当某个需要使用某个对象的功能数乘各个功能的使用频率大于某个值时就将其作为资源看待。此处功能的使用频率和某个值就是由经验确定的。当然还有一种方法就是寄希望于平台给我们提供和链接池功能差不多的对象池。

当我们建造了一个稳定的、高效的却不受欢迎的产品后,又会获得另外一种经验——重视交互设计。努力保证所建造的软件的交互界面的一致性、交互方式的易用性、避免界面上文本的二意性……当然还有界面的美观。注意保证界面美观的保证交互方式的用户友好特性不是一个概念。前者由美工完成、后者由UI设计师完成。在一个总体不成熟的IT环境里“退化”是经常的现象,所以每一个软件设计师还要有一定的UI设计经验。

我们能够建造优秀的软件,但如果总是在交付期限之后完成,想象一下后果吧?略微一思考,就会认识到软件开发技术或成果的使用也是比较重要的。这是减少时间花费的有效手段。积累对某一编程框架的使用经验可以加快开发速度、可以保证产品的质量。但是我们却拥有OpenGL、OpenCV、GTK、MFC、COM、AJAX等难以计数的软件开发技术和成果可以使用、并且这些技术和成果也在不断的演化。不同的软件开发技术和成果针对不同的应用环境,我们只需学习感兴趣的或者需要使用的。为了跟上演化是需要学习能力作为支持的。

总之,在这三种经验中“如何完成高效的实现”是最稳定的也是包含内容最多的,只此一招可以应对万变,所以它是最重要的。软件开发技术或成果,还有行业应用方面的经验是相对次要的,但仍然是很重要的;它们的内容相对较少、较为容易掌握而且是容易变化的。“较为容易掌握”是相对于高学习能力而言的,所以有志于成为软件工程师的同胞们一定要注意培养学习能力。

回复列表 (共3个回复)

沙发

深刻!
想共鸣一下,却没什么经验

板凳

顶一下。
论坛被广告霸占,好帖都沉了,让人痛心,人肉顶上。

3 楼

[quote]顶一下。
论坛被广告霸占,好帖都沉了,让人痛心,人肉顶上。[/quote]
谢谢啊。这只是开始工作以来的心得。
还得希望高手们补充、指正啊。

我来回复

您尚未登录,请登录后再回复。点此登录或注册