java 面试题--基础

文章目录

  • 基础
    • java SE 、 EE 、 ME 的区别
    • jdk 和 jre 区别?
    • java 的日志级别
    • 基本数据类型
  • 特性
    • 关键字
      • final
      • abstract
      • super
      • switch
      • for
      • try catch
    • 接口和抽象类的区别
      • 接口
      • 抽象类
      • 适用场景
    • 类的加载循序
      • 静态代码块
    • 传参问题
    • 访问修饰符
    • 运算符
  • 反射
    • java 里的应用
    • 为什么反射的性能不好
    • 类的加载过程
    • 获取属性
    • 获取注解
  • 异常
    • 异常的分类
    • throw 和 throws 的区别
    • 异常处理示例
    • try 里有 return,finally 还执行吗?

基础

java SE 、 EE 、 ME 的区别

SE(Standard Edition):即Java平台标准版,是Java技术的核心和基础。它包含了Java语言的所有基本功能和API,主要用于开发和部署桌面应用程序、服务器应用程序和嵌入式设备应用程序

EE(Enterprise Edition):即Java平台企业版,是Java SE的一个扩展,用于开发和部署企业级应用程序。它提供了一组技术规范和API,用于构建复杂的分布式网络应用程序。

ME(Micro Edition):即Java平台微型版,是专门为嵌入式设备和移动设备设计的Java版本。它提供了一个精简的Java API,可以在有限的资源和计算能力下运行。

jdk 和 jre 区别?

jdk:(最小开发环境)
1、jvm
2、java api 类库
3、java编程语言
4、一些系列辅助工具,javac

jre:(最小运行环境)
1、jvm
2、java api

java 的日志级别

日志级别说明
debug程序调试bug时使用
info程序正常运行时使用
warning程序未按预期运行时使用,但并不是错误,如:用户登录密码错误
error程序出错误时使用,如:IO操作失败
critical特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使用

基本数据类型

数据类型字节数位数(bit)范围注意
byte (字节)18
char216可存一个汉字
short216-32768~32767
int432-2147483648 ~ 2147483647
long864最大存 19 位二进制数l 或 L 结尾
float432f 或 F 结尾
double864d 或 D 结尾
boolean432

注意:boolean 类型是4个字节,但这是在 .class 文件中表示时的情况。实际上,在虚拟机中,boolean类型的存储可能会根据具体的实现而有所不同。在某些情况下,boolean 可能只占用1/8个字节(因为一个 boolean值可以用1位来表示,但考虑到计算机存储的基本单位是字节,所以通常会用更多的空间来存储)
如果 boolean 类型被声明为 static final 并且被初始化,它可能会被存储在类的常量池中,这时它可能会占用4个字节的空间(因为常量池中的整数类型通常是以4个字节的形式存储的)

  1. bit(比特): 一位二机制数
  2. byte(字节):存储的基本单位, = 8 bit , 之后就是 KB,MB,GB,TB
  3. 十六进制的数字,以 0X 或者 0x 开头
  4. 八进制的数字,以 0 开头
  5. Mybatis plus 生成的雪花 id 是19 位,就是用 long 类型接收的

特性


关键字

transient : 带有它的属性,不会被序列化
native :调用本地方法 (c,c++)
volatile :多个线程资源共享
static:静态成员变量(在data seg里存储),不在堆内存中了


final

它可以保证变量的可见性

  1. 修饰的变量不能被改变
  2. 修饰的方法不能被重写
  3. 修饰的类不能被继承

abstract

  • 含有抽象方法的必须是抽象类,抽象的方法是必须被重写的
  • 抽象类不能被实例化
  • 抽象方法在抽象类中只需声明,不能实现

super

  • super可以用来引用直接父类的实例变量。
  • super可以用来调用直接父类方法。
  • super可以用于调用直接父类构造函数。

switch

它支持的数据类型:byte、short、int、char、String、enum

它为什么不支持 long?

switch 语句在 Java 中不支持 long 类型的主要原因是与 switch 语句的设计初衷和性能考虑有关。
switch 语句最初是为了提供一种在编译时能够进行优化以支持快速查找的语句结构。对于整型(byte、short、char、int)和枚举类型(enum),编译器可以生成一个查找表(通常是一个跳转表或者散列表),这样可以快速跳转到对应的 case 语句,从而提高执行效率。
然而,对于 long 类型,由于它占用的内存空间是 int 类型的两倍(64位 vs 32位),如果 switch 支持 long 类型,那么查找表的大小也会相应地增大,这会导致以下问题:

  1. 内存占用:查找表会占用更多的内存空间,这在内存受限的环境(如嵌入式系统)中可能是一个问题。
  2. 性能下降:更大的查找表意味着更长的查找时间,这可能会降低 switch 语句的执行效率。
  3. 编译器实现复杂度:为了支持 long 类型的 switch 语句,编译器需要实现更复杂的查找算法和数据结构,这会增加编译器的实现难度和复杂度。

