面试篇-java基础上

一、概念

1. 说一下Java特点

  • 平台无关性:Java编译器将源代码编译成字节码,该字节码可以在任何安装了Java虚拟机(JVM)的系统上运行

  • 面向对象:Java是一门严格的面向对象编程语言,几乎一切都是对象。面向对象编程这一特性使得代码更容易维护和重用,包括类、对象、继承、多态、抽象和封装

  • 内存管理:Java有自己的垃圾回收机制,自动管理内存和回收不再使用的对象。这样开发者不需要手动管理内存,从而减少内存泄漏和其他内存相关的问题


2. Java的优势和劣势

优势

  • Java的特点也是他的优势

  • 强大的生态系统,比如Spring框架、各种库和工具

  • 社区支持大,企业应用广泛

  • 多线程支持,方便并发编程

  • 安全性方面,Java有安全模型,比如沙箱机制,适合网络环境

  • 稳定性强,企业级应用长期使用

  • 版本更新也比较注重向后兼容

劣势

  • 性能比较差,相比于C这种原生编程语言性能较差

  • 内存消耗大,JVM本身占内存

  • 面向对象过于严格,有时候写简单程序反而麻烦

  • 开发效率相比动态语言(比如Python)较低,Java需要更多代码

  • 编译过程也可能拖慢开发节奏


3. Java为什么是跨平台的

  • 主要依赖于JVM

  • 编写的Java源码编译后生成.class文件(也就是字节码文件)

  • JVM就是负责将字节码文件翻译成特定平台下的机器码然后运行

  • 也就是说,只要在不同平台上安装对应的JVM,就可以运行字节码文件从而运行编写的Java程序


4. JVM、JDK、JRE三者关系

  • JVM(Java虚拟机):是Java程序运行的环境,负责将Java字节码编译成机器码,并执行程序。JVM提供了内存管理、垃圾回收、安全性等功能,使Java程序具备跨平台性

  • JDK(Java开发工具包):是开发Java程序所需的工具集合,包含了JVM、编译器、调试器等开发工具,以及一系列的类库。JDK提供了开发、编译、调试和运行Java程序所需的全部工具和环境

  • JRE(Java运行时环境):是Java程序运行所需的最小环境,包含了JVM和一组Java类库,用于支持Java程序执行。JRE不含开发工具,只提供Java程序运行时所需的运行环境


5. 编译型语言和解释型语言的区别

  • 编译型语言:在程序执行之前,整个源代码会被编译成机器码或者字节码,生成可执行文件。执行时直接运行编译后的代码,速度快,但跨平台性较差

  • 解释型语言:在程序执行时,逐行解释执行源代码,不生成独立的可执行文件。通常由解释器动态解释并执行代码,跨平台性好但执行速度较慢

  • 典型的编译型语言如C、C++,典型的解释型语言如Python、JavaScript


6. 值传递和引用传递的区别

  • 在Java中参数传递只有一种方式就是值传递,但是根据传递的参数类型(基本类型或引用类型)会表现出不同的行为

  • 对于基本类型,传递的是值的副本,在方法内修改不会影响原来的变量

  • 对于引用类型,传递的是对象内存地址的副本。也就是说在方法内修改对象的属性会影响原来的对象,因为引用指向同一个对象。但在方法内让引用指向一个新对象,不会影响原来的变量

二、数据类型

1. 基本数据类型

整数类型

  • byte:1字节

  • short:2字节

  • int:4字节

  • long:8字节

浮点类型

  • float:4字节

  • double:8字节

字符类型

  • char:2字节

位数等于字节数×8


2. 数据类型转换方式

自动类型转换(隐式转换)

当目标类型范围大于源类型时,Java会自动将源类型转换为目标类型,不需要显式的类型转换。比如int → long,float → double。

强制类型转换(显式转换)

当目标类型范围小于源类型范围时,需要使用强制类型转换将源类型转换为目标类型,可能导致数据丢失或溢出。比如long → int,double → int。

字符串转换

将字符串转换为整型或浮点型,比如Integer.parseInt()、Double.parseDouble()。

