JavaSE面试题

目录

你是怎样理解面向对象的

int和Integer有什么区别

==和equals的区别

谈谈你对反射的理解

反射机制

反射的作用

ArrarList和LinkedList区别

HashMap底层

HashMap和HashTable的区别

TreeSet和HashSet的区别

StringBuffer和StringBuild的区别

final、finally、finalize的区别

线程有几种状态,产生的条件是什么

产生死锁的原因

产生死锁的四个必要条件

什么是线程池,如何使用

使用线程池有何优点

Java自带有哪几种线程池

Java中有几种类型的流

字节流如何转为字符流

请说出你最常见的RuntimeException


你是怎样理解面向对象的

面向对象是利用语言对现实事物抽象。面向对象具有以下四大特征:

  • 封装:把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的方法
  • 继承:从已有的类得到继承信息创造新类
  • 多态:允许不同子类型的对象对同一消息作出不同的响应
  • 抽象:将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面

int和Integer有什么区别

  • int是基本数据类型,Integer是int的包装类
  • Integer必须实例化才能使用,int不需要
  • Integet的默认值是null,int是0
  • Integer是对象的引用,当new Integer时,会生成一个指针指向此对象,而int直接存储数据值

==和equals的区别

  • ==
    • 如果比较的是基本数据类型,那么比较的是变量的值
    • 如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)
  • equals
    • 如果没重写 equals 方法比较的是两个对象的地址值
    • 如果重写了 equals 方法后我们往往比较的是对象中的属性的内容
    • equals 方法是从 Object 类中继承的,默认的实现就是使用==

谈谈你对反射的理解

反射是通过实例或者类名获得类信息,一般反射和泛型可以同使用,典型的Spring整合其他框架时候,通过FactoryBean接口和泛型反射就可以为Spring容器注入需要的bean

反射机制

所谓的反射机制就是Java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的 动作做准备。

Java 的反射机制的实现要借助于 4 个类:Class,Constructor,Field,Method。

  • Class:类的类对象
  • Constructor:类的构造器对象
  • Field:类的属性对象
  • Method:类的方法对象

反射的作用

在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。动态获取类的信息以及动态调用对象的方法。

ArrarList和LinkedList区别

  • ArrayList底层是基于动态数组的数据结构,LinkedList底层基于链表的数据结构
  • 对于get和set,ArrayList优于LinkedList,因为LinkedList要移动指针
  • 对于add和remove,LinkedList优于ArrayList,因为ArrayList要移动数据

HashMap底层

HashMap的底层结构在jdk1.7中由数组+链表实现,在jdk1.8中由数组+链表+红黑树实现。

HashMap底层结构图:

HashMap.put()执行流程图:

HashMap和HashTable的区别

  • 线程安全性不同
    • HashMap是线程不安全的,HashTable是线程安全的,其中的方法是Synchronize的,在多线程并发的情况下,可以直接使用HashTable,但使用HashMap时必须自己增加同步处理
  • 是否提供contains()
    • HashMap只有containsValue()和containsKey();HashTable有contains()、containsKey()和containsValue(),其中contains()和containsValue()方法功能相同
  • key和value是否允许null值
    • HashTable中,key和value都不允许出现null值;HashMap中,null可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为null
  • 数组初始化和扩容机制
    • HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,HashTable不要求底层数组的容量一定要为2的整次幂,而HashMap要求一定为2的整次幂。HashTable扩容时,将容量变为原来的2倍+1,而HashMap扩容时,将容量变为原来的2倍

TreeSet和HashSet的区别

HashSet是采用Hash表来实现的,其中的元素没有按顺序排列,add()、remove()以及contains()等方法都是复杂度为O(1)的方法。

TreeSet是采用树结构实现(红黑树算法),元素是按顺序进行排列,add()、remove()以及 contains()等方法都是复杂度为O(log(n))的方法,它还提供了一些方法来处理排序的set,如first()、last()、headSet()、tailSet()等等。

