一、Java基础
1、基本概念
- 什么是Java?
- Java与C++区别
- Java语言特点
- Java SE/EE/ME的区别
- SE(标准版):Java的核心类库 + Java核心API + JVM + 开发工具
- EE(企业版):Java SE + 企业级Java组件(EJB)、Web技术(JSP、Servlet等)、数据库访问、分布式对象通信、Web服务、系统集成、管理和部署等
- ME(微型版):嵌入式设备和小型设开发
- Java如何实现跨平台?
- JDK、JRE、JVM三者关系
- “编译与解释并存”
- 为什么Java不支持多重继承?
- 多个父类命名冲突、避免实现复杂性、转型困难
- Java常用的工具类
2、基本语法
- 标识符和关键字区别
- break、continue、return作用
- 追问:两层循环内层break会咋样
- 什么是字节码?采用字节码的好处?
- 字节序定义以及Java属于哪种字节序?
- 多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。在计算机中是以字节为单位,每个地址对应一个字节,一个字节8bit。通常有小端(低字节→低地址端,)、大端(低字节→高地址端,)两种方式。Java→大端
- 简述Java中Class对象
- Java中对象(实例对象、Class对象)。每个类都有一个Class对象,其包含了与该类有关的信息。
- 获取Class对象的方法:使用对象/类的getclass()方法、使用类的forName()方法、使用反射
- 数组去重有几种方法?
- Set集合、双重循环、Stream API(数组→流,distinct()方法移除重复元素,结果→数组)、HashMap
- Java中对集合对象或者数组对象排序有几种实现方式?
- 追问:Comparable 和 Comparator 的区别
- 数组和链表的区别
- 存储方式、内存分配方式、插入和删除操作、存储容量、查找操作
- 数组中插入时空间不足会怎样?—(抛出一个ArrayIndexOutBoundException(数组越界异常))
3、基本数据类型
- Java基本数据类型有哪些?
- 基本类型与引用类型两者区别(存储位置、传递方式)
- 值传递和引用传递
- 值传递:将实际参数的值复制一份,传递给函数的形式参数,函数中对形式参数的修改不会影响到实际参数的值。
- 引用传递:将实际参数的地址或引用传递给函数的形式参数,函数中对形式参数的修改会影响到实际参数的值。
- 两者区别在于传递的是实际参数的值还是地址(或引用),对形参的修改是否会影响实参。
- Java是按值传递还是按引用调用?
- 深拷贝和浅拷贝了解吗?什么是引用拷贝
- 基本类型和包装类型的区别
- 包装类型的缓存机制了解么?
- Java中包装类型的创建方法
- 直接赋值、自动装箱、valueOf()方法
- 自动装箱与拆箱了解吗?原理是什么?
- valueOf()、xxxValue()
- 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 - Integer生成的两个对象可以用“==”直接进行比较吗?
- (-128,127)内用==比较;其他用b.equals(a)进行比较
- Integer在拆包过程中有什么要注意?
- 在integer对象拆箱的过程中,如果装箱时的值是null,会报NullPointerException异常
- 范围检查:拆包操作时要检查对象是否在基本类型所能表示的范围内,否则可能会导致数值溢出。
- 注意精度损失:拆包操作时要注意精度损失的问题。例如,将一个大于基本类型所能表示的最大值的Integer对象进行拆包操作,将会得到一个不可预期的结果
- switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?
- for each循环
- for each循环可以用于哪些类型的集合?
- for each循环和传统的for循环有什么区别?
- for each循环的性能如何?
- 能否在foreach循环调用ArrayList的remove方法,为什么?
- 不建议。
- a = a + b与 a += b的区别?
- += 将
+操作的结果类型强制转换为持有结果的类型。 - 而a = a + b则不会
- += 将
- i++与++i
- 3 * 0.1==0.3将会返回什么?true还是false?
4、变量
- 全局变量和局部变量的区别
- 静态变量与实例变量的区别(重要!!)
- 字符型常量和字符串常量的区别
二、面向对象
1、类与对象
- 对象的创建与使用
- 对象名称保存在栈内存中,而对象的属性信息则保存在对应的堆内存中。
- 堆内存:每一块堆内存的开辟都要通过new来完成。
- 栈内存:(只能保存一块)堆内存空间的内存地址数值。
- 对象的引用与传递
- 引用数据类型:类、数组、接口,引用数据类型就是指内存空间可以被多个栈内存引用
- 一个栈内存空间只能指向一个堆内存空间,如果想要再指向其他堆内存空间,就必须先断开已有的指向后才能再分配新的指向
- 引用传递形参和实参具有相同的储存单元,形参改变会影响实参的值
- Java创建对象有哪些方式?
- new关键字、反射(调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法)、clone()、反序列
- 对象实体和对象引用有何不同?
2、private、default、protected、public
局部变量是没有访问权限控制的,局部成员只在其所在的作用域内起作用,不可能被其他类访问到。
3、构造方法
- 构造方法的概述
- 类的一个特殊成员方法,类实例化对象时自动调用(只能执行一次),用于创建新的对象和初始化对象的成员变量。
- 每个类都有(可以有多个)
- 在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称与类名相等,一个类可以有多个构造方法。
- 定义构造方法的注意点
- 构造方法名称前不能有任何返回值类型声明,包括void。
- 不能return返回一个值,可单独写return语句作为方法的结束。……
- 构造方法的重载
- 一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。
- 构造器是否可被重写?——不可,……
4、重载(Overload)和重写(/覆盖)(Override)的区别?
- 重写:父子类,子类方法名称、参数列表与父类相同(子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类)
- 重载:同一类,方法名称相同、参数列表不同,返回类型可以相同也可以不同。
- 重写、重载的好处?
- 重写:子类可根据需要定义自己的行为
- 重载:让函数具有更多的功能
- 怎么重写父类方法?
- 重载的方法能否根据返回值类型进行区分?
- 重写中子类抛出的异常必须和父类一样吗?可以不抛出或者抛出比父类大的异常类型吗?
5、this关键字
- this和super有什么区别?this能调用到父类吗?
- 指代对象不同(当前类/父类)、查找范围不同、本类属性赋值不同、this可用于synchronized
- this() & super()在构造方法中的区别?
- 调用对象不同、调用位置不同、参数传递的方式不同、返回类型不同、调用方法不同
6、static关键字
- 说说你对static关键字的理解
- 为什么要用static关键字?(作用)
- 共享变量、执行与类本身相关的任务
- 加static的变量叫做静态变量;静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了;静态变量储存在方法区
- Java中是否可以覆盖/重写一个private或者是static的方法?
- static方法可以被继承和重载,但是不能被覆盖。(静态方法不能动态绑定,重写是基于动态绑定的)
- private方法不能被继承和覆盖,可以被重载。(父类不可见,无法继承、重写)
- static修饰的类(静态类)能不能被继承?——可以被继承,但是不能被重写
- 内部类
补充:静态内部类才可以声明静态方法;静态方法不可以使用非静态变量
- 能否在static中访问非static?
- 不可以。静态方法或静态代码块是属于类级别的,而非静态成员(非静态方法和非静态变量)是属于对象级别的,无法直接访问,可通过创建对象实例间接访问。
7、final关键字
- final、finally、finalize的区别?(高频)
- 如果final修饰了一个属性可以什么时候进行初始化
- 定义时或在类的构造函数中进行初始化(初始化只能进行一次!)
8、Java代码块执行顺序
- 父类静态代码块(只执行一次)
- 子类静态代码块(只执行一次)
- 父类构造代码块
- 父类构造函数
- 子类构造代码块
- 子类构造函数
- 普通代码块
9、构造方法、成员变量初始化以及静态成员变量三者的初始化顺序?
先后顺序:静态成员变量、成员变量、构造方法。
详细的先后顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。
10、面向对象和面向过程的区别
- 面向对象(OOP):分解为各个对象,分别设计对象,再组装。
- 面向过程(POP):分析步骤,按步骤实现。
11、面向对象四大特征(封装、继承、多态、抽象)
☺封装
- 定义
- 目的:
- 隐藏类的实现细节,便于修改内部代码,提高可维护性
- 简化外部调用,便于扩展和使用
☺继承
- 定义
- 注意点:
-
- 子类拥有父类对象所有的属性和方法,但是父类中的私有属性和方法子类是无法访问,只是拥有。
-
☺多态
- 定义
- 运行时多态的三个条件——(1)继承;(2)覆盖(重写);(3)向上转型
- 好处与弊端?如何解决多态的缺陷
- 好处:可扩展、灵活、代码复用、降低了耦合性
- 弊端:性能问题、可读性问题、隐藏细节
- 解决方法:缓存对象类型、显式类型转换、使用静态绑定...
补充:
- 多态存在的三个必要条件——(1)继承;(2)重写;(3)父类引用指向子类对象
- 多态的具体体现
- 编译类型看定义对象时 = 号的左边,运行类型看 = 号的右边
- 多态的实现方式
- 方法覆盖(覆盖、重写)、抽象类和接口、方法重载(重载、重复载入)
- 多态的实现原理是什么?
- 通过多态性来实现(或通过Java的动态绑定来实现的)
- 多态的转型
- 动态绑定
- ……
☺抽象
- 定义
JDK中对封装、继承、多态的典型应用?
12、接口和抽象类
- 接口和抽象类的区别是什么?
- 接口和抽象类的相同点
- 既然有了抽象类,为什么 Java还要不辞辛苦地引入接口?
- 一个类可以实现多个接口,但是一个类只能继承一个父类
- 接口中可以有构造函数吗?
- 不能。接口里可以包含成员变量(只能是静态常量)、方法(只能是抽象实例方法、类方法、默认方法或私有方法)、内部类(包括内部接口、枚举)定义。
- 面向接口编程的理解
- 核心是面向抽象编程。只关注对象应该做什么,而不关注对象具体是如何实现的。
- 抽象类(abstract class)和接口(interface)的应用场景
15、compator和compatable的区别
16、一个Java文件里可以有多个类吗(不含内部类)
- 一个java文件里可以有多个类,但最多只能有一个被public修饰的类;
- 如果这个java文件中包含public修饰的类,则这个类的名称必须和java文件名一致。
17、异常
18、Java API
三、集合、迭代器(Iterator)
1、集合概述
- 如何选用集合?
- 根据键值获取元素值,选Map接口下的集合。
- 只存放元素值,选Collection接口的集合。
- Java中线程安全的集合有哪些?
- Vector、Stack、Hashtable、Collections包装方法、ConcurrentHashMap、CopyOnWriteArrayList、其他并发实现类
- Collection和Collections有什么区别?
- Collection集合接口
- Collections不属于集合框架,它是集合类的一个工具类/帮助类。不能被实例化,服务于Collection框架
- Collections常用方法
- Arrays.sort和Collections.sort?
2、List
- Vector和Stack
- ArrayList和Vector区别?
- 线程安全(不安全、安全)、扩容机制(增1倍,增原来的一半)、性能、应用场景(多线程、单线程)
- ArrayList了解吗?
- Linkedlist了解吗?
- ArrayList和Linkedlist的区别、使用场景
- 场景:有一堆数据不知道大小,ArrayList存好还是LinkedList存好?
- 数据非常大,用ArrayList和LinkedList哪个空间浪费大?
- 既然有数组,为什么还要用ArrayList和Linkedlist?
- 大小可变、插入和删除元素的效率、内存利用率、线程安全性
✍ArrayList扩容机制
- 说说ArrayList的扩容机制
- 初始赋值是空数组,添加第一个元素容量扩为10,插入个数大于当前容量,扩容1.5倍
- 底层数组已满,创建一个新的数组,将原来元素复制到新数组
- 扩容的数组为什么是原数组的1.5倍?
- 这个倍数的选择是为了在不断添加元素时,尽可能减少扩容的次数,从而优化性能。…
- ArrayList扩容,数组特别大会有什么问题?
- 效率低,占内存
- ArrayList是怎么添加/删除元素的?
- 添加:add、addAll;删除:remove、removeAll
- ArrayList怎么删除奇数位元素?
- 循环(i+=2)
✎其他
- List采用for each调用了remove方*** 抛出什么异常?为什么?
- ConcurrentModificationException异常(并发修改异常)
- 如何实现List集合去重?
- List集合遍历的方式有哪些?
- Iterator接口
- 普通for循环
- 增强for
- List集合自有迭代器
- Lambda
- ArrayList内存分配在什么位置?
- 堆内存
- 场景:存储对象类型为person的对象,然后里面有name属性,需求是按照name查找,用哪个存好?
- stream遍历ArrayList
list.stream().forEach(System.out::println);
- 怎么提高ArrayList的增删效率?
- 如何使ArrayList变得线程安全
3、Map
- HashMap与HashTable/TreeMap/HashSet的区别
- HashMap、HashTable和ConcurrentHashMap三者的区别?
- LinkedHashMap/LinkedList如何保证节点顺序?
- HashMap的底层实现、扩容机制?
- 线程安全的Map有哪些?
- 安全的有:HashTable、SynchronizedMap、ConcurrentHashMap
- 不安全的有:HashMap、TreeMap
- HashMap是否线程安全?
- 在jdk1.7中,在多线程环境下,扩容时会造成 环形链 或 数据丢失
- 在jdk1.8中,在多线程环境下,会发生 数据覆盖 的情况
- HashMap线程不安全。是哪一步不安全?怎么解决不安全呢?
- 扩容操作、put操作、resize操作
- 使用ConcurrentHashMap、Collections.synchronizedMap()、使用线程安全的Map实现、使用锁(Lock)、使用volatile关键字
- HashMap有几种遍历方法?推荐使用哪种?(map遍历也是类似)
- jdk8之前:EntrySet、KeySet
- jdk8之后:Lambda、Stream单线程、Stream多线程
✍HashMap底层原理、扩容
- 说说HashMap的底层实现
- 数组和链表区别(存储方式、插入和删除、随机访问、内存占用)
- hashmap哈希算法详解
- 把任意长度值(Key)通过散列算法变换成固定长度的地址(key)
- 把关键码值映射到表中一个位置来访问记录
- 哈希冲突产生原因详解
- HashMap引入链表来解决哈希冲突。
- HashMap默认加载因子为什么是0.75?
- 对空间和时间效率的一个平衡选择
- JDK1.8以后为什么引入红黑树?
- 为了提高HashMap的查询效率
- HashMap为什么用红黑树,而不是B+树或B树?
- 红黑树使用普通的指针来实现红黑树节点之间的连接,而B+树或B树需要使用指针数组来实现节点之间的连接,这会导致B+树或B树的空间占用更大
- 为了避免出现hash冲突时链表过长的情况
- 为什么JDK1.8中红黑树阈值设为8?
- 和hashcode碰撞次数的泊松分布有关,主要是为了寻找一种时间和空间的平衡。
- 扩容过程
- 1.创建新的Entry数组,长度为原数组2倍
- 2.遍历,重新计算哈希值,存储到新数组
- 3.将新数组设置为当前数组,并释放原数组空间
- 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
- HashMap扩容原数组怎么处理的?一定会回收吗?
- 将原数组中的元素重新分配到新数组中,然后释放原数组的内存空间。
- 不是立即回收,等待垃圾回收器来回收
- HashMap的内部类Entry结点,这个Entry类实例里面有什么数据?
- key、value、hash、next
- 什么对象可以作为 hashmap 的 key
- hashmap创建一个初始化为10的对象之后容量会是多少?
- HashMap是如何实现元素查找的?
- 为什么HashMap会产生死循环?
- JDK1.7和1.8的Hashmap有哪些区别?
- 插入方式不同(头插、尾插)、扩容后数据存储位置的计算方式不同、hash计算规则不同、底层数据结构不同
✍ConcurrentHashMap
- 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数组大小,并发度更大
- ConcurrentHashMap是如何保证线程安全的?
- jdk1.7:数组(大数组Segment和小数组HashEntry)+链表。给Segment添加ReentrantLock重入锁来保证线程安全
- jdk1.8:数组+链表+红黑树。通过 CAS 或者 synchronized 来保证线程安全。
- ConcurrentHashMap 和 Hashtable 哪个效率更高?
- ConcurrentHashMap高,因为Hashtable给整个哈希表加了一把大锁从而实现线程安全。
- HashTable和CurrentHashMap在并发处理上的区别?
- ConcurrentHashMap在性能方面做的优化
4、Set
- HashSet、LinkedHashSet 和 TreeSet 三者的异同
- HashSet与HashMap的区别?——存储方式、唯一性、对null的支持、底层数据结构、使用场景
- 如何遍历Set?
- for-each循环、Iterator遍历
- 如何判断一个元素是否在Set中存在?——使用contains方法
- HashSet如何判断两个对象是否相等?——使用equals和hashcode()方法
- HashSet如何保证元素不重复?(如何去重)
- HashSet 的 value 为什么用 Object 而不用 null,效率更高而且还省得创建对象了?
- HashSet依赖于哈希码来判断元素是否重复。如果value为null,无法得出它的哈希码,从而无法进行比较和判断。而使用Object类型可通过hashCode()和equals()方法来判断元素是否相等,进行去重
- TreeSet如何保证元素有序?——红黑树
- HashSet底层原理——底层是HashMap,……
- 自己定义对象放到set里会去重吗?——不会
5、迭代器(Interator)
- 迭代器概念
- 是一种用于访问集合的方法(是集合框架的一种机制)(只能单向遍历,从前到后)
- 获取一个迭代器
- 使用iterator()方法
- 循环集合元素
- for循环和迭代器遍历的区别
- for在指定范围进行循环遍历,迭代器通过对象来遍历集合元素
- for适用于知道集合元素数量的情况,迭代器适用于不知集合元素数量的情况
四、JDK 1.8 新特性
- 在接口中提供默认的方法实现(有点像抽象类)
- Lambda表达式(是一种匿名函数)
- 使代码简洁紧凑,让Java也能支持简单的函数式编程
- Lambda允许把函数作为一个方法的参数(传递到方法中)。入参是一个List集合和一个Comparator 比较器。
- lambda表达式作用范围
- 访问外部的变量(局部变量,成员变量,静态变量,接口的默认方法)
- 函数式接口(Functional Interface)
- 函数式接口有且仅有一个抽象方法,可以有多个非抽象方法的接口。
- 只有那些函数式接口才能缩写成 Lambda 表示式
- Stream API
-
方法(/API?) 作用 forEach 对流中的每个数据进行操作(迭代) map 映射每个元素到对应的结果 filter 通过设置的条件过滤出元素 limit 获取指定数量的流 sorted 对流进行排序 reduce 将流中的元素进行合并 collect 将流转换为指定数据类型的集合 toArray 返回包含元素中所有元素的数组
- Optionals
- 设计它的目的是为了防止空指针异常
- Parallel-Streams并行流
五、Object和String
1、Object
Object是所有Java类的根类(不要怀疑!!)
- Object类的常见方法有哪些?
- equals、hashCode、toString、getClass、notify、notifyAll、clone、wait、finalize
- ==和equals()的区别
- 类没重写equals()方法,则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
- 类重写了equals() 方法。若两个对象的内容相等,则返回 true (即,认为这两个对象相等)。
- hashCode()的作用
- 用于获取一个对象的哈希码
- 提高对象查找速度
- hashCode()、equals()的关系?
- 为什么要重写hashCode和equals()方法?
- 重写equals和hashCode时要注意什么?
- 为什么“如果两个对象的 equals 相同,那么这两个对象的 hashCode 一定相同,但是反过来不一定”
- 为什么重写equals()就一定要重写hashCode()方法?(重点!)
- 如果同一个类中的两个对象hashCode相同,但是equals不同会出现什么问题?
- 对象的相等和引用相等的区别?
☃深、浅拷贝了解吗?什么是引用拷贝?
- 深、浅拷贝定义
- 深:拷贝对象本身(创建一个新对象)。互不影响。可通过序列化和反序列化、使用ObjectInputStream和ObjectOutputStream来实现。
- 浅:仅拷贝对象的引用。共享同一个引用,相互影响。clone()来实现。
- 深、浅拷贝区别
- 引用拷贝
- 引用拷贝就是拷贝引用地址,两个不同的引用指向同一个对象。
- 引用拷贝分为深拷贝和浅拷贝。
- 深拷贝怎么实现?
- 使用JSON.parse() 和 JSON.stringify() 方法(序列化和反序列化)
- 递归地遍历原始对象并创建新的对象
- 使用 jQuery 的 extend 方法
2、String
- String类有哪些方法?
- charAt、substring、split、trim、indexOf、startsWith、endsWith…
- String、StringBuffer、StringBuilder 的区别?
- 为什么String是不可变的,而StringBuffer和StringBuilder是可变的?
- StringBuffer和StringBuilder内部实际上是一个char[]数组,它没有被final修饰。
- 为什么String设计为不可变的?(为什么用final修饰)
- 避免被修改引起问题、线程安全、编译期优化、…
- String创建对象的几种场景?
- 使用双引号、new、字符数组、valueOf()转换
- String最大长度是多少?——2^31 -1(length方法返回值为int类型)
- String a = "abc"; 说一下这个过程会创建什么,放在哪里?
- new String("abc") 是去了哪里,仅仅是在堆里面吗?
- new String("hello")创建了几个字符串对象?
- String可以被继承吗?
- Java对字符串做过哪些优化?
六、泛型、反射、注解
1、泛型
- 说说你对泛型的理解
- 参数化类型。创建集合时指定集合元素的类型
- 可在编译时检查类型安全。
- 简述泛型擦除
- 编译时将泛型类型参数的具体类型擦除掉,使用Object类型来替代
- 注意:泛型擦除在编译阶段实现的,仍然可以通过使用反射等机制获取泛型类型参数的具体类型信息
- List<? super T>和List<? extends T>有什么区别?
- 泛型的使用方式有哪几种?
- 泛型类、泛型接口、泛型方法
- 泛型的高级用法
- 限制泛型可用类型、使用类型通配符、继承泛型类和实现泛型接口
- 项目中哪里用到了泛型?
2、反射
- 反射概念
- 运行时,动态获取一个类的信息,且运行时可修改类的行为
- java.lang.reflect来实现反射相关的类库:Construct、Field、Method、Class(构造方法、成员变量、方法信息和属性方法)
- 反射的实现方式(获取Class对象的几种方法)
- new 和 反射创建有什么区别?
- new:静态编译
- 反射:动态编译
- new创建效率比较高。通过反射时,先找查找类资源,使用类加载器创建,过程繁琐效率低。
- 反射优缺点
- 优点:灵活、提高代码复用率、动态调用
- 缺点:性能问题、模糊内部逻辑、内部暴露、安全问题
- 反射提供了哪些功能
- 实现Java反射的类有?
- 反射API
- 反射使用步骤(获取Class对象、调用对象方法)
- 利用发射动态创建对象实例(Class对象的newInstance())
- 反射的应用场景?
- JDK动态代理
- 注解/XML配置
- 用JDBC连接数据库
- Spring框架
3、注解
- 什么是注解?
- jdk1.5引入,特殊的注释。可被编译器打包进入class文件。是一种用于标记的“元数据”
- @ 符号开头的
- 注解的作用
- 生成帮助文档
- 跟踪代码依赖性,实现替代配置文件功能
- 在编译时进行格式检查
- 简述元注解(注解的注解)
七、I/O、NIO、序列化和反序列化
1、IO/NIO
- IO流分为几种?
- Java中的IO是什么?
- Java把不同的输入/输出源抽象表述为流
- 字节流和字符流的区别?
- I/O阻塞发生在哪里
- 等待数据传输的过程中
- 怎么用流打开一个大文件
- 分次读取。(1)采用缓冲流;(2)使用NIO
- Java中的NIO是什么
- 三部分(缓冲区Buffer、通道Channel、选择器Selector)
- IO/NIO的区别
2、序列化和反序列化
- 什么是序列化?反序列化?
- 对象的持久化、网络传输
- 序列化:数据结构/对象→二进制字节流(字节序列)
- 反序列化:与序列化相反 -
- 如何实现序列化和反序列化?
- (1)实现Serializable接口
- (2)使用ObjectOutputStream和ObjectInputStream类
- (3)使用JSON等方式
八、其他
1、lombok
- 如何安装lombok?
- IDEA或Eclipse中安装lombok插件。(方法1:向lib文件夹中添加lombok.jar包;方法2:Maven项目中,在pom.xml文件中添加lombok依赖)
- lombok注解用过吗?
- @Data
- @Setter
- @ToString
- @EqualsAndHashCode
- @NonNull
- @NonArgsConstructor
- @AllArgsConstructor