for

for-i、 for、 foreach 的区别与联系?

List<String> list = Arrays.asList("1", "2", "3");// [for-i]
// 最原始的,但是操作性很强,合适知道当前索引或需要在循环中控制迭代次数的场景
// 遍历的时候,可以通过索引来修改集合
for (int i = 0; i < list.size(); i++) {
}// [for]
// java 5 引入的,更简洁
// 遍历的时候,不能修改,否则会发生 `ConcurrentModificationException`
for (String s : list) {
}// [foreach]
// 本质就是 for 循环
// 上边两个 continue 退出本次循环 ,这个 return 退出本次循环
list.forEach(s -> {
});

break 和 continue 的区别和联系?
break:中止循环
continue:跳出本次循环

都可以用于:for 、 while 、 do-while 循环

循环起别名

// 起名字:此循环的名字就叫eric
eric:forint I = 0;I < 1 ; i++// 就会跳出这个循环
break eric;

try catch

为什么重写 equals 的时候,需要重写 hashcode?
潜规则:
1、两个对象相等,它们的 hashCode 一定相等
2、object 的 hashCode 方法是通过哈希算法对对象内存地址进行计算获取其 hash 值
但是你只重写了 equals ,没有重写 hashCode,就会出现两个对象相等,但是 hashCode 不相等的情况


接口和抽象类的区别

接口

一个完全抽象的类,不能包含任何方法实现。接口定义了一组方法,任何实现该接口的类都必须提供这些方法的具体实现。接口用于定义类的能力和行为,而不涉及具体的实现细节。

  1. 接口的属性都是常量 public static final (必须有初始值)
  2. 接口的方法都是抽象方法 public static (不能实现)
  3. 方法和字段不可以用反问修饰符号
  4. 没有构造函数
  5. 一个接口可以继承多个接口
  6. java 8 以后,可以包含默认方法(default)和静态方法

抽象类

抽象类是一种不能实例化的类,可以包含抽象方法和具体方法。抽象类用于捕捉子类的公共行为,并允许子类共享这些行为。抽象类通常用于表示“is-a”关系

  1. 可以拥有实例变量
  2. 方法可以是抽象方法,也可以是非抽象方法
  3. 方法和字段可用反问修饰符号
  4. 可以有构造函数
  5. 单继承
  6. 可以包含静态方法,不能包含默认方法

适用场景


使用接口:
  • 需要定义一组无关的行为,而多个类可以实现这些行为。
  • 需要支持多重继承。
  • 定义契约或能力,而不涉及实现细节。

使用抽象类:
  • 需要共享代码和行为(具体方法)在多个相关类之间。
  • 需要定义类的基本属性和行为,而允许子类扩展和覆盖这些行为。
  • 需要使用构造器来初始化公共字段。

类的加载循序

类文件加载到内存中
执行类中的static代码块--对类进行初始化
堆内存开辟空间--分配内存地址
建立对象属性--初始化默认值
给属性赋值--显式初始化
对象构造代码块初始化
对象构造函数初始化
将对象的内存地址给栈内存中的变量
  1. 父类的类初始化(clinit):
    a. 静态变量
    b. 静态代码块
    (它俩顺序执行)

  2. 对象初始化(init):
    a. 父类构造方法
    b. 非静态变量
    c. 子类的非静态代码块
    d. 子类的无参构造
    (b c 按顺序执行)

静态代码块

静态代码块,没有名字,类加载的时候执行,只执行一次,优先于主函数。

静态代码块什么时候进入内存?
1.创建该类对象的实例(对象)
2. 调用该类的静态方法

注意:

  • 优先级:静态代码块(给类初始化的) > 构造代码块(给对象初始化的) > 构造函数(给对应对象初始化的)
  • 子类被创建的时候,先走父类的构造方法
public class ClassLoadTest {// 1--静态代码块static {System.out.println("ClassLoadTest static block");}// 2--构造代码块{System.out.println("ClassLoadTest block");}// 3--构造函数public ClassLoadTest() {System.out.println("ClassLoadTest constructor");}// 4--静态方法public static void show(){System.out.println("ClassLoadTest show");}
}

