【巨人的肩膀】JAVA面试总结(一)

news/2024/4/26 11:40:15/文章来源:https://blog.csdn.net/Augenstern_QXL/article/details/129232897

💪

目录

  • 💪
    • 1、Java和C++的区别
    • 2、标识符和关键字的区别是什么
    • 3、continue、break和return的区别是什么
    • 4、成员变量和局部变量的区别
    • 5、静态变量有什么用
    • 6、字符型常量和字符串常量的区别
    • 7、类中都可以包含哪些成分
    • 8、static关键字
    • 9、super关键字
    • 10、Java继承的特点
    • 11、Java中有几种基本数据类型
    • 12、基本类型和包装类型的区别
    • 13、包装类型的缓存机制了解吗
    • 14、什么是自动装箱与自动拆箱
    • 15、如何解决浮点数运算的时候精度丢失
    • 16、对象的相等和对象引用相等的区别
    • 17、类的构造方法的作用是什么
    • 18、如果一个类没有声明构造方法,该程序能正确执行吗
    • 19、构造方法有哪些特点?是否可以被override
    • 20、字符串拼接用"+"还是StringBuilder
    • 21、String中的equals()和Object中的equals()
    • 22、字符串常量池了解过吗
    • 23、try-catch-finally如何使用
    • 24、finally 中的代码一定会执行吗
    • 25、如何使用try-with-resources代替try-catch-finally
    • 26、Java中是否可以重写一个private或者static方法
    • 27、Java中创建对象的几种方式
    • 28、抽象类和接口有什么区别
    • 29、语法问题
    • 30、Integer和int的区别
    • 31、final、finally、finalize的区别
    • 32、两个对象的 hashCode() 相同,则 equals()也一定为true吗
    • 33、为什么重写equals()就一定要重写 hashCode()方法
    • 34、&和&&的区别
    • 35、Java中的Math.round(-1.5)等于多少
    • 36、Java中的动态代理是什么?有哪些应用
    • 37、字节和字符的区别
    • 38、值传递和引用传递有什么区别
    • 39、BIO、NIO、AIO有什么区别
    • 40、访问修饰符public、private、protected以及不写时的区别
    • 41、final关键字的作用
    • 42、为什么局部内部类和匿名内部类只能访问final变量
    • 43、final、abstract关键字的关系
    • 44、接口和抽象类的区别

1、Java和C++的区别

Java 和 C++ 都是面向对象的语言,都支持封装、继承和多态,但是,它们还是有挺多不相同的地方:

  • Java 不提供指针来直接访问内存,程序内存更加安全
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
  • Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存。
  • C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载

2、标识符和关键字的区别是什么

  • 标识符就是一个名字。我们在写代码时,会为类、变量、方法取名字,这个名字就是标识符
  • 有一些标识符Java语言已经赋予了其特殊的含义,这些特殊的标识符就是关键字

3、continue、break和return的区别是什么

  • continue: 指跳出当前的这一次循环,继续下一次循环
  • break :指跳出整个循环体,继续执行循环下面的语句
  • return :用于跳出所在方法,结束该方法的运行

4、成员变量和局部变量的区别

  • 成员变量:作用范围是整个类,相当于C中的全局变量,定义在方法体和代码块之外,一般定义在类的声明之下;成员变量包括实例成员变量和静态成员变量(类变量);

  • 局部变量:类的方法中的变量,访问修饰符不能用于局部变量,声明在方法、构造方法或代码块中,在上分配,无默认值,必须初始化后才能使用;

  • 成员变量是属于对象的,可以被 public,private,static 等修饰符所修饰。局部变量是在代码块或者在方法中定义的变量或者是方法的参数,局部变量不能被 public,private,static 等修饰。但是成员变量和局部变量都能被 final 关键字所修饰

  • 若成员变量使用 static 修饰,那么这个成员变量属于类。如果没有用 static 修饰,那么这个成员变量是属于实例的。实例(对象)存在于堆内存,局部变量则存在于栈内存

  • 成员变量属于对象,随着对象的创建而存在。而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。

  • 成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值。但是如果被 final 关键字修饰必须显式的赋值,而局部变量不会自动赋值。

