java高级需要掌握的基础

JAVA基础

  1. 超过3层if else 的逻辑判断代码可以使用卫语句,策略模式,状态模式来实现

  2. 字段,类属性声明尽量不要使用is,get,set开头,容易出现错误读取

  3. 避免使用"等于"判断作为中端或退出条件,最好使用大于或小于区间判断条件

  4. if条件里面不要执行复杂语句进行条件判断或者赋值判断,可以再外面给一个boolean值,在if里面用这个值进行判断

  5. try-catch尽量不要放到for循环里去,最好能移到外面就移到外面

  6. if条件判断,尽量不要使用取反!操作, 能正着取值就正着

  7. try-catch块包含的内容要尽可能少

  8. 批量查询的公共接口,最好加一个入参保护,即最多提供多少数量的解析,防止后台爆掉

  9. 下列情况需要做参数校验

    1. 调用频次很低的方法
    2. 执行时间开销很大的方法
    3. 需要极高稳定性和可用性的方法
    4. 对外提供的开放接口
    5. 敏感权限入口
  10. 下列情况可以不做参数校验:

    1. 极有可能被循环调用的方法
    2. 底层调用频次比较高的方法
    3. 被声明private只会被自己代码调用的方法
  11. 标记待办事宜todo ; 标记此段代码错误不能工作FIXME; 记得及时处理掉

  12. 使用正则表达式时,利用预编译功能,可加快匹配速度,例如如下代码不要写在方法体里面

    Pattern pattern = Pattern.compile("规则")
    
  13. 不要使用apache BeanUtils 进行属性copy, 可以使用spring BeanUtils, cglib BeanCopier

  14. switch入参为string时,必须做null判断在使用,否则连default都不会走

  15. 所有的转int,double, float, long 最好是先转成string,在进行操作,防止出现精度丢失

日期时间

  1. 如果是jdk8的应用,可以使用Instant代替Date类 , LocalDateTime代替Calendar类, 获取纳米级别时间用System.nanoTime()
  2. 日期格式化 yyyy-MM-dd HH:mm:ss, MM大写代表月份, HH大写代表24小时,其他要小写

集合处理

  1. 只要重写了equals,就必须重写hashCode

  2. 判断集合内部元素是否为空,使用isEmpty()方法,不要用size()

  3. 使用list,map集合进行遍历时,不能对其进行增加和删除操作,会抛出异常,应使用iterator遍历方式操作,如果并发操作,需对iterator对象、进行加锁

  4. 使用集合转数组的toArray(T []array),直接toArray()会出现接收值时Object[]类型, 应传入一个类型一致,长度为0的空数组进去

  5. 使用Collection接口的addAll()方法是,要对输入的集合参数进行NPE判断

  6. Arrays.asList()方法转成的集合,不能使用它的add/remove/clear方法,否则会报错,因为转之后的集合其实是Arrays的内部类,不具备集合的方法,该方法体现的适配器,后台数据仍然是数组

  7. 无泛型集合给泛型集合赋值时,要注意使用instanceof进行类型判断,否则赋值时不报错,使用时会报类转换异常,例如

    List  a  = null;
    List  b  = new  ArrayList(8);
    b.add(1);
    a = b;
    则使用a.任何属性操作,都会报类转换异常
    
  8. 集合泛型的写法:HashMap如果不给默认值,在高并发场景,可能会出现cpu飙升

    // 后面实现类<>可以直接使用,不用写<String,String> 
    HashMap<String,String>  map = new HashMap<>(16);
    // 也可以全省略
    ArrayList<User>  user = New  ArrayList(10);
    
    注:括号里面的参数一定要给,如果不确定,默认给16, 参数值=(需要存储的元素个数 / 0.75) + 1
    
  9. 使用Map的遍历,不要遍历keyset和values, 要使用entrySet方式,可以返回k-v

  10. Map集合k/v不能为空的情况,如下表格

    集合类 key value super 说明
    HashTable 不能为null 不能为null Dictionary 线程安全
    ConcurrentHashMap 不能为null 不能为null AbstractMap 锁分段技术(jdk8:CAS)
    TreeMap 不能为null 允许为null AbstractMap 线程不安全
    HashMap 允许为null 允许为null AbstractMap 线程不安全

