再读王垠的《编程的智慧》,有怎样的感想?

 王垠老师的《编程的智慧》这篇文章已经读了最起码5遍了,最近的项目做完一个阶段,到了把他做干净的时候,也就是优化代码,全面整理的阶段,这个时候我又想起了这篇编程的智慧,有一些启发与大家分享。

王垠老师的《编程的智慧》

王垠老师是谁?想必很多朋友都有耳闻,不知道的也可以去查一查,首先是个真诚的人,性情中人,他也是一个颇具争议的人物,有过多次退学、辞职被封杀、喷教育制度等等一些争议事件,但是毫无疑问,他在计算机的理解、个人精湛的技术方面是无可争议的。

这里没有对个人进行正面或者负面的讨论,主要是他对语言的理解和经验让我受益,而我也觉得看人就需要看他的优点和对自己有益处的东西就行了,《编程的智慧》这篇文章真的可以仔细看看。

从第一次看这篇文章的时候就感觉这文章十分的厉害,不在我当时的层次范围里,甚至现在也不是,我也是渐渐的学习按照其中去做。把文中的习惯和好的做法融入到自己写的代码中去但是很多时候总是找不得要领,有点邯郸学步,所以总是在想到的时候打开看一遍。

这次再读的时候觉得应该整理一下,以自己的方式记录出来,与大家分享交流,形成一个直观的概念。

编程的智慧表达了什么?

王垠老师提出过很多次的教条主义,这篇文章也是苦口婆心的说了一些编程的知识与技巧,我们可能在编程的时候没有那么多的创新与自己的见解,但是我们应该知道什么时候干什么不该干什么,这是编程的共识,也是编程的智慧。

反复推敲代码

反复回头推敲代码真的很有益处,我认为在写代码之前就应该想着怎么写,一般来说,想的时间占比70%,写的时间30%即可。而在调试完成之后,更要回过头推敲。

可能得以实现的功能你用了100行代码搞定了,但是回头来看可以删掉不少的代码,这就会渐渐的把我们的思路带到精简的阶段,会让我们的水平得到一个提升。

古人也说过,温故而知新,不仅是回头看代码,甚至是过段时间回过头看这个项目,可能都会有新的东西,这种感觉是难得的,不然每次看别人的留下的代码都会吐槽:卧槽这个傻逼写的什么代码了。

写优雅的代码

优雅在代码中也可以体现,这一点确实还是很有趣的,其实早就在很久之前,就听过雷军的一句话,写像诗一样的代码,我想这就是优雅的一方面了。

一面说到,我们书写的格式以及大体结构上需要整齐,有好的分支与传递,还有在嵌套或者缩进方面都需要注意。我相信好的结构可以使我们的理解更加清晰,也会让我们的逻辑更加紧密。

另一面就是我们写代码的时候,需要注意一些用法,比如使用if语句的时候,else分支里面有可能出现少量重复的代码,但是这样的结构却是更加严密的。

写模块化的代码

什么是模块化?大家都知道我发过很多模块化的文章,但是真正的模块化,并不是文本意义上的,而是逻辑意义上的。

精选汇总 | 模块化编程 也讲到了很多。这里最让我收获大的一句话就是:每个函数只做一件简单的事情

写可读的代码

每当我们看代码的时候,总是会说这个人写的代码连注释都没有,让人怎么看。或者这么多注释,表达的也不清晰或者错位了,可能让我们产生更大的误解了,不但没有更可读反而成了障碍。

所以注释不是主要原因,真正可读的代码体现在每个细节上面。王垠老师说到:真正优雅可读的代码,是几乎不需要注释的。这一点我可能还没体会到,有时候还是需要一些语言来辅助一下。

但是其说到各种命名、合理换行、局部变量的使用、把复杂的逻辑提取出去,做成帮助函数、把复杂的表达式提取出去,做成中间变量,这些思想与做法真的是难能可贵的。

写简单的代码

随着时代发展,语言也渐渐的变得丰富起来,也就是写法变得更多了,支持更多特性了,有些代码变得短小精悍了但是依然可以解决当前的问题,这些特性往往是一些难以直观理解的代码。

的确,丰富的特性在一些特殊的场合是很耐用的,但是我们不能盲目去追求,去标新立异并以此为荣。我们需要写简单的代码,免得在后续让整个逻辑看起来没问题实际上正是这种特性使我们变得模糊,比如这个少了花括号。

if (...) action1();

这个判断没使用{},可是这其实经常引起奇怪的问题。比如,你后来想要加一句话action2()到这个 if 里面,于是你就把代码改成这样,不用说,这肯定是有问题的,而往往我们可以避免。

if (...) action1();action2();

写直观的代码

王垠老师说到:写代码有一条重要的原则:如果有更加直接,更加清晰的写法,就选择它,即使它看起来更长,更笨,也一样选择它

假如一段代码写出以下样式,你看得出想表达的是什么意思吗?

if (action1() || action2() && action3()) {...
}

