Java基础
Java 基础
JDK、JRE、JVM 关系
- JDK:java 开发工具包
- JRE:java 运行环境
- JVM:java 虚拟机
Java 数据类型
- 类(class)
- 接口(interface)
- 数组
&和&&的区别
- &和&&都可以用作逻辑与的运算符
- 表示逻辑与(and)
- &&还具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式
重载(Overload )和重写 (Override )
- 重载
- 发生在一个类中,方法名相同,参数列表不同,方法体不同
- 编译器在编译时根据方法的签名自动绑定调用的方法
- 重写
- 发生在父子类中,方法名称相同,参数列表相同,方法体不同
- 重写方法被调用时,看对象的类型
- 重写遵循”两同两小一大”原则:
- 两同:
- 方法名称相同
- 参数列表相同
- 两小:
- 派生类方法的返回值类型小于或等于超类方法的
- void 时,必须相等
- 基本类型时,必须相等
- 引用类型时,小于或等于
- 派生类方法抛出的异常小于或等于超类方法的
- 派生类方法的返回值类型小于或等于超类方法的
- 一大:
- 派生类方法的访问权限大于或等于超类方法的
- 两同:
重写与重载的区别
- 重写(Override):
- 发生在父子类中,方法名称相同,参数列表相同,方法体不同
- 遵循”运行期”绑定,看对象的类型来调用方法
- 重载(Overload):
- 发生在一个类中,方法名称相同,参数列表不同,方法体不同
- 遵循”编译期”绑定,看参数/引用的类型来绑定方法
访问修饰符,作用域
是否可以继承 String
String 类是 final 类,不可以被继承
抽象类(abstract class)和接口(interface)有什么异同
不同
- 抽象类中可以有构造器,接口不能定义构造器
- 抽象类中可以有普通成员变量和常量,接口中只能有常量,而且只能是
public static final
不写默认 - 抽象类中可以有抽象方法,也可以由普通的方法,接口中只能有抽象的方法而且修饰符只能是
public abstract
不写默认 - 抽象类只能是单继承,多实现,接口是可以多继承其他接口,但是不能实现接口,和不能继承其他类
- 抽象类中可以有静态的方法,接口中不可以
- 抽象类继承 object 而接口不继承
相同
- 不能够实例化
- 抽象类接口作为引用类型
静态变量和实例变量区别
- 静态变量:称为类变量,归类所共有,不依赖某个对象们可以通过类名直接访问
- 实例变量:必须依存实例,只能通过对象访问到他
面向对象的基本特征
- 封装:把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口
- 继承:从已有类得到继承信息创建新类的过程,子类拥有父类一切非私有的属性和方法
- 多态:指允许不同子类型的对象对同一消息作出不同的响应,同一种事物的不同种表现形式
- 抽象:将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面
java 中实现多态的机制是什么 重写、重载、父类的声明指向子类的对象
==和 equals 的区别
==
:比较基本数据类型是比较数值是否相等,引用数据类型,则比较对象地址是否相等(= =是比较数值和地址相等才相等)equals
:比较两者内容是否相等
String、StringBuffer、StringBuilder 的区别
- String:是不可变的,对 string 的改变都会返回一个新的对象,线程安全的
- StringBuffer:是可变的,可以对字符串修改,是线程安全的
- StringBuilder:是可变的,可以对字符串修改,线程不安全的,性能上有所提升
final, finally, finalize 的区别
- final:是声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承
- finally:是异常处理语句机构一部分,表示总是执行
- finalize:是 Object 类的方法,GC 回收执行时候此方法
异常处理
Throwable 异常分类
Error(错误)和 Exception(异常)
- Error(错误):是程序无法处理的错误
- Exception(异常):是程序本身可以处理的异常
常见 RuntimeException
- java.lang.NullPointerException 空指针异常;
- java.lang.ClassNotFoundException 指定的类找不到;
- java.lang.NumberFormatException 字符串转换为数字异常;
- java.lang.IndexOutOfBoundsException 数组角标越界异常;
- java.lang.IllegalArgumentException 方法传递参数错误;
- java.lang.ClassCastException 数据类型转换异常;
- java.lang.NoClassDefFoundException 未找到类定义错误;
- SQLException SQL 异常
- java.lang.InstantiationException 实例化异常
- java.lang.NoSuchMethodException 方法不存在异常
异常和错误的区别:异常能被程序本身可以处理,错误是无法处理
try、catch、finally
- try 块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
- catch 块:用于处理 try 捕获到的异常。
- finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。
线程
创造线程三种方式
- 继承 Thread 类创建线程
- 实现 Runnable 接口创建线程
- 使用 Callable 和 Future 创建线程
线程的状态
graph LR
A[就绪] --> B[运行]
B --> D[synchronize阻塞]
D --> E[wait 和 sleep挂起]
E --> F[结束]
sleep() 和 wait()的区别
最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁。 wait 通常被用于线程间交互, sleep 通常被用于暂停执行
synchronized
是多个线程之间访问资源同步性,修饰的方法代码块在任意时刻只能有一个线程执行
- 修饰实例方法:实例加锁
- 修饰静态方法:对象加锁
- 修饰代码块:
什么是线程池
线程池就是事先将多个线程对象放到一个容器中,当使用的时候就不用 new 线程而是直接去池中拿线程即可,节省了开辟子线程的时间,提高的代码执行效率。
线程池的优点
- 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
悲观锁与乐观锁
- 悲观锁:假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁 ,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。
- 乐观锁:是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据, 可以使用版本号机制和 CAS 算法实现
IO
集合
Collection 和 Collections 的区别
- Collection:是集合累的上级接口,继承与他的接口主要是 Set 和 List
- Collections:是正对集合类的帮助类,他提供一系列静态方法实现对各种的搜索、排序、线程安全化操作。
List
- Collection 的子接口
- 底层是数组方式实现
- 有序可重复的
-
遍历方式:for-each、for、迭代器(Iterator)
-
实现类
- ArrayList 底层结构是数组,底层查询快,增删慢
- LinkedList 底层结构是链表型的,增删快,查询慢
- voctor 底层结构是数组 线程安全的,增删慢,查询慢
Set
- Collection 的子接口
- 底层是散列表方式实现
- 无序不可重复的
-
遍历方式:for-each、for、迭代器(Iterator)
-
实现类
- HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素
- LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
- TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)
Map
- 键值对方式呈现
- Map 是有序,key 不重复,value 可重复
-
遍历方式:for-each、迭代器(Iterator)、通过键值遍历
- 实现
- HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希 冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
- LinkedHashMap: LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和 链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以-保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
- HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
- TreeMap: 红黑树(自平衡的排序二叉树)
HashMap 和 HashTable 区别
- HashMap 是非线程安全的,Hashtable 是线程安全的
- HashMap 要比 Hashtable 性能高一点
- HashMap 中 key 和 value 都可以可以为 null,HashTable 不可以 put 就会出异常
List、 Set、Map 的区别
- List 和 Set 是 Collection 的子接口,map 不是
- List 的底层是数组的方式实现, Set 是散列表的方式实现, map 是键值对的方式
- list 是有序可重复的, Set 是无序不可重复的, map 是有序, key 不重复, value 可重复
- list 和 Set 可直接使用 iterator 来进行遍历, map 只能通过先遍历 Key 在遍历 value.
内部类
定义:指在一个外部类的内部再定义一个类 分类:成员内部类、局部内部类、静态内部类、匿名内部类
匿名部类可以继承其他类或者实现其他接口
作用:
- 可以实现多重继承
- 内部类拥有外围类的所有元素访问权限
- 内部类可以很好实现隐藏
Java 反射
通过方法获取类的字节码,得到字节码之后,通过反射来创建对象,获取私有属性和方法,在 Spring 中就是依赖反射注入的,在 jdbc 中,通过反射生成驱动对象实 获取字节码的方式
- class.forNam(className)
- 类名.class
- this.getClass()
This post is licensed under
CC BY 4.0
by the author.