导航菜单

Java基础部分知识总结

面向对象

面向对象和面向过程

面向过程的区别:

优点:性能高于面向对象,因为类调用需要实例化,这既昂贵又消耗资源。例如,单片机、嵌入式开发、Linux/Unix等普遍采用面向过程的开发,而性能是最重要的因素。

缺点:没有一个面向对象容易维护、重用和扩展

面向对象:

优点:易于维护、重用和扩展。因为面向对象具有封装性、继承性和多态性的特点,所以可以设计一个低耦合的系统。使系统更加灵活和易于维护

缺点:性能低于面向过程

面向对象的三个特性(封装、继承、多态)

封装:

封装将对象的属性私有化,并提供一些外部世界可以访问的属性方法(get/set方法)。如果属性不想被外部世界访问,我们可能不需要提供外部访问的方法。

继承:

继承是一种使用现有类的定义作为创建新类的基础的技术。新类的定义可以添加新数据或新函数,也可以使用父类的函数,但不能选择性地继承父类。通过使用继承,我们可以非常方便地重用以前的代码。

关于继承有3点:

1。子类具有父类的非私有属性和方法。

2。子类可以有自己的属性和方法。坦率地说,子类可以扩展父类

3。子类可以用自己的方式实现父类的方法。

多态性:

是指程序中定义的引用变量所指向的特定类型,通过引用变量发出的方法调用不是在编程过程中确定的,而是仅在程序运行过程中确定的,即引用变量是否指向某个实例对象,引用变量发出的方法调用是在哪个类和哪个类中实现的,必须在程序运行过程中确定。

在Java中有两种形式的多态性:继承(由多个子类重写相同的方法)和接口(实现接口并在接口中重写相同的方法)。

* *

Java类型

* *

Java有哪些数据类型:

定义:Java语言是一种强类型语言,为每种数据类型定义了特定的数据类型,在内存中分配了不同大小的内存空间。

分类:

integer type

byte,short,int,long

floating point type

float,double

char

char

reference data type

reference data type

class,interface,array([))

Java语言使用什么编码方案?有什么特点?Java语言使用Unicode编码标准,Unicode(标准代码),它为每个字符设置一个唯一的值,因此程序可以在任何语言、平台或程序中安全使用。

什么是Java注释

定义:文本

解释程序的分类:

单行注释格式://注释文本

分类:

文档注释格式:

角色:

在程序中,特别是在复杂的程序中,适当地添加注释可以增加程序的可读性,有利于程序的修改、调试和通信。编译程序时,注释的内容将被忽略,并且不会生成目标代码。这些评论不会对程序的执行结果产生任何影响。

注意:多行和文档注释不能嵌套。

private :在同一个类中可见。使用对象:变量、方法。注意:不能修改类(外部类)

定义:在Java中,访问修饰符可以用来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。

private :在同一个类中可见。使用对象:变量、方法。注意:不能修改类(外部类)

default(即默认,不写任何内容,不使用任何关键字):在同一个包中可见,不使用任何修饰符,并使用对象:类、接口、变量、方法。

protected :对同一包中的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)。

public :对所有类都可见。使用对象:类、接口、变量、方法

operator

operator

运算符有两种用途:(1)按位与;(2)逻辑和。

操作员是短路和操作。逻辑与短路和之间的区别非常大,尽管两者都要求运算符左右两端的布尔值为真。整个表达式的值为真。之所以调用短路操作,是因为如果左边表达式的值为假,右边的表达式将直接短路,不会执行任何操作。

注意:逻辑或运算符(|)和短路或运算符(| |)也是如此。

keyword

final有什么用?

用于修改类、属性和方法;

final-modified类不能被继承。

final-modified方法不能重写。

final-modified变量不能更改。最终修改的变量是对变量的不可变引用,而不是对内容的引用。引用所指向的内容是可变的

final final finalize difference :

final可以修改类、变量和方法,修改后的类表示该类不能被继承,修改后的方法表示该方法不能被重写,修改后的变量表示该变量是常数,不能被重新分配。

finally通常在try-catch代码块中工作。当处理异常时,我们通常使用代码方法finally来处理必须执行的代码块,这意味着无论是否存在异常,代码块都将被执行。它通常用于存储一些关闭资源的代码。

finalize是属于Object类的方法,Object类是所有类的父类。该方法通常由垃圾收集器调用。当我们调用System.gc()方法时,垃圾收集器调用finalize(),回收垃圾,并最终判断一个对象是否可以被回收。

this keyword

this是一个对象本身的用法,表示对象本身(可以理解,这表示当前类(这个类))