5、静态变量有什么用

  • 静态变量可以被类的所有实例共享。无论一个类创建了多少个对象,它们都共享同一份静态变量。

    • 静态变量:static 修饰
    • 静态常量:static final 修饰
  • 通常情况下,静态变量会被 final 关键字修饰成为常量

final 修饰 StringBuffer 后 还可以 append 吗?

可以。final 修饰的是一个引用变量,那么这个引用始终只能指向这个对象,但是这个对象内部的属性是可以变化的。

6、字符型常量和字符串常量的区别

  • 形式:字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符。
  • 含义:字符常量相当于一个整型值( ASCII 值),可以参加表达式运算,字符串常量代表一个地址值(该字符串在内存中存放位置)。
  • 占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节。(char 在 Java 中占两个字节)

7、类中都可以包含哪些成分

  1. 成员变量:包括实例成员变量、静态成员变量
  2. 成员方法:包括实例方法,静态方法,抽象方法,getter setter 方法
  3. 构造器(构造函数):
    • 默认无参构造器:一个类默认会自带一个无参构造器,即使不写它也存在,但是如果一个类它写了一个构造器,那么默认的无参构造器就被覆盖了!
    • 有参构造器
  4. 代码块
  5. 内部类

8、static关键字

按照有无static修饰,成员变量和方法可以分为

  1. 成员变量
    1. 静态成员变量(类变量):有static修饰的成员变量称为静态成员变量,也叫类变量,属于类本身,直接用类名.静态成员变量访问即可
    2. 实例成员变量:无static修饰的成员变量称为实例成员变量,属于类的每个对象的,必须用对象.实例成员变量来访问
  2. 成员方法
    1. 静态方法:有static修饰的成员方法称为静态方法,也叫类方法,属于类本身的,直接用==类名.静态方法()==即可
    2. 实例方法:无static修饰的成员方法称为实例方法,属于类的每个对象的,必须用==对象.实例方法()==来访问

注意:静态方法和私有方法不可以被重写

  public static String staticField = "静态变量";static {    System.out.println("静态代码块");   ---- 1}public String field = "实例变量";       ---- 2{System.out.println("实例代码块");  ----3}// 最后才是构造函数的初始化public InitialOrderTest() {System.out.println("构造函数");    ----4}

初始化顺序:静态变量和静态代码块优先于实例变量和实例代码块,静态变量和静态代码块的初始化顺序取决于它们在代码中的顺序

存在继承的情况下,初始化顺序为:

  1. 父类(静态变量、静态语句块)
  2. 子类(静态变量、静态语句块)
  3. 父类(实例变量、普通语句块)
  4. 父类(构造函数)
  5. 子类(实例变量、普通语句块)
  6. 子类(构造函数)

9、super关键字

  1. 访问父类的构造函数:可以使用 super() 函数访问父类的构造函数,从而委托父类完成一些初始化的工作。
  2. 访问父类的成员:如果子类重写了父类的某个方法,可以通过使用 super 关键字来引用父类的方法实现
  3. this 和 super 不能同时出现在一个构造函数里面,因为 this 必然会调用其它的构造函数,其它的构造函数必然也会有 super 语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

10、Java继承的特点

  1. 单继承: 一个类只能继承一个直接父类
  2. 多层继承:一个类可以间接继承多个父类(C继承B,B继承A)
  3. 一个类可以有多个子类(C继承B,D也继承B,B就有了C,D两个子类)
  4. 一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类

为什么继承后子类的构造器会调用父类的构造器?

  • 子类的构造器第一行默认有super()调用父类的无参构造器,写不写都存在

11、Java中有几种基本数据类型

Java 中有 8 种基本数据类型,分别为:

  • 6种数字类型:
    • 4种整数型:byte、short、int、long
    • 2种浮点型:float、double
  • 1种字符类型:char
  • 1种布尔型:boolean

这 8 种基本数据类型的默认值以及所占空间的大小如下:

基本类型位数字节默认值
byte810
short1620
int3240
long6480
char162
float3240.0
double6480.0
boolean1false
  1. Java 里使用 long 类型的数据一定要在数值后面加上 L,否则将作为整型解析。
  2. char a = ‘h’ ,char 是单引号, String a = “hello” String 是双引号

