CoreJava重点

1、Java的运行机制

源文件-->编译器-->编译成字节码文件(.class文件)(平台通用文件)-->解释器-->逐行解释逐行执行

先编译,后运行

 

2、变量的创建方式

(1)先声明,后赋值

(2)声明的同时直接赋值

(3)同时声明多个相同数据类型的变量,其后再一一赋值

(4)同时声明多个相同数据类型的变量并直接赋值

3、八大基本数据类型

整数类型:byte、short、int、long

小数类型:float、double

字符类型:char

布尔类型:boolean

 

4、类型转换的两种情况

1自动类型转换

将小类型的值赋值给大类型时,不会出现数据缺失,所以可以自动完成类型转换

byte转char无法完整自动转换,因为byte取值有负数,而char无法接收负数

2)强制类型转换

将大类型的值赋值给小类型时,有可能出现数据缺失,导致数据不准确,所以需要强转

 

5JDK7.0之后switch中都能接收什么数据类型?

switch中只能判断bytecharshortintString(JDK7.0)

 

6、局部变量的慨念和使用特点

概念:定义在方法内部的变量

使用特点:

(1)必须先赋值才能使用

(2)从定义行开始,到直属代码块大括号结束

(3)在同一作用范围内,局部变量不可重名

 

7whiledo while循环的区别

while先判断,再执行

do while先执行,再判断

8breakcontinue的区别

break:直接跳出当前循环,使循环终止

continue跳出本次循环,继续下一次循环,只能作用于循环,无法作用于分支

 

9、嵌套循环的执行特点

执行特点:外层循环执行一次,内层循环执行一遍

 

10一维数组的创建和遍历(代码)

1.先声明,后指明长度

数据类型 []数组名;

数组名=new 数据类型[长度];

2.声明的同时直接指明长度

数据类型 []数组名=new 数据类型[长度];

3.创建的同时直接赋值

数据类型 []数组名=new 数据类型[]{值1,值2,值3...};

4.创建的同时直接指明长度 常用

数据类型 []数组名={值1,值2,值3...};

遍历:

for(int i=0;i<数组名.length;i++){

//i就代表数组下标

//通过数组名[i]就可以获取当前正在被遍历的数组元素

}

11、二维数组的创建和遍历(代码)

1)先声明,后指明长度

数据类型 [][]数组名;

数组名=new 数据类型[高维度数组长度][低维度数组长度];

2)声明的同时直接指明长度

数据类型 [][]数组名=new 数据类型[高维度数组长度][低维度数组长度];

元素个数=高维度数组长度*低维度数组长度

3)不规则创建 不常用

数据类型 [][]数组名=new 数据类型[高维度数组长度][];

数组名[高维度数组下标]=new 数据类型[低维度数组长度];

元素个数=每个低维度数组长度之和

4)声明的同时直接赋值

数据类型 [][]数组名={{值1,值2...},{值1,值2,值3...},{值1,值2...}};

高维度数组长度=内层大括号的个数

低维度数组长度=对应内层大括号中的元素个数

遍历:

for(int i=0;i<数组名.length;i++){//遍历高维度数组下标

for(int j=0;j<数组名[i].length;j++){//遍历低维度数组下标

//通过数组名[i][j]获取当前元素

}

}

 

12、下标的范围

下标从0开始,到数组长度前一位结束

13、数组属于什么数据类型及引用类型相互赋值的特点

属于引用类型

引用类型之间相互赋值传递的是堆地址

14、数组扩容的步骤(笔记)及三种实现方式(代码)

1)结合for循环:

01. 创建一个长度更大的数组,通常扩容原数组长度*2

02. 把原数组中的数据复制到新数组中

03. 将原数组的堆地址指向新数组

2)结合System.arraycopy():

System.arraycopy(原数组名,原数组的复制起始位置,新数组名,新数组的存放起始位置,复制长度);

3)结合Arrays.copyOf():

01.Arrays.copyOf(原数组名,预期的新数组长度);

02.返回值为扩容之后的新地址

