随笔分类 - 精选面试题
摘要:查询语句执行流程 查询语句的执行流程如下:权限校验、查询缓存、分析器、优化器、权限校验、执行器、引擎。 举个例子,查询语句如下: select * from user where id > 1 and name = 'seven'; 首先,通过连接器,客户端与MySQL服务器建立连接,并完成身份认证
阅读全文
摘要:整数类型的 UNSIGNED 属性有什么用? MySQL 中的整数类型可以使用可选的 UNSIGNED 属性来表示不允许负值的无符号整数。使用 UNSIGNED 属性可以将正整数的上限提高一倍,因为它不需要存储负数值。 例如, TINYINT UNSIGNED 类型的取值范围是 0 ~ 255,而普
阅读全文
摘要:工作中常见的6种OOM问题 堆内存OOM 堆内存OOM是最常见的OOM了。 出现堆内存OOM问题的异常信息如下: java.lang.OutOfMemoryError: Java heap space 此OOM是由于JVM中heap的最大值,已经不能满足需求了。 举个例子: @Test public
阅读全文
摘要:垃圾回收算法有哪些? 垃圾回收算法有四种,分别是标记清除法、标记整理法、复制算法、分代收集算法。 标记清除算法:首先利用可达性去遍历内存,把存活对象和垃圾对象进行标记。标记结束后统一将所有标记的对象回收掉。这种垃圾回收算法效率较低,并且会产生大量不连续的空间碎片。 复制清除算法:半区复制,用于新生代
阅读全文
摘要:GC是什么?为什么要GC? GC( Garbage Collection ),垃圾回收,是Java与C++的主要区别之一。作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码。这是因为在Java虚拟机中,存在自动内存管理和垃圾清理机制。对JVM中的内存进行标记,并确定哪些内存需要回收,根据一
阅读全文
摘要:什么是类加载器,类加载器有哪些? 实现通过类的全限定名获取该类的二进制字节流的代码块叫做类加载器。 主要有一下四种类加载器: 启动类加载器:用来加载 Java 核心类库,无法被 Java 程序直接引用。 扩展类加载器:它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加
阅读全文
摘要:类加载指的是把类加载到 JVM 中。把二进制流存储到内存中,之后经过一番解析、处理转化成可用的 class 类 二进制流可以来源于 class 文件,或通过字节码工具生成的字节码或来自于网络。只要符合格式的二进制流,JVM 来者不拒。 虚拟机遇到⼀条 new 指令时,⾸先将去检查这个指令的参数是否能
阅读全文
摘要:JVM内存结构分为5大区域,程序计数器、虚拟机栈、本地方法栈、堆、方法区。 程序计数器是什么? 特点: 线程私有 CPU会为每个线程分配时间片,当当前线程的时间片使用完以后,CPU就会去执行另一个线程中的代码 程序计数器是每个线程所私有的,当另一个线程的时间片用完,又返回来执行当前线程的代码时,通过
阅读全文
摘要:什么是CAS? CAS全称Compare And Swap,比较与交换,是乐观锁的主要实现方式。CAS在不使用锁的情况下实现多线程之间的变量同步。ReentrantLock内部的AQS和原子类内部都使用了CAS。 CAS算法涉及到三个操作数: 需要读写的内存值V。 进行比较的值A。 要写入的新值B。
阅读全文
摘要:简要回答 execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。 execute在执行任务时,如果遇到异常会直接抛出,
阅读全文
摘要:简要回答 线程池是一种池化技术,用于预先创建并管理一组线程,避免频繁创建和销毁线程的开销,提高性能和响应速度 它几个关键的配置包括:核心线程数、最大线程数、空闲存活时间、工作队列、拒绝策略 主要工作原理如下: 当线程池里存活的线程数小于核心线程数corePoolSize时,这时对于一个新提交的任务,
阅读全文
摘要:回答重点 synchronized 实现原理依赖于JVM 的 Monitor(监视器锁)和对象头(Object Header) synchronized 修饰代码块:会在代码块的前后插入 monitorenter 和 monitorexit 指令。可以把 monitorenter理解为加锁,moni
阅读全文
摘要:多线程环境下,使用Hashmap进行put操作会造成数据覆盖,应该使用支持多线程的 ConcurrentHashMap。 HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进行put操作,调用了HashMap的putVal(),具体原因: 假设两个线程A、B都在进行put操作
阅读全文
摘要:假设有一个 1G 大的 HashMap,此时用户请求过来刚好触发它的扩容.那么当前用户请求会被阻塞,因为 HashMap的底层是基于数组+链表(红黑树)来实现的,一旦它发生扩容,就需要新增一个比之前大2倍的数组,然后将元素copy到新的数组上 那么如何优化呢? 简要回答 此时可以借鉴 Redis 的
阅读全文
摘要:简要回答 如果刚好触发扩容,那么当前用户请求会被阻塞,因为 HashMap的底层是基于数组+链表(红黑树)来实现的,一旦它发生扩容,就需要新增一个比之前大2倍的数组,然后将元素copy到新的数组上 而 1G 的 HashMap 够大,所以扩容需要一定的时间,而扩容使用的又是当前的线程,所以用户此时会
阅读全文
摘要:关于深拷贝和浅拷贝区别,先给结论: 浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。 深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。 clone
阅读全文
摘要:泛型的代码只存在于编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,称之为类型擦除。 无限制类型擦除:当在类的定义时没有进行任何限制,那么在类型擦除后将会被替换成Object,例如<T>、<?> 都会被替换成Object。 有限制类型擦除:当类定义中的参数类型存在上下限(上下界),那么在类型擦
阅读全文
摘要:简要回答 这个是针对set和map这类使用hash值的对象来说的 只重写equals方法,不重写hashCode方法: 有这样一个场景有两个Person对象,可是如果没有重写hashCode方法只重写了equals方法,equals方法认为如果两个对象的name相同则认为这两个对象相同。这对于equ
阅读全文
摘要:简要回答 缓存穿透(cache penetration)是用户访问的数据既不在缓存当中,也不在数据库中。出于容错的考虑,如果从底层数据库查询不到数据,则不写入缓存。这就导致每次请求都会到底层数据库进行查询,缓存也失去了意义。当高并发或有人利用不存在的Key频繁攻击时,数据库的压力骤增,甚至崩溃,这就
阅读全文
摘要:简要回答 因为存在精度丢失的风险 《阿里巴巴 Java 开发手册》中提到:“浮点数之间的等值判断,基本数据类型不能用 == 来比较,包装数据类型不能用 equals 来判断”。“为了避免精度丢失,可以使用 BigDecimal 来进行浮点数的运算”。 浮点数的运算竟然还会有精度丢失的风险吗?确实会!
阅读全文

浙公网安备 33010602011771号