面试-java基础(小厂实习)

1.java中的序列化和反序列化是什么?

java的序列化是指将对象转化为字节流,主要是为了便于网络传输、持久化存储或者缓存。

java的反序列化是指将字节流转化为对象的过程,即从存储读取数据并重新创建对象。

java提供了java.io.Serializable接口来支持序列化。

serialVersionUID的作用是什么:验证作用

用来验证序列化对象的ID与反序列化对应的对象的ID是否相同

2.什么是java中的不可变类

关键特征:

1.声明类为final,不能被子类继承

2.类中所有的字段都是被private final修饰,确保它们在初始化之后不能被修改

3.通过构造函数初始化所有字段。

4.不提供任何修改对象状态的方法。

常见的不可变类有String、Integer等。

不可变类的优缺点

优点:

1.线程安全:在并发环境下不需要考虑同步问题。

2.缓存友好:可以安全地被缓存和共享

缺点:

1.性能问题:在每次状态更新时都需要new一个对象。(例如String拼接)

3.java中Exception和Error的区别

Exception和Error都是Throwable的子类

Exception通常是可以通过程序去捕获的,例如使用try-catch代码块去捕获

Exception分为编译时异常和运行时异常,常见的编译时异常有:IOException

常见的运行时异常有:NullPointerException、IllegalArgumentException

Error通常是jvm系统级的异常,无法通过程序去捕获

常见的Error有OutOfMemoryError、StackOverflowError

4.java的优势是什么?

1.面向对象

面向对象的三大特性:封装、继承、多态

2.自动垃圾回收机制

将内存交由GC管理,减轻程序员的负担

3.丰富生态

丰富第三方类库、网上全面资料、企业级的框架等

4.跨平台

Write once,Run anywhere 通过jvm实现

5.java是按值传递还是按引用传递?

在java中,参数都是按值传递,无论是基本类型还是引用类型

1.基本数据类型:传递的是基本类型的数值本身。

基本数据类型:

byte、short、int、long、float、double、char、boolean

2.引用数据类型:传递的是对象引用的内存地址。

6.为什么java不支持多重继承?

主要是java之父吸取C++教训,因为会产生菱形继承

为接口可以多实现?

因为接口当中无具体实现,必须要在子类实现方法(jdk8之前)

后面出现了default方法,如果接口有多个相同的默认方法,必须要在子类重写这个方法。

7.面向过程和面向对象的区别

面向对象编程:以类和对象作为基本单元来组织代码。关注对象之间的关系与交互

面向过程编程:以过程或函数作为基本单元来组织代码。关注执行的步骤和顺序

优缺点:

面向对象的优缺点:

优点:代码复用性、扩展性高,适合大型项目。

缺点:开发和理解成本高。

面向过程的优缺点:

优点:开发简单,适合小型项目。

缺点:代码复用性、扩展性差。

8.面向对象的三大特性

封装:将数据和行为封装在对象的内部,提供接口进行访问,隐藏实现细节,提高安全性。

继承:子类通过继承父类的属性和方法,实现代码的复用和扩展。

多态:对象可以通过父类或接口实现多态性调用,不同的对象在运行时可以展现不同的行为。

9.方法重载和方法重写有什么区别?

两者都是面向对象中多态特性的体现

方法重载:

在一个类中允许有多个同名方法,只要它们的参数列表不同(参数的个数、类型、顺序)

方法重写:

子类在继承父类或接口,对父类或接口中的方法的实现

注意点:

在重写时,子类重写的方法的访问等级不能比父类更加严格

10.java的内部类是什么?有什么用?

java内部类是指在一个类中定义的类。内部类可以访问外部类的成员变量和方法,甚至私有的成员。

java内部类有:

1.成员内部类

可以访问外部类的所有成员,包括私有成员

2.匿名内部类

没有类名的内部类

3.静态内部类

只能访问外部类的静态成员

4.局部内部类

定义在方法和代码块中的内部类

11.jdk8有哪些新特性

1.引入lambda表达式

2.引入接口的默认方法

3.引入Stream流式接口

4.元空间取代了永久代

5.修改了HashMapConcurrentHashMap的实现

12.String、StringBuffer、StringBuilder的区别

13.java中包装类型和基本类型的区别

基本类型:它们是直接存储数据的变量,存储在栈上,性能相对较高,不支持null。

包装类型:包装类型是类,存储在堆上,性能相对较差(涉及内存分配和垃圾回收),支持null。

14.接口和抽象类的区别

设计思想:

接口它是自上而下设计的。

抽象类是自下而上设计的,往往都是同一些类共同特点抽象出来的。

方法实现:

接口的方法默认是public abstract修饰的。

抽象类可以包含abstract方法和具体方法。

构造函数:

接口没有构造函数,成员变量都是public static final修饰的

抽象类有构造函数,成员变量可以有不同的修饰符

继承:

接口可以多继承

抽象类只能单继承

15.JDK和JRE的区别

JRE:是java的运行环境,包含jvm、核心类库和其他支持运行java程序的文件。

jvm:执行java的字节码,提供java运行环境。

JDK:是JRE的超集,即完整的java运行环境,包含了JRE、以及用于开发、调试和监控java应用程序的工具。

开发工具:如编译器(javac)、调试器(jdb)、打包工具(jar)等

16.JDK提供的工具

javac:java编译器,将java源代码编译成字节码

java:运行java应用程序的命令,使用jvm来解释并执行编译后的字节码文件

jdb:java调试工具,用于在命令行中调试java应用程序

jar:java打包工具

javadoc:生成API文档的工具

17.equals方法、==、hashCode方法

hashcode:用于散列存储结构中确定对象的位置。可用于快速比较两个对象的是否相同,如果两个对象的哈希值不相同,那么这两个对象肯定不相同。