传参问题

java 传参数,都是值传递:
1、基本数据类型,传值的
2、引用类型,则是传递是引用的内存地址值

public static void main(String[] args){String a = new String ("123");changeString(a);System.out.println(a);
} public static void changeString(String s){s = new String("456");
} // 输出 123,s 指向了新的 456, 但是 a 还是指向 123 public static void main(String[] args){Person p = new Person();p.setId(0L);changePerson(p);System.out.println(p.getId());
} public static void changePerson(Person p){p.setId(p.getId() + 10);
}  // 输出 10

访问修饰符

修饰符类内部同一个包子类任何地方
private
default
protected
public

运算符

运算符描述
&按位与。当两位同时为1时才返回1。
按位或。只要有一位为1即可返回1。
~按位非。单目运算符,将操作数的每个位(包括符号位)全部取反。
^按位异或。当两位相同时返回0,不同时返回1。
<<左移运算符。
>>右移运算符。
>>>无符号右移运算符。

一般来说,位运算符只能操作整数类型的变量或值


优先级

优先级运算符结合性
最高. () {} ;从左到右
++ -- ~ ! (data type)从右到左
* / %从左到右
+ -从左到右
<< >> >>>从左到右
< > <= >= instanceof从左到右
== !=从左到右
&从左到右
^从左到右
从左到右
&&从左到右
|| 从左到右
? :从右到左
= *= /= %= += -= <<= >>=从右到左
最低>>>= &= ^= |=从右到左

反射

反射的本质,推迟对象实例化到对象运行中,而不是编译阶段;也就是说,你实例化的类可以在编译的时候,根本就不存在。
它是一种动态类加载(new的方式加载类,是一种静态类加载的方式)

java 里的应用

  1. 对象实例化
  2. spring ioc
  3. 动态代理 aop

为什么反射的性能不好

它属于解释操作(告诉 jvm 要做些什么),会比 jvm 直接操作慢一些

类的加载过程

在这里插入图片描述

获取属性

// 获取所有属性包括私有
Field[] fields =  person.getClass().getDeclaredFields();// 获取属性名
field.getName()// 私有属性获取值
field.setAccessible(true);// 获取属性值
field.get(person);

获取注解

// 自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldCanEmpty {
}// 获取某个字段是否包含此注解
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {if (annotation instanceof FieldCanEmpty) {continue fieldFor;}
}

异常

异常的分类

一、被检查的异常 (Checked Exceptions)
受检异常是在编译时由编译器检查的异常,必须在代码中显式处理,否则编译器会报错。
这类异常通常是由于外部原因(如I/O错误、数据库访问错误等)引起的。
此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。


常见的被检查的异常 :

  1. IOException:输入/输出操作失败时抛出,例如文件未找到 (FileNotFoundException)。
  2. SQLException:数据库操作失败时抛出。
  3. ClassNotFoundException:尝试加载类时类不存在时抛出。
  4. InterruptedException:线程在等待、睡眠或其他活动时被中断时抛出

二、运行时异常 (Runtime Exceptions)
它是Exception中特殊的异常子类,它方法内部,方法名可以不去标识。
运行时异常是在程序运行期间可能发生的异常,不是编译器强制要求处理的异常。这类异常通常是由编程错误(如逻辑错误或不正确的API使用)引起的。


常见的运行时异常:

  1. NullPointerException:当应用程序尝试在需要对象的地方使用 null 时抛出。
  2. ArrayIndexOutOfBoundsException:数组访问越界时抛出。
  3. ArithmeticException:算术运算出错时抛出,例如除以零。
  4. ClassCastException:试图将对象强制转换为不兼容的类型时抛出。
  5. IllegalArgumentException:方法接收到非法参数时抛出

三、错误 (Errors)
错误是严重的运行时异常,表示应用程序的运行环境出现了问题。一般来说,错误是由Java虚拟机抛出的,程序不应该也无法通常地去捕获和处理这些错误。


常见的错误:

  1. StackOverflowError:方法调用栈溢出。
  2. OutOfMemoryError:JVM内存不足。
  3. VirtualMachineError:虚拟机操作出错。
  4. NoClassDefFoundError:类在编译时存在但在运行时找不到

throw 和 throws 的区别

throw:抛出的是一个异常类对象
throws:作为方法声明和签名的一部分,方法会对应抛出


异常处理示例

