有会编程的大神知道怎么改吗?

整合自网络信息,作者:小马儿

不记得从何时开始,自己就经常承担企业招聘的工作,侧重于工业嵌入式产品研发人员的招聘。

出于对企业和新人的负责态度,我倾向于寻觅那种基础知识扎实,且对嵌入式编程有兴趣的人员,这样对企业发展、对个人成长都有好处,可惜很多次都如同大海捞针,希望而来失望而归。

这是我很纠结的一个问题,不由得想起了曾经听过的一个故事:一个外国人来国内某公司考察,首先看到了职员的工作态度,狂吐槽,这样的员工企业应该全部裁掉;然后中午吃饭的时候,品尝了企业的午餐,又开始骂企业了。

回头看一看目前的大学教育模式,很多学校还是沿袭类似于初高中的填鸭式教育方式,大多数学生也是在吃喝玩乐混日子,即使大一新生还有些激情,很快就被大环境给污掉了。然后就是学生、学校和企业的互骂,搞得一片狼藉,戾气冲天。

一个要好的朋友在国内某985大学教计算机,一次和他聊天埋怨到,现在的学生入职后好长时间都没法上手,培训周期很长,然而朋友的观点是,这应该是理所当然的啊,大学能学点啥,都需要到企业才能锻炼的。无语……

真应该是这样吗?我很茫然,但看到每个学生背后为学费辛勤劳作的父母,看到他们对子女期望的眼神,我认为,我们可以做的更好,也应该做的更好。

为了让大家体会我内心纠结的心情,先简单的聊一聊招聘试题的事情。

以前我参加过中兴的招聘,招聘老师给我出了一道题目,int n = 3,4;我说我不知道,这是变态的用法,我们不应该这样用,您也不应该出这样的题目。可能当时年轻气盛,将招聘老师气了个半死,我当然也无缘中兴了。吸取以前的教训,后来我在组织招聘时,有一个基本原则,只有在工作中经常会用到的知识,才会作为考察的范围。

为了挖掘一些好的苗子,我们也一直在思考怎样的试题可以更好的考察出求职者的能力和兴趣。最开始的方式是先问一些基础课和专业基础课的基本概念,滤除基础知识不扎实的人;然后期望求职者能讲解一个自己曾经凭兴趣写过的程序,然后借着求职者的描述,然后不断的深入,以判断他的能力具体到了什么程度。

可惜,99%的人根本说不出自己凭兴趣写的程序,碰上几个胡诌的人,几句话就露馅了。后来只好雪藏该问题,然后降低难度,出一些单层循环,且每层循环适度判断的编程例子(如判断一个整数中0的个数等)。如果每次招聘,能碰上一两个将这类程序快速写出来的同学,大家都可以兴奋半天了。

这就是我们能招聘到的学生的普遍能力了,在我看来,要达到这个能力,只要随意的学习几天编程就可以了,还需要大学四年干嘛,让人郁闷啊。

但一个更加现实的问题是,这样的人招聘进来企业如何使用。我们不敢直接拿着产品让菜鸟人员练手,大家都知道,产品是要卖给用户的,初期的小问题到了用户那儿就会放大成大问题的。

企业培养不同于学校教育,不会有人给你填鸭式,更别指望有人手把手的教你,很多时候都是散养,顶多指点几句然后自己看书去。这种情况也导致了很多人初期很难上手,一些人甚至被迫转行,荒废了自己多年的专业方向。

如何快速过渡,结合自己多年的工作和新人培养经验,我总结了一套比较有效的方式,将产品研发需要的初级C语言知识巧妙的融入到三个例子中,让新人通过这三个例子去学习,去碰壁,去思考,持续的提高自己的C语言能力,尽快具备可参与产品研发的能力。

很多刚入职的新人,都喜欢问一个类似的问题:“如何学习……?”,然后一些朋友就会给拷贝一大堆书籍资料,更热心的还会指导先看哪本在看哪本。

但不幸的事,很多时候就截至于此了,一大堆资料依然静静的躺在电脑硬盘里,只是在偶然的情况下才会打开翻看两眼目录。

走过一些企业,培训体系一般是这样的:

1、新人入职后,师傅会给一堆资料让看,然后新人硬着头皮看一些;

2、哪天师傅不忙了,惦记起这个新人,然后交给其一个产品,让其折腾;

3、可惜具体产品一般都涉及多个学科,面对一大堆疑问,新人会感觉腾云驾雾般难以前行;4.一段时间后部分人迈过了入职时的绝望悬崖,有了自己的积累,开始慢慢的深入接触产品,但因各种文档资料奇缺,只能一边学习一边调整;

5、数年后,新人成为了老手,同时新的产品体系也诞生了;

6、然后重复以上死循环。

长此以往,公司的产品体系变得非常的杂乱,技术难以复用,无法进行有效的积累,那种如臂使指的团队构建更是空谈。

