前言
网上的 Java 基础面试题文章有非常多,但是很多都太官方了,太繁琐了,不太好理解甚至随着java版本更新,很多以前的答案也不太准确了,所以我就记录一版2021年的面试题!(个人理解,请谨慎参考!)。
本文章包含:java基础,集合,多线程,mysql,java框架等面试题。
正文
一,java基础
1,面向对象的三大基本特征?
三大基本特征:封装,继承和多态。
封装:把现实中的一类实例封装成一个类,包括它的属性和行为,并且类可以把自己的属性和行为只让可信的类或者对象操作,对不可信的类或者对象进行信息隐藏。
继承:一个类继承另外一个类,子类继承父类,子类继承父类的一些特性,子类可以从父类那里继承到方法和实例变量,并且可以修改和增加方法来满足当前的需要,通过继承可以满足代码的重用性 。
多态:多态存在的3个条件:1,继承;2,重写;3,父类引用指向子类对象。 对于同一个行为,不同的子类对象有不同的表现形式。
2,访问修饰符public,private,protected,以及不写时的区别?
public :对所有类可见。使用对象:类、接口、变量、方法。
private :在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
default (默认): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
3,用最有效率的方法计算2乘以8?
可以使用位运算符:2 << 3 ,通常情况下,可以认为位运算是性能最高的。
4,&和&&的区别?
都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&(逻辑与):可以用作位运算符,当 & 操作符两边的表达式不是boolean类型时,& 表示按位与操作。
&&(短路与):具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。
5,String 是 Java 基本数据类型吗?
答:不是,String是引用数据类型。Java 中的基本数据类型只有8个:byte、short、int、long、float、double、char、 boolean;
除了基本类型(primitive type),剩下的都是引用类型(reference type)。
6,String 类可以继承吗?
答:不行。String 类使用 final 修饰,无法被继承。
7,final在java中有什么作用?
final修饰过的类,叫做最终类,无法被继承。
final修饰过的方法不能被重写。
final修饰过的变量,叫做常量,创建时必须要初始化,不能被二次赋值。
8,String和StringBuilder、StringBuffer的区别?
String : 声明不可变的类,每一次操作都会创建新的对象,并且把指针指向新的对象。
StringBuffer : 声明可变的对象,线程安全,效率低。
StringBuilder : 声明可变的对象,线程不安全,效率高。
因此我们在不考虑线程安全的情况下推荐使用StringBuilder,考虑线程安全的情况下推荐使用StringBuffer 。
9,== 和 equals 的区别是什么?
==:运算符,用于比较基础类型变量和引用类型变量。
比较基础类型变量,比较的变量的值是否相同,类型不一定要相同。
比较引用类型变量,比较的是两个对象的地址是否相同。
equals:Object 类中定义的方法,通常用于比较两个对象的值是否相等。
10,两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
答:不对。当 a.hashCode() == b.hashCode() 时,a.equals(b) 不一定为 true。
11,两个对象的 equals() 相同,则 hashCode() 也一定为 true,对吗?
答:对。当有 a.equals(b) == true 时,则 a.hashCode() == b.hashCode() 必然成立。
12,什么是反射?
反射是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称为反射。
13,重载与重写的区别?
重载(overload):在同一个类中有几个方法,它们的方法名一致,但参数列表不同,与返回值无关。
重写(override):子类重写父类的方法,他们方法名,参数列表一致,返回值不能大于父类类型。
14,构造器是否可被重写?
构造器(Constructor) 不能被重写,但是可以被重载,这就是⼀个类中可以有多个构造函数的原因。
15,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:值传递。Java 中只有值传递,对于对象参数,值的内容是对象的引用。
16,静态变量与成员变量的区别?
1,静态变量存储在方法区中,成员变量存储在堆内存中。
2,静态变量从属于类,随着类的存在而存在,消失而消失,成员变量与对象共存亡。
3,静态方法通过类名的方式调用,成员变量通过对象调用。
17,抽象类(abstract class)和接口(interface)有什么区别?
1,抽象类只能单继承,但是可以实现多个接口。
2,抽象类可以有构造方法,接口没有。
3,抽象类可以有普通方法,接口只能有抽象方法。
4,抽象类可以有成员变量,接口只能有常量。
我在网上看到有个说法,挺形象的:
普通类像亲爹 ,他有啥都是你的。
抽象类像叔伯,有一部分会给你,还能指导你做事的方法。
接口像干爹,可以给你指引方法,但是做成啥样得你自己努力实现。
18,Exception 和 Error 有什么区别?
Error 和 Exception 都是 Throwable 的子类,用于表示程序出现了异常的情况。区别在于:
Exception:表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题。
Error:表示系统级的错误和程序不必处理的异常,是一种严重问题,比如内存溢出,不可能指望程序能处理这样的情况。
19,final、finally、finalize 的区别?
final:是java中的一个修饰符,修饰的类不能被继承,修饰的方法不能被重写,修饰的变量必须初始化,并且不能被二次赋值。
finally:是处理异常的一个代码块,通常配合 try、catch 使用,不管有没有异常,都会执行!
finalize :Object 中的一个方法,在对象被垃圾回收之前,java虚拟机就会调用该方法。
20,log4j的级别以及使用场景?
DEBUG:主要用于程序的调试,输出debug信息
INFO:主要用于打印正常信息和提示信息
WARN:表示潜在的错误,提示警告信息
ERROR:表示系统发生错误,但是不影响程序运行,提示错误信息
FINTA:表示程序发生重大错误,会让程序退出,提示严重错误
ALL level: 是最低等级的,用于打开所有日志记录
OFF level: 是最高等级的,用于关闭所有日志记录
log4j建议只使用五个级别,级别顺序(由低到高): DEBUG < INFO < WARN < ERROR < FATAL
二,java框架
1,JDBC 跟 Mybatis的区别?
1,mybatis是一个轻量级的持久层框架,但是底层用的也是jdbc。
2,mybatis封装了jdbc,相对于直接使用jdbc大大提高了效率。
3,mybatis中的SQL是写到配置文件中的,降低程序与SQL的耦合,方便维护。
4,mybatis支持动态SQL,以及较难的SQL编写。
2,简述一下什么是事务,事务的特性?
事务:一系列操作形成的一个整体业务单元,该业务单元是不可分割的,要么同时完成,要么同时结束!
四大特性:原子性,一致性,隔离性,持久性。
1,原子性:事务是不可分割的最小业务单元,事务内的操作要么全部都做,要么全部都不做。
2,一致性:事务执行时,是从一个一致状态变成另一个一致状态。
3,隔离性:一个事务的执行,不受其他事务(进程)的干扰。
4,持久性:事务一旦提交,对数据库的改变是持久的。
3,简述事务的类型?
编程式事务:以编程的方式管理事务,灵活但是难维护。
声明式事务:将业务代码和事务管理分离,用注解或者xml来管理事务,解耦且便于维护。
4,Spring框架的优点都有什么?
1,简化开发,spring对一些较难的API进行了封装,不仅更简洁而且质量更高。
2,提供了两大核心:
IOC:控制反转,应用本身不负责对象的创建以及依赖关系管理和维护,统一由IOC管理,特点就是,解耦,利于维护,同时也实现了资源的统一调度和管理。底层使用的是反射
AOP:面向切面编程,程序运行期间,在不改变原有代码的基础上动态的增强某个类或者某个方法,底层使用的是动态代理。AOP主要用来全局事务,全局异常,全局日志等处理。
3,轻量级的应用框架。
4,优秀的集成了其他框架。
5,构造器注入和 setter 依赖注入,那种方式更好?
答:每种方法都有他的特点,构造器注入的特点是保证每个注入都能初始化,setter方法注入更加灵活。
6,IOC的注入方式?
1,构造方法注入;
2,setter属性注入;
3,接口注入;
7,什么是IOC/DI,实现原理是什么?
IOC: 控制反转,指将对象的依赖关系交给IOC容器来管理。
DI: 依赖注入,指IOC容器通过构造器或者setter注入的方式建立对象之间的依赖关系。
8,简述SpringMVC的请求流程?
1,用户发送请求至前端控制器DispatcherServlet
2,DispatcherServlet收到请求调用HandlerMapping处理器映射器找到具体的Handler处理器并且返回给DispatcherServlet
3,DispatcherServlet通过HandlerAdapter处理器适配器调用Controller处理器
4,执行处理器(Controller,也叫后端控制器),Controller执行完成返回ModelAndView
5,DispatcherServlet将ModelAndView传给ViewReslover视图解析器,ViewReslover解析后返回具体View
6,DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中),DispatcherServlet响应用户
9,简述什么是MVC?
MVC:mvc是一种软件设计架构模式,是一种设计规范。主要作用就是降低视图与业务逻辑之间的双向耦合。
M: Mode,V: View,C: Controller
Model(模型):是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
View(视图):是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
Controller(控制器):是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
10,常用的设计模式有哪些,简单描述下其应用场景?
单例模式:保证系统中一个类只有一个实例而且该实例易于外界访问
工厂模式:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
11,springboot是什么?它有什么特点?
1,springboot提供了快速使用spring的方法。
2,内嵌tomcat和jetty容器,jar包直接发布一个web应用。
3,简化maven配置,一站式引入需要的各种依赖。
4,和各种流行框架,springMVC,mybatis,spring cloud无缝整合。
5,能快速的构建项目,可独立运行。
6,约定大于配置。
7,自动配置,让配置变得更简单。
12,什么是Nginx?它能做些什么?
Nginx是一款轻量级的Web服务器/反向代理服务器。
主要是用来做,反向代理,负载均衡。
Nginx的应用场景:
1、 http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器
2、 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
基于端口的,不同的端口
基于域名的,不同域名
3、 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求 时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
13,什么是Redis?
redis是一个开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。
Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
rides是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存。
14,hashset和hashmap有什么区别?
1,hashset实现了set接口,hashmap实现了map接口。
2,hashset存储的是对象,hashmap存储的是键值对。
3,hashset添加用的是add()方法,hashmap添加用的是put()方法。
4,hashset使用对象计算hashcode,如果hashcode相等,则比较equals是否相等,如果相等则返回ture,hashmap通过key计算hashcode。
15,什么是集群?什么是分布式?
集群:
单机结构:
我们最熟悉的当然是单机结构,当一个系统的业务量很少时,把它全部放到一个项目中,并且部署到一个服务器上,然后所有的服务都由这一个服务器提供,这就是单机结构。
但是,当我们系统的业务量很多时,一个服务器提供的服务满足不了我们的需求,这时候就需要用到集群了。
集群结构:
由多个提供相同服务的服务器,形成的一个整体就叫做 “集群”,在集群中每一个单独的服务器都是这个集群的节点,所有的节点构成这个集群,那么这样系统的处理能力就相当于提升了好几倍。
集群的特点:系统扩展非常容易,当我们当前的集群不满足我们的需求时,我们只需要添加集群的节点就行了。
集群存在的问题:
当你的业务发展到一定程度的时候,你会发现一个问题—无论怎么增加节点,貌似整个集群性能的提升效果并不明显了。这时候,你就需要使用微服务结构了。
分布式:
将一个完整的系统,根据业务功能,把它划分成一个个独立的子系统。
在分布式中,每一个子系统都是一个独立的服务,都能独立运行在web服务器上,他们之间通过RPC相互通信。
举一个例子:
我们要开发一个电商项目,我们可以把它按功能分为:用户模块,商品分类,商品详情,购物车,订单,后台管理等模块,每一个单独的模块都是一个服务,都可以独立运行,它们相互之间通过RP通信。
分布式的优点:
1,系统之间的耦合度大大降低,可以独立开发、独立部署、独立测试,系统与系统之间的边界非常明确,排错也变得相当容易,开发效率大大提升。
2,系统之间的耦合度降低,更加注重重点,从而系统更易于扩展。我们可以针对性地扩展某些服务。假设这个商城要搞一次大促,下单量可能会大大提升,因此我们可以针对性地提升订单模块节点数量,而对于后台管理而言,节点数量维持原有水平即可。
3,服务的复用性更高。比如,当我们将用户模块作为单独的服务后,该公司所有的产品都可以使用该模块作为用户模块,无需重复开发。
集群与分布式的区别:
集群是多个单独的服务形成一个整体,做同一件事情。
分布式是一个系统分解成多个子系统,并且能单独部署,独立运行,相互之间通过RPC通信。
16,什么是springcloud?
17,springboot和springcloud有什么关系?
18,什么是反向代理和负载均衡?
19,springMVC是什么?有什么特点?
是一个基于java实现MVC设计模式的一个轻量级web层框架,通过把mode,view,controller分离,把复杂的业务逻辑分成几部分,特点就是,降低耦合度,划分更明确,利于维护。
三,数据库
1,索引是什么?
索引是对数据库表的一列或者多列的值进行排序一种结构,
2,有什么目的?
1,快速访问数据表中的特定信息,提高检索速度。
2,创建唯一性索引,保证数据库表中每一行数据的唯一性。
3,加速表和表之间的连接。
4,使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
3, 什么情况下不宜建立索引?
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等
4,什么情况下设置了索引但无法使用
以“%”开头的LIKE语句,模糊匹配
OR语句前后没有同时使用索引
数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型)
5,索引的底层实现原理和优化
B+树,经过优化的B+树,主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此InnoDB建议为大部分表使用默认自增的主键作为主索引。
6,索引的类型?
主键索引:唯一索引,不能重复,不能为空
唯一索引:数据库索引列的值不能重复,但是能为空
普通索引:普通的索引,没有限制
全文索引:全文索引只能创建在CHAR、VARCHAR、TEXT类型的字段上,访问量多时可以提高速度,支持模糊查询
四,多线程
1,sleep() 和 wait() 有什么区别?
sleep:线程睡眠,他是线程类的一个静态方法,睡眠时间过后会跳到就绪状态,接着跟其他线程争夺CPU使用权,一个synchronized块中调用了sleep() 方法,线程虽然进入休眠,但是不会释放锁。
wait:线程等待,object类的方法,线程等待期间会释放锁,可以通过notify和notifyAll来唤醒。
未完结(未整理,后期待整理)!