java基础面试总结
java基础
1.排序
/*
选择排序。
特点:
在内循环第一次结束,最值出现最低角标位。
*/
public static void selectSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]<arr[y])
{
/*
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
*/
swap(arr,x,y);
}
}
}
}
/*冒泡排序。
特点:相邻两个元素进行比较。
内循环结束一次,最值出现在最后角标位。
*/
public static void bubbleSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=0; y<arr.length-x-1; y++)
{
if(arr[y]>arr[y+1])
{
/*
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
*/
swap(arr,y,y+1);
}
}
}
}
二分查找(折半查找)
/**
* 二分查找
*
* @param arr 数据源
* @param key 查找的数据
* @return 在arr里的位置
*/
private int halfSearch(int[] arr, int key) {
int min, mid, max;
min = 0;
max = arr.length - 1;
while (min <= max) {
mid = (min + max) / 2;
if (key > arr[mid]) {
min = mid + 1;
} else if (key < arr[mid]) {
max = mid - 1;
} else {
return mid;
}
}
return -1;
}
2.static final
static有三种形式,静态方法,静态变量,静态代码块。
静态在随着类加载的时候就一起加载。
静态只能调用静态变量;
静态方法只能调用静态方法;
不能以任何形式引用this,super;
静态方法的调用不依附于实例对象
final
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
当修饰类的时候,该类不能被继承。
当修饰方法的时候,该方法不能被重写。
当修饰变量的时候,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
3.基本数据类型
类型 | 字节 | 位数 |
---|---|---|
byte | 1字节 | 8位 |
short | 2字节 | 16位 |
int | 4字节 | 32位 |
long | 8字节 | 64位 |
double | 8字节 | 64位 |
float | 4字节 | 32位 |
char | 2字节 | 16位 |
boolean | 1字节 | 8位 |
4.集合
list
ArrayList 数组结构,线程不安全的,查询速度快。
LinkedList 链表结构,线程不安全,插入和删除的速度快。
vector 数组结构,线程安全。无论增删或者查询效率都很低。被ArrayList替代。
set
存入set的每个元素都必须是唯一的,因为set不保存重复元素。
HashSet 哈希表结构,为快速查找而设计,效率高
TreeSet 二叉树结构,使用它可以从set中提取有序的序列。
map
HashMap基于散列表的实现,可以存储键值对形式的数据,可以null键值,效率高,线程不安全。
LinkedHashmap 基于hashmap的结构之上,其默认获取数据的顺序是插入顺序。也可以通过构造方法设置为最近最少使用的次序(LRU)。
TreeMap基于红黑树的实现,查看数据的时候,会被排序。
5.线程
1.继承Thread
2.实现Runable接口
3.实现Callable,和Runable的区别是有回调方法。
区别 :实现Runable接口扩展性更好,因为继承只能单向继承
什么是线程?
线程是操作系统运行的最小单元;进程里包含了多个线程,他们处理不同的任务,组成了一个应用或者一个系统的整体逻辑。
sleep和wait的区别 最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁。wait 通常被用于线程间交互,sleep 通常被用于暂停执行。
Thread.yield():让步,当一个线程执行yield()方法,证明该线程执行让步,让其他线程有可能的获取资源运行。
**Thead.join(): **加入,当一个线程执行join(),证明该线程执行加入操作,会终止当前正在运行的线程,开始执行join的线程。
Thread 优先级:Thread.currentThread().setPrority(value);value=Max_prority;Norm_priority;Min_priority;三种不同的优先等级;
Thread.setDaemon(boolean);设置当前线程为后台线程,后台线程要在start之前调用才有效。后台线程,是指程序运行的时候在后台提供一种通用服务的线程,且这种线程并不属于程序中不可或缺的部分;只要有任何非后台线程在运行,程序就不会终止。
线程池:是统一管理线程的服务对象。优点是通过控制线程的创建和销毁,节省资源,提高效率。
6.面向对象,封装、继承、多态
封装:隐藏实现细节,提高程序的复用性和维护性
继承:子类继承父类,表明子类拥有父类的属性和方法(注意是public protected修饰符的)
多态:父类引用指向子类对象
抽象类和接口的区别
抽象类是abstract修饰的类,表示该类不足以描述一个具体的事物或者对象,就叫抽象类。
接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为或者功能。
抽象类可以存在非抽象的方法和变量。接口中除了static、final变量,不能有其他变量
抽象类可以有构造器,但接口不能有。
抽象类的方法可以用public、protected和default这些修饰符,但接口只能用public修饰。
抽象类是继承关系,而接口是实现关系。
7.泛型
- 概念:编写的代码可以被不同的对象类型所重用。泛型的本质是参数化类型。所操作的数据类型被指定为一个参数。有三种形式:泛型类、泛型方法、泛型接口
- 出现:有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。
- 泛型好处:
类型安全:提高java程序的类型安全,编译时期就可以检查出类型不正确导致的类型转换异常,消除强制类型转换。
泛型进阶
泛型的通配符:
<?> 无限制通配符
<? extends E> extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类
<? super E> super 关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类
泛型的类型擦除:当编译器对带有泛型的java代码进行编译时,它会去执行类型检查和类型推断,然后生成普通的不带泛型的字节码,这种普通的字节码可以被一般的 Java 虚拟机接收并执行,这在就叫做 类型擦除(type erasure)。
擦除的实现原理:Java 编辑器会将泛型代码中的类型完全擦除,使其变成原始类型。
当然,这时的代码类型和我们想要的还有距离,接着 Java 编译器会在这些代码中加入类型转换,将原始类型转换成想要的类型。这些操作都是编译器后台进行,可以保证类型安全。
总之泛型就是一个语法糖,它运行时没有存储任何类型信息。