知乎热议:你见过最烂的代码长什么样子?

发布时间:2022-10-27 阅读 990

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:张铁岳 (西北大学)
邮箱1683421485@qq.com

编者按:本文整理自「知乎热议:你见过最烂代码是什么?」,特此致谢!


目录


1. 烂代码的特点

知乎网友 隆道尔的孙笑川 曾调侃道:

  • 世界上最简洁易懂的代码,是自己刚写出来的代码;
  • 世界上最烂的代码,就是自己一年前写出来的代码。

相信很多人都有这样的感受,在尝试自己编写代码时,总是忐忑不安,生怕出现错误。在编写代码的前期阶段,大多数人都抱着一个代码能够正常运行,自己能够看懂就可以的心态,忽略了代码的质量,这也为日后不良的编写习惯埋下种子。好的代码应该具有可读性强、命名规范和扩展性强等优点。

从以往的编写经历中,我们不难发现烂代码往往伴随着一些共同的问题,例如代码可读性差、代码繁琐不简洁、注释的错误使用等。本文将以 Stata 代码为例,来具体说明这些问题。

2. 代码的可读性差

好代码的一个必要条件就是要可读性强,能够清楚、整洁并且快速地阅读内容。而烂代码之所以可读性差,是因为在编写过程中没有遵循代码编写规范,从而导致代码不够整洁,不够清晰。造成代码混乱的常见的问题有:不恰当的定义变量名、不注意断句和断行、忽略缩进格式。

2.1 不恰当的变量命名

变量命名要尽量清晰,完整。即使采用缩写也需要精准的表示相对应的具体名字。

* 好的示范
sysuse "nlsw88",  clear
global y "wage"
global x "hours tenure married collgrad age"
* 坏的示范
sysuse "nlsw88",  clear
global y "w"
global x "h t m c a"

在对变量或函数进行命名时,不要把多种不同风格的命名放在一起,它会让你的代码显得异常混乱,并且容易让人对这些代码产生歧义。(知乎网友:程序员柠檬)

* 好的示范
sysuse auto.dta,  clear
help graph box
graph box price
graph box price, by(foreign)
graph box weight, by(foreign)
* 坏的示范
help graph box
graph box price
graph b price, by(foreign)
graph b_weight, by(foreign)
* 好的示范
sysuse "auto.dta", clear
gen lnprice = ln(price)
label var lnprice "ln(汽车价格-price)"
* 坏的示范
sysuse "auto.dta", clear
gen lnp = ln(price)
label var lnp "ln(汽车价格-price)"

2.2 不注意断句和断行

在编写代码的初期,大多数人都忽略了对代码断句和断行的处理,甚至完全没有断句和断行,导致代码过长,这大大降低了代码的可读性。

* 好的示范
sysuse "auto.dta", clear
tw scatter mpg weight
gr export mpg.png, height(500) width(500) replace
png2rtf using "mpg.doc", g(mpg.png) replace
 
eststo clear
_eststo mpg: reg mpg weight
_eststo pri: reg price weight
esttab mpg pri using mpg.doc, rtf     ///
       label nogap onecell mtitle a   ///
       title(\par Here is some text{\page}{\b A title})
scatter price weight
graph export price.png, height(500) width(500) replace
png2rtf using "mpg.doc", g(price.png) append
* 坏的示范
sysuse "auto.dta", clear
tw scatter mpg weight
gr export mpg.png, height(500) width(500) replace
png2rtf using "mpg.doc", g(mpg.png) replace
 
eststo clear
_eststo mpg: reg mpg weight
_eststo pri: reg price weight
esttab mpg pri using mpg.doc, rtf  label nogap onecell mtitle a ///
  title(\par Here is some text{\page}{\b A title}) ///
  scatter price weight graph export price.png,     ///
  height(500) width(500) replace png2rtf using "mpg.doc", ///
  g(price.png) append

2.3 忽略缩进格式

在代码编写过程中,缩进可以使得内容排列更加紧凑,在编辑器中占用更小的空间。但如果没有对代码进行规范的缩进处理,不仅会占用更多空间,还会让内容看起来更加复杂和混乱,从而降低代码的可读性。(知乎网友:程序员柠檬)

* 好的示范
sysuse lifeexp, clear

gen loggnp = log10(gnppc)
label var loggnp "人均GNP(Log10)"
label var lexp "期望寿命"

scatter lexp loggnp, ysca(alt titlegap(1.5))    ///
                 xsca(alt titlegap(0.8)) ///
                 xlabel(, grid gmax)     ///
                 ylabel(,angle(0))       ///
                 saving(yx, replace)
histogram lexp, percent xsca(alt reverse titlegap(0.8)) ///
            horiz xtitle(占比) ylabel(,angle(0)) ///
            saving(hy, replace)                  ///
                 fxsize(25)
histogram loggnp, percent ysca(alt reverse titlegap(1.5))  ///
              ytitle(占比) ylabel(,nogrid angle(0))  ///
              xscale(titlegap(2)) xlabel(,grid gmax) ///
              saving(hx, replace)                    ///
                 fysize(25)      
