检查清单(20200510)

1. 逻辑代码

1.1 基础开发

1.1.1 参数校验

  • 入参基本校验:金额不能小于0、不能大于余额、不能大于应还总额等。
  • 字符串非空。

  • 请求参数用 POJO 接收,POJO 的属性要添加基本校验注解,Controller 方法要用 @Valid 注解开启校验。

  • 正则表达式:用正则表达式进行参数校验时,不能写太复杂的,因为 Java 的正则引擎采用的是贪婪匹配模式。

1.1.2 跨系统调用

  • 超时限定:为了防止外部服务出现响应缓慢而拖累调用方,调用方必须设置连接超时、读超时等。

  • 幂等性,防止重复调用:调用方传递唯一的请求编号、服务方根据请求编号进行幂等性控制;

  • 重试:对于重要业务,调用方应该有重试机制,重试一定次数后仍然失败的,有告警出来,人工介入处理。

  • 调用链跟踪:

1.2 SQL

  • 检查SQL语句的执行计划,关注是否有全表扫描、索引全扫描。

  • 尽量把 1+N 次查询改写成 1或2 次查询。

  • 不能在字段上应用函数。

  • 字段应该单独在比较运算符的左侧。

  • 检查是否有隐式类型转换

    • 隐式类型转换会对扫描到的每条记录的字段进行转换,然后再进行比较,执行性能较慢,还会导致无法使用被转换列上的索引。
    • 比如 varchar(10) 类型的字段用 abc=40 则会进行隐式类型转换, abc='40' 则不会。
    • MyBatis在处理数据库 Date 类型时只能传 TIMESTAMP。 类型,与Oracle的Date类型进行比较会导致隐式转换。
    • MySQL 里如果比较的两个字符串列的字符集不同也会发生隐式类型转换。
  • join 的连接条件不要放到 where 子句,连接条件与过滤条件的执行顺序不同。

继续阅读

2018 年终总结

一、生活

最大的变化应该是变身房奴了,租房时房租每年涨10%,租金加上公积金再加小几千的现金支出够供房,所以也还好吧。

选择在南山买个老破小、而不去关外买个大点的,主要是考虑上下班方便,一般情况下坐公交半个钟能到公司,走路回来也只要50分钟。

国庆后老妈也出来深圳,回家吃晚饭的次数就多了,吃过晚饭去中山公园溜溜老婆也挺好。

二、工作

1. 拆服务

年初开始,大部门划分为多个小组,每个小组负责的模块都从原来的系统里拆分出来做服务,所有新项目基于 Spring Cloud 1.X 技术栈搭建。

我小组拆服务比较晚,正好可以看看其他组踩的坑,观察到的问题主要有:

  • Ribbon、Feign 的自动重试问题;对于没有做幂等处理的逻辑,就可能出现重复执行、数据重复等问题。

  • SpringBoot 默认的数据源属性前缀是 spring.datasource,Druid 连接池的 SpringBoot 的组件的数据源属性前缀默认是 spring.datasource.druid,这样可能导致配置不生效。还必须指定 Druid 获取连接的超时时间,否则可能都进入一直等待状态,应该是有活锁的bug。

"http-nio-8080-exec-100" #7057 daemon prio=5 os_prio=0 tid=0x00007fc83c0a3800 nid=0x1b99 waiting on condition [0x00007fd7c9a57001]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000000c2923bd8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:1444)
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1088)
at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:953)
  • 用 Apollo 做配置管理,要考虑 线程池、连接池的实时刷新问题。Apollo 一般只支持刷新 Spring 容器管理的 @Value 注解的属性,这些池的属性一般都是没有这样的注解的。

  • Hystrix 用线程异步执行调用时,导致调用链跟踪中断。这个是小问题,不影响业务。

别人踩的坑也是可以学习的;技术还是要自己去验证、不能网上直接抄段代码就用。

2. 项目质量

小组负责的模块是纯后台服务,业务逻辑比较复杂,偏偏又是跟钱相关,不能出错。代码质量、逻辑的正确就非常重要。

趁着这次拆服务,把单元测试做起来,觉得效果还是不错的。让一个实习生给一个逻辑写单元测试时,发现了一个之前没注意到的数据问题;自己给一个模块补充测试用例时,也发现在某个场景下的逻辑问题。

19 年准备采取如下的步骤来做单元测试:

  1. 与具体的开发同事一起做需求分析;
  2. 让开发同事根据需求做单元测试用例设计:把场景、边界值等列出来;
  3. 复核测试用例及实现,所有对结果的校验必须用断言来实现。

欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

2016 年终总结

一、工作

离开顺丰科技

在顺丰待满了刚好两年,选择离开。很感谢顺丰科技,在那里获得一段不错的经历。

加入友金所

