Java问题整理
Java类加载器
加载器结构:
加载过程:
graph LR
A[加载] --> B[验证] --> C[准备] --> D[解析] --> E[初始化]
加载机制:双亲委派机制
需要加载一个类时,优先让父类去加载,父类无法加载时再交给子类加载。
优点:
- 放置重复加载
- 安全,核心类不会被替换
常用注解
@SpringbootApplication springboot启动类
@Configuration 配置类
@Compont
@Controller
@Service
@Mapper
@Bean
@Autowired
@Value
@ExceptionAdvice 统一异常处理
@Pointcut 切入点
@RequestMapping
@RequestBody
@Transactional
SpringBoot的运行机制是怎样的
@SpringBootApplication 注解是一个复合注解,其主要注解有三个,
第一个是@SpringBootConfiguration(相当于@Configuration),用了标注一个类为配置类;
第二个是@ComponentScan指定包下面需要装配的组件注册到容器里面;
第三个是@EnableAutoConfiguration,这个是SpringBoot的核心注解,这也是一个复合注解,里面有两个主要的分别是@AutoConfigurationPackage和@Import,第一个@AutoConfigurationPackage作用是将主配置类所在的包作为自动配置的包进行管理,第二个@Import作用是导入一个类进入IOC容器中,要导入的类配置在META-INF/spring.factories中。
总结一下就是SpringBoot通过根据配置文件,自动装配所属依赖的类,再通过动态代理的方式,注入到Spring容器中。
@Component 和 @Bean 的区别
这两个注解都是用来定义Spring bean的
@Component一般在类声明处,告诉spring这是一个需要管理的类。
@Bean一般用在方法上,将方法的返回值作为一个管理对象,好处就是可以把bean的声明和类定义分离,比如想要spring管理第三方jar包中的类时;并且经常与@Configuration配合使用。
Mybatis怎么开启二级缓存
在mybatis配置文件里面开启二级缓存(cacheEnable),然后再Mapper.xml里打上\<cache>标签就可以。
一级缓存是SQLSession级别,不同SQLSession之间是隔离的;二级缓存是Mapper级别的,不同SQLSession之间是共享的。
同一个事务中,用的是同一个SQLSession,一级缓存才会生效;如果没有开启事务,每次会创建一个新的SQLSession方法来执行。
Mybatis嵌套结果和嵌套查询区别
嵌套结果是一条SQL,按查询出来的结果自己封装;嵌套查询是多条SQL,Mybatis来封装。
Redis 数据类型
string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)
Redis缓存穿透、缓存击穿、缓存雪崩
Redis做中央缓存是为了减轻数据库压力
缓存穿透:Redis中的数据大部分是数据库中的,如果查询一条不存在的数据,Redis中没有,数据库中也没有,那就不能把这条数据放入Redis,导致每次查询这条数据都会请求到数据库。
解决方法:1、在Redis中添加一个返回Null的数据,过期时间设置短一些。2、基础校验,比如id<1的直接拦截
缓存击穿:缓存没有,但是数据库有的数据,这种情况的原因一般是缓存时间过期,然后如果同一时间访问量大的话,会给数据库压力
解决方法:使用互斥锁,防止并发查同一条数据。
缓存雪崩:Redis中的Key大量同时过期,导致请求都打向数据库
解决方法:1、key设置不同的有效时间,比如一个基础时间加一个随机时间。2、热点Key或者数据变更不频繁的时候,可以把过期时间拉长,甚至不过期。
Redis淘汰策略
默认:满了再添加就出错
常用:lru 淘汰最少使用
1、volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2、volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
3、volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
4、allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
5、allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
6、no-enviction(驱逐):禁止驱逐数据
Redis持久化
RDB:保存现状数据,类似快照
AOF:保存增删改命令
特点:
RDB性能好,但是数据不是实时的,如果Redis突然宕机,会造成数据丢失。
AOF安全性更好,但是性能稍微差点,因此如果同时存在AOF文件和RDB文件,Redis会优先使用AOF来回复数据。
两种方式可以结合使用。
Redis事务
Redis支持弱事务,即不能回滚。
如果一串命令执行错误,后面的命令会继续执行。如果中间出现的是语法错误,后面的就不会继续执行了。
Redis分布式锁
进程之间的锁是进程锁,如果程序在不同的系统中,就可以使用Redis作为分布式锁。
分布式锁实现接口幂等
SpringCloud相关
五大组件:
- 注册中心-Eureka
- 负载均衡-Ribbon
- 熔断器-Hystrix
- 网关-Zuul
- 分布式配置-Spring Cloud Config
负载均衡策略(7种):轮询(默认)、随机、重试、最低并发、可用过滤、加权(响应时间加权,区域加权);也可自定义
数据库索引
索引是帮助高效获取数据的一种数据结构
MySQL 两种引擎:Innodb和MyIASM(不支持事务),结构都是B+树,属于多叉树。虽然索引能够提高查询效率,但是牺牲的是插入删除的性能,因此建立索引的字段不应该经常变化。
建立索引之后,有一些SQL会造成索引失效(or连接或isnull判断不等于)。
不适合建立索引的情况:
字段的数据类型比较少,比如布尔值
字段内容比较大,比如数据库存放json的时候
字段经常变更的时候(需要重建索引,导致插入更新非常慢)
聚族索引和非聚族索引
聚族索引:把索引和数据放在一块,叶子节点一记录数据
非聚族索引:索引和数据分开放置,索引记录的是数据的位置
(字典中的字是按拼音从a开始排列,那么拼音就是聚族索引,索引的顺序和数据的顺序是一致的。偏旁部首的索引就是非聚族索引,查出来的是数据的位置。)
复合索引
复合索引就是把多个字段作为索引创建,有一个最左原则,如果where条件中没有第一个字段,会导致索引失效。如果字段之间使用是or连接条件,也会导致索引失效。
order by的字段如果是索引也会更快。
MySQL里可以使用select sql_no_cache...来不使用缓存查询。
覆盖索引:指查询的数据就是索引,不用再回表查询。
可以用来优化分页查询,先取ID再取数据,同时使用join查询,不要使用where in
SQL优化
Vue
路由的两种方式:hash方式,地址栏会有#号;history方式,地址栏没有#号
vue生命周期:总共8个部分,分别为created、mounted、updated、destroyed及其各自的before方法
子父组件传参:父组件添加属性或v-bind,子组件用props接收
子父组件方法调用:子调父:this.$emit发送事件,父组件监听;父调子:this.$refs
vue双向绑定原理:Object.defineProperty()进行属性数据拦截
ajax的原理:XMLHttpRequest对象请求数据。
多线程
多线程List: Victor、CopyOnWriteList、Collections.synchronizedList
多线程Map: HashTable、CopyOnWriteLinkedHashMap、Collections.synchronizedMap、ConcurrentHashMap