Java 面试题

java面试题 当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。 阅读详情

Java 面试题

1、Java都有哪些特点?

  1. 简单易学,容易学习和理解。
  2. 面向对象,支持封装,继承,多态等面向对象的特点
  3. 跨平台性,可以做到一段代码,在不同的平台上运行,只要对应的平台安装 Java虚拟机
  4. 内存自动回收机制,做到不需要手动释放内存,Java 使用垃圾回收器管理内存,减少了内存泄漏等情况
  5. 高性能,通过 JIT 即时编译器,将热点的字节码转换为机器码,提高了代码执行的效率
  6. 具有丰富的 AIP 社区,很多开源的 AIP 可以使用

2、面向对象和面向过程的区别?

  1. 面向对象是以对象为基础的编程方式,将数据和函数封装到一起,形成一个对象的实体,面向对象强调的是对象与对象之间的消息通讯,通过定义类和创建对象实现程序的设计和开发。面向对象编程适合解决复杂的问题,将抽象的问题用具体的对象的调用来解决。利用对象解决问题,可以更好的组织和管理代码,提高代码的复用性和可维护性。
  2. 面向过程是以函数为基础的编程方式,将问题拆分为一定的步骤和函数的调用,通过定义函数和全局变量等来实现设计和开发,面向过程更直观,用于简单问题和小型的项目。

3、八种基本数据类型和对应的大小,以及他们的封装类?

  1. 整型:
    1. byte: 1 字节 Byte
    2. shout: 2 字节 Shout
    3. int: 4 字节 Integer
    4. long 8 字节 Long
  2. 浮点型:
    1. float: 4 字节 Float
    2. double: 8 字节 Double
  3. 字符型:
    1. char: 2 字节 Character
  4. 布尔型
    1. boolean: - Boolean (单独:4 字节,在数组中:1 字节)

4、标识符和命名规则?

  • Java 中的标识符使用来标识变量名、方法名、类名、包名等
    • 只能由数字、字母、下划线、美元符号组成
    • 不能以数字开头
    • 标识符严格区分大小写
    • 标识符不能是关键字(class、public)或保留字(goto)或特殊的值(true、false)
    • 标识符要有具体的描述,要做到见名知意

5、重载和重写的区别?

  • 重载是指在同一个作用域下定义了多个同名的方法,但这些方法参数的种类、数量、顺序不同,编译器可以区分这些方法,重载方法可以提高代码的可读性和灵活性。(两同:同一个类,方法名相同)
  • 重写是重新定义了从父类中继承而来的方法,实现了多态性,即,父类的引用指向子类的对象,调用父类的方法时,执行的是子类中重写的方法。

6、equals与==的区别?

  • equal() 用于比较对象的内容是否相等,在对象没有重写的情况下,默认比较的是地址,只有重写了equal() 方法才会比较内容是否相同。
  • == 对于基本数据类型是比较值,对于引用数据类型是比较对象的地址是否相同,如果两个对象指向同一个内存地址,那么就认为这两个对象相同。

7、Hashcode的作用?

  • hashCode是对象的一个方法,用于计算对象在hash表中的位置
  • 在集合的查找和存储中,hashCode用于快速查询和储存对象,在使用hashMap等集合类时就可以快速的确定存储位置和查找位置,提高代码的运行效率。
  • 对象的判断,两个对象相同,那这两个对象的hash值一定相同,但是,因此可以先比较hash值,如果hash值不相同,这两个对象一定不相同,如果相同,再用equal()判断

8、String、StringBuffer 和 StringBuilder 的区别是什么?

  • String:

    • 不可变的,在对String进行操作时,都会创建一个新的对象,对系统的开销很大

    • 线程安全

    • jdk7 时,Spring常量池在永久代,到 jdk8 及以后,Spring常量池被转移到了堆内存中

      • 当使用 Stirng str = “AA”; 时,“AA”会被储存在常量池中,因此,当再次创建“AA”时,不会在创建一个新的字符串,而是引用常量池中存在的字符串。

                String str1 = new String("Hello"); //new出来的都堆中,不会进入常量池
                String str2 = "Hello";
                System.out.println(str1 == str2);  //false
        
        
                String str3 = "Hello";  //进入常量池
                String str4 = "Hello";  //引用常量池中的数据
                System.out.println(str3 == str4);  //true
        
                String str5 = new String("Hello");  //进入堆空间,开辟一块空间放入字符串
                String str6 = new String("Hello");  //进入堆空间,开辟一块空间放入字符串
                System.out.println(str5 == str6);  //false
        
  • StringBuffer

    • 可变的,可以在原来的基础上进行修改
    • 线程安全的,所有的公开方法都用synchronized
  • StringBuilder

    • 可变的
    • 非线程安全的

9、ArrayList和LinkedList的区别?

  • AllayList:
    • 底层使用数组进行储存,当超出数组的范围时,会自动扩容 1.5 倍。
    • 由于用利用数组进行储存,查询效率高,但是删除和插入效率低
  • LinkedList:
    • 底层使用双向链表实现的,每个节点包含前一个节点和后一个节点的引用。
    • 由于利用链表进行储存,删除和插入效率高,查询的效率低

