admin管理员组

文章数量:1435858

我是2022届双非软件工程应届生,目前在准备秋招,总结了一篇不错的八股文,如果你正好需要可以关注一下,共同学习;超链接如下:

Java后端八股文(CSDN不再同步) 语雀地址

Hello, interviewer. My name is . I graduated from Zhengzhou University of Light Industry, majoring in software engineering and I will graduate next year. I have experienced a software development internship. I have done several simple projects at school and chose a personal blog project to put on my resume.OK,This is my self-introduction. I look forward to working with you in your compan

Java基础知识

锁的实现原理

面向对象

面向对象基本概念   面向对象通俗举例蛋炒饭与盖饭

**概论:**面向对象是把一组数据结构和处理他们的方法组成对象;把具有相同行为的对象归纳成类;

通过封装隐藏类的内部细节;通过继承使类得到泛化;通过多态实现基于对象类型的动态分派

吃饭

  • 面向过程:买菜,洗菜,做饭,洗手吃饭,洗碗
  • 面向对象:点外卖,吃饭,扔外卖盒

两者区别:对比面向过程,面向对象更注重事情的每一个步骤及顺序,面向对象更注重事情有哪些参与者(对象),以及如何更好按需分配  面向对象更加易于复用,扩展和维护; 面向过程直接高效

面向过程优点:流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清楚,便于节点分析。

效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。

java是面向对象的,但是不是所有的都是对象,基本数据类型就不是对象,所以才会有封装类的

封装:明确标识出允许外部使用的所有成员函数和数据项;内部细节对外部调用透明,外部调用无需修改或关心内部实现

1.JavaBean的属性私有,提供get set对外访问,因为属性的赋值或者获取逻辑只能由JavaBean本身决定,而不能由外部糊涂乱改

private String name;
    public void setName(String name){
        this.name = "java 是最好的语言"+name;
}
//该name有自己命名规则,明显不能由外部直接赋值

2.orm框架:操作系统库,我们不需要关心连接是如何建立的,sql如何执行,只需引入mybatis调方法即可

继承:继承基类方法,并做出自己的改变和/或扩展子类共性的方法或者直接使用父类的属性,而无需自己再定义,只需扩展自己个性化的;继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段; 访问修饰符决定了是否可继承

多态:基于对象所属类的不同,外部相同类型变量对同一方法的调用,实际执行逻辑不同

继承,方法重写,父类引用指向子类对象  .前提条件:必须有子父类关系。

作用:提高了代码的扩充性和可维护性

牛客例题

父类类型  变量名 = new 子类对象
变量名.方法名()

无法直接调用子类特有功能(需要向下转型)

  • 多态的转型分为向上转型和向下转型两种
  1. 向上转型:多态本身就是向上转型过的过程使用格式:父类类型 变量名=new 子类类型();
    适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
  2. 向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型使用格式:
    子类类型 变量名=(子类类型) 父类类型的变量;适用场景:当要使用子类特有功能时。
    成员变量:编译看左边,执行看左边;  成员方法:编译看左边,执行看右边。
    向下转型可以调用子类类型中所有的成员,不过需要注意的是如果父类引用对象指向的是子类对象,那么在向下转型的过程中是安全的,也就是编译是不会出错误。但是如果父类引用对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现我们开始提到的 Java 强制类型转换异常,一般使用 instanceof 运算符来避免出此类错误。
//安全的向下转型是先把子类对象向上转型为父类,再将该父类强制转换为子类
Animal animal = new Cat();
if (animal instanceof Cat) {
   
    Cat cat = (Cat) new animal(); // 向下转型
    ...
}

instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false

默认是向上转型,父类引用指向子类对象,安全转换。向下转型是不安全的需要使用instanceOf方法判断

在对象进行向下转型时,必须首先发生对象向上转型,否则将出现对象转换异常

抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面,抽象只关注对象的哪些属性和行为,并不关注这此行为的细节是什么   可以有构造函数,但不能实例化

牛客例题  牛客例题2  牛客例题3

接口

牛客例题  牛客例题2  牛客例题3  JAVA基础——接口(全网最详细教程)   Java之implements

为什么要用接口:接口被用来描述一种抽象。因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。
接口也被用来实现解耦。
接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,接口的静态成员变量要用static final public 来修饰
\接口中的方法都是抽象的,是没有方法体的,可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。

可以直接把接口理解为**100%的抽象类,既接口中的方法必须全部**是抽象方法。(JDK1.8之前可以这样理解)

和抽象类区别:

  • 抽象类实例化是变量指向实现抽象方法的子类对象,接口变量必须实现所有接口方法的类对象
  • 抽象类要被子类继承,接口被类实现
  • 接口只能做方法申明,抽象类可以做方法实现
  • 接口定义的变量只能是公共的静态的常量,抽象类中是普通变量
  • 接口可以通过匿名内部类实例化

牛客例题4  类实现多个接口的时候,只需要一个implements,多个接口通过逗号进行隔开,先继承类再实现接口

abstract 与 implement       is a 与 like a

  • 一个抽象类可以是public、private、protected、default,接口只有public;
  • 一个抽象类中的方法可以是public、private、protected、default,接口中的方法只能是public和default
  • abstract不能与final并列修饰同一个类;abstract 不能与private、static、final或native并列修饰同一个方法
  • 抽象方法不能有方法体,抽象方法不能使用private修饰符,也不宜使用默认修饰符(default)接口 不可以实例化 。 通过接口实现类创建对象

