面试题整理

JVM内存模型?简单阐述

本地方法栈,方法区,java栈,java堆

本地方法栈:储存本地方法,主要由natuve修饰

java堆:储存对象

分为年轻代(eden区,form区,to区),老年代

java栈:储存变量的值或是对象的引用

方法区 储存有statuc修饰的变量,方法代码块以及常量

Java多线程在项目中哪里用到了

前端 下载文件

后端,大部分的服务,异步处理,给不同的用户发信息,加载数据

活锁死锁问题分析,什么是活锁、什么是死锁。出现的原因是什么?如何避免?

活锁,线程的运行条件不满足,等待资源满足会运行,若是迟迟得不到资源会有对应的放弃和重试逻辑

死锁,多线程互相抢占对方自愿,互不释放,若无外力干涉,程序会一直处于死锁状态

形成死锁的四个必要条件

互斥条件 线程使用的资源至少有一个是无法共享的,一段时间内只能被该线程战友,知道获取资源进入等待运行状态

请求与保持,线程至少已经占有有一个资源,但是又提出新的资源请求,而该资源被其他线程所占有,此时该线程请求阻塞并保持以获取的资源

不可剥夺:线程保持的资源不能被其他线程占有,必须该线程主动释放

循环等待:一个线程在等待另一线程的资源,而后者在等待前者的资源,形成僵持的局面

避免活锁的方法:采取先来先服务的原则

避免死锁的方法:破坏其产生的任意一个条件即可

破坏请求与保持:对资源进行排序,必须按照某种顺序来获得资源

破坏不可剥夺:无法执行的程序在一定时间后重试

破坏循环等待:一个线程只有获取全部的资源才可以运行

多线程如何做到数据共享?

使用同一个Runnable对象,然后将共享数据放在Runnable里,实现数据的共享

如果每个线程执行的代码不同,那么就需要不同的Runnable对象,但有两种方式实现这些Runnable对象之间的数据共享

  1. 将共享数据封装在另一个对象中,实现不同的操作,将这个对象传递给Runnable对象,每个线程对共享数据的操作也就对应的分配到了那个对象上去完成,实现概述的各种操作的互斥与通信
  2. 讲这些Runnbale对象作为某一个类的内部类,数据作为外部类的成员变量,每个线程对共享数据的操作也就分给了外部类,实现共享数据的各种操作的互斥通信

多线程如何保证线程安全?

互斥同步         使用synchronized,lock同步

非阻塞同步        使用decompareAndSet()和getAndIcrement)方法

缺点:

  • 容易出现ABA问题,使用版本号解决
  • 只能保证变量的原子操作,使用AtomicReference类来保证对象之间的原子性,可以把多个变量放在一个对象里

无同步方法

线程本地存储:共享数据的可见范围限制在一个线程中,这样无需同步也可以保证线程之间不用出现数据争用问题,通常使用的就是ThreadLocal类

HashMap底层详细介绍

hashmap是基于哈希表的Map接口的非同步实现。实现HashMap对数据的操作允许用多个null值

1.7和1.8区别

数据结构

  • 1.7 数组+链表
  • 1.8数组+链表/红黑树

扩容机制

  • 存放新值的时候当前已有的元素个数必须大于等于阈值
  • 存放新值的时候和当前存储的数据发生hash碰撞,已有元素个数大于等于阈值,狭义存放后必然触发扩容

发生hash碰撞时

  • 1.7头部插入
  • 1.8尾部插入

ArrayList和LinkedList的区别

ArrayList底层是数组,查询快,增删慢

LinkedList,增删快,中间查询慢

NIO和AIO,BIO的区别

BIO同步阻塞式IO,一个连接为一个线程,客户端有连接请求时,服务器端就需要启动一个线程进行处理,如果这个连接不作任何事情,就会造成不必要的线程开销美当然可以同建线程池机制改善

NIO同步非阻塞式IO,服务器实现一个模式为一个请求,客户端发送的连接请求会注册到多路复用器上,多路复用器轮询到连接有IO请求时会被注册到多路复用器上,多路复用器轮询到有IO请求时才会启动一个线程进行处理

AIO异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的IO请求都是由OS先完成再通知服务器应用区启动线程进行处理

介绍一下spring框架