数值之间的转换

通过类型的包装类可以实现转换,比如整型转换为字符型,字符型转换为整型等。


3. 类型互转会出现什么问题?

  • 大范围类型转换为小范围类型时会出现数据溢出或者精度损失

  • 数据溢出:目标类型无法容纳原数据就会数据溢出

  • 精度损失:浮点数类型转换会出现精度损失

  • 父类转换为子类(向下转型)时会出现问题,解决方式是用instanceof检查


4. 为什么用BigDecimal不用double?

double会出现精度损失的问题,double执行的是二进制浮点运算,二进制有些情况下不能准确地表示一个小数,而BigDecimal是精确计算。


5. 装箱和拆箱是什么?

自动装箱是程序需要一个包装类对象时,如果传入的是一个基本类型的值,编译器会自动将这个基本类型值转换为对应的包装类对象。

自动拆箱是程序需要一个基本数据类型的值时,如果传入的是一个包装类对象,编译器会自动将这个包装类对象转换为对应的基本数据类型值。

弊端

  1. 包装类对象为null时拆箱会报错

  2. 循环时拆箱或者装箱会影响程序性能


6. Java中为什么会有包装类?

包装类是对应基本数据类型的引用类型。

泛型只能用引用类型,因此要在泛型中用到int就必须使用Integer包装类。转换时,把int转换为字符串需要先把它转换为Integer再转换为字符串类型。集合也只能存储对象,不能存储基本数据类型。

但是基本类型的读写效率和存储效率要比包装类高效。


7. Integer缓存(128陷阱)

Java的Integer类内部实现了一个静态缓存池,用于存储特定范围内的整数值对应的Integer对象,这个范围是-128到127。数据在这个范围时不会每次都生成新的对象实例,而是直接复用缓存的现有对象,直接从内存中取出,不需要新建一个对象。因此在-128到127范围内的Integer对象比较是相等的,超出就是不相等的。

三、面向对象

1. 怎么理解面向对象?简单说说封装、继承、多态

面向对象是一种编程范式,它是将现实世界中的事务抽象为对象,对象具有属性和方法。面向对象编程的设计思想是以对象为中心,通过对象之间的交互来完成程序的功能,具有灵活性和拓展性。

封装:是指将对象的属性和方法结合在一起,对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。封装的目的是增强安全性和简化编程,使得对象更独立。

继承:继承是一种可以使得子类共享父类数据结构和方法的机制,是代码复用的重要手段。通过继承可以建立类与类之间的层次关系,使得结构更加清晰。

多态:是指允许不同类的对象对同一消息作出响应,即同一个接口使用不同的实例而执行不同操作。可以分为编译时多态(重载)和运行时多态(重写),它使得程序具有良好的灵活性和拓展性。


2. 多态体现在哪几个方面?

  1. 重载

  2. 重写

  3. 接口:类实现接口需要实现接口中的方法,多个类可以实现同一个接口

  4. 抽象类:抽象类的子类需要实现父类中的抽象方法

  5. 向上转型和向下转型


3. 面向对象的设计原则你知道有哪些吗?

面向对象编程的六大原则:

  • 单一职责原则

  • 开放封闭原则

  • 里氏替换原则

  • 接口隔离原则

  • 依赖倒置原则

  • 最少知识原则


4. 抽象类和普通类区别?

  1. 实例化:普通类可以实例化对象,抽象类不能被实例化,只能被继承

  2. 方法实现:普通类中的方法可以有具体实现,抽象类方法可以有实现可以没有实现

  3. 继承:一个类可以继承一个普通类,继承多个接口,而一个类只能继承一个抽象类

  4. 实现限制:普通类可以被其他类继承和使用,而抽象类一般用于作为基类,被其他类继承和扩展使用


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

实现方式 :实现接口关键字为implements,继承抽象类关键字为extends,一个类可以实现多个接口但只能继承一个抽象类。

方法方式 :接口只有定义,没有方法的实现,Java 1.8可以定义default方法体,抽象类可以有定义与实现。