10、HashMap和HashTable的区别?

  • hashMap:
    • 底层使用数组+链表+红黑树
    • 线程不安全
    • 允许null键和null值
    • 当hashMap不足时,会进行扩容,默认扩容为原来的 2 倍(因为通过二次hash值计算位置时方便)

11、List,Set,Map三者的区别?

  1. List:
    - List是一个有序的集合,可以包含重复的元素。
    - List允许通过索引访问元素,可以根据元素的位置进行增删改查操作。
    - 常见的List实现类有ArrayList和LinkedList。

  2. Set:
    - Set是一个不允许包含重复元素的集合。
    - Set不保证元素的顺序,即不按照插入顺序或者排序顺序进行存储。
    - Set提供了判断元素是否存在的方法,可以用于去重。
    - 常见的Set实现类有HashSet和TreeSet。

  3. Map:

    • Map是一种键值对的映射表,每个键对应一个值。
      • Map中的键是唯一的,但值可以重复。
      • Map提供了根据键获取值的方法,也可以根据键删除或更新对应的值。
      • 常见的Map实现类有HashMap和TreeMap。

12、Collection包结构,与Collections的区别?

  • Collection是集合类的上级接口。
  • Collections里面封装了有关集合操作的静态方法

13、Java的四种引用,强弱软虚?

  • **强引用:**这是最常见的引用类型,如果一个对象具有强引用,垃圾回收器绝不会回收它,当内存不足时,宁愿抛出错误终止程序,也不会随意

    ​ 回收具有强引用对象来解决内存不足问题。

  • **软引用:**用来描述一些还有用,但是并非必须的对象,将要发生内存溢出异常之前,将会把这些对象列进回收的范围中进行二次回收。

  • **弱引用:**弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,当垃圾回收器工作时,都会回收掉只被弱引用关联的对象

  • **虚引用:**最弱的引用关系,完全不会对其生存时间构成影响,唯一目的就是在这个对象被回收时,收到一个系统通知

14、泛型常用特点?

  • 泛型可以在定义类或接口的时候表示类型,在创建对象的时候指定类型
  • 提高代码的复用性和可维护性。
  • 提高代码的运行效率,泛型在编译时会进行类型擦除,减少运行时的开销,避免了装箱和拆箱的操作

15、Java创建对象有几种方式?

  1. 关键字 new 创建新对象
  2. 通过反射机制
  3. 采用clone机制
  4. 通过序列化机制

16、深拷贝和浅拷贝的区别是什么?

  • 深拷贝,就是创建一个新的对象,新对象将原来对象中的所有信息全部复制下来,如果是引用数据类型,会重新创建对象,然后放入值
  • 浅拷贝,创建一个对象,复制对象的属性,如果属性是引用数据类型,就只是引用原数据,不会创建对象。

17、final有哪些用法?

  • final修饰类,表示该类是最终类,不会被继承,没有子类
  • final修饰方法,表示该方法是最终方法,不能被子类重写
  • final修饰变量,表示该变量是常量,一旦复制,不可被改变
  • final修饰引用数据类型,该数据类型的地址不可变,但是其中的属性可变
  • final修饰参数,表示该方法内,该参数不可变

18、static都有哪些用法?

  1. 静态变量:使用static修饰的变量称为静态变量,也叫类变量。静态变量属于类,而不是属于类的实例。静态变量在类加载时被初始化,并且只有一份拷贝,所有实例共享该变量的值。可以通过类名直接访问静态变量。

    	//1. 静态变量:使用static修饰的变量称为静态变量,也叫类变量。静态变量属于类,而不是属于类的实例。静态变量在类加载时被初始化,并且只有一份拷贝,所有实例共享该变量的值。可以通过类名直接访问静态变量。
    
     	//2. 静态方法:使用static修饰的方法称为静态方法,也叫类方法。静态方法属于类,而不是属于类的实例。静态方法可以直接通过类名调用,无需创建类的实例。静态方法只能访问静态成员(包括静态变量和静态方法),不能访问非静态成员。
    
    	//3. 静态代码块:使用static关键字定义的代码块称为静态代码块。静态代码块在类加载时执行,并且只会执行一次。静态代码块常用于初始化静态变量或执行一些只需执行一次的操作。
    
    	//4. 静态内部类:使用static修饰的内部类称为静态内部类。静态内部类与外部类没有直接的关联,可以直接通过外部类名访问。静态内部类可以拥有自己的静态成员,但不能访问外部类的非静态成员。
    

19、有没有可能两个不相等的对象有相同的hashcode(哈希冲突) ?


20、如何解决哈希冲突?

  • 开放地址法:当发生哈希冲突时,通过一定的探测方法找到下一个可用的位置。常见的探测方法有线性探测、二次探测和双重哈希等。线性探测是指依次往后查找,直到找到一个空闲位置;二次探测是指通过二次方程计算下一个位置;双重哈希是指使用第二个哈希函数来计算下一个位置。

  • 再哈希法:当发生哈希冲突时,使用另一个哈希函数重新计算索引位置。如果仍然发生冲突,可以继续使用其他哈希函数进行再哈希,直到找到一个空闲位置。


