2023年java面试题(1-3)年

面向对象:封装、继承、多态
面向对象的编程是以对象为中心,以消息为驱动
面向过程比较直接高效。而面向对象更易复用、扩展和维护

封装:明确标识出允许外部使用的所有成员函数和数据项,内部细节对外部调用透明,外部调用无需修改或者关心内部实现
继续:继承父类方法,并做出自己的改变或者扩展,子类共性的方法或者属性直接使用父类的,而不需要自己在定义,只需扩展自己个性化的
多态:基于对象所属类的不同,外部对同一方法的调用,实现执行的逻辑不同

重载和重写的区别
重载:发生在同一个类中,方法名必须相同,参数类型、个数、顺序不同,方法值和访问修饰符可以不同
重写:发生在子类中,方法名,参数列表必须相同返回值小于等于父类,抛出异常范围小于父类

接口和抽象类
抽象类可以有构造方法,而接口没有
抽象类可以有抽象方法和具体方法,而接口只能有抽象方法
抽象类成员四种权限修饰符都可以修饰,而接口只能用private
抽象是单继承,接口多实现

final关键字

修饰类:类不能够被继承
修饰方法:方法不能够被重写
修饰变量:标识变量一旦被赋值,就不可以改变他的值

String 和Stringbuffer、stringbuilder

String 是不可变,如果尝试去修改,会新生成一个字符串对象
Stringbuffer和stringbuilder是可变的
Stringbuffer是线程安全的
Stringbuilder是线程不安全的,因为stringbuffer加了sny锁所以线程安全

hashmap和hashtable的区别
hashmap线程是不安全的,并且key 和value 允许null
hashtable是线程安全的因为他加了synchronize锁所以线程安全,并且key value不允许null值

并发的三大要素

原子性:原子性是指一个或多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部不执行

可见性:可见性是指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果

有序性:有序性是指程序执行顺序按照代码的先后顺序来执行

实现可见性的方法有哪些

synchronized或者lock:保证同一时刻只有一个线程获取锁执行代码,锁释放之前吧最新的值刷新到主内存,实现可见性

多线程的价值
发挥多核cpu的优势
防止阻塞
便于建模

创建线程有哪些方式

继承thread类创建线程类
实现runnable接口创建线程类
通过callable和futrue创建线程
通过线程池创建

java线程具有五种基本状态

新建:当线程对象创建后,即进入了新建状态 如 thread r=new thread
就绪:当调用线程对象的start()方法,线程即进入到就绪状态,处于就绪状态的线程,只能说明此线程已经做好了准备,随时等待cpu调度执行,并不是说执行了start()方法此线程就立马执行
运行:当cpu调度处于就绪状态的线程时,此时线程才真正得以执行,即进入到运行状态
阻塞:处于运行中的线程由于某种原因,暂时放弃对cpu的使用权,停止执行,此时进入阻塞状态
直到其进入到就绪状态,才有机会呗cpu调用进入到运行状态
死亡:线程执行完或者异常退出了run(方法该线程结束生命周期)

synchronized和volatile,CAS的比较

1.synchronized是悲观锁,属于抢占式,会引起其他线程阻塞
2.volatile提供多线程共享变量可见性和禁止指令重排序优化
3.CAS是基于冲突检测的乐观锁(非阻塞)

想要线程安全的hashmap怎么办
1.使用concurrenthashmap
2.使用hashtable
3.collects,synchronizedhshmap()

arraylist和linklist的区别

arraylist底层使用的数组linklist底层使用的是链表

arraylist查询快增删慢,linklist查询慢增删快

如何保证arraylist的线程安全
使用collections.synchronized()方法加锁

使用vector,vrctor底层与arraylist相同,但是每个方法都由synchronized加锁,速度很慢

使用juc下的copyonwriteArraylist,该类实现了读操作不加锁,写操作时为list创建一个副本,期间其他线程读取的是原先的lisy,写操作都在副本中进行,写完完成后,再将指针指向副本

Synchronized和lock的区别

synchronized是一个关键字,lock是一个类
synchronized在发生异常时自动释放锁lock需要手动释放锁

