原文 Software Engineering is different from Programming
一些人因为“工程”这个词而不喜欢软件工程师这个术语。这篇文章跟这个术语没什么关系,你不喜欢的话完全可以把这个词替换掉,改成软件作者、软件冒险家或者软件艺术家!
软件工程师,把编写高质量软件作为他们的专业,把科学和统计学融入其中,而不只是把写软件当成赚钱工具。
知道怎么编程不代表你就是软件工程师。
谁都可以学习编程,这很简单,每个人都可以写一些简单的代码,这些代码可以运行在他们的机器上,但不能保证其他机器能否运行。
类比一下:
- 我们可以学数学但是这不一定能让我们编程数学家
- 大多数人都可以学会煮饭,但是正式场合我们还是会请厨师做这件事
- 你不能叫住你隔壁的勤杂工给你盖个房子
我是想告诉大家,构建一个软件比编程难多了。
最简单的编程是,输入数据到电脑,处理后输出数据。
而构建一个软件是集设计、编写、测试和维护于一身的,其目的是要满足用户的需求。这要求创建健壮的代码,经得起时间考验的安全解决方案,有时候还不得不面对一些未知的问题。
软件工程师要深入理解他们要解决的问题、他们要提供的解决方案、这些方案的局限,以及一些隐私安全问题。
如果一个人没有深入了解一个问题,他们就没办法让程序去解决这个问题。
解决问题的心态
软件工程师不认为编程是他们事业的全部。他们要思考的是如何满足需求和解决问题。不是每个问题都需要写程序解决的,而是依赖现成的程序,或者结合多个程序。提早的准备可以避免很多问题,好的程序通常需要详尽的计划来预防未来出现的问题。
知识分子解决问题,而天才会防止问题出现。 -爱因斯坦
复杂的问题需要多个程序组合才能解决,有的需要程序并行运行,而有的需要顺序运行。当然还有一些问题,可以通过教育用户来解决。(译者:所谓的解决提出问题的人吗?)
写程序及构建软件之前先问自己:
- 我需要解决什么问题?
- 除了写代码还有什么方法解决问题?
- 用代码如何让问题变得更容易解决?
代码质量
好程序是简洁易读的,容易扩展的。他们可以和其他程序协作得很好,维护起来也很舒服。高质量代码是必须的,因为死线和心情不好而偷工减料是绝对不可取的。
构建软件重要的一点是贯彻可延展性,你总要更新软件以满足用户更多的要求。
一个单独的软件有时可能不是很有用。当多个软件互相交流,交换数据,合作呈现数据和与用户交互,这个软件才会变得有意义。
程序设计要时刻思考这些问题。他们接受什么信息?应该监听什么事件?什么信息被触发?通信间授权怎么做?
另一个重点是代码要清晰,而不是给出一大堆测试结果。这段代码可以被别人简单理解吗?你今天写的代码,几个星期后的自己能看懂吗?
计算机科学里只有两大难事:命名和缓存失效。 -Phil Karlton
代码可读性比你想象的更重要。但是很不幸的是,没有很好的准则判定代码可读性。记住一些设计模式和更多的实践会带来帮助,但这不一定足够。好的软件工程师以经验和直觉判定。(要不要写得这么玄学)
我没时间写一封短信,所以我决定写一封长的。 -马克吐温
出错时容易修复的程序才是好程序。发生错误时我们应该可以清晰地看到错误报告,并且可以从错误报告定位到程序出错位置,修复人员可以很容易地看懂上下文并修复系统。
环境与测试
软件工程师写的程序要保证在不同环境,不同时区正常工作。软件要运行在不同大小的屏幕,还包括屏幕旋转,甚至还要考虑机器性能和功率问题。
例如我们为网络浏览器设计一个软件,我们就要考虑到适配所有主流浏览器。桌面应用就要考虑到Mac和Windows甚至是Linux用户。一个依赖数据的软件在处理无法检索数据或检索缓慢时应有对策。
要写一个软件,软件工程师需要考虑各种不同的应用场景,然后测试这些场景。虽然意外没有发生,但是仍要列出这些可能发生的意外,测试他们。右侧软件工程师会先写测试用例,然后让他们的目标代码都通过这些测试。
工程师知道软件需求有时候是模糊或者不完善的。有天赋的工程师的独有技能不是知道怎么写解决方案,而是清楚有什么问题需要解决。
成本和效率
软件工程师在大多数情况下可以快速解决问题。如果你觉得聘请一个优秀工程师成本很高,请你三思。你聘请优秀的工程师,他们提供健壮、精准、可信、可维护的解决方案。这以为这长期成本的大大降低。你需要考虑运营软件的成本。每个程序都要占用电脑资源,但是高效的软件可以大大节省资源。如果你雇一个初学者给你构建软件,价格可能很便宜,但是后来的支出可能会非常高,还有一大堆遗留问题。
可用性
好的程序需要考虑用户体验。人机交互是一个大热点,无数研究都与他有关。
让我给你一下例子让你感受一下这一点:
- 设计输入表单时,如果是邮箱地址,就应该无视大小写,并去除头尾空格。如果是接受一个新的邮箱地址,提早验证是否可用并给出清楚的信息。重点不只是判断有没有@,也应该顺便判断用户有没有像“gmail.ocm.”的错误输入
- 使用重定向的时候,一个好程序会记下重定向前的地址,重定向处理完成之后应该回到原来的地址。更好的话,应该吧之前的表单信息也记录下来。例如你要买机票,找好了某一班机,但是注册之后又要重新搜索,这样用户体验就不是很好。
- 好程序为用户场景设计。站在用户的角度思考。不要只加 feature 不管后事!一次我订机票忘了我的飞行常客号码。前前后后搞了十分钟。我在网站找这个号码,没有明显路径可以让我找到,在找到的那个页面还把这个选项埋在一个大表格里面,进去之后我还填了 20 个选项甚至是手机号码都填了,最后才搞定,这就是不为用户设想的例子。
可靠性、安全性、稳定性
这可能是区分软件行业专业和业余的重要一点。他们知道他们要提供安全和稳定的解决方案。
好的软件对恶意输入、错误状态和错误交互都有所对策。这很难全部做到,也因此让大家觉得软件错误让人痛不欲生。
用户会对软件进行错误的输入,有些情况是恶意输入,目的是破坏软件或者是黑一些数据。最近的 Equifax 事件负责人就被指责没有尽职于恶意输入的对策。
安全问题不只是关于恶意输入,普通输入也有注意点。如果用户忘记密码,你会允许他们尝试输入多少次?会冻结他们的账号吗?如果是其他人让他们冻结呢?你会不会让你的用户在非加密链接输入密码?不在常用地点又怎么办呢?
你如何保护用户,避免跨站脚本、伪造请求、中间人攻击和网络钓鱼?后台有对抗DDoS攻击的策略吗?这都是一些常见问题的名字,我们应该首先关注的。安全的程序不会明文储存敏感信息而是用复杂的算法加密数据,这样黑客拿到数据也没什么用。
软件会犯错,并且必须要修正。即使是最好的软件也会出问题。如果你没有意识到这个,而没有为此做计划和对策,那么你就不是软件专家,只是一个不安全程序的写手而已。
软件缺陷是不可见的,我们预测和避免缺陷的能力也是有限的,所以软件工程师懂得利用工具矫正代码。
拥抱工具
毫无疑问我们需要更多更好的工具。工具十分有用,但却常常被低估。试想一下我们没有 Chrome 开发者工具 debug 和检测性能表现!试想一下没了 ESLint 和 Prettier 我们的效率会多么低!
如果你是个 JavaScript 开发者,被迫只能在编辑器装一个插件,那么你应该选择 ESLint。
可以在你编写代码时缩短反馈回路的工具,我们都可以尝试使用。Bret Victor 的 inventing immediate visual representations 观点让我大开眼界。拥抱和改善工具让我们有一个美好的前程,如果前面的视频你没看过,那就赶紧观看学习一下。
每当我找到一个好工具,我的感觉都是相逢恨晚,好工具能帮助你成为更好的程序员,找到他们,使用他们,欣赏他们,如果可以的话,你甚至可以完善他们,帮助更多的人。
对于类型安全问题,在JavaScript领域最好的就是TS和Flow了。静态类型的重要性比你想的更重要,如果不是这样,你的代码未来可能会很脆弱。尽量不要使用动态类型,如果你的语言是动态的话,最好换一个语言,或者找个转译器。现在的转译器已经智能到从注释入手转译,我觉得未来动态语言都需要这东西。
软件工程师的进化
两个月,半年,甚至一年精通软件工程是不可能的,你别去上什么培训班去学这个。我学了二十多年,直到现在还在学习。而我学了十年,构建和维护了上千上万人使用的程序,才敢自信地说一个有经验的软件工程师。
不是每个人都要当软件工程师,但是每个人都应该学会用电脑解决他们的问题。你应该力所能及地学习一下写程序。问题层出不穷,软件工程也应不断进步。这个行业的未来是让普通电脑用户可以不用学习很久就能简单完成一些工作,可以让用户用一些简单工具解决他们的问题。软件工程师则是研究更好的工具,解决更多已知问题,然后避免未知问题的发生。
感谢阅读这篇文章。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。