Java基础知识大总结

503 阅读25分钟

一、Java基础

1、基本概念

  1. 什么是Java?
  2. Java与C++区别
  3. Java语言特点
  4. Java SE/EE/ME的区别
    • SE(标准版):Java的核心类库 + Java核心API + JVM + 开发工具
    • EE(企业版):Java SE + 企业级Java组件(EJB)、Web技术(JSP、Servlet等)、数据库访问、分布式对象通信、Web服务、系统集成、管理和部署等
    • ME(微型版):嵌入式设备和小型设开发
  5. Java如何实现跨平台?
  6. JDK、JRE、JVM三者关系
  7. “编译与解释并存”
  8. 为什么Java不支持多重继承?
    • 多个父类命名冲突、避免实现复杂性、转型困难
  9. Java常用的工具类

2、基本语法

  1. 标识符和关键字区别
  2. break、continue、return作用
    • 追问:两层循环内层break会咋样
  3. 什么是字节码?采用字节码的好处?
  4. 字节序定义以及Java属于哪种字节序?
    • 多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。在计算机中是以字节为单位,每个地址对应一个字节,一个字节8bit。通常有小端(低字节→低地址端,)、大端(低字节→高地址端,)两种方式。Java→大端
  5. 简述Java中Class对象
    • Java中对象(实例对象、Class对象)。每个类都有一个Class对象,其包含了与该类有关的信息。
    • 获取Class对象的方法:使用对象/类的getclass()方法、使用类的forName()方法、使用反射
  6. 数组去重有几种方法?
    • Set集合、双重循环、Stream API(数组→流,distinct()方法移除重复元素,结果→数组)、HashMap
  7. Java中对集合对象或者数组对象排序有几种实现方式?
    • 追问:Comparable 和 Comparator 的区别
  8. 数组和链表的区别
    • 存储方式、内存分配方式、插入和删除操作、存储容量、查找操作
  9. 数组中插入时空间不足会怎样?—(抛出一个ArrayIndexOutBoundException(数组越界异常))

3、基本数据类型

  1. Java基本数据类型有哪些?
    • 基本类型与引用类型两者区别(存储位置、传递方式)
  2. 值传递和引用传递
    • 值传递:将实际参数的复制一份,传递给函数的形式参数,函数中对形式参数的修改不会影响到实际参数的值。
    • 引用传递:将实际参数的地址或引用传递给函数的形式参数,函数中对形式参数的修改会影响到实际参数的值。
    • 两者区别在于传递的是实际参数的值还是地址(或引用),对形参的修改是否会影响实参。
  3. Java是按值传递还是按引用调用?
  4. 深拷贝和浅拷贝了解吗?什么是引用拷贝
  5. 基本类型和包装类型的区别
  6. 包装类型的缓存机制了解么?
  7. Java中包装类型的创建方法
    • 直接赋值、自动装箱、valueOf()方法
  8. 自动装箱与拆箱了解吗?原理是什么?
    • valueOf()、xxxValue()
  9. int和Integer的区别?int a=1, new Integer(1)是否相等?
    • 补充:int与 int 用 == 比较,为true。不能用equals比较
    • int 和 Integer 比较,== 和 equals都为true
    • int 和 new Integer比较,== 和 equals都为true
    • Integer 和 Integer 进行==比较的时候,在[-128,127]区间的时候,为true,否则为false;进行equals比较,为true
    • Integer 和 new Integer 进行==比较,为false;进行equals比较,为true
    • new Integer 和 new Integer进行==比较的时候,为false ; 进行equals比较,为true。

    补充:

    String str1="hello";
    String str2="he"+ new String("llo");
    String str3="hello";
    String str4=new String("Hello");
    String str5="hel"+"lo";
            
    System.out.println(str1==str2);
    System.out.println(str1==str3);
    System.out.println(str1==str4);
    System.out.println(str1==str5);
    

    这个代码的运行结果是

    false
    true
    false
    true
    
  10. Integer生成的两个对象可以用“==”直接进行比较吗?
    • (-128,127)内用==比较;其他用b.equals(a)进行比较
  11. Integer在拆包过程中有什么要注意?
    • 在integer对象拆箱的过程中,如果装箱时的值是null,会报NullPointerException异常
    • 范围检查:拆包操作时要检查对象是否在基本类型所能表示的范围内,否则可能会导致数值溢出。
    • 注意精度损失:拆包操作时要注意精度损失的问题。例如,将一个大于基本类型所能表示的最大值的Integer对象进行拆包操作,将会得到一个不可预期的结果
  12. switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?
  13. for each循环
    • for each循环可以用于哪些类型的集合?
    • for each循环和传统的for循环有什么区别?
    • for each循环的性能如何?
  14. 能否在foreach循环调用ArrayList的remove方法,为什么?
    • 不建议。
  15. a = a + b与 a += b的区别?
    • += 将+操作的结果类型强制转换为持有结果的类型
    • 而a = a + b则不会
  16. i++与++i
  17. 3 * 0.1==0.3将会返回什么?true还是false?