graph combine hy.gph yx.gph hx.gph,    ///
       hole(3) imargin(0 0 0 0)        ///
       graphregion(margin(l=12 r=12))  ///
       title("图1:期望寿命与人均 GNP")  ///
       subtitle(" ", size(*0.5))
       note("资料来源: 世界银行小组,1988")
* 坏的示范
sysuse lifeexp, clear

gen loggnp = log10(gnppc)
label var loggnp "人均GNP(Log10)"
label var lexp "期望寿命"

scatter lexp loggnp, ysca(alt titlegap(1.5)) ///
          xsca(alt titlegap(0.8)) ///
        xlabel(, grid gmax) ///
             ylabel(,angle(0)) ///
           saving(yx, replace)

histogram lexp, percent xsca(alt reverse titlegap(0.8)) ///
            horiz xtitle(占比) ylabel(,angle(0)) ///
          saving(hy, replace) ///
              fxsize(25)

histogram loggnp, percent ysca(alt reverse titlegap(1.5)) ///
            ytitle(占比) ylabel(,nogrid angle(0)) ///
               xscale(titlegap(2)) xlabel(,grid gmax) ///
             saving(hx, replace) ///
               fysize(25)      

graph combine hy.gph yx.gph hx.gph, ///
       hole(3) imargin(0 0 0 0) ///
        graphregion(margin(l=12 r=12)) ///
      title("图1:期望寿命与人均 GNP") ///
     subtitle(" ", size(*0.5))
         note("资料来源: 世界银行小组,1988")

3. 代码繁琐不简洁

很多人在编写代码的初期,稍有不慎就会把一个简单的问题变得异常复杂。例如,史上最烂代码出自著名游戏公司 RockStar 开发的线上游戏 GTA 5,登录游戏的加载过程中往往需要 20~30 分钟左右,这也让众多该游戏玩家叫苦不迭。其原因是在游戏的加载过程中,CPU 执行了大约 19.8 亿次 if 语句。(知乎网友:量子位)

* 好的示范
local j = 0
while `j'<5 {
   dis `j'
   local j = `j'+1
}
* 坏的示范
clear
set obs 5
gen a = _n
forvalues j = 1/5 {
  if a[`j'] < 5 {
  dis a[`j']
  }
}

4. 注释的错误使用

4.1 不写注释

一段好的代码除了需要清晰、整洁、并符合代码编写规范外,还需要对容易造成困惑的地方添加注释来帮助解读。

* 好的示范
// kdensity: Stata 官方命令 
// 比较不同子样本的密度函数 
sysuse "nlsw88.dta", clear
# delimit ; 
gen lnwage = ln(wage) ;
twoway (kdensity lnwage if 1.race)       // 绘制 race值为 1 (白色人种)的密度函数图   
       (kdensity lnwage if 2.race)       // 绘制 race值为 2 (黑色人种)的密度函数图    
       (kdensity lnwage if race!=3),     // 绘制 race值不为3 (所有人种)的密度函数图   
       subtitle("density of ln(wage)")   // 为绘制图形添加标题“ density of ln(wage) ”  
       legend(order(1 "White"            // 设置图例顺序  1为白色人种
                    2 "Black"            //              2为黑色人种 
                    3 "All")             //              3为所有人 
              ring(0) pos(3) col(1))     // 图例格式: 图表内部、在3点位置、一列 
              scheme(scientific);        // s1mono, white_tableau
# delimit cr
* 坏的示范
sysuse "nlsw88.dta", clear
# delimit ; 
gen lnwage = ln(wage) ;
twoway (kdensity lnwage if 1.race)       
       (kdensity lnwage if 2.race)         
       (kdensity lnwage if race!=3),     
       subtitle("density of ln(wage)")   
       legend(order(1 "White"           
                    2 "Black"            
                    3 "All")            
              ring(0) pos(3) col(1))   
              scheme(scientific);      
# delimit cr

4.2 用不同语言来添加注释

在注释中应尽可能选择母语,当然在有具体外语阅读人群的情况下,可以使用对应的语言注释。尽量不要使用对阅读群体造成阅读障碍的语言来添加注释。(知乎网友:程序员柠檬)

* 好的示范
// 将 X 轴方向缩小为原始尺寸的 25%
// 将 y 轴方向缩小为原始尺寸的 25%
fxsize(25);
fysize(25);
* 坏的示范
// ลดทิศทางแกน X เป็น 25% ของขนาดดั้งเดิม ( 泰语 )
// ลดทิศทางแกน y เป็น 25% ของขนาดดั้งเดิม ( 泰语 )
fxsize(25);
fysize(25);

5. 结语

代码没有最好和最烂,代码质量的标准会随着我们每一个人的成长而不断发生变化。本文篇幅有限,只简单列举了几种常见的代码编写问题。希望我们能够吸取经验,在代码编写的过程中遵循好的代码编写规则,从而提高研究工作效率和质量,远离烂代码带给我们的困扰。

6. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 知乎热议, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh