java面试题

本文详细总结了Java面试中常见的知识点,包括HashMap与Hashtable的区别、String与StringBuilder的对比、抽象类与接口的区别、异常处理、多线程、反射机制、集合类特性、数据库操作、JVM内存管理、类加载、线程池核心参数、数据库索引等,是Java开发者面试复习的重要参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1:hashmap,hashtable的区别

1.继承不同,HashMap继承自AbstractMap,Hashtable继承自Dictionary

2.HashMap是线程不安全的,Hashtable是线程安全的

3.HashMap键key和值value都可以为null,但是key只能有一个为null,value可以有多个为null,Hashtable键key和值value都不能为null

4.哈希值的使用不同,Hashtable直接使用对象的hashcode值,而HashMap重新计算hash值

5.Hashtable、HashMap都使用了 Iterator进行遍历。而由于历史原因,Hashtable还使用了Enumeration的方式

6.HashMap的初始数组长度是16,扩容方式是2n,Hashtable的初始长度是11,扩容方式是2n+1

2:String,StringBuffer,Stringbuilder的区别

1.String是不可变的,对String的任何改变都会返回一个新的对象

2.StringBuffer是可变的,对StringBuffer中内容的修改都是当前这个对象

3.String创建的字符串是在字符串常量池中的,创建的字符串初始换一次,对字符串的任何改变都会产生一个新的字符串地址

4.StringBuffer是在堆中创建对象,对字符串改变不会产生新的字符串地址

5.StringBuffer是线程安全的,StringBuilder是线程不安全的,不考虑并发问题的情况下使用StringBudiler

3:抽象类和接口的区别

1.抽象类继承自Object类,而接口不是

2.抽象类有构造器,而接口没有

3.抽象类中可以有普通成员变量和常量,而接口中只能有常量,而且修饰符只能是public static final,不写默认

4.抽象类中可以有抽象方法,也可以有普通方法,接口中只能有抽象方法,而且修饰符只能是public abstract,不写默认,jdk1.8以后有static和default方法,jdk1.9以后可以有private方法

5.抽象类中可以有final方法(非抽象),接口中不能有final方法

6.抽象类只能是单继承多实现,接口可以多继承其他接口,但不能实现其他接口,也不能继承其他类

4:final,finally,finalize关键字的用法

1.final修饰类,方法,属性,修饰类不能被继承,修饰方法不能被重写,修饰属性值不能被修改

2.finally是异常处理结构的一部分,表示总是执行

3.finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集的其他资源回收,但JVM不保证此方法总被调用

5:什么是封装、继承、多态

1.封装是把数据和过程包围起来,对数据的访问只能通过已定义的界面

2.继承是子类拥有父类一切非私有的属性方法

3.多态是同一种事物的不同种表现形式

6:jvm为什么能跨平台

java程序编译后生成.class字节码文件,不是能被硬件系统直接执行的代码,不同的硬件平台上安装有不同的java虚拟机JVM,由JVM来把字节码文件翻译成对应平台所能够执行的代码

7:作用域public,private,protected,以及不写时的区别?

1.public所有类都可以进行访问

2.protected只有当前类,同包类,子类可以进行访问

3.default(不写)只有当前类和同包类可以进行访问

4.private只有当前类可以进行访问

8:ArrayList和LinkedList的区别

1.ArrayList底层是数组,查找快,增删慢

2.LinkList底层是双向链表,查找慢,增删快

9:==和equals的区别

1.==比较的是两个变量值和地址是否都相等,如果要比较两个基本数据类型用==

2.equals如果没有重写,和==意义一样,如果重写了按照重写的规则进行比较

3.重写了equals必须重写hashcode方法,否则可能出现同一个对象存储了两次

10:HashMap的底层数据结构,加载因子,初始容量,put过程

1.HashMap底层数据结构是数组+链表+红黑树(jdk1.8以后)

2.加载因子是0.75

3.初始容量是16

4.put过程

(1)首先确认数据存储在HashMap中数组的位置

计算key的hash值,然后用key的hash值与数组长度-1按位与得到在数组中的存储位置

(2)判断该位置是否有元素,没有就创建一个Node对象存入

(3)如果数组中只有一个头结点元素,判断key是否想等,相等就覆盖,不相等就放入量表最后位置

(4)如果链表长度超过8且数组长度超过64就自动转变为红黑树

