equals和==区别
==比较的是基本数据类型的字面值、引用数据类型的地址值,equals默认情况下与==一致,需要根据业务重写equals方法进行对象比较。
finally、final、finalize区别
finally与try-catch结构一起使用,在程序不出现突然down掉的情况下,finally代码块中的代码一定会执行(包括对try或者catch中的返回值进行覆盖)。
final表明被修饰的东西是不可改变的,对于类,不能被子类继承;对于方法,不能被子类冲写,对于变量,表示不可改变。
finalize是Object的一个方法,在对象被垃圾回收之前会被自动调用。
重载和重写的区别
重载是在同一对象中方法名相同,参数列表(参数类型、个数、顺序)不同的方法实现不同的处理流程。
重写是在父子类之间,子类对父类的方法处理流程进行重新定义,重写的方法签名在父子类之间必须保持一致。
equals和hashCode
两者之间的关系为:
- hashCode相等时equals不一定相等
- equals相等时hashCode一定相等
抽象类和接口的区别
- 抽象类使用abstract定义,可以有抽象方法、非抽象方法、实例变量、构造方法;接口通过interface进行定义,可以有抽象方法、默认方法、静态方法、常量。
- 子类只能继承一个父类,但可以实现多个接口
- 抽象类和接口都是对于类的一种抽象,只是抽象类抽象的是类的共同行为和属性,而接口是抽象大家公共的行为,是一种约定
String、StringBuilder、StringBuffer
String是不可变长字符序列,StringBilder和StringBuffer是可变长字符序列,StringBuffer的方法都使用了synchronized进行加锁,所以是线程安全的。单线程少量拼接字符串用String、单线程频繁拼接字符串用StringBuilder,多线程频繁拼接字符串用StringBuffer。
Comparator和Comparable区别
两者是用来实现比较操作的,Comparator将比较规则独立于类之外,而Comparable则将比较规则置身于类之内,如果有多种比较规则要求的情况下,可以使用Comparator。
JVM、JRE、JDK
JVM:虚拟机,读取字节码文件,解析字节码,执行程序
JRE:Java运行时环境,包含JVM和程序运行的基本类库
JDK:Java开发工具包,除了JRE以外,还包含javac、javadoc、javap等程序开发需要的工具
OOA(面向过程)、OOP(面向对象)
封装:网上找得到的背诵的定义为“对外暴露简单接口,隐藏实现细节”,这句话很精简,具体应用可以考虑一下自己开发使用的各种工具类,对于工具类而言,有些会配置一些固定参数,也就是常量,而对外,则是提供简单的方法调用,这就是一个封装的例子。
继承
多态
- 编译时多态:方法重载
- 运行时多态:绑定的具体对象在运行时才能确认
设计模式
设计模式主要分为创建型、结构型和行为型
创建型:单例、工厂、抽象工厂、建造者、原型
结构型:桥接、适配器、装饰器、代理、组合、外观、享元
行为型:策略、解释器、命令、观察者、迭代器、模版方式、访问者
多线程情况下对同一数据++
对数据的++操作步骤分为三步:读取数据、加一操作、写会数据,并发情况如果没有加锁可能会出现多个线程读取到的数据为同一值,多个线程下的++操作最终实际只进行了一次。
Redis存不存在线程安全问题
Redis执行操作的部分是单线程的,最多只有处理IO部分是多线程,在但客户端的情况下,不会存在线程安全问题,而多客户端情况下,可能因为操作不存在原子性而出现线程安全问题,这个可以通过加锁,或者使用lua脚本的方式解决。
Spring的BeanFactory和 FactoryBean的区别
Spring的IOC容器提供了一个从xml文件和和注释的方式为我们创建和管理Bean的方式,BeanFactory是所有Spring Bean容器的顶级接口,他实现了一套规范,为我们提供了从容器中获取指定Bean实例的方法,解决了Bean之间依赖注入的能力;FactoryBean是工厂Bean,一个接口,为我们提供了动态生成某一类型的Bean实例的方式,可以灵活的创建我们想要的Bean实例。
Spring的@Order和@DependsOn
@Order改变自动装配的顺序,用List接收自动装配的对象,通过@Order可以改变对象在List里面的顺序,在拦截器等地方会有使用到,涉及到拦截器的处理顺序;@DependsOn改变Bean创建顺序的作用,@Order值为数字,@DependsOn为另外一个对象。
Spring的事务传播行为
7种,
Spring的Bean生命周期
- singleton单例:整个Spring容器中只存在一个
- prototype原型:每次去IOC容器中获取Bean都是全新的
- request:针对每个请求获取一次
- session:针对每个会话创建一个Bean
- globalSession:针对全局session共享一个Bean
MyBatis缓存机制
MyBatis有两级缓存,一级缓存为sqlSession级别的,只能在同一个会话中使用,二级缓存是跨sqlSession级别的,可以在不同的会话中使用。MyBatis在查询的是偶会先查询二级缓存,再查询一级缓存,最后查询数据库,需要注意的点:因为缓存的存在,在查询的过程中可能出现脏读的情况。二级缓存是通过CachingExecutor实现全局缓存,而一级缓存是通过Executor实现的本地缓存。
MySQL事务隔离级别
隔离级别是为了解决事务竞争情况下数据安全问题的一种规范,共有4种:读未提交,读已提交,可重复读,串行化,默认可重复读。不同隔离级别下可能会出现不同的问题
| 隔离级别 | 出现的问题 |
|---|---|
| 读未提交 | 脏读、不可重复读、幻读 |
| 读已提交 | 不可重复读、幻读 |
| 可重复读 | 幻读 |
| 串行化 |
脏读:读取到其他事务未提交的数据,并且该数据最终可能还不存在。
不可重复读:同一事务在不同时间读取到的数据不一样。
幻读:一个事务在查询数据时,另外一个事务对数据实现插入操作或者删除操作。
RabbitMQ消息堆积
原因
- 消费者处理消息速度太慢
- 队列容量太小
- 网络故障
- 消费者故障
- 队列配置不当
- 消息大小
- 业务逻辑复杂或者耗时
- 消息产生速度大于消费速度
解决
- 增加消费者数量
- 优化消费者性能
- 消息预取限制
- 增加队列容量
- 网络监控和告警
- 持久化和高可用
- 使用死信队列
- 容错机制
- 优化队列配置
- 消息分片
- 优化业务逻辑
- 使用消息限流
- 负载均衡
- 消息优先级
- 调整RabbitMQ配置