JAVA基础

目录

1.面向对象的三大特征

2.重写跟重载

3.访问修饰符(从最弱到最严格)

4.基本数据类型

5.==和equals区别

7.String值不可变,不可被继承的本质

8.位运算的选择

9.&&和||

10.反射机制

11.深拷贝和浅拷贝

12.并行和并发

13.类的初始化

14.静态变量和成员变量

15.抽象类和接口

16.error和exception

17.list,set,map

18.ArrayList和LinkedList

19.HashMap

20.线程

21.synchronized和Lock区别

22.类加载器(从上到下,双亲委派机制从下到上)

23:类加载过程

24:双亲委派机制

25:垃圾回收机制


1.面向对象的三大特征

继承:子类继承父类的特征和行为,让子类对象具有父类的方法和行为

封装:隐藏对象的属性和实现细节,对数据的访问只能通过外公开的接口,一种对内部数据的保护行为

多态:对于同一个行为,不同的子类对象具有不同的表现形式

存在条件:1.继承

                   2.重写

                   3.父类引用指向子类对象

2.重写跟重载

重写:子类继承父类,他具有父类的所有方法和行为,但是他可以对父类的方法进行修改,以增加功能。

规则:1.子类的参数列表,返回类型必须跟父类保持一致,否则就是重载

           2.被子类的重写方法不能拥有比父类更严格的访问权限,即如果父类的访问修饰符是private,则子类不能对其进行重写操作

            3.重写的方法不能抛出新的异常

如果在子类中想要调用父类被重写的方法,可以使用super关键字。

重载:在一个类中,多个方法的方法名相同,但是参数列表不相同

规则:1.重载的参数列表必须不同,其他的都不能作为重载的判断条件

           2.构造器可以被重载,但是不能被重写

3.访问修饰符(从最弱到最严格)

4.基本数据类型

1.8种基本数据类型:数据直接存储在栈上

byte: 8位  -128 —— 127

short:16位 -2^15 —— 2^15-1

int:32位 -2^31 —— 2^31-1 

long:64位 -2^63 —— 2^63-1

float:128位 -2^127 —— 2^127-1

double:256位 -2^255 —— 2^255-1

boolean:只有true和false 默认值false

char:单一字符

2.引用数据类型:除去8中数据类型,其他都是引用数据类型数据,存储在堆上,栈上只存储引用地址,所以String肯定不是基本数据类型

tips:1.当基本数据类型进行计算时,小于int类型的计算会先将数据类型转为int然后进行计算

       2.经典的问题1
                 short s1 = 1; s1 = s1 + 1;
                 short s1 = 1; s1 += 1;

上面因为类型不一致所有会报错,下面再运算前先进行了类型转换,然后再进行计算,所有会出正常的记过

       3.经典的问题2
            Integer a = 128, b = 128, c = 127, d = 127;
            System.out.println(a == b);
            System.out.println(c == d);

上面的返回false,下面的返回true。Integer 中的 IntegerCache 的默认范围导致的结果(-128-127),导致a,b是俩个不同的对象,而==对于包装类型时比较的是俩者是否是相同的对象,所以返回false。当然,IntegerCache 的默认范围是可以修改的,所以结果只针对默认情况

5.==和equals区别

==:对于基本数据类型,比较的是俩者的值是否相等,数据类型无关紧要;对于引用数据类型,比较的是俩个对象的地址是否相等,所以new出来的俩个对象必定不相等。

equals:比较俩个对象的值是否相等

String:值不可变

StringBuilder:值可以被修改,使用 synchronized 来保证线程安全,单线程大数据建议使用

StringBuffer:StringBuffer 的非线程安全版本,没有使用 synchronized,具有更高的性能,多线程大数据建议使用

tips:在进行频繁的字符串拼接时,建议使用StringBuilder类或者StringBuffer,不使用性能较低的String

7.String值不可变,不可被继承的本质

String是被final修饰的,final的规定是,在程序编写时,希望一个方法的行为在继承期间保持不变,而且不可被覆盖或者该写,就使用final方法去修饰。而且String作为java中使用最多的类型,该操作也很大程度上保证了程序的安全性

8.位运算的选择

