重写与重载
1.同名不同参数名之间的方法之间互相称为重载,而重写是指子类重新构造和父类一摸一样的方法
2.重载是编译期确定下来的要使用哪个方法,而重写是运行时绑定的,即看对象引用指向的具体对象类型
只有返回类型不同,可以被叫做重载吗
不是,编译期会报错的
方法签名是由:方法名称 + 参数类型 + 参数个数组成的一个唯一值,这个唯一值就是方法签名,而 JVM
(Java 虚拟机)就是通过这个方法签名来决定调用哪个方法的
如果把返回类型也包含进去,那就不知道调用哪个了
1.同名不同参数名之间的方法之间互相称为重载,而重写是指子类重新构造和父类一摸一样的方法
2.重载是编译期确定下来的要使用哪个方法,而重写是运行时绑定的,即看对象引用指向的具体对象类型
只有返回类型不同,可以被叫做重载吗
不是,编译期会报错的
方法签名是由:方法名称 + 参数类型 + 参数个数组成的一个唯一值,这个唯一值就是方法签名,而 JVM
(Java 虚拟机)就是通过这个方法签名来决定调用哪个方法的
如果把返回类型也包含进去,那就不知道调用哪个了
运行时异常:
都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常(编译异常):
是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。如IOException、SQLException等
throw:
如果代码可能会引发某种错误,可以创建一个合适的异常类实例并抛出它,这就是抛出异常。
throws:
在Java中,当前执行的语句必属于某个方法,Java解释器调用main方法执行开始执行程序。若方法中存在检查异常,如果不对其捕获,那必须在方法头中显式声明该异常,以便于告知方法调用者此方法有异常,需要进行处理。 在方法中声明一个异常,方法头中使用关键字throws,后面接上要声明的异常。若声明多个异常,则使用逗号分割。
try-catch底层?
class字节码指令中会有异常表,表示哪一行到哪一行的代码可能有什么异常:


什么时候不走finally?
try或catch中进入了死循环
虚拟机退出
守护线程中可能不会走finally就被回收了
finally的执行顺序
finally正常情况下都会被执行的
如果finally里有return语句,那么它就是整个try-catch-finally结构的返回结果
若没有,就得看try or catch里的return语句了
程序出现了异常会发生什么?
运行时异常:
非运行时异常:
在编译时就必须被处理,所以和运行时异常走一样的逻辑
如何设置异常处理器?
为特定线程设置处理器:
1 | Thread thread = new Thread(() -> { |
案例:
异常被捕获,仍然执行代码,抛异常之前的代码都能正常执行:
打印:线程仍然执行,i = 10,b = 9
定义异常处理器处理异常:
打印:
OutOfMemoryError
StackOverflowError
NoClassDefFoundError

封装
就是利用一些抽象数据结构把数据和基于数据的操作封装成一个“黑盒子”,用户使用时不需要关注具体实现
直接使用就好了
继承
就是用来表示is-a的关系,比如父类是动物,子类是猫,就是用来表示这种关系。子类有着父类的全部属性和
方法。如果子类新增方法,那就是is-like-a关系
多态
同一方法在不同对象上有不同表现
多态的话我觉得就只在运行时才具有,如重写
即对象引用指向的具体类型只有在运行时才会被确定下来
要想实现多态就得满足以下条件
1.有接口实现or类继承
2.子类重写父类的方法
3.父类的引用指向子类的对象
组合
has-a关系,一个类的成员变量是其他类的对象
组合更适合面向接口开发,而且更加简单和灵活,相对于继承,能用组合就用组合
继承得有明确的is-a关系

如何扩容
1.检查加入新元素后是否会超过数组的容量,如果超过,就进行一次扩容
2.设置新的容量为老容量的1,5
最多不超过2^31-1 (Java 8中ArrayList的容量最大是Integer.MAX_VALUE - 8,即2^31-9。这是由于在Java 8中,ArrayList内部实现进行了一些改进,使用了一些数组复制的技巧来提高性能和内存利用率,而这些技巧需要额外的8个元素的空间来进行优化。)
3.申请一个容量为老容量的1.5倍的新数组,然后把原数组的元素复制上去
ArrayList的序列化
数据库死锁是指多个并发事务中,出现了彼此相互等待的情况,导致所有事务卡在那里了,无法继续执行
原因:其实就是长时间无法获取想要的资源且无法放弃获取
如何解决?
大部分的现在数据管理系统都有自动干预功能,即可以选择多个or一个事务回滚来释放锁
还能手动强制回滚
mysql自己也能解决死锁
1.定期检测死锁机制,检测到死锁后,MySQL会自动选择终止一个or多个事务来释放锁
2.设置事务持有锁的超时时间(InnoDB_lock_wait_timeout)。即如果事务持有锁的时间超过这个阈值
就会对这个事务进行回滚

长事务


从计算机结构来讲,I就是Input,o就是output,那么IO描述的就是描述计算机系统与外部设备通信的过程

如输入设备(键盘),输出设备(显示屏)就是外部设备,网卡和硬盘也是外部设备

从应用程序角度来说,IO是指应用程序通过系统调用请求操作系统内核空间执行与“外部设备的交互”的过程
当应用程序发起IO调用后,会经历两个阶段
1.内核等待IO设备准备好数据
2.内核把数据从内核空间拷贝到用户空间
UNIX 系统下, IO 模型一共有 5 种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。
jtea/linux/五种IO模型.md at master · jmilktea/jtea
应用程序发起IO调用后,会一直阻塞,直到成功拿到数据

连接一多起来,每来一次连接就得开一个线程,费内存。且线程阻塞住,不能去干其他事情

应用程序轮询 询问内核数据是否就绪,避免了一直阻塞。但不断轮询是很耗CPU资源的

有个重要角色selector会去监听客户端的channel,然后数据准备好了就主动通知客户端可以来读数据了
实现了一个线程就可以监听多个Client的功能

目前支持IO多路复用的系统调用有三种:select(几乎所有的系统都支持),poll,epoll
1.提高并发
2.降低锁的粒度,能有效降低死锁风险