成功程序员的基础实用编程技巧






4.90/5 (34投票s)
所有程序员的实用主义清单
引言
创建优秀、成功的软件非常困难——极其困难。
因此,对于每一位程序员来说,了解、理解并应用基础的软件开发实用技巧至关重要——这些实用的建议和规则已被证明是有用的,并能帮助我们在最短的时间内创建出最好的软件。
在本文中,我试图收集一套我认为最相关的基础实用技巧。如果您是一位经验丰富的程序员,您可能对其中大部分/所有内容都很熟悉。如果您遗漏了某些建议,请通过评论与我们分享。
请注意
- 本文中的实用技巧是关于设计和编写代码的。软件开发项目要取得成功,还有其他重要的方面(例如良好的用户界面、人际交往等),但这些超出了本文档的范围。
- 以下实用技巧仅涵盖基础原则,旨在普遍适用。不包含针对特定编程环境(编程语言、库、工具和架构)的建议。
技巧分为三类
- 通用指南
- 数据设计
- 编写代码(将在本文第二部分发布)
让我们开始吧。
通用指南
一切都应该尽可能简单,但又不能太简单! - 阿尔伯特·爱因斯坦
简单的工具和概念可以快速理解,易于使用,不易出错,并能提高我们的生产力。
我们都喜欢简单。简单使工作和生活更加愉快。
然而,我们必须意识到过度简化的危险,正如爱因斯坦美丽名言的结尾所示。
因此:保持简单,但不要过于简单!
许多名人都推崇简洁。以下是一些例子
引用简洁是可靠性的先决条件。
简洁和清晰……决定成功与失败。
荷兰计算机科学家;《Go To 语句被认为有害》的作者
引用控制复杂性是计算机编程的本质。
计算机科学家和作家;Unix 的联合开发者
引用简洁是终极的精致。
引用简洁能将普通变为非凡。
《呆伯特》的创作者
引用如果你不能简单地解释它,说明你理解得不够透彻。
物理学家;天才
引用真理总是在简洁之中,而不是在事物的多重性和混乱之中。
数学家;天文学家;神学家;作家和物理学家
如果注定要失败,那就快速失败!
大多数软件项目都会失败。这是一个令人 sad 且不可否认的事实。
如果一个项目被认为会失败,那么它应该尽快失败,以限制损失,并将时间和资源腾给其他(有望)不会失败的项目。
在此语境下的快速失败意味着问题应该尽早被检测到并得到处理。我们拖延解决问题的时间越长,浪费的时间、精力和资源就越多。随着时间的推移,累积损失会呈指数级增长。
例如,在设计阶段纠正一个设计缺陷既简单又便宜。但一旦软件投入生产并被许多人使用,修复错误通常会非常昂贵且令人沮丧。
引用我们越早“失败”并越快学习,成功的几率就越大。尽早失败可以为您节省时间和金钱。
Adobe 产品经理
引用快速测试,快速失败,快速调整。
畅销书《追求卓越》的作者
追求“够好”,而非“完美”。然后发布!
创建完美的软件(没有 bug,所有功能都已完全实现,最佳用户界面,优秀的文档等)非常耗时且昂贵,除非我们处理的是一个非常小的项目。在大多数情况下,由于实际限制,实现完美是不可能的。
即使是软件行业的主要参与者,拥有最好的开发者和充足的预算,也无法编写出完美的软件。这就是为什么他们不断提供补丁和新版本。
因此,请按以下方式进行
- 设定目标和优先级
- 创建原型
- 交付“够好”的软件
- 持续改进(参见下一项)
![]() | ![]() | ![]() |
原型 | 够好 | 更好 |
引用您无法编写 100% 完美的代码。即使您做到了,6 个月后它也不会是完美的。
CodeProject 联合创始人
引用在计算机简短的历史上,没有人编写过完美的软件。
作家;《实用的程序员》合著者
引用现在交付 90% 的功能比永不交付 100% 的功能要好。
计算机科学家和作家;Unix 的联合开发者
引用寻找完美解决方案通常会导致停滞和沮丧。坚持不懈,容忍不完美,追求改进,并致力于尽自己最大的努力,这些都是健康的,并且最有可能产生最佳结果。
心理治疗师
倾听用户的声音!
实践表明:
- 软件开发人员无法预料到用户真正想要的一切。
- 用户通常确切地知道他们想要什么,除非他们使用该软件一段时间。
- 用户的满意度是软件成功的决定性因素。
我们想要满意的用户。因此,最好的方法是迭代式的方法,如下所示