12、基本类型和包装类型的区别

  • 成员变量包装类型不赋值就是 null ,而基本类型有默认值且不是 null
  • 包装类型可用于泛型,而基本类型不可以
  • 基本类型比包装类型更高效。基本类型在中直接存储的具体数值,而包装类型则存储的是中的引用。 很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间。

int 和 Integer 有什么区别?

  • Integer是int的包装类;int是基本数据类型
  • Integer变量必须实例化后才能使用;int变量不需要
  • Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值
  • Integer的默认值是null;int的默认值是0

两个 new 生成的 Integer 变量的对比:

由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个对象,其内存地址不同)

Integer i = new Integer(10000);
Integer j = new Integer(10000);
System.out.print(i == j); //false

13、包装类型的缓存机制了解吗

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。

Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False

如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。

Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出 trueFloat i11 = 333f;
Float i22 = 333f;
System.out.println(i11 == i22);// 输出 falseDouble i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false

14、什么是自动装箱与自动拆箱

  • 装箱:将基本类型用它们对应的引用类型包装起来。装箱就是调用了包装类的 ValueOf() 方法,
  • 拆箱:将包装类型转换为基本数据类型,拆箱就是调用了xxxValue() 方法。
Integer i = 10;  //装箱
// 等价于 Integer i = Integer.valueOf(10)
int n = i;   //拆箱
// 等价于int n = i.intValue()Integer i1 = 40;
// Integer i1=40 这一行代码会发生装箱,也就是说这行代码等价于Integer i1=Integer.valueOf(40),因此 i1 直接使用的是缓存中的对象
Integer i2 = new Integer(40);
// Integer i2 = new Integer(40)会直接创建新的对象
System.out.println(i1==i2); // false

所有整型包装类对象之间值的比较,全部使用 equals 方法比较

  • 对于 Integer var = ? 在 -128至127之间的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间外的所有数据,推荐使用 equals 方法进行判断。

15、如何解决浮点数运算的时候精度丢失

首先为什么会出现浮点数运算的时候精度丢失问题呢?这个和计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的,而且计算机在表示一个数字时,宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况。这也就是解释了为什么浮点数没有办法用二进制精确表示。

如何解决呢?BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 BigDecimal 来做的

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */

16、对象的相等和对象引用相等的区别

new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向 0 个或 1 个对象,一个对象可以有 n 个引用指向它。

  • 对象的相等一般比较的是内存中存放的内容是否相等
  • 引用相等一般比较的是他们指向的内存地址是否相等

17、类的构造方法的作用是什么

构造方法是一种特殊的方法,主要作用是完成对象的初始化工作。构造方法的特性是:

  • 名字和类名相同
  • 没有返回值,但是不能用 void 声明构造函数
  • 生成类的对象时自动执行,无需调用

在Java中定义一个不做事且没有参数的构造方法有什么作用?

  • Java 程序在执行子类的构造方法之前,如果没有用 super() 来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”
  • 因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super() 来调用父类中特定的构造方法,则编译时将发生错误,因为 Java 程序在父类中找不到没有参数的构造方法可供执行。解决办法是:在父类里加上一个不做事且没有参数的构造方法。

18、如果一个类没有声明构造方法,该程序能正确执行吗

如果一个类没有声明构造方法,也可以执行!因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。如果我们自己添加了类的构造方法(无论是否有参),Java 就不会再添加默认的无参数的构造方法了,我们一直在不知不觉地使用构造方法,这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)。

如果我们重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑

19、构造方法有哪些特点?是否可以被override

构造方法特点如下:

  • 名字与类名相同。
  • 没有返回值,但不能用 void 声明构造函数。
  • 生成类的对象时自动执行,无需调用。
public class Student {// 两个成员变量 私有private String name;private int age;// 无参构造器public Student(){}// 有参数构造器public Student(String name,int age){this.name = name;this.age = age;}
}

构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。

20、字符串拼接用"+"还是StringBuilder

String str1 = "he";
String str2 = "llo";
String str3 = "world";
String str4 = str1 + str2 + str3;

字符串对象通过“+”的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象 。

Java用作字符串拼接有哪些方法?

  1. 加号拼接

  2. StringBuilder 的 append

  3. StringBuffer 的 append

  4. String 的 concat

在拼接少数字符串(不超过4个)的时候,concat效率是最高的

