程序员应该具备哪些良好的编程习惯?

news/2024/11/24 14:09:52/

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"!


培养一个好的编程习惯,能让你整个职业生涯收益。

例如,做好注释,方便自己也方便别人读懂代码;用科学的方法命名变量,而不是随心所欲;规范化测试,而不是拖到所有程序都完成再去测试,等等。

下面是一些值得坚持的好习惯,编程是个充满创意的工作,但同时也是细节决定成败的工作,你真正工作中可能80%的时间都在处理一些琐碎的问题。

所以,尽可能避免它们的频繁出现,会让你的职业生涯更轻松,也能更好的迈向成功。
一、技术层面
1. 初级技巧(技术细节)

1)我们知道在类C语言的编程语言中,int和bool是可以相互转换的。** 因此 a = 1 与 a == 1 都可以作为if的判别条件。很多新手会把“=”当成“==”,而这并不会引起报错。因此这种错误是比较难以发现的。一个小技巧是将判别条件写成:1 == a,这样如果误写为“=”,则会引起编译器的语法层面的报错,这样错误就会立刻被发现。

这个技巧只起到一个抛砖引玉的作用,编程语言种类繁多,但差不多每种语言里都能发现一些类似在类C语言中的这个技巧,这类技巧运用好了有时候能够节省大量时间。

2)善于利用位运算提高运行效率

在运算量较大的时候,善于运用位运算来代替一些普通的运算,往往可以起到提高代码效率的作用。例如,a * 2 可以写成 a << 1;再比如判断一个数字是否为奇数或偶数时,a & 1 要比 a % 2 的效率要高得多。
2. 中级技巧(代码的易读性)

1)空格的使用

很多新手程序员还没有体会到一个小小的空格作用能有多大:a=b+c 和 a = b + c ——— 对计算机来说这是一回事,但是对程序员来说却是完全两回事。当你面对成千上万行的代码要阅读时,你一定会感谢使用空格的程序员。

2)风格一致的代码

代码风格包括了代码本身的风格以及文件的命名。总之一切由你的手通过键盘写入到计算机里的东西,都应该保持一致的风格,包括文件名称、变量与函数名称、缩进等。这一点有经验的程序员一定深有体会,一致的代码风格不仅会方便你也会方便读你代码的人。

举个简单场景,你周围亲戚朋友有个两三岁的小孩,他说了两个字“gu hu”,每一个字你都听的很清楚,但由于音调和吐字的缘故很难第一时间就理解这两个字的具体含义,经过他妈妈的翻译之后,你恍然大悟:哦,原来说的是“姑父”。这就和风格不一的代码一样,你很难弄懂它的意思,要花费大量时间去解读敲代码的人的思维。

 3)命名要有含义

这一条不需要多解释,a = 1.2 和 price = 1.2 哪种更清晰一目了然。原则上,宁可让变量名或者函数名长一些,也不要起模糊的或没有含义的名字。

4)学会如何写注释

什么时候用注释,这是个古老的问题,它始终没有一个特定的标准。有这样一个说法:在一个健全的代码中,注释的部分应该是代码本身的二分之一到三分之二。小慕对这种说法不是很赞同,注释应该视情况而定,但这也说明了注释的重要性。永远不要相信,只要变量名函数名起得好,就不需要注释这种言论。

根据经验来说,在逻辑比较复杂的时候、容易踩坑的地方,注释是一定要写的。至于每个函数是不是都要写关于函数的返回值、参数这样的注释,要具体情况具体分析。如果项目要求你必须写,那无需多问;而如果项目没有这类硬性要求,那么对于那些经常被大家使用的较为复杂的函数,最好有注释。这样每个使用这个函数的人就可以通过注释很快明白如何使用这个函数。

另外,在一些函数体为空的地方,写一行注释也会起到积极的作用。比如:

void func () {}

void func ()

{

// nothing to do

}

当这两种写法出现在很多代码中时,很显然第二种写法要远好于第一种。

但是同时要注意,写注释也是有代价的。当你对代码进行修改时,相应的注释也要修改,这无形中就会增加工作量。如果你不小心忘记修改注释,那么很可能会让阅读代码的人产生困惑,也就是说:注释同样需要维护。因此切记不要滥用注释。
3. 高级技巧(debug)

1)用[控制变量法debug

很多新手往往意识不到一个事实:写代码本身并不会花太多时间,真正花时间的是debug。可以说,debug的速度可以直接反映出一个人的编程水平。debug的技巧,也许不同的程序员会有不同的经验之谈,不过真正能称得上是debug技巧的,只有两个:控制变量法 + 二分法。

所谓控制变量法,就是当面对多个不确定因素时,你要人为地修改这些因素,让不确定因素只剩下一个。请看这段代码:

if (func() < func2() && value > getSize())

{

// …

// …

}

当运行这段代码的时候,你发现本来不应该进入到这个if的情况下却进来了,此时需要找到问题所在。新手往往会觉得有点束手无策,因为这里有两个判断条件,到底是哪个出了问题?其实按照控制变量法去做,这样的debug会很容易被找到:我们只需要将一个条件暂时去掉,让程序执行,就可以立刻定位到错误的地方。

上面这个例子是一个真实的案例。其中,func和func2都是非常复杂的函数,而getSize()是朋友写好封装在库里的一个函数。bug是:value为-1而getSize()返回值是4的时候,居然执行了if里面的部分。其实bug的原因在于getSize的返回值类型是unsigned int,而-1是int类型,因此 -1 > 4 成了true。面对这样的bug,如果通过加断点的方式去逐步执行,那么依然需要花费很多时间才能找到这个错误。而如果把func() < func2() 先去掉,只留下后面的判断条件,那么立刻就可以定位到错误。

2)用二分法debug

面对大量代码出现bug时,想要在用极短的时间找到错误,就可以使用“二分法”。举个例子:

// a) 此处有1000行代码

// b) 你感觉bug大概在这个位置

// c) 此处有2000行代码

此时并不需要读懂a处和c处的代码,只需要读懂b处的代码即可。更准确地说,只需要知道b从a那里获取了什么、b给了c什么即可。

假设b处的代码依赖于a处代码所生成两个值,那么完全可以直接把a处的代码全部注释掉,而后模拟两个值给b,再运行,看看结果如何。如果bug依然存在,那就说明a处的代码没有问题 ——— 至少这个bug的源头不在a处;而如果bug消失了,则说明bug源自a处的代码。

比如:

int func ()

{

// 1000行代码

return x;

}

void func2 (int a)

{

// 2000行代码

}

int a = func()

// 改变了a的值

func2(a)

如果这段代码报错,最快的定位bug的方法是先模拟一个参数给func2,看看bug是否还在,如果bug还在,则说明func2有问题;反之,则说明问题出在之前的代码。新手们如果可以学会灵活运用这种方法去debug,相信很快就可以步入“老油条”的行列。

debug其实和找对象是同样的道理,要讲究方式方法,才能避免注孤生的命运。例如:

不要讲她听不懂的编程知识!

修电脑一定要跑去她家!

能区分女生说生气不理你了并不是真的不想理你!

……


二、工作、学习层面
1. 不断温故编程基础知识

 

对于事物而言,最基础的往往是最核心的。不断温故编程基础知识,理解编程的思维体系,知其然,知其所以然,才能运用的得心应手。才不会找了半天错误最后一拍脑袋:哦,原来在这出错了。

有个编程新手,前段时间写了一个代码,逻辑是这样的:一个超链接请求后台,但是点了链接之后,页面刷新,后台请求没有走到。他找了好久都没有发现问题。最后让资历较高的同事一看,他的A标签写的是这样的:

<a href="" οnclick="getUserInfo();"/>。于是改成了

<a href=”javascript:void(0)” οnclick=”getUserInfo();”/>。同事改完扭头就走,他这才恍然大悟。

 

2. 体系化罗列,碎片化整理

很多人说,自己高三那年是人生知识储备的巅峰时期,就是因为当时最主要的任务就是学习,每天反复背诵相关知识点。但是哪怕当时记得再清楚,随着时间的流逝,大学之后没有温故知新的话,很多东西就会慢慢遗忘。这就是人记忆的一个遗忘曲线。

对于编程,语言和技巧太多,指望过目不忘是不可能的事情。买一个笔记本,或者利用各种云端程序,体系化地罗列出自己的编程语言条目,条目下细分出详细的模块,平时工作、闲暇之际接触有优秀的观点、实用的技巧、深入的剖析原理都可以碎片化记录下来。这样可以方便平时翻阅,只要坚持一段时间,就会发现自己专业技术提升不少。其实也不仅仅是编程,在任何一个行业,没有不用付出就能登顶的天才。学习编程本身就需要时间和经验的积累,在勤奋的基础上,坚持良好的习惯和正确的方法论,成不成功不敢说,进步肯定会有的~


欢迎关注「慕课网」帐号,我们会一直坚持提供IT圈优质内容,分享干货知识,大家一起共同成长吧!
 


http://www.ppmy.cn/news/50811.html

相关文章

【22-23 春学期】AI作业4-无监督学习

K均值聚类 无监督学习的聚类算法&#xff0c;旨在将数据点分成K个不同的类别。在这个算法中&#xff0c;我们通过不断地迭代来优化每个数据点与其所属类别的距离。具体来说&#xff0c;它是一种判别式方法。 比较KNN与K-means 基于实例的学习方法&#xff0c;用于分类和回归。…

使用fwmark规则查路由表不通但直接配置静态ip rule可以的解决办法

最近在做组网时&#xff0c;有一个根据fwmark查不同路由表的需求&#xff0c;但是配好之后怎么也不通&#xff0c;找了好久才从这篇文章得知了问题所在 问题复现 针对路由表 $ ip route show table foreign default dev wg0 scope link配置如下规则 ip -4 rule add fwmark 2…

什么是AGI?

目录 前言一、什么是AI&#xff1f;二、什么是AGI&#xff1f;三、总结 前言 AGI和AI一字之差&#xff0c;它是什么&#xff1f; 一、什么是AI&#xff1f; AI&#xff08;Artificial Intelligence&#xff09;是指人工智能&#xff0c;是一种利用计算机和机器模拟、模仿或扩…

pinia的使用

介绍 一个拥有组合式 API 的 Vue 状态管理库主要是面向 Vue 3 的用户&#xff0c;除了安装和 SSR 两章之外&#xff0c;其余章节中提到的 API 均支持 Vue 2 和 VueDevtools 支持&#xff0c;追踪 actions、mutations 的时间线&#xff0c;在组件中展示它们所用到的 Store&…

rsync服务利用(端口:873)

目录 服务介绍 利用方法 任意文件下载 反弹shell 上传 id_rsa(用户名为sys_internal) 服务介绍 rsync

JAVA 类型的类型转换

JAVA 类型的类型转换 一、基本类型的类型转换 箭头开始的地方是小类型,箭头指向的地方是大类型 我们此处所指的"大"和"小",指的是对应类型的取值范围,不是字节数哦 1.1 小到大(隐式转换) byte m 120; int n m;//小转大,右面的m是小类型,给左面的n大…

Unity音量滑块沿弧形移动

一、音量滑块的移动 1、滑块在滑动的时候&#xff0c;其运动轨迹沿着大圆的弧边展开 2、滑块不能无限滑动&#xff0c;而是两端各有一个挡块&#xff0c;移动到挡块位置&#xff0c;则不能往下移动&#xff0c;但可以折回 3、鼠标悬停滑块时&#xff0c;给出音量值和操作提示 …

FWT学习笔记(快速沃尔什变换)

前言 首先&#xff0c;我们来看看多项式乘法。 f ( x ) a 0 a 1 x a 2 x 2 ⋯ a n x n f(x)a_0a_1xa_2x^2\dotsa_nx^n f(x)a0​a1​xa2​x2⋯an​xn g ( x ) b 0 b 1 x b 2 x 2 ⋯ b n x n g(x)b_0b_1xb_2x^2\dotsb_nx^n g(x)b0​b1​xb2​x2⋯bn​xn 而 h ( x ) …