1. nacos zookeeper eureka 的区别.
项目中用到了nacos, 当时没想到,这题目应该问的是分布式的 CAP理论
C: 分区一致性
A: 分区可用性
P: 分区容错性
| eureka | zookeeper | nacos | consul |
|---|---|---|---|
| AP | CP | CP/AP | CP |
2. MySQL 优化
- 设计数据库时: 数据库表,字段的设计,存储引擎
- 利用好MySQL自身提供的功能,如索引等
- 横向扩展:MySQL集群、负载均衡、读写分离
- SQL语句的优化(收效甚微)
3. 索引的类型
- 一般索引
- 主键索引
- 唯一索引
- 组合索引
- 全文索引
4. 多条件搜索页面怎么建立索引
统计查询条件的离散程度 (distinct),按照最左原则将离散程度最大的放置在左侧.
5. 事务的特性
- 原子性: 要么全都执行,要么全都没执行.
- 一致性: 保证从一个正确的状态向另一个正确的状态迁移.(程序保证)
- 隔离性: 多个并发操作对各个事务之间应该不能造成影响.
- 持久性: 一个事务一旦提交,那就不能被回滚,在数据库中保存留档.
6. spring bean 的创建流程
- BeanDefinition解析: 调用容器中InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法,可以在Bean实例化前修改BeanDefinition.
- 实例化: 将指定的BeanDefinition转换成BeanWrapper,然后调用createBeanInstance创建Bean的实例.Bean的实例化有多种策略,如工厂方法,指定参数构造器和默认无参构造器等.总之,createBeanInstance()方法会返回一个刚实例化好的,属性未赋值的空Bean.
- 属性填充: 调用populateBean()方法,为Bean进行属性的赋值和依赖的注入.
- 属性填充后置处理: 调用容器中InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法,进行属性填充后处理.
- 初始化前置处理: 调用BeanPostProcessor的postProcessBeforeInitialization()方法进行初始化前置处理.
- 初始化: 调用Bean的初始化方法,顺序为:InitializingBean的afterPropertiesSet() -> 注册的init-method.
- 初始化后置处理: 调用BeanPostProcessor的postProcessAfterInitialization()执行初始化后置处理.
- 调用registerDisposableBeanIfNecessary()方法,注册Bean的销毁处理逻辑: 将所有实现了DisposableBean接口的或者注册了destroy-method方法的Bean,封装成一个DisposableBean,将其销毁的回调注册到容器中.
7. ApplicationContext 继承了哪些接口
EnviromentCapable: 所有Spring应用程序上下文都具有 EnvironmentCapable 功能,并且该接口主要用于在接受 BeanFactory 实例的框架方法中执行 instanceof 检查,以便可以与环境交互(如果确实可用),而 BeanFactory 实例实际上可以是ApplicationContext实例,也可以不是.MessageSource: 处理消息的策略接口,用户消息的参数化和国际化.ApplicationEventPulisher: 封装事件发布功能的接口.ResourcePatternResolver: 将位置模式解析成 Resource 对象的策略接口.ListableBeanFactory: BeanFactory 可以由哪些枚举出他们所有 bean 实例的 bean 工厂实现,而不是根据客户端尝试一个个查找.那些预加载所有 bean 定义的 BeanFactory 可以实现这个接口.HierarchicalBeanFactory: 由 bean 工厂实现的子接口, 可以是层次结构的一部分.可以在ConfigurableBeanFactory接口中找到用于bean工厂的相应setParentBeanFactory方法,该方法允许以可配置的方式设置父对象.
8. 线程池有哪些参数,是怎么运行任务的
- corePoolSize: 核心线程数.
- maximumPoolSize: 最大线程数.
- threadFactory: 线程工厂,提供线程.
- blockingQueue: 阻塞队列,缓存任务.
- keepAliveTime: 线程空闲回收的时间.
- rejectedExecutionHandler: 任务饱和后的拒绝策略.
- 提交任务进线程池.
- 线程池创建线程,直到达到核心线程数(
corePoolSize),然后任务会进入阻塞队列(blockingQueue). - 当阻塞队列达到最大值时,将会继续创建线程到最大线程数(
maximumPoolSize). - 当线程数达到最大线程数时,继续提交任务,会触发拒绝策略(
rejectedExecutionHandler) - 当有线程达到空闲时间(
keepAliveTime),则会被回收.
9. 内置的拒绝策略有哪些
RejectHandler: 默认的拒绝策略, 直接抛出拒绝异常.CallerRunsPolicy: 将任务交还由execute方法执行的线程去执行.DiscardOldestPolicy: 将阻塞队列中最早的任务丢弃.DiscardPolicy: 直接放弃提交进的任务AbortPolicy: 抛出带有详细信息的异常.
10. 如何选择拒绝策略
对于必须不能放弃的任务来说,可以选择 CallerRunsPolicy 或者说自定义一个策略, 提交进新的线程池进去执行. 而不重要的业务可以根据不同的选择不同的丢弃策略.
11. 了解动态代理吗, 有哪些, Spring 默认用的是什么
程序可以在运行期间生成代理对象,进行业务增强.
JDK 默认的动态代理,以及 CGLIB 的代理增强.
- Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理.
- SpringBoot 2.x 开始,为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB.
- 在 SpringBoot 2.x 中,如果需要默认使用 JDK 动态代理可以通过配置项
spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效.
12. 了解静态代理吗
静态代理需要在编码阶段,指定实际执行对象.实际行为将由代理类和被代理类同时控制.
13. CGLIB 和 JDK 的动态代理有什么区别
- CGLIB 的动态代理是基于可以不定义接口就实现动态代理,但是被代理对象,以及方法不能是被 final 修饰.
- JDK 的动态代理是基于反射, 但是被代理对象必须实现目标接口.
14. jdk 的动态代理是只要类实现接口就可以代理吗
是的
15. git 不同的分支怎么合并
git merge 具体没有操作过,抽空去了解一下 git 的版本控制.
16. 版本怎么发布
一般用流水线,Jenkins之类. 平时涉及的也很少.