通常情况下,位运算比普通的运算方法要快速,但是随着发展,很多编译器其实也就自己可以做一些优化,一昧的使用位运算反而可能得不偿失,不仅没有加速运算速度,也使得程序不是很美观

9.&&和||

&& :且
||:或

10.反射机制

反射是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称为反射机制

11.深拷贝和浅拷贝

深拷贝:把复制的对象所引用的对象都复制了一遍

浅拷贝:只复制要复制的对象

区别:对于基本数据类型来说,深拷贝和浅拷贝完全没有区别;对于引用数据类型来说,深拷贝将对象和其引用对象都复制了一遍,而浅拷贝值复制了对象,那么我们对对象进行修改时,如果引起了原对象的引用对象的引用地址变动,那么浅拷贝变动的是原引用对象的地址变动,而深拷贝变动的是新的引用对象的引用地址变动(因为浅拷贝没有复制引用对象,所以只有原引用对象)

12.并行和并发

简单来说:当你在做一件事情时,另外一件事情也来了,你停止手中的事情去做另外一件事情,当另外一件事情结束时再回来做第一件事情,这叫做并发,而且同时做俩件事情,这叫做并行

13.类的初始化

父类静态变量(静态代码块)->子类静态变量(静态代码块)->父类非静态变量(非静态代码块)->父类构造器 ->子类非静态变量(非静态代码块)->子类构造器 

14.静态变量和成员变量

静态变量:存在于方法区中,随着类加载而存在,类消失而消失,可以被对象和类调用

成员变量:存在于堆内存中,随着对象创建而存在,对象回收而释放,只能被对象调用

15.抽象类和接口

抽象类:只能单继承,可以有构造方法,可以有成员变量,可以有抽象方法

接口:可以多实现,不可以有构造方法,只能有静态变量,可以有抽象方法

16.error和exception

error是程序无法处理的或者不必处理的问题,exception是程序可以处理的问题

17.list,set,map

list:存储一组有序不唯一的的对象,容许多个null元素

set:存储一组唯一的对象,只允许有一个Null值存在

1.TreeSet 支持自然顺序访问,但是添加、删除、包含等操作要相对低效(log(n)时间),不可以存null。
2.HashSet 则是利用哈希算法,如果哈希散列正常,可以提供常数时间的添加、删除、包含等操作,但是它不保证有序。
3.LinkedHashSet 内部构建了一个记录插入顺序的双向链表,因此提供了按照插入顺序遍历的功能,同时保证了常数时间的添加、删除、包含等操作。这些操作性能略低于HashSet(需要维护链表的开销)

map:以键对值的方式(key-value)存储一组对象

1.HashMap:

2.HashTable:不可为空,

3.TreeMap:不可为空,

4.LinkedHashMap:

1.HashMap 数据结构以数组为主,查询非常快,TreeMap 数据结构以红黑树为主,利用了红黑树左小右大的特点,可以实现 key 的排序,LinkedHashMap 在 HashMap 的基础上增加了链表的结构,实现了插入顺序访问和最少访问删除两种策略;
2.由于 Map 底层数据结构的差别,也导致了三者的使用场景的不同。TreeMap 适合需要根据 key 进行排序的场景,linkedHashMap 适合按照插入顺序访问,或需要删除最少访问元素的场景,剩余场景我们使用 HashMap 即可。我们工作中大部分场景基本都在使用 HashMap;

18.ArrayList和LinkedList和Vector 

ArrayList:底层基于动态数组实现,因此对于查询方法有很大的优势,根据index直接定位到该位置然后进行查询(内存的连续性),虽然线程不安全,但是由于经常做的是查询的方法,所以无关紧要,毕竟不存在完美的集合,如果非要追求安全可以使用Vector,Vector方法是在ArrayList方法基础上,增加一个synchronized 关键字。初始化长度为10,第一次扩容时会将长度变为1.5倍

LinkedList:底层基于链表实现,故而查询的时候无法通过index进行直接定位,而是需要从节头开始往后遍历,效率过低。在插入时,如果使用随机插入,ArrayList需要通过System.arraycopy 去移动节点后面的节点,从而效率较低,而使用顺序插入时,因为不需要移动借点后面的节点,使用插入效率反而高于LinkedList

Vector:Java 早期提供的线程安全的动态数组同步是有额外开销的),Vector内部是使用对象数组来保存数据可以根据需要自动增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据,扩容时会提高1倍