spring是一个轻量级,低耦合的一站式java开发框架

spring的核心是IOC和AOP,

IOC控制反转,把对象的净之泉交给IOC容器,DI注入是IOC的实现方式之一,依赖注入的三种方式:字段注入,构造方法注入,setter注入

AOP 面向切面,在不改变原有功能的情况下扩展功能,拦截器就是AOP的实现思路之一,前置通知,后置通知,最终通知,环绕通知,异常通知

介绍一下Soring IOC和AOP的实现原理

spring通过一个喷织文件描述Bean及bean之间的循环依赖关系,利用java语言的反射功能实例化bean 并建立Bean之间的依赖关系,Spring的ioc容器在完成这些底层工作的基础上,还提供了bean实例缓存,生命周期管理,bean实力代理,时间发布,资源装载等高级服务

Resource定位 resource是Spring对于用户定义Bean文件的统一标准

BeanDefinition的载入和注册:载入就是将Resource中的内容解析出来,转换成Spring内部定义的数据结构BeanDefintion

依赖注入:从Spring IOC容器获取对象

AOP实现原理:Spring提供了两种方式生成代理,JdkProxy和Cglib,spring默认使用Priox,Spring boot默认使用CGLib。默认的策略是如火目标类实现了接口,则使用JDKProxy实现,否则使用CGLib

BeanFactory和FactoryBean有什么区别? 

BeanFactory是IOC容器的杰阔,提供一套标准的Bean的规范

FactoryBean是对Bean扩展的接口,是创建Bean的一种形式,融合了简单的工厂设计模式和装饰者模式

Spring框架中出现的ABA问题循环依赖如何解决?

spring 的三级缓存解决

Spring框架中Bean对象的生命周期?

  1. bean的定义
  2. bena的实例化
  3. bean的属性注入
  4. 如果bean实现了BeanNameAware接口。则调用setBeanName()方法
  5. 如果bean实现了BeanFactoryAware接口,则调用setBeanFactory()方法
  6. 如果实现了ApplicationContextAware接口,则调用setApplicationContext()方法
  7. 如果bean实现了BPP接口,调用其预处理方法
  8. 调用init-method方法
  9. 如果bean实现了BPP接口,调用其后处理方法
  10. destroy方法

SpringMVC的工作原理

带入项目中的一个功能请求来阐述,例如登录请求、查询请求

 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XH0fEJst-1623044111711)(RackMultipart20210607-4-13lyxac_html_e58ee630c0df1991.png)]在这里插入图片描述

  1. 用户发送一个查询请求,经过过滤器过滤请求,
  2. 经过过滤器筛选之后,进入到前端过滤器,
  3. 前端过滤器将请求发送给请求映射器查询执行链
  4. 前端过滤器获取执行链获之后将执行链发送给拦截器,进行代理或其他行为
  5. 再执行控制层,服务层,持久层查询,
  6. 查询到的数据,返回拦截器进行统计,记录日志等功能
  7. 前端处理器获得,经过拦截器的返回数据,将数据交给响应处理器,封装反应结果
  8. 在通过视图解析器解析数据返回视图给前端控制器
  9. 前端控制前渲染之后将用户查询的数据显示呈现给用户

SpringMVC框架从发起请求到接收请求发生了什么?

三次握手

第一次握手:客户端发送SYN包到服务端,服务端确认

第二次握手:服务端向客户端发送SYN+ACK包

第三次握手:客户端收到服务端发送的SYN+ACK包,并且向服务端发送ACK确认包,至此,三次握手完毕,建立连接

MyBatis框架如何处理SQL注入问题?

 #和$的区别

 #符号有sql语句预编译的功能,类似于占位符,它会将数据转化成字符串,

$符号没有这种功能

MyBatis框架有几级?,默认开几级?

一共两级。默认一级

 默认开启的是SQLSession,SQLsession关闭,缓存清空,一级缓存缓存的是sql语句缓存

二级缓存是全局缓存,作用域超出SQLsession范围之外,可以被所有的sqlSession共享,实现了夸SqlSession,因此,二级缓存的是结果集

redis常见的数据类型

  • Stirng 最常用的数据类型,是安全的,返回的是JSON串
  • list,不安全,秒杀功能,
  • set,粉丝关注,不安全
  • Hash不安全,存储对象的属性

