知名博主和菜头有一个常用的签名:请你相信我所说的每一句话都是错的。如果你理性的分析这句话,你会发现这句话其实是一个很有意思的悖论,用来证明无论正反、相信或者不相信,他永远都是对的。
但只可惜,没有什么是绝对的正确,编程的经验与教条也同样没有永恒的正确。所谓经验,都是他人的感悟;所谓教条也都是他人的痕迹;你应当去实践,去思考,形成自己独有的编程体验。
所以,下面的观点,均是个人体验形成;虽不“成器”,但好在是“自己的”。
1 兴趣不是编程最大的动力,成就感才是
不骗人,我对编程谈不上兴趣。对编程有没有兴趣也不是一个人能否写好程序的必备条件。兴趣必然是一种不求回报能让自我陶醉甚至是沉迷其中的持续性行为。
”兴趣“太过于美丽,我觉得我远没有达到这种高度。”成就感“这个词也许会更贴切一些。事实上,我们绝大多数人编程其实只是为了混口饭吃或者让自己生活的更好一些。但不得不承认,长期从事一种近似枯燥的“劳作”没有一些信念与寄托是不行的。
排除掉编程是为了生存这个残酷的现实,还能支撑我持续编程的我认为是成就感。这和打游戏给我带来的感觉其实是没有区别的。
当我一次次的击倒关底的boss,当我角色的等级不断的提升,当我通过自己的努力打出超越常人水平的DPS,当我流畅的按出QWER 5杀后,这种满满的成就感是不可替代的。
编程也是一样。记忆中,我曾经无数次揉着睡眼惺忪双眼,一边看着窗外微微发白的夜色,一边偷瞄几眼连夜赶出、正在流程运行的程序,心中暗自得意。
这种感觉妙不可言。
准确的在编程中找到这种”成就感“,甩开”兴趣“或者”爱好“的包袱,对于一个程序员来说极其重要。为生存编程也好,为艺术编程也好,为理想编程也好,总之,你一定要找到一个可以驱动你长期编程的动力。
2 debug是倚天剑,提出优质问题是屠龙刀
debug与提问是编程过程中两个截然相反的方向。debug代表着自我解决问题,而提问代表着寻求帮助。
如果有可能,我们应当尽量的通过debug来解决问题,而不是通过提问来解决问题。
我才工作时,当我的代码出现了错误,我也曾天真烂漫的向我的同事寻求帮助。结果只有两个:要不就是别人来帮我debug调试错误,要不就是不怎么搭理我。
渐渐的,我意识到,不怎么搭理我是因为我提的问题根本就不是问题,直接把答案放到搜索引擎上搜一下大把大把的答案就疯狂的涌现出来;别人帮我debug,这实在是自己懒惰的借口。
从此我基本上不再向他人寻求帮助,因为,我不是在造火箭大炮,我也不是在做前无古人后无来者的工作,对于一个才工作的程序员,我必定是在重复了其他程序员已经重复了无数次的工作,这些必然是可以通过搜索引擎+自己debug就能寻找到答案的。
工作5年后,我才真正意识到自己debug分析问题是多么的重要。初级编程思维的形成不是来源于写代码的过程,而是来自于自己调试代码的过程。所以,每一次把希望寄托在他人身上来解决问题,其实都是浪费了一次培养自己编程思维的机会。
那我们可不可以向他人来提问或者寻求帮助呢?可以,但是如果自己一点都不思考就匆忙的发出提问,这绝对不是一个好的做法。如果要提问,尽量保证提问的是优质的问题。
debug毫无疑问是倚天剑,但只有“优质”的问题才是另一把屠龙宝刀。
什么是优质的问题?每个程序员功底不同,很难有个准确的定义。但我认为优质问题的前提是,问题必须已经经过你充分的思考,至少要保证你提出的问题思路是清晰的,而不是需要他人debug来帮你解决的问题。我们很难保证一个问题绝对的优质,但如果你能够自己先深入思考,那么至少你可以保证整个问题对于你自己来说是足够“优质”的。
我再提问区里看到的最多的问题就是“为什么出现undefined”,为什么出现“None”,为什么报404,为什么报500错误。这显然都没有触及到问题的本质,这些都是可以通过debug来找到原因的。而这些问题恰恰是老师最难以去解决的。因为老师也需要依赖“debug”。不仅仅是老师要debug,全人类程序员都要debug来解决问题。除非你是ET拥有人类不具备的超能力。
所以,遇到问题,首先debug,最好是断点调试,坚信debug的力量。一般来说通过debug都能触及到问题的本质,这些本质的问题可能就超出了你目前知识的范畴,这个时候再提问,就能够提出一个较为优质的问题。
好的问题是由问问题的人和回答问题的人共同构建的,我们大多数时候只会想到好的问题是由答者单方面构建的,这显示是不正确的。不要小瞧问问题,它其实也是一个人能力的体现。
3 努力写出优质的代码,而不是仅仅满足于功能的实现
编程到底是不是艺术,我们不做过多的探讨。艺术也好情怀也好,都是若有似无的东西。我绝对不会拿编程是艺术来说服你为什么要努力写出优质的代码。
我在管理研发团队的过程中发现二个很有意思的现象,第一个就是前面我谈到的:鲜有真正视编程为“兴趣”的coder。第二个就是,编程2到3年时,大部分的初级程序员不仅不会把编程当做兴趣,反而会认为编程很“无聊”。
通过与这些coder的聊天和查看他们的代码,我发现,这些coder普遍都只是完成了程序的功能,从来不考虑复用,不考虑维护,不考虑扩展。就像一次性的筷子,用完就扔。
可软件开发不能像吃饭一样,吃完就把筷子丢了。软件开发必然是一个反复迭代、修正、调整的工程,甚至调整和维护的人并不是你自己。
一次性筷子你用完后自己都不想再捡回来用第二次吧,那怎么可能别人还愿意捡回来继续用呢?
咱们很多coder写代码太直白了,标准的“直男型”代码。一个Controller中写100多行代码的人大有人在。
对于普通的编程工作,尤其是Web开发,只完成功能不考虑性能、代码结构,实在是太过于简单。你只需要掌握一门语言里最基础的流程控制和基本语法就能实现各种各样的功能,连稍微高级一些的语法都完全不需要。如果一件事情太简单,没有任何挑战,那必然会觉得无聊。
追求优质代码的写法,是可以让你长久保持编程动力的一个法宝。每个人其实内心都多多少少对“美”有一种期待,长期看到乱糟糟的代码,很容易让你对编程厌倦。
此外,代码风格其实分两类:一类是具体的代码,另外一类是抽象的代码。人类最直观的思维方式是从具体开始,所以写出具体的代码是很容易的,但要写出抽象的代码其实是不太容易的。这就好像你通过简单的绘画学习就可以画出一些还不错的风景,但你要成为梵高,这还是有点难度的,对吧。
如果要培养这种抽象代码的编写能力,起步条件就是追求优质的代码,如果连起步条件都不具备,那代码编写的能力必然逐步趋于平庸。放弃对于优质代码的追求,其实等同于放弃了编程思考的乐趣,没有了思考,代码哪儿还有你自己的风格和灵魂?
4 视频课程学习最好的方式是自己先实现
很早就想谈谈如何有效的通过视频进行学习。方法太多了,而且根据每个人的学习习惯又可以演化成各种侧重点不同的学习方法。
但收益最大一种方式是:对于有一定基础的同学,先不要看课程,直接先看老师项目成品,自己完全独立的1:1的完成整个项目。全部完成后,再细看老师的课程。
没有对比就没有伤害,也许对比后“伤害”的是你,也有可能“伤害”的是老师。但无论“伤害”的是哪一方,收益的终将是你。假如你被“伤害”了,那你必然是深刻理解了为什么老师的方案比你要更加优秀;如果老师被“伤害”了,那么,还用说吗,你可以去当老师了。
我们平铺直叙像看小说一样看完整个课程不能说没有收获,但相对于这种对比式的学习,“旅游”式的学习实在谈不上对视频课程“物尽其用”,挺遗憾的吧。
我当然知道很难有同学有足够的耐心先静心自己实现一遍整个项目。但是,这个行业就是这样,你必须衡量一下你与你同行业者的优劣势。如果你没有良好的外部资源,比如优质的项目、精英的团队,那么你只能从自己身上下功夫,去做一些自己惰性所不不愿意做的事情,只有这样才能弥补自身资源的不足。
如果实在无法完整的实现整个项目,那么其实可以阶段性的自我实现和思考。我的课程通常小节的划分都是比较讲究的,大多数小节是留有“悬念”的,整个悬念就是给你思考的节点。我很多时候会在小节的末尾提出问题,这个时候你就不应该急着去看下个小节的答案。
也许这样是不是更容易实现一些呢?
5 真正的去实践,而不是一味的学习
老生常谈的一个问题。
编程不是考试,还按照初高中备考的思路去学习编程这是不现实的。编程是一个实践性非常强的工种,很多知识和语法你知道并不代表你掌握了。编程考究的是你是否能够灵活的应用这些编程知识。很多时候,你只需要在你脑海中留下一个浅浅的印象,当需要解决问题的时候,迅速能够调出这些知识片段,把他们“组合”在一起来解决问题。细节不记得,不要紧,语言的速查手册就是帮你具体化这些知识的。
很多编程基础知识就如同阿拉伯数字一样,你只看他他就是数字,但你可曾想过数字也能演化出正数、负数、小数、实数、虚数、指数、复数?
这些变化只有在实践中,只有在你真正去解决问题的过程中,你才能体会到变化的奥妙与组合的奇妙。
很多同学经常会抱怨我不在大公司,我没有优质的项目机会,可你要知道80%的coder都在中小公司,绝大多数coder都没有接触优质项目的机会。
那难道我们就放弃实践?
人之所以为人,就在于我们有很强的主观能动性。外界条件不够优越,我们就自己寻找。模仿你会吗?找一个自己很欣赏的产品,1:1或者尽可能在细节上复制一个产品作为自己的练习项目,有什么不可以吗?连设计师的UI设计都给你省了。
但这个过程中,大家一定要注意细节,如果你只是实现了大体的功能,这意义不大。好的产品其实就优秀在细节上,好的程序员和普通的程序员一定的差距也在细节上。
6 学习一定要注重推导的过程,而不是关注结果
我常在我的课程中谈到这个问题。熟悉我课程的同学应该都知道,我很少去讲API的调用,更多的是关注编程思想。编程思想具体到课程中其实就是推导的过程。
工作中我们要更关注成果,但学习一定要注重过程。
比如在《Python Flask RESTFul API》中,我几乎二次开发了Flask框架。如果你只是拿到了一份很好用的Flask API框架那我觉得意义不大。关键在于我是怎么一步步的推导、分析和落实这个优质框架的。比如为了解决Python序列化模型很麻烦的问题,我是怎么想到去寻找JSONEncoder这个对象的,又是如何来重写他的;而当我们想进一步优化代码时,居然发现Sqlalchemy的模型对象在被动态创建时是不会调用构造函数的,这个时候你需要注意我是如何去sqlalchemy文档中去找到一个可以出发构造的装饰器的;再比如,我们采用JWT令牌,那在Flask中我应该如何来支持Token令牌。这所有的实现,我都不仅仅是直接给出大家一个好的结果,而是详细的描述了我思维的过程。
语言和框架是学不完的,你只有认真的去跟着我一起思考,才能摆脱受限于语言和框架的思维。很多时候,我课里所讲的内容和思路你放到任何一个语言或者框架里都是通用的。
结束语:近两年来,我看到太多努力学习的同学,很多同学在本科一年级就开始勤奋的编程和学习。这让我回想起我的大学生活,只有两个字“惭愧”。分享一些我的心得,希望能够帮助到大家。
转载;