多个字符串拼接的时候,StringBuilder/StringBuffer的效率是碾压的。

21、String中的equals()和Object中的equals()

String 中的 equals 方法是被重写过的,比较的是 String 字符串的值是否相等。 Objectequals 方法是比较的对象的内存地址。

22、字符串常量池了解过吗

字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建

// 在堆中创建字符串对象”ab“
// 将字符串对象”ab“的引用保存在字符串常量池中
String aa = "ab";
// 直接返回字符串常量池中字符串对象”ab“的引用
String bb = "ab";
System.out.println(aa==bb);// true

String s1 = new String(“abc”) 这句话创建了几个字符串对象?

  • 会创建 1 或 2 个字符串对象
  1. 如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个字符串对象“abc”

    String s1 = new String("abc");
    
  2. 如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”

    // 字符串常量池中已存在字符串对象“abc”的引用
    String s1 = "abc";
    // 下面这段代码只会在堆中创建 1 个字符串对象“abc”
    String s2 = new String("abc");
    

23、try-catch-finally如何使用

  • try块 : 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
  • catch块 : 用于处理 try 捕获到的异常。
  • finally 块 : 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行

注意:不要在 finally 语句块中使用 return,当 try 语句 和 finally 语句都有 return 语句时, try 语句块中的 return 语句会被忽略。

24、finally 中的代码一定会执行吗

不一定的!在某些情况下,finally 中的代码不会被执行。比如说 finally 之前虚拟机被终止运行的话,finally 中的代码就不会被执行。

try {System.out.println("Try to do something");throw new RuntimeException("RuntimeException");
} catch (Exception e) {System.out.println("Catch Exception -> " + e.getMessage());// 终止当前正在运行的Java虚拟机System.exit(1);
} finally {System.out.println("Finally");
}

输出:

Try to do something
Catch Exception -> RuntimeException

另外,在以下 2 种特殊情况下,finally 块的代码也不会被执行:

  1. 程序所在的线程死亡。
  2. 关闭 CPU。

25、如何使用try-with-resources代替try-catch-finally

  • 资源的定义:任何实现 java.lang.AutoCloseable或者 java.io.Closeable 的对象
  • 关闭资源和 finally 块的执行顺序:在 try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行

Java 中类似于InputStreamOutputStreamScannerPrintWriter等的资源都需要我们调用close()方法来手动关闭,一般情况下我们都是通过try-catch-finally语句来实现这个需求,如下:

//读取文本文件的内容
Scanner scanner = null;
try {scanner = new Scanner(new File("D://read.txt"));while (scanner.hasNext()) {System.out.println(scanner.nextLine());}
} catch (FileNotFoundException e) {e.printStackTrace();
} finally {if (scanner != null) {scanner.close();}
}

使用try-with-resources 语句改造上面的代码:

try (Scanner scanner = new Scanner(new File("test.txt"))) {while (scanner.hasNext()) {System.out.println(scanner.nextLine());}
} catch (FileNotFoundException fnfe) {fnfe.printStackTrace();
}

当然多个资源需要关闭的时候,通过使用分号分隔,可以在try-with-resources块中声明多个资源。

26、Java中是否可以重写一个private或者static方法

Java 中 static 方法不能被重写,因为方法重写是基于运行时动态绑定的,而 static 方法是编译时静态绑定的。

Java 中也不可以重写 private 的方法,因为 private 修饰的变量和方法只能在当前类中使用, 如果是其他的类继承当前类是不能访问到 private 变量或方法的,当然也不能重写。

注意:静态方法和私有方法不可以被重写

27、Java中创建对象的几种方式

  1. 使用 new 关键字
  2. 使用 Class 类的 newInstance 方法,该方法调用无参的构造器创建对象(反射):Class.forName.newInstance();
  3. 使用 clone() 方法(实现 Cloneable 接口并重写 Object 类中的 clone() 方法,实现的是浅克隆)
  4. 反序列化,比如调用 ObjectInputStream 类的 readObject() 方法(实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深克隆)

28、抽象类和接口有什么区别

  1. 抽象类中可以有抽象方法和具体方法,而接口中只能有抽象方法(public abstract)
  2. 抽象类中的成员权限可以是 public、默认、protected(抽象类中抽象方法就是为了重写,所以不能被 private 修饰),而接口中的成员只可以是 public(方法默认:public abstrat、成员变量默认:public static final)
  3. 抽象类可以有静态代码块和静态方法,而接口中不能含有静态代码块以及静态方法

