https://www.bilibili.com/video/BV1Eb4y1R7zd

p1.面向对象

多态 编译时运行时指向不一样。 多态无法调用子类成员函数。Person XiaoMing= new Man(); XiaoMing.只能跟Person有的方法,如果Man重写过就用Man的,不然就Person的。 要是想用Man的得加个(Man)XiaoMing。属性和方法不一样,访问得到的是Person的属性。

多态作用一个是方法参数一个是返回值。都可以编译时写成Person运行时用Man。

1
2
3
4
5
6
7
8

public void test(A a){
a.x()
}
// b是B的对象,这时候test方法中就调用了B的x方法
test(b)
// c是C的对象,这时候test方法中就调用了C的x方法
test(c)

另外,我我们在JDK中可以大量的看到多态的应用,比如在Object类中的equals(Object obj)方法中,参数是个Object类型的参数.因为Object是Java中所有类的基类.,但是才传入参数的时候,可以传入任何一个类的对象

p3.JDK JRE JVM

Java的执行过程整体可以分为两个部分,第一步由javac将源码编译成字节码.class,在这个过程中会进行词法分析、语法分析、语义分析,编译原理中这部分的编译称为前端编译。接下来无需编译直接逐条将字节码解释执行,在解释执行的过程中,虚拟机同时对程序运行的信息进行收集,在这些信息的基础上,编译器会逐渐发挥作用,它会进行后端编译——把字节码编译成机器码

p4.== vs equals

==:基本数据类型(byte、short、int、long、float、double)比较变量值,引用类型比较对象地址。

equals默认也是==,但通常会重写。

p5.final

p6.String、StringBuffer、StringBuilder区别及使用场景

p7.重载重写

重载:只有返回类型不同,没法区分方法,会报错。参数列表不同的基础上返回类型可以不同。

1
2
3
4
5
public int add(int a,int b){ return 0;}

public String add(int a,int b){ return "sb";} //会报错

public String add(String a,int b){ return "sb";}//没问题

重写:private方法不能重写。

p8.抽象类和接口

抽象类可以有普通成员函数,接口只能存在public abstract 方法。换句话说抽象类可以有实现,接口只有声明没有实现。
抽象类继承一个,接口实现多个。

接口目的是规范,抽象类目的是复用。接口是has A,抽象类是is A。

以下内容介绍抽象类,摘抄自

https://www.liaoxuefeng.com/wiki/1252599548343744/1260456371027744

https://www.runoob.com/java/java-abstraction.html

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

从Person类派生的Student和Teacher都可以覆写run()方法。

如果父类Person的run()方法没有实际意义,能否去掉方法的执行语句?
答案是不行,会导致编译错误,因为定义方法的时候,必须实现方法的语句。

能不能去掉父类的run()方法?

答案还是不行,因为去掉父类的run()方法,就失去了多态的特性。

如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法:

必须把Person类本身也声明为abstract,才能正确编译它:

1
2
3
abstract class Person {
public abstract void run();
}

抽象类强迫子类实现其定义的抽象方法,否则编译会报错(除非子类也是抽象类)。因此,抽象方法实际上相当于定义了“规范”。

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象

p9.List和Set区别

List有序可重复,Set无序不可重复。

p10.hashcode和equals

视频讲的不好
建议看这篇
https://www.cnblogs.com/skywang12345/p/3324958.html

p11.ArrayList和LinkedList

  1. 读取(也就是按位get)数组快 O(1) vs O(n)
  2. 查询一样
  3. 删除插入 若尾插可能也是数组快 头插可能是链表快。插入删除快指的可能是已找到待删除后删除操作本身。

原问题为:「本人新手,按照我的想法链表删除某个元素时,不是应该先找到该元素的位置么,求大佬解析一下」

当看到这句话「从链表或者数组中删除某个元素」时,大部分人的反应都会想到:先得找到待删除的元素,然后再删除。

而很多「教科书」中表达的意思是:假设已经找到了待删除的元素,只讨论删除操作本身,所需要的时间复杂度。

  1. 查找待删除的元素,无论单链表,还是数组(无序),复杂度都是O(n)
  2. 找到待删除的元素以后,进行删除操作时,链表可以将待删除的节点的前继节点next指针直接指向待删除元素的后续节点即可,时间复杂度是O(1);而数组需要进行搬移操作,时间复杂度是O(n)