这种写法是滥用了逻辑操作&&的短路特性,这种累加的判断会让人很费脑,而随着代码或者逻辑复杂度的增加,这样的代码就很容易出现错误了。其实很简单的就可以改成以下代码,会清晰很多。

if (!action1()) {if (action2()) {action3();}
}

写无懈可击的代码

无懈可击的代码其实是很难的,以前在上语文课的时候,老师说过好的诗句没有一个字是多余的,甚至没有哪一个字是可以替代的,但是代码不尽相同。

王垠老师想表达的应该是让代码不容易出现疏忽和漏洞,比如if语句分支最好考虑到极端状况,也就是说最好要有else,在里面处理一些东西。比如下面s缺省为 null,如果x<5,那么把它等于ok,如果不成立,你需要往上面看,才能知道s的值是什么。

String s = "";
if (x < 5) {s = "ok";
}

那么将代码改成下面的形式,虽然多打了两个字,然而它却更加清晰。

String s;
if (x < 5) {s = "ok";
} else {s = "";
}

正确处理错误

在异常出现的当时就作出处理,不要丢回给调用者。

这是给我印象最深的一句话,一旦有错误,就应该立即处理,即使是任何一种可能会出现的情况,都可能产生意想不到的灾难性结果。

我在项目中经常遇到这样的情况,为了赶项目进度,这种方法实现不了或者实现的不是那么灵活,就放任不管,而继续做下去。进度是赶上了,但是总会出现一些莫名其妙的错误,或者当需要更改一些功能的时候,这一块代码又出现问题了,你不得不重新去解决,所以不要逃避错误,每个错误都不容放过。

防止过度工程

只说三点,直击要害

  1. 先把眼前的问题解决掉,解决好,再考虑将来的扩展问题。

  2. 先写出可用的代码,反复推敲,再考虑是否需要重用的问题。

  3. 先写出可用,简单,明显没有 bug 的代码,再考虑测试的问题

Over engineering在我看来就是一个过度装逼的设计,我在工作中也遇到过这样的同事,一副架构师的样式指点江山,但实际上最重要的还是眼前的问题,解决掉!

最后

我认为王垠老师身上最让我缺少的就是:对权威以及先行者敢于质疑,对编程语言原理、框架、概念等等理解的深度,以及他的钻研精神,不论怎么样,我都收获了很多。

愿我们都可以看到他人的闪光点,同样的这篇《编程的智慧》真的值得我们好好读一下。

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号


点击“阅读原文”查看更多分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国外流行的五款免费在线图片编辑器评测

也许当你在度假的时候&#xff0c;不喜欢携带着你的笔记本电脑&#xff0c;但你在度假的时候一定会拍照。现在&#xff0c;你可以打理这些照片&#xff0c;甚至还可以在“网络咖啡屋”中进行一些高级的图像编辑。一些基于网络的照片编辑程序在去年逐渐兴起&#xff0c;大多是基…

void 型指针的高阶用法,你掌握了吗?

[导读] 要比较灵活的使用C语言实现一些高层级的框架时&#xff0c;需要掌握一些进阶编程技巧&#xff0c;这篇来谈谈void指针的一些妙用。测试环境采用 IAR for ARM 8.40.1推荐一首中文歌曲<<后来>>&#xff0c;英文翻唱<<life>>来自瑞典歌手Sofia Kal…

电子美图更新36张!

电子美图更新36张&#xff0c;下面请欣赏&#xff01;如果喜欢&#xff0c;请帮忙点“赞”和"在看"哦&#xff01;推荐阅读&#xff1a;专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号&#xff0c;后台回复「1024」获取学习资料网盘链接。欢迎点…

C#多线程JOIN方法初探

