敏捷开发
外汇网2021-06-19 19:01:37
89
敏捷开发简述敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经历试探,具备集成和可运行的特质。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处在可运用状态。">编辑]敏捷开发的路线图:敏捷开发的路线图Test-Driven Development,试探驱使开发。它是敏捷开发的最重要的部分。在ThoughtWorks,我们达到任何一个功能均为从试探开始,首先对业务需求执行分析,分解为一个一个的Story,记录在Story Card上。然后两个人同期坐在电脑前面,一个人依照Story,从业务需求的角度来编撰试探代码,其他人看着他而且执行思考,假使有不同的意见就会提出来执行讨论,直到促成共识,如此写出来的试探代码就真实反应了业务功能需求。接着由其他人控制键盘,编撰该试探代码的达到。假使没有试探代码,就不能编撰功能的达到代码。先写试探代码,能够让开发人士清晰目标,就是让试探通过。Continuous Integration,连续集成。在以往的软件开发过程中,集成是一件很痛苦的事情,一般很长时间才会做一次集成,如此的话,会导致很多困难,比如 build未通过或者单元试探失利。敏捷开发中提倡连续集成,一天之内集成十几次甚至几十次,这样频繁的集成能尽量降低矛盾,受于集成很频繁,每一次集成的更改也很少,即便集成失利也容易定位错误。一次集成要解决哪些事情呢?它起码包含:得到所有源代码、编译源代码、运行所有试探,包含单元试探、功能试探等;证实编译和试探能否通过,最后发送数据。诚然也会做一部分其它的任务,比如说代码分析、试探覆盖率分析等等。在我们公司里,开发人士的桌上有一个火山灯用来标志集成的状态,假使是黄灯,表明正在集成;假使是绿灯,表明上一次集成通过,开发人士在这时候得到的代码是可用而牢靠的;假使表明为红灯,就要小心了,上一次集成未通过,需要赶紧定位失利原因进而让灯变绿。在连续集成上,我们公司运用的是自己开发的产品CruiseControl。Refactoring,重构。相信大家对它都很熟悉了,有很多很多的书用来介绍重构,最著名的是Martin的《重构》,Joshua的《从重构到模式》等。重构是在不更改系统外部举动下,对内部结构执行整理优化,致使代码尽量简单、优美、可扩展。在以往开发中,一般是在有需求过来,当下的系统架构难以易达到,进而对原有系统执行重构;或者在开发过程中有余下时间了,对当下代码执行重构整理。但是在敏捷开发中,重构贯穿于整个开发流程,每一次开发者check in代码以前,都要对所写代码执行重构,让代码高达clean code that works。值得注意的是,在重构时,每一次更改要尽或许小,用单元试探来保证重构能否引起矛盾,而且不导致对达到代码执行重构,假使试探代码中有重复,也要对它执行重构。Pair-Programming,结对编程。在敏捷开发中,做任何事情均为Pair的,包含分析、写试探、写达到代码或者重构。Pair做事有很多好处,两个人在一起探讨很容易造成思想的火花,也难以易走上偏路。在我们公司,仍有很多事均为Pair来做,比如Pair学习,Pair翻译,Pair做PPT,有关这个话题,钱钱同学有一篇很有名的文章对它执行介绍,名叫Pair Programming (结对编程)。Stand up,站立会议。每天早上,项目组的所有成员全将站立执行一次会议,受于是站立的,所以时间不会很长,一般来看是15-20分钟。会议的内容并没有是需求分析、任务分配等,而是每个人都回答三个困难:1. 你昨天做了什么?2. 你今天要解决什么? 3. 你遇到了哪些问题?站立会议让团队执行交流,彼此相互熟悉工作内容,假使有人曾经遇到过和你相似的困难,那么在站立会议后,他就会和你执行讨论。Frequent Releases,小版本公布。在敏捷开发中,不会显现该种情形,拿到需求以后就闭门造车,直到最后才将产品交付给客户,而是尽量多的产品公布,一般以周、月为单位。如此,客户每隔一段时间就会拿到公布的产品执行试用,而我们可以从客户那得到许多的反馈来改进产品。正由于公布频繁,每一个版本新添的功能简单,不需要复杂的设计,如此文档和设计就在很大程度上简化了。又由于简单设计,没有复杂的架构,所以客户有新的需求或者需求执行变动,也能迅速的适应。Minimal Documentation,较少的文档。其实敏捷开发中并没有是没有文档,而是有大批的文档,即试探。这些试探代码真实的反映了客户的需求以及系统美国石油协会 的用法,假使有新人加入团队,最快的熟悉项目的方法就是给他看试探代码,而比一边看着文档一边执行debug要高效。假使用书面文档或者注释,某天代码改变了,需要对这些文档执行更新。一旦忘记更新文档,就会显现代码和文档不匹配的情形,这愈加会使人迷惑。而在敏捷中并没有会显现,由于只有试探改变了,代码才会改变,试探是真实反映代码的。这时有人会问:代码不写注释行吗?一般来看好的代码不是需要大批的注释吗?其实简单可读的代码才是好的代码,既然简单可读了,别人一看就能够看懂,这时候根本不需要对代码执行任何注释。若你认为这段代码不加注释的话别人或许看不懂,就表明设计还不够简单,需要对它执行重构。Collaborative Focus,以合作为中心,显现为代码共享。在敏捷开发中,代码是归团队所有并非是哪些模块的代码属于哪些人,每个人都有权利得到系统任何一部分的代码然后修改它,假使有人目睹某些代码不爽的话,那他能够对这部分代码重构而不需要征求代码作者的答应,很或许也不晓得是谁写的这部分代码。如此每个人都能熟悉系统的代码,即便团队的人士变动,也没有风险。Customer Engagement ,现场客户。敏捷开发中,客户是与开发团队一起工作的,团队到客户现场执行开发或者邀请客户到团队公司里来开发。假使开发过程中有什么困难或者产品经历一个迭代后,能够以最迅速度得到客户的反馈。Automated Testing ,自动化试探。为了减小人力或者重复劳动,所有的试探包含单元试探、功能试探或集成试探等均为自动化的,这对QA人士提出了更高的要求。他们要熟悉开发语言、自动化试探工具,能够编撰自动化试探脚本或者用工具录制。我们公司在自动化试探上做了大批的工作,包含Selenium开源项目。Adaptive Planning,可调整计划。敏捷开发中计划是可调整的,并没有是像以往的开发过程中,需求分析->概要设计->详细设计->开发 ->试探->交付,每一个阶段均为有计划的执行,一个阶段终结便开始下一个阶段。而敏捷开发中只有一次一次的迭代,小版本的公布,依据客户反馈随时做出相应的调整和改变。敏捷开发过程与传统的开发过程有很大不同,在这过程中,团队是有激情有动力的,能够适应更大的改变,作出更高质量的软件。敏捷开发的特点敏捷方法首要有两个特点,这也是其区别于其余方法,特别是重型方法的最首要特质:(1)敏捷开发方法是“适应性”(Adaptive)而非“预设性” (Predictive)。这里说的预设性,可以通过一般性工程项目的做法理解,比如土木工程,在这类工程实践中,有比较平稳的需求,同期建设项目的要求也相对固定,所以此类项目一般非常强调施工前的设计规划。只要图纸设计得合理并考虑充分,施工队伍可以完全遵照图纸顺遂建造,而且可以很方便地把图纸划分为很多更小的部分交给不同的施员工员分别完成。但是,在软件开发的项目中,这些平稳的原因却很难谋求。软件的设计难处在于软件需求的不平稳,进而致使软件过程的不可预期。但是传统的控制项目模式均为尝试对一个软件开发项目在漫长的时间跨度内作出详细的计划,然后依计划执行开发。所以,这类方法在不可预期的环境下,很难适应改变,甚至是婉拒改变。与之相反的敏捷方法则是欢迎改变,目的就是形成适应改变的过程,甚至能允许更改本身来适应改变。所以称之为适应性方法。(2)敏捷开发方法是“面向人” (people oriented)而非“面向过程”(process oriented)。Matin Flower觉得:“在敏捷开发过程中,人是第一名的,过程是第二位的。所以就个人来看,应当可以从各种不同的过程中寻到真正适合自己的过程。”这与软件工程理论提倡的先过程后人恰好相反。 (续致信网上一页内容)在传统的软件开发工作中,项目团队分配工作的着重是清晰角色的定义,以个人的能力去适应角色,而角色的定义就是为了保证过程的实行,即个人以资源的方式被分配给角色,同期,资源是值得替代的,而角色不可以替代。但是,传统软件开发的这些方法在敏捷开发方式中被完全颠覆。敏捷开发尝试使软件开发工作能够利用人的特点,充分发挥人的创造能力。敏捷开发的目的是建立起一个项目团队全员参与到软件开发中,包含设定软件开发流程的管理人士,只有如此软件开发流程才有可接受性。同期敏捷开发要求研发人士独立自主在技术上执行决策,由于他们是最了解什么技术是需要和不需要的。再者,敏捷开发特别重视项目团队中的信息交流,有调查表明:“项目失利的原因最终都可追溯到信息没有及时精准地传递到应当接受它的人。” 敏捷开发的价值观事实上敏捷开发运动在数年前就开始了,但它正式开始的标志是2001年2月的“敏捷宣言”(Agile Manifesto),这项宣言是由17名当时说之为“轻量级方法学家”所编撰签署的,他们的价值观是:个人与交互重于开发过程与工具;可用的软件重于复杂的文档;谋求客户的合作重于对合同的谈判;对改变的响应重于始终遵循固定的计划。个人与交互重于开发过程与工具的原因:一个由优秀的人士构成但运用普通的工具,要比运用优秀的工具但由普通人构成、紊乱的小组做得更好。多年来民众花了很多时间尝试建立一种过程,以便把人当作机器上的一个可以替代的齿轮,但结果却并没有成功。敏捷过程是承认每个人都有特定的能力(以及缺点)对之加以利用,并非是把所有的人当成一样来说待。更重要的是,在如此的理念下,几个项目做下来,每个人的能力都从中得以提升。该种人的能力的提升,对公司是无价之宝。而不至于把人当成齿轮,伴随时间的推动,人的能力逐渐被消耗掉,最后变成留之无用、弃之可惜的尴尬人物。可用的软件重于复杂的文档的原因:可用的软件可以帮助开发人士在每次迭代终结的时机,得到一个平稳的、渐渐加强的版本。进而允许项目早日开始,而且更为频繁的收集对产品和开发过程的反馈。伴随每次迭代完成软件的上涨,以保证开发小组始终是处理最有价值的功能,而且这些功能可以满足用户的期待。谋求客户的合作重于对合同的谈判的原因:敏捷开发小组期望与项目相关的所有团体都在朝共同方向付出,合同谈判有时会在一开始就使小组和客户出于争执中。敏捷开发追求的是要么大家一起赢,要么大家一起输。换句话说,就是期望开发小组和客户在面对项目的时机,以一种合作的立场共同向目标前进。诚然,合同是必需的,但是如何起草条款,往往影响到不同的团体是执行合作式的依旧对抗式的付出。对改变的响应重于始终遵循固定的计划的原因:敏捷开发觉得对改变执行响应的价值重于始终遵循固定的计划。他们最终的重心是向用户交付尽或许多的价值。除了最简单的项目以外,用户不或许知道他们所需要的所有功能的每个细节。不可避免地在过程中会造成新的想法,也许今天看上去是必需的功能,明日就会认为不那么重要了。伴随小组得到许多的知识和经验,他们的进度速度会比开始的时机期望值慢或者快。对敏捷开发来看,一个计划是从某个角度对将来的观点,而具有多个不同的角度看困难是有机会的。项目的敏捷开发方法敏捷方法很多,包含 Scrum、极限编程、功能驱使开发以及统一过程(RUP)等多种法,这些方法本质事实上是一样的,敏捷开发小组首要的工作方式可以归纳为:作为一个整体工作; 按短迭代周期工作; 每次迭代交付一部分成果; 关注业务优先级; 检查与调整。下图是典型的敏捷过程总图,下面介绍其相关的特点。1、敏捷小组作为一个整体工作项目获得成功的核心在于,所有项目参与者都把自己看成朝向一个共同目标前进的团队的一员。“扔以往不管”的心理不是属于敏捷开发。设计师和架构师不会将程序设计“扔”给编码人士;编码人士也不会将只经历部分试探的代码“扔”给试探人士,一个成功的敏捷开发小组应当具有“我们一起参与其中的思想”, “帮助他人完成目标”这个理念是敏捷开发的根本管理文化。诚然,即使强调一个整体,小组中应当有适当的角色分配,各种敏捷开发方法角色的起名方案或许不同,但愿则差不多是一样的。第一个角色是产品所有者,他的首要职责包含:证实小构成员都在追求一个共同的目标前景;确定功能的优先等级,以便总是处理最有价值的功能;做出可以使项目的投入造成不错回报的决定。产品所有者一般是公司的市场部门或者产品管理部门的人士,在开发内部运用的软件的时机,产品所有者或许是用户、用户的上级、分析专员,也或许是为项目供应资金的人。2、敏捷小组按短迭代周期工作 在敏捷项目中,总的上并没有什么上游阶段、下游阶段,你可以依据需要定义开发过程在初始阶段可以有一个简短的分析、建模、设计,但只要项目真正开始,每次迭代全将做同样的工作(分析、设计、编码、试探。等等)。迭代是受时间框制约的,也就是说即便放弃一部分功能,也务必终结迭代。时间框一般很短,多部分是 2~4周,在 Scrum中采取的是 30个日历天,也就是 4 周。迭代的时间长度一般是固定的,但也有数据说,有的小组在迭代开始的时机选择合适的时间长度。3、敏捷小组每次迭代交付一部分成果比选择特定迭代长度更重要的,是开发小组在一次迭代中要把一个以上的不太精确的需求声明,经历分析、设计、编码、试探,变成可交付的软件(称之为功能增量)。诚然并没有需要把每次迭代的结果交付给用户,但目标是值得交付,这就代表着每次迭代全将增长一部分小功能,但增长的每个功能都要高达公布质量。每次迭代终结的时机让产品高达可交付状态十分重要,但这并没有代表着要完成公布的全部工作,由于迭代的结果并没有是真正公布产品。假定一个小组需要在公布产品以前对软硬件执行为期两个月的“平均无故障时间”(MTBF)试探,他们不或许缩短这两个月的时间,但这个小组依然是依照 4 周迭代,除了MTBF试探,其它都高达了公布状态。4、敏捷小组关注业务优先级敏捷开发小组从两个方面表明出他们对业务优先级的关注。首先,他们依照产品所有者策划的顺序交付功能,而产品所有者一般会依照组织在项目上的投资回报最大化的方式来确定优先级,而且把它组织到产品公布中去。要高达这个目的,需要综合考虑开发小组的能力,以及所需功能的优先级来建立公布计划。在编撰功能的时机,需要使工能的依靠性最小化。假使开发一个功能务必依靠其它 3 个功能,那产品所有者这就很难确定功能优先级。功能完全没有依靠是不太应该的,但把功能依靠性控制在最低程度依旧相当可行的。5、敏捷小组检查与调整任何项目开始的时机所建立的计划,仅仅是一个目前的猜测。有很多事情可以让如此的计划失效:项目成员的增减,某种技术比预期的更好或更差,用户更改了想法,竞争者致使我们作出不同的反映,等等。对此,敏捷小组不是害怕该种改变,而是把该种改变看成使最终软件更好地反应事实需要的一个机会。每次新迭代开始,敏捷小组全将结合上一次迭代中得到新知识作出相应调整。假使觉得一部分原因或许会影响计划的精准性,也或许更改计划。比如发现某项工作比预计的更耗费时间,或许就会调整进度速度。也许,用户目睹交付的产品后更改了想法,这就造成反馈,比如他发现他更期望有另一项功能,或者某个功能并没有像先前看得那么重。通过先期公布增长许多的用户期望的功能,或者降低某些低价值功能,就可以增长产品的价值。迭代开发是在变与不变中谋求平衡,在迭代开始的时机谋求变,而在迭代开发阶段不能更改,以期集中精力完成已经确定的工作。受于一次迭代的时间并没有长,所以就使平稳性和易变性得到很好的平衡。在两次迭代阶段更改优先级甚至功能自身,对于项目投资最大化是有益处的。从这个看法来说,迭代周期的长度选择就比较重要了,由于两次迭代之间是供应变更的可能,周期太长,变更机会就或许失去;周期太短,会发生频繁变更,而且分析、设计、编码、试探这些工作都难以易做到位。综合考虑,对于一个复杂项目,迭代周期选择4周依旧有道理的。MIT Sloan Management Review(麻省理工学院项目管理评论)所刊载的一篇为时两年对成功软件项目的研究数据,数据表示了软件项目得到成功的共同原因,排在首位的是迭代开发,并非是瀑布过程。其它的原因是:1、起码每天把新代码合并到整个系统,而且通过试探,对设计变更作出迅速反映。2、开发团队具备运转多个产品的工作经验。3、很早就努力于构建和供应内聚的架构。从这个数据中所表露出的信息告诉我们,认真研究敏捷过程对软件项目的成就是非常故意义的,它的意义在于:1)给开发小组的自组织给予了机会经典项目管理就好比一个具备中央调度服务的航空管理系统,这个系统是自治的,而且是封闭的,但现实中更庞大的系统,疑似并没有属于中央调度控制系统,但也同样也是有效的。假如我们开车到某个地方,我们可以任意选择所需要的路线,我们甚至不需要精准计算停车,只要我们遵守交通法规,驾驶员可以临时依据路况更改某个转弯点,在驾驶游戏规则的框架内,依照本身最大利益作出决策。成千上万的驾驶者,并没有需要中央控制和调度服务,民众仅仅在简单的交通法规的框架内,就可以完成综合起来说是更庞大的目标,很多事情从管理的角度只要抓住转折点,并没有需要多么复杂的规则,往往会更有效。伴随系统复杂度的提升,中央控制和调度系统面对崩溃。仔细研究交通系统的特点,我们会发现如此的系统中独立的个体在一组适当的规则下运行,并没有需要设计每个个体临时变更的方案,而每个个体只需要知道目标和大差不差的情况,他们完全可以利用自己的聪明才智来决定自己的举动。2)缩短了反馈通道敏捷过程有效运转的其他原因是,它极大的缩短了用户与开发者、预期目标与实行情况、投资与回报之间的反馈回路。在面对持续改变的市场、业务过程以及持续发展的技术状态的时机,便需要有一种方法在比较短的时期内发展完善。实际上,所有的过程改进都不同程度的运用着戴明循环,以研究困难、试探处理方案、评估结果,从而依据已知的事实来执行改进,这就称之为基于事实的决策模式,我们都知道,这比前端预期的决策方式愈加有效。3)易于集思广益敏捷过程能有效应用的其他原因在于,它可以就一个困难集思广益。我们的经验告诉我们当一个困难发生的时机,总有某些人士知道困难所在,但他的看法却遭到忽略。比如航天飞机在起飞阶段发生爆炸,事后分析出了各种原因,但该种调查也供应给我们一个惊人的事实,就是部分工程师早就意识到这些潜在困难,却无法说服他人重视这个忧虑。对这些事实的深入思考,促使我们研究我们应当采取何种管理系统,使前线工作人士的经验、看法及忧虑得到充分的重视呢?对敏捷开发的误解误解一:敏捷对人的要求很高很多人在试图实行敏捷时称:敏捷对人的要求太高了,我们没有如此的条件,我们没有如此的人,所以我们没法敏捷。可是,敏捷对人的要求真的那么高么?软件归根见底依旧一种创造性活动,开发人士的技术水平和个人能力对软件的质量依旧起着决定性的作用,各种过程与方法导致帮助开发人士、试探人士等角色能够更好的合作,进而造成更高的生产力。不管用什么方法,开发人士的水准永远均为一个首要的原因。从其他角度来说:过程和方法究竟能帮开发人士多大忙?对于技术水平较低的开发人士,敏捷方法和传统方法对他的帮助是差不多的,所以看不足显着的效果,甚至某个时候仍有反效果;而伴随开发人士技术水平的提升,敏捷方法能够解开对人的束缚,激励创新,效果也会越来越显着。敏捷对人的要求并没有高,而且会帮助你培养各种所需的能力,诚然前提是你处在真正敏捷的环境中。误解二:敏捷没有文档,也不做设计这个误解从XP开始就没有停止过,XP激励“在非到必要且意义巨大时不写文档”。这里面提及的“必要且意义巨大”是一个分析标准,并没有是所有的文档都不写。比如,用户手册是不是“必要且意义巨大”?这取决于客户的要求,假使客户不需要,那就不用写,假使客户需要,就一定要写;再如,架构设计文档要不要写?复杂要写,不复杂不用写。一般架构设计只需要比较简单的文档,对于有些项目,一幅简单的UML图就够了。所以,写不写,怎么写,都要依据这个文档见底有多大意义,产出和投入的比例,以及项目的具体情形决定。事实操作时可以让项目组所有人士表决决定,尽量避免由某一个人(比如lead)来决定。至于设计,XP奉行的是连续设计,并没有是不设计。这事实上是将设计工作分摊到了每天的日常工作中,持续的设计、改观(重构),致使设计一直维持灵活牢靠。至于编码前的预先设计,Kent Beck等人的确实施着不做任何预先设计的开发方式,但是对于我们这些“非大师”级开发人士,必要的预先设计依旧需要的,导致不要太多,不要太细,要有将来会彻底颠覆的预案。误解三:敏捷好,其余方法不好有些人一提及敏捷就大呼好,只若是敏捷的实践就什么都好,而提及CMMI等方法就大呼不好,不管是什么只要沾上边就哪里都不好,疑似敏捷和其余方法是完全对立的。牛顿说过,我是站在了巨人的肩膀上。敏捷同样也吸取了其余方法论的优点,也是站在了巨人的肩膀上,敏捷任然维持了很多历史悠久的实践和原则,导致表现方式不同罢了。从其他方面来说,方法本没有好环,好与坏取决于能否适合处理你的困难。每一种方法都有他最善于处理的困难和最佳的发挥环境,在需求平稳、软件复杂度相对不高的时代,瀑布模型也可以工作的很好,而敏捷正好适用于改变快风险高的项目 - 这恰恰是当下很多项目的共性。所以选择一个方法或过程,并没有是依据它能否敏捷,而应依据它能否适合。而要了解一个东西能否适合,依旧要试图之后才知道,任何没有经历实践检验的东西都不可信。误解四:敏捷就是XP(极限编程),就是ScrumXP 和Scrum导致大量敏捷方法中的两种,仍有很多其余的敏捷方法。龙生九子各个不同,敏捷的这些方法看上去差别也是很大的,可是他们之所以被称为敏捷方法,就是由于他们后面的理念和原则均为相同的,这个原则就是《敏捷宣言》。学习敏捷不仅仅要学习实践,还要理解实践后的原则,不仅要理解怎么做,还要理解为何这么做,以及何时不要这么做。即便将XP或Scrum完全的应用的你的项目中,也未见得就能成功,适合别人的东西未必就适合你。敏捷的这些实践和方法给了我们一个起点,但绝对不是终点,最适合你的方式还要由你自己在事实工作中探索和寻求。误解五:敏捷很好,所以我要策划标准,所有项目都要遵循着个标准没有哪两个项目是一样的,客户是不一样的,人士是不一样的,需求是不一样的,甚至没有什么或许是一样的。不一样的环境和困难,用同样的方法处理,是不或许处理的好的。方法是为人服务的,应当为项目团队寻到最适合他们的方法,并非是先确定方法,再让团队适应这个方法。所以也不存在适合所有项目的统一的方法。任何企图统一所有项目过程的方法均为不正确的。同期,对于同一个团队,伴随项目的执行,对需求理解的深入,对技术理解的深入,一开始适合项目的过程和方法也会逐渐的不适合。这时候也需要团队对过程执行及时的调整,保证项目的质量和效率。敏捷是动态的,而非静止不变的,由于这个世界自身就是改变的,在改变的世界运用不变的方法,是不现实的。银弹从来就没有过,在有限的将来也不会存在。参考文献↑ Bluse Huang's cnblogs
标签:
随机快审展示
加入快审,优先展示
推荐文章
- 黑马在线:均线实战利器 7853 阅读
- 短线交易技术:外汇短线博弈精讲 3318 阅读
- MACD震荡指标入门与技巧 3453 阅读
- 黄金操盘高手实战交易技巧 3667 阅读
- 做精一张图 2612 阅读
热门文章
- 港币符号与美元符号的区别是什么啊? 21141 阅读
- 我国各大银行汇率为什么不一样啊? 9173 阅读
- 越南盾对人民币怎么算的?越南盾对人民币汇率换算方法是什么 8742 阅读
- 黑马在线:均线实战利器 7853 阅读
- 小白经济学 7435 阅读