如何才能跳出上述死循环呢?我在自己的职业生涯中进行了大量的探索尝试,有了一点感悟:不仅需要将新人的培训工作尽可能前移,尽可能体系化,而且要尽早的融入我们的设计及团队理念。因此在后续的三个C语言例子中大家会体会到很多东西不仅仅是C语法层次的内容。

前面我谈到,在公司,不可能在重复学校的填鸭式的教育模式,也不会有人手把手的教你。那么在这种情况下,如何组织培训工作,很多时候反而成了一件颇具艺术感的选择难题。

随着移动互联网的盛行,在线教育也流行了起来,网络上出现了大量的视频教程。紧随时代的脉络,我尝试过将入职需要学习的内容做成书籍和视频,但效果一般。后来细细研究这个领域,发现大多数视频仅仅是将大学课堂的内容移到了网络上,很多人也仅仅是耐着性子看个几集,然后就不了了之了,因此导致的效果不佳。关于在线教育我也有一些自己的想法和思考,后面会专门撰文描述,这儿就不深入介绍了,总之,初期的尝试是不太成功的。

C语言第一个例子:需求不明确

第一个例子:“编写一个控制台程序,已知内层和外层菱形的高度,输出一个空心菱形”。

是否看上去很简单啊,写到这儿,很是期望正在阅读的你能先停下来,思考思考,然后付诸行动,编写几行代码小试一番,然后在继续读下去,收获会更大。

这些年,我带过很多人,大部分人看到这个题目后,然后立即就开始写程序去了,自己内心多少有点小小的失望,为何?

一般通过公司层层把关招聘进来的软件人员,这个例子总是可以弄出来的,不过可惜的是,近一半以上的人不能准确的实现出来,仅一个菱形高度的理解,就是五花八门,乱七八糟的,执行如这样的:

为何会出现这种情况,这恰恰是该例子的第一个大坑:需求不明确。一开始就碰到挫折,对很多新人来说,这无异于当头一棒,不过记忆也最为深刻。

一个团队协作时,会存在大量的交流,而交流过程中,总是会产生或多或少的歧义,而恰恰是这些歧义会导致需求的不明确,会导致大量的返工,甚至会导致项目的失败。我给新人的第一份建议:将需求用自己的语言表达出来,和对方确认后再实施。这一点在以后的团队协作中非常的重要,因此我早早的将这一点嵌入到了入职培训中。

经过这么一折腾,第一个例子重新描述如下:“写一个控制台程序,用户输入内层和外层菱形的高度,输出一个空心菱形,菱形的高度定义为菱形的上三角形的高度,如输入5和3,输出如下:

1、菱形高度定义好似有违常理,但在编程的世界中,简洁就是常理,如果定义为整个菱形高度,那么不仅需要进行正整数判断,而且还需要奇数判断,增加了程序的复杂度。

2.、用一个例子描述,比一大堆文字管用多了,是所谓一图顶千言。

明确知道要做什么了,然后很多人又回去,然而很多情况下执行结果如下所示:

这儿引出了第二个很重要的概念:边界判断。给出两个数,如何简洁且完备的判断其是合理的输入,这是编程的基本功,这些内容在大学教学过程中一般不太重视,但想做出合格的嵌入式产品,这一点必须引起足够的重视。如何做出优雅的边界判断,这个例子比较简单,留给正在阅读的你吧,顺便回头想一想我前面菱形高度的定义吧。

第二次被打道回府后,很多人会有急躁情绪,菱形还没输出呢,就给灌输了一堆规则。碰到这种情况,我会给他们讲解嵌入式程序的特点(这一点留待后文慢慢描述),以及我以前的经历。我刚开始工作时,因CPU速度受限,程序还主要是汇编语言,领导让写一小段汇编程序,但每次提交后,都被劈头盖脸的骂一通,让回去整改,直到后来一行汇编语句都省不下去了,才算通过了。回头看,为了一个小小的例子,竟然将大多数汇编指令熟悉了,方才明白领导的良苦用心。现在的新人脸皮薄了一些,不敢乱骂了,只好慢慢讲道理了。

经过第二次的折腾,大部分新人态度都能稍微端正起来,而且这次写出来的例子,和需求基本吻合了,但当兴致冲冲的跑过来交差时,我反而不看程序,开始问起在实现这个程序过程中用到的调试技巧。

这个例子对新人来说有一点点的难度,不可能一次就写好的,肯定会经历一些痛苦的调试过程。但是在国内的大学教育体系下,却又不太重视基本调试技能的锻炼,期望新人一开始意识到调试是一项基本功夫,需要引起足够的重视,需要去持续的加强。

雄关漫道真如铁,而今迈步从头越,一个小小的例子还未起步,对很多人已是一场痛苦的经历。要想成为一个合格的嵌入式工程师,需要方法,需要才智,更需要背后的汗水和坚持,本系列文章会带领大家体味我的成长路,但无法代替你自己的付出和汗水。

