学习代码语法是一件比较简单的事情。但是如何利用简单的语法去组建庞大的项目,会衍生出很多问题。这里总结了一些编程过程中需要注意的陷阱和原则,之后如果有新的总结,我会继续更新。
1,不要编程
对,不要编程。能用草稿纸解决的问题,不用去写程序。
在写程序之前,应该先弄清楚问题。花更多的时间去听、读和理解问题。
非常多的程序员在写代码的过程中去梳理问题,所以他们会花更多时间去调试和找 bug.
2,不要太依赖工具
不管是编程语言,类库和成熟软件,都是解决问题的工具,真正值钱的并不是工具,而是掌握的编程技能,计算机知识和思维。
为具体的项目去寻找合适的编程语言,类库和软件。每个工具都有适用场景,python 更适合上层开发,go 更适合底层开发。 如果只会特定的编程语言,类库,工具的使用,你只能根据这些工具去找工作,选择性会大大降低。
太依赖工具还有另一个副作用:只懂用法,不懂实现。当工具更新或者过时了,又要重新学过,辛辛苦苦积攒的经验毫无勇武之地,和一个从来没用过的新人没有多大区别。
尽可能的原生语句实现,不要随意安装第三方库。一旦这些库停止维护,或者因为版本更新出现兼容性问题,你的代码将无法运行。
对于不是特别复杂的问题,尽量用原生语法和标准库。要用第三方的类库,也要选择那些成熟的,持续维护而且兼容性够好的类库,就算实现起来麻烦一点。
3,不要欠技术债务
技术债务指的是:开发人员为了加速软件开发,在应该采用最佳方案时进行了妥协,改用了短期内能加速软件开发的方案,从而在未来给自己带来的额外开发负担。这种技术上的选择,就像一笔债务一样,虽然眼前看起来可以得到好处,但必须在未来偿还。
比如使用了新潮但是不成熟的框架。或者在编程中复制粘贴别人的代码,但是没有经过自己的思考而直接使用。
在代码编写过程中尽量要弄懂框架和代码的原理,就算当时因为进度不理解,也要抽时间去消化。否则代码出问题了都不知道怎么回事。
4,远离商业炒作的项目,对新兴技术保持警惕
许多流行的框架都是一些公司为了 KPI 或者商业需要开发的。这些框架可能面临后期无人维护,或者社区运营无力的风险。这意味着当底层出现问题的时候你不能高效的解决问题。
在 github 上有很多热门的项目非常受人欢迎,但很多没有实质内容。开发者从来不去处理 issue, 也不对代码进行更新。
对新兴技术同样需要保持警惕。新兴技术可能是公司的实验产品,不管是稳定性,社区运营都没有得到市场证明,过早投入太多精力风险很大。如果这个技术没有形成气候,基本上前期的努力就白费了。 一个成熟的技术框架需要长时间和大量用户的实践证明,选用技术方案时最好优先考虑成熟方案。
5, 保持学习
离开你的舒适区。每天学习。并且把你学到的教给别人(教学是最好的学习工具)。除非你是一位大师,你就可以不用学习。让自己接触其他语言、技术、文化并保持好奇心。
学习一定要有产出。可以通过文字,视频,语音等方式记录。 没有产出,很难形成自己的思维,马上就会忘掉。
对于新兴的技术,不是完全不能碰。新技术出来的时候可以安排适当的时间接触,从中吸收新的思想和设计方式。 学习的时候一定要做一个项目出来,以项目驱动学习。
6,写文档
好代码不需要文档,但是优秀的代码都有很好的文档。
有了文档,别人在使用的时候就可以大幅减少试错成本。 之后你去优化更新代码的时候也可以极大的提升效率。
7,提高代码的可读性
你不是为机器写代码,而是为你的同事和未来的自己写代码。如果你不想在更新的时候花大量时间去阅读之前的代码,那就应该让你写的代码,小朋友也能看得懂。
尽量使用简单易懂的语法,不要炫技。很多流行的技术框架使用了一些非常酷炫的语言特性,让人容易产生技术崇拜,但是很多实现都可以使用更加通俗易懂的语法写成。
酷炫的语法糖或者语言特性容易让你迷失自我。
8,编写独立的模块
你不应该把你所有的代码像面条一样搅在一起,彼此依赖。 这样一旦某个部分出现问题,整个项目都会受到影响。
你应该为每一个功能编写独立的模块,并且对模块进行独立测试,然后再导入到其他的代码,做集成测试。
模块交互的地方容易出现 bug, 所以要更加仔细检查。
9, 编写纯函数
纯函数是指:
- 当传入相同的输入值时,产生相同的输出;
- 函数的输出和输入值以外的状态无关;(比如在输入值不变的情况下,时间改变,输出发生了变化)
对那些不方便通过纯函数实现的,使用类和对象进行封装。 使用类的时候,尽量避免重写、继承和隐式智能。
对纯函数和非纯函数进行分开管理。
10,不要复制粘贴
复制粘贴非常容易产生 Bug。复制越多次,bug 越多。 可以说一个项目里的 bug 数量和你复制粘贴的数量是成正比的。 如果一定要复制粘贴,请仔细检查每一行代码。
11,面向异常编程
人的思维习惯总是倾向于考虑正常情况,而忽略可能潜在的异常。 有时候是没有考虑到,更多的时候则是考虑到了,但是嫌麻烦。
如果不处理异常,意味着你的代码随时会终止运行,意味着这份代码是不可信赖的。
尽早处理异常,并且回答这些异常为什么会发生,如何检测,以及如何解决。验证所有系统输入(包括用户输入),尽早发现问题,你的代码就会少更多的隐患。
编程的时候,应该习惯性的问自己,如果程序没有按照我预设的路径执行,会怎么样?
12, 分清楚代码的优先级
并不是所以的代码都同样重要。有的代码,没了它程序完全无法执行,有的代码,自从你写了以后,就从来没被使用过。
你需要理解这 3 者之间的区别:
- 核心代码:就像汽车里的引擎。没有它,产品就没有意义。
- 必要代码:就像汽车的备用轮胎。它很少使用,但当需要时,它的功能决定了系统的成功。
- 附加代码:就像汽车的杯托。有它很好,但没有它,汽车照样开。
13, 分清楚产品规范的优先级
用户体验、安全性、性能是相互冲突的。
一个一般的原则是:
安全性 > 可用性(易访问性和用户体验)> 可维护性 > 简单性(开发人员体验/DX)> 简洁性(代码长度)> 性能
但也不要盲目,每个类型的产品都有侧重点。和任何职业一样,经验越丰富,就越能在每一种情况下找到正确的平衡点。例如,在设计游戏引擎时,性能是最重要的;但在创建银行应用程序时,安全性是最重要的因素;在初创项目,你完全不需要考虑性能,当项目发展起来的用户太多,性能就会成为你首要要考虑的问题。
14, 让别人参与你的代码维护
开源和闭源并不是永远都是争锋相对的。 对于涉及到商业风险的项目,可以选择闭源。但是对于不触及商业的底层代码,开源是个更好的选择。
因为底层的代码脱离了商业逻辑,而且往往非常抽象和复杂,需要更多人的参与和实践。可参考 linux 开源项目。
任何有意义和有回报的软件都是协作的结果。一个人总是会有思维死角,不要太相信自己的能力。
请跟我默念 3 遍:我写的代码是垃圾,我写的代码是垃圾,我写的代码是垃圾。 它们需要别人的优化。