Java面试题

1.重载和重写的区别?

重载   发生在一个类中,同名的方法如果有不同的参数列表(类型不同、个数 不同、顺序不同)则
         视为 重载
重写  发生在子类与父类之间,重写要求子类重写之后的方法与父类被重写方法有相同的返回类
         型,比父类被重写方法更好访问,不能比父类被重写方法 声明更多的异常。

2.String 和 StringBuffffer、 StringBuilder 的区别是什么?

①可变性
String 类中使用 final 关键字修饰字符数组来保存字符串,所以 String 对象是不可变的。而
StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder
中也 是 使用字符数组保存字符串char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可
变的。
②线程安全性
String 中的对象是不可变的,也就可以理解为常量,线程安全。StringBuffer 对方法加了同步锁
者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,
所以 是非线程 安全的。
③性能
每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String
对象。StringBuffer 每次都会对StringBuffer 对象本身进行操作,而不是生成新的对象并改变对
象引 用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能
提升, 但却要冒多线程不安全的风险

3.== 与 equals 的区别?

对于基本类型和引用类型 == 的作用效果是不同的,基本类型:比较的是值是否相同; 引用类型:
比较的是引用是否相同;
equals 本质上就是 ==,只不过 String Integer 等重写了equals 方法,把它变成了值比较

4.说说自己是怎么使用 、synchronized 关键字,在项目 中用到了吗?

①修饰实例方法,作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁
②修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
③修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
④双重校验锁实现对象单例(线程安全)

5.抽象类和接口的区别是什么?

①实现:抽象类的子类使用 extends 来继承;接口必须使用 implements来实现接口。
②构造函数:抽象类可以有构造函数;接口不能有。
③实现数量:类可以实现很多个接口;但只能继承一个抽象类【java只支持单继承】。
④访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的抽象方法可以使用Public
Protected修饰,如果抽象方法修饰符为Private,则报错:The abstract method 方法名 in type
Test can only set a visibility modifier, one of public or protected。接口中除了staticfinal
量,不 能有其他变量,而抽象类中则不一定
⑤设计层面:抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范。

6.Collection 和 Collections 有什么区别?

Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口 方法,所有集合都是 
它的子类,比如 ListSet 等。
Collections 是一个包装类,包含了很多静态方法,不能被实例化,就像一个 工具类,比如提供 
的排序方法: Collections. sort(list)

7.List、Set、Map 之间的区别是什么?

 
  List:元素有序且允许元素重复
  Set:主要分为两部分,①AbstractSet,HashSet 元素无序且不允许元素重复;
                                     ②TreeSet 元素有序(用二叉树排序)  不允许元素重复。
  
  Map:主要分为两部分,①AbstractMap,HashMap元素无序,Key值必须唯一,value可重复。
                                       ②TreeMap 元素有序(用二叉树排序),Key值必须唯一,value可重复。

8. HashMap 和 Hashtable 有什么区别?

①存储:HashMap 运行 key value null,而 Hashtable 不允许。
②线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。
③推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使 用 , 推 荐 在 单
线程环境下使 用 HashMap 替 代 ,如果需要多线程使用则用ConcurrentHashMap替代。

9. 说一下 HashMap 的实现原理?

HashMap基于Hash算法实现的,我们通过 put(key,value)存储,get(key)来获取。 当传入key
时,HashMap会根据key. hashCode() 计算出hash值,根据hash值将value保存在bucket里。
当计算出的 hash值相同时,我们称之为 hash 冲突,HashMap的做法是用链表和红黑树存储相
同hash值的value。当 hash冲突的个数比较少时,使用链表 ;hash冲突个数大于8且数组长度大
于等于 64 时使用红黑树。

10. 说一下 HashSet 的实现原理?

 HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此
HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相 关方
法来完 成,HashSet 不允许重复的值。