sleep和wait的区别

wait是object的方法,sleep()是thread类的方法

wait()会释放锁,sleep()不释放锁

wait()要在同步方法或者同步代码块指向,sleep()没有限制

wait(要调用notify()唤醒),sleep自动唤醒

                                                                                  Spring篇

spring用了那些设计模式

beanFactory用了工厂模式,,Aop用了动态代理模式,RestTemplate用来模板方法模式,SpringMVC中的handlerAdaper用来适配器,spring里的监听用了观察者模式

springmvc工作原理
1.dispatchServerlt接收用户请求发送给handlerMapper
2.handleMapper根据请求url找到具体的handle和拦截器返回给dispatvhServerlet
3.dispatchServerlet调用handleadpter,handleadpter执行具体的controller并将controller返回给moderANDview返回给dispatchServer
4)DispatchServerlet将ModelAndView传给ViewReslover,ViewReslover解析后返回具体view

(5)DispatchServerlet根据view进行视图渲染,返回给用户

springboot自动配置原理

1.springbootConfigguration:表示启动类是一个自动配置类
2.compontScan:扫描启动类所在包外的组件到容器中
3.@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效的类就会被实例化,加载到ioc容器中

springboot的常用注解
@RestController
@RequestMapping():修饰类,该控制器的请求路径
@Autowired:修饰属性,按照类型进行依赖注入
@PathVariable:修饰参数,将路径映射到参数上
@ResponseBody:修饰方法,该方法会返回json数据

                                                redis篇
redis为什么快
完全基于内存,数据都存在内存中
采用单线程,避免了不必要上下文切换带来的性能问题,也不用考虑锁的问题
数据结构简单,对数据操作简单

redis的数据类型
String,list,hash,set,sortset

redis的缓存穿透如何解决
缓存穿透是指频繁请求客户端和缓存中都不存在的数据,缓存永远不生效,请求都到达了数据库
解决办法:
1.在接口上做基础校验,比如id<=0就拦截
2.缓存空对象:找不到数据也给他缓存起来,并设置过期时间,可能会造成短期不一致
3.布隆过滤器,在客户端和缓存之间添加一个过滤器,拦截一定不存在的数据请求

redis如何解决缓存击穿
缓存击穿是值一个key非常热点,key在某一瞬间失效,导致大量请求到达数据库

设置热点数据永不过期

给缓存重建的业务加上互斥锁,缺点就是性能低

redis如何解决缓存雪崩
缓存雪崩是大量的key非常热点,key失效,导致大量的请求到达数据库

                             Spring篇

Spring的生命周期
1.spring容器根据配置中的bean定义一个实例化的bean
2.Spring使用依赖注入填充所有属性,比如bean中所定义的配置
3.如果bean实现了beannameAware接口,则工程通过传递bean的id调用setBeanFactory()
4.如果bean实现了beanFactoryAeare接口工厂通过传递自身的实例来调用setBeanfactory()
5.如果存在bean关联的任何beanPostProcessors则调用PostProcessbeforeInitalization()方法
6.如果bean指定来int方法,那么将调用它
7.如果存在bean关联任何beanPostProcessors()则调用postProcessAfterinitalization()方法
8.如果bean实现了disposableBean接口,当spring容器关闭时,则会调用destroy()
9.如果bean指定了destroy方法(中的destroy-methed属性)那么直接调用他
Spring常用注解

1.@Autowired  :注入bean对象可以用在字段,方法,构造函数上(默认根据类型来自动装配bean)自动配置的方式:类型,名称,构造函数
2.@Component :将类定义为springbean,并交给spring管理,用于自动扫描生成一个实例
3.@Controller :声明springmvc控制器
4.@Service :声明业务逻辑层
5.@Repository :声明数据访问组件
6.@Configuration:声明此类为spring的配置类,用于定义bean的相关配置
7.@bean :在spring配置类中定义的bean,用于手动创建实例
8.@Value :注入属性值或者外部配置文件中的值
9.@Quelifier :当存在多个类型相同的bean时,此注解指定要注入的bean
10.@Scope:指定bean的作用域
11.@PostConstruct :定义bean的初始化方法
12.PirDestory:定义bean的销毁方法
13.@RequeestMapping:映射url到控制器的方法
14.@pathVariable:将url中的占位符映射到方法中
15.@RequestParam:将自定义的请求参数映射到方法参数中
16.@Requestbody:httpbody中的输出数据
17.@Exceptionhandler:定义异常处理办法
18.@Primary:指定默认的bean
19.Transactional(事务注解):
20.19.1 常用参数:propagation:事务的传播机制
     Spring框架的好处
