Java基础篇
1、面向对象和面向过程的区别
面向过程:是分析解决问题的步骤,使用函数一步一步的实现,在使用的时候调用即可。性能比较高
面向对象:把构成问题的事务分解成各个对象,建立的对象是为了描述某个事物的特征和行为。面向对象
有封装继承和多态的特性,所以容易维护,复用和扩展。可以解耦合。但是性能上来说,比面向过程要低。
2、面向对象三大特性(封装继承多态)
封装:隐藏属性与动作,暴露接口,增强安全性和简化代码,提高代码复用性。
继承:实现代码的复用,但是不能继承父类的私有属性方法和构造方法。同时子类可以扩展属于自己的方法,或者重写父类方法。
多态:主要是通过方法的重写重载实现调用相同的方法产生不同的结果。
3、8种基本数据类型
基本类型 大小(字节) 默认值 封装类
byte 1 (byte)0 Byte
short 2 (short) 0 Short
int 4 0 Integer
long 8 0L Long
float 4 0.0f Float
double 8 0.0d Double
boolean 1 false Boolean
char 2 \u0000(null) Character
注:使用封装类主要是因为封装类可以存null,
boolean类型,java对它没有很多的支持,编译过之后还是使用int类型代替,
boolean[] 则是被编译成byte[] 数组
4、标识符的命名规则
标识符的含义:就是我们可以自己定义的内容,比如类名,方法名,变量名等
命名规则(Java的要求):可以使用英文字母,0-9的数字以及$和_,但是标识符不能用数字开头,
并且标识符还不能是关键字。
命名规则(命名规范):类名:首字母大写,后面每个单词的首字母大写(大驼峰)
变量名、方法名:首字母小写,后面的单词首字母大写(小驼峰)
常量名:所有字母全部大写,单词中间使用_隔开
5、instanceof关键字的作用
1.用来测试某个对象是不是一个类的实例,或者是其间接子类,实现类
boolean b = obj instanceof Class
int i = 0;
sout(i instancesof Integer)//编译报错,i必须是引用类型
sout(null instancesof Integer) //返回的是fales
6、Java自动装箱和拆箱
装箱: 基本数据类型通过,valueOf()方法进行装箱成为包装类
拆箱: 包装类通过,例如intValue()方法进行拆箱成为基础数据类型
7、重载和重写的区别
重写:Override,在继承关系下,子类将父类的方法进行扩展,方法名,参数,返回类型都不能改变(返回值类型可以是父类返回值类型的子类)。注意权限修饰符一定大于父类权限修饰符。主要是重写方法体。
重载:同一个类中,多个方法名相同,但参数类型,个数,顺序不同,就可以实现方法的重载,与返回值相不相同无关。
8、接口和抽象类的区别
1、接口可以多实现,抽象类只能单继承。
2、抽象类可以有非抽象方法和构造方法以及变量,接口只能有抽象方法和静态常量。
3、抽象类的子类可以继承抽象类中的公共方法和公共属性,接口中只有静态常量所以不存在继承关系。
9、equals和 == 的区别
==:比较的是变量的内存中存放对象的内存地址是否相同。
equals:用来判断两个对象的内容是否相同,如果没有重写equals方法的话,还是比较的**==**操作
10、hashcode的作用
1、根据对象内存地址换算出来一个值。
2、如果有同样的hash产生就进行equals操作比较是不是同一个对象,
3、如果不是就放到其他的地方重新再计算hashcode值
11、String、StringBuffer、StringBuilder的区别
1、String 底层是使用final关键字修饰的字符数组,其所引用的字符串不可以被改变,每次操作String都会产生新的String对象,所以也是线程安全的。
2、StringBuffer 是线程安全的可变字符数组,效率相对StringBuilder较低(底层使用的同步块关键字),多线程操作字符串建议使用。
3、StringBuilder 是线程不安全的可变字符数组,效率相对较高。
12、java中的集合们
java中的集合分为单列集合 和双列集合,单列集合顶级接口是Collection,双列集合是:Map
单列集合顶级接口是Collection的子接口有List和Sat:
1、List 接口的特点:元素可重复,存取有序。实现List接口的实现类有:
a、ArrayList:底层实现是数组,查询速度快,增删速度慢,线程不安全,效率高。
b、Vector:底层实现的是数组,查询速度快,增删速度慢,线程安全,效率低,已经被废弃了
c、LinkedList:底层实现是链表,查询慢,增删快,线程不安全,效率高。
2、Set接口的特点;元素不可重复且唯一,存取无序。实现Set接口的实现类有:
a、HashSet:底层实现HashMap,数组+链表实现,不允许元素重复,无序
b、TreeSet:底层实现红黑二叉树,实现元素排序
双列集合是:Map 接口特点是:
1、Key-Value键值对形式存储数据,Map接口的实现类:
a、HashMap:底层数组+链表实现,线程不安全效率高
b、TreeMap:底层红黑二叉树实现,可实现元素排序
c、LinkedHashMap:底层hashMap+linkedList实现,通过hashMap实现Key-value键值对存储,通过链表实现元素有序。
13、ArrayList和LinkedList的区别
相同点:
1、都是List接口的实现类,元素可重复,存取有序
2、线程都不安全
不同点:
1、数据结构:ArrayList底层使用动态数组,LinkedList底层使用双向链表
2、随机访问效率:ArrayList的动态数组相比linkedList的双向链表在访问时较有优势。
3、增删效率:双向链表的突出表现,LinkedList完胜ArrayList
14、HashMap底层原理
Hash底层使用数组+链表实现,默认初始化的大小为16,也就是0-15的索引,没个索引中都存储一个链表。
JDK8之后当hashMap表的单一链表长度超过8个的时候,链表结构就会转为红黑树结构。
当到达容量的75%后,会对数组进行扩容,新建数组,然后把元素拷贝到新数组中,每次扩容翻倍。
hashMap在存储的时候一样可能会产生hash碰撞(就是两个数据完全不同,但hash值却相同),hashMap会将元素以链表的形式进行储存存到链表中,第一个entry存在链表顶端,再有产生hash值相同的,则继续往后放。
15、Java是值传递还是引用传递
Java只支持值传递,并且基本数据类型和引用数据类型存储的变量都存储在栈(stack)内存中
基本数据类型存储的是他的字面值。
引用类型存储的是他引用对象在堆(heap)中的地址。
16、Java的类加载机制
加载阶段:ClassLoader通过类的全限定名查找该类的字节码文件,并且使用字节码文件创建class对象。
验证阶段:此阶段主要是为了确认class文件的字节流包含的信息是当前虚拟机可以识别的,并且不会危害到虚拟机自身的安全,
主要有四种验证:1、文件格式的验证 2、元数据的验证 3、字节码验证 4、符号引用验证
准备阶段:给加载的类中的静态变量也就是static修饰的变量进行分配内存,并且赋予初始值。
**注意:**此时使用final关键字修饰的static在编译的时候就已经被赋予了,所以这里不包含他们。
另外实例变量也不会分配初始化,类变量会分配在方法区中,实例变量会随着对象分配到Java堆中。
解析阶段:此时是把常量池中的符号引用转换为直接引用
初始化阶段:这是如果该类具有父类,则先初始化其父类,如果没有就继续执行该类静态代码块和静态初始化成员变量(此时被static修饰的静态成员变量被赋值,成员变量也将被初始化)
17、Java类的加载顺序
1、所有的类都会优先加载基类
2、静态成员变量优先被初始化
3、城边初始化后,才会执行构造方法
4、 静态成员与静态代码块的执行,发生在类加载的时候;
成员加载在对象创建的时候,
类对象以及静态代码块的访问都会触发类加载。
18、手写排序算法
//冒泡排序(大的往后排)
public void bobbleSort(int[] a){
int len = a.getLenth();
for(int i = 0, i < len, i++){
for(int j = 0, j < len - i - 1, j++){
if(a[j] > a[j+1]){
int temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
}
//选择排序(小的往前排)
public void selectSort(int[] a){
int len = a.getLenth();
for(int i = 0, i < len, i++){//循环次数
int value = a[i];
int p = i;
for(int j = i + 1, j < len, j++){//定位小值
if(a[j] < value){
value = a[j];
p = j;
}
}
a[p]=a[i];//交换位置和数据
a[i]=value;
}
}