21、Object 有哪些常用方法?方法的含义?

  1. equals(Object obj):判断当前对象是否与给定对象相等。默认情况下,equals方法比较的是对象的引用是否相等,即是否指向同一个内存地址。如果需要比较对象的内容是否相等,需要在具体类中重写equals方法。
  2. hashCode():返回当前对象的哈希码值。哈希码是根据对象的内部状态计算得出的一个整数值,用于快速查找和比较对象。在重写equals方时,通常也需要重写hashCode方法。
  3. toString():返回当前对象的字符串表示。默认情况下,toString方法返回的是对象的类名和哈希码值的组合。可以根据需要在具体类中重写toString方法,以便返回更有意义的字符串表示。
  4. getClass():返回当前对象所属的类的Class对象。Class对象包含了关于类的各种信息,可以用于获取类的名称、字段、方法等。
  5. clone():创建并返回当前对象的一个副本。默认情况下,clone方法会创建一个浅拷贝,即只复制对象的引用而不复制对象本身。如果需要实现深拷贝,需要在具体类中重写clone方法。
  6. finalize():在垃圾回收器回收对象之前调用。可以在具体类中重写finalize方法,以便在对象被销毁之前执行一些清理操作。

22、jdk、jre、jvm

  • 理解:

    1. **jvm:**Java虚拟机,是 Java 平台的核心,它使得 Java 程序可以在不同的操作系统上运行而无需编译

    2. **jre:**Java运行时环境提供了Java的核心类库(Java.long / java,util)等,如果如果只是运行Java程序,那jre就能满足

      ​ 需求。

    3. **jdk:**jdk是Java的开发包,包含编译,调试,运行Java代码的开发工具。

  • 关系:jdk 包含 jre ,jre包含jvm

  • jdk = jvm + 核心类库(java.long / java.util) + 开发工具(javac、javadoc、jdb(deBug))


23、Java是半编译、半解释的语言

  • Java 在编译阶段将源代码转换为字节码,在运行阶段又通过解释器或者即时编译器将字节码转换为机器码执行,所以说 Java 是半编译、半解释的语言。

24、注解

  • 注解是一种元数据标记,用于提供关于代码的额外信息,注解不会直接影响程序的执行,但可以被编译器、运行时环境或工具使用
  • 注解通常在类、方法或变量前使用@注解名的形式添加注解。例如,@Override 用于检查方法是否正确重写。
  • 优缺点
    • 优点:增强代码的可读性,提供元数据,支持编译时检查,简化代码编写。
    • 缺点:过度使用注解可能导致代码难以理解,某些注解可能会影响性能。

25、字符型常量和字符串常量

  • 字符型常量是单个字符,用单引号表示;字符串常量是字符序列,用双引号表示。
  • 字符常量用于表示单个字符,如 'A';字符串常量用于表示文本,如 "Hello"。
  • 优缺点
    • 优点:字符型常量和字符串常量在 Java 中是基本的数据类型,使用广泛。
    • 缺点:字符串是不可变的,频繁修改字符串内容会导致性能问题

26、标识符和关键字的区别

  • 标识符是用户自定义的名称,关键字是Java预定义的有特殊意义的词。
  • 标识符用于命名类、方法、变量等,关键字用于特定的语法结构,如 if、for 等。
  • 优缺点
    • 优点:标识符提供了灵活性,关键字提供了语言的结构。
    • 缺点:需要避免将关键字作为标识符,否则会导致编译错误。

27、自增(++)和自减(–)

  • 自增和自减是Java中的运算符,用于增加或减少变量的值。
  • ++var 或 var++ 用于自增,--var 或 var-- 用于自减。
  • 后置++或- - 是使用后就会生效,即:(i= 2) ——》a = (i + i ++) + (++i) ==> (2 + 2 ++) + (++2) ==> (4) + (++3) ==> 4 + 4 = 8
  • 优缺点
    • 优点:提供了一种简洁的方式来修改变量的值。
    • 缺点:在复杂表达式中使用时可能导致混淆。

28、泛型

  • 泛型是Java中用于支持类型参数化的一种机制,允许在类、接口和方法中使用类型参数。类型擦除是泛型的实现方式,类型擦除的设计是为了兼容那些早期不支持泛型的语言特性,开发者可以在编写代码时享受泛型带来的便利,而编译器则会在编译阶段确保类型安全,然后擦除这些类型信息以适应现有的类结构体系。

29、transient 关键字(阻止序列化)

  • 主要功能:
    • transient 关键字用于标记类的字段,使其在对象序列化过程中不被保存。
    • 这可以用于保护敏感数据(如密码)或避免序列化不必要的字段,从而提高性能和安全性。
  • 应用场景:
    • 当某些字段不需要或不应该在序列化过程中被保存时,可以使用 transient 关键字。
    • 例如,临时数据、计算结果、敏感信息等。

通过使用 transient 关键字,开发者可以更灵活地控制对象的序列化过程,确保只有必要的数据被持久化。


30、快速失败&安全失败

在Java编程当中,Iterator迭代器是一种用于遍历如List、Set、Map等集合的工具。这类集合部分存在线程安全的问题,例如ArrayList,若在多线程环境下,迭代遍历过程中存在其他线程对这类集合进行修改的话,就可能导致不一致或者修改异常问题,因此,针对这种情况,迭代器提供了两种处理策略:Fail-Fast(快速失败)和Fail-Safe(安全失败)。