11:java异常处理体系

1.java异常包括Exception(异常)和error(错误),都继承自Throwable

2.error一般是java虚拟机出现的问题,程序无法处理

3.Exception包括运行时异常和非运行时异常

4.非运行时异常必须进行处理,可以用try-catch或者用throws声明抛出

5.运行时异常一般为不可检查异常,一般是由程序逻辑错误引起的,可以处理也可以不处理,程序应该从逻辑角度尽可能避免这类错误的发生

12:获取Class对象的几种方法

1.类的class属性,类名.class

2.对象的getClass()方法,对象.getClass()

3.Class.forName(类的全路径)

4.类加载器ClassLoader

13:常见的异常,如何产生

1.java.lang.NullPointerException 空指针异常

调用了未初始化的对象或不存在的对象

2.java.lang.ClassNotFoundException 类找不到异常

类的名称和路径错误

3.java.lang.ArithmeticException 数学运算异常

算数运算除零

4.java.lang.ArrayIndexOutOfBoundsException 数组下标越界

调用的数组的下标超过了数组下标范围

5.java.lang.ClassCastException 类型转换异常

将某个对象向下强转,但是该对象不能转换为该子类的实例

6.java.lang.NumberFormatException 数字转换异常

将字符串转换为数字类型,但是该字符串不满足数字类型格式要求

7.java.sql.SQLException 操作数据库异常

SQL语句书写错误

8.java.io.IOException 输入输出流异常

读写数据的时候产生

9.java.io.FileNotFoundException 文件找不到异常

文件路径书写错误

10.java.lang.InstantiationError 实例化异常

当试图通过Class的newInstance()方法创建某个类的实例,但程序无法通过该构造器来创建该对象时引发

11.java.lang.IllegalArgumentException 非法参数异常

比如SimpleDateFormat来日期格式化format里面传一个对象参数,new Date()没问题,但是你传入字符串一串数字会出现异常

14:字节流和字符流的区别

1.字节流是以字节来进行读写,可以读写任意格式的文件,如视频、音频、exe等

2.字符流的底层是字节流,是以字符来进行读写,处理的最基本单元数Unicode码,只能读写文本文件

15:创建多线程几种方式,线程池有哪几个核心参数

1.继承Thread类

2.实现Runable接口

3.实现Callable接口

4.线程池,核心参数有:(1)核心线程数(2)最大线程数(3)多余线程存活时间(4)时间单位(5)任务队列(6)线程工厂(7)拒绝执行处理器

16:什么是反射?反射的作用

反射可以获取已加载类的字段,方法,构造函数等信息

1.动态创建一个类的对象

2.动态调用对象的方法

3.判断任意一个对象所属的类

4.判断任意一个类所具有的的成员变量和方法

17:说说list,set,map 及常用实现类的特性

1.List和Set继承自Collection接口,Map不是

2.List和Set是单列集合,Map是双列集合

3.List底层是数组的方式实现,Set是散列表的方式实现,Map是键值对的方式实现

4.List是有序可重复的,Set是无序不可重复的,Map是有序的,key不重复,value可重复

5.List和Set可以通过迭代器进行遍历,Map只能通过键或者键值进行遍历

18:Object类的常用方法及作用

1.getClass():获取类的class对象

2.clone():克隆方法

3.hashCode():计算对象的hashCode值

4.equals():如果没有重写,比较的是对象的地址和值

5.toString():如果没有重写,打印的是对象的地址值

6.notify():随机唤醒一个处于阻塞状态的线程

7.notifyAll():唤醒所有处于阻塞状态的线程

8.wait():使线程进入阻塞状态

9.finalize():对象回收时调用

19:什么是数据库三范式

第一范式:字段具有原子性,不可再分

第二范式:非主属性完全依赖于主属性

第三范式:不存在传递依赖

20:什么是死锁?如何避免死锁

死锁是两个或两个以上的线程(事物)都需要某些资源才能执行完毕,线程(事物)都在等待对方释放自己需要的资源,自己又不释放对方需要的,就会造成死锁。

1.如果多个线程需要对多个 Lock 进行锁定,则应该保证它们以相同的顺序请求加锁。

2.一个线程先获取所有资源在运行。

3.尽量避免同一个线程对多个 Lock 进行锁定。

4.使用定时锁,超过一定时间就释放该资源

21:什么是主键,什么是外键?二者的区别是什么?

