刷完牛客网910道Java题目,快速总结上万字,带你扫清Java基础面试障碍

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

如果要操作少量的数据用:String

单线程操作字符串缓冲区下操作大量数据:StringBuilder

多线程操作字符串缓冲区下操作大量数据:StringBuffer

11、重载和重写的区别?

答:重载(Overload):在同一个类中,如果多个方法,名字相同、参数不同,即称为重载。在编译器眼里,方法名称+参数类型+参数个数,组成一个唯一键,称为方法签名,JVM通过这个唯一键决定调用哪个重载的方法。

重写(Override):方法重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的名字、参数、返回类型

口诀看这里:

方法重写的记忆口诀“ 一大两小两同”

  • 一大:子类的方法访问权限控制符只能相同或变大。

  • 两小:抛出异常和返回值只能变小, 能够转型成父类对象。子类的返回值、抛出异常类型必须与父类的返回值、抛出异常类型存在继承关系。

  • 两同:方法名和参数必须完全相同。

12、集合框架中的泛型有什么优点?

答:泛型提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。泛型限制了集合容纳的对象类型,如果添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现 ClassCastException。泛型也使得代码整洁,我们不需要使用显式转换和 instanceOf 操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

13、final, finally, finalize的区别?

答:final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

finally是异常处理语句结构的一部分,表示总是执行。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用。

14、Exception和Error的区别?

答:Exception 和 Error 都是继承了 Throwable类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。

在这里插入图片描述

Exception:程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。

Error:是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是 Error 的子类。

Exception 又分为可检查(checked)异常和不检查(unchecked)异常。

● 可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。

● 不检查异常就是所谓的运行时异常,类似NullPointerException、ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。

15、throw 和throws 的区别?

答:位置不同:throws 用在函数上,后面跟的是异常类,可以跟多个;而throw 用在函数内,后面跟的是异常对象。

功能不同:

(1)throws 用来声明异常,让调用者只知道该功能可能出现的问题,可以给出预先的处理方式;throw 抛出具体的问题对象,执行到throw,功能就已经结束了,跳转到调用者,并

将具体的问题对象抛给调用者。也就是说throw 语句独立存在时,下面不要定义其他语

句,因为执行不到。

(2) throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw 则是抛出了异常,执行throw 则一定抛出了某种异常对象。

(3)两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

16、什么是Java反射机制?

答:Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java 语言的反射机制。

它的功能:

(1)在运行时判定任意一个对象所属的类;

(2)在运行时构造任意一个类的对象;

(3)在运行时判定任意一个类所具有的成员变量和方法;

(4)在运行时调用任意一个对象的方法;

(5)生成动态代理;

17、获取Class 对象的方法?

答:(1)调用某个对象的getClass()方法;

Person p=new Person();

Class clazz=p.getClass();

(2)调用某个类的class 属性来获取该类对应的Class 对象;

Class clazz=Person.class;

(3)使用Class 类中的forName()静态方法(最安全/性能最好);

Class clazz=Class.forName(“类的全路径”);

18、什么是Java复制?

答:将一个对象的引用复制给另外一个对象,一共有三种方式。

第一种方式是直接赋值,第二种方式是浅拷贝,第三种是深拷贝。

(1)直接赋值

A a1 = a2,实际上复制的是引用,也就是说a1 和a2 指向的是同一个对象。因此,当a1 变化的时候,a2 里面的成员变量也会跟着变化。

(2)浅复制(复制引用但不复制引用的对象)

创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。

(3)深复制(复制对象和其应用对象)

深拷贝不仅复制对象本身,而且复制对象包含的引用指向的所有对象。

19、什么是Java序列化?

答:序列化:将java对象转换为字节序列的过程称为对象的序列化;

在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的“状态”,即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。

为什么要序列化?

(1)持久化(2)网络传输

20、为啥要实现Serializable接口?

答:这个接口其实是个空接口,那么实现它有什么用呢?其实,当我们让实体类实现Serializable接口时,其实是在告诉JVM此类可被序列化,可被默认的序列化机制序列化。

21、Transient 关键字有什么作用?

答:简而言之,被transient修饰的变量不参与序列化和反序列化。

22、截止JDK1.8版本,java并发框架支持锁包括?

● 自旋锁:自旋,jvm默认是10次吧,有jvm自己控制。for去争取锁

● 阻塞锁:被阻塞的线程,不会争夺锁。

● 可重入锁:多次进入改锁的域