离开顺丰后加入了友金所的资产端团队,即友金普惠。友金普惠的贷前贷后的管理系统是从一个厂商购买的,受限很大,进去后主要做一些新系统搭建、业务逻辑重写。

刚进去不久,因为一些定时任务出问题,其实是由于 Quartz 使用不当导致,基本上把 Quartz 关于并发控制的源码都看了遍。

做了个规则引擎,这个引擎是由规则+数据组成,规则由业务人员在网页上自己配置,数据主要是对接的合作方的数据、去第三方网站搜索的数据。

为了第三方网站搜索统一起来,对搜索的流程进行了封装,只要通过配置就可以直接把搜索结果转化为特定的 POJO。为了把网页信息提取为 POJO,基于 WebMagic 做了个组件来基于 XML 配置信息完成这个提取。

其他的主要是一些业务逻辑开发、重写,比如记账、扣款的逻辑等。

二、学习

虽然 RSS 订阅、微信公众号每天看,但这些都不是系统性的、零散,收获不多。

继续阅读

2015 年终总结

一、工作

工作上做了些功能、逻辑的优化,取得了一些的效果,大概有 4 个月几乎没有出现 IO 告警;系统优化需要持续进行,当前的 top sql 消除后,以前的次 top sql 又会变成新的 top。

主要的优化措施就是对大表做分区,尽量做到分区消除;对大表有关的统计不再实时统计,采用统计汇总表加增量统计的方式来优化;在业务上进行优化。

一大感触就是,起始设计非常重要,一开始的设计不合理,后期的优化、修复成本极其高昂。比如用户积分表只维护的用户的当前可用总积分,而没有维护历史总积分,而页面展示却需要历史总积分,导致每次展示用户历史总积分都需要实时从明细日志里累加出来。随着历史明细数据越来越多、用户数量和活跃度提高,这样的设计是没法支撑的,而如果要维护其历史总积分,现有3千万的用户,也非常不好弄。这种设计上的债务是长期存在的。有时候下定决心重新设计数据结构,迁移历史数据、代码上做平滑迁移的过程真的很酸爽。。。

多花精力在初始设计上!

二、学习

学习主要集中在 Oracle 数据库上,基本上把《基于 Oracle 的 SQL 优化》看了一遍。

因为工作需要,写了个 MyBatis 的批量插入的插件http://coderbee.net/index.php/open-source/20150721/1274

在学 Scala,看《深入理解 Scala》。

四、不足

看书太少,危机!

博客也写得很少。。。

五、高兴的事

找到女朋友啦,,^^,^^,,程序员知道这件事的重要意义啦。。。


欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。

2014 年终总结

今年过完春节回来就提离职流程走人,2月底到深圳后大概找了两周多,确定了现在的公司后是等入职流程两周,趁这个时间去了一趟帝都,也算出过省了哈,回来后就是往常的上班日子。

一、工作

在现在这家公司做的项目是面向互联网用户的一个网站,普通用户的访问量不大,数据量一般,千万级到亿级。系统的主要压力是在跟公司核心系统对接的 MQ 消息处理上,还有就是其他关联系统对我们系统的 API 调用。

这个项目是 13 年拼命赶出来的,今年是进入运维期,代码质量真不咋地;每天看着那样的代码,也经常在想,如果自己负责一个项目的研发,该怎么保证代码质量,在整理一份自己的项目规范,希望以后有机会实践下。

技术上没有太难的东西,能让我记起来的也就是定位解决了几个生产问题。

继续阅读

2013 年终总结

日志

09年毕业,工作4年多,以前都没写过年度总结。今年开始要在每年年底最后一周完成该年度的总结。诚如我的QQ空间的签名“有些事不记下来就象什么也发生过”,现在想想年初做过什么已经比较模糊了,希望用文字把记忆变得清晰点。

工作

本来这份工作面试时是说做移动网盘(叫彩云)后台的,结果各种原因项目留在南京,接不回来,新建的团队没有可以长期做的项目,做了几个小项目后在去年底就解散了。今年转到另一个项目组,主要是做彩云的web portal,也就是彩云的web客户端,这个东西每隔2、3个月就大改一次,要不然我早失业了。职责主要是写JS做业务展现、写一些Java代码调后台接口,开发速度相对还是比较快的,而且人也多,不会出现一个人负责很多模块。所以,上班时可以支配的时间还是不少的。

自我学习

既然上班都有可以支配的时间,自然还是要学点东西的。

总体情况

今年在工具的使用上有很大进步。早上上班前、中午都会刷下微博,可以了解下业界的新东西、别人的分享等等。学习了Markdown书写法,用印象笔记做了大量的笔记,搭建了自己的个人博客,到目前累计发表了94篇文章,访问量也过万了,还是挺满意的。8月份买了kindle,看了几本电子书,效果很赞的。早上搭公车也用微信看一些公共帐号。feedly的订阅更多了,要有选择地阅读。
继续阅读