设计层面上的区别:

  • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
  • 设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计

抽象类能使用 final 修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类。

29、语法问题

short s1 = 1;
s1 = s1 + 1; // 报错,在 s1 + 1 运算时会自动提升表达式的类型为 int ,那么将 int 型值赋值给 short 型变量,s1 会出现类型转换错误short s1 = 1;
s1 += s1; // 正确: += 是 Java 语言规定的运算符,Java 编译器会对它进行特殊处理,因此可以正确编译

30、Integer和int的区别

  • int 是 Java 的八种基本数据类型之一,而 Integer 是 Java 为 int 类型提供的封装类;
  • int 型变量的默认值是 0,Integer 变量的默认值是 null,这一点说明 Integer 可以区分出未赋值和值为 0 的区分;
  • Integer 变量必须实例化后才可以使用,而 int 不需要。

Integer 和 int 的比较延伸

  1. 由于 Integer 变量实际上是对一个 Integer 对象的引用,所以两个通过 new 生成的 Integer 变量永远是不相等的,因为其内存地址是不同的
  2. **Integer 变量和 int 变量比较时,只要两个变量的值是相等的,则结果为 true。**因为包装类 Integer 和基本数据类型 int 类型进行比较时,Java 会自动拆包装类为 int,然后进行比较,实际上就是两个 int 型变量在进行比较
  3. 非 new 生成的 Integer 变量和 new Integer() 生成的变量进行比较时,结果为 false。因为非 new 生成的 Integer 变量指向的是 Java 常量池中的对象,而 new Integer() 生成的变量指向中新建的对象,两者在内存中的地址不同
  4. 对于两个非 new 生成的 Integer 对象进行比较时,如果两个变量的值在区间 [-128, 127] 之间,则比较结果为 true,否则为 false。

31、final、finally、finalize的区别

final:用于声明变量、方法和类,分别表示变量不可变、方法不可重写、被其修饰的类不可继承;

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

finallize:Object类的一个方法,在垃圾回收时会调用被回收对象的finalize

32、两个对象的 hashCode() 相同,则 equals()也一定为true吗

两个对象的 hashCode() 相同,equals() 不一定为 true。因为在散列表中,hashCode() 相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等【散列冲突】。

33、为什么重写equals()就一定要重写 hashCode()方法

这个问题应该是有个前提,就是你需要用到 HashMap、HashSet 等 Java 集合,用不到哈希表的话,其实仅仅重写 equals() 方法也可以。而工作中的场景是常常用到 Java 集合,所以 Java 官方建议重写 equals() 就一定要重写 hashCode() 方法。

对于对象集合的判重,如果一个集合含有 10000 个对象实例,仅仅使用 equals() 方法的话,那么对于一个对象判重就需要比较 10000 次,随着集合规模的增大,时间开销是很大的。但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,后续比较过程中,如果两个对象的 hashCode 不相同,也不再需要调用 equals() 方法,从而大大减少了 equals() 比较次数。

所以从程序实现原理上来讲的话,既需要 equals() 方法,也需要 hashCode() 方法。那么既然重写了 equals(),那么也要重写 hashCode() 方法,以保证两者之间的配合关系

34、&和&&的区别

Java 中 && 和 & 都是表示与的逻辑运算符,都表示逻辑运输符 and,当两边的表达式都为 true 的时候,整个运算结果才为 true,否则为 false。

  • &&:有短路功能,当第一个表达式的值为 false 的时候,则不再计算第二个表达式
  • &:不管第一个表达式结果是否为 true,第二个都会执行。除此之外,& 还可以用作位运算符:当 & 两边的表达式不是 Boolean 类型的时候,& 表示按位操作

35、Java中的Math.round(-1.5)等于多少

long l1 = Math.round(-1.5); // -1
long l2 = Math.round(1.5);  // 2

因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃

36、Java中的动态代理是什么?有哪些应用

动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的新功能。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。

动态代理的应用:Spring 的 AOP 、加事务、加权限、加日志。

