面试题(Java面试)

本文整理了Java面试中常见的问题,涵盖了Java基础、多线程、集合框架、并发编程、异常处理、JVM内存模型、数据库操作、设计模式等多个方面。其中,详细解释了面向对象的四大特征、抽象类与接口的区别、线程同步和锁机制、异常处理、String对象的创建与内存管理、线程状态、以及多线程安全通讯。此外,还涉及到了JSP的内置对象、Servlet生命周期、数据库操作、网络编程等知识点,是Java面试的重要参考资料。
摘要由CSDN通过智能技术生成

常遇面试题
不同的面试官问的问题不一样,侧重点不一样。并不是下面的都会问,可能还会问其他的,仅供参考。这些问题一般会结合一些场景来问,不过下面是大致问过比较多的一些。
Java基础:
面向对象的特点
面向对象主要有四大特征

  • 抽象:将一些多个对象的共同特点进行找出来,然后抽象出来一个类或者方法。例如人类和狗都是动物,那么他们都有移动的功能,只不过移动的方式不同而已。在项目中一般抽象出来最多的是接口与方法
  • 继承:对象的一个新生可以从现有的类中派生,这个过程成为类继承。子类拥有父类的所有非私有方法,并且执行顺序为:父类静态代码块、子类静态代码块、父类构造方法、子类构造方法。显示世界中也有继承,如:子女继承父类的遗产等。
  • 封装:是面向对象的特征之一,1、主要是为了将数据隐藏,提供特定的方法进行调用,保护了模块的独立性2、方便传输或者保证传输过程的一致性,如项项目中常将页面信息封装成一个VO对象传递到Dao层。在实际过程中属相设为私有,方法设为protected,数据封装成对象都是一种表现形式
  • 多态性:允许不同类的对象对同一信息作出相应,李彤同样选择了编辑-粘贴操作,在字处理程序和绘图程序中有不同效果。同样是查询操作,在查询个人信息与查询学生课程信息会显示不同的信息
    面向对象在程序设计过程中首先设计的是对象,然后再考虑对象之间的关系,例如:老师添加学生信息,首先应该有两个对象:学生、老师,然后在老师对象中有添加学生的功能

