Java 面试常见题【未记录完】
自述
记录 Java 面试常见问题,欢迎留言监督
Api 接口如何实现 ?
在类里使用 implement 关键字实现 Api 接口
MySQL 链接数据库常用的几种方式 ?
- Mybatis 框架
- Hibernate 框架
- JDBC 技术
- c3p0 连接池
- dbcp 连接池
SpringBoot 如何集成 Redis ?
在 pom.xml 文件引入 redis 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在 application 配置文件中 书写 redis 配置
spring.redis.host=127.0.0.1 #Redis服务器连接端口 spring.redis.port=6379 #Redis服务器连接密码(默认为空) #spring.redis.password=
SpringCloud 的优点 ?
- 服务之间采用Restful等轻量级通讯
- 精准的制定优化服务方案,提高系统的可维护性
- 服务之间拆分细致,资源可重复利用,提高开发效率
SpringCloud 用了哪些组件 ?
- netflix Eureka 注册中心
- netflix Ribbon 负载均衡
- netflix Zuul 网关
- netflix Hystrix 熔断器
- feign 服务调用
堆和栈的区别 ?
- 栈内存用来存储局部变量和方法调用
- 而堆内存用来存储 Java 中的对象.无论是成员变量,局部变量,还是类变量.,它们指向的对象都存储在堆内存中.
- 栈内存归属单个线程,一个栈对应一个线程,其中储存的变量只能在该线程中可以访问到,也可以理解为私有内存
- 而堆内存中的对象 所有线程均可见,堆内存中对象可以被所有线程访问到
- 栈内存要远小于堆内存
ArrayList 与 LinkList 的区别 ?
- AarrayList 是动态数组构成 LinkList 是链表组成
- AarrayList 常用于经常查询的集合,因为 LinkList 是线性存储方式,需要移动指针从前往后查找
- LinkList 常用于新增和删除的集合,因为 ArrayList 是数组构成,删除某个值会对下标影响,需要进行数据的移动
- AarrayList 自由度较低,需要手动设置固定的大小,但是它的操作比较方便的,①直接创建②添加对象③根据下标进行使用
- LinkList 自由度较高,能够动态的随数组的数据量而变化
- ArrayList 主要开销在List需要预留一定空间
- LinkList 主要开销在需要存储结点信息以及结点指针信息
List 和 Map 的区别
- List 允许有多个重复对象,而 Set 不允许有重复对象
- List 允许有多个NULL值,而 Set 只允许有一个NULL值
- List 是一个有序的容器,输出顺序即是输入顺序
- Set 是一个无序的容器无法保证每个元素的顺序,但是可以用 TreeSet 通过 Comparator 或者 Comparable 维护排序顺序
- List的实现类有 ArrayList、LinkList、Vector 其中 ArrayList 最常用于查询较多,随意访问.LinkList 同于新增和删除较多的情况,Vector 表示底层数组,线程安全象
- Set的实现类有 HashSet、TreeSet、LinkedHashSet 其中基于 HashMap 实现的 HashSet 最为流行,TreeSet 是一个有序的Set容器象
扩展
Map的实现类有HashMap、HashTable、TreeMap
Java 中 static 的作用
- 表示全局或静态的意思、用来修饰成员变量和成员方法,也可以形成静态代码块
- 达到了不用实例化就可以使用被 public static 修饰的变量或方法
sleep() 和 wait() 有什么区别?
- 最大区别是sleep() 休眠时不释放同步对象锁,其他线程无法访问 而wait()休眠时,释放同步对象锁其他线程可以访问
- sleep() 执行完后会自动恢复运行不需要其他线程唤起.而 wait() 执行后会放弃对象的使用权,其他线程可以访问到,需要其他线程调用 Monitor.Pulse() 或者 Monitor.PulseAll() 来唤醒或者通知等待队列
什么单例模式 ?
保证整个项目中一个类只有一个对象的实例,实现这种功能就叫做单例模式
- 单例模式的好处:
- 单例模式节省公共资源
- 单例模式方便控制
- 如何保证是单利模式 ?
- 构造私有化
- 以静态方法返回实例
- 确保对象实例只有一个
- 单例模式有哪几个 ?
- 饿汉模式
把对象创建好,需要使用的时候直接拿到就行
- 懒汉模式
等你需要的时候在创建对象,后边就不会再次创建
SpringBoot 常用的几个注解 ?
- @SpringBootApplication SpringBoot的核心注解 启动类
- @EnableAutoConfiguration 开启SpringBoot自动配置
- @RestController 在控制层 是@ResponseBody注解与@Controller注解的合集
- @RequestMapper 处理请求地址映射的注解
- @RequestParam 获取url上传过来的参数
- @Configuration 声明配置类
- @Component 通用注解
- @Service 业务逻辑层
Java 八大数据类型
char 字符型 byte 字节型 boolean 布尔型
float 单浮点型 double 双浮点型
int 整数型 short 短整数型 long 长整数型
MySQL分页和升序降序如何实现 ?
- 可以用 limit
select
name
,age
,sex
from t_student limit(0,5);
- 升序 order by xx asc
select
name
,age
,sex
from t_student order byage
asc;
- 降序 order by xx desc
select
name
,age
,sex
from t_student order byage
desc;
maven 是干什么的,它有什么好处 ?
- maven 专门构建和管理Java项目的工具
- maven的好处在于可以将项目过程规范化、自动化、高效化以及强大的可扩展性
Sql调优
- 创建索引 尽量避免全盘扫描 首先考虑在 where 和 order by 涉及的列上创建索引
- 避免在索引上使用计算 注意就是IN关键字不走索引,它是走全盘扫描
- 使用预编译防止 sql 注入
- 尽量将多条 SQL语句压缩到一条 SQL 语句中
- 最最最好的就是少用 * , 应该写成要查询的字段名,尽量避免在 where 条件中判断 null
- 尽量不用like 的前置百分比
- 对于连续的数值,能用 between 就不要用 in
- 在新建临时表时,如果一次性插入数据量较大.可以用 select into 代替 create table
MySQL 的常用引擎 ?
InnoDB 和 Myisam 都是用 B+Tree 来存储数据的
- InnoDB 支持事务,且支持四种隔离级别(读未提交、读已提交、可重复读、串行化),默认的为可重复读.
- Myisam 只支持表锁,且不支持事务.Myisam 由于有单独的索引文件,在读取数据方面的性能很高.
MySQL 如何添加索引 ?
- PRIMARY KEY (主键索引)
- 添加INDEX(普通索引) ALTER TABLE
table_name
ADD INDEX index_name (column
)- 添加FULLTEXT(全文索引) ALTER TABLE
table_name
ADD FULLTEXT (column
)- 添加多列索引 ALTER TABLE
table_name
ADD INDEX index_name (column1
,column2
,column3
)
MySQL 索引的实现方式?
Vue的数据双向绑定原理
使用v-mode属性, 它的原理是利用了Object.defineProperty()方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的
redis缓存预热
- 在项目配置文件中生命自定义的key,在项目启动时会判断redis是否存在key,如果没有就会创建一个key传入null值
- 数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中
redis缓存穿透是什么,怎么解决 ?
就是访问redis数据库,查不到数据,就是没有命中,会去持久化数据库查询,还是没有查到.假如高并发的情况下,持久化数据库一下增加了很大压力,就相当于出现了缓存穿透
解决方案
- 缓存空对象 在存储层命中失败后,即使返回空对象也将其缓存,并设置一个过期时间,之后访问的这个数据将会从缓存中取出,很好的保护了后端数据源,这样也会有出现问题 例如空值被缓存也就会增加大量的缓存空间,设置了过期时间还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响
- 布隆过滤器 对所有可能查询的参数以 hash 形式存储,查询时发现值不存在就直接丢弃,不会去持久层查询
redis 缓存雪崩是什么,怎么解决 ?
缓存雪崩是指,缓存层出现了错误,不能正常工作了.于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况.
解决方案
- redis 高可用 就是搭建 redis 集群,其中一台redis挂掉后 可以使用其他的 redis
- 限流降级 就是每一个 key 只能一个线程来查询数据和缓存,其他线程等待
- 数据预热 数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中.在即将发生大并发访问前手动触发加载缓存不同的 key ,设置不同的过期时间,让缓存失效的时间点尽量均匀.*
RabbitMQ的消息存储方式
RabbitMQ 对于 queue 中的 message 的保存方式有两种方式:disc 和 ram.如果采用disc,则需要对 exchange/queue/delivery mode 都要设置成 durable 模式. Disc 方式的好处是当 RabbitMQ 失效了, message 仍然可以在重启之后恢复.而使用 ram 方式, RabbitMQ 处理 message 的效率要高很多, ram 和 disc 两种方式的效率比大概是 3:1.所以如果在有其它 HA 手段保障的情况下,选用 ram 方式是可以提高消息队列的工作效率的.
ActiveMQ的消息存储方式
- 采取先进先出模式,同一时间,消息只会发送给某一个消费者,只有当该消息被消费并告知已收到时,它才能在代理的存储中被删除.
- 对于持久性订阅来说,每一个消费者都会获取消息的拷贝.为了节约空间,代理的存储介质中只存储了一份消息,存储介质的持久订阅对象为其以后的被存储的消息维护了一个指针,消费者消费时,从存储介质中复制一个消息.消息被所有订阅者获取后才能删除.
KahaDB消息存储
基于文件的消息存储机制,为了提高消息存储的可靠性和可恢复性,它整合了一个事务日志.KahaDB拥有高性能和可扩展性等特点.由于KahaDB使用的是基于文件的存储,所以不需要使用第三方数据库