1.轻量级
2.Ioc容器:可以将bean的创建和依赖关系交给bean处理,
3.控制反转:负载创建对象,装配对象,配置对象,管理对象之间的关系,并管理这些对象的生命周期
4.Spring的好处:降低组件的耦合度,管理对象的生命周期,提高代码的可测试性,可以将对象替换成mock对象或者其他的测试对象,提高代码的可维护性,方便实现aop
5.面向切面编程aop:在程序的运行期间,动态的对方法进行增强
6.Aop作用:1.提供声明式事务管理2.实现安全控制3.实现缓存机制,4.实现日志记录5.实现性能监控
7.Aop的通知类型:@Before:前置通知,在方法执行之前@around:环绕通知,围之方法执行@after:后置通知,在方法执行之后@afterReturning:返回通知,在方法返回结果之后执行@AfterThrowwing:异常通知,在方法抛出异常之就执行
8.Aop实现原理:动态代理:代理类是在程序运行时创建的,静态代理:代理类是我们自己定义好的,在程序运行之前就已经编译完成的
9.spring的好处:1.事务管理2.集成性:可以与其他框架无集成3.松耦合4.易于测试

主要模块
1.springcore模块:是框架的核心,提供了ioc和di的功能,将bean的创建和依赖关系交给spring容器
2.springaop模块:提供面向编程的支持
3.springmvc:是spring框架的wed框架
springdao模块:数据访问模块
5.springorm模块:方便进行对象关系映射操作
6.springtest模块:是spring的测试模块
beanfactory:是spring的基本接口,负责管理bean的生命周期,配置元信息,依赖关系,aop事件等,
加载bean定义下的文件,并常见bean的实例化,管理bean的生命周期,包括初始化,装配,销毁等,实现依赖注入和aop,提供事件异常处理机制
2.ApplicationContext:负责读取配置文件,管理bean的生命周期,装配bean之间的管理,事务传播,国际化支持
classPathXmlApplicationContext:从类路径下的xml文件加载上下文
FileSystemXmlApplicationContext:从文件下xml文件加载上下文
AnnotationConfigApplicationContext:根据注解创建上下文
wedApplicationContext:用于wed应用程序的上下文
xmlIwedApplicationContext:用于wed应用程序的xml上下文
StaticApplicationContext:不依赖外部资源的实现
ApplicationContext:是beanfactory的子接口:是即时加载,自己创建和管理资源对象,支持国家化,支持基于依赖的注解

ApplicationContext的获取方式:
1.直接注入,
2.实现applicationContextAware接口,
3.继承wedApplicationObjecrSupport、
4.使用wedApplicatonContextUtils工具类,
5.从当前线程绑定获取
依赖注入:Di:1.构造器注入,2.setter注入,3.字段注入
bean支持的作用域:
1.单例作用域,每个ioc都存在一个实例
2.多例作用域每个请求都会创建一个实例
3.请求作用域:每次http会话都会创建一个新的实例,只在http中有效
4.会话作用域:每次http会话都会创建一个新的实例,只在http会话中有效
5.应用作用域:每个web应用程序都有唯一的实例,在wed应用程序的生命周期有效
spring支持的事务类型
1.编程式事务
2.声明式事务
3.注解驱动事务
spring常见的事务管理器
1.jdbc
2.hibernate
3.jpa
4.分布式事务
5.响应式事务

                                                                   多线程
线程的创建方式
1.通过继承thread类
2.实现Runnable,没有返回值,异常只能在内部处理
3.实现CallAble接口,有返回值,异常可以在内部处理也可以抛出
4.通过线程池创建

