河北创客情创业服务有限公司
邯郸软件开发 , 软件开发公司 , 软件定制开发公司 , 进销存软件
邯郸软件公司-如何开发合格的软件系统
发布时间:2023-04-06

怎么样才是合格的软件工程师?”。

曾经对这个问题有过很多思考,有积极的,也有消极的。积极时,觉得只要写的软件达到产品定义的功能并且没有重大bug便是一个合格的工程师。消极时,甚至在某些时候觉得自己压根不适合从事软件开发工作,觉得既不能“改变世界”,也不能随心所欲“为梦想发烧”。久而久之,觉得自己只是出卖了时间,为上层阶级贡献的新形式劳动力,虽然看起来像中产阶级,但和以前的“纺织工”并无二异.....有时候,并不复杂的功能却未能及早发现一些潜在的缺陷。

更多时候我会把根源归结于自己,但是这种情况多了,就会开始怀疑自己的能力。实际上,虽然确实有个人因素导致,但是就和学生时代一样,有时并非人本身能力不够,或者不爱学习,而是缺了个好的学习环境,一个相得益彰共同进步的小伙伴。因为个人的持续地自我驱动确实很难。

同理,一个合格的软件工程师,也依赖于一个良好的开发环境,工作环境以及流程。这就延伸出了这篇想要讨论的问题:

3016910089.jpg

什么才是合格的开发流程和互联网软件系统?

其实合格的开发流程与软件系统是同一个问题,互为因果。只要开发的流程合理,真的很难做出一个极其糟糕(不能用)的系统。我认为软件开发主要分为这么几块:

对产品需求的再次分析

由需求抽象出的软件架构设计

编码

测试

系统健康监控

故障修复

需求挖掘

上述的几个方面,如果一一展开,估计每个都能写本书。我并不打算面面俱到,而仅从作为好几年开发经验的软件开发者角度来聊聊这几个方面是如何影响后的结果。

对产品需求的再次分析

再次分析,并不是无意义,漫无目的地审视产品提出的需求,而是当产品将需求交到开发手中时,作为开发者的我们需要去思考

这个需求是为了什么?

为什么产品会提出这样的需求?

带过一些新人,也和一些同事一起工作过,有时候新人会胆怯不敢问产品“这个需求的初衷是为了什么”,而是接过需求,就吭哧吭哧开始编码。确实,很用功,效率也很高,工作态度也非常之好。但是我更建议的是,接过需求的时候,先理解一下产品提出这个需求的初衷是为了达到什么目的。为了达到这个目的而提出的这个需求,它是否合理,或者说是否是相对较优的一个方案。因为产品也是人,还是会存在欠考虑或者在某些领域并非精通的情况,特别是有些需求,达到的目的都是一样的,但是技术实现难度,用户的偏好却完全不同。作为开发,可以在自己的技术基础上给予产品多一些思考甚至引导产品的设计。这样有时候会比忙忙碌碌几周甚至个把月,后需求不达预期被取消,要好的多。软件的设计是多人参与的过程,每个环节都可以体现出开发的价值,从而让结果产生1+1>2的效果,也能建立起产品和开发之间的信任度。

摄图网_500327392_wx_计算器和眼镜组合拍摄(企业商用).jpg

由需求抽象出的软件架构

确定了产品需求和功能后,开发人员就需要对这些需求进行抽象,并对软件架构进行一些设计。

1. 对于日常的小功能迭代或者小需求。这块工作十分简单,大多数情况往往是在原有的基础上进行一些功能的支持,常常要做的无非就是增加一些class类或者在已有的class中加一些method便可,这个过程中相对关键的是需要对已有的class的理解,可能需要做一些调整,而不是简单的代码的累加。比如说原来设计的时候,并没有这些额外的功能,而当时可能由于时间紧迫或者尽可能简单地实现重要的需求而不会过度为将来提前设计这些模块,而导致当下添加这些新功能模块时,需要做调整,改变一些设计模式或者类继承关系,这一步是非常关键而且重要的,如果只是一味的功能的堆积会导致后续维护变得异常困难(而且我觉得只会堆积功能代码也没有一点点成就感)。因此,及时在实现新功能时做适当的调整就至关重要。否则,久了,大家谁也不想改,只想快速完成自己的工作,那么这块代码毋庸置疑就成了传说中的“屎山”。