[说明&#xff1a;刚接触多线程时&#xff0c;弄不明白Join()的作用&#xff0c;查阅了三本书&#xff0c;都不明不白。后来经过自己的一番试验&#xff0c;终于弄清了Join()的本质。大家看看我这种写法是否易懂&#xff0c;是否真的写出了Join()的本质&#xff0c;多提宝贵意见…

STM32F0单片机快速入门八 聊聊 Coolie DMA

1.苦力 DMA世上本没有路&#xff0c;走的人多了&#xff0c;便成了路。世上本没有 DMA&#xff0c;需要搬运的数据多了&#xff0c;便有了 DMA。大多数同学应该没有在项目中用过这个东西&#xff0c;因为一般情况下也真不需要这个东西。在早期的单片机中也不存在DMA模块。再加上…

Python学习之==第三方模块的安装、模块导入

一、模块&包 1、模块 模块实质上就是一个Python文件&#xff0c;它是用来组织代码的。意思就是把Python代码写在里面&#xff0c;文件名就是模块的名称。例如&#xff1a;random.py&#xff0c;random就是模块的名称。 2、包 包又叫pageage&#xff0c;本质就是一个文件夹&…

操作系统中抢占式和非抢占式内核的区别

编排 | strongerHuang微信公众号 | 嵌入式专栏操作系统分为抢占式内核和非抢占式内核&#xff0c;通常RTOS都是抢占式内核。下面就来讲讲抢占式内核和非抢占式内核的内容。非抢占式内核非抢占式内核要求每个任务&#xff08;线程&#xff09;都做一些事情来明确放弃对 CPU 的控…

Python3——简单的TCP实例

Python3网络编程——简单的TCP实例 服务器&#xff1a;创建套接字——绑定服务器地址——监听连接——接受连接——数据接收/发送 客户端&#xff1a;创建套接字——连接服务器地址——数据接收/发送 """ server.py encode()/decode() """ fro…

UDP协议 sendto 和 recvfrom 浅析与示例

图片/在思考的樱木花道UDP&#xff08;user datagram protocol&#xff09;用户数据报协议&#xff0c;属于传输层。UDP是面向非连接的协议&#xff0c;它不与对方建立连接&#xff0c;而是直接把数据报发给对方。UDP无需建立类如三次握手的连接&#xff0c;使得通信效率很高。…

劝你要看一些有门槛的机会

最近发了很多招聘信息&#xff0c;招聘的岗位算不错的&#xff0c;但是投简历的人不多。我想起来刚开始工作那几年&#xff0c;工资虽然很低&#xff0c;但是也不怎么想鞠躬投简历&#xff0c;毕竟那个时候把面子这个事情看的比什么都重要。自己觉得自己有才&#xff0c;不过后…

Python3——简单的UDP实例

Python3——简单的UDP实例 服务器&#xff1a;创建套接字——绑定套接字——数据接收/发送 客户端&#xff1a;创建套接字——数据接收/发送 """ server.py encode()/decode() """ from socket import * from time import ctimeHOST PORT 11…

怎么得到自增列的下一个会插入的id

代码 1declareTable_namevarchar(60) 2setTable_namePay_inputpay; 3Selectso.name Table_name, --表名字4sc.name Iden_Column_name, --自增字段名字5ident_current(so.name) curr_value, --自增字段当前值6ident_incr(so.name) incr_value,…

ESP32,使用gitee搭建 ESP-IDF 开发框架

ESP32便宜&#xff0c;开发方便&#xff0c;非常适合初学者用来学习&#xff0c;之前我自己写的开发环境可能不再适合&#xff0c;推荐下面这篇文章。关于如何搭建ESP32的开发环境&#xff0c;乐鑫官方给出了很详细的教程和文档&#xff0c;基本上跟着官方教程来操作&#xff0…

jQuery的ajax技术

编辑本博客 ajax异步的JavaScript和html load() 从服务器加载数据&#xff0c;并把返回的数据放入备选元素中。这里加载回来的数据可以只有一个p标签&#xff0c;无需head元素等 $("selector").load(url,data,callback) url&#xff1a;必选&#xff0c;规定加载的ur…

Linux设备树的传递以及kernel中对设备树的解析

当U-Boot将设备树加载到内存指定位置后&#xff0c;ARM内核的SoC以通用寄存器r2来传递dtb在内存中的地址。kernel获取到该地址后对dtb文件做进一步的处理。#设备树的传递当使用bootm加载kernel镜像时&#xff08;bootz是对bootm的一种封装以及功能扩展&#xff0c;实质一样&…

常用shell命令

要复制整个目录&#xff0c;请使用 cp 命令的 -r 选项。例如&#xff0c;如果有一个名为 mydir 的目录&#xff0c;其中包含 myfile 和 newfile&#xff0c;则可以将该目录复制到一个名为 mydir2 的新目录。mydir2 还将包含 myfile 和 newfile 的副本。请使用以下命令&#xff…

Linux kernel之SMP初始化

01—SMP数据结构SMP的数据结构如下图所示&#xff0c;主要由2部分构成&#xff0c;通过两个宏定义CONFIG_SMP和CONFIG_HOT_PLUG来控制。当设置kernel支持SMP模式时&#xff0c;那么CONFIG_SMP选项是一定会打开的&#xff0c;因此第一部分是必须实现的内容。而第二部分是否需要实…

Python3——多线程之threading模块

Python3——多线程之threading模块 目录 Python3——多线程之threading模块 Threading模块的对象 Threading模块的Thread类 queue模块&#xff08;线程间通信&#xff09; Python 提供了多个模块来支持多线程编程&#xff0c;包括 thread、 threading 和 Queue 模块等。程…

MTK笔试1题~

这个题目是前几天一个好友分享给我的&#xff0c;但是因为时间原因没有及时写成文章。这是他参加MTK笔试的题目题目如下&#xff1a;网友提供的代码如下&#xff1a;#include "stdio.h"typedef struct n{int data;struct n* next;struct n* pre; }*pnode;int main(){…

Python3 —— 逗号分隔值CSV

Python3 —— 逗号分隔值CSV 目录 Python3 —— 逗号分隔值CSV CSV 读写CSV文件 CSV 逗号分隔值&#xff08; Comma-Separated Value&#xff0c; CSV&#xff09;。与专有的二进制文件格式截然不同&#xff0c; CSV 通常用于在电子表格软件和纯文本之间交互数据。CSV 文件…