class DivDemo{// 在功能上通过throws的关键字声明该功能可能出现的问题int div(int a,int b) throws Exception{return a/b;}
}
class Start{// 如果方法内部不捕捉,也可以将异常抛出 throws Exceptionpublic static void main(String[] args){DivDemo dd = new DivDemo();// 捕捉调用该功能时可能会出现的问题try{dd.div(4,0);System.out.println();}catch (Exception e){// 异常信息System.out.println(e.getMessage());// 异常名:异常信息System.out.println(e.toString());// 异常名,异常信息,异常出现的位置(堆栈跟踪信息)// jvm 默认的异常处理机制,及时调用的此方法e.printStackTrace();}} 
}  

try 里有 return,finally 还执行吗?


执行,并且 finally 的执行早于 try 里面的 return
  1. 是否出现异常,finally块中代码都会执行;
  2. 当 try 和 catch 中有 return 时,finally 仍然会执行;
  3. finally 是在 return 后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保
    存起来,管finally中的代码怎么样,返回的值都不会改变,扔然是之前保存的值),所以函数返回值是
    在finally执行前确定的;
  4. finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
public static void main(String[] args) {System.out.println(test());
}public static int test() {int a = 1;try {a = a + 1;return a;} finally {a = a + 1;System.out.println("finally a = " + a);}
}

在这里插入图片描述
a=2 会被暂存起来,然后 进行 finall 里的计算


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》Chapter 10插图

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》 Chapter 10插图

YOLOv8旋转目标检测Yolov8n-obb详细实例+rolabelimg

一、Yolov8环境搭建 首先创建虚拟环境下载安装&#xff08;其实就是yolov8的环境&#xff09;再大概写一下步骤&#xff0c;没有想详细的看本人另外一篇&#xff1a;YOLOv8环境搭建_yolov8环境配置-CSDN博客 1、下载安装anaconda 2、创建虚拟环境 conda create -n my_yolov8…

【Gradio】Chatbot | 如何使用 Gradio Blocks 创建自定义聊天机器人

简介 重要提示&#xff1a;如果您刚开始接触&#xff0c;我们建议使用 gr.ChatInterface 来创建聊天机器人——它是一个高级抽象&#xff0c;使得可以快速创建漂亮的聊天机器人应用程序&#xff0c;往往只需一行代码。在这里了解更多信息。 本教程将展示如何使用 Gradio 的低级…

vue3中实现3D地图——three.js

需求点 地图区域大小随着父盒子大小变动&#xff0c;窗口缩放自动适配每个区域显示不同颜色和高度&#xff0c;描边每个区域显示名字label和icon点击区域改变其透明度&#xff0c;并且弹窗显示信息窗口点击点也可以可以自由放大缩小&#xff0c;360度旋转 包 npm install d3^…

背景渐变动画登录页

b站视频演示效果: 效果图: 完整代码: <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>背景…

大模型商业化:李开复向左,张亚勤向右

文&#xff5c;白 鸽 “零一万物坚决做To C&#xff0c;不做赔钱的To B&#xff0c;要做能赚钱的To B。”2024年6月14日&#xff0c;在智源大会上&#xff0c;零一万物创始人李开复如此坚定地说道。 而与之相对&#xff0c;中国工程院院士、清华大学智能产业研究院&…

2024/06/18--代码随想录算法8/17| 股票问题

