转眼又是五个月,发生的事情颇多,最主要的是妻子顺利生产,我升级成了一名父亲。我觉得吧,程序员这个身份和父亲是冲突的,前几天听到一位同事开玩笑说,晚上回去完了也不敢大声怕吵醒了孩子,有时候一天都见不到孩子一面: ),带新生儿也是一件十分耗费心力的事情,夜里得起来好几次喂奶换尿布,妻子心疼我加班,工作日晚上是不会叫我起来帮忙的,真的辛苦她了。谈完生活,说说工作吧,这几个月中给我印象深刻的事情不少,总结一下:工作中不要干私活,不要夹带需求,这在大公司是大忌;程序员需要清楚业务,明白业务价值,或者说懂这样的程序员才有能更好的发展方向;说得好有时候真的要比做的好重要,虽然亲身经历时候挺毁我个人三观的。闲话说完,看看这段时间我在代码世界又学到了什么,又踩了那些坑。
1.最近学习使用了Java8相关语法,让我觉得很好玩的是,项目里只要有一两个人使用了新技术,那么这个技术就会慢慢在团队推广开来,因为其他人总会有维护或者接受的时候吧。关于Java8里面新增的接口,简单工具方法如Objects、Optional,lambda表达式、流习惯使用了真的爱不释手,可以新开一篇文章来写,我遇到的坑是当时用并行流时,偶现排序被打乱,但疑惑的是在网上查了下,大牛解释返回结果有序与否与是否并行流无关。另发现大家更多是在 forEach() 方法上碰到乱序问题,使用forEachOrdered()可以解决。
2.mybaties排序拼接出问题,别人的代码一眼没有看出来,查询的排序字段需要传进来,于是mapper语句就写成了 select * from table order by #{orderBy},看起来没有问题,实际上这里会预编译然后导致排序结果不正确,比如我传值 String orderBy = "id" 进来,最终语句会执行 select * from table order by 'id' ,注意id旁边的单引号,而且这个语句不会报错。当时问题1、2同时触发实在令人抓瞎。
3.最近简单学习使用 markdown 语法,的确比单纯的文本记录调理更清晰,持续学习中。https://www.cnblogs.com/nickchen121/p/10821946.html
4.最近还在某个配置中遇到了 YAML 语法,也是长见识,这里就不赘述,具体可以参见百度。
5.讲个代码规范导致的血案吧,是 switch 语句导致的,具体原因是在跳出的时候使用了return 而不是 break,这段代码出现在Ding Talk里面,由于最开始的版本是单条消息轮询处理,并没有出篓子,但是后来由于业务体量变大,做了一次版本升级,单条处理改成了批处理,return 导致很多消息的漏处理。还好发现及时,不然后果不堪设想。
6.在之前的文章里都提到了灰度方案和代码开关的重要性,阿里的发布红线:可监控、可灰度、可回滚都是金钱堆积出来的经验。这里为什么又提到灰度呢,是因为最近在某个业务场景里由于我的灰度方案没有延续性碰到一些问题。场景简述,灰度的科技可以体验新功能,我简单按照客户id取模来灰度的,customerId mod grayRule == 0;可以看出grayRule等于10时也就以为着10%的灰度,grayRule等于3时也就以为着33%的灰度,但是这里漏考虑一个问题,可能某个客户在10%灰度的时候能进入新功能,但是33%灰度时候反而进不去,那么客户就会产生疑惑。如果让我重新设计的话,我会吧灰度策略改成 customerId mod 100 <= grayResult,通过控制 grayResult 来扩大灰度范围。
7.切面编程,以前也提到过切点里面报错没有被方法里面的 try catch 捕获到的事例,这次我纯粹想吐槽不应将比较重要的代码放在切面里面,首先这样不利于以后的查找和维护,其次是容易出问题,哪怕后面的人只是 refactor 了类名或者方法名。
8.讲讲 Spring 相关的,起源与同事问我注解 @Autowired是不是可被继承,基于经验我说是,然后我打开 @Autowired 的源码试图找到元注解 @Inherited 的身影,到那时却并没有,这让我怀疑了下人生。复习了下,遂想起 @Autowired 的机制是 Spring 扫描代码时候看字段上面是否有注解来实现的,而且显然会扫到父类的可继承字段。很久没有学习 Spring 相关知识了,觉得关于Spring的生命周期又可以开一篇文章了。就使劲欠吧:)
9.Git 如何回退已经add 但没有 commit 的代码,由于升级了Source Tree,回退的功能居然没有了,只能找下命令行。https://blog.csdn.net/qq_41345773/article/details/92838092
10.drop、truncate和delete的区别。DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,DELETE操作不会减少表或索引所占用的空间。DROP命令则是删库跑路的意思。
最后想说的是,好记性不如烂笔头,特别是身处在复杂系统当中的时候,与君共勉,新年快乐,祝二零二零年生活零忧愁,代码零Bug,一切顺利。