11.ArrayList和LinkedList的区别

ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问),扩容机制:因为数组长度固
定,超出长度存数据时需要新建数组,然后将老数组的数据拷贝到新数组,如果不是尾部插入数据
还会涉及到元素的移动(往后复制一份,插入新元素),使用尾插法并指定初始容量可以极大提升性
能、甚至 超过linkedList (需要创建大量的node对象)
LinkedList:基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询:需要
一遍历,遍历LinkedList必须使用iterator,不能使用for循环,因为每次for循环体内通过get(i)
取得 某一元素时都需要对list重新进行遍历,性能消耗极大。

12.ConcurrentHashMap原理,jdk7和jdk8版本的区别

https://blog.csdn.net/qq_38525526/article/details/99624132
jdk7:
①数据结构:ReentrantLock+Segment+HashEntry,一个Segment中包含了一个HashEntry
组,每个HashEntry又是一个链表结构。
②元素查询:二次hash,第一次hash定位到Segment,第二次hash定位元素所在链表的头部
③锁:Segment分段锁,Segment继承了ReentrantLock,锁定操作的Segment,其他Segment
不受影 响,并发度为Segment的个数,可以通过构造函数指定,数组扩容不影响其他Segment
get方法无 须加锁,volatile保证
jdk8:
①数据结构:synchronized+CAS+Node+红黑树,Nodevalnext都用volatile修饰,保证可
见性 查找,替换,赋值操作都使用CAS
②锁:锁链表的head节点,不影响其他元素的读写,锁粒度更细,效率更高,扩容时,阻塞所有
读写操作,并发扩容
③读操作无锁:Nodevalnext使用volatile修饰,读写线程对该变量互相可见数组使用volatile
饰,保证扩容时被读线程感知。

13.哪些集合类是线程安全的?

VectorHashtableStack 都是线程安全的,而像 HashMap 则是非线程安全 的,不过在
JDK1.5 之后随着 Java.util.concurrent 并发包的出现,它们也有 了 自 己 对 应 的 线 程 安 全 类
, 比 如 HashMap 对 应 的 线 程 安 全 类 就 是 ConcurrentHashMap.

14.创建线程有哪几种方式?

    创建线程有三种方式:
①继承 Thread 重写 run 方法;②实现 Runnable 接口; ③实现 Callable 接口。

15.说一下 runnable 和 callable 有什么区别?

runnable 没有返回值,callable 可以拿到有返回值,callable 可以 看作是 runnable 的补充。

16.线程有哪些状态?

当线程对象被创建后,即进入了新建状态(NEW),;当调用线程对象的start()方法
t.start();), 线程即进入就绪状态(Runnable);CPU获取到时间片,进入到运行状态
Running;当线程调 用 wait()或者sleep()时,进入阻塞状态(Blocked),当休眠时间结束后,
或者调用notify或notifyAll时 会重新进入就绪状态(Runnable),再重新获取时间片,进入运行状
态,线程执行完了或者因异常 退出了run()方法,该线程结束生命周期,进入终结状态(Dead)

17.sleep() 和wait() 有什么区别?

类的不同:sleep() 来自 Threadwait() 来自 Object
释放锁:sleep() 不释放锁;wait() 释放锁。
用 法 不 同 : sleep() 时 间 到 会 自 动 恢 复 ; wait() 可 以 使 用 notify()/notifyAll()直接唤醒。

18.notify()和 notifyAll()有什么区别?

notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后, 会将全部线程由
等待 池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则 留在锁池等待锁被释
放后 再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个 线程由虚拟机控制。

19.线程的 run() 和 start() 有什么区别?

start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。
run() 可以重复 调用,而 start() 只能调用一次。

20.说一说几种常见的线程池及适用场景?

①FixedThreadPool:可重用固定线程数的线程池。(适用于负载比较重的服务器)
②SingleThreadExecutor:只会创建一个线程执行任务。(适用于需要保证顺序执行各个任务;
在 任意时间点,没有多线程活动的场景。)
③CachedThreadPool:是一个会根据需要调整线程数量的线程池。(大小无界,适用于执行很多
短期异 步任务的小程序,或负载较轻的服务器)
④ScheduledThreadPool:继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任
务,或 者定期执行任务。使用DelayQueue作为任务队列。