先简单介绍下这两种策略——

  1. Fail-Fast(快速失败)机制
    快速失败机制是指集合在迭代遍历过程中,其他多线程或者当前线程对该集合进行增加或者删除元素等操作,当前线程迭代器读取集合时**会立马抛出一个ConcurrentModificationException异常,避免数据不一致。**实现原理是迭代器在创建时,会获取集合的计数变量当作一个标记,迭代过程中,若发现该标记大小与计数变量不一致了,就以为集合做了新增或者删除等操作,就会抛出快速失败的异常。在ArrayList默认启用该机制。

  2. Fail-Safe(安全失败)机制
    安全失败机制是指集合在迭代遍历过程中,若其他多线程或者当前线程对该集合进行修改(增加、删除等元素)操作,当前线程迭代器仍然可以正常继续读取集合遍历,而不会抛出异常。该机制的实现,是通过迭代器在创建时,对集合进行了快照操作,即迭代器遍历的是原集合的数组快照副本,若在这个过程,集合进行修改操作,会将原有的数组内容复制到新数组上,并在新数组上进行修改,修改完成后,再将集合数组的引用指向新数组,,而读取操作仍然是访问旧的快照副本,故而实现读写分离,保证读取操作的线程安全性。在CopyOnWriteArrayList默认启用该机制。


31、Hash的理解

  • hash的基本概念就是把任意长度的输入通过一个hash算法后,映射成固定长度的输出

32、Hash为什么采用高16位异或低16位

  • 优化hash算法,因为散列表的长度一般不会太大,hash值一般就用到低16位(hash & (table.length-1)),高16位没用

    因此,将高16位与低16位进行 异或 操作,让高16位也有用


33、为什么java只有值传递

  • 认识:Java中引用数据类型传递的是该对象的引用副本,在方法中,重新引用不会影响到原有对象,但是,改变对象的属性,可以影响。

  • **安全性和可预测性:**开发人员可以明确的知道方法调用的数据是否被修改,对于基本数据类型,参数的值不会被修

    改,对于引用数据类型,可以清楚的知道,引用所指向的对象的修改会影响到所有指向该对象的引用。这种设计也避免了潜在的错误和混淆,提高程序的安全性。

  • **内存管理一致:**从内存管理的角度来看,值传递机制与 Java 的内存模型相匹配。无论是基本数据类型的值还是引用数据类型的引用,都是在栈内存中进行传递和操作的,而对象本身存储在堆内存中。这种清晰的内存划分有助于提高垃圾回收的效率和准确性,也使得 Java 程序在内存管理方面更加稳定和可靠


34、java常见语法糖

  • 泛型
  • 自动装箱和自动拆箱
  • 增强for循环
  • 可变参数
  • 枚举
  • Lambda 表达式

35、java三大特性

  • 封装性:
    • **定义:**将类的某些信息隐藏在内部,不允许外部直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
    • **实现方式:**通过四种权限修饰符,public,protected、private、缺省,来控制类、变量和方法的可见性。
    • **优点:**提高代码的安全性,不允许外部随意修改内部数据而导致错误。符合开闭原则(对扩展开放,对修改关闭)
  • 继承:
    • **定义:**继承是子类继承父类的属性和方法,子类可以在不修改父类的情况下,对继承的属性和方法进行扩展和重写。
    • **实现方式:**Java中通过extends关键字实现继承
    • 优点:
      • 提高代码的复用性,子类可以服用父类的代码
      • 类之间的层次更加分明,有利于代码的维护
  • 多态:
    • **定义:**多态是指同一个操作作用于不同的对象可以有不同的表现形式,Java中主要的表现形式为编译时多态(方法重载)和运行时多态(方法重写)
    • **实现方式:**泛型,子类的引用指向父类的对象等。
    • **优点:**提高代码的灵活性和可维护性

36、抽象类和接口的区别

  • 抽象类使用的是abstract关键字定义,而接口使用interface进行定义
  • 抽象类中可以包含抽象方法和普通方法,而接口中的方法默认都是抽象方法,在jdk8之后可以包含默认方法和静态方法(有方法体)
  • 抽象类可以包含各种成员变量,包括实例变量和静态变量,有不同的访问修饰符,而接口中的成员变量默认都是public static final类型的
  • 一个类只能继承一个抽象类,而一个类可以实现多个接口。
  • 抽象类主要用于对事务的抽象,可以提供部分实现,体现的是is a的关系。而接口时定义一种行为规范,它不提供任何实现,体现的是一种can do的关系

37、权限修饰符

  • public:任意位置可见
  • private:本类中可见
  • protected:本包以及子类中可见
  • 缺省:本包中可见

38、@autowired与@Resource

  • @Autowired:先根据类型进行匹配注入,后根据@Qualifier指定的名称进行注入
  • @Resource:先跟据名称进行注入,后根据类型进行匹配

39、Redis基本数据类型

字符串(String)、哈希(hash)、列表(List)、集合(Set)、有序集合(Sorted Set)

