Java面经学习汇总:
前言
从今天起开始为实习做准备,历时一个月,不断积累面经知识,加油!
一、Java基础
这一模块主要是java基础知识。
1.Java访问权限的了解
Java语言提供了三种访问修饰符,private、public和protected,在使用这些修饰符修饰目标时,可以形成四种访问权限:private、default、protected和public。
注意:在不加任何修饰符时为default访问权限。
- private:可以被该类内部类成员访问。
- default:可以被该类内部成员访问,也可以被同一包下的类访问,还可以被它的子类访问。
- protected:可以被该类内部成员访问,也可以被同一包下的类访问,还可以被它的子类访问。
- public:该类可以被任意包下,任意类的成员进行访问。
2.Java的数据类型
Java数据类型包括基本数据类型和引用数据类型两大类:
基本数据类型有8个,可以分为4类:整数类型(int、short、byte、long)、浮点类型(float、double)、字符类型(char)、布尔类型(boolean)。其中,4个整数类型中,int类型最为常用。2个浮点类型中,double类型最为常用。此外,在这8个类型中,除了boolean类型外,它们之间都可以进行类型转换。
引用类型就是对一个对象的引用,根据引用对象的不同,可以分为3类:数组、类、接口类型。
- byte:1字节(8位)
- short:2字节(16位)
- int:4字节(32位)
- long:8字节(64位)
- float:4字节(32位)
- double:8字节(64位)
- char:2字节(16位)
3.自动装箱和自动拆箱
自动装箱:可以把一个基本数据直接赋值给对应的包装类型;
自动拆箱:可以把一个包装类型的对象直接赋值给对应的基本类型;
通过自动装箱,自动拆箱功能,可以简化基本类型对象和包装类型对象之间的转化过程。比如,某个方法的参数类型为包装类型,调用时我们所持有的数据却是基本类型数据,则可以不用做特殊处理,直接将这个基本类型的值传入参数即可。
4.如何对Integer和Double类型判断相等?
不能直接用==进行比较,因为他们是不同的数据类型;
将Integer、Double先转为相同的基本数据类型,然后再用==进行比较
Integer i = 100;
Double d = 100.00;
System.out.println(i.doubleValue() == d.doubleValue());
5.Integer和int有什么区别,二者在做==时会得到什么结果?
int是基本数据类型,Integer是int的包装类型;二者在做==运算时,Integer会自动拆箱为对应的int数据类型,然后再做==比较,如果二者值相同,则返回TRUE,不同则返回FALSE。
6.面向对象的大三特征是什么?
面向对象的程序设计方法具有三个基本特征:封装、继承和多态。
- 封装:将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能;
- 继承:是面向对象实现软件复用的重要手段,当子类继承父类后,将直接获得父类的属性和方法;
- 多态:子类对象可以直接赋值给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时,可能表现出多种行为特征。
7.封装的目的是什么?为什么要有封装?
封装是面向对象编程语言对客观时间的模拟,在客观世界里,对象的状态信息都被隐藏在对象内部,外界无法直接操作和修改。对一个类或对象实现良好的封装,可以实现以下目的:
- 隐藏类的实现细节;
- 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入逻辑控制,限制对成员变量的不合理访问;
- 可进行数据检查,从而有利于保证对象信息的完整性;
- 便于修改,提高代码的可维护性。
封装:把该隐藏的隐藏起来,把该暴露的暴露出来。
8. 说一说对多态的理解。
相同类型的变量,调用同一个方法时呈现出多种不同的行为特征。多态可以提高程序的可扩展性,在程序设计上让代码更加简洁。
9. continue、break和return的区别是什么?
都存在于循环结构中,当某种条件满足时,会提前终止循环。
continue:指的是跳出当前循环,直接进行下一次循环
break:用于终止整个循环
return:结束该方法的运行,返回没有函数值或者有函数值的方法
10. 对象的相等和引用相等的区别
- 对象的相等一般比较的是内存中存放的内容是否相等
- 引用相等一般比较的是指向的内存地址是否相等
11. 深拷贝和浅拷贝区别是什么?什么是引用拷贝?
-
浅拷贝:浅拷贝会创建一个新的对象,不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是拷贝对象和原对象共用同一个内部对象。
-
深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。
-
引用拷贝:只是复制了对象的地址,并不会创建对象
12. ==和equals()的区别
==:
对于基本数据类型来说,==比较的是值
对于引用数据类型来说,==比较的是对象的内存地址
equals:
类没有重写方法:等价于==的比较方法
类重写方法:比较两个对象的值是否相等;若相等,返回true,否则返回false
13. hashCode()有什么用?
hashCode()的作用是获取哈希码。这个哈希吗的作用是确定该对象在哈希表中的索引位置。
hashCode()定义在JDK的Object类中,这就意味着java中的任何类都包含有hashCode()函数
14. 为什么重写equals()时必须重写hashCode()方法?
因为两个相等的对象的hashCode值必须是相等的。如果重写equals()方法时没有重写hashCode()方法就可能会导致equals方法判断是相等的两个对象,而hashCode值却不相等。
equals方法判断两个对象是相等的,那这两个对象的hashCode值也要相等
15. String#equals()和Object#equals()有何区别?
- String中的equals方法是被重写过的,比较的是String字符串的值是否相等;
- Object中的equlas()方法比较的是对象的内存地址。
16. String s1 = new String("abc"); 这句话创建了几个字符串对象?
(1)如果字符串常量池中不存在字符串“abc”的引用,那么会在堆中创建2个字符串对象“abc”;
(2)如果字符串常量池中已经存在字符串对象“abc”的引用,则只会在堆中创建1个字符串对象“abc”
17. intern方法有什么作用?
String.intern()是一个native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:
- 如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用。
- 如果字符串常量池中没有保存了对应的字符串对象的引用,那就在常量池中创建一个指向该字符串对象的引用并返回。
18. Exception和Error有什么区别?
Exception程序本身可以处理的异常,可以通过catch来捕获。
Erro属于程序无法处理的错误。
19. 什么是泛型?有什么作用?
增强代码的可读性以及稳定性。编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。
比如:ArrayList<Persion> persions = new ArrayList<>();
表明该ArrayList对象只能传入Persion对象,如果传入其他类型对象就会报错。
20. 什么是反射?
通过反射可以获取任意一个类的所有属性和方法,还可以调用这些方法和属性。让我们的代码更加灵活。
21. 什么是SPI?
给服务提供者或者扩展框架功能的开发者去使用的一个接口。SPI将服务接口和具体的服务实现分离开来,将服务调用放和服务实现者解耦,提升程序的扩展性和可维护性。
22. 什么是序列化和反序列化?
如果需要将java对象保存在文件中,或者在网络传输java对象等,都需要用到序列化。
- 序列化:将数据结构或对象转换成二进制字节流的过程
- 反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
序列化的目的是通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。
23. Java IO流
IO即Input/Output,输入和输出。数据输入到计算机内存的过程称为输入,反之输出到外部存储(数据库、文件、远程主机)的过程为输出。
- InputStream/Reader:前者是字节输入流,后者是字符输入流。
- OutputStream/Writer:前者是字节输出流,后者是字符输出流。
二丶Java集合
1. 讲讲java集合
- 数组长度是固定的,而集合的长度是可变的,如果往集合里面添加一个元素,集合的长度会自动加一,自动扩容。
- 集合存的是引用数据类型,基本数据类型需要变成其对应的包装类,才可以存储。
1.1 Java集合可分为Collection和Map两种:
- Colleciton:单列数据,定义了存取一组对象的方法集合
常用方法:
(1)添加:add(Object obj)
(2)获取有效元素的个数:int size()
(3)清空集合:void clear()
(4)Iterator迭代器接口:主要用来遍历Collection集合中的元素
1.1.1 List:元素有序、可重复的集合(保证按照插入顺序排序)
ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复
优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。
缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。
LinkedList:底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。LinkedList 适用于要头尾操作或插入指定位置的场景。
缺点:因为LinkedList要移动指针,所以查询操作性能比较低。
当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList。
Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
1.1.2 Set:元素无序、不可重复的集合(存储和取出顺序不一致)
- Map:双列数据,以key-value进行保存,每一个key都有与之对应的value值。
三、Mysql数据库
1.什么是事务?
事务就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部成功,要么全部失败,是一个不可分割的工作单元。
2. 事务的四大特性
- 原子性:是作为一个整体被执行,要么全部成功,要么全部失败。
- 一致性:是指事务开始之前和结束之后,数据都不会被破坏,假设A给B账户转了10块钱,无论成功与否,A与B账户的总金额是不变的。
- 隔离性:多个事务并发访问时,事务之间是相互隔离的,一个事务不会影响另一个事务的运行。
- 持久性:表示事务操作完成后,事务对数据库的更改将持久的保存在数据库之中。
3. 事务的隔离级别有哪些?
[读未提交]:最低级别
[读已提交]:可避免脏读的发生
[可重复读]:可避免脏读、不可重复读的发生
[串行化]:可避免脏读、不可重复读、幻读的发生
Mysql默认的事务隔离级别是:[可重复度]。
4. 什么是脏读、不可重复读、幻读呢?
- 脏读:读到了并不一定最终存在的数据。
- 不可重复读:在一个事务内,最开始读到的数据和事务结束前的任意时刻的同一批数据出现不一致的情况。
- 幻读: 在select时记录不存在,但是在insert时发现此条记录又存在,无法插入。
5. 乐观锁悲观锁
- 悲观锁:在操作数据之前会对数据进行上锁,然后才能读写数据,最后对数据进行解锁。在解锁之前任何人都不能对数据进行操作,只有当数据解锁完之后,下一个人才能对数据加锁、读写、解锁。
特点:可以保证数据的独占性和正确性。因为每次请求都要对数据进行加锁解锁机制,所以会消耗性能。
- 乐观锁:在提交数据时通过加入版本号检验数据版本是否一致的方法来验证数据是否冲突。乐观锁是并发类型的锁,它省去了加锁和解锁机制,所以会提交操作的性能。但是当高并发状态下,大量的无用验证操作会浪费资源,所以在高并发状态下,乐观锁的性能不如悲观锁。
6. 什么是索引?
索引就相当于一本书里的目录,通过目录可以很快查到到需要的内容。
索引是数据库中用于排序的数据结构,用来快速查询数据库中的数据。Mysql数据库使用B+树来实现索引。B+树的特点就是叶子结点包含了所有的关键信息和data数据,非叶子节点只包含子节点的最大或者最小关键字,用来实现索引。
- 优点:大大加快了数据的查询速度
- 缺点:占用物理空间,对数据库增删改的时候也要动态的维护索引
B+树和B树的区别:
B树又叫做平衡多路查找树,这种数据结构一般用来查找速度比较快,B+树是B树的一种加强数。
- B树的每个节点都存储key和data
- B树由于key和data存在同一个节点,无法进行区间查询
- B树的查询最好时间复杂度为O(1)
- B+树的查询时间复杂度固定为logN
- B+树只在叶子节点中存储数据
- B+树可以进行区间查询,并且由于非叶子节点没有存储data,所以每一页加载到内存的信息量更大
结论: 数据库中索引数据结构用的是B+树,第一点是因为其非叶子节点不存储数据;第二点是可以进行区间查询;第三点查询时间复杂度固定。
今天就写到这里~ 2022.11.14~~~~~~