引用在尝试了一些营销技巧并花费了大量时间后,他(乔尔·斯波尔斯基,Stack Exchange 联合创始人)总结说(5 年后):没有什么比改进你的产品更好。制作人们想要的好软件并不断改进它。与你的客户(用户)交谈并倾听。找出他们的需求。
引用……我们为每个主要产品功能构建原型。我们很早就与预发布用户和关键客户进行测试,并且绝对在实现之前进行。是的,我们确实经常“失败”,这很棒!这很棒,因为我们在过程中学到了很多东西,并最大程度地降低了长期的失败风险。最终,我们以富有同情心的方式,以创新的方式解决了客户的实际需求。
Adobe 产品经理
引用
引用程序最重要的属性是它是否实现了用户的意图。
计算机科学家;1980 年 ACM 图灵奖获得者
数据设计
在编写代码之前,仔细设计您的数据!
无论何时创建应用程序,都从仔细设计数据结构及其关系开始。在编写代码之前完成此操作。
设计良好的数据结构可以带来更简单、更易于维护的代码,减少 bug,提高性能,并降低内存消耗。
差异可能非常显著。
引用一项又一项研究表明,最优秀的设计师产生的数据结构更快、更小、更简单、更清晰,并且付出的努力更少。优秀与平庸的方法之间的差异接近一个数量级。
书籍《没有银弹》
引用给我看你的流程图(代码),隐藏你的表格(数据结构),我仍然会感到困惑。给我看你的表格(数据结构),我通常就不需要你的流程图(代码)了;它们会很明显。
书籍《人月神话》
引用表征规则:将知识折叠成数据,这样程序逻辑就可以是愚蠢而健壮的。
数据主导一切。如果你选择了正确的数据结构并组织得当,算法几乎总是显而易见的。数据结构,而不是算法,是编程的核心。
引用我非常提倡围绕数据设计代码,而不是反过来。
糟糕的程序员担心代码。好的程序员担心数据结构及其关系。
Linux 的创造者
引用如果你正确地处理了数据结构及其不变量,大部分代码就会自己写出来。
书籍《程序员访谈录》