40、Redis缓存一致性

  • **设置过期时间:**可以为不同的数据类型固定过期时间,当时间过期时,从数据库中重新加载数据,确保数据的一致性
  • 在数据库更新数据时,先更新数据库,后更新缓存,并为数据更新添加事务,保证数据的一致性
  • 异步队列,将数据的写操作放入消息队列中,由专门的线程获取队列更新数据。

41、Redis缓存雪崩

  • 问题:Redis 缓存雪崩是指在缓存系统中,大量的缓存数据在同一时间失效(过期),或者缓存服务器在短时间内出现大量故障,导致大量的请求直接到达数据库,使得数据库的负载瞬间剧增,甚至可能导致数据库服务器崩溃,从而影响整个系统的性能和可用性。
  • 解决:
    • 设置一定范围的随机的过期时间,如以60分钟为基础,在50 ~ 70 之间的随机失效时间
    • 使用Redis集群,将数据分片储存到多个节点上,当某个节点出现故障时,其他节点继续提供服务保证整体的可用性
    • 主从复制,将数据从主节点复制到多个从节点上,当主节点故障时,从节点升级为主节点,保证服务的连续性

42、为什么String是不可变的

  • 安全性:
    • 防止数据被篡改,当一个String作为参数传递时,如果是可变的,可能在调用者不知情时导致数据的的更改
    • 避免安全漏洞,防止恶意代码篡改敏感信息
  • 缓存优化:
    • 使用字符串常量池保证Stirng的不可变性,节省空间
  • 线程安全:
    • 并发操作的安全性,当多个线程修改同一个字符串时,不会出先一个线程修改,导致其他线程不一致的情况

43、String如何实现不可变的

  • final修饰类
  • 成员变量用private final修饰
  • String类中的所有方法都返回的是一个新的字符串对象,防止对原有的数据的修改

44、反射创建class对象的方法

  • Class.forName("com.example.Person")
  • 使用.class语法
  • 使用getClass()方法

45、异常的分类

编译时异常、运行时异常、错误

46、try - with - resources的异常捕获

当在 try 关键字后面的括号 () 中创建并初始化资源(这些资源需要实现 AutoCloseable 接口)时,在 try 块执行结束后,无论是否抛出异常,这些资源都会被自动关闭。

47、java8新特性

  • Lambda 表达式
  • 函数式接口
  • 方法引用
  • Stream AIP
  • 接口的默认方法和静态方法

48、switch可用的数据类型

  • Java 8 之前,只能用于byte、short、int、char,在Java 7开始支持字符串以及对应的包装类
  • 从 Java 14 开始,支持包装类等类型

49、枚举类

枚举类是一种特殊的类,用于表示一组有限的常量

Java 中可以用 enum来定义枚举类

枚举类的表达清晰,提高代码的可读性

50、为什么重写equals和hashcode

  • equals 方法用于判断两个对象是否,相等,如果不重写equals方法,则会比较两个对象的引用,只有指向同一个地址才会返回true

  • hashCode 方法用于为对象生成一个 hash 值,在集合类(HashMap)中,用于快速定位存储对象的位置

    如果不重写,就可能导致相同对象在集合中被重复储存无法从集合中正确的检索到。

51、jvm内存区域有哪些

  • 线程私有区域:

    • 程序计数器,当前线程执行字节码的行号指示器
    • 虚拟机栈,用于存放方法的局部变量表等信息
    • 本地方法栈
  • 线程共享区域:

    • 堆,用于储存对象实体和数组,可以在物理内存上不连续,逻辑内存上连续

    • 方法区,用于储存类信息,常量,静态变量,即时编译器编译后的代码,jdk8后被元空间代替

      元空间不再与堆内存相连避免永久代的内存溢出问题,更好的管理方法区的内存

52、垃圾回收的算法有哪些

  • 标记—清除算法:

    • **过程:**先标记出所有可能需要回收的对象,在标记完成后同一回收所有标记的对象

    • 缺点:

      • **效率问题:**标记和清除两个过程的效率都不高

      • **空间问题:**会产生大量不连续的内存空间碎片,可能导致下一次分配较大的连续内存空间时,无法找到

        足够多的内存而不得不触发另一次的垃圾清除动作

  • 复制算法:

    • **过程:**将可能用到的内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块内存用完时,

      将还存活着的对象复制到另一块上面,然后再把使用过的内存空间一次清理掉。

    • **优点:**实现简单,运行效率高,不会产生内存碎片

    • **缺点:**将内存缩小到原来的一半,代价较高

  • 标记—整理算法:

    • 过程:根据对象存活周期的不同将内存划分为几块,一般 Java 把堆内存划分为新生代和老年代,在新生代中

      每次垃圾收集时都发现有大批对象死去,少量存活,那就选用复制算法,而老年代存活率高,没有额外空间对它进行分配担保,

      就必须用标记–清理或标记–整理算法

53、gc垃圾回收器有哪些

  • Serial 收集器
  • Serial Old 收集器
  • CMS 收集器
  • G1 收集器

