java复盘高途社招一面没答好的问题

线程相关

sleep和wait对应的线程状态

线程从创建开始可能经过的状态:

  1. 初始状态:线程创建后未调用start时
  2. 运行状态:线程调用start后等待运行
    调用start后并不是能够立马运行,未被CPU调度时处于就绪状态,被调度之后是运行状态,但是JVM并没有区分这两种状态,因为线程的切换速度很快,区分这两个没有什么意义
  3. 阻塞状态:需要等待锁的释放
  4. 等待状态:当前线程需等待其他线程做出特定动作(通知或中断)
  5. 超时等待状态:线程在指定时间之后返回
  6. 终止状态:线程运行结束

所以sleep()和设置了时间的wait()都是会进入超时等待状态
未设置时间的wait()会进入等待状态,直到有线程调用notify()或者notifyAll()方法

线程池中submit()和execute()的区别

  1. execute()提交任务不会有返回值;
  2. submit()提交会返回一个Future对象,通过这个对象可以知道线程任务是否成功执行,并且可以调用Future对象的get()方法获取这个返回值
    在这里插入图片描述
    在这里插入图片描述
  3. 关于异常处理的方式不同。execute()不需要手动捕获异常,而submit()需要捕获ExecutionException才能编译成功。

SpringBoot

spring-boot-starter了解吗,如何实现的自动装配?

详细可以看这篇文章SpringBoot 自动装配原理详解
总的来说就是springboot通过SPI的方式定义了一个接口规范,只要外部jar包按照这个规范去实现了,就能够将自己的功能装配到springboot中去。
具体而言@EnableAutoConfiguration注解表示开启自动装配,该注解内的一个类会去读取所有stater下的META/INFO/spring.factories,并且将这些配置类的信息加载到容器中,不过并不是一次性全部加载,只有满足@Conditional筛选条件的配置类才会加载,从而实现按需加载。

mybatis

mybatis-plus做了哪些改进?

这个可以对照官网看看,平常用plus比较多,真要问到具体改进了什么还真不好系统性的表达出来,我相信用过的人最直观的感受就是——方便、易于开发
我列几点自己用的最多,感受最直接的改进吧

  1. 内置分页插件,基于mybatis的物理分页,但是开发者使用起来不需要关心内部细节
  2. 内置通用的mapper和service,完美覆盖单表的CRUD操作,相比于mybatis我们不再需要为每个mapper写最基本的增删改查和sql语句,非常省时省力!
  3. 条件构造器,且支持lambda表达式
  4. 内置代码生成器,简化了很多重复又繁琐的工作

mybatis中的mapper和xml文件名一定要相同吗?

不一定
具体我还没去实践,(我可以说压根没咋用过mybatis>﹏<)

mybatis的mapper是怎么执行的?

我们知道mapper是个接口,并没有让我们写实现类,调用接口方法时:

  1. mybatis是通过接口的全限定名+方法id组成的字符串作为key,去获得唯一的一个MappedStatement对象;
  2. xml里面我们写的<select> <insert> <update> <delete>这样的标签,最终都会被解析为MappedStatement对象;
  3. mybatis通过JDK Proxy生成代理对象,然后通过代理对象去调用对应的MappedStatement方法

redis相关

redis的基本数据类型 分别的底层实现和应用场景

五种常见的基本类型:

String

底层:SDS简单动态字符串
应用场景: 缓存数据,比如token

List

底层:双向链表
应用场景:最新文章、最新动态等

Hash

底层:与jdk1.8之前的hashmap差不多,数组+链表
应用场景:购物车信息

Redis中的hash与Java的hashmap一样吗?

差不多类似,跟jdk1.8之前的hashmap类似,都是数组+链表的结构
对比jdk1.8之后的:

  1. redis中的hash是数组+链表,Java的hashmap是加入了红黑树;
  2. 添加元素的时候,发生哈希冲突的话,hash是头插法插在链表的头部,hashmap是尾插法;
  3. 扩容的时候,hash是渐进式扩容,扩容期间还是可以操作的,hashmap则需要一次性扩容完成。

Set

底层:Dict、Inset
应用场景:需要统计不可重复的业务场景,比如共同好友、共同关注、点赞

ZSet

底层:SkipList,跟Set差不多,ZSet就是Sorted Set,有一个score权重参数,用于根据权重排序,实现了有序的集合
应用场景:排行榜

MySQL相关

MySQL有哪些锁?什么时候会用到行锁表锁?

总体来分是有行锁和表锁,其中行锁又可以继续细分为记录锁、间隙锁、临键锁
不论是表级锁还是行级锁,都有共享锁和排他锁。

行锁

MySQL只有InnoDB引擎有行锁。
行锁是针对索引字段的锁,如果在执行update、delete的操作时,如果where中的条件没有用到唯一索引或者索引失效,会导致全表扫描为所有记录加上锁。
行锁是通过对索引数据页上的记录加锁实现的。

  1. 记录锁:单个记录上的锁。
  2. 间隙锁:锁住一个范围,但不包括记录本身。
  3. 临键锁:就是记录锁+间隙锁,这就是为什么MySQL的可重复读隔离级别能够解决幻读的问题,临键锁可以锁住一个范围并且包括记录本身。

表锁

表锁是针对非索引字段的锁,操作时锁住整张表。
意向锁属于表级锁。
在对一个表加锁时,需要表中是否有记录被加了行锁,意向锁就用于判断是否可以对一个表使用表锁。

  1. 意向共享锁:事务有意向对某些记录加共享锁,需要先获取对应的意向共享锁。
  2. 意向排他锁:事务有意向对某些记录加排他锁,需要先获取对应的意向排他锁。

共享锁和排他锁

  1. 共享锁:读锁,允许多个事务同时获取。
  2. 排他锁:写锁,不允许多个事务同时获取,并且如果一个记录已经被加了写锁,那么不允许再加任何其他的锁。
  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值