1.主键是唯一标识一条记录,不能有重复的,而外键是另一张表的主键,可以重复,不能创建对应表中不存在的外键。

2.主键不允许为空,而外键可以。

3.主键是用来保证数据完整性,而外键是用来和其他表建立联系的。

4.主键只有一个,外键可以有多个。

22:内连接和外连接的区别是什么?

1.内连接查询操作列出与连接条件匹配的数据行;

2.外连接,返回的查询结果集合中不仅包含符合连接条件的行,而且还包括主表的不符合连接条件的所有数据行,左表(左外连接)、右表(右外连接)或两个边接表(全外连接)中的所有数据行。

23:什么是事务?事务的4个特性?事务的隔离级别?脏读,不可重复读,幻读是什么?mysql默认隔离级别是什么?

1.事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,然后操作就会回滚到操作前状态,或者是上一个节点。为了确保要么执行,要么不执行,就可以使用事务。

2.原子性、一致性、隔离性、持久性

3.读未提交(read uncommit)、读已提交(read commit)、可重复读(repeatable read)、串行化(serializable)

1)脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2)不可重复读:事务 A 多次读取同一个数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

3)幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就

在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像

发生了幻觉一样,这就叫幻读。

5.默认隔离级别是可重复读

24:char为什么能存储一个汉字?

char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了全世界所有的字体。

25:静态变量和实例变量的区别?

静态变量也称为类变量,归全类共有,它不依赖于某个对象,可通过类名直接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。

26:switch 可以支持什么类型的变量?

switch里面的条件必须是能隐式的转化成为int,可以支持 byte、short、char、int或者其对应的封装类以及Enum类型,jdk1.7之后String类型的也可以。

27:java 有哪8大基本类型?分别占用几个字节?

整形:byte 1个 short 2个 int 4个 long 8个

浮点类型:float 4个、double 8个

字符类型:char 表示字符 utf-16 2个

布尔类型:boolean true/false 1个

28:什么是GC?GC流程? 新生代,老年代?

1.GC是垃圾收集的意思,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

1)初始状态,假设整个堆内存大小为20M,其中老年代10M,新生代10M,新生代中Eden区6M,两个Survivor区各2M。大多数情况下,新创建的对象首先都会尝试在Eden区分配(初始年龄为0),随着程序运行,对象不断被创建,Eden区空间快要被占满了。此时,一个新的对象(1M)申请分配内存,Eden区没有足够的空间来给这个对象分配内存

2)这时候会触发一次Minor GC,把Eden区中还存活的对象转移到From区(年龄+1为1),其他对象则视为垃圾被清理掉。然后在Eden区中给新创建的那个对象分配空间。

3)程序继续运行,更多的对象不断地创建,很快,Eden区的空间又不足了

4)这时会再次触发Minor GC,把Eden区和From区中存活的对象转移到To区(年龄+1为2),清理掉剩下的垃圾对象,然后在Eden区给新对象分配内存

5)From区和To区不是固定不变的,是不断交替的。触发GC时,哪个区中有存活对象,哪个区就是From区,另外一个没有对象的区就是To区。拿上面的例子来说,再进行一次Minor GC,会把存活的对象转移到S1区。转移前,S2是From区,S1是To区。转移后,S1区中有存活对象,变为From区,S2则变为To区。

首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年龄以及达到了老年的标准,一般是 15,则赋值到老年代区)

同时把这些对象的年龄 + 1(如果 ServicorTo 不够位置了就放到老年区)

然后,清空 Eden 和 ServicorFrom 中的对象;最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom 区。

2.新生代主要是用来存放新生的对象。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发 MinorGC 进行垃圾回收。

3.老年代的对象比较稳定,所以 MajorGC 不会频繁执行。

4.永久代指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息。

29:java创建对象有几种方式?

1.new

2.反射

3.反序列化

4.克隆

30:一个静态方法,里面可不可以用this和super关键字

不可以,

静态方法是存储在静态区内的,静态区会随着类加载器一起加载到内存当中,这时候,只是加载到内存当中,但是并没有真正的去运行,此时也就没有产生实例化的对象,this是表示当前对象的。super表示父类的对象,这时候,连实例化的对象都没有产生,所以this和super也就不存在。

31:JDBC常用接口有哪些?

1.Driver接口是所有JDBC驱动程序必须要实现的接口,该接口提供给数据库厂商使用。