54、io与nio的不同之处

  • 面向流与面向缓冲区
    • IO 是面向流的,意味着每次从流中读取一个或多个字节,如果需要再读取已读取的字节,只能重新从新的流中的开始位置读取
    • NIO 是面向缓冲区的,先读取数据到缓冲区,如果需要反复读取可以在缓冲区中前后移动位置进行处理
  • 阻塞与非阻塞
    • IO 流是阻塞的,当一个线程调用read()或write()操作时,该线程被阻塞,进入等待状态,无法进行其他任务
    • NIO 流是非阻塞的,当没有数据可读取时,线程不会阻塞,而是做其他的事情,稍后回来检查是否有数据可读取
  • NIO 的选择器
    • 一个选择器可以同时管理多个通道的事件,使得一个线程可以处理大量的连接

55、Java的类加载机制

  • **加载:**在内存中生成一个代表这个类的对象

  • 验证: 确保类的字节码符合JVM的规范和安全要求。

  • **准备:**为类变量(static修饰)分配内存并设置初始值

  • **解析:**将类中的符号引用转化为直接引用

  • **初始化:**执行类的初始化代码

  • Java的类加载机制采用了双亲委派模型,即,当一个类加载器收到类加载请求时,它首先会将请求委派给父类加载器完成

    只有当父类加载器无法完成加载请求时,子类加载器才会尝试自己加载,确保类的类的唯一性和安全性防止重复加载和恶意代码的篡改

56、详细说明双亲委派机制

双亲委派机制是 Java 类加载机制中的一种重要设计模式,主要用于确保类的唯一性和安全性。以下是对双亲委派机制的详细说明:

一、定义与工作原理

双亲委派机制规定,当一个类加载器收到类加载请求时,它不会自己去尝试加载这个类,而是把请求委派给父类加载器去完成。如果父类加载器无法加载这个类,子加载器才会尝试自己去加载。这个过程会一直向上委托,直到顶层的启动类加载器。如果启动类加载器也无法加载这个类,再依次向下由子加载器进行尝试加载。

例如,当应用程序类加载器(Application ClassLoader)收到一个加载类 com.example.MyClass 的请求时,它不会立即去加载这个类,而是把请求委派给它的父类加载器——扩展类加载器(Extension ClassLoader)。如果扩展类加载器也无法加载这个类,再继续向上委托给启动类加载器(Bootstrap ClassLoader)。如果启动类加载器仍然无法加载这个类,才会依次向下由扩展类加载器和应用程序类加载器尝试加载。

二、作用

  1. 确保类的唯一性:
  • 通过双亲委派机制,同一个类在 JVM 中只会被加载一次。因为类的加载请求会一直向上委托,最终由顶层的启动类加载器首先尝试加载。如果启动类加载器能够加载这个类,那么就会使用这个加载器加载的类,保证了类的唯一性。
  • 例如,在不同的应用程序中可能都有一个名为 java.util.ArrayList 的类,如果没有双亲委派机制,每个应用程序可能会使用自己的类加载器加载这个类,导致出现多个不同版本的 ArrayList 类,这会引起程序的混乱。
  1. 保证安全性:
  • 双亲委派机制可以防止恶意代码替换核心类库中的类。由于启动类加载器通常是由 JVM 自身实现的,它加载的是核心类库中的类,这些类具有较高的安全性和稳定性。
  • 如果没有双亲委派机制,恶意代码可以通过自定义的类加载器加载一个与核心类库中同名的类,并替换其中的方法,从而对系统造成安全威胁。有了双亲委派机制,当加载核心类库中的类时,会优先由启动类加载器进行加载,确保了核心类库的安全性。

三、实现方式

在 Java 中,双亲委派机制主要是通过 ClassLoader 类的 loadClass() 方法实现的。这个方法的默认实现会首先检查父类加载器是否已经加载了这个类,如果没有,则调用父类加载器的 loadClass() 方法进行加载。如果父类加载器无法加载这个类,才会调用当前类加载器的 findClass() 方法尝试自己去加载。

以下是一个简单的示例代码,展示了类加载器的层次结构和双亲委派机制的实现:

public class ClassLoaderExample {
    public static void main(String[] args) throws ClassNotFoundException {
        // 获取应用程序类加载器
        ClassLoader appClassLoader = ClassLoaderExample.class.getClassLoader();
        System.out.println("Application ClassLoader: " + appClassLoader);    
        // 获取扩展类加载器
        ClassLoader extClassLoader = appClassLoader.getParent();
        System.out.println("Extension ClassLoader: " + extClassLoader);

        // 获取启动类加载器
        ClassLoader bootstrapClassLoader = extClassLoader.getParent();
        System.out.println("Bootstrap ClassLoader: " + bootstrapClassLoader);

        // 加载一个类,触发双亲委派机制
        Class<?> clazz = Class.forName("java.lang.String");
        System.out.println("Loaded class: " + clazz.getClassLoader());
	}
}

在这个示例中,我们首先获取了应用程序类加载器、扩展类加载器和启动类加载器,并打印它们的信息。然后,我们使用 Class.forName() 方法加载 java.lang.String 类,这个过程会触发双亲委派机制,最终由启动类加载器加载这个类。

总之,双亲委派机制是 Java 类加载机制中的一个重要设计模式,它确保了类的唯一性和安全性,是 Java 语言安全稳定运行的重要保障。

57、tomcat是如何打破双亲委派机制的

  • 打破双亲委派机制的方法是通过重写类加载方法,先通过自己加载,如果加载不了,在委派给父类加载
  • Tomcat 通过重写类加载方法和打破双亲委派机制,实现了在一个服务器中部署多个 Web 应用程序时,各个应用程序之间类的隔离、独立加载、热部署和热加载等功能。
