- Java有几种数据类型?分别存储的是什么?
java 中有八种基本数据类型。
分别为整型 int,短整型 short,长整型 long,字节型 byte,布尔型 boolean,字符型 char,单精度浮点数 float,双精度浮点数 double。
- Java的八种基本数据类型?所占字节空间大小是多少?
char | 2 | Character |
short | 2 | Shot |
int | 4 | Integer |
long | 8 | Long |
float | 4 | Float |
double | 8 | Double |
boolen | 1 | Boolean |
byte | 1 | Byte |
- 循环语句while和do while的区别什么?
while是先判断再循环
do while 是先循环一次再判断
- i++和++i区别是什么?
++ i 是先加后赋值;i ++ 是先赋值后加;
i++ 不能作为左值,而++i 可以。
- 什么是局部变量?
定义在方法、局部代码块中,没有初始值,必须手动初始化,第一次赋值时分配内存,局部变量的作用范围在定义的大括号内有效,在作用域中不能重复定义;局部变量的生命周期:局部变量的作用域就是它的生命周期,如方法里的局部变量,在方法调用完就销毁。
- 什么是实例变量?
定义在类中,自动初始化成默认值,作用域在整个类中,访问范围可以用访问控制符来控制,允许定义同名的局部变量;成员变量属于对象,也叫实例变量;
成员变量的生命周期:成员变量的生命周期贯穿其整个对象的生命周期,在对象销毁时销毁。
- 什么是类变量?
被static修饰的变量称为静态变量,静态属于类,所以也叫类变量。只要加载了类的字节码对象,静态变量就会被配空分间,静态变量就可以被使用,可以直接用类名来引用。
静态方法中,不能直接调用非静态方法;要创建对象,用对象调用;
静态变量的生命周期:随着类的加载而存在,随着类的消失而消失。
- 局部变量、实例变量和类变量的区别是什么?
1、成员变量属于对象,静态变量属于类;
2、局部变量作用域只在定义的大括号内,成员变量访问范围由访问控制符控制
3、局部变量的作用域就是它的生命周期,成员变量的生命周期贯穿其整个对象的生命周期,在对象销毁时销毁,静态变量生命周期随着类的加载而存在,随着类的消失而消失。
4、成员变量存在堆内存中,静态变量存在方法区中(栈存方法,堆存属性)
5、成员变量只能被对象调用,静态变量可以被对象调用,也可以被类名调用
6、优先级局部变量>成员变量,调用成员变量使用this
- 什么是值传递?什么是引用传递?
值传递是传递变量的值,并不会改变方法外变量的值;引用传递是传递对象的地址,会改变对象本身的值;
值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。
引用传递:(形式参数类型是引用数据类型参数):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。
- String、StringBuilder和StringBuffer的区别?
String是字符串常量,修改时会产生新对象,StringBuilder和StringBuffer是字符串变量,能够多次被修改,并且不产生新对象
在运行速度上:StringBuilder > StringBuffer > String
线程安全上:StringBuilder 线程不安全,StringBuffer线程安全
- 什么是封装类?有什么作用?
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。(代码常见在pojo层)
封装的优点:
良好的封装可以减少耦合;
类内部的结构可以自由修改;
可以对成员变量更精准的控制;
隐藏信息,实现细节;
- 什么是重载?什么是重写?
1、重载(发生在本类,编译器绑定)和重写(发生在父子类,运行期绑定)中的区别?
a、重载发生在本类中,重写发生在父子类中;
b、重载在编译器绑定,重写在运行期绑定;
C、被final修饰的方法不能被重写,但是可以被重载;
d、重写是子类重写父类的方法,但不能重写父类中被final修饰的方法;重载是一个类有多个同名不同参数 的方法,本类中被final修饰的方法可以被重载;
- 构造函数能否重载或者是重写?为什么?
可以重载,因为只要方法名相同,参数不同即可
不可以重写,因为重写的前提是发生在继承里
- super与this可以同时放在首行吗?为什么?
不可以.
- 举个例子说说什么是多态?多态的存在条件是什么?
多态是同一个行为具有多个不同表现形式或形态的能力。
多态的优点:可以消除类型之间的耦合关系;具有可替换性、可扩充性、接口性、灵活性和简化性;
多态存在的三个必要条件:继承;重写;父类引用指向子类对象;
如 Parent p = new Children();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
虚函数:虚函数的存在是为了多态;Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。
- 继承有什么好处?
提高了代码的复用性,提高了代码的维护性,让类与类之间产生了关系,是多态的前提
- 什么是面向对象?
java的面向对象是一种软件开发的方法,也是一种编程思想;面向对象可以将复杂的业务逻辑简单化,增强代码复用性,面向对象具有继承、封装、多态、抽象特性;
- final修饰基本类型变量和引用类型变量的区别?
Java关键字,用来修饰常量(变量)、方法、类
用来修饰类时:final修饰的类不能被继承,
用来修饰变量时:
如果变量是基本数据类型变量,其数据一旦初始化后便不能被更改;
如果变量是引用类型变量,初始化后便不能再指向另一个对象
如果修饰的是类变量,只能在静态初始化块中指定初始值
如果修饰的是成员变量:可以在非静态初始化块声明该变量或者在构造器中执行初始值;
修饰局部变量:可以在定义指定默认值,也可以不指定
用来修饰方法时:表示方法不可被重写、覆盖,但是可以被重载
- 对象创建过程是怎么样的?
1,获取到传过来的key,调用hash算法获取到hash值
2,获取到hash值之后调用indexFor方法,通过获取到的hash值以及数组的长度算
出数组的下标 (把哈希值和数组容量转换为二进,再在数组容量范围内与哈希值
进行一次与运算,同为1则1,不然则为0,得出数组的下标值,这样可以保证计算出的数组下标不会大于当前数组容量)
3,把传过来的key和value存到该数组下标当中。
4,如该数组下标下以及有值了,则使用链表,jdk7是把新增元素添加到头部节点 jdk8则添加到尾部节点。
- 说说hashmap的工作原理?
HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,计算并返回的hashCode是用于找到Map数组的bucket位置来储存Node 对象。这里关键点在于指出,HashMap是在bucket中储存键对象和值对象,作为Map.Node 。
以下是HashMap初始化 ,简单模拟数据结构Node[] table=new Node[16] 散列桶初始化,tableclass Node {hash;//hash值 key;//键 value;//值 node next;//用于指向链表的下一层(产生冲突,用拉链法)}
以下是具体的put过程(JDK1.8版)
1、对Key求Hash值,然后再计算下标
2、如果没有碰撞,直接放入桶中(碰撞的意思是计算得到的Hash值相同,需要放到同一个bucket中)
3、如果碰撞了,以链表的方式链接到后面
4、如果链表长度超过阀值( TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表
5、如果节点已经存在就替换旧值
6、如果桶满了(容量16*加载因子0.75),就需要 resize(扩容2倍后重排)
以下是具体get过程(考虑特殊情况如果两个键的hashcode相同,你如何获取值对象?)当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。
- LinkedList 与ArrayList的区别?
ArrayList是基于数组实现的,LinkedList基于链表实现的;ArrayList随机查询快,LinkedList插入和删除速度快;
- 说说你对线程的理解?
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。
线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。(线程之间实际上是轮换执行的)
- error和Exception 的区别?
Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。
Exception又分为检查性异常和非检查性异常。两个根本的区别在于,检查性异常 必须在编写代码时,使用try catch捕获(比如:IOException异常)。非检查性异常 在代码编写使,可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的。 切记,Error是Throw不是Exception 。
- 抽象类和接口的区别
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类将很容易的就能得到这些新方法。
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
23、什么是线程死锁?怎么避免?
死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。
死锁产生的必要条件
产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。
互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, ..., pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, ..., n-1),Pn等待的资源被P0占有
24、说说java中的集合?
java中的集合分为value(Collection),和key-value(Map)两种;
存储value的有list和set两种:
list是有序的,可重复的
set是无序的,不可重复的
存储为key-value是map:HashMap,Hashtable,CurrentHashMap
25、说说你对多线程的理解?
线程是由一个主线程和很多个子线程组成的,主线程消失,子线程也会消失,但是子线程消失其中一个主线程不会消失
线程的生命周期分为5个步骤像人的一生一样,这5个步骤分别对应了5个方法
新生-->启动-->运行-->阻塞-->销毁
继承Thread类or实现runnable方法-->start-->run-->sleep(睡眠)or wait(挂起)-->destroy