这种用法在java中可以大致分为三种类型:

common direct reference,这指的是当当前类对象的

formal参数和成员变量同名时的用法。他们用这个来区分

super关键字的用法指的是这个类的构造函数,可以理解为指的是它们自己的父类对象,它指的是最近的父类。

super还有三个用途:

common direct reference,与此类似,当子类中的成员变量或方法与父类中的成员变量或方法同名时,super相当于对当前对象的父类的引用。区分超级

Reference父类构造函数

this和超级

super:它是指当前对象的直接父类成员

this:它表示当前对象名

super()类似于此()。区别在于super()调用子类中父类的构造函数,而这个()调用这个类的其他构造函数

super()并且这个()必须放在构造函数的第一行。

static的主要含义是创建独立于特定对象的域变量或方法。即使没有创建对象,也可以使用属性并调用方法!

static关键字在形成静态代码块以优化程序性能方面也起着关键作用(静态代码块)。静态块可以放在类中的任何地方,并且一个类中可以有多个静态块。当第一次加载类时,每个静态块按照静态块的顺序执行,并且只执行一次。静态代码块之所以在类加载之前执行

static optimizer,是因为当类加载(通常用于加载资源配置文件)

static application scenario

时,它只执行一次,因为静态是由类的实例对象共享的,所以如果一个成员变量被所有对象共享,那么这个成员变量应该被定义为静态变量。

因此,更常见的静态应用程序场景是:

1。修饰符成员变量

2。修饰符成员方法

3。静态代码块

4修饰符类(仅内部类,即静态内部类

静态考虑

1。静态只能访问静态

2。非静态可以访问非静态或静态

过程控制语句:

break。Continue,return

1.break的区别和功能跳出当前循环,当前循环体直接结束于

2.continue跳出当前循环,继续返回下一个循环

3.return程序,并且不再执行code

class下的return和interface

abstract class与interface

abstract class之间的比较。抽象类用于捕获子类的一般特征。接口是以下各项的集合

相同点:

接口和抽象类不能被实例化

被其他类继承,或者实现

都包含抽象方法,并且它们的子类(实现类)必须重写这些抽象方法

不同点:

普通类和抽象类之间的区别?

普通类不能包含抽象方法,抽象类可以包含抽象方法。

抽象类不能直接实例化;普通类可以直接实例化。

抽象类可以用final修饰吗?

1。不,因为抽象类被定义为允许其他类继承,如果使用final,那么它就是一个不能继承的类,所以final不能修改抽象类。

变量和方法

成员变量和局部变量之间有什么区别?

定义:

1。成员变量:类中方法之外的变量。

2。局部变量:类的方法中的变量。

成员变量和局部变量

1的区别。Scope

member变量:对整个类有效。

local variable:仅在特定范围内有效。(一般指方法、语句体)

2。存储位置

成员变量:随着对象的创建而存在,随着对象的消失而消失,并存储在堆内存中。

local variable:在调用方法或执行语句时存在,并存储在堆栈内存中。当方法被调用或语句结束时,它会自动释放。

3。生命周期

成员变量:随着对象的创建而存在,随着对象

局部变量的消失而消失:当方法被调用或语句结束时自动释放。

4。初始值

成员变量:默认初始值

局部变量:无默认初始值;您必须在使用之前指定一个值。

5。使用规则

使用变量时应遵循的原则是:邻近原则应首先在本地找到,并在有邻近原则时使用;然后寻找成员位置。“构造方法”的特点是什么?

name与类名相同;

没有返回值,但构造函数不能用void声明;

在不调用的情况下生成类的对象时自动执行。(创建对象时直接调用)

静态变量和实例变量有什么区别?

静态变量:静态变量属于类,不属于任何实例对象,因此内存中只有一个副本。在类的加载过程中,JVM只为静态变量分配一次内存空间。

instance variable:每次创建对象时,都会为每个对象分配成员变量的内存空间。实例变量属于实例对象。在内存中,在创建几个对象后,将创建几个成员变量。

静态变量和普通变量有什么区别?

静态变量也称为静态变量。静态变量和非静态变量的区别在于,静态变量由所有对象共享,并且仅在首次加载类时初始化。但是,非静态变量由对象拥有,并在创建对象时初始化。有多个副本,并且每个对象拥有的副本互不影响。另一点是静态成员变量是按照定义的顺序初始化的。

静态方法和实例方法有什么不同?

当从外部调用静态方法时,可以使用=="类名。方法名"==或"对象名。方法名”。但是示例方法只有后者。换句话说,调用静态方法可以消除创建对象的需要。

静态方法只允许访问静态成员(即静态成员变量和静态方法),而不允许在访问此类成员时访问实例成员变量和实例方法;实例方法

override和重载

constructor没有这样的限制。

构造函数可以被重写吗?

构造函数不能被继承,因此不能被重写,但可以被重载。

过载和超驰的区别。重载方法可以通过返回类型来区分吗?

定义:重载和重写方法都是实现多态性的方法,不同的是前者实现编译时多态性,而后者实现运行时多态性。

重载:发生在同一个类中,不同的参数列表具有相同的方法名(不同的参数类型、不同的数字和不同的序列),独立于方法返回值和访问修饰符,即重载的方法不能通过返回类型来区分

重写:发生在父子类、方法名和参数列表中

=和等于之间有什么区别?

==:它的功能是确定两个对象的地址是否相等。也就是说,判断两个对象是否是同一对象。(基本数据类型==比较值,参考数据类型==比较内存地址)

等于():它还确定两个对象是否相等。但是,它通常有两种用法:

1。该类不重写equals()方法。那么通过equals()比较这个类的两个对象就相当于通过“===”比较这两个对象。

2。类重写等于()方法。通常,我们重写equals()方法以使两个对象的内容相等;如果它们的内容相等(也就是说,这两个对象被视为相等),则返回true。

hashCode和equals

hashCode()和equals()的相关规则

如果两个对象相等,hashCode必须相同

两个对象相等,对两个对象分别调用equals方法返回true

两个对象具有相同的hashCode值,它们不一定相等

IO streams

在Java中有多少个IO流?

根据流量的流向,可分为输入流量和输出流量。

根据运算单元的划分,可以分为字节流和字符流;

根据流程的作用,分为节点流程和处理流程。

InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。

OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流。

reflection

JAVA反射机制是为了知道任何类在运行状态下的所有属性和方法。对于任何对象,都可以调用其任何一个方法和属性;这种动态获取信息和动态调用对象方法的功能被称为java语言的反射机制。

reflection mechanism的优点和缺点

优点:运行时类型判断、类的动态加载和改进的代码灵活性。

缺点:性能瓶颈:反射相当于一系列解释操作,通知JVM要做什么。性能比直接java代码慢得多。

反射机制的应用场景是什么?

例如:①当我们使用JDBC连接到数据库时,我们使用Class.forName()通过反射加载数据库的驱动程序;(2) ②Spring框架还使用了许多反射机制,其中最经典的是xml的配置模式。Spring通过XML配置模式加载Bean)将程序中的所有XML或属性配置文件加载到内存中;2)分析xml中的内容或2)Java类中的属性,得到相应实体类的字节码字符串和相关属性信息;3)使用反射机制根据该字符串获取类的类实例;4)动态配置实例的属性