2. 为一个从0到1全新的系统做设计。这块工作就比较考验一个人甚至几个人的架构能力。它需要开发者和产品一起,对要做的产品相当熟悉,全局上把握产品会有哪些功能模块,需要对这些功能模块做哪些拆分,逐步拆解成领域相对独立的微服务,这步我们可以称之为:“服务拆分”,此时往往是层的拆分。这块主要是将系统根据功能模块和后续的计划安排拆分成合理的服务模块。除此之外,还需要对微服务内部具体使用哪种缓存,哪种数据库,哪种日志系统,以及微服务间使用哪种RPC,哪种服务间鉴权认证,哪种服务外层网关等等,都需要考量。这块工作看起来不容易,但是也并没有想象中的难,因为大部分开发者经过几次设计后,往往对常用的几个技术和框架讳莫如深,从而在大部分情况下可以比较快的凭借“经验”得出几个备选方案,后往往是在这几个方案中根据业务的实际情况“择优”。这个设计工作往往决定了微服务架构的好坏,一个糟糕的拆分会导致业务团队之间可能做着重复且相似的工作从而浪费了开发资源,也有可能出现一个微服务拆分不到位导致一个微服务做了过多的职责而显得非常臃肿。上述两种情况在实际开发过程中往往需要业务团队的成员们主动“控诉”而及时做调整,因为设计者可能站在更高一个层面看问题,而没注意到一些困扰不同服务团队之间的这些设计缺陷。

对于上述提到的潜在问题,根据实际情况,建议再找一定数量的开发人员进行评审,使得尽可能在早期发现一些设计的缺陷和不合理的地方,从而及早修改,减少后期更改的代价。

编码阶段

如今需求已经明确,设计方案也落实了,顺理成章到了编码的时候了。编码的具体模式,技巧,此处略过不提。我认为,在此阶段,重要,必不可少且需要认真对待的是“Code Review”!

经历过很多公司:

有的公司完全没有Code Review,这导致的问题很明显:代码随意上线,隐藏了很多潜在的bug,且代码杂乱无章,毫无规范。技术强的开发人员或许提交的代码质量还行,但是如果遇到有些不负责开发或是受情绪的波动而不愿意再斟酌代码实现时,简直是场灾难。

有的公司Code Review形同虚设。没人认真review同事们的代码,随便“通过”。甚至有些同事出于对项目和代码的要求,仔细review并给对方了很多意见,反而会导致“惹人嫌弃”,被嫌弃给他制造了“麻烦”,耽误了功能的上线。

只有良好的Code Review氛围和流程才能保证尽可能减少bug的产生,提高代码质量,甚至提高开发团队之间的凝聚力。我个人认为Code Review 如同匠艺的“传承”,相互的“帮助”,以及实实在在地提高开发团队的“安全感”。

3018852627.jpg

传承:当团队来了新员工,如果是应届生,那么Code Review是对他们好的提高途径之一,能帮助应届生们快速提高编程技巧,传授我们这些老员工的“法宝”,增强应届生的工程意识。毕竟,不管是经历了多少学校项目或者算法比赛,真正到了工作中,往往需要有工程思维,结构思维,这对于刚毕业的人来说大多数情况下是缺乏的。因此,Code Review能快速帮助他们养成工程的思维和编程技巧。同时,更为重要的是,可以帮助他们避免很多“坑”,这些坑或许是缺乏考虑,或许是对于项目的不了解而没注意到的一些小细节。我相信,当我们认真对待每一个新人的Pull Request,为每次代码提交都尽心负责,并给予review的一些意见时,即便是在几年后,他们都不在同一家公司了,也会在某个时候突然想起,曾经有位同事给予了很多的帮助,提高了他的编程技巧,并在内心深深感谢这位同事的付出。对于那些职场老手,初来到新项目,code review也同等重要,大家来自五湖四海,都带着各自的编程风格,review这些老手的代码,不仅可以帮助他们尽可能符合当下公司的规范,当下项目的一些约定,提醒他们这个项目有哪些更深层的底层设计和“坑”,也能够反过来让我们这些reviwer学习到一些编程的新技巧,通过review他们的code来自我进步和提高。

