2025年java面试知识点(java面试题总结)

java面试知识点(java面试题总结)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。



 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <blockquote> 

讯享网

最近找工作不写一遍老感觉记不住,基本纯手写,如遇到错误麻烦大家指正!

1)语法层面
1.接口关键字为interface;抽象类关键字为abstract。
2.接口子类用implements来实现,支持可以多实现;抽象类本质也是一个类,子类用extends来继承,为单继承。
3.抽象类中可以有构造函数和main方法(构造方法用于子类的实现),接口中没有
4.抽象类的成员变量可以是变量也可以是常量,成员方法可以是抽象方法也可以非抽象方法;接口中成员变量只能是常量(默认修饰符:public static final),成员方法在jdk1.8中添加了default和static的具体方法。
2)设计层面的区别(选择的依据)
1.抽象类重点描述的是抽象的概念,比如具体生活中的概念:动物,植物,食物等
2.接口重点描述的是特征,比如 飞 这个方法,麻雀可以飞,蜻蜓可以飞。

1)封装
是指将类的细节部分包装、隐藏起来的方法。封装可以认为是一个保护屏障,防止该类的代码数据被外部定义的代码随机访问。对外界而言,它的内部细节是隐藏的,暴露给外界的只是它的访问方法。封装的优点:能够减少耦合、类内部的结构可以自由修改、隐藏信息实现细节。通俗来讲,封装就是该让你访问到的会访问到,不该访问的就隐藏起来。
2)继承
继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并扩展自己新的能力,就形成了父子类关系。也提高了代码的复用性。举例来说,兔子和羊是食草动物,狮子和豹子是食肉动物,而食草动物和食肉动物又都是动物类。虽然食草动物和食肉动物都属于动物类,但两者属性和行为上又有差别,所以子类具有父类的一般特性,也会有自身的特性。
3)多态
顾名思义,多态就是同一行为具有多个不同表现形式,比如说打印机,有彩色打印机,打印彩色,黑白打印机打印黑白。多态存在的三个必要条件,继承,重写,父类引用指向子类对象。同时多态特征优点也很多,可替换性、灵活性、简化性。

四类八中

数据类型字节数位数整形byte18short216int432long864浮点型float432double864布尔型boolean18字符型char216

1)== 的作用:基本类型比较值是否相同、引用类型比较的是地址值是否相同
equals的作用:默认情况下比较的是地址值,但是重写了equals方法就比较的内容。
2)一般equals比较时,常量要写前面避免空指针异常。

讯享网


1)虽然java有垃圾回收机制,但是也还是会存在内存泄漏的问题
2)java内存泄漏指的是:对象不在被程序所使用,垃圾回收器没有将其收回,对象仍然处于被引用的状态,久而久之,不能回收的内存越来越多,最终就导致了内存溢出。
3)内存泄漏的原因:
*单例模式静态持有的引用
*各种连接(数据库连接,网络连接,IO连接等),各种流未关闭
*静态集合类引起的,如HashMap,LinkdList等,生命周期与程序一致,容器中的对象在程序结束之前不能被释放
*内部类持有外部类,非静态内比类会持有外部类,如果有地方引用了这个非静态内部类,会导致外部类也被引用,垃圾回收时无法回收这个外部类。

4)解决方法
*尽量减少使用静态变量,或者使用完及时 赋值为 null。
*明确内存对象的有效作用域,尽量缩小对象的作用域,能用局部变量处理的不用成员变量,因为局部变量弹栈会自动回收;
*减少长生命周期的对象持有短生命周期的引用;
*对于不需要使用的对象手动设置null值,不管GC何时会开始清理,我们都应及时的将无用的对象标记为可被清理的对象;
*各种连接(数据库连接,网络连接,IO连接)操作,务必显示调用close关闭。