抽象类与接口的区别
一个是用abstract修饰、一个是interface修饰
抽象类拥有构造方法、接口没有构造方法
抽象类能拥有方法的实现,接口不能有方法的实现
抽象类被继承需要重写里面所有的抽象方法,接口被实现必须实现所有方法
抽象类里面的方法类型可以是public、protected方法,接口必须是public方法
抽象可以包含静态方法、接口不能包含静态方法
一个类可以实现多个接口,但只能直接继承一个抽象类
说说final
中文为:最终的、最后的
可以用来修饰局部变量、类属性、形参、方法、类
当final修饰类是,该类为最终类,不可以被继承
当final修饰方法是,为最终方法,不能被重写
当final修饰变量是,该变量的引用不能被改变
当final修饰属性以及变量属性,必须进行进行初始化赋值
Static的用法
用static修饰的方法为静态方法,静态方法只能引用静态的全局属性,静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能使用this和super关键字
使用static修饰的变量叫做静态变量或者类变量,存放在jvm里面的堆区,每次创建一个类对象,都是访问同一个类变量
静态方法块,在每次实例化这个类,静态方法块首先被加载。并且只能被加载一次
==与equals的区别:java中所有的非基本数据类型,存放的值都是对象的引用
Java分为基础类型分为两类:一个是基本数据类型、一个是复合数据类型
基本类型用==比较的是他们的值
当他们用==比较复合数据类型时,比较的是他们存放的地址,除非是同一个new出来的对象,他们比较够的对象为true,否则比较结果结果为false 如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的
重载与重写的区别
方法重载是让类以同一的方式处理不同类型的一种手段,是多态的一种表现;重写用于父类与子类之间,子类不适应父类的方法,需要在子类中重新定义一个方法
重载方法时候,方法参数类型与长度不一样,也可以返回值不同,但是不能与返回值类型来区分。重写方法是参数类型与长度和返回值必须一样
String,stringBulider与stringBuffer的区别
首先String是常量,对象不可变;StringBuffer与StringBuilder是继承AbstractStringBuilder类,对象可变
String是常量,所以线程安全;StringBuffer对方法加了同步锁,所以也是线程安全;StringBuilder并没有对方法加同步锁,所以是非线程安全的
因为StringBuilder没有加同步锁,所以效率高于StringBuffer
String对象的创建
String s = new String(“abc”),如果在java方法区的常量池中没有“abc”对象,则会创建三个对象,其中s作为对象的引用会在栈区开辟一个空间,类型为String类型,new String(“abc”)则会在堆区创建一个空间,用于存放“abc”的引用地址,真正用于保存“abc”字符串的空间在方法区的常量池中
Object类有哪些方法
toString、wait、equals、getClass、notify、notifyAll、hashCode
异常有哪些?举几个例子
RuntimeException:NullPointException异常
ReflectiveOperationException:ClassNotFundException异常
InterruptedException:当一个线程正在处于等待、休眠等状态被打断时,抛出的异常
Throw与throws的区别
Throw是明确在哪个地方抛出的哪个异常,throws是告诉程序这个方法可能抛出的那几个异常,方法调用者需要对这些异常进行处理
Throw语句是在方法体内,表示抛出异常,由方法体内的语句处理
Throws语句在方法声明后面,表示再抛出异常,由该方法调用者来处理
ArrayList与LinkedList的区别
ArrayList是基于动态数组的数据结构、LinkedList基于链表的数据结构
随机访问ArrayList效率高于LinkList,但是若是单条的新增与删除效率高于LinkList,但是批量的删除、新增效率低于LinkList,做了测试,如果用两个list集合添加1000000数据,并且每条数据只存一个值,那么两个相差不大;测试结果为150ms左右与125ms左右,但是如果每条数据为两个值:list.add(1,null);那么ArrayList为100ms左右,LinkedList数据为20ms左右
HashMap,Hashtable和HashSet的区别(只要问了集合都会问到)
HashSet底层采用的是HashMap进行实现的,但是没有HashMap中的value,HashSet不容许重复对象
Hashtable是基于Dictionary类的,而HashMap是基于Map接口的一个实现
Hashtable里默认的方法是同步的,而HashMap则是非同步的,所以HashTable是多线程安全的
HashMap可以将key设置为null,但是只能有一个,而value可以有多个null.但是Hashtable不能有null
HashMap的初始化大小为16,并且扩容方式为超过长度的75%,增加一倍;Hashtable的初始化大小为11,超过长度的75%,扩容方式为2*size+1
HashTable、HashMap、HashSet都是迭代器快速失败的集合,也就是在创建Iterator之后,如果是不使用iterator的remove方法,而是使用其他方法对HashTable进行修改,则会抛出ConcurrentModificationException
concurrentHashMap的实现原理
多线程
首先多线程是一中机制,它允许在程序中并发的执行多个指令流,每个指令流称为一个线程,在单核中,并发是指:在同一个时间段可以执行多个指令
在java中实现多线程的方法有两种,一个是继承Thread类,重写run()方法,第二是方法是实现Runnable接口,实现run()方法
线程有5个状态,分别是:新建、就绪、运行、阻塞、死亡,其中在java中新建就是new出一个线程,就绪就是调用了start方法,运行就是执行了这个线程、阻塞就是这个线程被挂起、死亡就是线程运行完毕
线程同步,同一个进程的多个线程共享同一片存储空间,容易造成数据的混乱,而synchronized关键字可以解决这个问题,包括synchronized 方法和synchronized 代码块
synchronized 方法会大大的影响效率,所以一个加了锁的方法最好的设计成最简单的实现,一些不能引起数据混乱的操作可以放在方法外面
对于一些访问类成员变量的代码最好可以放在synchronized块中,这样可以很大的提高效率
Java采用采用同步机制来保障多个线程对共享资源的访问不能真正的满足需求,因为在任意时刻需要的资源部一定都准备好,同一时刻准备好的资源也不止有一个,所以java采用了线程的阻塞,例如sleep()方法,有相应的唤醒机制,如:notity方法
什么叫多线程的可见性和有序性
可见性:多个线程之间是不能互相传递数据通信的,它们之间的沟通只能通过共享变量来进行。Java内存模型(JMM)规定了jvm有主内存。主内存是多个线程共享的。当new一个对象的时候,也是被分配在主内存中,每个线程都有自己的工作内存,工作内存存储了主存的某些对象的副本,当然线程的工作内存大小是有限的
有序性:线程在引用变量时不能直接从主内存中引用,如果线程工作空间中没有该变量,则会从主内存中拷贝一个副本到工作空间内,这个过程为read-load,完成后线程会引用该副本。如果同一线程再度引用该字段时,有可能重新从主内存中获取变量副本,也有可能直接引用原来的副本,也就是说read、load、use顺序可以有JVM实现系统决定
怎么使用锁,以及锁之间怎么运行
理论上,每一个对象都可以作为锁,但是一个对象作为锁时,应该被多个线程共享,这样才显得有意义
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了被阻塞的线程,当一个线程被唤醒后,才会进入到就绪队列,等待CPU的调度
一个线程执行临界区代码过程如下
获取同步锁
清空工作空间
从主存拷贝变量副本到工作空间
对这些变量计算
将变量从工作内存写回到主存
释放锁
怎么保证线程之间的安全通讯的问题
Synchronized关键字:作为线程并发环境的执行有序性的保证手段之一,当一段代码会修改共享变量,这一段代码成为互斥去或者临界区,为保证共享变量的正确性,synchronized标示了临界区
Volatile关键字:是java提供的一种同步手段,只不过它是轻量级的同步,因为volatile只能保证多线程的内存可见性,不能保证多线程的执行有序性
Sychronized方法和sychronized块
sychronized块的特性
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内是能有一个线程执行
当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块
当一个线程访问object中的synchronized(this)同步代码块时,其他线程访问object中所有其他synchronized(this)同步代码块的访问将被阻塞
各种锁之间的执行关系
一个类中所有synchronized方法,在争取获取该对象锁时形成互斥
一个类中的synchronized方法与非synchronized方法之间不会形成互斥
一个类中的使用一个类的字节码为为对象锁,与synchronized方法不会形成互斥
GC
对于每个对象而言,垃圾回收机制分为两个阶段:finalization和reclamation,其中finalization指运行这个对象的finalize方法
GC的过程的基本步骤1、首先确定这个对象是不可达的,其次,如果对象有finalize方法,那么对象被添加到finalization队列中,然后在某个时间点finalize方法,用于释放finalize中的资源,最后,回收对象占用的内存
对象的引用类型
StrongReference:强引用类型的引用,如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题
SoftReference:被这种引用指向的对象,如果没有被其他Strong Reference引用的话,在任何时候都可能被GC.通常在可用内存较低或者在抛出outOfMemeoryError之前被GC,适合实现Cache
WeakReference,如果没有SoftReference和StrongReference引用时,立即会被GC,和SoftReference的区别是:WeakReference对象是被eagerly collected,即一旦没任何SoftReference和StrongReference引用的对象,立即被程序了解
PhantomReference(幻影引用):当没有StrongReference、SoftReference和WeakReference引用时,随时被GC,通常和ReferenceQuere联合使用,管理和清除与被引用对象相关的本地资源,没有finalize方法
进程与线程的区别
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,线程是进程的一个实体,是CPU调度和分派的基本单位:如开一个QQ程序相当于开了一个进程,你在QQ里面与多人聊天相当于开了多个线程
进程与线程的主要差别在于它们是不同的操作系统资源管理方法。进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值