Java中,实现动态代理有两种方式:

  1. JDK 动态代理:java.lang.reflect 包中的 Proxy 类和 InvocationHandler 接口提供了生成动态代理类的能力
  2. Cglib 动态代理:Cglib (Code Generation Library )是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。

JDK 动态代理和 Cglib 动态代理的区别:

  1. JDK 的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口
  2. cglib 代理的对象则无需实现接口,达到代理类无侵入。(如果想代理没有实现接口的类,就可以使用 CGLIB实现)

37、字节和字符的区别

字节是存储容量的基本单位,字符是数字、字母、汉字以及其他语言的各种符号。1字节 = 8 个二进制位,一个字符由一个字节或者多个字节的二进制单位组成。

38、值传递和引用传递有什么区别

  • 值传递,按值调用(call by value):指的是在方法调用时,传递的参数是值的拷贝,传递后就互不相关了
  • 引用传递,引用调用(call by reference):指的是在方法调用时,传递的参数是引用变量所对应的内存地址。传递前和传递后都指向同一个引用(也就是同一个内存空间)

为什么Java中只有值传递?

  • Java采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。

39、BIO、NIO、AIO有什么区别

先来回顾一下这样几个概念:同步与异步,阻塞与非阻塞。

  • 同步: 同步就是发起一个请求,被调用者未处理完请求之前,调用不返回。
  • 异步: 异步就是发起一个请求,立刻得到被调用者的响应表示已接收到请求,但是被调用者并没有返回请求处理结果,此时我们可以处理其他的请求,被调用者通过事件和回调等机制来通知调用者其返回结果。

同步和异步的区别在于调用者需不需要等待被调用者的处理结果。

  • 阻塞: 阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当返回结果才能继续。
  • 非阻塞: 非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。

阻塞和非阻塞的区别在于调用者的线程需不需要挂起。

  • BIO(jdk1.4之前):Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它基于流模型实现,一个连接一个线程,客户端有连接请求时,服务器端就需要启动一个线程进行处理,线程开销大。

  • NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

    • NIO 能解决什么问题?通过一个固定大小的线程池,来负责管理工作线程,避免频繁创建、销毁线程的开销,这是我们构建并发服务的典型方式
  • AIO(jdk 1.7过后 又叫NIO 2):异步非堵塞 IO,是 NIO 的升级,异步 IO 的操作基于事件和回调机制,性能是最好的。也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

40、访问修饰符public、private、protected以及不写时的区别

Java 支持 4 种不同的访问权限。

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类
  • public : 对所有类可见。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类

41、final关键字的作用