POJO

  1. 所有的pojo类属性,必须使用包装类数据类型(防止数据库接受出现NPE异常),所有的局部变量使用基本数据类型
  2. 定义DO/DTO/VO 等POJO类时,不要设定任何属性的默认值
  3. 构造方法里面 , 禁止加入任何业务逻辑,如果有初始化,可放到init方法里面
  4. POJO类必须写toString()方法
  5. 字段,类属性声明尽量不要使用is,get,set开头,容易出现错误读取
  6. split方法获取的数组,需要做内容检查,防止空值,出现数组越界异常
  7. get,set方法内,不要增加业务逻辑,增加排查问题的难度
  8. 循环体内,用stringbuilder的append方法进行扩展

前后端协作

  1. 前后端数据列表相关接口返回,如果为空,则返回空数组[]或者集合{}, 尽量不要返回null, 或者添加code,msg值,返回成功或者失败
  2. 前后端交互的数据中,所有key必须都是小写字母开始的骆驼表达式,最好定义DO(数据对象)
  3. 后端返回给前端的int,long,double,float值,尽量使用toString(),返回给前端
  4. 前端传给后端的字段,尽量不要超过2048个字节,超过可能会出现异常情况,可以传关键字段,后台掉接口去查一遍(针对频次不太高的)

并发操作

  1. 自己定义的ThreadLocal变量,尤其在线程池场景下使用的,尽量在代理方法中使用try-finally块进行回收threadLocal.remove()

  2. 在使用lock.lock()时,要保证该代码与try之间不要有异常场景发生,不然容易造成无法解锁

  3. simpleDateFormat是线程不安全的类,一般不要定义为static,如果要定义,请加锁,或者使用DateUtils工具类也可

  4. 在使用尝试机制获取锁之前,先判断是否持有锁:

    Lock  lock = new  XxxLock();
    ....
    boolean   islocked = lock.tryLock();
    if(islocked){
        try{
            ....
        }finally{
    	    lock.unlock();
        }
    }
    
  5. java并发包,如果主线程创建多个子线程进行处理多个逻辑,又想在处理结束后保持同步操作,需要在每个线程退出前调用coundDown方法,主线程使用CountDownLatch进行异步转同步操作,具体使用方法自行百度

  6. volatile 解决多线程内存不可见问题, 如果是count++操作,推荐使用

    AtomicInteger  count = new AtomicInteger();
    count.addAndGet(1);
    // 如果是jdk8,推荐使用LongAdder对象,比AtomicLong性能更好
    

异常日志

  1. 错误码5位: 来源分3类:例如:A/B/C ,A代表来源于用户,B代表来源于业务逻辑,C代表来源于第三方系统, 后面4位数字,从0001到9999,可以定义为不同的错误类型常亮或者枚举
  2. finally里面不要有return,否则会直接放弃掉try的return; 流程是执行完try,并不会直接返回,而是执行完finally,然后在返回
  3. 防止NPE,可以使用jdk8的Optional类来做,具体自行百度
  4. String.format可以用来做占位符输出,还有logger.debug等也有对应的占位符写法
  5. 对于dao层出现异常,推荐自定义异常,命名用DAOException , Service层出现异常,用ServiceException 异常类处理或者抛出