C语言第二个例子:边界判断

上文中,我提到由该例子引出了三个重要概念,其中第二个概念是:边界判断。给出两个数,如何完备且简洁的判断其是合理的输入,这是编程的基本功。很可惜的是,这几个例子都没有做到。结合自己多年带人的经验,这儿补充阐述一下。

输入两个数,一个是外菱形的高度(m表示),一个是内菱形的高度(n表示),有如下几个判据:

1、两个高度都应该是正整数(内菱形高度可以为0);

2、受限于屏幕的大小,菱形高度应该受限;

3、外菱形高度应该大于内菱形的高度。

以前带人的时候,拿到例程后,我喜欢先输入(1000,800)这样的值,因为这是容易被忽略的地方,很多人郁闷的铩羽而归。

大部分人都是缺判据,也有一些人性格比较谨慎,习惯写一大堆的判断条件,如下面这种的:

总之,都没有抓住判断条件应该完备且简洁的基本准则,实际上该例子很简单,只要简单的分析,判断条件也就三个,如下:

1、内菱形高度大于等于0;

2、外菱形高度小于约定之(假设30);

3、外菱形高度大于内菱形高度;

还记得第(1)节中我们约定菱形的高度是上三角形高度吗,带来的好处就是判断的简洁化,概念是为目标而服务的,不然该处的判断还需要额外的增加两条奇数判据了,简洁性也会打折扣了,呵呵,可以再回味一番。

在嵌入式产品中,最终产品的鲁棒性,很多时候就是表现在这样一点一滴的简单判据上,该处的不厌其烦,也是期望新人慢慢的融入研发团队时,能够充分意识到这一点。

终于要开始输出空心菱形了,但对于刚毕业的大学生,这个例子刚上手还是有一些绕的,其思维逻辑是如何的呢。

一般人都会发现,输出空心菱形要稍微复杂一些,那么我们修改为输出菱形呢,是否简单很多,如果还嫌复杂,修改为输出三角形呢。呵呵,说白了,就是将复杂的问题去其枝叶,先简后繁的慢慢处理。

一开始的问题就简单多了,已知三角形高度m,输出三角形,如m=5,输出如下:

为了直观,将空格也表示出来,示例如下:

此时,结论已经很形象了,每行输出的空格从m-1递减,每行输出的*从1开始递增,循环子为m,程序示例如下:

问题复杂化,考虑空心三角形,相当于里面又多了一个三角形,我们输出的时候,将其简单扣去即可,假设n=3,如下图示例:

进一步复杂化,输出完整的空心菱形,仅仅需要将上面的程序重复一下,仅仅是将其颠倒一下,且高度调整一下(减1处理,表达式更加复杂了)而已,我就不展示示例程序了,大家有兴趣的可以自己尝试一下。

有些人在实现该程序的时候,一开始就是对空心菱形进行分析,最直观的分析策略就是将菱形分层了三段,上三角形,下三角形,中间的空心部分,如下图示意:

按照这种思路,程序示意如下:

不管如何,至此,这个例程就算完成了,但大家有没有发现上面这些程序都谈不上优雅啊,其中各种m和n的表达式,一段时间以后看,基本同乱麻差不多了,试想,如果这是产品的程序,让后来人如何阅读并维护。

C语言第三个例子:简单粗暴的数字之美

优美,总是让人心醉,一提到优美,最容易想到的是悦目的图画,动听的乐章、精妙的诗文……。然而,数学,自然科学的皇后,却蕴含着比诗画更多的优美。

优雅的程序,或许其背后都蕴藏着数学的优美。

在上一节中描述的一些例子中,我们总是在努力的拼凑各种m和n的表达式,与其这样苦苦寻找,为何不直接将这个空心菱形放入坐标轴中呢。

在电脑屏幕上,人们习惯将靠右称之为x轴,靠下称之为y轴,将空心菱形画在屏幕上,示意如下:

然后通过解析几何知识勾勒空心菱形,程序示意如下:

我们将所有的判断都集中在了一起,阅读程序,很容易明白这个大大的判断语句是干嘛的了,是否比以前的实现都优雅了很多呢。

不过这个判据好像还是挺复杂的,有没有更好的办法呢,估计很多朋友在看到我上面的那幅图时已经想到了,那就是将坐标轴移到菱形的中间去,示意如下:

外菱形的四条边我们用表达式描述出来,如下:

合并后的表达式为:abs(x)+abs(y)<m,此时的程序示意如下:

不知大家看到这段代码是怎样的感觉,我仅记得当初自己发现这个实现后,第一次被这种简单的数学美给震撼了。如果大家也有相同的感觉,我坚信,你可以在编程的这条荆棘路上走很高很远…

C语言第五个例子:嵌入式C语言和桌面C语言差异巨大

在大学阶段,我学的是计算机专业,对编程的爱好聚焦在各种巧妙的算法和实现上。工作后,开始从事嵌入式产品开发,碰了N多的壁,吃了N多的苦,才明白了嵌入式C语言和桌面C语言是有差别的。