03.需要导入java.util.Arrays

 

15、三种排序方式的原理

1冒泡排序

原理:让相邻的两个数字进行比较,根据比较结果决定是否换位

2)选择排序

原理:让固定位置的元素与其他位置进行比较,根据比较结果决定是否换位

3JDk排序

原理:结合工具类Arrays中sort方法

16、类和对象间的关系

(1)类是对象的模板

(2)对象是类的实例

(3)一个模板可以创建多个相同相似的实例

17、属性和局部变量的区别

局部变量

属性

位置

方法内部

方法外部

默认值

没有

作用范围

从定义行开始到所在直属代码块{}结束

至少整个类

命名冲突

在同一作用域内,不可重名

属性和局部变量可以重名,局部变量优先级更高

 

18、构造方法的特点

(1)语法特点

01.访问修饰符通常都为public

02.没有返回值类型部分(注意:不是没有返回值,是没有这一部分)

03.方法名必须与类名保持一致

2)使用特点

01.只能用来创建对象

02.创建对象只能使用构造方法完成

03.只能通过new关键字调用

3)有参构造和无参构造的区别:

01.有参构造可以在创建对象的同时直接为属性赋上初始值

02.无参构造只是单纯的创建对象

03.类中默认存在一个无参构造,当类中显式定义声明构造之后,默认的无参构造将会失效

04.一个类中可以有0-1个无参构造,可以有0-多个有参构造

19、方法重载的规则

(1)方法名必须相同

(2)参数列表必须不同(数据类型、个数、顺序)

(3)与访问修饰符、返回值类型、异常没有关系

 

20this.this()的区别

this:代表当前对象,this.属性名表示当前类的属性,this.方法名为调用本类的方法,可用于构造方法和普通方法

this():调用本类构造,只能写在构造方法有效代码第一行

21、属性的三个赋值时期

(1)给属性分配空间,赋默认值(必须)

(2)给属性赋初始值(不一定)

(3)利用构造再次为属性赋值(不一定)

22、对象的内存结构

(1)引用名下存放的是对应的堆地址

(2)“逢new必开”:当执行到new关键字,堆空间中一定会开辟新的地址

23、面向对象三大核心思想

封装、继承、多态

24、继承的前提

建立在is a关系之上

 

25、继承的规则

(1)一个子类只能有一个直接父类,但是一个父类可以拥有多个子类

(2)子类在拥有父类可被继承的内容之上,可以存在独有内容

(3)父类无法访问子类独有内容

(4)子类在身为子类的同时也可以是其他类的父类

(5)一个类可以拥有直接父类和所有间接父类中所有可被继承的内容

(6)子类无法继承父类构造方法

(7)父类私有内容子类无法直接继承

 

26、方法重写的规则

(1)建立在继承关系之上

(2)方法名、参数列表必须与父类相同

(3)返回值类型必须与父类相同或为子类

(4)访问修饰符必须与父类相同或者更宽

(5)不允许抛出比父类更多更大的异常

 

27、四个访问修饰符及其范围

本类

同包

非同包子类

非同包非子类

public(公共的,公开的)

protected(受保护的)

default(默认的)

private(私有的)

(1)只有public和default可以修饰类

(2)default不允许显式声明

(3)四个修饰符都可以修饰属性、方法、构造

(4)四个修饰符都不能修饰局部变量

 

28、super()的使用

(1)只能写在构造方法有效代码第一行

2)可以在子类有参构造中通过super(实参列表)的方式在创建子类对象的同时直接给父类封装属性赋值

3)this()和super()不能同时显式出现

原因:所需位置相同

(4)子类构造方法第一行默认存在无参的super()

原因:为了辅助构建子类对象内容

 

29、有继承关系的对象创建过程

(1)给父/子类属性分配空间,赋默认值

(2)给父类属性赋初始值

(3)利用父类构造再次给父类属性赋值

(4)给子类属性赋初始值

(5)利用子类构造再次为子类属性赋值

总结:先构建父类对象才能构建子类对象

30、多态的语法

