其实,写代码的时候,没有必要写太多的注释,因为好的方法名、变量名,就是最好的注释。以下就是笔者总结的一些注释规范:
所有的类都必须添加创建者和创建日期,以及简单的注释描述
方法内部的复杂业务逻辑或者算法,需要添加清楚的注释
一般情况下,注释描述类、方法、变量的作用
任何需要提醒的警告或TODO
,也要注释清楚
如果是注释一行代码的,就用//
;如果注释代码块或者接口方法的,有多行/* **/
一块代码逻辑如果你站在一个陌生人的角度去看,第一遍看不懂的话,就需要添加注释了
以下就是一些添加注释的demo:
public class TianLuoClass {
/**
* 这是卖田螺的两法,它将两个田螺的价格整数相加并返回结果。
*
* @param x 第一个整数
* @param y 第二个整数
* @return 两个整数的和
*/
public int sellTianLuo(int x, int y) {
return x + y;
}
}
error、warn、info、debug
四种,不要反手就是info
userId,bizSeq
等等,不方便问题排查userId
非空检查、金额范围检查、userName
长度校验等等。一般我们在处理业务逻辑的时候,要遵循先检查、后处理
的原则。varchar(16)
,对方传了一个32
位的字符串过来,你不校验参数,插入数据库直接异常了。获取对象的属性时,都要判空处理。要不然很多时候会出现空指针异常。
if(object!=null){
String name = object.getName();
}
如果你要遍历列表,也需要判空
if (CollectionUtils.isNotEmpty(tianLuolist)) {
for (TianLuo temp : tianLuolist) {
//do something
}
}
Exception
异常,而应该尽可能捕获特定的异常finally
块中释放资源,或者使用try-with-resource
e.printStackTrace()
,而是使用log
打印。catch
了异常,要打印出具体的exception
,否则无法更好定位问题Throwable cause
RuntimeException
,或者直接抛出Exception\Throwable
。ConcurrentHashMap
是线性安全的,HashMap
就是非线性安全的version
控制,悲观锁一般用select …for update
sychronized ,reentrantlock
Redis
分布式锁或者走zookeeper
Test
,如:CalculatorTest
.test
开头+ 测试的方法,如testAdd
.75%
.Redis
异常.80
个字符类变量、实例变量、构造函数、公共方法、私有方法
等。代码评审的时候,要重点关注是否考虑到了接口的兼容性.因为很多bug都是因为修改了对外旧接口,但是却不做兼容导致的。关键这个问题多数是比较严重的,可能直接导致系统发版失败的。新手程序员很容易犯这个错误哦~
所以,如果你的需求是在原来接口上修改,尤其这个接口是对外提供服务的话,一定要考虑接口兼容。举个例子吧,比如dubbo接口,原本是只接收A,B参数,现在你加了一个参数C,就可以考虑这样处理:
//老接口
void oldService(A,B){
//兼容新接口,传个null代替C
newService(A,B,null);
}
//新接口,暂时不能删掉老接口,需要做兼容。
void newService(A,B,C){
...
}
代码评审的时候,要关注程序逻辑是否清晰。比如,你的一个注册接口,有参数校验、判断用户是否已经注册、插入用户记录、发送注册成功通知等功能。如果你把所有所有功能代码塞到一个方法里面,程序逻辑就不清晰,主次不够分明,反例如下:
public Response registerUser(String userName, String password, String email) {
if (userName == null || StringUtils.isEmpty(userName)) {
log.info("用户名不能为空!");
throw new BizException();
}
if (password == null || password.length() < 6) {
log.info("密码长度不能少于6位!");
throw new BizException();
}
if (email == null || StringUtils.isEmpty(email) || !email.contains("@")) {
log.info("邮箱格式不正确!");
throw new BizException();
}
Response response = new Response();
UserInfo userInfo = userService.queryUserInfoByUsername();
if (Objects.nonNull(userInfo)) {
response.setCode(0);
response.setMsg("注册成功");
return response;
}
UserInfo addUserInfo = new UserInfo();
addUserInfo.setUserName(userName);
addUserInfo.setPassword(password);
addUserInfo.setEmail(email);
userService.addUserInfo(addUserInfo);
MessageDo messageDo = new MessageDo();
messageDo.setUserName(userName);
messageDo.setEmail(email);
messageDo.setContent("注册成功");
messageService.sendMsg(messageDo);
response.setCode(0);
response.setMsg("注册成功");
return response;
}
其实,以上这块代码,主次不够分明的点:参数校验就占registerUser
方法很大一部分。正例可以划分主次,抽一下小函数,如下:
public Response registerUser(String userName, String password, String email) {
//检查参数
checkRegisterParam(userName, password, email);
//检查用户是否已经存在
if (checkUserInfoExist(userName)) {
Response response = new Response();
response.setCode(0);
response.setMsg("注册成功");
return response;
}
//插入用户
addUser(userName, password, email);
sendMsgOfRegister(userName, email);
//构造注册成功报文
Response response = new Response();
response.setCode(0);
response.setMsg("注册成功");
return response;
}
private void sendMsgOfRegister(String userName, String email) {
MessageDo messageDo = new MessageDo();
messageDo.setUserName(userName);
messageDo.setEmail(email);
messageDo.setContent("注册成功");
messageService.sendMsg(messageDo);
}
private void addUser(String userName, String password, String email) {
UserInfo addUserInfo = new UserInfo();
addUserInfo.setUserName(userName);
addUserInfo.setPassword(password);
addUserInfo.setEmail(email);
userService.addUserInfo(addUserInfo);
}
private boolean checkUserInfoExist(String userName) {
UserInfo userInfo = userService.queryUserInfoByUsername();
if (Objects.nonNull(userInfo)) {
return true;
}
return false;
}
private void checkRegisterParam(String userName, String password, String email) {
if (userName == null || StringUtils.isEmpty(userName)) {
log.info("用户名不能为空!");
throw new BizException();
}
if (password == null || password.length() < 6) {
log.info("密码长度不能少于6位!");
throw new BizException();
}
if (email == null || StringUtils.isEmpty(email) || !email.contains("@")) {
log.info("邮箱格式不正确!");
throw new BizException();
}
}
CSRF
令牌,以防止未经授权的人员执行这些操作。@Transactional
的声明式事务。因为 @Transactional
有很多场景,可能导致事务不生效。 大家可以看下我的这篇文章哈: 美团二面:spring事务不生效的15种场景数据库、Redis、RocketMq
等的中间件时,我们需要关注这些中间件的一些注意事项哈。SQL
时,如果条数不明确,是否加了limit
限制限制SQL
是否有监控Redis
:
hgetall、smember
远程调用是代码评审重点关注的一栏,比如:
HTTPS 或 SSL/TLS
。