4、变量

  1. 全局变量和局部变量的区别
  2. 静态变量与实例变量的区别(重要!!
  3. 字符型常量和字符串常量的区别

二、面向对象

1、类与对象

  1. 对象的创建与使用
    • 对象名称保存在栈内存中,而对象的属性信息则保存在对应的堆内存中。
    • 堆内存:每一块堆内存的开辟都要通过new来完成。
    • 栈内存:(只能保存一块)堆内存空间的内存地址数值。
  2. 对象的引用与传递
    • 引用数据类型:类、数组、接口,引用数据类型就是指内存空间可以被多个栈内存引用
    • 一个栈内存空间只能指向一个堆内存空间,如果想要再指向其他堆内存空间,就必须先断开已有的指向后才能再分配新的指向
    • 引用传递形参和实参具有相同的储存单元,形参改变会影响实参的值
  3. Java创建对象有哪些方式?
    • new关键字、反射(调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法)、clone()、反序列
  4. 对象实体和对象引用有何不同?

2、private、default、protected、public

局部变量是没有访问权限控制的,局部成员只在其所在的作用域内起作用,不可能被其他类访问到。

3、构造方法

  1. 构造方法的概述
    • 类的一个特殊成员方法,类实例化对象时自动调用(只能执行一次),用于创建新的对象初始化对象的成员变量
    • 每个类都有(可以有多个)
    • 在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称与类名相等,一个类可以有多个构造方法
  2. 定义构造方法的注意点
    • 构造方法名称前不能有任何返回值类型声明,包括void。
    • 不能return返回一个值,可单独写return语句作为方法的结束。……
  3. 构造方法的重载
    • 一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。
  4. 构造器是否可被重写?——不可,……

4、重载(Overload)和重写(/覆盖)(Override)的区别?

  • 重写:父子类,子类方法名称、参数列表与父类相同(子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类)
  • 重载:同一类,方法名称相同、参数列表不同,返回类型可以相同也可以不同。
  1. 重写、重载的好处?
    • 重写:子类可根据需要定义自己的行为
    • 重载:让函数具有更多的功能
  2. 怎么重写父类方法?
  3. 重载的方法能否根据返回值类型进行区分?
  4. 重写中子类抛出的异常必须和父类一样吗?可以不抛出或者抛出比父类大的异常类型吗?

5、this关键字

  1. this和super有什么区别?this能调用到父类吗?
    • 指代对象不同(当前类/父类)、查找范围不同、本类属性赋值不同、this可用于synchronized
  2. this() & super()在构造方法中的区别?
    • 调用对象不同、调用位置不同、参数传递的方式不同、返回类型不同、调用方法不同

6、static关键字

  1. 说说你对static关键字的理解
  2. 为什么要用static关键字?(作用)
    • 共享变量、执行与类本身相关的任务
    • 加static的变量叫做静态变量;静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了;静态变量储存在方法区
  3. Java中是否可以覆盖/重写一个private或者是static的方法?
    • static方法可以被继承和重载,但是不能被覆盖。(静态方法不能动态绑定,重写是基于动态绑定的)
    • private方法不能被继承和覆盖,可以被重载。(父类不可见,无法继承、重写)
  4. static修饰的类(静态类)能不能被继承?——可以被继承,但是不能被重写
  5. 内部类

image.png

补充:静态内部类才可以声明静态方法静态方法不可以使用非静态变量

  1. 能否在static中访问非static?
    • 不可以。静态方法或静态代码块是属于类级别的,而非静态成员(非静态方法和非静态变量)是属于对象级别的,无法直接访问,可通过创建对象实例间接访问。

7、final关键字

  1. final、finally、finalize的区别?(高频)
  2. 如果final修饰了一个属性可以什么时候进行初始化
    • 定义时或在类的构造函数中进行初始化(初始化只能进行一次!)

8、Java代码块执行顺序

  1. 父类静态代码块(只执行一次)
  2. 子类静态代码块(只执行一次)
  3. 父类构造代码块
  4. 父类构造函数
  5. 子类构造代码块
  6. 子类构造函数
  7. 普通代码块

9、构造方法、成员变量初始化以及静态成员变量三者的初始化顺序?

先后顺序:静态成员变量、成员变量、构造方法。

详细的先后顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。

10、面向对象和面向过程的区别

  • 面向对象(OOP):分解为各个对象,分别设计对象,再组装。
  • 面向过程(POP):分析步骤,按步骤实现。

11、面向对象四大特征(封装、继承、多态、抽象)

封装

  1. 定义
  2. 目的:
    • 隐藏类的实现细节,便于修改内部代码,提高可维护性
    • 简化外部调用,便于扩展和使用

继承

  1. 定义
  2. 注意点:
      1. 子类拥有父类对象所有的属性和方法,但是父类中的私有属性和方法子类是无法访问,只是拥有

多态

  1. 定义
  2. 运行时多态的三个条件——(1)继承;(2)覆盖(重写);(3)向上转型
  3. 好处与弊端?如何解决多态的缺陷
    • 好处:可扩展、灵活、代码复用、降低了耦合性
    • 弊端:性能问题、可读性问题、隐藏细节
    • 解决方法:缓存对象类型、显式类型转换、使用静态绑定...

补充:

  1. 多态存在的三个必要条件——(1)继承;(2)重写;(3)父类引用指向子类对象
  2. 多态的具体体现
    • 编译类型看定义对象时 = 号的左边,运行类型看 = 号的右边
  3. 多态的实现方式
    • 方法覆盖(覆盖、重写)、抽象类和接口方法重载(重载、重复载入)
  4. 多态的实现原理是什么?
    • 通过多态性来实现(或通过Java的动态绑定来实现的)
  5. 多态的转型
  6. 动态绑定
  7. ……

抽象

  1. 定义

JDK中对封装、继承、多态的典型应用?

12、接口和抽象类

  1. 接口和抽象类的区别是什么?
  2. 接口和抽象类的相同点
  3. 既然有了抽象类,为什么 Java还要不辞辛苦地引入接口?
    • 一个类可以实现多个接口,但是一个类只能继承一个父类
  4. 接口中可以有构造函数吗?
    • 不能。接口里可以包含成员变量(只能是静态常量)、方法(只能是抽象实例方法、类方法、默认方法或私有方法)、内部类(包括内部接口、枚举)定义。
  5. 面向接口编程的理解
    • 核心是面向抽象编程。只关注对象应该做什么,而不关注对象具体是如何实现的。
  6. 抽象类(abstract class)和接口(interface)的应用场景

15、compator和compatable的区别

16、一个Java文件里可以有多个类吗(不含内部类)

  • 一个java文件里可以有多个类,但最多只能有一个被public修饰的类;
  • 如果这个java文件中包含public修饰的类,则这个类的名称必须和java文件名一致。

17、异常

18、Java API

三、集合、迭代器(Iterator)

1、集合概述

  1. 如何选用集合?
    • 根据键值获取元素值,选Map接口下的集合。
    • 只存放元素值,选Collection接口的集合。
  2. Java中线程安全的集合有哪些?
    • Vector、Stack、Hashtable、Collections包装方法、ConcurrentHashMap、CopyOnWriteArrayList、其他并发实现类
  3. Collection和Collections有什么区别?
    • Collection集合接口
    • Collections不属于集合框架,它是集合类的一个工具类/帮助类。不能被实例化,服务于Collection框架
  4. Collections常用方法
  5. Arrays.sort和Collections.sort?

2、List

  1. Vector和Stack
  2. ArrayList和Vector区别?
    • 线程安全(不安全、安全)、扩容机制(增1倍,增原来的一半)、性能、应用场景(多线程、单线程)
  3. ArrayList了解吗?
  4. Linkedlist了解吗?
  5. ArrayList和Linkedlist的区别、使用场景
  6. 场景:有一堆数据不知道大小,ArrayList存好还是LinkedList存好?
  7. 数据非常大,用ArrayList和LinkedList哪个空间浪费大?
  8. 既然有数组,为什么还要用ArrayList和Linkedlist?
    • 大小可变、插入和删除元素的效率、内存利用率、线程安全性

ArrayList扩容机制

  1. 说说ArrayList的扩容机制
    • 初始赋值是空数组,添加第一个元素容量扩为10,插入个数大于当前容量,扩容1.5倍
    • 底层数组已满,创建一个新的数组,将原来元素复制到新数组
  2. 扩容的数组为什么是原数组的1.5倍?
    • 这个倍数的选择是为了在不断添加元素时,尽可能减少扩容的次数,从而优化性能。…
  3. ArrayList扩容,数组特别大会有什么问题?
    • 效率低,占内存
  4. ArrayList是怎么添加/删除元素的?
    • 添加:add、addAll;删除:remove、removeAll
  5. ArrayList怎么删除奇数位元素?
    • 循环(i+=2)

✎其他

  1. List采用for each调用了remove方*** 抛出什么异常?为什么?
    • ConcurrentModificationException异常(并发修改异常)
  2. 如何实现List集合去重?
  3. List集合遍历的方式有哪些?
    • Iterator接口
    • 普通for循环
    • 增强for
    • List集合自有迭代器
    • Lambda
  4. ArrayList内存分配在什么位置?
    • 堆内存
  5. 场景:存储对象类型为person的对象,然后里面有name属性,需求是按照name查找,用哪个存好?
  6. stream遍历ArrayList
    • list.stream().forEach(System.out::println);
  7. 怎么提高ArrayList的增删效率?
  8. 如何使ArrayList变得线程安全

3、Map

  1. HashMap与HashTable/TreeMap/HashSet的区别
  2. HashMap、HashTable和ConcurrentHashMap三者的区别?
  3. LinkedHashMap/LinkedList如何保证节点顺序?
  4. HashMap的底层实现、扩容机制?
  5. 线程安全的Map有哪些?
    • 安全的有:HashTable、SynchronizedMap、ConcurrentHashMap
    • 不安全的有:HashMap、TreeMap
  6. HashMap是否线程安全?
    • 在jdk1.7中,在多线程环境下,扩容时会造成 环形链 或 数据丢失
    • 在jdk1.8中,在多线程环境下,会发生 数据覆盖 的情况
  7. HashMap线程不安全。是哪一步不安全?怎么解决不安全呢?
    • 扩容操作、put操作、resize操作
    • 使用ConcurrentHashMap、Collections.synchronizedMap()、使用线程安全的Map实现、使用锁(Lock)、使用volatile关键字
  8. HashMap有几种遍历方法?推荐使用哪种?(map遍历也是类似)
    • jdk8之前:EntrySet、KeySet
    • jdk8之后:Lambda、Stream单线程、Stream多线程

HashMap底层原理、扩容

  1. 说说HashMap的底层实现
  2. 数组和链表区别(存储方式、插入和删除、随机访问、内存占用)
  3. hashmap哈希算法详解
    • 把任意长度值(Key)通过散列算法变换成固定长度的地址(key)
    • 把关键码值映射到表中一个位置来访问记录
  4. 哈希冲突产生原因详解
    • HashMap引入链表来解决哈希冲突。
  5. HashMap默认加载因子为什么是0.75?
    • 对空间和时间效率的一个平衡选择
  6. JDK1.8以后为什么引入红黑树?
    • 为了提高HashMap的查询效率
  7. HashMap为什么用红黑树,而不是B+树或B树?
    • 红黑树使用普通的指针来实现红黑树节点之间的连接,而B+树或B树需要使用指针数组来实现节点之间的连接,这会导致B+树或B树的空间占用更大
    • 为了避免出现hash冲突时链表过长的情况
  8. 为什么JDK1.8中红黑树阈值设为8?
    • 和hashcode碰撞次数的泊松分布有关,主要是为了寻找一种时间和空间的平衡。
  9. 扩容过程
    • 1.创建新的Entry数组,长度为原数组2倍
    • 2.遍历,重新计算哈希值,存储到新数组
    • 3.将新数组设置为当前数组,并释放原数组空间
  10. HashMap的put/get/resize方法的执行过程?
    • put:1. 根据key计算出存储位置;2. 检查该位置,存在则比较key的hashCode和equals方法,相等则覆盖。不存在则将新的key-value插入;3. 容量超过阈值则重新计算key存储位置
    • get:1(同上);2. 检查该位置,存在则比较key的hashCode和equals方法,相等则返回value,不存在则返回null
    • resize:1. 根据hashmap容量计算出新的容量;2. 创建新的hashmap并将原来的拷贝过来;3. 将新的赋值给原来的hashmap
  11. HashMap扩容原数组怎么处理的?一定会回收吗?
    • 将原数组中的元素重新分配到新数组中,然后释放原数组的内存空间
    • 不是立即回收,等待垃圾回收器来回收
  12. HashMap的内部类Entry结点,这个Entry类实例里面有什么数据?
    • key、value、hash、next
  13. 什么对象可以作为 hashmap 的 key
  14. hashmap创建一个初始化为10的对象之后容量会是多少?
  15. HashMap是如何实现元素查找的?
  16. 为什么HashMap会产生死循环?
  17. JDK1.7和1.8的Hashmap有哪些区别?
    • 插入方式不同(头插、尾插)、扩容后数据存储位置的计算方式不同、hash计算规则不同、底层数据结构不同

ConcurrentHashMap

  1. JDK1.7 和 JDK1.8 的 ConcurrentHashMap 实现有什么不同?
    • 线程安全实现方式:1.7采用Segment分段锁;1.8采用 Node + CAS + synchronized
    • Hash碰撞解决方法:1.7采用拉链法;1.8采用拉链法结合红黑树
    • 并发度:1.7最大并发度是Segment个数,默认16;1.8最大并发度是Node数组大小,并发度更大
  2. ConcurrentHashMap是如何保证线程安全的?
    • jdk1.7:数组(大数组Segment和小数组HashEntry)+链表。给Segment添加ReentrantLock重入锁来保证线程安全
    • jdk1.8:数组+链表+红黑树。通过 CAS 或者 synchronized 来保证线程安全。
  3. ConcurrentHashMap 和 Hashtable 哪个效率更高?
    • ConcurrentHashMap高,因为Hashtable给整个哈希表加了一把大锁从而实现线程安全。
  4. HashTable和CurrentHashMap在并发处理上的区别?
  5. ConcurrentHashMap在性能方面做的优化

4、Set

  1. HashSet、LinkedHashSet 和 TreeSet 三者的异同
  2. HashSet与HashMap的区别?——存储方式、唯一性、对null的支持、底层数据结构、使用场景
  3. 如何遍历Set?
    • for-each循环、Iterator遍历
  4. 如何判断一个元素是否在Set中存在?——使用contains方法
  5. HashSet如何判断两个对象是否相等?——使用equals和hashcode()方法
  6. HashSet如何保证元素不重复?(如何去重)
  7. HashSet 的 value 为什么用 Object 而不用 null,效率更高而且还省得创建对象了?
    • HashSet依赖于哈希码来判断元素是否重复。如果value为null,无法得出它的哈希码,从而无法进行比较和判断。而使用Object类型可通过hashCode()和equals()方法来判断元素是否相等,进行去重
  8. TreeSet如何保证元素有序?——红黑树
  9. HashSet底层原理——底层是HashMap,……
  10. 自己定义对象放到set里会去重吗?——不会

5、迭代器(Interator)

  1. 迭代器概念
    • 是一种用于访问集合的方法(是集合框架的一种机制)(只能单向遍历,从前到后)
  2. 获取一个迭代器
    • 使用iterator()方法
  3. 循环集合元素
  4. for循环和迭代器遍历的区别
    • for在指定范围进行循环遍历,迭代器通过对象来遍历集合元素
    • for适用于知道集合元素数量的情况,迭代器适用于不知集合元素数量的情况

四、JDK 1.8 新特性

  1. 在接口中提供默认的方法实现(有点像抽象类)
  2. Lambda表达式(是一种匿名函数)
    • 使代码简洁紧凑,让Java也能支持简单的函数式编程
    • Lambda允许把函数作为一个方法的参数(传递到方法中)。入参是一个List集合和一个Comparator 比较器。
  3. lambda表达式作用范围
    • 访问外部的变量(局部变量,成员变量,静态变量,接口的默认方法)
  4. 函数式接口(Functional Interface)
    • 函数式接口有且仅有一个抽象方法,可以有多个非抽象方法的接口。
    • 只有那些函数式接口才能缩写成 Lambda 表示式
  5. Stream API
  • 方法(/API?)作用
    forEach对流中的每个数据进行操作(迭代)
    map映射每个元素到对应的结果
    filter通过设置的条件过滤出元素
    limit获取指定数量的流
    sorted对流进行排序
    reduce将流中的元素进行合并
    collect将流转换为指定数据类型的集合
    toArray返回包含元素中所有元素的数组
  1. Optionals
    • 设计它的目的是为了防止空指针异常
  2. Parallel-Streams并行流

五、Object和String

1、Object

Object是所有Java类的根类(不要怀疑!!)

  1. Object类的常见方法有哪些?
    • equals、hashCode、toString、getClass、notify、notifyAll、clone、wait、finalize
  2. ==和equals()的区别
    • 类没重写equals()方法,则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
    • 类重写了equals() 方法。若两个对象的内容相等,则返回 true (即,认为这两个对象相等)。
  3. hashCode()的作用
    • 用于获取一个对象的哈希码
    • 提高对象查找速度
  4. hashCode()、equals()的关系?
  5. 为什么要重写hashCode和equals()方法?
  6. 重写equals和hashCode时要注意什么?
    • 为什么“如果两个对象的 equals 相同,那么这两个对象的 hashCode 一定相同,但是反过来不一定”
    • 为什么重写equals()就一定要重写hashCode()方法?(重点!)
    • 如果同一个类中的两个对象hashCode相同,但是equals不同会出现什么问题?
  7. 对象的相等和引用相等的区别?

深、浅拷贝了解吗?什么是引用拷贝?

  1. 深、浅拷贝定义
    • 深:拷贝对象本身(创建一个新对象)。互不影响。可通过序列化和反序列化、使用ObjectInputStream和ObjectOutputStream来实现。
    • 浅:仅拷贝对象的引用。共享同一个引用,相互影响。clone()来实现。
  2. 深、浅拷贝区别
  3. 引用拷贝
    • 引用拷贝就是拷贝引用地址,两个不同的引用指向同一个对象。
    • 引用拷贝分为深拷贝和浅拷贝。
  4. 深拷贝怎么实现?
    • 使用JSON.parse() 和 JSON.stringify() 方法(序列化和反序列化)
    • 递归地遍历原始对象并创建新的对象
    • 使用 jQuery 的 extend 方法

2、String

  1. String类有哪些方法?
    • charAt、substring、split、trim、indexOf、startsWith、endsWith…
  2. String、StringBuffer、StringBuilder 的区别?
  3. 为什么String是不可变的,而StringBuffer和StringBuilder是可变的?
    • StringBuffer和StringBuilder内部实际上是一个char[]数组,它没有被final修饰。
  4. 为什么String设计为不可变的?(为什么用final修饰)
    • 避免被修改引起问题、线程安全、编译期优化、…
  5. String创建对象的几种场景?
    • 使用双引号、new、字符数组、valueOf()转换
  6. String最大长度是多少?——2^31 -1(length方法返回值为int类型)
  7. String a = "abc"; 说一下这个过程会创建什么,放在哪里?
  8. new String("abc") 是去了哪里,仅仅是在堆里面吗?
  9. new String("hello")创建了几个字符串对象?
  10. String可以被继承吗?
  11. Java对字符串做过哪些优化?

六、泛型、反射、注解

1、泛型

  1. 说说你对泛型的理解
    • 参数化类型。创建集合时指定集合元素的类型
    • 可在编译时检查类型安全。
  2. 简述泛型擦除
    • 编译时将泛型类型参数的具体类型擦除掉,使用Object类型来替代
    • 注意:泛型擦除在编译阶段实现的,仍然可以通过使用反射等机制获取泛型类型参数的具体类型信息
  3. List<? super T>和List<? extends T>有什么区别?
  4. 泛型的使用方式有哪几种?
    • 泛型类、泛型接口、泛型方法
  5. 泛型的高级用法
    • 限制泛型可用类型、使用类型通配符、继承泛型类和实现泛型接口
  6. 项目中哪里用到了泛型?

2、反射

image.png

  1. 反射概念
    • 运行时,动态获取一个类的信息,且运行时可修改类的行为
    • java.lang.reflect来实现反射相关的类库:ConstructFieldMethodClass(构造方法、成员变量、方法信息和属性方法)
  2. 反射的实现方式(获取Class对象的几种方法)
  3. new 和 反射创建有什么区别?
    • new:静态编译
    • 反射:动态编译
    • new创建效率比较高。通过反射时,先找查找类资源,使用类加载器创建,过程繁琐效率低。
  4. 反射优缺点
    • 优点:灵活、提高代码复用率、动态调用
    • 缺点:性能问题、模糊内部逻辑、内部暴露、安全问题
  5. 反射提供了哪些功能
  6. 实现Java反射的类有?
  7. 反射API
  8. 反射使用步骤(获取Class对象、调用对象方法)
  9. 利用发射动态创建对象实例(Class对象的newInstance())
  10. 反射的应用场景?
    • JDK动态代理
    • 注解/XML配置
    • 用JDBC连接数据库
    • Spring框架

3、注解

  1. 什么是注解?
    • jdk1.5引入,特殊的注释。可被编译器打包进入class文件。是一种用于标记的“元数据
    • @ 符号开头的
  2. 注解的作用
    • 生成帮助文档
    • 跟踪代码依赖性,实现替代配置文件功能
    • 在编译时进行格式检查
  3. 简述元注解(注解的注解)

七、I/O、NIO、序列化和反序列化

1、IO/NIO

  1. IO流分为几种?
  2. Java中的IO是什么?
    • Java把不同的输入/输出源抽象表述为流
  3. 字节流和字符流的区别?
  4. I/O阻塞发生在哪里
    • 等待数据传输的过程中
  5. 怎么用流打开一个大文件
    • 分次读取。(1)采用缓冲流;(2)使用NIO
  6. Java中的NIO是什么
    • 三部分(缓冲区Buffer、通道Channel、选择器Selector)
  7. IO/NIO的区别

2、序列化和反序列化

  1. 什么是序列化?反序列化?
    • 对象的持久化、网络传输
    • 序列化:数据结构/对象→二进制字节流(字节序列)
    • 反序列化:与序列化相反 -
  2. 如何实现序列化和反序列化?
    • (1)实现Serializable接口
    • (2)使用ObjectOutputStream和ObjectInputStream类
    • (3)使用JSON等方式

八、其他

1、lombok

  1. 如何安装lombok?
    • IDEA或Eclipse中安装lombok插件。(方法1:向lib文件夹中添加lombok.jar包;方法2:Maven项目中,在pom.xml文件中添加lombok依赖)
  2. lombok注解用过吗?
    • @Data
    • @Setter
    • @ToString
    • @EqualsAndHashCode
    • @NonNull
    • @NonArgsConstructor
    • @AllArgsConstructor

2、