● 读写锁

● 互斥锁:锁本身就是互斥的

● 悲观锁:不相信,这里会是安全的,必须全部上锁

● 乐观锁:相信,这里是安全的。

● 公平锁:有优先级的锁

● 非公平锁:无优先级的锁

● 偏向锁:无竞争不锁,有竞争挂起,转为轻量锁

● 对象锁:锁住对象

● 线程锁

● 锁粗化:多锁变成一个,自己处理

● 轻量级锁:CAS 实现

● 锁消除:偏向锁就是锁消除的一种

● 锁膨胀:jvm实现,锁粗化

● 信号量:使用阻塞锁 实现的一种策略

● 排它锁:X锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。

23、JDK提供的用于并发编程的同步器有哪些?

答:(1)Semaphore

可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

(2)CyclicBarrier

主要的方法就是一个:await()。await()方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。

(3)CountDownLatch

直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。

24、HttpServlet容器响应Web客户请求流程

(1)Web客户向Servlet容器发出Http请求;

(2) Servlet容器解析Web客户的Http请求;

(3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;

(4)Servlet容器创建一个HttpResponse对象;

(5) Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;

(6) HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;

(7)HttpServlet调用HttpResponse的有关方法,生成响应数据;

(8)Servlet容器把HttpServlet的响应结果传给Web客户。

25、内部类的访问特点

● 内部类可以直接访问外部类的成员,包括私有。

● 外部类要访问内部类的成员,必须创建对象。

● 外部类名.内部类名 对象名 = 外部类对象.内部类对象。

26、数组和集合的区别

(1) 存储

  • 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值。

  • 集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象。

(2)长度

  • 数组长度是固定的,不能自动增长。

  • 集合的长度的是可变的,可以根据元素的增加而增长。

27、synchronized关键字和volatile关键字比较?

● volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。

● 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。

● volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。

● volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

28、以下哪种方式实现的单例是线程安全的

● 饿汉式(线程安全,调用效率高,但是不能延时加载);

● 懒汉式(线程安全,调用效率不高,但是能延时加载);

● Double CheckLock实现单例:DCL也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用);

● 静态内部类实现模式(线程安全,调用效率高,可以延时加载);

● 枚举类(线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用)。

29、集合结构

在这里插入图片描述

30、服务端和客户端的Socker交互

在这里插入图片描述

public class TcpServer {

public static void main(String[] args) throws Exception {

// Server端监听10000端口

ServerSocket serverSocket = new ServerSocket(10000);

while(true){

// 等待客户端连接,此时进入阻塞状态

Socket socket = serverSocket.accept();

System.out.println("Connected: " + socket.getRemoteSocketAddress());

// 从Socket读取数据

InputStream inputStream = socket.getInputStream();

byte[] b = new byte[1024];

int length = inputStream.read(b);

System.out.println(length + " Bytes Received");

}

}

}

public class TcpClient {

/**

  • @param args

  • @throws IOException

  • @throws UnknownHostException

*/

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

//1.建立TCP连接

Socket client = null;

try {

client = new Socket(“127.0.0.1”, 10006);

client.setSoTimeout(10000);

}catch (Exception e){

throw new Exception(“TCP连接异常”);

}

//2、传输内容

String content = “这是一个JAVA模拟客户端”;

byte[] bstream = content.getBytes(“UTF-8”);//字节流

OutputStream os = client.getOutputStream();

os.write(bstream);

//3、关闭TCP连接

if (null != client ){

client.close();

}

}

}

31、常用的排序

在这里插入图片描述

32、如何判断哪些内存需要回收?

答:(1)引用计数(存储在堆对象数据里面(对象头)):一个对象被引用一次,那么应用计数就加1,如果说没有引用,减1 引用计数等于0,就表示这个对象需要回收。(有循环引用问题)

(2)可达性分析法:这个算法的基本思想是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。(注意:不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记过程。两次标记后仍然是可回收对象,则将面临回收。)

33、简述 java 垃圾回收机制?

答:在 java 中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM 中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。

34、说一下常见的垃圾回收算法?

答:(1)标记-清除算法(年老代)

产生大量的内存碎片,效率也不高。适用于存活对象较多的情况下比较高效,适用于年老代(即旧生代)。

(2)复制算法(新生代)

时间换空间,解决了效率问题,但浪费了空间。适用于存活对象较少的情况下比较高效,适用于年轻代(即新生代)。

(3)标记-整理算法(年老代)

