面试之Java基础

1.String与StringBuffer与StringBuilder的区别

1.1概念

  • String:Java中数据类型分为基本数据类型和引用数据类型,String就属于引用数据类型。String是被final所修饰的类不可被继承。String类不可被修改,我们对字符串的操作在底层都是重新创建一个String对象,将引用指向新的对象而已。
  • StringBuffer:StringBuffer对象代表一个字符序列可变的字符串,当一个StringBuffer对象被创建后,提供了例如append(),insert(),reverse()等方法来操作字符串,这些操作都会是在原本的字符产上操作,不会产生新的对象
  • StringBuilder:StringBuilder和StringBuffer基本类似,他也是代表一个可变的字符串,他们的构造方法和方法也相同。两者最主要的区别就是一个线程安全,一个线程不安全。

1.2三者的异同

相同点: 都用来代表字符串,底层都是通过char数组实现的。
不同点:

  • String类是不可变类,String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;即任何对String的改变会引发新的String对象的生成。
  • StringBuffer和StringBuilder类则是可变类,他俩的原理和操作基本相同,任何对它所指代的字符串的改变都不会产生新的对象。StringBuffer几乎所有的方法都使用synchronized实现了同步,支持并发操作,线程安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder线程不安全,不支持并发操作,不能同步访问,不适合多线程中使用。但是效率比较高。
  • 需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费。考虑线程安全的场合使用 StringBuffer,如果不需要考虑线程安全,追求效率的场合可以使用 StringBuilder

2.String的常用方法

  • 获取字符串长度

int length();
  • 获取指定位置上某个字符 

char charAt(int index);
  • 获取指定字符在字符串中位置

int indexOf(int ch);//返回的是ch在字符串中第一次出现的位置

int indexOf(int ch, int fromIndex);//从fromIndex指定位置开始,获取ch在字符串中出现的位置

int indexOf(String str);//返回的是str在字符串中第一次出现的位置

int indexOf(String str, int fromIndex);//从fromIndex指定位置开始,获取str在字符串中出现的位置

int lastIndexOf(int ch);//返回的是str在字符串中最后一次出现的位置
  • 判断字符串中是否包含某一个子串 

boolean contains(String str);
  • 判断字符串是否是以指定内容开头

boolean startsWith(str);
  • 字符串是否是以指定内容结尾
boolean endsWith(str);
  • 判断字符串内容是否相同。复写了Object类中的equals方法
boolean equals(str);
  • 判断内容是否相同,并忽略大小写
boolean equalsIgnoreCase();
  • 将字符数组转换成字符串
构造函数:
String(char[])
String(char[],offset,count);//将字符数组中的一部分转成字符串

静态方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data, int offset, int count)
static String valueOf(char[]):
  • 将字符串转成字符数组
char[] toCharArray();
  • 将基本数据类型转成字符串
static String valueOf(int)
static String valueOf(double)
String str = 123 + "";
  • 替换指定字符
String replace(oldchar,newchar);//返回替换后的字符串
  • 切割
String[] split(regex);//返回一个string数组
  • 获取字符串中的一部分
String substring(begin);//包含起点到结尾
String substring(begin,end);//从起点到end(不包括end下标)
1
  • 将字符串转成大写或则小写
String toUpperCase();//大写
String toLowerCase();//小写
  • 将字符串两端的多个空格去除
String trim();

 3.final关键字

final关键字可以修饰类,变量,方法

3.1final修饰类

final用来修饰一个类,意味着该类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final。

当一个类被final修饰时,表明该类中所有的成员方法都会被隐式的指定为final方法。

3.2.final修饰方法

使用final修饰的方法为最终方法,不能再被子类重写,可以重载。

3.3final修饰变量

  • final修饰成员变量表示常量,只能被赋值一次,并且创建变量是必须要初始化,赋值后不再改变
  • final修饰基本数据类型的时候,表示该基本数据类型一旦被初始化之后便不能发生改变
  • 如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。

4.static关键字

4.1static修饰属性

static修饰类中属性,称之为类的静态属性/类属性(存储在JVM的方法区),和具体的对象无关。

使用:直接使用类名来访问静态变量,不推荐使用某个对象访问

4.2static修饰方法

static修饰方法,称之为类方法/静态方法,只能使用类中的静态属性以及静态方法。

使用:与具体对象无关,直接通过类名称来访问。

注意

  • 静态方法只能访问类中的静态属性,不能直接访问成员属性(需要通过对象来调用)。
  • 静态方法只能访问类中的其他静态方法,不能直接访问成员方法。
  • 访问其他类的静态方法必须加上类名称来访问,不然编译器只会在当前类中查找同名静态方法。

4.3static修饰内部内

普通类不允许static修饰,只有内部类可以被static修饰的内部类可以直接作为一个普通类来使用,而不需要实例一个外部类。

4.4static修饰静态代码块

  • 静态代码块会随着类的加载而执行,而且只执行一次。
  • 代码块就是一段独立的代码空间,静态代码块就是用static修饰的一段独立的代码。
  • 静态代码块优先于main函数执行。

5.抽象类和接口

  1. 抽象类和接口都用于抽象具体化对象,都不能直接实例化。但是两者的侧重点不同:抽象类主要用来抽象类型,表示这个对象是什么;接口主要用来抽象功能,表示这个对象能做什么
  2. 抽象类不仅有方法的声明,也有默认方法的实现;接口完全时抽象的,根本不存在方法的实现
  3. 对于实现:子类使用extends关键字来继承抽象类。如果子类不是抽象类,他必须提供抽象类中所有的声明的方法的实现;子类使用用implements来实现接口。它需要提供接口中所有的声明的方法的实现
  4. 抽象类除了不能实例化之外,和Java的普通类没有区别;接口是一个完全不同的类型
  5. 抽象类可以继承一个类和实现多个接口;接口只可以继承一个或者多个其他接口
  6. 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码;如果你往接口中添加方法,那么你必须改变实现该接口的类

6.==与equals的区别

"==":该运算符不仅可以比较基本数据类型,还可以比较引用类型

如果"=="比较基本数据类型,此时判断他们的值是否相等

如果"=="比较引用类型,判断两个对象指向的内存地址是否相同

"equals":是object 类中的方法,所有继承自object的类都有equals方法,他只能判断引用类型

在object中默认判断地址是否相同,等价于"=="比较两个对象,如果在子类中重写了equals方法,此时也可以判断内容是否相同。

7.ArrayList与LinkedList

相同点:ArrayList与LinkedList都是List的实现类

不同点:

  • 底层实现不同:
    • ArrayList底层是基于数组实现的,对于普通的数组而言,它是一个可以动态修改的数组。没有数组大小的限制,我们可以进行添加元素和删除元素。
    • LinkedList底层是基于双向链表来实现的,每一个元素都和他前一个元素和后一个元素连接在一起
  • 工作效率不同:
    • ArrayList由于底层的原因,对于查找某个元素的速度很快
    • LinkedList对于添加,删除元素的速度更快,因为将元素添加到集合的任意一个位置时,不需要像数组一样重新计算大小或者更新索引。
  • LinkedList相比于ArrayList更占用内存:因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

你可能感兴趣的:(面试,面试,java)