equals:默认实现就是==,比较两者的内存地址是否相同

通常需要我们自己在自定义类中去重写这个方法,以基于对象属性进行内容的比较

==:基本数据类型比较的是值,引用类型比较的是两者的内存地址是否相同

18.什么是java的动态代理

java的动态代理是指在程序运行时创建代理对象的机制。动态代理允许程序在运行决定代理对象的行为,而不需要像静态代理那样在编译时确定。

主要用途:

1.简化代码:通过代理可以减少重复代码,尤其是在横切关注点(如日志记录,事务管理,权限控制等)方面。

2.实现AOP:是AOP的基础,可以在方法调用的前后插入额外的逻辑。

3.增强灵活性:因为代理对象是在运行是生成的,可以动态地改变行为。

19.动态代理与CGLIB的区别

动态代理是基于接口实现的,所以要求一定是有定义接口的。

CGLIB是基于ASM字节码生成工具,它是通过继承的方式生成目标类的子类来实现代理类,所以要注意final方法。

20.java中注解原理是什么?

注解其实就是一个标记,是一种提供元数据的机制,用于给代码添加说明信息。可以标记在类上、方法上、属性上等。注解本身不影响程序运行,但是可以通过工具,或者框架对这些信息进行特殊处理,如代码生成,运行时处理。

21.反射机制

可以在程序运行时获取类的结构信息(如方法、字段、构造函数)并操作对象的一种机制。反射机制提供了在运行时动态船舰对象、调用方法、访问字段等功能,而无需在编译时知道这些类的具体信息。

22.SPI

SPI是一种插件机制,用于在程序运行时动态地加载某些功能的实现。

理解版:

API:我去水果店买水果,说“我要一盒苹果”,店员给我一盒已经包装好的苹果

SPI:我给店员一个具体的包装方式(比如“用红色盒子,每盒装5个”),店员按照我的要求来包装水果。

23.泛型

类型安全:将运行时异常转编译时异常

代码重用:不用为一个类型创建一个集合,而是可以使用多种不同类型。

消除显示类型转换:类型擦除帮我们转换好了

24.泛型擦除

定义:泛型擦除是指在编译时将泛型信息进行擦除,使原本数据类型转为object类。

作用:提高了对象的向后兼容性。

影响:在程序运行时不能获取原本对象数据类型。

25.浅拷贝与深拷贝区别

浅拷贝:浅拷贝创建一个新对象,但是它的字段指向的是原对象相同的内存地址。

深拷贝:深拷贝不仅复制对象本身,还递归复制对象所有的引用。新对象与原对象是完全独立互不影响的。

26.Integer的缓存池

在-128和127范围内的Integer对象会被缓存和复用。

原理:

java在自动装箱时,对于值在-127到128范围内的int类型,会直接返回一个已经缓存的Integer对象,而不是创建新的对象。

27.java的类加载过程

三个阶段

1.加载:通过类加载器将类文件加载到内存中,生成一个Class对象

类加载器:是jvm中用于动态加载类文件的组件。它将.class文件中的字节码加载到内存中,并将其转化Class对象,以供jvm执行。

jdk8时的三种类加载器:

1.启动类加载器Bootstrap ClassLoader

2.扩展类加载器Extension ClassLoader

3.应用程序类加载器Application ClassLoader

双亲委派模型:类加载器会先把类加载请求交由父类加载器处理,只有父类加载器找不到类时,才由当前类加载器执行。

2.验证:确保加载的类信息符合jvm规范,没有安全问题。

3.准备:给类的静态变量分配内存,并设置默认初始值。

4.解析:jvm将常量池内的符号引用替换为直接引用。

5.初始化:执行类构造器方法。

28.BigDecimal

是java提供的一个高精度计算的不可变类,属于java.math包。

为什么能够保证精度:

因为使用了任意精度的整数表示法,而不是浮动的二进制表示。

29.使用new String语句会在java中创建多少个对象

会创建一个或两个对象

主要看字符串常量池中是否存在这个字符串对象的引用

29.final和finally

1.final:用于修饰类、方法和变量,主要用来设计不可变类、确保类的安全性、优化性能。

类:被final修饰的类不能被继承。

方法:不能被重写。

变量:不可重新赋值,常用于定义常量。

2.finally:与try-catch语句块结合使用,用于确保无论是否发生异常,finally代码块都会执行。

主要用于释放资源(如关闭文件、数据库连接等)。

30.如果一个线程在java中被两次调用start()方法,会发生什么?

会报错

一旦线程开始执行,它的状态不能回到初始状态。线程的生命周期不允许它从终止状态回到可运行状态。

31.java的访问修饰符有哪些?

public:可以被任何类访问。

protected:可以被同一个包的类访问,或者是子类。

默认:只能被同一个包的类访问。

private:内部可以访问,外部不可以。

32.静态方法和实例方法的区别

静态方法是用static修饰的,它是属于类的,而不属于实例,可以直接通过类名调用,可以访问静态变量和静态方法,不能直接访问实例变量和实例方法

33.for和for each的区别

for循环:适合用复杂操作,例如根据索引进行操作、反向遍历等。

for each:简单遍历,不需要访问索引。

34.sleep()和wait()方法的区别

1.sleep是属于Thread类的方法,释放cpu给其他线程,不释放锁资源。

2.wait是属于Object类的方法,释放cpu给其他线程,释放锁资源。

需要通过其他线程通过notify()和notifAll()唤醒

必须配合synchronized一起使用

35.BIO、NIO和AIO

BIO:调用操作时会被阻塞,直到操作完成后才继续执行。

NIO:调用操作后可以立即返回,即使操作未完成。

AIO:调用操作后,不需要等待操作完成。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值