为了让新人尽快迈入嵌入式门槛,因此,今天,注定是一场批斗大会,经历波折,方能成长。

我们首先拿最优秀的实现开刀,在上一节最后,分享了一个很优美的实现,示例如下:

该实现将最复杂的条件判断置于两层循环之中,因此程序效率很低,而在嵌入式编程中,尤其是一些强实时模块,性能经常是紧绷着的弦。

工业嵌入式产品研发,追求团队作战,追求产品可维护性,追求性能和资源的均衡。可读性、可维护性、cpu计算能力、内存、可靠性等等东东都成为了资源,需要我们的庖丁解牛,经常,我们喜欢将工业嵌入式产品编程戏称为针尖上的舞蹈。

除了这一点,前面的程序还有很多的不足,举例如下:

1、整个程序经常混杂一谈,增加了他人阅读程序的复杂性;

2、m,n类似的名字,典型的学校风格;

3、各种复杂的m和n的表达式,一段时候后,估计自己看起来都头大了;

因此,我们需要继续上路,为了后续程序实现的方便,将整个程序结构约定如下:

看到这个程序框架,容易明白一点,我们要求以单层循环的方式输出菱形。

细细观察空心菱形的结构,每一行从左到右可以抽象为前导空格,左边星号,中间空格和右边星号四部分,只需要找出这四个值和行号的函数关系,整个程序也就迎刃而解了,如下图示意:

我的职业导师经常会和我探讨计算机编程思维的概念,时至今日,我们也没有办法给其下一个准确的定义,但在反复的迭代锻炼中,慢慢的体会到了哪些实现可以称之为计算机编程思维。

举一个例子,在计算机世界中,我们经常仅鼠标、键盘、磁盘、磁盘上的数据等等都称之为文件,可以进行简单的遍历。为何风牛马不相及的东西,我们非要将其抽象成统一的概念呢,这非一句话能描述清楚,后续会带着大家慢慢体悟,但这种设计思想在产品研发过程中,却比比皆是。

插入这两段废话后,回头再来看我们的菱形输出例子,明明每一行的结构不尽相同(回忆一下第二个实现版本,就是分类型分别输出的),但我们非要求同存异,或许,我期望从一开始,就在新人的心中播下架构设计的种子,期待着后续的萌芽。

虽然这儿的话题是以新人培训切入的,但未尝不是自己的成长之路,所不同的是我是在一次次的跌打滚爬中成长起来的。将自己曾经摔过的跟头融入到入职C语言训练的例子中,甚至将自己的整个成长史写出来,但愿别人能以我为镜,成长的更踏实更快速一些。

C语言第六个例子:嵌入式C语言和桌面C语言差异巨大

在上一节中,我们已约定了程序基本框架,并且也简单的介绍了编程思维的理念,好似,新人很快就可以写出合乎要求的程序了。

可惜,每个人的成长之路都不是一帆风顺的, 记得当初自己学习计算机编程时,哪个技能不是从大量的模仿中才能体悟一点点的,进而融入到自己的知识体系中的,一点一滴的成长起来的。

依据上一节的整体框架要求,我曾经带过的很多新人,甚至包含一些粉丝给我的发来的邮件,写出来的程序基本上都是新瓶装旧酒,仅是以前实现例子的翻版而已。

我给大家示意一下,大家体会体会,自己是否也有这样实现的冲动。