解决对象都存活的问题,是标记-清除算法的优化,将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。适用于年老代(即旧生代)。

(4)分代收集算法

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),在堆区之外还有一个代就是永久代(Permanet Generation)。新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代的特点是每次垃圾收集时只有少量对象需要被回收,对象存活率高,就可使用“标记-清理”或“标记-整理”算法来进行回收。

35、Minor GC 与 Full GC 分别在什么时候发生?

答:新生代内存不够用时候发生 MGC 也叫 YGC,JVM 内存不够的时候发生 FGC

36、classload类加载过程?

答:JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。

(1)加载

将class字节码文件加载到内存中,通过一个类的全限定名获取该类的二进制流,并将该二进制流中的静态存储结构转换成方法区中的运行时数据(静态变量、静态代码块、常量池等),在堆中生成一个Class类对象代表这个类(反射原理),作为方法区类数据的访问入口。

(2)验证

确保加载的类信息符合JVM规范,没有安全方面的问题。

● 文件格式验证:验证字节流是否符合 Class 文件的规范,如主次版本号是否在当前虚拟机范围内,常量池中的常量是否有不被支持的类型.

● 元数据验证:对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不被继承的类等。

● 字节码验证:是整个验证过程中最复杂的一个阶段,通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证。如:方法中的类型转换是否正确,跳转指令是否正确等。

● 符号引用验证:这个动作在后面的解析过程中发生,主要是为了确保解析动作能正确执行。

(3)准备

正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。注意此时的设置初始值为默认值,具体赋值在初始化阶段完成。

(4)解析

虚拟机常量池内的符号引用替换为直接引用(地址引用)的过程。

(5)初始化

初始化阶段对静态变量和静态代码块执行初始化工作。到了初始化阶段,才真正开始执行类中定义的Java 程序代码。

初始化顺序:父类的静态变量->父类的静态代码块->子类的静态变量->子类的静态代码块->父类的非静态变量->父类的非静态代码块->父类的构造方法->子类的非静态变量->子类的非静态代码块->子类的构造方法。

37、类加载器有几种?

答:(1)启动类加载器(Bootstrap ClassLoader)

负责加载加载 Java 核心类库,无法被 Java 程序直接引用。 在JAVA_HOME\lib 目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。

(2)扩展类加载器(Extension ClassLoader)

负责加载Java的扩展库,在 JAVA_HOME\lib\ext 目录中的,或通过java.ext.dirs系统变量指定路径中的类库。

(3)应用程序类加载器(Application ClassLoader)

负责加载用户路径(classpath)上的类库。 JVM通过双亲委派模型进行类的加载,当然我们也可以通过继承java.lang.ClassLoader实现自定义的类加载器。

在这里插入图片描述

38、说一下双亲委派?

答:当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

有什么好处:

(1)基于双亲委派模型规定的这种带有优先级的层次性关系,虚拟机运⾏程序时就能够避免类的重复加载。

(2)双亲委派模型能够避免核⼼类篡改。

39、JAVA 中的引用类型?

答:(1)强引用

在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到JVM也不会回收。因此强引用是造成Java内存泄漏的主要原因之一。

(2)软引用

软引用需要用SoftReference类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。

(3)弱引用

弱引用需要用WeakReference类来实现,它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存空间是否足够,总会回收该对象占用的内存。

(4)虚引用

虚引用需要PhantomReference类来实现,它不能单独使用,必须和引用队列联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。

40、HashMap底层原理?

答:博文链接:一文看懂HashMap底层原理

总结

在清楚了各个大厂的面试重点之后,就能很好的提高你刷题以及面试准备的效率,接下来小编也为大家准备了最新的互联网大厂资料。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
够,总会回收该对象占用的内存。

(4)虚引用

虚引用需要PhantomReference类来实现,它不能单独使用,必须和引用队列联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。

40、HashMap底层原理?

答:博文链接:一文看懂HashMap底层原理

总结

在清楚了各个大厂的面试重点之后,就能很好的提高你刷题以及面试准备的效率,接下来小编也为大家准备了最新的互联网大厂资料。

[外链图片转存中…(img-8qN6SSWn-1713103569342)]

[外链图片转存中…(img-ZuJPf4LE-1713103569342)]

[外链图片转存中…(img-6h0XYcFV-1713103569342)]

[外链图片转存中…(img-yvoULVOl-1713103569343)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-3m0qhx15-1713103569343)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值