首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >规范与避坑指南

规范与避坑指南

作者头像
IT技术小咖
发布2021-02-22 16:50:24
8270
发布2021-02-22 16:50:24
举报
文章被收录于专栏:码上修行码上修行

1. Git 使用避坑指南

1)切分支出错

master 主分支,即生产版本,xx_test 分支对应测试环境分支,请基于 xx_test 分支拉功能分支开发。比如两个新需求同时开发,项目管理人员此时需基于 xx_test 拉出两个功能分支,分别是 feature-a 分支和 feature-b 分支。开发人员检出对应的功能分支,并在其上开发。

粗心的开发人员忘了切换分支,直接在检出的 master (xx_test 分支)开发、合并或提交。容易参数代码混乱。

2)测试完过早合并至 master 主分支

如 feature-a 分支 和 feature-b 分支对应两个功能需求,需求 feature-b 功能先开发测试完,然后合并至 master 主分支,这时产品和项目经理确定发版内容为 feature-a 分支功能,由于开发人员疏忽,导致 feature-b 也上线了,容易出现生产事故。

开发完合并至 xx_test 分支,测试环境测试完成,待发版时,再合并到 master 主分支。

3)merge 代码冲突解决不当

feature-a 分支 或 feature-b 分支开发完成,git merge 到 xx_test 分支时,如果涉及其他开发人员提交的内容,且不确定,错误删除了别人的代码。

请与相关需求对应的开发人员一同解决代码冲突问题。

4)遵循一个分支只做一件事

feature-a 分支只开发新的需求 a,此时开发人员看到某个方法觉得编码不太规范,顺手优化一下,结果优化完,没有和测试人员或项目经理说,等上线完,线上出现问题,为时已晚。如果有修改非新需求的代码,请告知测试或产品进行回归测试相关系统的一切功能。

建议优化代码时,另拉出一个 optimize-a 分支进行优化或重构。

5)同一个功能开发人员 commit 多次,不利于阅读,合并提交记录

为了使分支提交记录更清晰,需要合并多次提交为一次提交。

①第一种方式交互式,主要涉及的 git 命令如下:

# 得到需要合并提交记录的前一个提交记录的 commitId
git log  
# 进入交互式修改,以其中一个 pick 为基准,其他需要合并的 commitId 前的pick 修改为 squash(简写 s),保存修改并退出即可
git rebase -i [commitId]  
# 推送至远程仓库
git push 
# 或强制推送至远程仓库(谨慎使用)
git push -f  

②第二种方式回滚,主要涉及的 git 命令如下:

git log
# 比如合并前三个,commitId 是前第四个的提交记录
git reset [commitId]  
# 添加至暂存区
git add .
# 提交至本地仓库
git commit -m “commit msg”
git push 或 git push -f

功能分支的代码合并至 master 分支后,提交记录更合理清晰,方便其他开发人员了解或是 code review。

2. 数据库避坑指南

1)业务上唯一特性的字段(或组合字段)请建立唯一键约束

避免出现诡异现象或是导致业务上出现错误,增加排查的难道或是编码复杂。

很多人认为,保证唯一性,“先查后插”。其实高并发场景下,如果没有进行同步操作,两个事务同时开启,查数据库没有,然后导致数据库插入了两条重复的数据(即产生垃圾数据)。

可能的影响有:Dao 层出现 sql 执行异常,业务逻辑层处理与实际不符等等。

2)delete 操作时请注意带上 where 条件

开发人员,在写 delete 语句时,请先带上 where 条件查询数据库,看数据是否符合删除的逻辑,然后再写 delete 语句删除相应条件下的垃圾或是废弃数据。

delete ... where条件很重要

3)由于业务需要某旧表新增字段,设置 NOT NULL 请谨慎!

可能影响其他接口业务逻辑插入该表,没有插入非空字段,导致线上系统接口异常。

如果新增字段为空,请检查相关接口,或是设置默认值。

4)新增字段考虑是否创建索引

大多数人在建新表时,有意识的新增索引,但是在旧表新增字段时,却忘记创建索引。后期因为数据量大或是并发高,导致数据库性能下降。

如果新增字段是 where 查询条件,请考虑创建索引或是组合索引,避免出现数据库查询性能问题

5)使用 insert into 语句注意字段对应关系

强制使用 insert into table_name (field1, field2, ...) values (value1, value2, ...);

禁止使用 insert into table_name values (value1, value2, ...);

如何新增字段,可能导致其他接口服务报错(sql 语法错误)

6)分页查询条数限制

在数据库分页查询时,mysql 中 select * from table_name limit m,n; 注意对 n 参数校验,防止每页查询的数据量过大,导致内存溢出;oracle 中 select * from (select * from (select rownum rn, t1.* from (select * from page_table_name) t1) where rownum <= currentPage * pageSize) where rn > (currentPage - 1) * pageSize; 注意对 pageSize 参数校验,防止每页查询的数据量过大,导致内存溢出。

分页查询需对每页条数参数校验,防止发生线上系统出现OOM

7)避免数据库长事务发生

批量入库操作时,循环结束后再提交可能引起长事务发生,注意每多少条 sql 执行一次提交;多个 sql 执行顺序、执行时机按业务逻辑和性能调到最优。

长事务易触发数据库机制导致kill进程或是数据库阻塞等,合理事务范围及事务耗时。