1)基本区别string是不可变的,stringBuffer、stringBuilder是可变的。string是字符串常量,stringBuffer和stringBuilder是字符串变量
2)性能方面,stringBuilder执行最快,其次为stringBuffer,最后是string
3)安全方面,string和stringBuffer是线程安全的,stringBuilder线程是不安全的
4)用途方面,string适用于少量字符串操作,stringBuffer适用于多线程下字符串缓冲区进行大量操作,stringbuilder适用于单线程下字符串缓冲区进行大量操作。

1)继承线程类Thread
优点:编写简单,直接使用this即可获得当前线程
缺点:继承了Thread类,就不能继承其他父类。

 

2)实现Runnable接口
优点是:可以继承其他的类,这种方式下共享同一个target对象,适合多个相同的线程来处理同一份资源的情况
缺点就是编程相对比较复杂

讯享网
 

new 新建状态 (创建线程对象)
runnable 就绪状态(start方法)
blocked 阻塞状态(无法获得锁对象)
waiting 等待状态(wait方法)
time_waiting 计时等待(sleep方法)
terminated 结束状态(全部代码运行完毕)

讯享网

递归概述:以编程的角度来看,递归指的是方法定义中调用方法本身的现象

 

1)ArrayList和LinkedList的区别
①首先,ArrayList底层结构是动态数组结构,地址是连续的,一旦数据存储好了,查询效率会比较高。增删较慢。LinkedList是基于链表的数据结构,其中add和remove比较占优。缺点就是LikedList要移动指针,所以查询的性能比较低。
②ArrayList和LinkedList都实现了List接口,而LinkedList还实现了Deque接口,所以LinkedList还能当双端对列来使用。
2)HashMap和Hashtable的区别
①hashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()
②hashTble是同步的,而hashMap是非同步的,效率上要比hashTable要高
③hashMap允许空键值,而hashTable不允许

inner join… on
left join…on
right join …on
在这里插入图片描述
讯享网

1.隔离性:一个事务不被其他事务干扰,多并发的事务之间相互隔离。
2.持久性:一个事务一旦被提交,对数据库的改变是永久性的。
3.原子性:一组sql语句是不可分隔的单位,要么都发生要么都不发生。
4.一致性:执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。

1.脏读:一个事务读取到了另一个未提交的数据,
2.不可重复读:一个事务中两次读取的数据内容不一致,只要是update操作。
3.幻读:一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同,主要发生在delete,insert操作。

1.读未提交 read uncommitted
2.读已提交 read committed 可避免脏读
3.可重复读 repeatable read 避免了脏读,和不可重复读
4.串行化 serializable 最安全,但是性能最低。
安全性:serializable > repeatable read > read committed > read uncommitted
性能 : serializable < repeatable read < read committed < read uncommitted

1.MyISAM在mysql5.5之前是默认的存储引擎,虽然MyISAM性能各方面还行,但是他不支持事务和行级锁,最大的缺陷是崩溃后无法安全恢复。
2.是否支持行级锁MyISAM只有表级锁,而InnoDB支持行级锁和表级锁,默认为行级锁。也就是说MyISAM一锁就是整张表,在并发的时候性能比较低。
3.是否支持事务MyISAM不支持事务,InnoDB提供事务支持,实现了SQL标准定义的四个隔离级别,读未提交,读已提交,可重复读,串行化,InnoDB默认是可重复读,可以解决脏读和不可重复读的问题。
4.是否支持外键MyISAM是不支持外键的,而InnoDB支持。
5.是否支持数据库异常崩溃后的安全恢复MyISAM不支持,而InnoDB支持,使用InnoDB的数据库异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态。
6.索引的实现不一样都是B+Tree作为索引结构。。。巴拉巴拉。

请添加图片描述