帮助:Code Review的传承技艺,除了帮助新人(新员工)。实际上也能明显帮助到在公司多年的老鸟们(老员工)。因为人总会犯错,总会欠考虑,如同再牛逼的老司机也有出事故的时候,因此对于一个看起来很明确的需求,在实现的时候往往会存在一些细节,和边角,没有考虑到。一者,很多时候同一个项目,往往不同同事会负责不同模块,而忘了某些模块其实已经做了变更,所以没考虑到。二者,有些需求的细节确实也难以考虑周全。此时Code Review就能发挥项目组同事之间的智慧,发现很多潜在的细节,而这些细节既减少了bug的产生,帮助作者提高了质量,而这些反过来能让线上项目运行更加稳定可靠,进一步减少了on call值班时的负担。

安全感:如上述提到的,Code Review能帮助提高相互之间的编程技巧,提高项目质量,减少线上bug,降低值班的负担,终的结果也增加了整个项目组成员的安全感。这个安全感会发生在代码提交时的“不放心”,部署线上时的“怕有bug没发现”,和线上稳定运行时发生线上问题时“出的问题不熟悉”。Code Review就可以尽可能降低这些问题,让团队成员提高安全感。终,这种“传承”,“帮助”和“安全感”也就能让整个团队有更高的凝聚力和战斗力。

认真做好Code Review,至关重要!

测试

测试工作,有些公司是由专门的测试人员进行测试,有些公司直接没有测试人员而是由开发人员自行保证代码的质量和功能的完善。这两者各有优缺点,也都经历过这两者风格的公司。

但是,我认为不管是采用哪种方式,都有一个前提:不能盲目赶工期!

任何赶出来的代码,不管是谁来写,都会很糟糕。当明明需要4天的工作,被强制要求2天就要上线,那么再牛的开发,都会降低自己的要求,因为这样的加班会让人烦躁和厌倦,别提代码多完善了,能做完就“谢天谢地”了,谁还奢望代码质量有多好。只有不明真相的所谓“leader”才会觉得“你看,功能上线了,运行也完全没问题”,实际埋了不知道多少的雷,恶心的代码技术负债,导致接手的人不愿再重构(风险和所得不成正比),日积累月,终不得不停下来,为之前的负债做技术偿还。

还有一点是,赶出来的代码,会让测试人员也倍感痛苦。因为开发时间不够,那么开发人员不可能考虑全面,也不可能很仔细地自我测试。而是“差不多就完了,反正有测试,她们测了有问题再改,管它呢,时间不够了”。可想而知,这样的交付质量,到了测试那头,也是灰头土脸,既增加了测试的负担,也摧毁了测试和开发人员之间好不容易积攒的信任,倘若这样的代码终上线,出了线上问题,那到时候估计都会互相甩锅,“测试怪开发的代码一坨屎”,“开发怪测试没认真测”。终会导致一个恶性结果:

开发觉得:“领导傻逼,测试傻逼,公司傻逼”,“走人,老子不待了!”
测试觉得:“领导傻逼,开发傻逼,公司傻逼”,“走人,老子不待了!”

好的管理层,和负责的leader或许会从这样的一个结果中吸取经验教训,改善流程,避免这样的事情再发生。然而也有的“领导”,觉得这些人“怎么技术这么差,写的都是bug,这么点事情都做不好,还动不动离职!” 。这,我只能为这个项目组默哀了。然而讽刺的是,这种情况在国内很多互联网企业天天上演。