父类引用指向子类对象,也可以是接口指向实现类对象

父类类名 引用名=new 子类类名();

 

31、多态的使用

(1)实际创建的是子类对象

(2)优先执行子类内容

(3)父类引用无法使用子类独有内容

等号右边决定了是什么

等号左边决定了能做什么

(4)前提:建立在继承关系之上

 

32、引用类型间的类型转换

1)自动类型转换

子类对象赋值给父类引用

父类类名 引用名=new 子类类名();

2)强制类型转换

父类引用赋值给子类引用

子类类名 引用名=(子类类名)父类引用名;

01.只能转向父类引用原本指向的子类类型

02.子类与子类之间不可进行类型转换

 

33、多态的三个使用场景

1用于数组

将数组的数据类型声明为父类类型,则数组中可以存放父类对象和子类对象

2)用于参数

将形参类型定义为父类类型,传入的实参可以为父类对象或者子类对象

3)用于返回值

将返回值类型定义为父类类型,return返回的可以为父类对象或者子类对象

 

34、instanceof关键字的使用

判断引用是否与指定类型兼容,兼容返回true,否则返回false

35、多态的好处

(1)更加贴合现实逻辑

(2)解耦合

(3)提升代码可重用性

(4)减少代码冗余

36、抽象类和抽象方法的使用

抽象类:

(1)无法实例化对象

(2)通常情况下父类都应该是抽象类

(3)抽象父类仍然可以使用多态

(4)抽象父类中仍然存在构造方法,用于辅助子类创建对象

(5)抽象类中可以存在非抽象内容

(6)好处:

更加贴合现实逻辑

优化代码结构

抽象方法:

(1)没有{}方法体部分

通常抽象类中的行为方法都应该是抽象方法

(2)子类必须对父类中的抽象方法提供方法实现,除非子类自身也是抽象类

通常情况下,除非子类同时身为其他类的父类,否则子类不应该成为抽象类

(3)抽象方法只能存在于抽象类中

(4)作用:

更加贴合现实逻辑,抽象类中的行为方法不应该存在具体的方法实现

抽象父类可以在约束子类拥有哪些内容的基础之上,强制要求子类提供方法重写

 

37、static修饰属性和方法的使用特点

属性:

(1)静态属性不独属于某个对象,被该类的所有对象共享

JDK8.0之后,方法区被归纳到堆之中

(2)可以通过类名.属性名的方式直接访问静态属性

与对象名.属性名访问的区别:

类名直接访问可以不借助对象,对象名访问必须创建对象

类名直接访问会直接进入方法区,对象名访问时编译器会转换为对象访问的模式优先进入栈空间

(3)当静态属性进行封装之后,只能通过任一对象名.getter/setter方法的方式访问

方法:

(1)无法访问非静态内容

(2)可以通过类名.方法名()的方式直接调用

仍然可以使用对象名.方法名()的方式调用

(3)无法修饰局部变量

原因:局部变量的作用范围有限制

(4)无法修饰构造方法

原因:构造方法只能通过new关键字调用,无法手动调用

(5)静态方法内部无法使用this和super关键字

原因:调用静态方法时,如果通过类名调用,则有可能当前对象及父类对象并未被创建

(6)子类仍然可以继承并重写父类静态方法,但是在多态之下,子类的重写没有意义,仍然执行父类内容

原因:静态内容的调用只关注引用类型,与对象类型无关

38、final都能修饰什么及其特点

(1)修饰属性

变成常量,值不可改

(2)修饰方法

不可被重写

可以被继承

(3)修饰类

变成断子绝孙类,不能被继承

修饰局部变量:变成常量,值不可改

修饰引用:堆地址不可改

 

39、什么是类加载?

当第一次使用类内容时,通过CLASSPATH类路径找到当前类的字节码文件,将字节码文件中的内容加载到jvm虚拟机中的过程,称之为类加载。通常情况下,类加载只会触发一次

40、类加载的时机

(1)第一次创建类的对象时

2)第一次使用类中静态内容时

3)通过Class.forName("类的全限定名")强制触发类加载

