当前位置: 华文星空 > 知识

开始慢慢抄代码敲对自己编程提高有用吗?

2020-04-15知识

没用。和太平洋小岛上那些戴着木头做的耳机型祭祀用品叽里咕噜想把神灵的大铁鸟喊下来一样滑稽。

学习编程照着别人的代码敲进去有效率吗?

真想学的话,建议你买个便宜机械表拆了,或者买点电子元件自己焊个收音机,彻底搞明白它们是怎么工作的。

不会编程、没有思路,多半是因为你压根不会活用知识,理解不了机械/电子产品的工作原理,不知道自己学过的物理数学化学知识是怎么应用于电磁炉微波炉电视机里面的。

缺了这个理解,所以你看什么都是咒语的堆砌。所以你抄/背这玩意儿不会有半点用:

拧你面前的圆盘子!右边!快!90°!
保持!保持!
圆盘子拧回来!180°!
脚!右脚!从现在的位置向左挪10厘米,踩!快!快!
圆盘子下面有个钥匙,逆时针拧。拧到拧不动。
右边,中间,看见那个向前的把手了吗?拉起来!
下车,跟着警察叔叔走。

因为程序是执行过程的 抽象 。它离具体动作太近,离思想太远。所以跟着上面那些咒语你只会跳大神,绝对不可能学会开车。

离具体执行过程远点,真正理解了它,上面一大堆就精简为如下几句话:

圆盘子是方向盘。
旋转方向盘就可以让车辆向对应方向转弯。
有人过马路,要踩刹车避让。刹车是油门左边紧挨着那个。
如果撞到人了,停车,熄火,拉手刹,等警察带走。

程序其实隔的更远。它可能是这样:

select_port(197);
out(90);
select_port(198);
out(1);
select_port(199);
out(5);

翻译过来是:

197号端口接了个电机控制板,这是它的第一个控制寄存器。它控制的电机和方向盘相连。
对它输出90,它就旋转90圈,一圈对应方向盘转动1°。
这两句对应「拧你面前的圆盘子」。

198号端口接着电机控制板的第二个寄存器。
对它输出1,意思是动作要在1秒内完成。
这两句对应「快!快!」。

199号端口接电机控制板的第三个寄存器。
对它输出5,意思是动作执行后锁死电机,保持5秒,避免方向盘回转。
这两句对应「保持!保持!」。

现在,告诉我,你抄这堆鬼画符,能抄到什么?

select_port(197);
out(90);
select_port(198);
out(1);
select_port(199);
out(5);

背下来?

下次我把电机接网线上,ip 192.168.1.7,你怎么办?

控制字?没了。现在我把这个丢给下位机,你发个报文,内容是「turn 75, left, fastest」就好。车辆会左转到和现有路线成75°夹角的方向,以最快速度。具体执行细节在下位机上。

你看,随便你背多少,是不是全没用了?

想有用,你必须理解这个电动小车究竟是怎么一回事;加速你应该控制哪个电机;倒车、转弯、装卸,刹车,以此类推。

理解了这个东西,然后你再编程,发电信号过去,触发这些动作。这才是正确过程。

换句话说,编码是具体执行细节,是因地制宜的东西——是跟着环境、需求甚至个人习惯不停变动的东西。

背这个,就好像太平洋岛屿的土人考证「呼唤大铁鸟需要抠几下鼻子」一样,完全是扯淡。

想理解它,你恰恰必须站的足够高、离的足够远,直到你可以用人类语言去描述它的机制为止。

然后,程序是另一套机制,它把模糊的人类语言翻译成具体细致的执行动作——把手指从鼻孔拿出来,取纸巾擦擦,换一档,松离开,起步!

你背这个,晕不晕?迂不迂?

你没抠鼻子,起步也必须先抠下鼻子,纸巾擦擦?不然不能挂挡?

高速上,你朋友问到你家怎么走,你也伸手指掏鼻孔,摸张纸巾擦擦,从后排伸手给人家挂个二档?

金牌教练都这么教的?你照做了居然会挨打?

打的好。

你猜正规公司为何忌讳从网上拷贝代码?

