编程中有哪些从一开始就值得坚持的好习惯?

此生再无相见时 提交于 2019-12-01 15:13:13

本文来自知乎上的同名问题,本文对优秀的回答进行了整理,解释权归答主所有,如有侵权请联系删除。

请大家各抒己见,为初学者提供参考。感谢各位。


Yul8ulY:

重视模块化,重视抽象但不滥用
我刚接触编程的时候,在网上看到许多大牛写程序都十分注重模块化,因此我就下意识的模仿他们;后来看SICP,知道了抽象的好处,因此在写程序的时候会仔细思考抽象的问题。这些对我都有着非常大的帮助。
在一篇讲述程序员代码行数瓶颈的博客中(程序员的成长和代码行数的关系)提到,程序员在2k行、20k行、200k行等若干程序规模时会遇到瓶颈,如果不用更科学有效的方法,超过了这个行数代码就会混乱到难以维护。但我第一次写很大的程序时(8k+)并没有感觉到文中提到的瓶颈;我目前接手的项目有近900k行,我自己写的部分也已经快上10k,但我仍然没遇到文中提到的瓶颈。
针对这一现象,我做过一些实验。我在很不认真的写一些小程序时,也总是写的混乱不堪,我发现,这种情况下,程序行数超过200行我就觉的很难受了,在需要进行一点小的修改时,我往往需要花很长时间去寻找到底该改哪里,十分吃力——这种吃力感是我在那些精心思考的大项目里从未感受过的。这说明了,我并没有过人的天赋能在混乱中轻易找出清晰的脉络,那就是说,之前的如鱼得水,是因为好的习惯。
后来,我进行了深入的思考。在模块划分合理、抽象合理的程序里,我可以简单的把一个个功能抽象为一个简单的黑盒,我不需要知道他们内部发生了什么复杂的反应,我只需要知道他们对什么样的输入会做出什么样的输出。这种抽象极大的减轻了大脑的负担,让我可以把精力更多的投入到真正需要考虑的地方。而那些混乱的程序里,我需要理清每一句话之间的关系,这无疑会极大的消耗脑力。这种情况下,200行就浑身难受就可以理解了——因为我用于维护项目关系所消耗的脑力已经远远大于了那些好程序里的消耗。
这个习惯,真的让人十分受益,请一定坚持。刚开始的时候,你或许觉得花很长时间去思考程序的模块划分、抽象层级是十分浪费时间的无用功;但久了以后,你就会感受到这种习惯带来的好处:它会在无声无息之间帮你消除掉许多瓶颈。而且还有额外的好处:当你习惯用模块
化组织你的思维时,思维能力也会有一定的增强。

李济深:

哈,这真是一个有意思的问题。
一些朋友说的比如尽早习惯做版本管理,一开始就形成良好的代码风格,我很赞同,另外一些朋友提到DRY原则,大括号对齐,甚至还有free(p);p=NULL;这样的建议,都是很容易误导人的,这里希望刚入门或者入门不久的朋友们学会独立思考,凡事打个问号,不要盲目遵循。
我个人觉得最重要的一个习惯其实有不止一个人说了,就是想清楚之后再动手。这里我稍微展开说一下,因为“想清楚”其实是一个很模糊的概念。怎样才算想清楚了呢?
我常常有这样的经历,对一个难题,经过了一番思考之后觉得自己想到了一个比其他人好得多的方法,结果去实现的时候,发现原来是想的时候疏漏的一个细节,方法不可行,感到很挫败,不得不回头过去重新审视问题,浪费了很多时间。
怎样才能想清楚呢?
Leslie Lamport在斯坦福做了一个讲座(底下有链接,推荐)。里面引用了一句话:“Writing is nature‘s way of let you know how sloppy your thinking is” 我深有同感。怎么才能知道自己是否想清楚了呢?最自然的方式就是写下来。怎么写呢?这个因人而异,比如我在编码之前,会在如下两个问题里面迭代几次。

  1. 做什么?(需求:白话)
  2. 怎么做?(方法:伪码)
    关于做什么,其实就是分析需求,这里跟那个“需求分析”过程有些区别。怎么舒服怎么来,大白话,不拘一格,理清楚问题就行。我通常的做法就是以自言自语自我审问的方式把整个过程理出来,为了不至于特别无聊,这部分通常会写得十分口语化。等这部分弄清楚之后,基本上伪代码的框架在心里面就有眉目了。接下来会尝试着写伪代码,写伪代码的途中通常会不断的进行重构或者跟第一步进行迭代,直到伪代码比较精简,逻辑上没有冗余的时候,就去喝杯咖啡,小个便,回来开始实现。实现的过程中难免会有需要回到第一个步或者第二步进行迭代的时候,随着经验的提升,迭代的次数会变得越来越少。
    实际上0,1两步我都是在代码的头部大块注释里面完成的,这个部分可以直接成为十分容易理解的文档。实际中除了这块注释,我几乎不在代码里面写注释。除了少数实现的trick外。
    另外刚才提到写伪代码,引出了一个潜在的问题:怎么写伪代码?建议不要尝试着用算法导论或者一些论文里面的方法。那些数学符号或者不容易敲打的符号会严重的影响写伪代码的快感。我觉得《The algorithm design manual》里面的伪代码格式就不错,但是因为实际中的伪代码可能比写一个算法复杂一些,所以还需要添加一些其他元素,比如我自己的伪代码格式其实有点像是Python代码。写伪代码的主要目的是弄清楚实现的逻辑。
    在第0步,其实不是每个人一开始都能写得清晰的,需要通过长期写作来锻炼。所以无论是写日记,写博客还是写情书,坚持下去,都能对日后写代码的能力有所帮助。
    时间不早了,最后再附送两个程序员生活小贴士:
  3. 做笔记,OneNote或者EverNote,把遇到的bug,看到过的好trick,好文章,好照片都记录下来。
  4. Eat your own dog food. 那些自己写过的可以抽离出来重用的代码或者脚本整理好同步到github或者bitbucket上去,不断增加和改善自己的dog food。
    Update 2015-07-22:评论里几个人提到free(p);p=NULL;是一个合理的建议。我想支撑这一点的理由是“悬空指针被复用的话很危险”。但是在你的程序里面每一个p都存在被复用的可能吗?并不是。所以每一次写下free(p)的时候就应该想这个问题。然后再考虑是否写p=NULL;因为害怕而写下的这些冗余代码会极度影响代码的美观,这也是我认为从free(p)到p=NULL不应该成为一个顺手的习惯的原因。---https://www.youtube.com/watch?v=6QsTfL-uXd8

闭嘴看我秀:

说一些基础的、适用于初学者的好习惯。

1.在开始编码之前先规划和组织代码

在项目的开始阶段,不要上手直接写代码,一定要先确定代码的分层和架构。该分层和架构在一定程度上决定了未来整个项目的代码风格和维护性,对于项目的长期维护,代码架构的设计是一件非常重要的事情。
代码架构可以提供更好的可读性和可维护性。大家可能还记得刚开始写代码的时候,所有的代码都会集中在一个文件,甚至一个函数中,比如

 

 

随着需求的增长,代码量的扩大,这样的代码是很难阅读和进行维护的,于是我们会使用重构的手段去让代码更便于维护和阅读:

 

 

进一步,我们将代码分散在不同的文件、文件夹中,通过良好的命名,我们甚至可以在不去看具体的代码实现的情况下,仅仅通过文件名就能判断出在做的事情:
│   main.c

├───job
│       first.c
│       second.c
│       third.c

└───other        
other file
就文件来说,可以从文件名上,分清哪些是头文件、哪些是源文件、哪些是第三方库、还有各种功能模块的细分等。
就代码来说,包括统一的命名风格,封装在同一个文件里的代码的相关性足够强等。
一个好的架构还应该尽可能的提高代码的可扩展性。
你要知道需求变更太TM正常了,新增需求也太TM正常了。因此好的架构,必须要考虑到这些情况的发生,因为他们是一定会发生的。所以,一定要避免把代码写死。

2. 避免大块重复代码,小块也不行

一个非常好的编程习惯是确保为代码创建函数或类,以便有时重用。当你的编码过程中多次出现重复的代码块,这样很臃肿、很鸡肋,你就应该想他们是否应该封装成一个函数或类。专门为可以反复使用的功能构建专用文件。例如,数据库调用(例如打开数据库连接,选择数据,插入数据,更新数据,删除数据和关闭连接)都应该转换为函数。通过不必重写冗余代码行,也会使你的工作变得更加容易。你需要做的就是调用该函数,简单、清洁、而且容易。
例如,以下是将记录插入MySQL数据库的PHP函数示例:

 

 