全限定名:类的完整路径 包名.类名

(4)当子类被触发类加载时父类也会一并触发类加载

5)只声明引用不会触发类加载

41、接口和实现类的使用

接口:

(1)属性必须为公开静态常量(public static final)

接口中内容修饰符固定,所以可以省略不写或书写不完整,编译器会自动完成填充

(2)方法必须为公开抽象方法(public abstract)

(3)接口中不存在构造方法,所以无法实例化对象

实现类:

(1)实现类必须对接口中的所有方法提供方法实现

如果未提供完整的方法实现,则该类必须成为抽象类

(2)仍然可以使用多态

接口名 引用名 = new 实现类名();

(3)实现类可以实现多个接口,接口也可以有多个实现类(多实现)

class 类名 implements 接口名1 , 接口名2 … {

    
}

(4)当实现类实现多个接口时,需要重写所有接口中的所有方法

(5)使用多态创建实现类对象时,接口引用只能调用自身内部声明的方法

其他接口中的方法对于当前引用来说属于独有内容

(6)多态时如果需要使用实现类独有内容,仍需要完成引用强转

实现类名 引用名 = (实现类名) 接口引用名;

不能转向未指向的实现类类型

实现类之间不可进行转换

(7)实现类可以在实现接口的基础之上继承父类,继承优先

class 类名 extends 父类类名 implements 接口名1 , 接口名2 … {

    
}

 

42、接口和抽象类的区别

抽象类

接口

关键字

abstract class/extends

interface/implements

属性

无特殊要求

公开静态常量

方法

可以有非抽象方法

都是公开抽象方法

构造

继承性

单继承

多继承

 

43、高版本接口中添加了哪些方法?

1)JDK8.0

01.默认方法
default 返回值类型 方法名 (参数列表){
    //操作语句
}

当父类方法与接口方法出现冲突时,实现类会优先执行父类内容(类优先规则)

当多个接口之间出现方法冲突时,实现类必须对该方法再次进行重写,然后执行自身重写内容

02.静态方法
static 返回值类型 方法名 (参数列表){
    //操作语句
}

2)JDK9.0

私有方法
private 返回值类型 方法名 (参数列表){
    //操作语句
}

 

44、接口回调的概念

"开闭原则":扩展开放,修改关闭

在为当前代码添加扩展功能时,允许扩展,但是前提是不允许修改之前的代码

概念:

先有接口的使用者,再有接口的实现者

在方法中把接口引用作为形参,方法中调用接口的方法,最终在调用执行该方法时传入不同的接口实现类对象

 

45、接口的好处

(1)解耦合,将方法声明与方法实现分离,为接口回调做支持

(2)提升代码可重用性

(3)优化代码结构,使代码结构更加清晰

 

46、内部类的分类

(1)成员内部类(了解)

(2)静态内部类(了解)

(3)局部内部类(了解)

(4)匿名内部类(掌握)

 

47、匿名内部类的使用和特点

特点:

将类的声明、方法的定义、对象的创建三合一

使用:

(1)必须继承某个父类或者实现某个接口

(2)一个匿名内部类只能创建一个对象

(3)只有一个默认的无参构造,无法显式定义构造

(4)可以定义独有内容,但是只能在自身类的内部使用

(5)无法定义静态内容

 

48、lambda的语法

(形参列表)->{方法重写的操作语句}

结合接口引用:

    接口名 引用名=(形参列表)->{方法重写的操作语句};

 

49、lambda的简化标准

1)小括号中的数据类型可省(要省则都省)

2)参数只有一个时,则小括号可省(无参或者多个参数时不可省)

3)操作语句只有一条时,大括号可省

4)当操作语句只有一条并且为return语句时,大括号和return都可省(要省则都省)

(5)JDK8.0之后

 

50、equals方法的重写

重写原因:与hashCode()相同,在某种情况下,只需要关注对象内容,但是该方法默认关注对象地址,所以需要重写

重写规则:自反性、非空判断、类型比较、类型强转、属性值比较