线程的状态
1.new:创建时的线程,还没有开始启动
2.runnable:刚触发start方法调用,线程处于就绪状态,等cpu正式调用才会处理运行状态,runnable是这个两个状态的统称
3blocked线程堵塞:等待获取锁,获取到锁就继续运行了进入runnable状态
4.waiting:无限等待状态,比如通过wait方法进行等待,join方法进行等待,当通过相关的事件唤醒线程就继续运行runnable状态
5.timed_waiting进入有时限的等待,比如sleep方法,等待设置的时间过去后,将继续运行
6.terminnated:线程终止

多线程的概念:装有线程的池子
多线程的好处:节省系统资源
线程池创建线程池的核心参数:
1.核心线程池大小,最小线程池大小
2.最大线程池大小,最大线程5亿多
3.空余线程存活时间,超过存活时间将进行销毁
4.工作队列,存储等待执行的线程
5.创建线程的工厂
6.拒绝策略
线程池的执行流程
1.如果线程池的线程小于线程的核心数时,则创建新线程直接执行任务
2.线程池中的线程大于核心线程数的时候,将任务存储到工作队列中
3.如果工作队里满了,线程数小于最大线程池数时,则会创建新的线程来处理,当大于等于最大线程池数时,执行拒绝策略

多线程创建内置的线程池:
1.newFixedTreadPool:固定线程池,核心线程数和最大线程数时固定相等的,存活时间为0毫秒,线程时永远存活的,工作队列为堵塞队列,最大值为integere的最大值
2.newCachedTreadPool:缓存线程池,核心线程池为0,最大线程数为integer最大值,等待时间为60,
秒,使用的事直接提交队列
3.newSingleTreadPool:单线程线程池,核心线程数和最大线程数为1,存活时间为0,永久存活,每次只执行一个线程,多余的放入堵塞队列中一个一个的执行,保证线程的执行顺序

4.newSchediiedTreadPool:调度线程池,按照一定的周期执行任务
5.newSingleScheduledExecutor:单个调用线程池
6.newWorkStealingPool1.8加入:fork/join线程池

线程的拒绝策略
abortPoliy丢弃任务并抛出任务抛出异常
callerRunsPoily:线程池未关闭,调由线程处理该任务
DiscardPoily:丢弃任务,但是不抛出
DiscardOldesPoily:丢弃最早未处理的任务,尝试执行新的任务

提交线程时的方式/关闭线程池
提交线程池:submit:有结果返回,返回一个future对象,execute无结果返回
关闭线程池:shutdown:不接受新的任务,执行之前提交的任务在关闭线程池,返回等结果后关闭线程池
shutdonwnNow:不接收新的任务,停止池中的任务在关闭线程池,返回未处理的线程列表

设置线程池的大小
cpu密集型:设置n+1个线程  线程cpu所占时间比较长
io密集型,设置2n个线程  线程等待的时间比较长
混合型:拆分io密集型和cpu密集型

多线程的CAS
1.比较在交换
2.是一个乐观锁算法,里面有3个操作,旧的预期值A,内存值V要修改的新结果值B当A和内存值V相同时
,将内存V修改结果结果值B,否则一直循环,直到匹配成功
3.失败循环次数过多会导致cpu消耗过大,只能保证一个变量的院子操作,无法同时多个变量的原子操作,会出现aba问题     abc:当一个值为A变成了b又变成了a


多线程的进程和线程的区别:进程:是系统分配资源的最小单位,每个进程都有自己的独立空间
线程:是操作系统调度的最小单位,一个进程里面有多个多线程同时并发操作,每个线程都有自己的独立虚拟机栈,线程之间运行互相不影响

多线程的原子性:一个操作或多个操作要么不执行要么在执行中不被其他操作打断
多线程的可见性:指的是多个操作共享一个变量时,一个线程对变量进行修改,其他线程
可以立即看到最新修改的结果称为可见性
多线程的有序性:程序的执行代码顺序必须按照先后顺序执行的称为有序性,volatlit可以保证有序性
多线程优先级:分为1-10个等级,数字越大优先级越高,默认5超出访问异常