final 关键字:

  • 修饰类:类不可被继承
  • 修饰方法:方法不能被重写
  • 修饰变量:变量有且仅能被赋值一次
  1. 修饰成员变量

    • 如果 final 修饰的是类变量,只能在静态初始块中指定初始值或者声明该类变量时指定初始值
    • 如果 final 修饰的是实例成员变量,可以在非静态初始块、声明该变量或者构造器中执行初始值
    public class Hello{// 有static修饰的就是类变量,静态成员变量,final static int a = 0;  // 在声明的时候就要赋值,或者静态代码块赋值static {a = 0;}// 没有 static 修饰的是实例成员变量,在声明的时候就需要赋值,或者代码块中赋值,或者构造器赋值final int b = 0;{b = 0;}}
    
    1. 修饰基本类型数据和引用类型数据

      • 如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改
      • 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。但是引用的值是可变的
      final int a = 1;
      a = 2; // 非法final int[] arr = {1,2,3,4};
      arr[2] = -3; //合法,可以对数组中某个元素的值进行更改
      arr = null; //非法,不能在对arr重新赋值final Person p = new Persson(25);
      p.setAge(24); //合法,可以修改引用类型的属性
      p = null; // 非法
      

42、为什么局部内部类和匿名内部类只能访问final变量

public class Test{public static void main(String[] args){}// 局部final变量a、bpublic void test(final int b){final int a = 10;// 匿名内部类:只能访问final变量a、bnew Thread(){public void run(){System.out.println(a);System.out.println(a);};}.start();}
}

内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁。当外部类的方法结束时,局部变量就会被销毁,但是内部类对象可能还存在,这就有一个矛盾,内部类对象访问了一个不存在的变量。为了解决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍然可以访问它,实际访问的是局部变量的copy,这样就好像延长了局部变量的生命周期。

将局部变量设置为final,可以保证内部类的成员变量和外部类的局部变量的一致性。

43、final、abstract关键字的关系

互斥关系,不能同时出现修饰成员!

  • abstract 修饰类,类是抽象类,必须被继承

  • final 修饰类,类不能被继承

  • abstract 修饰方法,方法必须被重写

  • final 修饰方法,方法不能被重写

44、接口和抽象类的区别

  • 抽象类除了抽象方法,还可以存在普通成员函数,但是接口中的方法必须是 public abstract 抽象方法。
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的(常量类型)
  • 抽象类只能继承一个,而接口可以实现多个

接口的设计目的,是对类的行为进行约束,也就是提供一种机制,可以强制要求不同的类有相同的行为。它只约束了行为的有无,但不对如何实现行为进行限制。

抽象类的设计目的,是代码复用。先有子类,再有父类,将子类共性的特征抽象为一个父类。抽象类不允许创建对象,表达的是 is a 的关系,比如 BMW is a Car。而接口是对行为的抽象,表达的是 like a 的关系,比如 Bird like a Aircraft,接口的核心是定义行为,即实现类可以做什么,至于实现类主体是谁、是如何实现的,接口并不关心。

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

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

相关文章

一文带你搞定线程池原理

1.使用线程池的意义何在?项目开发中,为了统一管理线程,并有效精准地进行排错,我们经常要求项目人员统一使用线程池去创建线程。因为我们是在受不了有些人动不动就去创建一个线程,使用的多了以后,一旦报错就…

怎么依靠网络赚钱,网上可以做什么副业

如今,网上赚钱已经成为许多人职业生涯的选择之一。网上有很多可靠的兼职,让你在家里轻松赚钱。今天给大家推荐五份可靠的网上兼职。一、怎样选择可靠的网络兼职可靠的网络兼职一般是指在家通过网络平台完成兼职任务,完成任务后即可获得报酬。…

学习python第一天---前缀和

一、3956.截断数组(前缀和)二、前缀和(前缀和)[0]list(map(int,input().split()))三、子矩阵的和(前缀和)range(1,n1)四、K倍区间(前缀和)五、激光炸弹(前缀和&#xff0…

Spring Cache的使用--快速上手篇

系列文章目录 分页查询–Java项目实战篇 全局异常处理–Java实战项目篇 完善登录功能–过滤器的使用 更多该系列文章请查看我的主页哦 文章目录系列文章目录前言一、Spring Cache介绍二、Spring Cache的使用1. 导入依赖2. 配置信息3. 在启动类上添加注解4. 添加注解4.1 CacheP…

在Angular项目中引入NG-ZORRO

在Angular项目中引入NG-ZORRO1.前置2.安装NG-ZORRO并进行初始化配置3.引入样式4.引入组件1.前置 首先创建一个angular项目:angular创建一个新项目的步骤 这是我项目的结构: 2.安装NG-ZORRO并进行初始化配置 安装NG-ZORRO:cd 到当前项目位…

智能算法实现PID智能车控制系统

智能算法实现PID智能车控制系统可在微信公众号 *高级嵌入式软件* 里回复 *智能算法* 查看完整版文章摘要关键词第一章绪论1.1智能车概述1.2智能PID研究现状1.3本文工作第二章 PID控制简介第三章 内模PID简介3.1 内模PID控制第四章内模智能PID智能车控制系统设计4.1 系统设计4.2…

《MySQL学习》 表中随机取记录的方式

一.初始化测试表 创建表 words CREATE TABLE words ( id int(11) NOT NULL AUTO_INCREMENT, word varchar(64) DEFAULT NULL, PRIMARY KEY (id)) ENGINEInnoDB;插入测试数据 create procedure idata()begin declare i int; set i 0; while i<10000 do insert into words…

第二节类型转换、运算符

类型转换 自动类型转换&#xff1a; 类型小的变量可以赋值给大的类型变量。 表达式的自动类型转换&#xff1a; byte short char在表达式中是当做 int计算的。 强制类型转换&#xff1a; 大类型的变量转化为小类型的变量。 注&#xff1a;浮点型转换为整数是直接丢掉小数部…

尚硅谷nginx基础

nginx1. nginx安装1.1版本区别1.2安装步骤1.3 启动nginx1.4关于防火墙1.5 安装成系统服务1.6 配置nginx环境变量2. nginx基本使用2.1 基本运行原理2.2 nginx配置文件2.2.1 最小配置2.2.1.1 基本配置说明2.3 虚拟主机2.3.1域名、dns、ip地址的关系2.3.2IP地址和DNS地址的区别2.3…

学渣适用版——Transformer理论和代码以及注意力机制attention的学习

参考一篇玩具级别不错的代码和案例 自注意力机制 注意力机制是为了transform打基础。 参考这个自注意力机制的讲解流程很详细&#xff0c; 但是学渣一般不知道 key&#xff0c;query&#xff0c;value是啥。 结合B站和GPT理解 注意力机制是一种常见的神经网络结构&#xff0…

Android安卓中jni封装代码打包为aar

前文【Android安卓中jni与Java之间传递复杂的自定义数据结构】已经介绍jni编译c++代码且已经成功封装成java,但是c++是以源代码形式继承在app中,本文介绍如何将前述jni c++代码以隐藏源代码封装成aar的形式。 1、aar打包 1.1、新建module 按照流程 File -> New Module …

windows服务器实用(4)——使用IIS部署网站

windows服务器实用——IIS部署网站 如果把windows服务器作为web服务器使用&#xff0c;那么在这个服务器上部署网站是必须要做的事。在windows服务器上&#xff0c;我们一般使用IIS部署。 假设此时前端给你一个已经完成的网站让你部署在服务器上&#xff0c;别人可以在浏览器…

Objective-C description 自定义对象的打印格式/输出的字符串 类似于Java 中的 toString 方法

总目录 iOS开发笔记目录 从一无所知到入门 文章目录IntroNSObject 源码测试类截图测试代码输出Intro 在 Java 中&#xff0c;对于自定义类一般会重写集成自Object类的toString方法&#xff0c;这样在打印该类的对象时&#xff0c;打印出的字符串就是我们在 toString() 方法中返…

Oracle Apex 21.2 安装过程

什么是 Oracle APEX&#xff1f; Oracle APEX 是广受欢迎的企业级低代码应用平台。借助该平台&#xff0c;您可以构建功能先进的可扩展安全企业应用&#xff0c;并在任何位置&#xff08;云或内部部署&#xff09;部署这些应用。 使用 APEX&#xff0c;开发人员可快速开发并部…

数据结构入门DAY1

力扣刷题合集&#xff1a;力扣刷题_Sunlightʊə的博客-CSDN博客217.存在重复元素相关题目链接&#xff1a;力扣 - 存在重复元素题目重现给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返…

大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——ReduceTask工作机制

1、ReduceTask工作机制 ReduceTask工作机制&#xff0c;如下图所示。 &#xff08;1&#xff09;Copy阶段&#xff1a;ReduceTask从各个MapTask上远程拷贝一片数据&#xff0c;并针对某一片数据&#xff0c;如果其大小超过一定阈值&#xff0c;则写到磁盘上&#xff0c;否则直…

Active Directory 05 - 初识 AD CS 证书服务

写在最前 如果你是信息安全爱好者&#xff0c;如果你想考一些证书来提升自己的能力&#xff0c;那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里&#xff1a; https://discord.gg/9XvvuFq9Wb我会提供备考过程中尽可能多的帮助&#xff0c;并分享学习和实践过程…

1029 旧键盘 C++中find函数的使用

题目链接&#xff1a; 一、自己的想法&#xff1a;&#xff08;弱化版双指针&#xff09; 思路为用两个“指针”i, j分别指向原来字符串和实际输入字符串的第一个字符&#xff0c;然后判断i&#xff0c;j所指字符是否一致&#xff0c;若是则i, j同时&#xff0c;若否则将i所指…

【5G RRC】5G系统消息SIB3介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

Windows下命令执行绕过技巧总结(渗透测试专用)

一、连接符1、双引号不要求双引号闭合举例&#xff1a;"who"a"mi" //闭合的 "who"a"mi //不闭合的2、圆括号必须在两边&#xff0c;不能包括中间的字符。举例&#xff1a;((whoami))3、^符号&#xff08;转译符号&#xff09;不可以在结尾&…