hashCode()的重写通常与equals()的重写同时存在,目的为提高效率

 

51、自动封箱和拆箱的概念

封箱:基转包

拆箱:包转基

 

52、String转基本类型的写法

使用parseXxx()方法

基本类型 变量名=对应的包装类名.parseXxx(String变量名);

Xxx:对应基本类型,首字母大写

 

53、String转包装类型的写法

(1)与基本类型转包装类型的两种方式一致

String s="20";

Integer i=new Integer(s);

Integer i2=Integer.valueOf(s);

注意:当String转基或者转包时,如果字符串数据与对应类型不兼容,则会报NumberFormatException数据类型转换异常

 

54、整数缓冲区的概念

官方认定,-128至127是最常用的256个数字,所以在方法区中设立了整数缓冲区,区中存放着这256个数字,如果使用的数字区间在这之内,会直接从区中取出,不会额外开辟新的堆空间,目的为减少空间浪费

 

55、String两种创建方式的区别

(1)String 变量名="值";

(2)String 变量名=new String("值");

第一种方式只有当内容在串池中不存在时才会开辟堆空间

第二种方式无论如何都会开辟堆空间

56、String、StringBuffer、StringBuilder的区别?

StringBuffer : JDK1.0 线程安全,效率低

StringBuilder : JDK5.0 线程不安全,效率高

String:值不可变

StringBuffer、StringBuilder:值可变,只能通过构造创建,只能调用对应方法处理字符串内容,append("值"):在字符串末尾追加指定字符串

 

57、集合的特点

(1)用来存储Object对象(引用类型)

不能存放基本类型和接口,但是可以存放接口实现类

(2)集合属于java.util包

 

58、List集合的存储特点

是一个接口

有序、有下标、元素可以重复

 

59、List的常用实现类及其特点

(1)ArrayList 最常用

JDK1.2 底层数组实现 查询快,增删慢 线程不安全,效率高

(2)LinkedList 一般不用

JDK1.2 底层链表实现 增删快,查询慢 线程不安全,效率高

(3)Vector 压根不用

JDK1.0 底层数组实现 干什么都慢 线程安全,效率低

 

60、List的四种遍历方式

1for循环+get()

for (int i = 0; i < 集合名.size(); i++) {

//通过list.get(i)获取当前元素

}

2)Iterator迭代器

通过调用iterator()方法获取迭代器对象

迭代器方法:

hasNext():判断集合中是否存在下一个元素

next():获取下一个元素

Iterator it=集合名.iterator();

while (it.hasNext()) {

//通过it.next()得到当前元素

}

3forEach外遍历

for (元素数据类型 元素名(随便起) : 集合名) {

//元素名就代表当前元素

}

4)自遍历forEach

利用集合自身的forEach()方法实现自遍历

forEach(Consumer实现类对象)

集合名.forEach(new Consumer() {

@Override

public void accept(Object t) {

//t就代表当前遍历元素

}

});

5使用lambda简化自遍历

集合名.forEach(

    (Object t)->{//t就代表当前元素}

);

61、泛型在集合中的作用

作用于集合,可以约束集合中元素的数据类型

 

62、Collection的特点

(1)存放着所有子接口共同拥有的内容

(2)没有自己的直接实现类

 

63、Set的存储特点

无序,无下标,元素不可重复

 

64、Set的常用实现类和特点

1) HashSet

JDK1.2,底层哈希表(数组+链表)实现,线程不安全,效率高

2) LinkedHashSet

JDK1.2,是HashSet的子类,底层哈希表实现        线程不安全,效率高

3) TreeSet

JDK1.2,底层红黑树实现,是SortedSet的直接实现类        线程不安全,效率高

 

65、Set的三种遍历方式

1)Iterator迭代器遍历

System.out.println("迭代器遍历");

Iterator<Integer> it=set.iterator();

while (it.hasNext()) {

System.out.println(it.next());

}

2)外遍历forEach

System.out.println("外遍历forEach");

for (Integer i : set) {

System.out.println(i);

}

3) 自遍历forEach