21.线程池中 submit() 和 execute() 方法有什么区别?

execute():只能执行 Runnable 类型的任务。
submit():可以执行 Runnable Callable 类型的任务。
Callable 类型的任务可以获取执行的返回值,而 Runnable 执行无返 回值。

22.在 Java 程序中怎么保证多线程的运行安全?

方法一:使用安全类,比如 Java. util. concurrent 下的类。
方法二:使用自动锁 synchronized
方法三:使用手动锁 Lock

23.什么是死锁?

当线程 A 持有独占锁 a,并尝试去获取独占锁 b 的同时,线程 B 持有独 占锁 b,并 尝试获取独占
a 的情况下,就会发生 AB 两个线程由于互 相持有对方需要的锁,而发生 的阻塞现象,我们称
为死锁。

24.怎么防止死锁?

①尽量使用 tryLock(long timeout, TimeUnit unit)的方法 (ReentrantLock、
ReentrantReadWriteLock),设置超时时间,超 时可以退出防止死锁。
②尽量使用 Java. util. concurrent 并发类代替自己手写锁。
③尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
④尽量减少同步的代码块。

25.ThreadLocal 是什么?有哪些使用场景?

ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个 线程都可以独 立地改变
自己的副本,而不会影响其它线程所对应的副本。 ThreadLocal 的经典使用场景是数据库连接和
session 管理等

26.synchronized 和 Lock 有什么区别?

synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码 块加锁。
synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自 动释放 锁,不会造成死锁;
而 lock 需要自己加锁和释放锁,如果使用不 当没有 unLock() 去释放锁就会造成死锁。 通过 Lock
可以知道有没有成功获取锁,而 synchronized 却无法办

27.什么是 Java 序列化?什么情况下需要序列化?

Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象 状态再读出来。
以下情况需要使用 Java 序列化:
①想把内存中的对象状态保存到一个文件中或者数据库中时候;
②想用套接字在网络上传送对象的时候;
③想通过 RMI(远程方法调用)传输对象的时候。

28.动态代理是什么?有哪些应用?

动态代理是运行时动态生成代理类。 应用:
动态代理的应用有 spring aoprpcJava 注解对象获取等。

29.怎么实现动态代理?

JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实 现的,而 cglib 是基于继
承当前类的子类实现的。

30.为什么要使用克隆?

克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都 还是初始化 时候的值,
所以当需要一个新的对象来保存当前对象的“状态 靠克隆方法了。

31.session 和 cookie 有什么区别?

①存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
②安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
③容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个 数限制。
④存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序 中;而 cookie 只能存储在
   浏 览器中。

32.如何避免 SQL 注入?

①使用预处理 PreparedStatement。② 使用正则表达式过滤掉字符中的特殊字符。

33.throw 和 throws 的区别?

throw:是真实抛出一个异常。 throws:是声明可能会抛出一个异常。

34.final、finally、finalize 有什么区别?

final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变 量,则表示此方法和此变量不
           能在被改变,只能使用。
finally:是 try{} catch{} finally{} 最后一部分,表示不论 发生任何情况 都会执行,finally 部分可
              以省略,但如果 finally 分存在,则一定会执行 finally 里面的代码。
finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调 用被回 收对象的此方法。

35.常见的异常类有哪些?

①NullPointerException 空指针异常
②ClassNotFoundException 指定类不存在
③NumberFormatException 字符串转换为数字异常
④IndexOutOfBoundsException 数组下标越界异常
⑤ClassCastException 数据类型转换异常
⑥FileNotFoundException 文件未找到异常

⑦NoSuchMethodException 方法不存在异常 

⑧IOException    IO异常

⑨SocketException   Socket 异常

36.说一下你熟悉的设计模式?

①单例模式:保证被创建一次,节省系统开销。 ②工厂模式(简单工厂、抽象工厂):解耦代码。
③观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改 变时, 它的所有的依
                         赖者都会收到通知并自动更新。
④外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定 义了 一个高层的接
                     口,让子系统更容易使用。
⑤模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值