数据库

  1. 单元测试方法之间是独立的,不能相互引用
  2. 数据库表名,字段名,尽量使用小写字母表示,不要使用大写字母
  3. 小数类型是decimal, 禁止使用float,double, 会出现精度丢失
  4. 业务上具有唯一特性的字段,即使建立了组合索引,也必须建成唯一索引, 唯一索引insert速度可以忽略不计,但是提高查询速度很可观,而且没有唯一索引,必然会有脏数据产生
  5. 查询全表,适当每次查所有数据集合时做好分页
  6. 页面搜索严禁左模糊或者全模糊,因为索引文件具有B-Tree的最左前缀匹配特性,如果左边的值不确定,那么无法使用此索引
  7. where最先筛选出元素的条件放到前面,记得索引优先,匹配度最高的在最左边
  8. 不要使用count(列名),count(1) 来代替count(* ) , count(* ) 会统计null行,其他的可能会忽略统计; count(distinct col1)计算该列除null的不重复行数, count(distinct col1,col2) 如果其中有一列全是null, 那么另一列即使有不同的值,也返回0
  9. 使用sum时要注意结果空值判断,可使用如下方式:select IFNULL(SUM(col1), 0) from table;
  10. 使用ISNULL(col1) 来判断数据库null值比较高效而且简洁
  11. 禁止使用存储过程,难调试,难扩展,更没有移植性
  12. sql语句中表别名必须加, 防止后面关联sql查询出现相同列,导致异常
  13. in操作能不用就不用,即使要用,也要评估in后面的数据不能超过1000个
  14. truncate table 不要用,因为不会触发事务,容易出现问题
  15. POJO类的布尔属性不能加is , 而数据库boolean字段必须加is_ , 因为强制要求,必须在xml中做resultMap的映射,时字段与DO类解耦,方便维护
  16. 尽量不要使用HashMap和Hashtable作为结果集直接返回,容易出现字段类型转换错误, 推荐使用DO
  17. mybatis 中的 isNotEmpty表示不为空并且不为null时执行, 而isNotNull表示不为null值时执行

工程结构

  1. 分层领域模型:
- DO : 与数据库表机构一一对应,DAO层向上传输的数据对象
- DTO : 数据传输对象,service层之间传输的数据对象
- BO : 业务对象,由service层输出的封装业务逻辑的对象
- Query :数据查询对象,各层接收上层的查询请求, 禁止使用Map类来传输
- VO : 显示层对象,通常是web向模板渲染传输的对象

开头:

1.介绍下最近这个项目,项目背景,上下游关系,主要功能,应用场景,受众人群,用户量,
2.你在项目中负责哪些模块
3.掌握的后端java框架技术

java基础:

1.什么叫拆箱,装箱? 装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型
2.jdk和jre的分工是什么?
3.遇到过内存溢出这种情况么? 一般哪些情况容易出现?怎么解决的?开发过程中怎么避免?
4.通过反射得到一个类的对象,有几种方法?
5.如何实现HashMap线程安全?
1.HashTable
Map<String, String> hashtable = new Hashtable<>();
2.ConcurrentHashMap
Map<String, String> concurrentHashMap = new ConcurrentHashMap<>();
3.Synchronized Map
Map<String, String> synchronizedHashMap = Collections.synchronizedMap(new HashMap<String, String>());
6.java的堆和栈分别是什么? 堆是公共的内存区域,栈是当前线程运行使用的内存区域
7.有没有遇到过sql注入,用哪些手段可以解决这个问题?

线程&高并发:

1.线程池用过么?都有什么参数?
2.线程和进程有什么区别?
2.多线程实现有几种方式?thread的start()和run()方法有什么区别?
2.ThreadLocal 有用过么? 用在哪些地方?
3.java的 Volitile变量 有用过么? 这么用的? 为什么要用?
4.如果线程运行时发生异常会怎么走?

spring:

1.Spring bean的生命周期?默认创建是单例模式,如果不想单例怎么办? 实例化bean——》依赖注入——》处理Aware接口(3种),实现不同Aware接口的传入不同的信息——》初始化bean(两种,前置和后置)——》destroy(); scope="prototype"
2. spring Aop的实现原理?
3.springBoot的启动流程? 首先从SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器,第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块,第三部分是自动化配置核心模块
4.spring如何实现多数据源配置? +mybatis配合,如何做到读写分离?

sql:

1.那些情况下会发生明明创建了索引,但是执行的时候并没有通过索引呢?
2.一般会在什么情况下加索引?最起码列出来3条?
3.聚集索引和非聚集索引有什么区别? 分别在什么情况下使用?

mybatis:

1.mybatis mapper方法能重载么?dao层呢?
2.mapper接口的工作原理是什么?
3.mybatis批量新增,可以返回主键列表么?
4.mybatis插件有哪几个接口可以实现? ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件
5.Mybatis是如何进行分页的?分页插件的原理是什么?

posted @ 2020-10-17 18:16  Jiane```  阅读(292)  评论(1)    收藏  举报
……