如何提高代码能力?
写代码指的是将算法实现为程序代码,前提是你已经决定好了你要实现的算法,对代码能力的讨论应当在这一前提下。

代码能力包含写代码与调试代码两方面的能力。

写代码的能力
评价一个人写代码的能力自然是以其写代码的速度为标准,但这里的写代码的速度指的是一个人在写全新代码时的速度,而不是指他写旧有代码的速度。

譬如写线段树这个数据结构,基本上所有 OIers 都能炼到炉火纯青的地步,写一个线段树板子也只是手到拈来,5 分钟就能上百行,那么这就意味着他的写代码能力强吗?

未必,这只能说明他对线段树的记忆好。倘若是在写一道思维含量高的题,程序的每一步都是全新的,需要自己一步一步想,那么这就是在创造新代码,这时候他的写代码速度才能反映他的写代码的真实能力。

而不管是赛场上,还是以后工作中,社会所看重的肯定是创造新代码的能力,所以 OIers 在平时训练时就要注意锻炼自己创造新代码的速度。

当然 OIers 毕竟也要上赛场的,一些基本的板子,如线段树、树状数组、倍增等板子,肯定也要练到滚瓜烂熟,最起码的要求是在赛场上不需要编译运行也能保证完全正确。

在草稿纸上写代码
不过管是写哪种类型的代码,写代码之前都必须要在脑子里先过一遍,边写边想很可能写着写着发现算法有错误,之前写的那么多行代码就白写了,而且就算算法没有错误,也会大大增加打错字符的概率,为后续的代码调试增添负担。

在创造新代码时,大脑的思维负担是很高的,为了减少记忆负担,可以在草稿纸上写代码。著名的计算机科学家高德纳就一直坚持这个习惯,他在写任何代码前都要先用铅笔在草稿纸上写一遍,然后再搬到笔记本上。

高给其它人的解释是,人打字的速度远远快于思考的速度,边打边想会导致思维出现太多停顿,用笔写字则可以让输入与思考的速度保持一致,所以在纸上写代码的过程是最流畅的,也更容易从中发现算法上的一些小错误并及时改正。

当然,对于 OIers 来说,那些经过千锤百炼的板子代码就不必在草稿纸上过一遍了,在纸上写代码还是挺消耗时间的。

随着你的阅历增多,经验增长,对你来说,需要在纸上写的代码会越来越少,也越来越抽象和关键。这就意味着在纸上写下的代码不必严格遵循编程语言的语法规范或者伪代码的语法规范,能够简写一些步骤,只要自己看得懂就行,就像你在英语听说考试中不可能把听到的每个单词都完整地写在草稿纸上,你只可能记录下一些关键词,甚至连关键词都只记下首字母和尾字母。

先主后次
创造新的代码时,肯定有很多部分要实现,而实现的顺序应是从实现算法关键部分的代码开始,然后再是次要部分。至于哪一部分关键哪一部分次要就凭借你自个灵活判断啦。

多用 assert 语句

在程序的开头加上

#include <assert.h>
//#include 也行
然后就可以使用 assert 函数了。

它的作用是接受一个 bool 数据类型的参数,运行程序时,若该参数为 true 则什么事也不会发生,若该参数为 false 则程序会直接报错并告诉你触发了哪个 assert 语句。

比如现在要计算一个概率数组 {p_i}(1\le i\le n) ,其中 p_i 是第 i 个事件发生的概率,显然有 \sum_{i=0}^{n}p_i=1 ,所以若计算完了数组,可以用 assert 判断一下是否满足这个条件。

#include //fabs 函数需要通过这个库导入
double sum = 0;
for(int i = 1; i <= n; ++i){
sum += p[i];
}
assert(fabs(sum-1.0) <= 1e-5)
再比如调用某个函数时需要传入两个整数 L 和 R ,作为区间的左端点和右端点,因为肯定有 L\le R ,所以可以 assert。

void function(int L, int R){
assert(L <= R);
}
如果你的程序中已经出现了很多个 assert 语句,但又嫌手动删除它们太麻烦可以在 #include <assert.h> 前加入一个宏定义来使 assert 失效。

#define NDEBUG
#define <assert.h>
然后在 main 函数里加入 assert(false) 来判断 assert 是否确实失效。

养成随处写 assert 的习惯可以帮助你快速定位程序出错的地方,当然前提是若程序无误则 assert 一定不会报错。

调试代码的能力
调试代码的能力简直比写代码的能力还要重要,估计有不少 OIers 都有这样的经历,写出一份代码所花的时间可能只是十几分钟到一个小时,但调试代码的时间却数倍于前者,往往调试到最后,发现错误竟然只是写代码时粗心打错了几个字符。

调代码的过程主要是发现程序中的两种错误。

第一种是写代码时不可避免犯下的一些低级错误,如敲错字符,漏写语句,这种低级错误最让人头疼,也浪费了大量时间。

对付这种低级错误,最有效的方法是静态排错,即不运行代码,只通过看代码、分析代码来调试。

比如写完一道题目的代码后,不是立刻点编译运行的按钮,而是先浏览一遍自己代码,把程序的每一行语句都仔细检查一遍(即便是你写过千百遍的代码也可能出现小错误),像写完语文作文后检查自己有没有错别字一样。

OI 中的题目通常只需要 100~200 行的程序就能实现,所以浏览一遍整个程序所花费的精力和时间是可以接受的,基本上浏览完一遍后就能找出 70% 的低级错误,浏览两遍就能找出 95%。

第二种就是思维错误这类高级错误,这类错误的来源不是因为粗心所导致的打错符号,而是来源于算法上的错误,这类错误往往只是一些细枝末节的小问题,只要发现了,对算法稍加修改就能解决。

这类错误,以我的经验,比较难通过静态排错发现,因为你在静态排错中的大部分时候,只是在检查你写下的程序与你脑子里想的程序是否一致,而高级错误,是你脑子里想的程序的错误。

所以我在调试这些高级错误的时候,只会使用输出中间数据这一古老而低效的方法。

当然,如果不断提升静态排错的能力,使得能在检查程序的时候对一些细节进行演绎,那么也是可以发现高级错误的,这就需要凭借经验和积累了。

分模块架构
对于一些较复杂的程序,进行分模块肯定是能减轻思维负担的,要善于进行函数封装和 struct 封装,这不会使你的程序运行效率有多大降低,编译器往往会帮你完成绝大多数数优化,但这会使你架构代码和写代码的速度显著提高。

\text{Debug} 流程
最后给一份我的 \text{Debug} 流程作为参考,希望能帮助到你。

(1)重新计算一遍程序的空间复杂度,确定你的程序所用到的各种数组的数据范围在,然后检查你的程序当中设置的常量、宏定义常量、声明数组时的大小是否能应对极限数据。

(2)静态排错:写完程序后先扫视一遍每一行代码、每一个字符,处理敲错、敲漏字符等低级错误,确保敲出来的程序与脑子里想的程序一致。

(3)运行程序,检查能否过大样例、对拍。如果没问题则万事大吉,如果有问题,再次进行静态排错,并增加注意事项(4)、(5),因此第二次静态排错会比第一次静态排错要耗时。

(4)浏览每个函数(包括全局函数、结构体内的函数)时,思考运行程序时参数的数据范围,然后对你的代码在所有可能的参数组合下进行演绎,确保你的代码都能正确且符合预期效率地完成任务。

(5)思考每个函数运行时的抽象意义,即它完成的任务是什么,如果这个函数有返回值,思考这个返回值的意义,并审视一遍这个计算这个返回值的每一个细节,检查自己有没有出现思维错误。

比方说某一个函数,给定 w ,要求统计 x<w 和 x=w 的 x 的数目,通过 pair<int,int> 返回,但因为做大部分题时计算的贡献都是 x\le w 以及在这个任务下同时存在符号 < 与符号 = 带来的干扰,潜意识里认为第一项计算的是 x\le w ,认为这个函数该返回的是 x\le w 和 x=w 的 x 的数目。

此外还要检查对于数据的计算过程有没有爆 int 或爆 long long。

若某一函数过于复杂——包含不同阶段的任务(比如 main),则每一阶段的任务应当视作独立的一个函数,并演绎不同阶段任务之间的衔接。

(6)如果上述流程都没成功帮助你通过大样例和对拍,那你所犯下的错误一定是算法上的错误,对于这种不幸,只有最古老而传统的方法——输出中间值是你最后的救命稻草了(本质上断点调试也是输出中间值),即通过小样例或对拍找一组让你的程序出错的小规模数据(如 n\le 10,w\le10 ),人工模拟程序的运行并发现错误所在。

输出中间值能发现 \text{100%} 的错误,但你可能会(尤其对于数据结构题)花费数倍于想算法和写代码的时间来调试。不到万不得已就不要用输出中间值,如果通过输出中间值调试,最后调出的 \text{Bug} 还是一些敲错字符、小思维错误的话既浪费生命(不会从调试中收获什么),也打击自信心。