哪怕你照着一行行抄进自己的工程,都比拷贝黏贴靠谱。起码该公司的考核可以保证你看得懂代码;然后,你就能在一行行的输入过程中,发现其中某几句不符合你所在公司的软件环境。

而一旦换了环境,原本0 warning 0 error 0 bug的代码,或许连基本功能都会牛头不对马嘴。

国外统计显示,近年来各公司软件质量明显下降。因为从StackOverflow等网站拷贝代码的现象越来越多。

类似的,算法看不懂,一行行抄代码是行不通的。你得真正理解算法的思路,理解每行代码究竟干了什么、究竟和整个内存环境、整个计算机有着哪些互动——术语叫side effect。

前者其实是初中知识——本科阶段的算法也就这点水平,考你语文能力(阅读理解)和基本的逻辑知识。

后者其实是X语言编程的基础知识——你是不是真的在学X编程语言时,自己敲过代码?是不是真的做过每章习题?如果做过,你自然就明白了程序语句的作用和能力;等学到算法与数据结构时,你会觉得那本书的内容,大部分你自己都想到了。

中学知识死记硬背、满是夹生饭,所以理解不了钟表收音机等各种器物的工作原理;编程语言满是夹生饭,死记硬背for/while/i+++++i,连个普通的日程管理/日历/排课程序都不会写——现在突然让你学算法,你不懵逼才怪。

那么,究竟是因为什么,让你学不会编程呢?要如何针对性的训练?

要回答「为什么学不会编程」,首先你必须先学会编程。那些「考前突击混过数据结构考试」的憨批是教不会你的,因为他自己都不会。

光会还不行,你还得学的比较好,起码得是个职业程序员——码农趁早别发言。教人一碗水你起码得有一桶水。半瓶子咣当的怎么敢来?

学编程,无非两个难点:

一是 思路

思路是最难的。你必须极为了解各种事物背后的原理,了解到能用数学语言表达出来的程度。

二是「 如何把思路塞进编程语言语法的套子 」。

注意,你得先有思路,然后像调遣手下的战士一样,安排编程语言提供的指令们各就各位,把你的思路分片包干、执行下去。

编程语法这类东西太浅,看一遍书就应该完全能理解的。全都小学知识。

当然,理解了不等于就能运行。因为格式太死板,一点不能错——很多人学不会编程,就是学偏到死记硬背规则/格式上了。比如什么short是几个字节、每个字节几个位;或者if后面应该是圆括号还是中括号;或者print里面有哪些符号、参数代换规则是什么之类。

这些东西自然是必须熟练掌握的。但根本 不需要死记硬背 大概理解是什么意思 ,多敲程序,就好像玩游戏一样,不知不觉一切细枝末节就都牢牢记住了。

记住它的意义,大概在于证明你的确上机敲过不少程序;另外就是键盘输入效率更高、更容易一次敲对,不需要频频翻资料对照格式,不会遇到语法错误茫然失措。但它并不影响你设计程序。

重复一遍: 设计程序的思路,并不受语法格式影响 。无非就是你先理清思路、然后想办法把这个思路塞进语法的套子里罢了。

换句话说,第二点其实并不难。但需要大量的练习。

编程最难的地方还是思路,没有思路,就好像突然让你去打仗;结果你看着一排排大头兵,连自己要做什么都不知道,怎么给它们安排任务?

那么, 思路是怎么来的

从看得见摸得着的开始。

你有个远方结识朋友来找你玩,但你不在家,得几个小时后才能回去。所以你需要通过文字信息给他指个路,让他到你家门前的咖啡厅等着。

请问,你该如何编写这条信息?你需要他理解哪些东西,才能确保他找到正确地方?

1、首先你得知道你家在哪。或者说, 确定一个目标

连目标都没有,思路可能存在吗

——你写个程序!
什么程序?
——我怎么知道!快写!
那我写个hello world?
——别写那种逗小孩玩的!写个牛逼点的!
写什么?
——我怎么知道!

嗯,你说这程序该怎么写。

因此,你必须给自己一个明确的目标。

2、你是怎么找到你家的?