Java以获得反射

1的三种方法。通过新对象2实现反射机制。通过路径3实现反射机制。通过类名实现反射机制

String类

String类的常用方法。

indexOf():返回指定字符的索引。

charAt():返回指定索引处的字符。

replace():字符串替换。

trim():删除字符串两端的空白。

split():拆分字符串并返回拆分字符串的数组。

getbytes():返回字符串的字节类型数组。

length():返回字符串的长度。

toLowerCase():将字符串转换为小写字母。

toUpperCase():将字符串转换为大写字符。

substring():截取字符串。

equals():字符串比较。

当使用HashMap时,使用字符串作为键

HashMap的内部实现的优点是通过键的hashcode来确定值的存储位置。因为字符串是不可变的,所以它的hashcode在创建字符串时被缓存,并且不需要重新计算,所以它比其他对象更快。

String和StringBuffer以及StringBuilder之间有什么区别?为什么字符串是不可变的

可变的:

字符串类使用字符数组来保存字符串,私有的最终字符值[],所以字符串对象是不可变的。StringBuilder和StringBuffer都继承自AbstractStringBuilder类。在抽象字符串生成器中,字符数组也用于存储字符串,字符[]值,这两者都是可变的。

螺纹安全:

字符串中的对象是不可变的,可以理解为常量和线程安全的。StringBuilder是StringBuilder和StringBuffer的公共父类。它定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer是线程安全的,因为它向方法或调用方法添加了同步锁。StringBuilder不同步锁定方法,因此它是非线程安全的。

Performance :

每次更改字符串类型时,都会生成一个新的字符串对象,并且指针指向新的字符串对象。StringBuffer每次都对StringBuffer对象本身进行操作,而不是生成新对象和更改对象引用。在同样的情况下,与使用StringBuffer相比,使用StirngBuilder只能实现大约10%~15%的性能提升,但是会冒多线程不安全的风险。