本文将详细介绍如何在 Qt (C++) 应用程序中集成 osgEarth,加载三维数字地球,并在指定经纬度添加三维模型(如飞机、建筑等)。 OSG 与 Qt 的交互通常需要处理 OpenGL 上下文。osgEarth 3.x 提供了对 Qt 的较好支持,或者可以使用。在普通 OSG 程序中,你需要手动处理坐标系转换将经纬度转为笛卡尔坐标 (XYZ)。这是实现的关键,将 OSG 的渲染循环集成到 Qt 的事件循环中。第三方库,但在本教程中,我们将展示一种通过继承。,将 Qt 的输入事件转换为 OSG 理解的。事件,这是实现交互(旋转地球、缩放)的基础。来嵌入 OSG 视图的标准方法。在这里我们初始化地球并添加模型。节点简化了这一过程。 阅读详情

相关推荐

直流电机双闭环调速系统MATLAB仿真

Chopper-Fed DC Motor Drive This example shows a Chopper-Fed DC Motor Drive. Description The DC motor is fed by the DC source through a chopper which consists of GTO thyristor and free-wheeling diode ...

飞行动力的博客 2万+

八股文01:基础篇

一共有8种:boolean 1 bit,不到一个字节byte 8 bit,1字节short 16 bit,2字节char 16 bit,2字节int 32 bit,4字节float 32 bit,4字节long 64 bit,8字节double 64 bit,8字节说明:1、int是基本数据类型,Integer是包装类型。int的默认值为0,Integer的默认值为null,因此Integer能区分出null和0。

ybq19513345431的博客 807

[零基础]用docker搭建Hadoop集群

[零基础]用docker搭建Hadoop集群,每一步都有详细的解释!

weixin_56114243的博客 2万+

JAVA 面试背 通过_java面试题背不下来怎么办?java面试题总结

Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)。最近有很多java人员反映,说java面试题太多根本就背不下来,这可急坏了他们,毕竟要去面试java工作的,那么接下来,我们就来给大家讲解一下java面试题背不下来的解决方法。可以正确编译,因为s1+= 1;

m0_74825409的博客 1415

告别地图偏移!手把手教你用MapOnline V1.2在ArcGIS里加载无偏谷歌影像和历史影像

本文详细介绍了如何使用MapOnline V1.2插件在ArcGIS中加载无偏谷歌影像和历史影像,解决GIS工程师长期面临的地图偏移问题。通过三步安装配置、无偏影像加载和时空分析功能,提升地理信息数据的精确度和工作效率,特别适用于城市规划、环境监测等场景。

weixin_29252171的博客 232

解锁Vscode:C/C++环境配置超详细指南

本文详细介绍如何在 VSCode 中配置 C/C++ 开发环境,帮助开发者快速搭建高效的编码调试环境。内容涵盖前期准备、软件下载安装、环境变量配置、工作区文件设置及测试运行全流程:首先需准备 VSCode 编辑器、MinGW-w64 编译器及 C/C++ 插件;接着完成工具下载与安装,配置系统环境变量以确保编译器可全局调用;然后通过创建.vscode工作区文件夹,配置核心文件,实现代码智能提示与调试功能;最后通过编写 Hello World 示例验证环境可用性,并附上常见问题排查方案。

邓邓子的博客 3047

Java面试题

Java面试题(01)Java面试题(02)Java面试题(03)Java面试题(04)Java面试题(05)Java面试题(06)Java面试题(07)Java面试题(08)Java面试题(09)Java面试题(10)Java面试题(11)Java面试题(12)Java面试...

心底善良小剥皮de博客 4320

PPT制作能力在职场中真的重要吗?一定要美术功底才能学好PPT吗?

我推出PPT技能培训专栏啦!好的PPT可以让你事半功倍、2023拥有PPT能力还可以让你具备一门极有价值的斜杠能力。更多内容请进:梦幻训练营专栏。专栏内会用本人积累的近10年的PPT学习方法论在短时间内教会你如何制作出精美绝伦的PPT,每篇教程后还会免费赠送一些小福利,不可多得。

打造全国最全的AI Agent开发知识领域的博客 728

java 入门面试题

基础:JDK 和 JRE 的区别== 和 equals 的区别基本类型和包装类对象使用 == 和 equals进行比较的结果?什么是装箱?什么是拆箱?装箱和拆箱的执行过程?常见问题?hashCode()相同,equals() 也一定为 true吗?final 在 java 中的作用final finally finalize()区别finally语句块一定执行吗?final 与 static 的区别return 与 finally 的执行顺序对返回值的影响String对象中的replace和replaceA

m0_74824755的博客 1167

用MATLAB计算卡方值

然后,我们计算了期望频数,即在两个分类变量独立的情况下,每个单元格的预期频数。接下来,我们使用卡方检验的公式计算了卡方值。卡方检验是一种常用的统计方法,用于确定两个分类变量之间是否存在相关性。它基于观察到的频数和期望频数之间的差异来评估分类变量之间的独立性。在MATLAB中,我们可以使用。请注意,这只是一个简单的示例代码,用于说明如何使用MATLAB计算卡方值。在实际应用中,您可能需要根据您的具体数据和研究问题进行相应的修改和调整。在上面的代码中,我们首先创建了两个分类变量。函数显示了计算得到的卡方值。