2.Connection接口表示Java程序和数据库的连接,Java程序和数据库的交互是通过Connection接口来完成的。

3.Statement接口用于向数据库发送SQL语句,Statement接口提供了三个执行SQL语句的方法。

4.继承自Statement接口,用于执行预编译的SQL语句,PreparedStatement接口提供了一些对数据库进行基本操作的方法。

5.CallableStatement接口,继承自PreparedStatement接口,由方法prepareCall()创建,用于调用SQL存储过程。

6.ResultSet接口表示执行select查询语句获得的结果集,该结果集采用逻辑表格的形式封装。

7.ResultSetMetaData接口用于获取关于ResultSet 对象中列的类型和属性信息的对象。

32:什么是索引,索引是不是越多越好

索引(Index)是帮助MySQL高效获取数据的数据结构。

数据量小的表不需要建立索引,建立会增加额外的索引开销;

数据变更需要维护索引,因此更多的索引意味着更多的维护成本;

更多的索引意味着也需要更多的空间(索引也是需要空间来存放的);

33:mysql有哪些常见索引

逻辑上:
Single column 单行索引
Concatenated 多行索引
Unique 唯一索引
NonUnique 非唯一索引
Function-based函数索引
Domain 域索引
物理上:
Partitioned 分区索引
NonPartitioned 非分区索引
B-tree:
Normal 正常型B树
Rever Key 反转型B树
Bitmap 位图索引

mysql索引类型normal,unique,full text

normal:表示普通索引,适合性别,姓名,状态等内容长度较短的字段上

unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique

full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以

34:mysql 有哪些常见引擎?

1.InnoDB 是 MySQL 5.1 之后默认的存储引擎,它支持事务、支持外键、支持崩溃修复和自增列。

2.MyISAM 是 MySQL 5.1 之前默认的数据库引擎,读取效率较高,占用数据空间较少,但不支持事务、不支持行级锁、不支持外键等特性。

3.MEMORY内存型数据库引擎,所有的数据都存储在内存中,因此它的读写效率很高,但 MySQL 服务重启之后数据会丢失。它同样不支持事务、不支持外键。

35:数据库锁有哪些?

1.表级锁(表级锁一次会将整个表锁定,所可以很好的避免死锁问题)

(1)锁定粒度大,锁冲突概率高、并发度低;

(2)好处是不会出现死锁、开销小、获取锁和释放锁的速度很快;

(3)使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎,适用于以查询为主,少量更新的应用。

2.行级锁

(1)好处是锁定对象的颗粒度很小,发生锁冲突的概率低、并发度高;

(2)缺点是开销大、加锁慢,行级锁容易发生死锁;

(3)使用行级锁定的主要是InnoDB存储引擎、及分布式存储引擎NDBCluster等。适用于对事务完整性要求较高的系统。InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁。

3.InnoDB行级锁类型

(1)共享锁:又称读锁,简单讲就是多个事务对同一数据进行共享一把锁,都能访问到数据,但是只能读不能修改。

(2)排他锁:又称写锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,只有获取排他锁的事务可以对数据进行读取和修改。

(3)意向锁是InnoDB自动加的,不需用户干预。意向锁不会与行级的共享 / 排他锁互斥!!!

36:Statement和PreparedStatement的区别?

1、PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高

2、使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。

3、statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译的, preparedstatement支持批处理 。

4、执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。

5、 PreparedStatement 可以规避 Statement弊端:①拼串 ②sql注入问题

6、PreparedStatement 可以实现操作Blob类型、Clob类型的数据

37:深拷贝和浅拷贝的区别?

浅拷贝 :只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块

深拷贝:是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象

38:单例模式和工厂模式的区别?

单例:这个类在整个生命周期中只有存在一个对象

单例类的构造方法一定是private的,然后提供一个public static 的 获取该类对象的一个方法。

单例: 1. 饿汉式单例 2. 懒汉式单例3. 内部类实现单例

工厂模式:

在细看到这个模式时候,有些疑惑单例模式与工厂模式的区别,虽然看起来像最大区别在于是否多次实例化。

单例模式它限制了类的实例化次数只能一次。 在实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,它会简单返回该对象的引用。

39:拆箱和装箱是什么?

装箱就是自动将基本数据类型转换为包装器类型;

拆箱就是自动将包装器类型转换为基本数据类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值