且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

代码与程序员的成效

更新时间:2022-08-22 13:49:52

缘起


话说,程序员的成效是否是一个重要的话题?谁应该关心?是度量程序员的管理者还是程序员自己?


话说,大家在大谈Google如何,回到座位又继续撸测试用例的时候,那些熟悉的数据准备动作、校验动作,然后是断言动作,有没有让人想吐的感觉!


我10年的时候,干了一件现在看来不靠谱的事情,就是把一个模块的代码测试覆盖率撸到了80%,接手的时候是30%的样子。为了撸,我让其中一位研发同学只补测试,补了一周。有人说了,单纯追求覆盖率是不对的,诚然!我在11年还整理过一个内部文档,如何做单元测试,不能为了测试而测试。但在哪个历史时期,我还是做了【正确】的选择,如果是一个拖了整个系统后退的模块owner,有何面目谈质量!!!


我在质量系列文章中前3篇中不经意有装X嫌疑,高大威猛;其实谁没有不堪回首的过去,那些血淋淋的过往需要回首对视呢?


从黑天鹅事件到墨菲定律

软件质量稳定性之殇

求解质量熵

本文姑且作为第四篇吧,念念不忘,或有回响。


卓有成效的程序员

【卓越成效的程序员】是若干程序员系列书籍我比较喜欢的一本,类似的还有卓越程序员密码【The Developer's Code】等。【卓越成效的程序员】高明之处是不仅仅给出原则,还大谈工具和代码,这如同诸多鸡汤文在【布道】的层面之下【实战】干货,可操作性强。这2天,重温了一下这本书给出的诸多原则,有些体会姑妄言之。


四大原则

四大原则是加速原则、专注原则、自动化原则和规范性原则。

  • 加速法则

加速法则,就是能加快我们工作的一切的东西。

  • Launchy 加载器

http://launchy.net/download.php#windows

  • 比如系统启动

最近一位同事做了一个热部署插件,解决容器在自测中启动的成本消耗。

  • 比如记住IDE快捷键


  • 专注法则

工作当中,专注可以很大的提高工作效率。

  • 排除干扰,隔离(带耳机、如设定专注编码时间段)
  • 关掉不必要的提示
  • 搜索优于导航,比如我想找一篇资料
    搜索可以使用本地搜索,比如google桌面搜索。

  • 自动化法则

自动化法则是把能自动化的一切都自动化掉

  • 不要重复发明***(***太多,乱花迷眼是又一话题;追求新***,又是技术人贪嗔痴的表现之一,热爱技术但忘掉了要解决的问题域)
  • 建立本地缓存
  • 使用RSS订阅我们需要的信息
  • 构建工具
  • 用Rake执行常见任务

ps:最近望神搞了一个eclipse插件解决了看起来很简单的一个问题,就是配置环境init。在一个新的space中load 配置,可以拥有你想要的java、maven、junit、checkStyle等一系列设置的内容。当然从频度来说,这属于低频,但仍然可以自动化掉。越高频的行为越应该优先实现自动化。

 关于发明***,有另外一个观点,就是基于提升技能的目的。不妨去做一下,对于问题域会有更深入的理解。


  • 规范性法则

规范很重要,这个可以减少不一致

  • 使用版本控制
  • 使用标准的构建服务器
  • 数据迁移,Ruby on rails里的Migration就很赞
  • 关于文档:错误的文档很糟,尽量生成所有的技术文档
  • 数据库结构 SchemaSpy可以生成数据关系图;开源的starUML可以生成类图结构
  • 减少重复,重复是软件开发中最大的阻力


代码与程序员的成效


关于文档的问题

关于要不要文档,文档写多少?

张老师如是说【文档方面目前个人觉得靠谱的做法是整理成思维树,标注定义,关键描述,关键词,关联词,详细文档link。对新人来讲更容易找到切入点,快速了解项目或系统全貌,已经可能与自己未来工作相关的上下文(内涵,外延)是什么。传统的文档管理方式往往使新人在浩如烟海的文档中迷失