用时间复杂度表示的话,ArrayList的get(n)是o(1),而LinkedList是o(n)。

图里说链表不能用get意思是很慢 所以不能用。

p12.hashmap

https://yikun.github.io/2015/04/01/Java-HashMap%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE%9E%E7%8E%B0/

https://www.liaoxuefeng.com/wiki/1252599548343744/1265117217944672

我们再思考一下HashMap为什么能通过key直接计算出value存储的索引。相同的key对象(使用equals()判断时返回true)必须要计算出相同的索引,否则,相同的key每次取出的value就不一定对。

通过key计算索引的方式就是调用key对象的hashCode()方法,它返回一个int整数。HashMap正是通过这个方法直接定位key对应的value的索引,继而直接返回value。

由上面可以看出,当我们根据key的hash确定其在数组的位置时,如果n为2的幂次方,可以保证数据的均匀插入。因此,HashMap 容量为2次幂的原因,就是为了数据的的均匀分布。

一般我们可能会想通过 % 求余来确定位置,这样也可以,只不过性能不如 & 运算。而且当n是2的幂次方时:hash & (length - 1) == hash % length

在Java 8之前的实现中是用链表解决冲突的,在产生碰撞的情况下,进行get时,两步的时间复杂度是O(1)+O(n)。因此,当碰撞很厉害的时候n很大,O(n)的速度显然是影响速度的。

因此在Java 8中,利用红黑树替换链表,这样复杂度就变成了O(1)+O(logn)了

p13.concurrentHashMap 没看

p14.IOC 没懂

p15.字节码

p16.java类加载器 没看懂

p17.双亲委派 基于16的。没懂,向上委派,向下查找。

p18.

p19.GC如何判断对象可以被回收。

  1. 引用计数法。
  2. 可达性分析法。

p20.线程生命周期和状态

p21.讲的不好 关于线程状态建议看这篇文章 讲的超级好
https://my.oschina.net/goldenshaw/blog/802620

主要是sleep和wait的关系 两种阻塞 是否释放锁。还得再看看。

p22.对线程安全的理解(主要讲了堆内存 栈内存)

堆是共享内存,可以被所有线程访问。存放对象实例和数组。

栈是线程独有的。是线程安全的。

在Java中,栈stack内存是用来存储函数的主体和变量名的。Java中的代码是在函数体中执行的,每个函数主体都会被放在栈内存中,比如main函数。加入main函数里调用了其他的函数,比如add(),那么在栈里面的的存储就是最底层是main,mian上面是add。栈的运行时后入先出的,所以会执行时会先销毁add,再销毁main。

在Java中,堆内存是用来存储实例的。比如main函数里面声明了一个people的类per,people per;这个per是存储在栈stack内存中的,实例化后(per = new people());实例后的对象实体是存在堆heap内存中的。栈stack内存中存储的per存储着指向堆heap内存的地址指向。堆heap内存的存在是为了更好的管理内存,实现garbage collection。当per不再指向堆heap内存中的实例的时候,garbage collection机制就会把这个堆heap内存中的new people()实例删除,释放内存。

链接:https://www.zhihu.com/question/24807877/answer/139282174

p24.守护线程 没看完 开始跳着看了

p27.并发、并行、串行。

串行就是执行完任务1执行任务2。

并发执行任务1一半了执行任务2,2执行了一半又回到任务1。

并行两个任务一起执行。

p28并发三大特性 只看了第一个特性 还没看懂。

p29 p30线程池参数+处理流程

p34.AOP 讲的不好 看这两个知乎回答。

什么是面向切面编程AOP? - 柳树的回答 - 知乎
https://www.zhihu.com/question/24863332/answer/350410712

面向切面编程(AOP),那我们说的切面到底是什么? - 葛尧的回答 - 知乎
https://www.zhihu.com/question/57741911/answer/154139735

p35.IOC 讲的不好 看这个知乎回答。

Spring IoC有什么好处呢? - Mingqi的回答 - 知乎
https://www.zhihu.com/question/23277575/answer/169698662