哎呀我说不清,反正闭着眼睛就走到了……
嗯……那我回去了。反正我闭着眼睛走不到你家。
别!我想想办法……

有了。第一步,先找个公交站台,坐车到……对了你得先告诉我站名……哎呀太复杂了。你看站台上的说明,随便找个公交车,先到火车站!
到了火车站怎么办?
坐101路车,到XX中路XX学院站下车。
然后?
到街对面,沿刚才101路车前进方向走50米,进XX胡同。
继续?
进胡同一直往前走,走到一个丁字路口,左转,20米就到了。

没错。这就是思路。这就是算法。

3、有思路了,现在就可以写成程序。

3.1、找公交站台

3.2、找一辆目的地是火车站的公交车

3.3、上车,去火车站

3.4、听语音播报,if(站名==火车站) then 下车 else 在车厢里呆着 endif

3.5、火车站下车后,找到101路车站台,上车

3.6、

while ( true ) { input ( "输入公交站名" , & station ); //不是C标准函数。我故意的。自己想法封装去。基础知识而已。 if ( station == "XX中路XX学院站" ) { //c里面没法直接用==比较字符串。自己想办法解决。 break ; } } // 下车,然后按指示走到地方

4、现在,轮到你给你同学指路了。

别抄我上面的。没用。我家又不是你家——何况还是我随口杜撰的案例。

但是,领会了思路,这事还有那么难吗?

你看,就这么点东西。

类似的,数据结构与算法讲的是什么?

一些比较难的、一般人一下子想不出解法的问题的解决思路——有了思路,你自己写出代码。

不仅如此,它还要告诉你,这些思路好不好、为什么、如何评判——冒泡法时间复杂度⊙(N^2),空间复杂度⊙(1),快排时间复杂度⊙(N X logN),等等。

学了这些进阶知识,今后你调兵遣将就必须有章法——你不光要能写出程序,还要能说出其复杂度、甚至证明你的算法已经是这个问题的最佳解法。起码复杂度不能高一个级别,业界通用实现O(N)你弄成O(N^2),乐子可就大了。丢本科生的人!

所以,你 学不会编程的根本原因 在哪呢?

第一,你 是不是真的指挥过你的士兵

如果你连它们是火枪兵还是藤牌军、或者是步坦协同的近代军队、空地协同的现代化精锐部队都不知道,你能正确指挥它们吗?

没错。if/else/while/for/ class,这些就是你的兵。

它们是你 未来几十年生涯里的唯一依靠 ,是你最为忠心耿耿的近卫队。

你一定得经常和它们玩,尽可能的挖掘它们的极限,直到能够如臂使指。

如果你只是为了混过考试死记硬背过一点东西、连差遣它们帮你提醒一下女朋友生日的尝试都没有……

该干嘛干嘛去吧。你根本就不该学这一行。

真想入这行,从现在开始,操练你的兵。从女朋友生日提醒、到写给女朋友玩的萌萌哒的沙雕小游戏,你都要亲历亲为,一行行的自己想出来——你必须和你的亲兵吃住都在一起,熟悉它们每个人,它们才会为你效死力。

这是最朴实,但也是程序员 最重要 的技能。是你的 立身之本

第二,在一的基础上,你是否真正看懂了别人的调兵思路。

比如,给你一组数字,让你排序。

不要看书,你会怎么排?写个程序验证下你的想法是否可行。

注意,一定要先想出思路、并把程序写出来,确保结果正确。

然后,看书,看看别人的算法是什么思路。是他的思路好,还是你的思路好?为什么?

你能不能学会评估一个算法的好坏?

现在,你是否发现,所谓算法,其实就是简单的物理原理(冒泡)、数学知识(辗转相除法)?

没错,过去你学过的物理、数学、化学知识,它们背后的原理,也全都是你忠心耿耿的得力下属。

那些编程水平很高的程序员是怎么训练出来的?

它们,就是你的思路。

如你所见,这两个重点,全都没有抄代码的位置——背代码更是愚不可及。还是那句话,我家又不是你家。你背它有什么意义?

尤其是第二个重点,它完全是在考你过往知识的掌握程度,和计算机本身反而没太大关系——你中学的物理化学数理逻辑学的踏实不踏实?现在,开花结果的时候到了。

这就是我建议你「买个便宜钟表拆开揣摩揣摩原理」或者「买点散件焊个收音机」的原因——先学着把数学物理知识应用于现实,然后才能把它应用于计算机虚拟的数字世界(以前叫「建模」)。这就是算法的来源。

至于第一个问题,它很好解决。马上动手就行。

比如说,我们知道Windows有计划任务;但现在我们不要用它。

任务:

1、写一个程序,让它开机启动(网上有如何设置一个程序开机启动的教程)

2、查询你使用的语言的相关教程,看看怎么取当前时间

3、判断当前时间是不是你女朋友生日

4、如果是,播放一首歌曲(网上有教程)

5、如果不是,退出程序

除了标注网上有教程的,其它请自己解决。你有这个能力。

解决之后,如果意犹未尽,继续:

1、女朋友生日那天,不要只提醒一次;而是只要电脑开着,就每隔5分钟提示一次。

2、找找文件读写的示例程序;把程序改为「最多提示十次」,哪怕关机重启也不会重复提示。

3、继续修改为「每年女朋友生日提示十次,然后当年不再提醒;下一年女朋友生日继续提示十次,以此类推」。

4、考虑女朋友生日是农历的情况;把生日设置/是否农历做成可配置项(还记得那个文件读写示例吗?),或许你的室友也想拿它来讨好自己女朋友。试试看,能不能推销出去一份。

5、考虑女朋友生日是农历闰月,一年出现两次的情况

6、想办法测试你的程序是否能表现得如同你所希望的那样

这些你都能办到。你绝对有思路。只是你没有逼过自己而已。

如果连这点尝试都没有,你当然看什么都是天书。

还是那句话:编程从思路到实施,中间隔的比现实中其它的一切都远,远到不可避免的要丢失大量信息。

因此不要去记「圆盘子旋转多少度」,你必须反过来,自己主动:我要去哪里?路线已知,我该怎么指挥一辆车?指挥它的原理是什么?我该如何用这些基础设施体现我的意图?

你,永远是行为的发起者。你必须站在指挥者的角度看问题。你的兵只是在机械的执行你的一条条指令而已,它们并不知道你的战略意图。

因此,不要抄别人的代码。甚至,只要书本质量合格,看都不要看它的例程。像一个大头兵一样被指挥的团团转,这怎么可能教会你编程?

领会思路,然后自己动手指挥,这才能学到东西。

一旦你通过这种更为科学的手段解决了「编程无法入门」问题,你就会知道为什么我说那些鼓动你抄代码的家伙是「Cargo Cults」了——你不会指挥你的兵,所以你跟着电视里打仗的镜头,对着话筒大吼?这样能学会打仗?

换句话说,【X语言编程】这门课教你「步兵操典」,你本应该通过它学会调兵遣将。结果你不学,当咒语背,混过考试拉倒。

然后,【数据结构与算法】教你战役指挥法则,教你在旅团级作战会议上讨论作战方案——结果你基础不牢,完全无法理解,不得不吃力的死记硬背别人给下属打的电话?你能从中学到什么?

如果你还知道通过模仿这些调兵遣将的口令、把X语言编程这门课补上( 逆向可比按部就班学习难得多,充其量像很多人那样,四年学了个大一水平、还敢自鸣得意 );这虽然迟了点、而且方法也不对头, 通过逆向猜测去补课 毕竟事倍尚能功半 ;结果你居然是想继续用死记硬背来混过战役指挥考试?你觉得混过考试就是终极目的?

那么,等后来的操作系统原理、编译原理这些战略级别的、必需算法与数据结构为基础的课程,你又如何混过考核呢?

将来毕业了,让你上阵真刀真枪干时,你能行吗?

国内计算机系毕业生,起码90%以上可都干不了这行;好不容易凑合进去的,其中又有90%会在30岁/35岁遭遇职业危机——干了好多年,因为当年夹生饭太多一点长进没有,谁肯白养你?