多线程的实现方式,区别:
- 实现Runnable,继承Thread,两者并没有什么实际区别,就算实现Runnable调用的时候还是需要new一个Thread,只不过实现Runnable更好,因为Java规定单继承多实现
多线程的状态:
- 新生,就绪,运行,阻塞,死亡
多线程有几种同步方式:
- 有很多种,但是我了解的有悲观锁synchronized(升亏奈斯特),还有乐观锁CAS
- synchronized(升亏奈斯特):java的一个关键字,每次只让一个线程操作共享资源
CAS:
- 比较并替换,但其实它是一个原子性的操作,CAS有三个操作数,当前值A,内存值V,要修改的新值B,在修改时候当前值A比较内存值V相等,则把内存值V改成B,没有加锁,多个线程可以直接操作共享资源,在实际修改时候才判断是否修改成功,失败则会自旋,CAS虽然好但是会引起ABA的问题。
ABA问题:
- 线程A读到当前值是100,可能线程B把值修改为50,然后线程C又把值修改为100,等到线程A拿到执行权的时候,因为当前值和内存值是一样的,站在线程A的角度来说,这个值是未被修改的,在程序的角度来说这是不合法的(可以举例小偷投了钱又放回去,还是会触发法律的例子),这就是CAS所引起的ABA问题,解决方式也很简单,java提供了AtomicStampReference(A塔没克 思达 瑞福斯)类给我们用,说白了就是在内存值后面加了一个版本号。
既然问了多线程锁,ConcurrentHashMap逃不掉了
- 数据结构是数组+链表+红黑树,简单来说ConcurrentHashMap为每一组哈希槽进行分段上锁,不同组的哈希槽进行数据读写操作互不影响
线程池(参数,以及几种创建方式,以及拒绝策略):
- 使用ThreadExecutor线程池创建线程,能更了解线程池运行规则,避免资源耗尽的风险。
重要的五个参数:
- corePoolSize: 核心线程数量
- maximumPoolSize: 最大线程数量
- keepAliveTime: 线程空闲时间
- workQueue: 阻塞队列,只需要实现BlockingQueue这个接口即可
- handler: 任务拒绝策略
四种拒绝策略(了解即可)
- AbortPolicy(抛出一个异常,默认的)
- DiscardPolicy(直接丢弃任务)
- DiscardOldestPolicy(丢弃队列里最老的任务,将当前这个任务继续提交给线程池)
- CallerRunsPolicy(交给线程池调用所在的线程进行处理)
为了形象描述线程池执行,打个比喻:
- 当产品提个需求,正式员工(核心线程)先接需求(执行任务)
- 如果正式员工都有需求在做,即核心线程数已满),产品就把需求先放需求池(阻塞队列)。
- 如果需求池(阻塞队列)也满了,但是这时候产品继续提需求,怎么办呢?那就请外包(非核心线程)来做。
- 如果所有员工(最大线程数也满了)都有需求在做了,那就执行拒绝策略。
- 如果外包员工把需求做完了,它经过一段(keepAliveTime)空闲时间,就离开公司了。
Spring IOC:
- 依赖注入,自动装配(可按名字@Autowired和类型@Resource来装配),在创建新的Bean时,IoC容器会自动注入新Bean的所依赖的其他Bean,而无须自己手动创建。
底层:
- 正常的对象创建是直接new,然后生成class文件,存储在jvm,spring容器来创建bean不一样,因为有懒加载等等的原因,spring并没有直接创建bean,而是先创建BeanDefinition对象,存储所有属性信息,存到spring的map里面
Spring AOP:
- 面向切面编程,定义一个AOP需要在类上面加入,Aspect注解,切点最小单位为方法,需要在方法加入一个Pointcut切点,切点里面配置接入点,也就是表达式。
底层:
- creactBean方法既创建了原始对象(原始对象存在wappedObject字段),也返回了代理对象(initializeBean 生成的代理),然后addSingLeton方法向map添加了对象,getbaen的时候,只是去this.SingLotonObject里面拿到对象而已,这就是spring代理的过程
Spitng容器:
- Spring容器分为宏观和微观,而微观的spring容器仅仅是一个map而已,可以理解为单例池,例如SingLotonObject Spring所有的组件加载一起。可以理解为宏观的spring容器。
技术问题(能默背出一半不卡顿,且算合格):
(1天)多线程
- 【熟悉】多线程的实现方式
- 【熟悉】多线程的状态
- 【熟悉】多线程有几种同步方式,乐观锁(CAS无锁算法)和悲观锁(synchronized)
(0.5天)线程池
- 【熟悉】线程池的七个参数
- 【熟悉】线程池的几种创建方式
(3天)Spring
IOC
- 【熟悉】IOC的注入过程 + Spring源码的实现
AOP
- 【熟悉】切面编程的过程,代理的过程 + Spring源码的实现
(0.5天)SpringMVC
- 【熟悉】流程即可
(0.5天)SpringBoot
- 【熟悉】对比传统架构区别,以及注解
(1天)SpringCloud(常用组件)
- 【熟悉】Hystrix熔断器
- 【熟悉】Eureka注册中心
- 【熟悉】Feign:服务调用
(1天)mybatis(流程)
- 【熟悉】一些常用的标签
- 【了解】一二级缓存
(1天)Redis缓存
- 【熟悉】Redis有哪几种类型
- 【了解】缓存穿透+缓存雪崩+缓存击穿概念
(2天)JVM性能优化
- 【了解】JVM内存模型
- 【了解】深拷贝和浅拷贝
- 【了解】GC垃圾收集
- 【了解】JVM性能调优方法和步骤
(1天)Java基础
- 【熟悉】手写冒泡排序
- 【熟悉】集合方面
- 【熟悉】自动拆装箱
- 【熟悉】基本类型和引用类型
- 【熟悉】http常见状态码
- 【熟悉】java的异常区别,例如(Error和Exception)
(1天)SQL优化
- 【熟悉】分区分表,读写分离
- 【熟悉】数据库引擎
- 【熟悉】SQL语句优化
(2天)设计模式
- 【熟悉】单例模式
- 【熟悉】工厂模式
- 【熟悉】策略模式
- 【熟悉】责任链模式
非技术问题:
- 自我介绍
- 你的职业规划是什么
- 你在项目中遇到过最难的技术问题是什么
- 你为什么离职上一家公司