如何提升自己写代码的能力相关推荐

  1. 怎么提升写代码的能力

    作者 | 毕玄 来源|阿里巴巴云原生公众号 对于程序员而言,我始终认为代码是展现能力的关键,一个优秀程序员写的代码,和一个普通程序员写的代码是很容易看出差别的,代码作为程序员的硬实力和名片的展示,怎么 ...

  2. 马斯克的这波神操作,让我意识到保持写代码的能力有多重要

    作为一个在IT行业摸爬滚打了多年的老油条,我是越来越看不懂现在的互联网行业了. 至少曾经我听过太多人吐槽写代码的永远干不过写PPT的,并且在现实工作中验证过也确实如此,但是老马的这一波骚操作,让推特工 ...

  3. linux中pss用法,使用 pss 提升你的代码搜索能力 | Linux 中国

    原标题:使用 pss 提升你的代码搜索能力 | Linux 中国 搜索代码库是开发者每天都要做的事情.从修改 bug 到学习新代码,或者查看如何调用某个 API,能快速在代码库中导航的能力都是一大助力 ...

  4. 怎么提升个人的代码编写能力

    一.先列三个常见的开发场景: 1.拿到一个模块详细设计文档,大部分程序员的通常做法就是开始搭建界面代码,然后从第一个按钮点击事件或页面Load事件开始写第一行业务代码.写的差不多了,就运行一下,发现哪 ...

  5. 程序员自我修练-提高写代码的能力

    首先让我们看一看刚入软件公司会出现的情况: 1. 你可能会常常发现,写了一段代码后,编译程序时是一大堆的出错 (原因:语法不熟) ──别担心,这是每个程序员必须经历的事,这时候你就需要更大的耐心及细心 ...

  6. 为什么 CTO、技术总监、架构师都不写代码,还这么牛?

    作者| Mr.K   整理| Emma 来源| 技术领导力(ID:jishulingdaoli) 常常会被问到这样的问题:CTO.技术总监.架构师很少写具体代码,为什么还很牛逼的样子,拿这么高工资? ...

  7. #为何程序员百万年薪,CTO技术总监架构师不写代码还这么牛逼 ?

    [此文章转自乐字节] 真的是一点不服气我的领导,每天就在座位上看看头条,到时间开开会,每天写代码的时间可能不到两小时,到底是为什么他的收入有年薪百万?我们都是985研究生毕业,是什么铸就了他的价值? ...

  8. 为什么CTO、总监、架构师都不写代码,还这么牛逼?

    见字如面,我是军哥! 常常会被问到这样的问题:CTO.技术总监.架构师很少写具体代码,为什么还很牛逼的样子,拿这么高工资? 其实,这个问题本身就错了.就好比问:导演.制片人为什么不懂演戏,还能指导演员 ...

  9. 为什么CTO、技术总监、架构师都不写代码,还这么牛逼?

    常常会被问到这样的问题:CTO.技术总监.架构师很少写具体代码,为什么还很牛逼的样子,拿这么高工资? 其实,这个问题本身就错了.就好比问:导演.制片人为什么不懂演戏,还能指导演员,好像比演员厉害似的? ...

  10. 为什么 CTO 不写代码,还这么牛逼?

    见字如面,我是军哥! 各位周末好呀! 经常有读者问我,为什么 CTO 不写代码,还这么牛逼?拿那么高工资? 其实,这个问题本身就错了.就好比问:导演不会演戏,还能指导演员,好像比演员厉害似的?其实不难 ...

最新文章

  1. web前端培训分享:面向对象中类和对象的定义是什么?
  2. 解决transition动画与display冲突的几种方法
  3. vba 窗体单选框怎么传回sub_VBA之EXCEL应用
  4. Ubuntu 16.04下ASP.NET Core+ MySql + Dapper在 Jexus、nginx 下的简单测试
  5. 导出sql文件_(一)SQL基本知识
  6. continue 与break 的区别
  7. python asyncio 高并发_python-将asyncio与多处理结合起来会出现什么样的问题(如果有)?...
  8. intellij idea设置代码提示不区分大小写
  9. android 电视安装apk,给一切安卓智能电视安装第三方软件市场
  10. 两块stm32仿真protues串口通信程序
  11. 《自己动手写网络爬虫》笔记6-使用布隆过滤器实现Visited表
  12. Excel如何将两列数据左右调换位置
  13. C语言printf按二进制输出整数
  14. 近两年最快上市房企,祥生控股究竟是在控制负债,还是饮鸩止渴?
  15. JAVAScript:mobile端,基于transform-origin和tranform(scale),实现表格缩放
  16. tcl/tk实例详解——eval
  17. 华硕电脑显示电源已连接未充电解决方法
  18. Kali linux查看局域网内其他用户的输入信息
  19. 计算机xp系统是什么意思,什么是xp系统-xp系统是什么?电脑上的系统xp的 爱问知识人...
  20. python+django+Vue社区医院管理服务系统

热门文章

  1. Moss到底算不算叛逃?
  2. 【Python】日期处理-中国法定节假日
  3. html添加右键菜单,JS添加右键菜单
  4. 购买服务器 架设代理服务器 Android studio设置代理
  5. 巨潮网怎么下载年报_如何下载上市公司的年度报告
  6. USB驱动——键盘驱动(控制传输)
  7. 使用Fiddler抓取安卓手机APP链接
  8. Oracle 增加USERS表空间
  9. 036--python--摇骰子游戏
  10. 3dMax 导出材质球