三个概要

如果你想操作少量的数据,使用=String

单线程操作在字符串缓冲区下操作大量的数据=StringBuilder

多线程操作在字符串缓冲区下操作大量的数据=StringBuffer

Collection

Collection

1。Set:

TreeSet:基于红色和黑色树实现,它支持有序操作,如根据范围查找元素。然而,搜索效率不如哈希集,哈希集搜索的时间复杂度为O(1),树集为O(logN)。

HashSet:基于哈希表实现,支持快速搜索,但不支持有序操作。并且元素的插入顺序信息丢失,也就是说,使用迭代器遍历哈希集合的结果是不确定的。

LinkedHashSet:具有HashSet的搜索效率,并使用双链表在内部维护元素的插入顺序。

2。List

ArrayList:基于动态数组实现,支持随机访问。

Vector:类似于ArrayList,但它是线程安全的。

LinkedList:基于双链表,它只能按顺序访问,但它可以快速插入和删除链表中间的元素。不仅如此,LinkedList还可以用作堆栈、队列和双向队列。

地图(双排集)

树地图:基于红色和黑色的树。

HashMap:基于哈希表的实现。

HashTable:类似于HashMap,但它是线程安全的,这意味着多个线程可以同时写HashTable,而不会导致数据不一致。它是一个遗留类,不应该使用。ConcurrentHashMap现在可以用来支持线程安全,并且效率更高,因为它引入了分段锁。

LinkedHashMap:使用双链表来维护元素的顺序,要么是插入顺序,要么是最近最少使用的(LRU)顺序。

ArrayList和LinkedList之间的区别

是否保证线程安全:ArrayList和LinkedList不同步,即不保证线程安全;

底部数据结构:数组列表在底部使用对象数组;基础链表使用双循环链表数据结构;

是否支持快速随机访问:链表不支持高效的随机元素访问,而数组列表实现了随机访问接口,因此具有随机访问功能。快速随机访问是通过元素的序列号快速获取元素对象(对应于get(int index)方法)。

内存空间占用:ArrayList的空空间浪费主要体现在列表末尾的预留容量空间上,而LinkedList的空间消耗则体现在每个元素需要消耗比ArrayList更多的空间(因为要存储直接后继、直接前导和数据)。使用add方法时,

ArrayList扩展机制

首先调用ensureCapacityInternal方法,并传入大小为1的值,以检查elementData数组是否需要扩展。

newCapacity=扩展后的数组是原始数组的1.5倍(不能自定义)。如果容量不够,请使用它来指定要扩展的容量大小,然后确定该容量是否大于max _ array _ size(整数。max _ value-8)。如果大于,则为整数。取最大值;

扩展的主要方法:增长;

ArrayList中复制数组的核心是System.arrayCopy方法,它将原始数组的所有数据复制到复制数组中。这是一个本地方法。

HashMap/底层数据结构的实现原理?JDK1.7和JDK 1.8

JDK 1.7:条目数组链表

JDK1.8:Node 数组 + 链表/红黑树,当链表上的元素个数超过 8 个并且数组长度=64 时自动转化成红黑树,节点变成树节点,以提高搜索效率和插入效率到 O(logN)。Entry 和 Node 都包含 key、value、hash、next 属性。

HashMap 的 put 方法的执行过程

当我们想往一个 HashMap 中添加一对 key-value 时,系统首先会计算 key 的 hash 值,然后根据 hash 值确认在 table 中存储的位置。若该位置没有元素,则直接插入。否则迭代该处元素链表并依次比较其 key 的 hash 值。如果两个 hash 值相等且 key 值相等(e.hash==hash ((k=e.key)==key || key.equals(k))),则用新的 Entry 的 value 覆盖原来节点的 value。如果两个 hash 值相等但 key 值不等 ,则将该节点插入该链表的链头。

HashMap 的 resize 方法的执行过程

有两种情况会调用 resize 方法:

第一次调用 HashMap 的 put 方法时,会调用 resize 方法对 table 数组进行初始化,如果不传入指定值,默认大小为 16。

扩容时会调用 resize,即 size threshold 时,table 数组大小翻倍。

每次扩容之后容量都是翻倍。扩容后要将原数组中的所有元素找到在新数组中合适的位置。

HashMap 与 HashTable 的区别是什么?

线程是否安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);

效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它;

对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。

初始容量大小和每次扩充容量大小的不同 : ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。

层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。