除非有充分的理由,否则使所有数据结构都不可变!
不可变数据结构更容易理解,更易于使用,并且不易出错,因为
- 创建后,状态不再改变。没有状态转换,没有临时无效状态,也无需同步、锁定或防御性复制。
- 不可变数据可以在并发/并行计算环境中自由共享——没有数据损坏、死锁或其他可能非常难以解决和修复的棘手问题的风险。
- 基于不可变数据计算出的结果可以轻松缓存,以提高性能。
然而,不可变数据结构并非总是最佳选择。例如,为每一次更改克隆整个结构可能非常昂贵(在时间和空间上)。在某些情况下(例如游戏或 GUI 应用程序),可变数据结构更适合。
此外,如果两个对象需要直接相互引用,那么对象必须是可变的。例如,树中的父节点和子节点直接相互引用,互为好友(A 指向 B,B 指向 A)等。在这种情况下,如果必须保留不可变性,那么一种可能的解决方案是拥有一个额外的描述关系的数据结构,例如一组表示一对相关对象的元组。
将允许的值集限制为最小可能的值!
限制数据类型允许的值集
-
记录并帮助理解数据类型
-
消除因错误值而导致的误行为或严重故障的风险
-
简化处理数据的代码
例如,考虑数据类型employee
的name
字段。允许将任何字符串存储在name
中,可能会发生以下情况
-
长字符串可能导致缓冲区溢出(取决于编程语言)、内存耗尽或其他软件故障。
-
在名称中无效的字符,但用作 JavaScript 和 SQL 中的有效符号(例如
<
、>
和"
)可能会为 SQL 和/或脚本注入等攻击敞开大门。 -
如果代码没有正确显式处理空字符串或
null
值,则可能导致 bug。
为避免这些风险,应限制name
字段。例如,以下简单的正则表达式消除了上述所有问题
[a-zA-Z ]{1,70}
此正则表达式将名称限制为最多 70 个字符,至少需要一个字符,并且只允许字母和空格。但请注意,上述正则表达式过于简化,不适用于必须允许包含连字符、撇号等的名称的实际应用程序。有关更多信息,请参阅 Chad3F 在评论。
保护数据免受无效值的影响(尤其是在处理来自外部源的数据时)通常被认为是编写安全软件最重要的规则。(例如,参见OWASP Top 10 关键 Web 应用程序漏洞和前 10 名安全编码实践)
数据输入表单中SQL 注入尝试的示例
JavaScript 注入尝试的示例
大多数情况下,默认值应该是允许值集中最严格的。
通过选择最严格的可能值作为默认值,我们始终处于安全的一边。
更宽松的值需要明确说明(在代码中、配置文件中等)。
例如
-
一个写入文件的函数,默认情况下不应覆盖现有文件。
-
默认应启用所有编译器警告。
-
如果在多用户应用程序中添加新用户,则默认应授予最低的权限。
最后一个例子表明,严格的默认值并不总是最佳选择。它们可能令人烦恼。如果该多用户应用程序只由一个人在其 PC 上使用,那么用户显然希望默认拥有完全的权限。因此,最佳默认值有时取决于几个因素。
GUI 中严格默认值的示例

避免数据冗余!
在不同位置存储可变数据的副本容易出错、劳动密集且成本高昂,因为
-
在数据更改的情况下,存在未更新所有位置的风险——由于健忘、技术问题、安全问题等。这可能导致数据不一致和损坏,并最终导致严重的软件故障。
-
有时需要实现和激活锁定/同步机制以进行每次数据修改(创建、更新和删除操作),以避免在数据修改过程中访问无效数据。实现这些机制可能非常棘手且容易出错。
-
需要额外的内存来存储副本。
肤浅的例子:一位推销员错过了一个重要的约会。原因:他将约会输入了他的 PC 上的日程表,但忘记了与他手机上的另一个日程表同步数据。如果两个日程表的数据都存储在一个地方(例如云端),他就不会错过约会了。
考虑使用通用、标准化格式将数据存储在纯文本文件中!
使用文本文件作为存储介质有很多优点
-
所有操作系统都完全支持文本文件。无需安装和配置数据库服务器等附加软件。
-
文本文件可以由人类轻松读取和处理。这对于调试非常方便。
-
它们也可以由许多第三方应用程序(用任何编程语言编写)和工具轻松读取和处理。例如,Unix 提供了许多有用的文本处理工具,如 grep、awk、sed 等。
-
使用 JSON、XML 和 CSV 等标准格式可以使数据被许多现有应用程序查询、排序、过滤、搜索、打印和转换。例如,CSV 文件可以在电子表格应用程序中轻松使用。
然而,文本文件也有严重的局限性,尤其是在大数据的情况下。复杂的查询(带过滤和连接)、更新和删除操作、事务处理、数据加密和其他功能可能需要手动实现,并且可能非常低效。当涉及大数据时,将其存储在数据库中通常是唯一可行的选择。
此外,将数据存储为字符(而不是位)会消耗更多的空间和时间。因此,二进制数据有时是不可避免的。
使用文本表示图形的一个很好的例子是SVG
(可缩放矢量图形)。
这是一个 SVG 文件的简单示例(SVG_example.svg)
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" > <circle cx="70" cy="70" r="40" stroke="red" stroke-width="4" fill="yellow" /> </svg>
用(例如您的网络浏览器)打开文件会显示以下图像

引用编写处理文本流的程序,因为这是一个通用接口。
Unix 管道的发明者
引用Unix 传统强烈鼓励编写读取和写入简单、文本化、面向流、设备无关格式的程序。
《Unix 编程艺术》
编写代码
请继续阅读第二部分。