程序与人生

最近趁着离职的一点空隙,稍微能有些时间和心情来思考一些更有深度和更长远的问题,这篇文章的内容算是我近期开的小小脑洞之一。

越来越发现,前人总结的一些众所周知并经过时间验证过的关于写代码的道理,只要我们换个角度来类比和思考,同样可以适用于我们人生历程的一些方面。这篇文章就是我想到的一些例子,小标题都是写代码时所谓的一些「金科玉律」,而我会试图通过这些相通的「规律」,衍生出个人对人生某个方面的思考,可能小到微不足道的个人习惯,大到能够决定人生方向的人生观。

做好垃圾回收

任何使用 C/C++ 写代码的程序员都会在编码时尤其注意一个问题,那就是及时进行垃圾回收。具体来说,由于 C/C++ 本身不具有自动垃圾回收的机制,所以但凡程序向操作系统「借用」了一块内存来存放新生成的对象,都必须在对应对象的生命期结束之后的某个时刻主动的进行内存释放,即手动进行垃圾回收。如果没有进行合适的垃圾回收,则系统会陷入了我们常说的「内存泄漏」的问题——由于无用的内存得不到及时的释放,导致程序占用的内存越来越多,最后导致内存不足而整个系统无法正常运行。

一个合格的 C/C++ 程序员会把主动进行垃圾回收的习惯带到生活中,小到随手关灯、随手关门、把用过的会议室恢复原样,中到把借来的东西物归原主,甚至大到整个人类对发展过程中对生态环境破坏的及时弥补,其内在其实都是自然的「垃圾回收」原则。

永远不忘把错误默默吞掉

“Errors should never pass silently”《The Zen of Python》中重要的一条,它告诉我们永远不要忽视代码中的「异常」(Exception)。无论你是像目前大多数语言或框架所设计的把「异常」向上「抛」到一个足够高的层次然后统一记录日志并做处理然后程序继续运行,还是像 Erlang 那样崇尚 let it crash 的思想把所有被「异常」所「感染」到的轻量级 Process 全部挂掉,其相同的基点都是不能把异常默默的忽视掉。

其内在的逻辑在于,我们绝不能忽视系统中的任何一个错误,把问题暴露出来总是比隐藏问题要更好。任何一个不加处理和纠正的错误,对于有状态的系统而言,可能导致系统处于一个完全失常的状态,其行为得不到有效的控制;对于无状态的系统而言,则可能使得任何触发了这个错误的用户请求都产生错误的结果和返回,即便不直接把 Process 挂掉,也至少把错误捕捉到且记录日志并视问题严重程度适当进行告警,否则问题将永远得不到解决。

生活中其实也是如此。当我们遇到问题时,人的本能反应都是逃避的,但逃避永远解决不了我们遇到的问题。选择直面问题和困难是强者和自信者的逻辑和选择,人生也只有在不断的打怪升级中进阶成为更好的自己。具体来说,学习时遇到难点要想办法去弄懂原理,人际交往中遇到误会要及时沟通,工作时遇到阻碍要直面解决等等。

分工明确,关注点分离

SoC(Separation of Concerns)是面向对象程序设计的核心概念之一,它强调把业务逻辑的代码与解决特定领域问题的代码分离,这样才能使得代码具有「高内聚,低耦合,分层明确」的特点,也就是使得日后由于需求变动带来的维护修改能够以尽可能小的影响面来进行。其实 Erlang 的 actor 并发模型设计对此也有所体现,整个系统任务被拆分成一个个不同的小任务,被大量的轻量级 Work Process 来执行,而 Process 之间唯一的交互方式是通过 messages(这就是好比各个子系统通过 API 来进行黑盒交互),这样的并发模型就完全避免了传统的共享内存式并发的 data race、死锁等固有问题。

人类社会整个就是一个分工明确的动态系统,不同人一定会有不同的专长和兴趣,在走向社会之后也一定会或主动或被动的走到合适自己的岗位上去。而整个人类社会系统是不断动态发展的,正是由于明确的分工机制,客观世界的某个具体的变化不必需要人类全体都进行调整来适应,这样人类社会总体上才得以能够勉力跟上客观世界变化的速度。其实道理很简单,就拿最近影响面极广的 WannaCry 勒索病毒事件来说,即便微软早在两三月前就已经推送了补丁修复漏洞,但由于需要调整的用户数量太大(即便假设所有用户对系统更新都持开放态度),所以肯定还是会有大量来不及进行调整的用户中招。更明确的说,个体数量越多,则所有个体都从当前状态调整到另一个确定状态所遇到的阻力就越大。

结语

其实如果有心,还可以发现很多沉淀下来的技术「准则」都可以有更哲学更生活化的解读和理解,也欢迎留言提供你的「新发现」。

程序与人生,不仅仅是写程序的人生,更是透着程序思想哲思的人生。