对于没有测试人员的公司来说,赶工期虽然不会再出现“测试甩锅开发,开发甩锅测试”的情况,但是也会导致代码质量的下降,因为实现这个需求的开发,受时间的限制不会写的完善,那么他提出Code Review的请求时,其他同事来review这块代码会非常之痛苦,觉得“为啥代码这么粗糙,这不是他的水平呀”,但是也会屈服现实,表示理解。Review的时候很痛苦,那么也会导致要么不敢给“通过”,要么随便给“通过”。不敢给“通过”是因为这个代码确实不够好,也没法很容易被review,或许还有连带责任。随便给“通过”是因为有时候同事之间感情很好,这个同事又被deadline折磨地常常加班,心力交瘁,此时就想尽可能让对方脱离这个局面,出于好心,“通过了再说吧”,“我相信他,代码虽然丑,但是应该没bug”。

上述这些情况都会导致整个开发团队凝聚力的下降,工作环境变得焦虑,长期以往也会导致人员的流失。如果遇上一个瞎指挥,独裁和不听下属反馈的管理者。那就是灾难。

系统健康监控

功能上线后,需要有一个完善的监控系统,其作用是监控系统和功能的健康。除了基础的系统资源的监控(如CPU,磁盘负载,数据库负载,用户请求量等)还需要监控诸如用户的使用成功率,用户每个使用场景出现异常错误的数量,等等。

拿我之前工作过的一家某二三线打车公司为例,这家公司有一个项目是做充电服务的。在其app中,用户可以通过该app对市面上大部分的充电桩进行扫码充电。它的系统监控是怎么做的呢?
不好意思,压根没有!我们不知道多少用户在扫码时因为哪些原因失败了,在什么时候失败多,什么时候成功多。我们也不知道大部分用户充电花了多少时间,不知道用户在支付的时候是否都成功了,还是说发生了异常。至少,其中很多结论都无法很方便地通过dashboard看出来结果,而是需要去登陆服务器去人肉搜log文本。这简直不可维护!而且更重要的一点是,我们作为服务的作者和提供者,反而不是时间知道服务出现故障,往往是等故障全面爆发后,产生了用户投诉才发现“原来系统出现故障了,原来系统又出bug了”。这简直无法接受!

因此,一个合格的系统健康监控(或者叫做告警系统)就显得很重要了,它能帮助开发者监控上线的功能在用户层面是否有发生异常,如果有,就可以立马进行警告,然后在这个异常全面扩散之前,或者在全部用户感知到之前发现问题,并尽快解决修复,如果无法马上解决,起码也可以尽早尝试缓和这个线上故障,争取尽可能少地影响到更多的用户群体。这样的系统,其实往往依赖于一个比较完善的日志系统,通过给每个功能,用户场景打印相关的日志,然后监控系统再根据开发人员的配置对这些日志依据一些规则进行检测和告警,达到自动化。然后Dashboard也是通过这些日志所收集的数据进行结果的聚集和展示。除此之外,开发人员和技术支持也能够像使用数据库sql语句一样,直接对日志进行结构化地搜索查询。这就能够让相关人员全面、快速和便捷地掌控服务的情况。

更重要的是,通过这样的一个告警系统,我们在日常的开发和维护过程中可以非常快速得到警告,并分析产生的原因,评估其问题的优先级,就可以在每次需求排期时安排到下一次开发计划中去,进而可以不断解决bug,打磨服务,提高服务质量,而不是等待压死骆驼的后一根稻草和造成雪崩的后一片雪花。

故障发现与修复

基于前文提到的“系统健康监控”,从积极一面看,我们更倾向于将故障修复的工作在日常开发维护中就进行按部就班的排期并完成。在修复之后,我们也可以根据监控系统来验证此问题是否已经被完全解决,是否改善了用户使用体验。因此,系统健康监控可以及时发现系统问题,告警系统故障,帮助发现故障,进而帮助开发团队能采取更加积极主动的措施来完善系统,做到“早发现,早治疗”,帮助开发人员减轻系统维护的负担,让系统告诉我们它是否生病了,而不是我们时时刻刻去盯着系统不断去轮训系统去询问系统是否病了。


展开全文
优质商家推荐 拨打电话