System.out.println("自遍历forEach");

set.forEach(new Consumer<Integer>() {

@Override

public void accept(Integer t) {

System.out.println(t);

}

});

System.out.println("lambda简化自遍历");

set.forEach(t->System.out.println(t));

 

66、哈希表的去重过程

当往集合中存放元素时,会先调用元素的hashCode()方法获取哈希码值

通过哈希码值%数组长度得到存放下标

如果下标位置未存有元素,则直接存放

如果存有元素,则调用元素的equals()方法与其下标位上所有元素进行比较

若与任一已有元素相同,则直接舍弃该元素

都不相同,在当前数组下标位上链表存放该元素

 

67、TreeSet实现自定义排序规则的两种方式

1)Comparable接口

要对谁排,就让谁实现

需要重写compareTo()方法

原理:让当前对象与参数对象进行比较

返回值规则:

从小到大:this比o大返回正数

从大到小:o比this大返回正数

相等返回0

2)Comparator接口

创建一个接口实现类,存放比较规则

实现compare()方法

在集合创建处的小括号内传入该实现类对象

 

68、Map的存储特点

(1)以键(key)值(value)对的形式存储

(2)键无序、无下标、元素不可重复

(3)值无序、无下标、元素可以重复

 

69、Map常用实现类和特点

1)HashMap

JDK1.2 底层哈希表实现 线程不安全,效率高

2)LinkedHashMap

JDK1.2 是HashMap的子类,底层哈希表实现 线程不安全,效率高

3)TreeMap

JDK1.2 是SortedMap的实现类,底层红黑树实现 线程不安全,效率高

4)Hashtable

JDK1.0 底层哈希表实现 线程安全,效率低

5)Properties

JDK1.0 是HashTable的子类,底层哈希表实现 线程安全,效率低

 

70、Map的四种遍历方式

1)键遍历

keySet()+get()

Set<键的泛型类型> keySet():返回由所有键组成的Set集合

Set<键的泛型> set=map.keySet();

for (键的泛型 i : set) {

//i代表当前的键

//map.get(i)代表当前的值

}

2)值遍历

Collection<值的泛型> values()

Collection<值的泛型> collection=map.values();

for (值的泛型 i : collection) {

//i就代表当前遍历的值

}

3)键值对遍历

Set< Map.Entry<键的泛型,值的泛型> > entrySet()

相当于Set<键值对对象类型> entrySet()

Entry:键值对对象类型

getKey():获取键

getValue():获取值

Set<Map.Entry<键的泛型, 值的泛型>> set=map.entrySet();

//遍历Entry对象

for (Entry<键的泛型, 值的泛型> entry : set) {

//通过entry.getKey()获取当前的键

//通过entry.getValue()获取当前的值

}

4forEach自遍历

集合名.forEach(new BiConsumer<键的泛型, 值的泛型>() {

@Override

public void accept(键的泛型 k, 值的泛型 v) {

//k就代表键

//v就代表值

}

});

5lambda简化自遍历

map.forEach((k,v)->System.out.println("键:"+k+",值:"+v));

 

71、面试知识点补充

(1)Set就是只有键,值为空的Map集合

(2)哈希表底层数组长度为16

(3)为什么HashSet和HashMap在存放数值类型时,有时候会出现自动排序的情况?

答:数值的哈希码值就是其本身,当数值过小时,它的存放下标也是它本身,下标从小到大,所以数值输出也是从小到大

(4)底层数组加载因子为75%,当数组位的使用到达75%时,就会以平衡二叉树的形式开启数组扩容。扩容长度为原长度*2,扩容形式为创建新

的若干个长度为16的数组,然后数组与数组之间进行链接

(5)红黑树的存储模式:比当前节点大,右侧黑色存储,比当前节点小,左侧红色存储

(6)红黑树的优势:查询效率快

红黑树底层查找采用的是二分查找法,一次舍弃当前比较节点不符合条件的一半

(7)哈希表底层中,如果链表长度到达8时,会自动重组链表数据,开启红黑树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值