如何自学编程北京理工大学计算机学院金旭亮知乎Live(2017-7-18晚8:00)适合自学编程的前提条件:参看知乎我的专栏文章:《自学编程vs.参加培训》足够的时间强的自控能力高中以上学历基本的物质保障漫漫自学编程路……将敏捷软件开发的原则应用于自学编程的过程。明确你的目的了解软件技术与编程这件事拟定自学路线、策略、计划和安排按计划进行自学4123反馈调整加深更加知己知彼策划行动第1部分目标决定行动你打算自学编程,为了什么?考研求职兴趣驱动创新、创造更好地干好本职工作不同的学习目的,应该采用不同的学习策略和路线。第1种目的:为了考研而自学啃下计算机专业核心课程掌握考研初试、复试用到的编程语言可以参看我的知乎Live:《如何自学计算机专业课程》多半是C/C++/Java,上机考试大多是针对特定场景,自行设计并实现相应的数据结构和算法。主要干两件事情:12第2种目的:为求职而自学13分析当下人才需求情况,预测未来发展趋势。分析自己现有基础和现实条件(知己)2依据人才需求情况,倒推出需要掌握的技术群与技能树。制定一个技术学习路线,拟定具体学习策略项目为王:学习做项目再学习再做项目……45知彼第3种目的:为了应付日常工作的挑战收集信息,看看国内外领先的同行是如何应用信息技术的思索如何选择特定的技术将自己的日常工作自动化,提升效率在本职工作上做出出色的业绩,升职、提薪,寻找到新的发展机遇信息技术的战场,并不全在IT行业,而分布于几乎所有的,正在被信息技术所改造和重塑的传统产业之中。第4种目的:出于纯粹的兴趣……什么好玩,什么酷,就学什么,用它来捣腾一些有趣的东西第5种目的:创新、创造和创业要完成你的项目,业界主流使用的技术是什么?需要什么技术就学什么技术用掌握的技术去实现你的想法技术是实现目标的工具和手段,学习技术不是目的,创新创造才是目的。通用的自学编程学习路线学习编程语言学习开发框架做项目学习计算机科学与理论基础成长为专业软件开发者第2部分程序是怎样编写出来的?避免陷入“盲人摸象”的困境程序是什么?程序入出原始数据处理结果程序的规模有大有小,运行环境多种多样,要解决的实际问题无所不包……编写程序员“计算器”示例程序程序支持常规的四则运算功能,拥有两种类型的UI界面程序能动态地切换四则运算表达式解析算法2.1问题定义与分析阶段问题是什么?怎么解决它?程序是怎样编写出来的?分析程序要处理的数据所具有的特性▪表达式示例:9+5×(4-3)1.只有“加减乘除”四种运算符2.运算符具有优先级:乘除优先于加减3.可以有多个括号,左右括号必须配对,括号的优先级最高所有软件都需要处理数据,弄清楚数据本身的特性,是设计与开发软件的第一件事。表达式的特性:解析四则运算表达式的算法基础表达式类型定义示例中序(Infix)X+Y2*3/(2-1)+5*(4-1)前序(Prefix)+XY+/*23-21*5-41后序(Postfix)XY+23*21-/541-*+使用前序、中序和后序表达式,都是一个字串扫描的过程(比如前序算法是从右到左扫描字串),一边扫描一边处理,要使用堆栈这个数据结构。+/*23-21*5-41四则运算表达式的算法基础-2▪通过构造表达式树,三种类型的表达式可以相互转换+/**235-21-41“2*3/(2-1)+5*(4-1)”的表达式树对树进行前序遍历,就得到前序表达式。类似地,也能得到中序和后序表达式。我看编程与数学之关系是不是数学不好,我就学不好编程?与数学密切相关的计算机算法在实际开发中到底处于什么地位?数学如何解决开发中的难题?2.2系统设计阶段绘制软件大厦的施工图程序是怎样编写出来的?一个著名的公式……程序=数据结构+算法类NiklausWirth教授,Pascal系列语言之父,世界闻名的计算机科学家,1984年获图灵奖。“运算表达式”类“表达式树”类将数据结构与算法转换为类应用DIP原则使程序中可以动态地切换使用不同的算法抽象出来的算法接口所有算法类,都必须实现指定的接口所有需要调用算法对象计算的地方,都通过接口来调用面向对象软件系统的分析与设计是门学问!可以参看我的MOOC课程——“面向对象软件开发实践”第一系列和第三系列的相关视频学习。2.3编码开发阶段编程中充满了“套路”与“规范”,你不要乱来……程序是怎样编写出来的?预处理用户输入表达式调用算法输出结果封装抛出捕获并显示出错信息“异常处理”的典型编程“套路”一本书,教你写出规范的代码这是一本巨厚的书,里头将软件构建的方方面面都做了详细的介绍,可以说是一本开发宝典。这本书中介绍了大量的编程套路与编程规范,了解并且将它们用在自己的实际开发中,是菜鸟成长为“老鸟”的捷径。确定具体开发顺序-单兵作战中序算法相对独立先实现数据结构最后才是窗体的开发虽然是“预”处理,但要到后期才开发取操作数是基础组件开始MathExpressionOperandGetterInfixAlgorithmConverterPrefixAlgorithmExpressTreeAlgorithmPreProcess可视化窗体的开发结束表达式类取操作数中序算法表达式转换前序算法表达式树算法预处理完成它是开发前序算法的前提团队开发项目的进度管理开始结束多人开发,最关键是各个开发者之间的“同步”,项目完成的时间,取决于“最慢”“最长”的那条关键路径的长度和完成时间采用迭代的软件开发过程开发功能一设计编码测试发布开发功能二……设计编码测试发布编码测试发布设计开发时必须进行单元测试▪单元测试是针对类中的“方法(即函数)”的测试输入预先准备好的数据类中的方法将方法输出结果与期待的处理结果进行比对测试用例(TestCase)单元测试的典型套路:中序算法的测试代码publicvoidCalculateTest(){//1.创建待测试对象InfixAlgorithmtarget=newInfixAlgorithm();//2.输入测试数据stringexpr=(10+30*2).ToString();doubleexpected=70;doubleactual;//3.计算,获取最终结果actual=target.Calculate(expr);//4.比对结果,下断言Assert.AreEqual(expected,actual,1e-6);}“数据驱动”的单元测试:可将测试用例放入数据库,程序从数据源中提取测试用例数据,自动运行单元测试。程序员必须具备之基本技能掌握常规的代码重构方法学会编写单元测试会用版本管理工具2.4演化阶段支持演化的项目具有长久的生命力程序是怎样编写出来的?为重用而重构原先是一个exe文件包容所有代码桌面应用项目(exe),其中只包容与用户交互的UI界面代码类库项目(dll),只包容完成数据处理的算法代码将数据处理与UI界面代码剥离之后,数据处理代码可以在多个项目中重用组件化重构进入移动互联的时代……通过重用MathFuncLib组件库,可以很容易实现一个Web版的计算器。{expression:1+2,result:3.0}通过调用REST服务,可以很容易地给手机集成四则运算功能。WebServer编写Web服务,内部通过调用MathFuncLib组件解析四则运算表达式软件开发的组件时代1.重用已有的旧组件2.开发部分新组件3.将各个组件以“搭积木”的方式组装成整个软件系统。技术平台常用的组件技术Javajar/war包.NETassembly(程序集)Linux静态和动态链接库学会如何将大系统分割为小系统,将可重用可替换部分抽取为特定的组件,是一项极为重要的开发技能。软件开发的过程小结程序员必知之软件工程理论第3部分自学编程的方法程序员小明的“修仙之路”3.1软件技术的现状与发展规律破解“软件技术选择困难症”自学编程的方法时代的背景与软件技术的三大发展趋势入门的门槛不断降低软件向一切行业渗透!技术的天花板在不断地升高软件知识与技术的层次性基本原理与基础理论运行平台、基础框架应用层的技术从下往上,越往上走,变化越快掌握这块,打好内功基础学习外功招式,破敌致胜变化慢变化快软件技术的生命周期时间使用人数初始期成长期稳定期衰退期软件技术人才市场的价值规律会某技术的人数企业愿意给出的工资实现供需平衡时间支付工资金额、可雇佣人数软件技术选择困难症那么多的技术,我该学啥?3.2自学编程的学习指导鞋子合不合适,脚知道……自学编程的方法知识技能技术开发能力常变的,不断增长的缓慢变化的,相对稳定的手段目的软件开发职业技能培养的两个阶段可以通过自学获得必须通过团队开发实践单兵作战团队协作职业程序员的“软硬”职业技能清单源代码的阅读能力调试程序的能力结构化/面向对象基础技能和编程套路必要的计算机科学理论基础重构与单元测试会用版本管理工具特定应用领域的理论与相关技术“硬”技能(部分)“软”技能一万小时定律一万小时定律造成了误解……•并非所有人,把任何工作重复干10000小时就能成为特定领域的专家•并非所有领域,必须努力10000小时才能成为专家•真正有效的训练,是“刻意练习(deliberatepractice)”刻意练习是一种有目的的练习,它具有以下几个特征:刻意练习发展的技能,是其他人己经想出怎样提高的技能,己经拥有一套行之有效的训练方法(向高手学)刻意练习发生于人们的舒适区之外,需要专注与投入刻意练习包容精心定义的阶段目标,并需要及时的反馈,总是针对特定的方面进行重点突破(分解动作)刻意练习产生并且依靠心理表征(可看成是一种对编程的感悟)“刻意练习”两法宝LearningByDoing(做中学)分解之后,各个击破12你要学习的东西将实际应用在什么情境中,那么你就应该在什么样的情境中学习这些东西。在战争中学习战争LearningByDoing(做中学)——AndersEricsson(《刻意练习》作者)实例:在典型场景下训练“递归”编程技巧应用递归在编程在计算机中查找文件。ABCD^header应用递归遍历链表)!(!!knknCkn应用递归求解组合数实例:训练面向对象编程基础技能-1两个窗体实时互动,数值变化始终同步一个对象向多个对象广播消息实例:训练面向对象编程技能-2一个对象监控多个对象使用C#/Java/C++/Python等不同语言或框架实现这些实例在不同的运行环境(Windows、Linux、Android)中实现这些例子总结共性与差异,就能对面向对象编程有更好的理解。螺旋式上升有目的的刻意练习必须遵循“由浅入深”,“从简单到复杂”的认识规律,循环式反复,螺旋式上升小的编程练习题有着完整功能的小工具功能集合庞大的项目个人项目两三个人的小项目多人协作的大项目随着你所从事的项目的规模与难度不断上升,你的个人能力也会随之增长。“刻意练习”时怎样选择练手的项目?七巧板法你学习了某个软件技术,掌握了某个技术实现某个功能的方法,这些都可以看成是“七巧板”中的“构造块”,开动大脑,能不能将多个“构造块”组合起来,拼出有趣的图案?你想要做某个东西,比如某个游戏,那么,为了完成这个游戏的开发,该学什么技术就学什么技术,每次实现一个小功能,像滚雪球一样,慢慢地把整个软件给做出来……滚雪球法分解之后各个击破分解学习某项技能时,将其分解成一系列的训练步骤,每个步骤都有明确的目标和衡量成功与否的标准,以得到训练结果的及时反馈,每次重点掌握其中的一个步骤,掌握了一个之后再转入下一个,直到实现最终的目标。——总结自《刻意练习》一书自行尝试分解软件技术领域将一个庞大的技术领域进行细分,以便各个击破……进一步细分,得到特定子领域的知识关联图SpringMVCServlet/JSP依赖于SpringFramework的基础特性(依赖注入,AOP)基于Web工作原理、面向对象理论与基础需要了解Tomcat/ApacheMaven/GradleSTS/Eclipse/NetBeans/IntelliJ承载于构建使用开发使用Spring技术家族的其它成员基于知识关联图制定自己的学习路线面向对