访问修饰符

  • 接口成员变量默认为public static final,必须赋初值,不能被修改

  • 接口中的抽象方法默认是public abstract

  • 从Java 8开始接口可以定义defaultstatic方法,并且可以实现

  • Java 9还可以定义private方法

  • 抽象类中成员变量默认为default访问权限,可在子类中被重新定义,也可被重新赋值

  • 抽象方法被abstract修饰

变量:抽象类可以包含实例变量和静态变量,接口只能包含常量。


6. 接口里面可以定义哪些方法?

  1. 抽象方法 :默认是public abstract修饰,可以省略

  2. 默认方法default修饰,在Java 8引入,允许修饰的方法提供具体实现

  3. 静态方法static修饰,Java 8引入,通过接口名调用,不需要重写

  4. 私有方法:Java 9引入,不能被实现类访问,只能在接口内部使用


7. 解释Java中的静态变量和静态方法

静态变量

  • 静态变量属于类本身而不是某个实例

  • 共享性:所有该类的实例共享同一个静态变量,如果一个实例改变了静态变量的值,其他实例也会看到这个更改

  • 初始化:静态变量在类被加载时初始化,只会对其进行一次分配内存

  • 访问方式:静态变量可以通过类名访问也可以通过实例访问

静态方法

  • 静态方法属于类本身而不是某个实例

  • 无实例依赖:静态方法可以在没有创建类实例的情况下调用,对于静态方法来说,不能直接访问非静态成员变量或方法

  • 访问静态成员:静态方法可以直接调用其他静态变量或静态方法

  • 多态性:静态方法不支持重写

四.关键字

1. final关键字

修饰类:该类不能被继承

修饰方法:该方法不能被重写

修饰变量

  • 修饰基本数据类型变量,则该变量被赋值后不能更改

  • 修饰引用类型变量,则该变量不能再指向其他对象,但是该对象属性的值是可以修改的

2. static关键字

修饰变量:静态变量

修饰方法:静态方法

修饰代码块:静态代码块,在类加载时执行,且只执行一次,用于初始化静态变量或执行类级别的预处理操作

修饰内部类:静态内部类不依赖于外部类的实例,可以独立存在,不能直接访问外部类的非静态成员

五、深拷贝和浅拷贝

1. 深拷贝和浅拷贝的区别?

浅拷贝

  • 创建一个新的对象

  • 将原对象的字段值复制到新对象中

  • 但如果原对象内部有引用类型的字段,只是将引用复制到新对象中

  • 两个对象指向的是同一个引用对象

深拷贝

  • 会递归复制对象内部所有引用类型的字段

  • 生成一个全新的对象以及其内部的所有对象

2. 实现深拷贝的三种方式是什么?

  1. 实现Cloneable接口并重写clone()方法

  2. 使用序列化和反序列化

  3. 手动递归复制

相关推荐
前端摸鱼匠2 小时前
【AI大模型春招面试题27】字节对编码(BPE)的分词过程?如何处理未登录词(OOV)?
人工智能·ai·面试·大模型·求职招聘
itzixiao2 小时前
L1-054 福到了(15 分)[java][python]
java·python·算法
lwx572802 小时前
MySQL 性能调优完全指南:从硬件到 SQL,一篇吃透
后端
威迪斯特2 小时前
GoFr框架:加速微服务开发的Go语言利器
开发语言·后端·微服务·架构·golang·命令行框架·gofr框架
Flittly2 小时前
【SpringSecurity新手村系列】(7)基于资源权限码(Authority)的接口权限控制实战
java·spring boot·安全
ECT-OS-JiuHuaShan2 小时前
哲学的本质,是递归因果
java·开发语言·人工智能·科技·算法·机器学习·数学建模
倾听一世,繁花盛开2 小时前
Java语言程序设计——篇十三(1)
java·开发语言·ide·eclipse
大腕先生2 小时前
通用分页超详细介绍(附带源代码解析&页面展示效果)
xml·java·linux·服务器·开发语言·前端·idea
A_aspectJ3 小时前
如何抓住Java开发岗的市场红利?从需求端反推学习路径
java·开发语言·职场和发展