StringBuffer和StringBuild的区别

  • StringBuffer与StringBuilder中的方法和功能完全是等价的
  • 只是StringBuffer中的方法大都采用了synchronized关键字进行修饰,因此是线程安全的,而 StringBuilder没有这个修饰,可以被认为是线程不安全的
  • 在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全而StringBuffer则每次都需要判断锁,效率相对更低

final、finally、finalize的区别

final:修饰符(关键字)有三种用法(修饰类、变量和方法)。修饰类时,意味着它不能再派生出新的子类,即不能 被继承,因此它和 abstract 是反义词。修饰变量时,该变量使用中不被改变,必须在声明时给定初值,在引用中只 能读取不可修改,即为常量。修饰方法时,也同样只能使用,不能在子类中被重写。

finally:通常放在try…catch的后面构造最终执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。

finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。

线程有几种状态,产生的条件是什么

  • 新建状态(New)
    • 线程对象被创建后,就进入了新建状态。例如Thread thread = new Thread()
  • 就绪状态(Runnable)
    • 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如thread.start()。处于就绪状态的线程,随时可能被CPU调度执行
  • 运行状态(Running)
    • 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态
  • 阻塞状态(Blocked)
    • 阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行。直到线程进入就绪状态, 才有机会转到运行状态。阻塞的情况分三种(①等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成;②同步阻塞:线程在获取synchronized同步锁失败;③其他阻塞:通过调用线程的sleep()或join()或发出了IO请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或超时、或者 IO 处理完毕时,线程重新转入就绪状态。)
  • 死亡状态(Dead)
    • 线程执行完了或者因异常退出了run()方法,该线程结束生命周期

产生死锁的原因

  • 系统资源不足
  • 进程运行推进的顺序不合适
  • 资源分配不当
  • ......

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

产生死锁的四个必要条件

  • 互斥条件:一个资源每次只能被一个进程使用
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
  • 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

什么是线程池,如何使用

线程池就是事先将多个线程对象放到一个容器中,当使用的时候就不用new线程而是直接去池中拿线程即可,节省了开辟子线程的时间,提高的代码执行效率。

在JDK的java.util.concurrent.Executors中提供了生成多种线程池的静态方法。

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);

ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(4);

ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

然后调用他们的execute()方法即可。

使用线程池有何优点

  • 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗
  • 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳 定性,使用线程池可以进行统一的分配,调优和监控

Java自带有哪几种线程池

  • Executors.newCachedThreadPool()
    • 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。这种类型的线程池特点是:工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE),这样可灵活的往线程池中添加线程。如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪
  • Executors.newFixedThreadPool(4)
    • 创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始 的最大数,则将提交的任务存入到池队列中。FixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源
  • Executors.newSingleThreadExecutor()
    • 创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO、LIFO、优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。 单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的
  • Executors.newScheduledThreadPool(4)
    • 创建一个定长的线程池,而且支持定时的以及周期性的任务执行。例如延迟 3 秒执行

Java中有几种类型的流

字节流如何转为字符流

字节输入流转字符输入流通过InputStreamReader实现,该类的构造函数可以传入InputStream对象。

字节输出流转字符输出流通过OutputStreamWriter实现,该类的构造函数可以传入OutputStream对象。

请说出你最常见的RuntimeException

  • java.lang.NullPointerException(空指针异常)
    • 出现原因:调用了未经初始化的对象或者是不存在的对象
  • java.lang.ClassNotFoundException(指定的类找不到)
    • 出现原因:类的名称和路径加载错误,通常都是程序试图通过字符串来加载某个类时可能引发异常
  • java.lang.NumberFormatException(字符串转换为数字异常)
    • 出现原因:字符型数据中包含非数字型字符
  • java.lang.IndexOutOfBoundsException(数组角标越界异常)
    • 出现原因:常见于操作数组对象时发生
  • java.lang.IllegalArgumentException(方法传递参数错误)
    • 出现原因:调用方法时传参错误
  • java.lang.ClassCastException(数据类型转换异常)
    • 出现原因:常见于进行数据类型转换时发生
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫咪老师QAQ

赏一点猫粮叭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值