美文网首页
编码自查-阿里云开发手册

编码自查-阿里云开发手册

作者: yangc91 | 来源:发表于2019-01-23 23:43 被阅读0次

    github地址

    学习阿里云开发手册,摘选出不知晓的、出过错的、记不住的条例,并附上自己的经历、解决方案等,方便以后强化记忆。

    编程规约

    常量定义

    【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。

    说明:大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解和维护。 正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

    代码格式

    【强制】左小括号和字符之间不出现空格;同样,右小括号和字符之间也不出现空格;而左大 括号前需要空格。

    反例:if (空格a == b空格)

    【强制】采用 4 个空格缩进,禁止使用 tab 字符。

    如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时, 请勿勾选Use tab character
    ;而在 eclipse 中,必须勾选
    insert spaces for tabs

    目前使用的是 Square code style, 一个 tab 为 2 个空格。

    【强制】IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式, 不要使用 Windows 格式。

    修改line separators方法

    【推荐】单个方法的总行数不超过 80 行。

    包括方法签名、结束右大括号、方法内代码、注释、空行、回车及任何不可见字符的总 行数不超过 80 行。 正例:代码逻辑分清红花和绿叶,个性和共性,绿叶逻辑单独出来成为额外方法,使主干代码 更加清晰;共性逻辑抽取成为共性方法,便于复用和维护。

    个人开发时有些方法业务逻辑太多,很臃肿,需提升设计、抽象能力,优化。

    【推荐】不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。 说明:任何情形,没有必要插入多个空行进行隔开。

    OOP 规约

    关于基本数据类型与包装数据类型的使用标准如下:

    1. 【强制】所有的POJO类属性必须使用包装数据类型。
    2. 【强制】RPC方法的返回值和参数必须使用包装数据类型。
    3. 【推荐】所有的局部变量使用基本数据类型。

    POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何
    NPE 问题,或者入库检查,都由使用者来保证。

    吃过 POJO 属性为基本类型的亏

    集合处理

    【强制】使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全
    一样的数组,大小就是 list.size()。

    :使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配
    内存空间,并返回新数组地址;如果数组元素个数大于实际所需,下标为[ list.size() ]
    的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集
    合元素个数一致。
    正例:

    List<String> list = new ArrayList<String>(2);  
    list.add("guan");
    list.add("bao");
    String[] array = new String[list.size()]; array = list.toArray(array);
    

    以前传的是长度为 0 的数组,未分配到指定长度

    【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方 法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

    asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。 Arrays.asList 体现的是适配器模式,只是转换接口,后台的数据仍是数组。

    String[] str = new String[] { "you", "wu" };
    List list = Arrays.asList(str);
    

    第一种情况:list.add("yangguanbao"); 运行时异常。
    第二种情况:str[0] = "gujin"; 那么list.get(0)也会随之修改。

    以前并不知晓

    【强制】泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用add方 法,而<? super T>不能使用get方法,作为接口调用赋值时易出错。

    扩展说一下PECS(Producer Extends Consumer Super)原则:第一、频繁往外读取内 容的,适合用<? extends T>。第二、经常往里插入的,适合用<? super T>。

    需时常翻看

    集合处理

    并发处理

    【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为
    static,必须加锁,或者使用 DateUtils 工具类。

    正例:注意线程安全,使用 DateUtils。亦推荐如下处理:

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override
    protected DateFormat initialValue() {
    return new SimpleDateFormat("yyyy-MM-dd");
    } };
    

    如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。

    控制语句

    【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。

    如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间 判断条件来代替。

    反例:判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变 成了负数,这样的话,活动无法终止。

    【推荐】表达异常的分支时,少用 if-else 方式,

    这种方式可以改写成:

    if (condition) { 
    ...
    return obj; 
    }
    
    // 接着写 else 的业务逻辑代码;
    
    

    说明:如果非得使用 if()...else if()...else...方式表达逻辑,
    【强制】避免后续代码维
    护困难,请勿超过 3 层。
    正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现, 其中卫语句示例如下:

    public void today() { 
        if (isBusy()) {
        System.out.println(“change time.”); return;
        }
        if (isFree()) {
        System.out.println(“go to travel.”);
        return; 
        }
        System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);
        return; 
    }
    

    注释规约

    异常日志

    异常处理

    【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。

    说明:如果 JDK7 及以上,可以使用 try-with-resources 方式。

    【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:

    1)返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
    反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。

    1. 数据库的查询结果可能为null。
    2. 集合里的元素即使isNotEmpty,取出的数据元素也可能为null。
    3. 远程调用返回对象时,一律要求进行空指针判断,防止NPE。
    4. 对于Session中获取的数据,建议NPE检查,避免空指针。
    5. 级联调用obj.getA().getB().getC();一连串调用,易产生NPE。
      正例:使用 JDK8 的 Optional 类来防止 NPE 问题。

    日志规约

    【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架
    SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    private static final Logger logger = LoggerFactory.getLogger(Abc.class);
    

    【强制】避免重复打印日志,浪费磁盘空间,务必在 log4j.xml 中设置 additivity=false。 正例:

    <logger name="com.taobao.dubbo.config" additivity="false">
    

    安全规约

    【强制】隶属于用户个人的页面或者功能必须进行权限控制校验。

    说明:防止没有做水平权限校验就可随意访问、修改、删除别人的数据,比如查看他人的私信 内容、修改他人的订单。

    需注意的地方

    【强制】禁止向 HTML 页面输出未经安全过滤或未正确转义的用户数据。

    可参考SpringMvc防御XSS实践

    【强制】在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放的机 制,如数量限制、疲劳度控制、验证码校验,避免被滥刷而导致资损。

    说明:如注册时发送验证码到手机,如果没有限制次数和频率,那么可以利用此功能骚扰到其 它用户,并造成短信平台资源浪费。

    设计时需注意

    【推荐】发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文本内容违禁词过 滤等风控策略。

    需学习

    Mysql 数据库

    【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。

    项目上遇到过此情况, 拆分大字段处理

    【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检 索速度

    image

    相关文章

      网友评论

          本文标题:编码自查-阿里云开发手册

          本文链接:https://www.haomeiwen.com/subject/fkeejqtx.html