Redis的缓存雪崩和击穿如何解决?

  • 雪崩:
    • 大量数据过期,或redis宕机,大量请求直接访问数据库,引发雪崩
    • 前期准备:热点数据刷新,redis定期备份RDB,AOF。设置本地缓存,限流算法,设置互斥锁,
    • 后期升级:及时恢复,主副缓存,集群升级
  • 击穿:
    • 同一时间大量请求访问同一个热点数据,
    • 分段锁,互斥锁,热点数据永不过期,缓存时长刷新
  • 穿透:
    • 访问redis不存在的数据,恶意攻击
    • 设置空值缓存,布隆过滤器,队请求进行正则校验,

数据库有2000w条数据,redis有20w条,如何保证redis中的数据一定是热点数据

  • 从已设置过期时间的数据集(server.db[i].expires)挑选最近最少使用的数据淘汰
  • 从一设置过期时间的数据集(server.db[i].expires)挑选过期的数据淘汰
  • 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

spring boot 启动流程

第一部分:SpringApplication初始化模块,配置一些结拜呢的环境变量,资源,监听器,构造器

第二部分:实现了应用具体的启动方案,包括流程的监听模块,加载配置环境及创建上下文环境模块

第三部分:自动化配置模块,这个模块是实现Spring Boot的自动配置

启动

每个SpringBoot程序都有一个入口也就是main方法,main李淼调用SpringApplication.run()启动整个Spring-boot程序,该方法所在类有一个@SpringBootApplication注解,它是一个组合注解

@SpringBootyConfiguration:表示这是一个配置类,整合第三方框架

@EnableAutoConfiguration:SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置

@ComponetScan:组件扫描,可以自动发现和装配bean,自动扫描并加载符合的组件(比如@Component和@Repository等)或者Bean定义,最终这些类的定义加载到IOC容器中

SpringBoot启动类:

首先进入run方法,run方法中区域创建了一个SpringApplication实例,使用SpringFactoryiesLoader在应用的META-INFO/spring.facories中查找所有可用的ApplicationContextInitializer。使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationListener。

在构造方法内,我们可以发现其调用了一个初始化的initialize方法,在该方法中实现了如下几个关键步骤:

  1. 创加进了应用的监听器SpringApplicationRunListeners并开始监听
  2. 加载SpringBoot配置环境(ConfigurableEnvironment),如果是通过web荣旗发布,会加载StandardEnvironment
  3. 配置环境(Environment)加入到监听对象中(SpringApplicationRunListeners)
  4. 创建Run方法的返回对象:ConfigurableApplicationContext(应用配置上下文)
  5. 回到run方法内,prepareContext方法将listeners,environment,applicationArguments,banner等重要组件与上下文对象关联
  6. 接下来refershContext(context)方法(初始化方法如下)将是实现spring-boot-starter-*(mybatis,redis等)自动化配置的关键,包括spring.factories的加载,bean的实例化等核心工作

refresh方法

配置结束后,Springboot做了一些基本的收尾工作没返回了应用环境上下文,回顾整体流程,Springboot的启动,主要是创建了配置环境(environment),事件监听,应用上下文(applicationCintext),并基于以上条件,在容器中开始实例化我们需要的Bean,至此,通过SpringBoot启动的程序已经构造完成

数据库中有2000W条数据,而Redis当中只有20W条数据,如何保证Redis中的数据一定是热点数据?(可考虑设置缓存过期时间)

redis的八种淘汰策略

全局的键空间选择性移除

allokeys-lru(常用):当内存不足以容纳新写入数据时,在全局键空间中,移除最近使用最少的key

allkeys-random:当内存不足以容纳写入新数据时,在全局键空间中,随机移除某个key

no-eviction:当内存不足以容纳新写入数据时,新写入操作会报错

allkeys-luf:从数据集中选取使用频率最低的数据淘汰

设置过期时间的键空间选择性移除

volatile-lur:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key

volatile-random:党内润不足以容纳新写入的数据时,在设置了过期时间的键空间中,随机移除某个key

volatile-ttl::内存不足容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

volatile-lfu:从已经设置过期时间的数据集挑选使用频率最低的数据淘汰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sayhitoloverOvO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值