作为一名程序员,在工作中大概率都会遇到接手老项目的情况。
- 跳槽从一个坑跳到另一个坑,接手老项目
- 同事内部活水了,他手上的项目都交接给你
- 团队“核心”成员要上新项目or重点项目了,团队人力资源调整,“核心”成员的老项目交接给你维护。
老项目谁接谁知道,不是坑就是泪。
前人新做的项目,拿了绩效+晋升,完事了抹抹嘴,扔给你。
别人吃完肉了,到你这,你还能喝到汤吗?
别说喝汤了,项目里的坑你都不知道在哪里,搞不好哪天出个问题,责任全在你这。
兄弟,既然工作中避免不了接手老项目,那咱就得思考怎么做老项目这项工作。
1,老项目之性能优化
做老项目,一个常见的思路是做性能优化。
先聚焦到一个突破口,找到一个性能差强人意的接口,提出改进措施。
别小看只是优化了一个接口的耗时,这就是整个工作的突破口。
有了这个突破口,慢慢地捋顺流程,就可以以点带面,提出项目中某一个环节的优化方案。
如果说优化了一个接口看不出什么工作亮点,但是要是能优化某个环节,这在leader那里绝对可以说是你工作上的一个亮点了。
这其实也是量变引起质变的思路,一个接口优化不足挂齿,但是把若干个接口优化包装成某个环节的优化,就能引起质变。
2,单个项目性能优化的常见思路
2.1 兵马未动粮草先行——先做性能监控
你可能听到产品或其他下游业务抱怨,哪哪哪慢了什么的,然后你就开始埋头改代码。
兄弟,等一等,工作不是这么搞的。
任何工作开始前,都要思考两个问题:该怎么做?怎么能证明我做了这个工作,并且做的很好?
你要优化一个接口的性能,首先要做的就是加上性能监控,拿出数据来说明某某接口耗时太高。这就是你工作的背景和出发点。最后再拿出优化后的接口耗时,一对比,就体现出你工作的效果了。
2.2 sql优化
大部分系统都是操作缓存或DB,性能优化的第一步就是做DB SQL的优化。
常见的sql优化措施:
- explain后,给table加上index
- 取消join,改为内存组装
- 慢/大SQL拆解。比如 in查询带上了1000个元素,这个SQL语句就变得很庞大,光在日志里打出来就好几行,那可以把in分拆为多个in查询。
2.3 代码优化
常见的代码优化措施:
for 循环里查db,改为in查询
for element in list {
// do something
sql query (element)
// do something
}
// 优化后
sql query in (list)
递归里查db,改为一把查出所需数据后内存构建
func buildTree(tree) {
if has child:
buildTree(tree)
// 递归里查db
sql query
}
// 优化后
// 先一把查出所需的数据
alldata = sql query
// 内存递归在数据上构建
func buildTree(alldata) {
if has child:
buildTree(alldata)
}
避免N*2 N*3的逻辑
避免二次方、三次方时间复杂度的代码逻辑。
- 剪枝,缩小计算范围。把不符合要求的数据先清理掉。
- 能提前返回的就提前返回,没必要再往下走。
- 空间换时间,使用Map Set等数据结构
2.4 2层cache大法
内存cache
一些几乎不变的数据,可以直接放在内存cache里,这样访问效率是最高的,比第三方cache如redis还要高。
第三方cache
如Redis。
对于变动较多的数据,则内存cache就不可用了,因为内存cache都是在各个实例内部,而请求往往是loadbalance到某一个实例,这就导致各个实例间内存cache数据不一致。
此时就得上第三方cache了。