1.首先乐观锁和悲观锁都是用于解决并发场景的数据竞争问题,但却是两种完全不同的思想,他们使用广泛,不局限于编程语言或数据库。
2.乐观锁:指的是在操作数据库的时候非常乐观,乐观的认为别人不会同时修改数据,因此乐观锁默认是不上锁的,只有在执行更新的时候才会去判断在此期间别人是否修改了数据,如果别人修改了数据则放弃操作。----冲突较少的时候,使用乐观锁,由于乐观锁默认不上锁的特性,所以在性能方面要比悲观锁好,比较适用于读大于写的业务场景。
3.悲观锁:指的是操作数据库的时候比较悲观,悲观的认为别人一定会同时修改数据,因此悲观锁在操作数据时是直接把数据上锁,直到操作完毕后才会释放锁,在上锁期间不能操作数据。----冲突比较多的时候,使用悲观锁,对每一次的数据修改都要上锁,适合写大于读的情况。
4.读取频繁使用乐观锁,写入频繁使用悲观锁。

1.什么是索引:是帮助MySQL高效获取数据的有序数据结构,将数据进行排序整理的过程就称为索引。可以大大提高查询的速度。
2.创建索引
在已有的表的字段上直接创建

讯享网

创建表的时候指定(掌握)

 

3.索引创建的原则:①字段内容的可识别度不能低于70%,字段内数据唯一值得个数不能低于70%;
②经常使用where条件搜索的字段,例如user表的id name等字段
③经常使用表连接的字段,可以加快连接的速度。
④经常排序的字段,order by。因为索引已经排过序了,就会加快排序查询速度。
4.索引的缺点:索引的建立和维护都需要耗时,数据库中创建索引需要占用一定的存储空间,在表中的数据进行修改时,索引还需要动态维护。

1.列参与了运算(例如使用不等于查询!=,列参与了数学运算或者函数)
2.以%开头的Like模糊查询,索引失效
3.当mysql分析全表扫描比使用索引快的时候不使用索引.
4.in 走索引, not in 索引失效。
5.字符串不加单引号,造成索引失效。
6. 如果MySQL评估使用索引比全表更慢,则不使用索引。

1.轻量

入门简单,上手较快,一个完整的spring框架大小在1M左右,占用空间小,开销也小,加载的时候不用加载全部内容。

2.IOC 控制反转,依赖注入

spring通过IOC技术促进低耦合,不主动创建对象,一个对象依赖其他对象是通过被动方式传递进来的。控制反转的意思就是,对象的控制权(创建,销毁。。)从开发者的手中转移到了工厂中。

1.取值的时候,${id}取值时必须使用@param,如果是单个值可以用 ${value}。#号取值时如果没有@param指定参数名称,括号里面可以随便写。
2.使用 ${ }获取参数的时候有sql注入的问题,它是直接将实参拼接到sql语句的位置。
3.#{ }是预编译方式将参数设置到sql语句中的,防止sql注入问题,参数是以 ? 显示的。

– —${ }虽然有sql注入的问题,但是也有应用场景,需要对sql语句进行拼接(不是参数)

讯享网

1.SqlSessionFactoryBuilder;会话工厂构造类创建会话工厂对象
2.SqlSessionFactory:会话工厂类创建会话对象
3.SqlSession:会话类

即对象关系映射,是一种数据持久化技术。他在对象模型和关系型数据库直接建立起对应关系,并且提供一种机制,通过javaBean对象去操作数据库表的数据。

 

3.开启驼峰映射,字段的下划线会自动转化。