8)大表创建索引或 DDL 避免高峰期执行,或是升级停库时执行

大表创建索引或是执行 DDL 时,引起数据库表锁表,对高峰期业务接口响应影响较大。

创建索引或执行 DDL 时停机执行。

9)where 条件少写 (field != 'X' 或者 field <> 'X')

可能会出现结果集不符合预期。比如数据库字段 field 不是 NOT NULL,where 条件如果是 field != 'X' 此时查询的结果集不全(不包含 is null),所以 where 条件应该是 field is null or field <> 'X'。

一般建议创建新表定义字段时,添加 not null 约束。另外查询条件不建议使用 != 或 <>,这样索引可能失效,尽量使用等值或范围查询。

10)单表或多表关联分页

如果执行计划出现 SORT ORDER BY,一般这种分页查询的 sql 是有问题的。

利用索引的有效性,等值查询,创建组合索引(等值过滤条件与排序字段优先组合、非等值过滤条件放在后面,其中等值过滤条件能过滤掉大量数据的放在最前面)等;

多表关联分页,走嵌套循环,如果驱动表返回的数据是有序的,那么关联之后的数据集也具备有序性。

让参与排序的表作为嵌套循环的驱动表,其他关联表对应的连接列创建索引。如果存在外连接,选择主表列作为排序列。语句中不能存在 distinct、group by、max、min、avg、union、union all。

11)oracle 分页 sql 写法误区

select * from (select t.*, rownum rn from(select * from tmp) t) where rn >= 1 and rn <= 10;

上面的分页查询 sql 是错误的写法。

这种写法没有使用到 oracle 的 COUNT STOPKEY 特性,即获取到分页的结果集后 sql 立即停止运行。

正确的写法应该如下:

select * from (select t.*, rownum rn from (select * from tmp) t where rownum <= 10) where rn >= 1;

走索引排序。使用 COUNT STOPKEY 特性。如果有过滤字段,可以考虑组合索引,如果过滤条件能够过滤大部分数据,排序列可以不包含在索引中。

3. Java 避坑指南

技术原理理解不到位带来的性能问题或坑。可参考《阿里巴巴Java开发手册》

举例说明:

1)创建 ArrayList 或 HashMap 时,合理设置集合初始化容量

避免集合扩容带来的性能消耗。

集合都有默认初始化容量和扩容机制,多次扩容会引起性能问题或接口响应变慢等。

2)谨慎使用 ArrayList 集合的 subList 方法

subList 方法返回的子类是 ArrayList 内部类 SubList,是原 ArrayList 的地址引用(和数据库视图有点类似)。

对subList返回的结果操作会反映在原ArrayList集合上,而对原集合进行结构变化,会触发并发修改异常

3)合理使用 Executors 构造线程池,最好使用 ThreadPoolExecutor(7参)构造

避免 Executors 构造的无限线程或是无界队列造成 OOM 异常。

根据任务是 I/O 密集性还是 CPU 密集性,合理设置线程池参数(核心线程数、最大线程数、任务队列、拒绝策略等),使线程池发挥最大功效。

4)开启事务时,注意事务隔离级别、回滚条件、传播策略、事务超时设置

MySQL 数据库默认事务隔离级别是RR(可重复读);Orcale 数据库默认事务隔离级别是RC(读已提交)。针对RC,会出现幻读,不可重复读。事务回滚条件设置(捕获程序异常时注意)。传播策略默认是当前有事务直接加入该事务,没有事务新建事务。设置合理的事务超时时间(数据库管理系统内置有相关的参数设置)。

养成好的习惯很重要!

举例说明:

1)开发前没有仔细梳理需求、绘制 UML、时序图、活动图的习惯(针对开发人员、技术经理);

2)开发时没有自我 code review 的习惯(针对开发人员、技术经理);

3)测试时没有看 error log 的习惯(针对开发人员、测试人员);

4)上线前没有检查各种 properties file 的习惯(针对开发人员、技术经理);

5)上线过程中和上线后没有关注线上系统日志和系统监控的习惯(针对开发人员、项目经理)。

编码规范很重要!可参考《阿里巴巴Java开发手册》和《Google 开发编码规范》

举例说明:

1)int a,b,c = 0; 命名不规范,debug 不方便(建议定义变量时一行一个);

2)定义变量,作用域最小化,遵循就近原则,对象引用范围最小化(比如:静态成员变量中引用了其他类对象);

3)合理使用强引用、弱引用、软引用、虚引用。

4)规范日志记录,使用占位符(减少拼接字符串的性能消耗);

不规范:log.info(“programme_id:” + programmeId + “, appl_no:” + applNo);

规范:log.info(“programme_id:{}, appl_no:{}”, programmeId, applNo);

5)Controller 控制层严格接口参数校验,Service 业务逻辑层处理业务操作并减少与数据库交互次数(合理使用事务),Dao 层操作数据库;

6)sql 编写规范,where 条件要求走索引(索引优化、组合索引)等。

多交流、多讨论、多思考、多学习、多积累、多实践

1)持续学习、积累项目经验;

2)业余时间多研究框架源码;

3)积极参与需求讨论,合理设计解决方案。

4)积极思考业务场景,简化优化流程,提高用户体验;

5)多看别人的优秀代码并讨论,减少不必要的开发和踩先人以前的坑;

6)养成持续优化持续重构的意识。

加油

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上修行 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档