3 . 使用易于阅读的命名约定

无论你正在开发什么类型的代码,命名约定都很重要。你创建的变量名称,函数名称,类名称和任何其他程序名称越人性化,你后续的开发和引用就会越容易。因为所有代码并不都是同一天写的,而且一个项目往往由很多人共同参与,好的命名约定可以大大提高编码效率,还可以降低你在同事心中的傻逼程度。

 

 

4 .给代码多添加注释,即使它看起来很明显

就算它写在脸上,也一定要注释、注释、注释。因为当你正在处理代码的时候,它肯定是易懂的,不然你也写不出来这样的代码。但是,当你再次回到该代码时,你可能完全看不懂。而且这也会大大减轻同事的负担,换位思考一下,假如老大让你改一下同事A没有注释的代码,可能改一下只需要2个小时,看懂得两天,你心里肯定万匹草泥马奔腾。

特别是如果该代码中有大量嵌套元素。对这样的代码块的右括号进行注释也是一种好习惯。

 

 

5.在构建时测试和调试代码

每次创建代码块时,都应该对其进行测试和调试,以确保它正常工作。不要蒙头就是写,然后写完了之后在调试,避免为了找到错误而筛选数百或数千行代码。不仅需要在构建代码时测试和调试代码,还需要确保打开所有错误报告,以便在实际操作中实际查看错误。比如PHP,你还需要确保在php.ini文件或user.ini文件中打开这些设置,该文件通常位于根目录中。

 

6 - 实现版本控制系统

版本控制是编程的一个重要方面。当你构建一个简单的软件时,你可能不会在一开始就考虑版本控制。但是,随着时间的推移,你将需要改进该代码,无论它是什么类型的代码。而且,随着你的改进,你将需要跟踪你的版本。请记住,编程不只是编写代码行,你必须能够正确地组织代码并跟踪你的工作。
保留版本也是很好的,这样你就可以不时地检查一下,看看你在之前的版本中做了什么,或者可能带回你在先前版本中删除但现在想要重用部分的代码。这是一个很好的习惯。因此,你需要一个可以控制版本的工具比如git。

Ryan:

遇到不清楚或不懂的知识点,先去看官方文档!先!去!看!官方!!文档!!!!
很多官方文档是英文的,硬着头皮也要看!看着看着就习惯了。
刚开始读英文文档会费时间和精力,但是等你回过头来再看,你会觉得这才是最恰当的选择。为什么酱讲?
且不说你的英文水平得到提升(这是程序员无法回避的问题),耐性得到锻炼,什么叫官方文档?!两个痣:权威!准确!当你习惯了在百度上百度一些似是而非,似懂非懂的答案时,甚至有的文章观点完全不一样,你就会懂我在说什么了。当然,我并没有否认网上有好的答案和文章,我自己也经常看别人的博客。只是,作为初学者,你的水平很难去辨别一些文章,观点的好坏对错,而这可能会对你理解一些知识带来致命的误导!
所以,作为初学者,我们应该多读官方文档,不要浮躁,要知道任何成长都没有捷径!共勉。

坐家:

可能不算一个编程习惯,算一个工作习惯吧。
要懂得拒绝,要懂得说不(知道),也要懂得主动要工作。
拒绝的理由可以是:忙着呢;这块不归我负责;xx更加适合做这个;这个需要老大同意才能做 …….。这样你可以少做很多无关紧要的事情,专注于自己负责的或者感兴趣的工作上。
拒绝主要对普通同事,其他部门的要求,对老大不能随便拒绝,只能说不知道。
不知道的理由可以是:没做过啊;不熟悉啊;好久没碰这个了 ……。这样老大会给你更多时间,你可以把一件事情做好而不是做完。
主动要工作:当你不太忙或者当你手上的工作完成时间可预期的时候,向老大要工作。主动选择那些你负责的和你感兴趣的工作要。这样,当你拒绝和说不知道的时候,老大就不会觉得不爽了。  有些工作是很有趣的,你不要别人就会要走 :)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!