使用mysql的拼接函数 concat(’ %‘,’#{ name} ‘,’ %'),既可以防止sql注入,又拼接了参数。

1.mybatis支持一对一和一对多的延迟加载,在配置文件中可以配置lazyLoadingEnabled = true 开启。
2.延迟加载就是懒加载,在真正使用数据的时候才发起查询,不用的时候不查询关联的数据。
3.原理是,他使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现了a.getB()是null值,那么就会单独查询B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着a.getB().getName()就完成了调用,这就是延迟加载的基本原理。

1.缓存就是用来提高查询和访问速度的,就是将每次的访问记录缓存在一个地方,下次查询的时首先访问的不是数据库,而是缓存,在缓存中查到了,就不访问数据库了。
2.一级缓存是本地缓存,是由PerpetualCache类的HashMap本地缓存实现的,他的作用域是SqlSession,比如说一个SqlSession执行两次sql查询,两次的位置是不同的,第一次缓存中没有去数据库,第二次就在缓存中查,等SqlSession结束后相应的缓存也就销毁了。mybatis默认一级缓存开启,不能关闭。
3.二级缓存是全局缓存,默认也是有PerpetualCache类中Hashmap存储的,他的作用域是mapper范围的,多个SqlSession可以共享二级缓存,同一个mapper的namespace,在同一个namespace中查询sql可以从缓存中命中,不同的SqlSesison可以从二级缓存中命中。先进入一级缓存,一级缓存中的SqlSession 关闭后,一级缓存的数据存入二级缓存中。一旦进行了增删改操作会将二级缓存清空。二级缓存需要手动开启 setting标签 cacheEnabled 为true开启。

公司服务器有限,用户量暴增,此时有两个方案,1.增加服务器数量。2.将并发的请求快速存放到对列中,存放完毕后,给用户响应一个信息,操作成功
总的一句话就是,用更少的服务器接收更多的请求,缓存请求,请求在 对列中等。
RabbitMq

同步请求的优点:时效性强,可以立即得到结果。
     缺点:耦合度高,性能和吞吐能力下降,有额外的资源消耗。
异步请求的优点:吞吐量提升,响应速度更快。故障隔离,服务没有直接调用,不存在级联失败的问题、调用件没有阻塞,不会造成无效资源的占用、耦合度低,每个服务可以灵活插拔,可替换、流量削峰,不管发布的流量波动多大,都由broker接收,并按照自己的速度处理。
     缺点:架构复杂,业务没有明显的流程线,不好管理、需要依赖broker
问:如果让你选择用异步还是同步,你怎么选?
大多时候用的都是同步请求,就是因为同步请求时效性很强,这是异步请求没有的。

1)基本模式。简单对列模型
在这里插入图片描述
2)工作模式。WorkQueue也称为任务模型,多个消费者绑定到一个对列,共同消费对列的消息。
在这里插入图片描述
3)发布订阅模型
在这里插入图片描述
订阅模型中多了一个exchange角色,过程发生了变化
publisher生产者,发送消息不在直接发送给对列,而是发给交换机。
exchange交换机,exchange接收生产者的消息,处理消息又分为了三大类型
  Fanout:广播,将消息交给所有绑定到交换机的队列
  Direct:定向,把消息交给符合指定routing key 的队列
  Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
exchange交换机只负责转发消息,不具备存储消息的能力。

1.生产者消息确认,RabbitMQ提供了confirm机制来避免消息发送到MQ过程中丢失。这种机制必须给每个消息指定一个唯一id。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。
返回结果有两种方式:
confirm发送者确认
成功到达交换机,返回ack
位成功,返回nack
return发送者回执
消息到达交换机了,但是没有路由到对列,返回ack和路由失败原因。
2.消息持久化,生产者发送消息成功到RabbitMQ对列中,此时MQ宕机,可能就会发生消息丢失。就必须开启持久化机制。
交换机、对列、消息持久化。
3.消费者确认机制,消费者获取消息后,应该向rabbitMQ发送ack回执,表名自己已经处理消息。
消费者确认机制分为三种确认模式:
manual:手动ack,自己调用api发送ack
none:关闭ack,此模式是不可靠的,可能丢失。
auto:自动ack,由spring监测代码,没有异常返回ack。一般默认用auto模式。
当auto模式代码出现异常时,对列会不断重新发送给消费者,无限循环报错,导致消息处理飙升,出现不必要的压力。配置retry就可以解决问题,重试达到最大次数后,Spring会返回ack,消息会被丢弃。

小讯
上一篇 2025-04-19 11:30
下一篇 2025-04-28 08:47

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/157619.html