线程的常用方法:
join方法(thread类):
wait
多线程的死锁:多个线程互相占用对方资源的锁,而又互相等待多方释放锁
多线段的活锁:在多线程互相谦让,导致资源在多线程中跳动,而不执行
多线程的无锁:多个线程同时修改一个共享资源,但同时只有一个线程能够修改成功,其他失败的线程会一直重试,知道共享资源修改成功过


mysql的三范式:
原子性:(确保每列保持原子性)
唯一性(确保表中的每列都和主键有关)
冗余性:确保每列都和主键列直接相关
事务特性:
原子性A,一致性,隔离性,持久性,
事务的隔离级别
允许脏读,幻读,不可重复读            读未提交
不允许脏读,允许幻读,不可重复读  读已提交
默认隔离级别   可重复读
不允许脏读,不可重复读,允许幻读 可重复读
都不允许  单行化

索引
索引的优点:存储是有序的,因为有序,所以在通过索引查询的时候不用遍历所有记录 查询速度快
通过创建唯一索引,保证数据库表中的每一行数据的唯一性
通过创建外键索引,加快表和表之前的连接
索引的缺点:占用物理空间
数据量越大,维护索引消耗时间越长
降低修改和删除的速度

索引单表最多创建64个索引
每个索引最多包含16列

底层数据结构
B+Tree:
1.提高索引查询时的磁盘IO效率,提高范围查询效率
2.查询IO次数少
3.查询都是查询子节点,稳定性强
4.元素是有序的

哈希索引:
1.适合等值查询,无法范围查询
2.无法用索引完成排序
3.不支持多列联合索引的最左匹配规则
4.会存在哈希碰撞问题,效率会低

hashmap1.7版本扩容
1.先生成新数组
2.遍历老数组中的每个位置上的链表上的每个元素
3.获取每个元素的key,并基于新数组的长度,计算每个元素在新数组的下标
4.将元素添加到新数组中
5.将所有元素转移完后,将新数组赋值,给hashmap对象的table属性
hashmapjdk1.8版本扩容
1.先生成新数组
2.遍历老数组中每个位置的链表或者红黑树
3.如果是链表,则直接将链表中每个元素重新计算下标,并添加新数组中去
4.如果是红黑树,则先遍历红黑树,先计算出红黑树每个元素对应在新数组中的下标位置
a:统计每个下标位置的元素个数
b.如果该位置下的元素个数超过了8则会生成一个新的红黑树,并将根节点添加到新数组的对应位置
C.如果该位置下的元素个数没有超过8,那么则会生成一个链表,并将链表的头结点添加到新数组的对应位置
5.所有元素转移完了之后,将新数组赋值给HashMap对象table属性
jdk1.7采用的是头插法 1.8采用的是尾插法
1.7数据结构为,数组+链表 1.8位数组+链表+红黑树
因为1.8插入key或者value时会先遍历每个元素链表个数

mybatis的执行流程
1.根据配置文件创建SqlsessionFactory工厂对象
2.创建Sqlsession会话对象,里面包含了sql的所有方法
3.创建exector执行器对象,根据sqlSession传递的参数动态生产sql语句
4.通过StatementHandler对象执行sql语句,并使用ParamerentHandld处理参数
5.ResulrSetHandle和TypeHandler将结果映射为java对象或者列表返回用户

开启事务方法
1.配置事务管理器
2.通过sqlsession操作事务
3.使用RowBounds对象

实现分页
1.通过sql实现
2.可以通过分页插件Pagehelper


传参的方式
1.顺序传参
2.@Param注解传参
3.Map传参
4.JavaBean传参

缓存机制
1.一级缓存:是sqlsession内部共享的缓存区,是sqlsession缓存级别,底层PerpetualCache缓存,使用hashmao存储

2.二级缓存:是Mapper级别缓存,是跨sqlsession的,同一个mapper产生的sqlsession都共享一个二级缓存,只要mapper的namespace相同就能共享数据,只要当一级缓存的sqlsession对象使用并提交或者关闭时,才会提交到二级缓存,底层使用LruCache缓存,lrucache使用linkedHashMao来保存

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值