孙老师提出:负责业务层的同学必须同步文档,否则会遭到移动客户端两个组前端用户层,开放商家层,内部管理层的投诉。我们最近就吃过这亏,有一个服务器同学写了一个接口文档,大概是一个参数,他定义的时候说的给的是 bool,但是没给事例,结果 ios 用的 YES 传的,安卓用的是 true,把 ios 的 YES 翻译过来就是 1 在判断的时候 1 和 true 是不相等的,因为类型都不一样,服务器的人和安卓对接完以为就 ok 了,结果上线了才发现有这个问题。


我的浅见:

  • 关于文档,项目研发过程中的关键文档需要保留和管理,比如需求和系分文档。这些是逐步堆积的过程中文档。
  • 一个系统/平台,需要有core文档,比如领域模型、主体架构等,由于这部分文档更新并不频繁,可以定期维护。
  • 用例即文档,验收测试及接口测试等保持稳定,是研究细节和用户场景的入手点。
  • 活文档:接口文档通过接口声明生成,接口声明对于每个参数都会有说明。批量接口,会给出数据量的limit,代码中也会进行防御;采用Swagger,在Swagger Editor中,我们可以基于YAML语法定义我们的RESTful API,然后它会自动生成一篇排版优美的API文档,API修改之后,API文档会随之而修改。


关于YAGNI

YAGNI(“You Ain’t Gonna Need it”)

你不会需要它,如无必要,勿增复杂度。


根据Cunningham & Cunningham的wiki页面所说:

即使你非常确信将来你需要某个特性,也不要现在就去实现它。在很多情况下,你会发现或许最终你不需要它了,或者是你真正所需的特性与你之前预计的有很大的出入。遵循YAGNI实践有两个主要原因:

  • 你节约了时间,因为你避免了编写最终证明不必要的代码。
  • 你的代码质量更高了,因为你使代码不必为你的“推测”所污染,而这些“推测”最终可能或多或少有些错误,但此时这些错误已牢牢地依附在你的代码中了。

Martin Fowler进一步表示,当我们在考虑推定特性时,很有可能我们是错的。在这种情况下,推定特性一个很明显的成本就是整个构建过程的成本,也就是对这个在当下没有用处的特性进行分析、编码以及测试所耗费的精力。他同时表示,假设我们对这个需求的理解恰好是正确的,但即使在这种比较理想的情况下,创建这个推定特性同样会带来两种巨大的成本。第一种成本是软件价值的延误成本,第二种成本是延续这一特性所带来的成本。

from http://www.infoq.com/cn/news/2015/06/yagni


关于YAGNI的思辨

如果对一个问题有2个解决方案,明明第二个解决方案更好【扩展性增强】,而实现成本相差无几,难道我要墨守此原则吗?

以我们团队的2个case来说明这个问题。第一个case是去年接到一个钱包积分的需求,经过分析,我们的设计不仅仅实现钱包积分,而是实现了商户通用积分的生命周期管理。因为后者有扩展性,并从业务嗅觉上依稀感受到未来或许有这样开放的必要。经过评估,实现成本没有增加太多,我们就果断采取了商户通用积分的实现方案。过了1年,果然,类似的需求来了...


第二个case,我们在14年底规划了一个券平台,解决此前各种红包、优惠类业务的烟囱架构的问题。这个平台的提出是基于若干需求背后的核心领域抽象,在8、9年前做红包系统的时候,是万不能想到的。也就是说对于问题域的本质认知,随着业务发展而发展,延迟设计决策是非常重要的,而把握这个度很难,没搞好,新装修的房屋不到2年就能翻新。

结论:YAGNI并非不做预设计,而是在成本、复杂度之间做权衡。光聪奉英杰为师,对于英杰非常崇拜。曾向我表示,英杰师关于YAGNI的观点与我有些近似。如果未来一个预期中的变化发生,而要付出的成本可能很大,我们眼前需要建立一些机制(比如抽象、约束)应对它。注意,只是建立机制,实现层面仍然按当前刚刚好的功能实现,除非你找到额外复杂度非常小的方案能把预期的变化也覆盖了,那么just do it!


定期检查阻碍,运用四大法则

如果说技术债是背在身上的猴子,总有一天会压得你喘不过气来;那么自发的提升研发过程的效能就是更好的追求。发挥程序员的三大美德,轻装上阵,让工作变得不一样。我们采取的是团队自发定期组织各种小沙龙,发现行径中的阻碍的模式,最近的一次沙龙收到10余条issue。比如下面这一条


代码与程序员的成效