一、JavaSE编程基础
1.JDK,JRE,JVM三者关系
a.、jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。
b.、JRE是JAVA程序运行时需要的运行环境,就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就 能运行已经存在的JAVA程序了。
c.、JDk、JRE内部都包含JAVA虚拟机JVM,JAVA虚拟机内部包含许多应用程序的类的解释器和类加载器等等。
2.面向过程和面向对象的区别
a.、两者都是软件开发思想,先有面向过程,后有面向对象。在大型项目中,针对面向过程的不足推出了面向对象开发思想。 b.、编程思路不同:面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、 执行方法来完成功能。
c.、封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据和功能。面向对象具有继承性和多态性, 而面向过程没有继承性和多态 性,所以面向对象优势是明显。
3.Java有哪些基本数据类型
定义:Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。 a.、数值型:整数类型(byte,short,int,long)
b、浮点类型(float,double) c、字符型(char)
d、布尔型(boolean)
4.什么Java注释
定义:用于解释说明程序的文字分类:
单行注释:格式: // 注释文字多行注释:格式: /* 注释文字 /
文档注释:格式:/* 注释文字 */
作用:在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内 容在程序编译的时候会被忽视,不会产生目标代码,注释的部分不会对程序的执行结果产生任何影响。
注意事项:多行和文档注释都不能嵌套使用。
5.Java 有没有 goto
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
6.final 有什么用?
用于修饰类、属性和方法;
a、被final修饰的类不可以被继承
b、被final修饰的方法不可以被重写
c、被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
7.final fially finalize区别
a、final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个 常量不能被重新赋值。
b、finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是 否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
c、finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调 用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
8.面向对象三大特性
a、封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
b、继承:继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的 功能,但不能选择性地继承父类。通过使用继承可以提高代码复用性。继承是多态的前提。
c、所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序 运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必 须在由程序运行期间才能决定。
9.== 和 equals 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
10.String 类的常用方法都有那些?
a、indexOf():返回指定字符的索引。b、charAt():返回指定索引处的字符。 c、replace():字符串替换。
d、trim():去除字符串两端空白。
e、split():分割字符串,返回一个分割后的字符串数组。 f、getBytes():返回字符串的 byte 类型数组。
g、length():返回字符串长度。
h、toLowerCase():将字符串转成小写字母。 i、toUpperCase():将字符串转成大写字符。g、substring():截取字符串。
k、equals():字符串比较。
11.String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的
a、可变性:String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串, char[] value,这两种对象都是可变的。
b、线程安全性:String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步 锁,所以是非线程安全的。
c、性能:每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer 每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的总结:如果要操作少量的数据用 = String,单线程操作字符串缓冲区 下操作大量数据 = StringBuilder,多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
12.自动装箱与拆箱
a、装箱:将基本类型用它们对应的引用类型包装起来; b、拆箱:将包装类型转换为基本数据类型;
13.int 和 Integer 有什么区别
Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
14.Java 为每个原始类型提供了哪些包装类型:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
15.ArrayList、LinkedList、Vector 的区别。
ArrayList,Vector 底层是由数组实现,LinkedList 底层是由双线链表实现,从底层的实现可以得出它们的性能问题, ArrayList,Vector 插入速度相对较慢,查询速度相对较快,而LinkedList 插入速度较快,而查询速度较慢。再者由于 Vevtor 使用了线程安全锁,所以ArrayList 的运行效率高于 Vector。
16.HashMap 和 Hashtable 的区别
a、线程是否安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);
b、效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它;
c、对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为null。。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛出 NullPointerException。
d、初始容量大小和每次扩充容量大小的不同 : ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了 容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小
e、底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。
17.Synchronized 用 过 吗 , 其 原 理 是 什 么 ?
Synchronized 是 由 JVM 实 现 的 一 种 实 现 互 斥 同 步 的 一 种 方 式 , 如 果你 查 看 被 Synchronized 修 饰 过 的 程 序块 编 译 后 的 字 节 码 , 会 发 现 ,被 Synchronized 修 饰 过 的 程 序 块 , 在 编 译 前 后 被 编 译 器 生 成 了monitorenter 和 monitorexit 两 个 字 节 码 指 令 。这 两 个 指 令 是 什 么 意 思 呢 ?在 虚 拟 机 执 行 到 monitorenter 指 令 时 , 首 先 要 尝 试 获 取 对 象 的 锁 :如 果 这 个 对 象 没 有 锁 定 , 或 者 当 前 线 程 已 经 拥 有 了 这 个 对 象 的锁 , 把 锁的 计 数 器 +1; 当 执 行 monitorexit 指 令 时 将 锁 计 数 器 -1; 当 计 数 器为 0 时 , 锁 就 被 释 放 了 。如果 获 取 对 象 失 败 了 , 那 当 前 线 程 就 要 阻 塞 等 待 , 直 到 对 象 锁 被 另 外 一个 线 程 释 放 为 止 。Java 中Synchronize 通 过 在 对 象 头 设 置 标 记 , 达 到 了 获 取 锁 和 释 放锁 的 目 的 。
18.为 什 么 说 Synchronized 是 非 公 平 锁 ?
非 公 平 主 要 表 现 在 获 取 锁 的 行 为 上 , 并 非 是 按 照 申 请 锁 的 时 间 前 后 给 等待 线 程 分 配 锁 的 , 每 当 锁 被释 放 后 , 任 何 一 个 线 程 都 有 机 会 竞 争 到 锁 ,这 样 做 的 目 的 是 为 了 提 高 执 行 性 能 , 缺 点 是 可 能 会 产 生线 程 饥 饿 现 象 。
19.为 什 么 说 Synchronized 是 一 个 悲 观 锁 ? 乐 观 锁 的 实 现 原 理又 是 什 么 ? 什 么 是 CAS, 它 有 什 么 特 性 ?
Synchronized 显 然 是 一 个 悲 观 锁 , 因 为 它 的 并 发 策 略 是 悲 观 的 :不 管 是 否 会 产 生 竞 争 , 任 何 的 数 据 操作 都 必 须 要 加 锁 、 用 户 态 核 心 态 转换 、 维 护 锁 计 数 器 和 检 查 是 否 有 被 阻 塞 的 线 程 需 要 被 唤 醒 等 操 作
。随 着 硬 件 指 令 集 的 发 展 , 我 们 可 以 使 用 基 于 冲 突 检 测 的 乐 观 并 发 策 略 。先 进 行 操 作 , 如 果 没 有 其他 线 程 征 用 数 据 , 那 操 作 就 成 功 了 ;如 果 共 享 数 据 有 征 用 , 产 生 了 冲 突 , 那 就 再 进 行 其 他 的 补 偿 措施 。 这 种乐 观 的 并 发 策 略 的 许 多 实 现 不 需 要 线 程 挂 起 , 所 以 被 称 为 非 阻 塞 同 步 。乐 观 锁 的 核 心 算 法是 CAS( Compareand Swap, 比 较 并 交 换 ) , 它 涉及 到 三 个 操 作 数 : 内 存 值 、 预 期 值 、 新 值 。 当 且 仅 当预 期 值 和 内 存 值 相等 时 才 将 内 存 值 修 改 为 新 值 。这 样 处 理 的 逻 辑 是 , 首 先 检 查 某 块 内 存 的 值 是 否 跟之 前 我 读 取 时 的 一样 , 如 不 一 样 则 表 示 期 间 此 内 存 值 已 经 被 别 的 线 程 更 改 过 , 舍 弃 本 次 操作 , 否 则说 明 期 间 没 有 其 他 线 程 对 此 内 存 值 操 作 , 可 以 把 新 值 设 置 给 此块 内 存 。CAS 具 有 原 子 性 , 它 的 原 子 性由 CPU 硬 件 指 令 实 现 保 证 , 即 使 用JNI 调 用 Native 方 法 调 用 由 C++ 编 写 的 硬 件 级 别 指 令 , JDK 中 提供 了Unsafe 类 执 行 这 些 操 作 。
20.乐 观 锁 一 定 就 是 好 的 吗 ?
乐 观 锁 避 免 了 悲 观 锁 独 占 对 象 的 现 象 , 同 时 也 提 高 了 并 发 性 能 , 但 它 也有 缺 点 :
a、乐 观 锁 只 能 保 证 一 个 共 享 变 量 的 原 子 操 作 。 如 果 多 一 个 或 几 个 变 量 , 乐观 锁 将 变 得 力 不 从 心 , 但互 斥 锁 能 轻 易 解 决 , 不 管 对 象 数 量 多 少 及 对 象颗 粒 度 大 小 。
b、长 时 间 自 旋 可 能 导 致 开 销 大 。 假 如 CAS 长 时 间 不 成 功 而 一 直 自 旋 , 会给 CPU 带 来 很 大 的 开 销 。
c、ABA 问 题 。 CAS 的 核 心 思 想 是 通 过 比 对 内 存 值 与 预 期 值 是 否 一 样 而 判断 内 存 值 是 否 被 改 过 , 但 这个 判 断 逻 辑 不 严 谨 , 假 如 内 存 值 原 来 是 A,后 来 被 一 条 线 程 改 为 B, 最 后 又 被 改 成 了 A, 则 CAS 认 为 此内 存 值 并没 有 发 生 改 变 , 但 实 际 上 是 有 被 其 他 线 程 改 过 的 , 这 种 情 况 对 依 赖 过 程值 的 情 景 的 运 算 结果 影 响 很 大 。 解 决 的 思 路 是 引 入 版 本 号 , 每 次 变 量 更新 都 把 版 本 号 加 一 。