121.买卖股票的最佳时机 力扣链接 动规五部曲 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][0] 表示第i天持有股票所得最多现金,dp[i][1] 表示第i天不持有股票所得最多现金确定递推公式 dp[i][0] max(dp[i-1][0], -price[i]) dp[i][1]max(dp[i-1][1], …

QTimeEdit、QDateEdit、QDateTimeEdit、QCalendarWidget

实验 QTime和字符串相互转换 QDate和字符串相互转换 QDateTime和字符串相互转换 QCalendarWidget使用 year&#xff0c;month&#xff0c;day&#xff0c;minute&#xff0c;second&#xff0c;msec&#xff0c;dayOfWeek, dayto方法/属性的使用 布局 datetimeexample.cpp #inc…

智慧之选:Vatee万腾平台,引领未来的创新引擎

在数字化浪潮席卷全球的今天&#xff0c;我们身处一个信息爆炸、技术革新的时代。在这样的大背景下&#xff0c;选择一个能够引领我们走向未来的平台显得尤为重要。而Vatee万腾平台&#xff0c;正是这样一个不容错过的智慧之选。 Vatee万腾平台&#xff0c;作为一个集创新、科技…

PostgreSQL源码分析——口令认证

认证机制 对于数据库系统来说&#xff0c;其作为服务端&#xff0c;接受来自客户端的请求。对此&#xff0c;必须有对客户端的认证机制&#xff0c;只有通过身份认证的客户端才可以访问数据库资源&#xff0c;防止非法用户连接数据库。PostgreSQL支持认证方法有很多&#xff1…

Stable Diffusion 3 Medium 正式开源

Stable Diffusion 3 Medium 正式开源 Stability AI宣布Stable Diffusion 3 Medium现已开源&#xff0c;这是最新的文本生成图像AI模型&#xff0c;被官方声称为“迄今为止最先进的开源模型”&#xff0c;其性能超过了Midjourney 6。 这款Stable Diffusion 3 Medium模型拥有2…

【SpringBoot项目常见细化错误】(保姆级教程)Result Maps collection already contains value for

SpringBoot项目常见错误 1.当Mybatis报错 Result Maps collection already contains value for一、重复点击Mybatis-Generator导致配置文件重复生成XML二、正确配置Yml仔细检查有没有多了或者少了一个空格三、spring boot mybatis四、应该用resultMap来接收返回值&#xff0c;…

Blazor的SSR服务端渲染是不是交互式的

从.NET8开始&#xff0c;Blazor引入了SSR服务端渲染&#xff0c;归功于MVC和RazePage的沉淀&#xff0c;虽然来得晚&#xff0c;但一经发布&#xff0c;就将Blazor推向了新的高度。从今年开始&#xff0c;Youtube上关于Blazor的优质教学视频&#xff0c;以肉眼可见的速度在增加…

[保姆级教程]uniapp实现接口请求和请求方法二次封装

文章目录 新建文件配置方法发送请求使用 新建文件 现在src中新建一个api目录 新建index.js和request.js文件 配置方法发送请求 request.js中输入以下内容 const http {baseUrl: http://127.0.0.1:8000,request(config) {config beforeRequest(config)config.url this…

前端工具篇

在线工具 https://tool.lu/ 程序员工具箱 http://tool.pfan.cn/apitest 配色 https://webkul.github.io/coolhue/ 在线字符串和16进制互转 https://kw360.net/ox2str/ 代码美化截图 https://carbon.now.sh/?bgrgba 菜鸟工具 https://www.jyshare.com/ 文件格式转换 htt…

C++智能指针auto_ptr(有缺陷已废弃)

一、auto_ptr不能共享所有权 auto_ptr类没有拷贝构造函数。可以看出将Right对象的资源释放掉了。 在下面的操作中&#xff0c;ptr1的值给ptr2&#xff0c;那么此时ptr1的值将会为nullptr。在构造和赋值都发生了所有权的转移。调用函数的时候&#xff0c;接收参数的时候同样也会…

Rapidfuzz,一个高效的 Python 模糊匹配神器

目录 01初识 Rapidfuzz 什么是 Rapidfuzz? 为什么选择 Rapidfuzz? 安装 Rapidfuzz 配置 Rapidfuzz 02基本操作 简单比率计算 03高级功能 查找单个最佳匹配 查找多个最佳匹配 使用阈值优化性能 04实战案例…

IPython大师课:提升数据科学工作效率的终极工具

IPython是一个增强的Python交互式shell&#xff0c;它提供了丰富的功能和易用性改进&#xff0c;特别适合进行数据分析、科学计算和一般的Python开发。本文将全面介绍IPython的基本概念、使用方法、主要作用以及注意事项。 一、IPython简介 1. IPython的起源 IPython最初由Fe…

【Android】使用Binder(AIDL)实现利用自定义Bean进行的进程间通信(二)

项目前置 这是我之前写的关于Binder的一些知识点和使用基本数据类型在通信的文章&#xff0c;感兴趣的可以看一下: Binder&#xff08;一&#xff09;Binder的介绍和AIDL使用Binder的实例 项目目标 在两个APP之间进行数据传递&#xff0c;使用Android推荐的Binder通讯&#…

使用Flink接受kafka中的数据并对数据进行ETL

做这个开发是因为&#xff1a;在实际开发操作中&#xff0c;你的kafka主题中会有大量的数据但是需求并不需要所有数据&#xff0c;所有我们要对数据进行清洗&#xff0c;把需要的数据保存在flink流中&#xff0c;为下流的开发做好数据保障&#xff01; 首先创建工具类 再写一…