Java抽象类、接口能否有构造方法 趣说abstract 简书 abstract牛客例题 牛客例题2 牛客例题3 牛客例题(抽象类)

抽象类的实现是为了替代繁琐的接口实现

类之间几种常见的关系

“USES-A”关系    依赖关系,A类会用到B类,这种关系具有偶然性,临时性;在代码中的体现为:A类方法中的参数包含了B类
“HAS-A”关系    表示聚合。是整体与部分的关系,同时它们的生命周期都是一样的    
“IS-A”关系    表示继承。父类与子类,一个类包含另一个类的所有属性及行为
“LIKE-A“关系  表组合

内部类

成员内部类     局部内部类    匿名内部类    静态内部类

重写与重载

Java中重载与重写   牛客例题  牛客例题2

Java数据类型

Java基本数据类型    Java 基本数据类型 及 == 与 equals 方法的区别  牛客例题  牛客例题2  牛客例题3  牛客例题4

实线可以直接转,虚线直接的转换可能损失精度

位移运算符

& ( " and " )     | ( " or " )         ^ ( " xor " )         ~ ( " not " )

局部变量与成员变量对于基本数据类型与引用类型的存储

  • 对于局部变量来说,不论是基本数据类型还是引用类型,他们都会先在栈中分配一块内存,对于基本类型来说,这块区域包含的是基本类型的内容;而对于引用类型来说,这块区域包含的是指向真正内容的指针,真正的内容被手动的分配在堆上。
  • 对于成员变量来说,不论是基本数据类型还是引用类型,他们都会存储在堆内存或者方法区中;成员变量可细分为静态成员变量和普通成员变量,静态成员变量类属于类,类可以直接访问,存储在方法区中;普通成员变量属于类对象,必须声明对象之后,通过对象才能访问,存储在堆中。

基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,显式的String常量放在常量池,String对象放在堆中

数组初始化后默认值

牛客例题  牛客例题2

牛客例题  数组的复制的效率System.arraycopy>clone>Arrays.copyOf>for循环

什么是构造方法

什么是构造方法?    Java构造方法  牛客例题  牛客例题2  牛客例题3  牛客例题4

构造方法的声明:
修饰符 class_name(类名)  (参数列表){
 逻辑代码
}
  1. 构造⽅法的⽅法名和类名⼀致(包括⼤⼩写)
  2. 构造⽅法没有返回值类型(连void都没有)
  3. 构造⽅法可以重载
  4. 构造⽅法不可以⼿动调⽤,只能在创建对象的时,jvm⾃动调⽤
  5. 构造⽅法在创建对象时只能调⽤⼀次

当⼀个类中,没有定义构造⽅法 系统会⾃动提供⼀个公开的 ⽆参的构造⽅法 当类中已经定义了构 造⽅法,系统不再提供⽆参公开构造,如果需要使⽤⽆参的构造 那么必须⾃⼰定义出来 ⼀般开发如果 定义了有参的构造 都会再定义⼀个⽆参的构造

构造方法不能被 static、final、synchronized、abstract 和 native(类似于 abstract)修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。


构造函数的作用是创建一个类的实例。用来创建一个对象,同时可以给属性做初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。

泛型

泛型概述  牛客例题   牛客例题2

  • 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)
  • 泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的基本类型

泛型使用过程中操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法

Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法

使用泛型的好处

1,类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

2,消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

3,潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

所以泛型只是提高了数据传输安全性,并没有改变程序运行的性能

  • ? 表示不确定的 java 类型
  • T (type) 表示具体的一个 java 类型
  • K V (key value) 分别代表 java 键值中的 Key Value
  • E (element) 代表 Element

泛型擦除后是作为Object而存在的,而基础数据类型并没有继承自Object,所以编译器不允许将基础类型声明为泛型类型。最

近版本的编译器当涉及基础类型作为泛型参数时,编译器会自动进行拆箱和装箱,所以编译器不会报错

枚举

保障类型安全,避免出现取值范围错误的问题;适合采用于信息标志和信息分类

弥补常量赋值缺陷: 1.可读性差,易用性降低; 2.类型不安全;  3.耦合性高,扩展性差

int compareTo(E o) 
          比较此枚举与指定对象的顺序。

Class<E> getDeclaringClass() 
          返回与此枚举常量的枚举类型相对应的 Class 对象。

String name() 
          返回此枚举常量的名称,在其枚举声明中对其进行声明。

int ordinal() 
          返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

String toString()
           返回枚举常量的名称,它包含在声明中。

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 
          返回带指定名称的指定枚举类型的枚举常量。

static T[] values()
                    返回该枚举的所有值。

反射

反射小白入门   反射总结

Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,也有称作“自省”。
在程序运行状态中,对于任意一个类或对象,都能够获取到这个类的所有属性和方法(包括私有属性和方法),这种动态获取信息以及动态调用对象方法的功能就称为反射机制

优点

  1. 可以在程序运行过程中,操作这些对象;
  2. 可以解耦,提高程序的可扩展性。

获取Class对象的三种方式

  • 【Source源代码阶段】 Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象;
    多用于配置文件,将类名定义在配置文件中,通过读取配置文件加载类。
  • 【Class类对象阶段】 类名.class:通过类名的属性class获取;
    多用于参数的传递
  • 【Runtime运行时阶段】对象.getClass():此方法是定义在Objec类中的方法,因此所有的类都会继承此方法。
    多用于对象获取字节码的方式
    Java反射机制的作用
  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的方法

牛客例题

正则表达式

简书   牛客例题

[

本文标签: java