SE 基础
阐述你对 JVM、JDK 和 JRE 的理解?
答案
JVM是java虚拟机,提供了不依赖底层和操作系统的接口,跨平台基础;JRE 是 java 运行环境,支撑 Java 程序的运行,包含基本类库,面向使用 java 程序的用户;
JDK 是 java 开发程序包,支持 Java 程序的开发,包含 JRE,面向 java 开发人员;
== 和 equals 的区别是什么?
答案
- ==
如果是基本类型,判断是否相等
如果是对象,判断地址是否相等
- equals
只能判断对象内容是否相等。
对于自定义类,如果没有重写 equals 方法,则比较的是地址。
Math.round(-1.5) 等于多少?
答案
四舍五入的本质是:加0.5 然后取整重写和重载的区别
答案
重写:子类修改父类的方法;重载: 同一个类里的不同参数;
为什么函数不能根据返回类型来区分重载
答案
函数的返回值只是作为函数运行之后的一个“状态”,不能作为标识。抽象类(abstract class)和接口(interface)有什么异同
答案
构造函数:接口不能有方法:接口必须全部是抽象类
属性(成员变量):接口中都是常量
权限修饰符:接口全是 public,抽象不限制
静态变量和实例变量的区别
答案
静态变量由static修饰。属于类,不属于任何一个实例。而实例变量就是我们每次 new 后在内存中开辟的新的对象。
Java 中实现多态的机制是什么
答案
父类的引用变量可以指向子类的实例对象;switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String
答案
可以,java 任何版本都不能作用在 Long 上;
jdk7 开始,可以作用在 String 上。
String 、StringBuilder 、StringBuffer 的区别
答案
String 是只读字符串StringBuffer/StringBuilder 是可修改字符串。
StringBuilder 它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比 StringBuffer 要高
如何取得年 月日、小时分钟秒
答案
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.YEAR));
System.out.println(cal.get(Calendar.MONTH)); // 0 - 11
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.HOUR_OF_DAY));
System.out.println(cal.get(Calendar.MINUTE));
System.out.println(cal.get(Calendar.SECOND));
jdk8 日期处理函数
答案
TODOstring 常量池
Integer 常量池
答案
serialVersionUID 的作用
答案
serialVersionUID 指定了class的版本。如果你不定义,会自动生成,每次修改类属性都会变。
反编译时,如果 UID 不一样则反序列化失败。
当我们修改 class 但仍然想反序列化之前文件,则必须要定义这个 UID
如何实现对象克隆
答案
方法一: 继承Cloneable接口,并重写clone()方法方法二:
实现 Serializable 接口,通过序列化和反序列化,实现深度克隆。
public class MyUtil {
/**
* 通过序列化实现深度克隆
* 先序列化对象到内存
* 再反序列化对象并返回
*
* @param obj
* @param <T>
* @return
* @throws Exception
*/
public static <T extends Serializable> T clone(T obj) throws Exception {
/**
* 先序列化对象到内存
*/
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(obj);
/**
* 反序列对象并返回
*/
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
}
}
异常处理
异常分类
答案
编译时异常CheckedException:(try...catch 、throws)运行时异常
error 和 exception 的区别
答案
Error 类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存溢出等。Exception 类表示程序可以处理的异常,分为编译时异常和运行时异常。
java 异常处理机制
答案
详细信息请写出你最常见的 5 个 RuntimeException
答案
运行时异常,没有使用try catch,JVM进行处理的异常。未初始化然后调用函数,NullPointException
下标越界:ArrayIndexOutOfBoundsException
StringIndexOutOfBoundsException
强转失败:
ClassCastException
NumberFormatException
除数为 0:
ArithmeticException
throw 和 throws 的区别
答案
throw方法体内,执行就一定抛出异常;throws 方法声明后,表示可能发生异常。
final、finally、finalize 的区别
答案
final: 修饰类、属性、方法,表示不能继承、重写。finally:try catch
finalize:object 的一个方法,永远回收对象。
Java 的集合(重点)
阐述 Collection 和 Map 的体系
答案
阐述 hashmap 和 arrayList 底层原理
阐述集合的线程安全
答案
ArrayList HashSet HashMap 线程不安全。
Vector HashTable 线程安全。
其实,Collections 提供了方法可以 jiang 将不安全转换为安全:
Collections.synchronizedCollection(c)
Collections.synchronizedList(list)
Collections.synchronizedMap(m)
Collections.synchronizedSet(s)
打开源码可以查看到,其实就是在方法上面加了同步代码块。
如何给 hashmap 排序
答案
先存到list集合中,排序后使用linkedhashmap保存什么是并发集合
答案
* ConcurrentHashMap(原理:分段锁) * CopyOnWriteArrayList(原理:操作的时候给一个副本,读多写少的时候使用) * CopyOnWriteHashSetMap 中的 key 和 value 可以为 null 么
答案
HashMap 都可以 HashTable key value 都不可以多线程和并发库
在 java 程序中怎么保证多线程的运行安全?
如何开启多线程
答案
继承Thread继承 Runable
继承 Callable
线程状态
答案
什么是 ThreadLocal
答案
是为了维护当前线程变量不被其他线程影响的结构,还是存储在自己的线程,以当前线程为key,一个threadlocal只能保存一个变量。synchronized 和 volatile 关键字的作用
答案
volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;只能修饰变量,不保证原子性。为什么要用线程池及线程池的启动策略???
答案
降低资源消耗(避免重复创建和销毁)提高响应速度(需要的时候直接去拿)
提高线程的可管理性(规定线程数量等)
线程池的启动策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(10,
20,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
线程池创建
1、当线程数小于 corePoolSize
时,创建线程执行任务。
2、当线程数大于等于 corePoolSize
并且 workQueue
没有满时,放入 workQueue
中
3、线程数大于等于 corePoolSize
并且当 workQueue
满时,新任务新建线程运行,线程总数要小于 maximumPoolSize
4、当线程总数等于 maximumPoolSize
并且 workQueue
满了的时候执行 handler
的 rejectedExecution
。也就是拒绝策略。
如何控制某个方法允许并发访问线程的个数
答案
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
static Semaphore semaphore = new Semaphore(5, true);
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
ceshi();
}
}).start();
}
}
public static void ceshi() {
try {
/**
* 申请一个请求
*/
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"进来了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "出去了");
/**
* 释放一个请求
*/
semaphore.release();
}
}
谈谈你对死锁的理解
答案
什么是死锁: 多个线程竞争资源而造成无限等待的情况。产生死锁的条件?
互斥:一个资源同一个时间只能为一个线程使用。
不剥夺:未使用完不能被剥夺。
请求和保持:请求资源,但是不释放自己的 资源。
会形成一个资源等待链。
如何避免?
加锁顺序
加锁时限
答案
说一下 runnable 和 callable 有什么区别?
答案
runnable 没有返回值,不能抛出异常
callable 靠 futuretask(实现 runable)来实现。可以有返回值和异常。
JavaSE 高级
反射
答案
根据类的字节码来实例并初始化对象、执行方法。如何获取类的字节码:
类名.class
类.getClass
Class.forName("")
动态代理
答案
JVM 内存模型
JVM 内存分配
答案
堆:存放引用对象;
方法区:存放类的字节码文件、常量池、字节码对象;
栈:存储基本类型的变量、对象名和对应的堆地址、及时调用的方法开辟的空间。
垃圾回收机制
答案
GC 机制:
主要处理堆内存;
1、判断是不是垃圾:
引用计数器算法
根搜索算法 (gc root:栈中引用的对象,方法区中的静态变量和常量,本地 native 中引用的对象)
2、怎么处理垃圾:
新生代-edon:标记清除
新生代-survivor:复制算法
老年代:标记整理算法
jvm 如何优化
答案
先监视是程序问题还是配置问题。
1、程序问题
先看日志,是否有错误提示
是否有死循环
大量递归
数据库查询数据
集合中是否有大量不用的对象。
java 类加载器有哪些
答案
- 系统提供的:
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类 - 自定义加载器(必须继承 ClassLoader)
类加载机制--双亲委托
答案
子类加载器,先看是否加载过,没有则让父级去加载;
父级是否加载过,加载直接返回 class,没有继续往上,直到引导类加载器。
只有父类找不到的时候,才会从自己的目录寻找并加载。
类什么时候初始化,初始化顺序?
答案
什么时候初始化?
new 一个对象;
静态方法被调用;
静态域被赋值和调用;
初始化子类,父类会被初始化;
反射;
程序启动时,作为程序入口包含 main 方法的类。
初始化顺序?
如果父类没有被加载和初始化,先加载父类。
静态属性:static 开头定义的属性
静态方法块: static {} 圈起来的方法块
普通属性: 未带 static 定义的属性
普通方法块: {} 圈起来的方法块
构造函数: 类名相同的方法
方法: 普通方法
既然有 GC 机制,为什么还会有内存泄露的情况
答案
存在无用但可达的对象。在开发中遇到过内存溢出么?原因有哪些?解决方法有哪些?
答案
有。
原因:
一次加载太多数据;
程序循环、迭代太多产生太多对象;
启动参数设置太小。
监听程序,查看内存消耗状态。
加大内存查看是内存原因还是程序原因。
如果是程序,查看错误日志或者是否有死循环等。
重点:
数据库查询是否数据量过大。
检查代码中是否有死循环或递归调用;
检查是否有大循环重复产生新对象实体
如果集合存有大量数据,使用完后要及时清除。
BIO、NIO、AIO 有什么区别?
答案
BIO (Blocking I/O):同步阻塞 I/O 模式
NIO (NoneBlock I/O):非阻塞模式
AIO ( Asynchronous I/O):异步非阻塞 I/O 模型
netty 处理 socket 的工具。
RPC, Remote Procedure Call 即远程过程调用,比如 dubbo
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于