19.HashMap

jdk1.8之后采用“数据+链表+红黑树”,1.7使用“数组+链表”

存取原理:即当你插入一个新的key-value值时,会先对key值进行hash运算(key.hashcode()),如果返回值相同,那么他们的存储位置相同的。此时使用equals方法去比较Entry的key值,如果返回值为true,则用新的value值去覆盖旧的,如果返回值我false,则将其Entry和原来的Entry形成链结构并插入头部。(头插法)

头插法:讲新的元素插入数组成为头部,旧的元素以新元素为头,形成链表

尾插法:以旧的元素为头部形成链表,当链表长度大于7的时候形成红黑树(根据泊松分布,大于8的时候红黑树的优势开始展示,所以转换成红黑树)

为什么使用尾插法:因为使用头插法,在多次hash冲突后,很容易引起环形链表

扩容机制:当容量超过负载因子时,进行扩容

初始长度:16(1<<4的位运算,原因是2的幂等便于计算,位运算效率高)

负载因子:0.75f(默认)

扩容:创建一个新的entry空数组,长度为原数组2倍,然后进行Rehash操作

Rehash:遍历原Entry数组,把所有的Entry重新Hash到新数组

 ReHash原因: 因为hash的计算规则是 index = HashCode(Key) & (Length - 1),那么经过扩容后,length值发生了改变,计算出来的index值也发生了改变,所以必须要ReHash

hash计算规则:index = HashCode(Key) & (Length - 1)。因为hashmap中的indexfor方法,该方法传入的参数是hashcode和length俩个参数,然后直接返回HashCode(Key) & (Length - 1)的位运算结果值

安全性能:不安全,不能用在多线程中,建议使用ConcurrentHashMap

为什么重写equals方法必须先重写hashcode方法:对于hashmap来说,equals是比较俩个对象的内存地址,而hashmap是通过key的hashcode去查找index值,所以index值其实也形成了链表,所以为了保证相同的对象返回相同的的hash值,不同的对象返回不同的hash值,必须重写hashcode方法,然后才能使用equals方法

hashmap容许键对值都为null

LinkedHashMap:按照传值顺序进行存储的集合

20.线程

生命周期:新建,就绪,运行,阻塞,死亡

创建方法:1.继承 Thread 类

                   2.实现 Runnable 接口

                   3.实现 Callable 接口

sleep( )和wait( )的区别:

                sleep( ):继承Thread 类,不会释放锁,可以在任何地方使用

                wait( )类:继承Object类,会释放当前锁,只能在同步方法或者同步代码块中使用,需要notif( )方法唤醒 

start( )方法和run( )方法的区别:

                start( ):新启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到 CPU 时间片,就开始执行 run() 方法

                run():普通的方法调用,在主线程中执行,不会新建一个线程来执行

21.synchronized,Lock,volitile

synchronized:Java关键字;线程会一直等待直到获得锁

Lock:一个接口;需要手动释放锁仿制死锁现象出现

volitile:只用于修饰变量,无法保证原子性,不会造成线程堵塞

22.类加载器(从上到下,双亲委派机制从下到上)

启动类加载器:(BootStrap)

扩展类加载器:(Extension)

应用程序类加载器:(System)

自定义加载器:

23:类加载过程

加载,验证,准备,解析,初始化

24:双亲委派机制

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,会抛出异常,让子类加载器去尝试加载

25:垃圾回收机制

在触发GC的时候,对死去的对象进行垃圾收理,然后使用对应的垃圾回收算法

如何判断对象是否死去:可达性分析算法(Java默认使用)和引用计数法

Young GC:新生代中Eden 区没有足够的空间,使用复制算法进行回收(老年代是用标记-清除算法和标记-整理算法)

Full GC:当准备要触发一次Young GC时,如果发现统计数据说之前Young GC的平均晋升大小比目前老年代剩余的空间大,则不会触发Young GC而是转为触发Full GC。(通常情况)
        如果有永久代的话,在永久代需要分配空间但已经没有足够空间时,也要触发一次Full GC。
        System.gc()默认也是触发Full GC。
        heap dump带GC默认也是触发Full GC。
        CMS GC时出现Concurrent Mode Failure会导致一次Full GC的产生。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值