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
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于