/* 循环输出菱形 */for(……){/* 输出前导空格 */if(上半菱形)以三角型方式输出;else以倒三角形方式输出;

/* 输出中间空格 */if(上半空心)以三角型方式输出;elseif(下半空心)以倒三角形方式输出;

注:该处的示例是结合第二个实现版本的,将一个菱形分为上三角形,下三角形,中间的空心三部分分别输出,详情请查看《入职C语言例子一(2)》。

应该如何实现呢?在上一节中,我们提到了重点在于寻找四个函数关系。文字的表现力经常是苍白的,给大家展现一幅我指导新人时的随意手绘图,或许,大家立即就明白了。

理解了上图,额外强调几点:

1、空心菱形的每一行都必须等同看待,忘记上三角、下三角、中间空心等这样的分割;

2、四个函数关系内部不允许出现if语句,但允许提炼公共函数,如abs类的;

3、成功没有捷径,技能的学习也没有捷径,将浮躁的心放下来;

走到这儿,很多人都写了七八遍了,拜目前的大学教育模式所赐,很多人又出现了浮躁情绪,即时的安抚还是很有必要的,经常打趣的一句话就是瞧瞧你的师兄xxx,别看现在负责好几款产品得心应手,当初还写了十多遍呢,哈哈。

实际上很多人也意识到了我这样折腾的目的。大学的学习都是浅尝辄止的,很多东西都急于求成,但将这种心态带入企业,带入产品研发中却是致命的,我仅是想通过这样的形式,让新人少走弯路。用心良苦,却常引来误解无数,内向者口是心非肚子里骂几句,张狂者会直接诘问我这样折腾他们有何意义,呵呵。

随意牢骚了几句人生坎坷路啊,经这样一指点,大部分人都可以按照要求顺利的完成该例子,虽然每一部分都是一个复杂的表达式。

此时,我会给大家讲解一个很关键的计算概念:迭代。

我们所从事的嵌入式产品是强实时工业产品,不仅经常涉及傅里叶等各种复杂计算,而且还要求在指定时间内完成,因此对计算效率等要求会比较高,最经常采取的策略就是通过迭代,保留有价值的中间计算结果,减少整体计算量。

而通过迭代,不仅各部分的表达式不至于那么的复杂,而且会减少计算量。该例子比较简单,没什么技术含量,大部分人很快的就完成了迭代的调整,但前后对比的效果却印象深刻,算是额外的收获吧。

至此,空心菱形程序的所有技术点都描述完毕了,按着这样的要求,大多数人可以写出满足要求的程序了。还是非常的建议正在阅读的你能亲自写一写,调一调,下一节我会贴出标准答案,大家可以在比对一下,而差异部分正好是我们后续内容的起点。

C语言第七个例子:不断完善心中的答案

前面几节中,列举了一个很优雅的实现,一些朋友提醒我该程序输出不正常,自己测试了一下,确实如此。

当时写程序时,是直接以文档的方式写的,一些例程也是小伙写的程序中拷贝出来的,重在意图表现,所有的程序代码都没有测试过,缺乏了严谨性,优化如下:

咱们书接上节,言归正传,在上一节中,新人磕磕碰碰的,终于写出了符合技术要求的程序,皆大欢喜,以为要完工了,可惜,路依旧漫漫。

此时,我会给大家分享该题目的标准答案,让大家同自己写的程序进行比对,以前的程序都是以片段方式提供的,标准答案以完整的格式提供,示意如下: 文件名称:diamond.c* 软件模块:空心菱形输出* 版 本 号:1.0* 生成日期:* 作 者:xiaomaer* 功 能:空心菱形输出,该程序占用内存小,但计算稍大,可修改为"内存换资源"算法*

不知正在阅读的你看到这个标准答案的感觉,能否寻找出和自己程序的差异的地方,下一节我们以此程序为起点,给大家介绍一些真实产品中的代码特点。

撇开大道理讲嵌入式代码

在上一节中,我们给出了标准答案,是以真实产品代码风格写的,期望小伙伴们能同自己的实现比较一下。

现在的90后是有个性的一代,很多人都非常反感直接的大道理灌输,鉴于此,我期望我们的小伙伴们能自己需寻找答案,然后大家在交流碰撞中成长,效果或许会更好一些。

这篇文章就让我们一起来找出标准答案中有价值的地方吧。

1. 有意义的变量命名

大学老师教编程的时候,重点精力都放在了语法方面,侧重于将所有的语法给大家展现一下(这种学习方法我相当不赞同,后续会展现自己的方法,项目组内俗称大树法则的方法),因此经常使用短小的程序展示语法,但因为程序短小,因此变量命名也就随意了一些,因此i,j,k,m,n就成了常客,然后不小心带入了产品中,然后……。

但在产品研发的时候,即使比较简单的设备,代码量也会比较大,为了代码阅读维护方便,有意义的名字就变得非常的重要了。在标准例子中,使用了nIn和nOut就是想用简单的英语单词表示内外菱形的高度。

一些朋友可能读过《可读代码的艺术》或《代码整洁之道》等书籍,作者强调使用准确的英文单词来表达特定含义。

但我们是中国人,能想起一些简单的单词词汇已经颇为不易,想准确表达更是天方夜谭,因此,项目组内经过了无数次的迭代和探索后,形成了一种变量定义习惯:尽可能使用简单的相近英文词汇,全局变量必须加准确含义的中文注释,函数内的一些自动变量,因其作用范围很小,有时候注释可省略。

关于变量命名的故事还有好多,这个刚刚是给大家起个头,我们后面会有专门的系列文章介绍,记住在真实产品的代码中,需要有意义的变量命名,忘记m和n吧。

是什么是节(section),第一次知道这个概念的时候,正式全球跨千年的时候,我还在大四,我在北京一家企业打零工,当时公司承接了一个日本银行的项目,日方对代码质量要求很严格,专门派了一个专家过来给我们讲解各种要求,以及其背后的道理。

当时还很年轻,狂傲不羁,因此大部分的苦口婆心都被当做了耳旁风,但唯独对节的概念记忆比较深刻(可能是一开始就讲的是这个了,呵呵,后续的就没耐心听了,这个系列文章阅读比例逐次下降,估计是同样的道理)。

我们在读代码的时候,人的思维一段时间内仅停留在一个较窄范围的点上,如果面对的是看不到尾的代码,会潜移默化的将其看做灭绝师太的裹脚布——又臭又长,逆反情绪悠然而生。

因此,我们需要将代码按逻辑分成一块一块的,以空格作为区分,然后每块代码前增加适当的注释,解释这一块代码的功能,是所谓节的概念。

经过这样的改造,读代码的时候,感觉会完全不一样。关于节的价值,远不值这些,后续会在编程规范系列文章中和大家慢慢道来,此时,我们仅要求小伙伴知道垒又臭又长的代码是不对的。

实际上在第5节中,我约定程序整体结构时,已经有这样的意图了,大家不放回忆并体味一下。

某些代码存在着一定的深度,一段时间就会忘记,通过右侧简单的注释加以标注,不仅便于后续代码的阅读理解,而且标注点一般是关键代码段,给后续的代码审查也带来的方便。

在示例代码中,会看到迭代表达式右侧(微信公众号排版问题,经常到了下面一行)有简单的标注,主要就是起这样的作用的。

但万事过犹不及,很多刚入职的小伙伴喜欢在右侧加好多的注释,仅挑出有价值的进行标注,需要长期的锻炼和慢慢的体悟,或许,那一天回头审视自己的代码,会将许多无用的注释删除的时候,就修炼到家了。

嵌入式系统中,资源是一个需要时时刻刻关注的问题。

何为资源,在我们的概念中,不仅内存和flash空间大小是资源,cpu计算能力也是资源,甚至代码可读性(可维护性),代码实现复杂度(耗去的人力成本),复用率等等诸多方面,都被我们称之为资源。

好钢要用在刀刃上,但首先要明白刀刃在哪儿。缺乏了明确边界,空谈提高资源利用率是无意义的。如可读性第一位,内存和cpu资源比较宽裕,我们那个最优雅实现版本最佳了。如果cpu计算能力紧张,上一节的标准实现更好一些。如果内存稍微宽裕,为了增加代码可读性,我们还有更好的方法。

前面已经有人给我留言提到过这种方法了,不知大家有没有感受到,锻炼到现在这个时候,单纯的菱形输出是多么easy的事情啊,非要搞个空心菱形,将程序搞的混乱不堪。

但加入我们用一个数组来表示整个菱形输出,第一次以*输出一个菱形,第二次以空格在输出一个菱形,然后将整个数组输出出来,是否会非常的简单呢,代码可读性瞬间爆棚,执行效率也高,仅仅多占了一些内存而已。

经过马拉松的历程,终于到了最后的篇章,我们来归纳汇总一下第一个空心菱形输出例程中提到的知识点:

1、需求清晰理解,最使用的策略是:将需求用自己的语言表达出来,和对方确认后再实施。

2、边界判断,要让小伙伴意识到:在嵌入式产品中,最终产品的鲁棒性,很多时候就是表现在这样一点一滴的简单判据上。

3、基本调试手段的锻炼,工欲善其事必先利其器,无须多言。

4、编程思维的引入,需要慢慢的体会抽象的价值,这是一个难点,但想走得远必须扛过去。

5、数值计算过程中,很重要的一个概念:巧用迭代。

6、基础编程规范的引入,体会节的概念,要意识到产品代码可读可维护的重要性。

7、在嵌入式编程领域,资源是受限的,而我们要学会针尖上的舞蹈。

8、撰写工作笔记,善于总结,习惯去体悟成长的脚步。

记得刚开始从事嵌入式编程的时候,我的职业导师给我欣赏了他的记事本,密密麻麻的各种调试记录,感悟想法,技术资料,知识归纳,我终于明白了他为何获得了全公司上上下下的认可。

因此,我们的团队形成了一条不成文的规矩,必须做工作笔记,不管方式,不管格式,只要开始记录就好。

入门就一句话:从入门到放弃。

是个麻烦事,从哪里入手也是件麻烦的事情,很多初学者往往找不到北,这时候,如果能掌从一门简单易学的编程语言,那就信心百倍了!

在这里,我郑重跟各位安利 Python 。

蟒蛇:老铁,咱能不提到我吗?

大家别被这名吓到,这门语言的创造者Guido van Rossum是根据BBC的搞笑节目“蟒蛇飞行马戏”(Monty Python’s Flying Cirecus)来命名的——并非他有喜欢看蟒蛇绞杀动物的奇特癖好(不过logo的确是两条蛇缠在一起)

据我多年 女装大佬 Python老司机经验,总结有下:

  • 简单:阅读一个好的Python程序,就像在读英语一样,这种伪代码本质是它最大优点之一,使你能专注解决问题,而不是去搞明白语言本身。
  • 免费、开源:Python是FLOSS(自由/开放源码软件)之一。你可以自由发布这个软件的拷贝、阅读它的源代码、对它做改动、把它的一部分用于新的自由软件中。
  • 高级语言:当你用Python编写程序时,你无需考虑一些底层细节。诸如:怎么管理你的程序使用的内存之类的。
  • 可移植性:由于它的开源本质,Python已经被移植在许多平台上。如果你小心避免使用依赖于系统的特性,那么你的所有Python程序无需修改就能在这些平台上运行。包括Linux、Windows、FreeBSD、Macintosh、AS/400、Windows CE等,甚至还有PocketPC!

所以有人说,Python 是一款非常适合新手开的好车,不要驾驶证就能上路。除非你想体验速度与激情的快感,一般来说,你不需要其它车。

听说Python有两个不同版本,我该选择2还是3?

Python2.x是已经进入稳定状态的Python版本,Python3.x是开发更加活跃的面向未来的版本。它们在语言特性上有略微不同,但不至于相差太大。

至于选择哪个版本,要根据你的使用方式而定。一般来说,大部分Linux和MacOS设备都默认预装Python 2,且旧版本支持的第三方库也更多;Python 3 则提供更舒服的字符编码处理机制。

所以,如果你需要处理中文文本,或者你并不需要用到某些只有在Python 2上才能运行的库,那你可从 Python 3 开始你的学习之旅。

了解了些基本内容,我需要怎么开工?

为了编写存储程序代码的文本文件,我们需要一个趁手的编辑器

对于编辑器的基本要求之一是语法加亮功能,利用这一功能,你的Python程序的不同部分被标以不同的颜色,这样你可更好看清你的程序,使它的运行显得形象化。

如果你使用Windows,我建议你使用IDLE。IDLE具备语法加亮功能,还有其他功能,比如允许你在IDLE中运行你的程序。注意:不要使用Notepad——它是一个糟糕的选择,它没有语法加亮功能,且不支持文本缩进。

如果你使用Linux/FreeBSD,你有很多种选择。

有经验的程序员:使用VIM/Emacs。

勿庸置疑,它们是两个功能最强大的编辑器。我个人使用VIM编写我的大多数程序。

是不是还要选择适合我学习方式的教程?

目前初学者容易接触到的Python教材大致有以下两类(文末有具体推荐):

一类是文字材料,例如实体书、电子书、网络教程和程序文档等。文字教程的好处在于信息密度大,学习中遇到不懂的内容可随时查阅,书中的文字材料/代码段可直接复制,方便看到运行结果。

另一类是多媒体教材,例如视频课程和自学APP等。它们的好处在于直观、互动性强,能清楚通过动画、视频的演示了解教学内容。

不管选哪个,结合教材中的实例代码,通过不同的修改和输出了解代码的执行原理,都是非常重要的环节,多动手吧!

那么,入门的时候要怎么做?

啊,明明按照教程做的,怎么跳出这么多红字?

Python程序在运行时遇到的错误,通常会显示详细行号和错误信息,方便用户查找修正。遇到自己不认识的,别慌,先看看它们的描述,再打开你的文件,找到出错的行号。

如果问题过于诡异,就要好好利用 Google 或者必应这些搜索引擎,搜索你遇到的具体问题,通常情况下,基础性语法和逻辑问题还是比较容易解决的。

上面步骤,依然没有解决我的问题怎么办?

耐心点,不要指望搜索几秒钟就能解决一个复杂问题。如果你第一次搜索没有结果(或者结果太多),也不要抛出一堆问题,这时要进行思考。

思考并不是发呆,要动起手来,通过搜索得到的信息,修改你代码中“可能有问题”的部分,观察它的输出结果,逐步定位问题产生原因;

或是通过修改从网山搜到的别人代码,研究运行情况,来了解别人是如何解决特定问题的。

可我想破了脑袋还是不明白,救救我啊!

这点我放到最后来说,因为如何提出一个好问题至关重要。

除了学习群和论坛之外,有几个主要的问答网站:

在问问题前,请在这网站上再搜索一遍你的问题——毕竟新手容易遇到的问题,在这里可能早有人回答过了。

那么,当你排除以上一切,准备开始问时,该怎么组织自己的问题呢?这里有几点建议:

提供简练精确的信息非常重要。

第一,表现出你为简化问题付出了努力,可使你得到回答的机会增加;

第二,简化问题使你有可能得到更有用的答案;

第三,在你精炼自己问题的过程中,可能自己就找到了解决方法。

描述错误信息,不做猜测

向别人陈述你的猜测是没有用的(如果你的诊断理论真的那么有用,你还会向别人求助吗?)。所以,你只需要告诉他们问题的原始状态,而不是你的解释和理论,让他们来解释和诊断。

如果你想知道如何做某事,但在实现过程中卡住了,你需要在开头就表明你的目标,再陈述你遇到问题。

当你选择学习,你的业余时间都会被它所占据,随着学习曲线逐渐变陡,你感到枯燥、迷茫、自卑以及脑汁耗竭的痛苦。

这是非常正常的。许多人(包括我)在学习一门新技术时,都会遇到类似问题。对此,我个人的解决办法有:

当你看完基础语法,对继续往下挖掘感到枯燥时,别勉强自己,翻翻书本,找一些有趣的练习题练练手,或者编写、修改一些简单有趣的小项目,跟你朋友讲你学到的新内容,给自己找点成就感。

2、专注在当前的学习目标上

没有技术背景的人,学习容易被复杂的技术体系吓到,网上经常会出现“一定要读这本书”、“最好先有 XX 基础再看这篇教程”之类的警告,结果常会出现这种情况:本来你只打算学编写网页 ,结果却开始苦读《精通正则表达式》。

别担心,你无需掌握所有分支,很多时候,你只要知道在需要某个知识点时,能从这类教程中找到对应用法即可。

无论学习什么,往往越深入就觉得自己无知。这并不是坏事,它能让你保持谦虚,但千万不要被吓得不敢继续前进。

觉得写出来的代码就像一坨屎?正常,因为你看过的例子和学到的知识增进了你的眼界,但编程技能和思想需要在练习中成长,所以千万不要因此而自卑,继续尝试,相信自己。

人的认知能力是会随着时间流逝而耗竭的,别逞能,站起来走动走动,呼吸一下新鲜空气吧!

最后,祝各位新晋魔法师学习顺利,祝大家赚大钱

最初是从rust的文档找到learnku的,很喜欢这里纯技术的氛围。别的板块都是大神讨论参与不进去,就在这里聊聊天吧。

我在本科是非CS专业,所以只是自学了一点。自学的过程,一言难尽,走了很多弯路。最开始是学的C,用的CS课程的教材,这个坑就比较大了。本来书上的东西没人给讲就半蒙半猜的不是很明白,这种教材还有一个问题就是太过于学术化,不接地气,所以看了个把月几乎没有任何进步。我当时觉得主要问题是没人带路,为了解决这个问题,我投奔了。

找到它是因为搜索免费的课程,在udacity上找到了一个免费的swift的课程。之前C嘛学了有一个月吧,等于没学,切换到其它语言从头学起也没有啥沉没成本,所以看到免费就入坑了。

大概跟了5节课的样子,前后花了2个星期吧。课程上说的手把手的照猫画虎也写了好几段能跑的“代码”。后来因为准备申请学校啊什么事的开始准备,就放下了一段时间。等到放假的时候再想捡起来,发现似乎还是啥也不会,啥也没记住。这就有点难堪了。

等到假期我想重新捡起课程的时候,发现这么学虽然有人给讲,还是效率非常低下。最严重的问题是,我跟着课程做的练习似乎都会做,但是离开了那个练习我还是啥也不会。

我逐渐感到这样也是不行的,还是得改进下。

我就去研究了一下别人的自学方法,看到有人说要自己做项目更锻炼人,决定找个事情练练手。既然学了swift,不如就开发个ios应用吧!我当时就决定要搞一个赛车游戏吧(不知深浅愚蠢的人类)。

可想而知,连门都没摸到我就发现这个水挺深的,甚至要提交到应用商店还要花钱注册开发者账号,我甚至都走不到那一步。

虽然目标定的不对,但是方法还是对的,还是要自己做一个项目。我最后选择了自己做一个展示课程表的网页。

这个小小的课程表网页让我进步很大,对编程有了完全不同的认识。在这个过程中,我没有去像学习一门课程一样去尝试100%理解所经历的所有问题。在学校上课就是要100%理解每个遇到的问题,否则拿不到好的分数就完蛋了。但是这个项目上我完全没有这么做,实际上我基本上跳过了大部分不懂的内容,只关心如何实现自己想要的功能。不会做的就google,然后找到答案再拷贝粘贴。

回想起来,这么做之所以有用,实际上是因为以结果导向不探究细节原理可能对初学者是最好的,容易获得成就感获得激励。如果要探究所有细节原理,那可能就会被淹没在细节原理中,无法获得整体的感觉,就是没有办法对如何编程这件事形成整体的认识。

做了这个项目之后,我至少是对一个小网页是知道大致是怎么回事了。在这个阶段,我回头找到过去忽略的一些问题,重新审视了一次。虽然不是所有问题都能弄懂,但是我发现这时候要弄懂这些问题,容易多啦,至少别人说的问题啊,答案啊上下文我能明白是怎么回事了,一些名词(Front End就是新词儿概念太多太多了)也知道是什么意思了。

真的这时候理解能力大增啊,感觉自己入门了,开始成长了。

啰哩啰嗦说了一堆,算是为使用learnku的一点回报吧。推荐一些学生日常资源,如果你也是小白,会用得到:

  • UI库,有了他做UI不用愁CSS了,我最讨厌CSS了。
  • antd,如果做后台程序,那这个是不二之选了
  • 一个让你集中注意力的chrome插件
  • 如果你也是留学生,计算绩点跑不了就是它了
本作品采用,转载必须注明作者和本文链接

我要回帖

更多关于 UG编程怎么把显示字体改大 的文章