CodeNexus的博客 2658

Skill的嵌套

Skill的嵌套就很简单,直接引用其他的Skill就好了。在一个 Skill 的 SKILL.md 中,可以明确指示 Claude 去读取另一个 Skill 的文档。

Criss@陈磊 957

Java面试题(最新最全Java面试题汇总)

Java面试题(最新最全Java面试题汇总)JAVA相关基础知识Java面试题集-Java面试题,J2EE面试题集J2EE面试题集(附答案)Java常见面试题集--面试题全面综合(一)Java常见面试题集--面试题全面综合(二)Java面试题集(欢迎大家踊跃提供) 最全的C/C++面试题集(C/C++试题和部分答案)最全的C/C++面试题集(最全的C/C++试题集和答案)(续)一道有趣的C#考试题

首席技术执行官CTO(Chief Technology Officer)|技术总监--邓斌博客 3024

【软考中级网络工程师】知识点之 ICMP 协议

本文聚焦软考中级网络工程师必备的 ICMP 协议知识,先概述其在 TCP/IP 协议族网络层的地位与无连接特性,再阐述差错报告、网络诊断等功能。解析报文格式,详解差错与查询类报文类型及工作机制,还介绍其在 Ping、Traceroute 命令中的应用,分析常见攻击与防范措施,最后总结核心要点,为网络工程师学习和应用 ICMP 协议提供全面指导。

邓邓子的博客 1402

2020最新Java面试题

@TOC1、面试题模块汇总 面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下图所示: 可能对于初学者不需要后面的框架和 ...

java开发郭靖 3053

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

最新Java面试题,常见面试题及答案汇总

Java最新常见面试题 + 答案汇总 原文地址:https://blog.youkuaiyun.com/sufu1065/article/details/88051083 1、面试题模块汇总 面试题包括以下十九个模块: Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate...

JustDI0209的博客 568

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java经典面试题

这份面试题,包含的内容了十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM。下面一起来看 208 道面试题,具体的内容。以下是网上整理的非常全面的面试题,当然,绝大多数人不可能全部用到,但是都罗列在此,大家可根据自己的情况,选择对应的模块进行阅读。

2401_87878486的博客 1339

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【面试题】-java面试题总目录

前言:先吐槽一下面试吧,相信不少人都有这样的经历,其实你对某项技术已经掌握的很OK了,但在面试的时候却未必能发挥到很好,让面试官觉得你确实已经很好的掌握该技术,也就是说你实际对该技术掌握的程度有90%,但面试时表现出来的却只有30%甚至更少,这可能是表达能力的问题,但也可能很大程度是因为你没有刷面试题,有些平时几乎很少会用到地方没有涉及到刚好被问到了.就好生活中有些人开车开得很好,甚至是一些开车多...

老汉健身的博客 578

java面试题_2019 最新 200 道 Java 面试题

2015 年,因为工作岗位的变动,开始负责给集团招聘一些技术人员,出于对公司的负责,也为了更好的胜任技术经理的职位,在面试的这件事上,我做了大量的“功课”,首先我研究了几乎所有大厂的面试题,还和负责招聘工作的几个朋友,详细的探讨了 Java 面试所要涉及的知识点,于是就有了今天大家看到的这 200 多道面试题。为什么要公开这些面试题?原因一:身边从事 Java 开发的人员越来越多,我的表...

weixin_39734458的博客 154

Java面试题集锦

 Java面试题集锦 2017-09-26 阿木侠 Java知音 Java知音 Java知音 微信号 Java_friends 功能介绍 致力打造一个有情怀的Java相关技能推送号 这是整理之后的面试题,本来都是已经发过的,后台不断有小伙伴留言想我去把这些集中到一块儿看着方便,最近一直挺忙就一直没动手,今天终于抽出空来整理了,顺手把推荐书籍

java_2017_csdn的博客 3450

常用Java面试题

        以下链接都是一些洋人整理的常用Java面试题,有些答案很简单,需要读者在深度发掘,有的答案则很详细。我觉得想从事Java领域的人应该认真学习一下,另外企业的招聘人员也可以参考里面的相关题目。        http://www.roseindia.net/interviewquestions/corejava.shtml        http://java.sys-con.com

moneyice的专栏 3万+

大厂JAVA面试题

精心整理的近几年国内大厂的一些java面试题,希望对大家有所帮助

狗剩没有饭吃 1400

java面试题背不下来怎么办?java面试题总结

Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)。最近有很多java人员反映,说java面试题太多根本就背不下来,这可急坏了他们,毕竟要去面试java工作的,那么接下来,我们就来给大家讲解一下java面试题背不下来的解决方法。可以正确编译,因为s1+=1;...

m0_67401270的博客 1110

java面试题总结汇总

java面试题总结汇总 Java面试总结汇总,持续更新中… 序号 内容

更阑一霎的博客 747
上一篇: docker浅学
下一篇: 我的生活记(dz-cn)
o独酌o
博客等级 码龄3年 324粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值