回复“000”获取程序员必备电子书 大家好,我是老田,上周,一位群里的朋友去平安保险面试了,结果有些遗憾,蛮可惜的,但希望你不要气馁,正如你所说的,面试中遇到的问题,基本上都是可以通过背面试题解决的,所以请加油! 另外,有问题欢迎随时找我探讨,共同进步。 不扯远了,咱们进入主题,下面是这位同学整理的技术面试题和参考答案。 Java中有哪些线程安全的类?
另外,还有JUC包下所有的集合类
Java创建对象有几种方式?
Object 有哪些常用方法?
java.lang.Object 下面是对应方法的含义。 clone 方法 保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常,深拷贝也需要实现 Cloneable,同时其成员变量为引用类型的也需要实现 Cloneable,然后重写 clone 方法。 finalize 方法 该方法和垃圾收集器有关系,判断一个对象是否可以被回收的最后一步就是判断是否重写了此方法。 equals 方法 该方法使用频率非常高。一般 equals 和 == 是不一样的,但是在 Object 中两者是一样的。子类一般都要重写这个方法。 hashCode 方法 该方法用于哈希查找,重写了 equals 方法一般都要重写 hashCode 方法,这个方法在一些具有哈希功能的 Collection 中用到。 一般必须满足
wait 方法 配合 synchronized 使用,wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait() 方法一直等待,直到获得锁或者被中断。wait(long timeout) 设定一个超时间隔,如果在规定时间内没有获得锁就返回。 调用该方法后当前线程进入睡眠状态,直到以下事件发生。
此时该线程就可以被调度了,如果是被中断的话就抛出一个 InterruptedException 异常。 notify 方法 配合 synchronized 使用,该方法唤醒在该对象上等待队列中的某个线程(同步队列中的线程是给抢占 CPU 的线程,等待队列中的线程指的是等待唤醒的线程)。 notifyAll 方法 配合 synchronized 使用,该方法唤醒在该对象上等待队列中的所有线程。 hashCode方法和equals方法有什么关系
如果a.equals(b)返回“true”,那么a和b的 如果a.equals(b)返回“false”,那么a和b的 hashcode的作用
于是有人发明了哈希算法来提高集合中查找元素的效率。这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。
说说Spring Boot的自动装配原理
在Spring Boot中有个很关键的注解 - - - 其中 数据库事务的隔离级别有哪些?
数据库事务的隔离级别有4种,由低到高分别为
说说你对MySQL中索引的理解
索引是一种数据结构,使得Mysql能够高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 优点
缺点
熟悉哪些SQL优化方法?
1、查询语句中不要使用select * 2、尽量减少子查询,使用关联查询(left join,right join,inner join)替代 3、减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代 4、or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,union all会更好) 5、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 6、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0 在 MySQL 中一条查询 SQL 是如何执行的?
比如下面这条SQL语句(面试官现场给的 select 字段1,字段2 from 表 where id=996
JVM中堆与栈有什么区别?
二者本质区别:栈是线程私有,而堆是线程共享的。 栈是运行时单位,代表着逻辑,一个栈对应着一个线程,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片; 堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片。 1)、功能不同 栈内存用来存储局部变量和方法调用,而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。 2)、共享性不同 栈内存是线程私有的。堆内存是所有线程共有的。 3)、异常错误不同 如果栈内存或者堆内存不足都会抛出异常。 栈空间不足:java.lang.StackOverFlowError。 堆空间不足:java.lang.OutOfMemoryError。 4)、空间大小 栈的空间大小远远小于堆的。 熟悉类加载机制吗?
JVM类加载分为5个过程:加载,验证,准备,解析,初始化,使用,卸载,如下图所示: 下面来看看加载,验证,准备,解析,初始化这5个过程的具体动作。 加载 加载主要是将.class文件(并不一定是.class。可以是ZIP包,网络中获取)中的二进制字节流读入到JVM中。在加载阶段,JVM需要完成3件事:1)通过类的全限定名获取该类的二进制字节流;2)将字节流所代表的静态存储结构转化为方法区的运行时数据结构;3)在内存中生成一个该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。 连接 验证 验证是连接阶段的第一步,主要确保加载进来的字节流符合JVM规范。验证阶段会完成以下4个阶段的检验动作:1)文件格式验证 2)元数据验证(是否符合Java语言规范) 3)字节码验证(确定程序语义合法,符合逻辑) 4)符号引用验证(确保下一步的解析能正常执行) 准备 主要为静态变量在方法区分配内存,并设置默认初始值。 解析 是虚拟机将常量池内的符号引用替换为直接引用的过程。 初始化 初始化阶段是类加载过程的最后一步,主要是根据程序中的赋值语句主动为类变量赋值。注:1)当有父类且父类为初始化的时候,先去初始化父类;2)再进行子类初始化语句。 能够触发条件 Full GC 有哪些?
通常触发Full GC的场景有如下5种场景: (1)调用 (2)老年代空间不足 (3)方法去空间不足 (4)通过Minor GC后进入老年代的平均大小 > 老年代的可用内存 (5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。即老年代无法存放下新年代过度到老年代的对象的时候,会触发Full GC。 线上系统CPU飙高,怎么办?
常规操作是: 1. top oder by with P:1040 // 首先按进程负载排序找到 axLoad(pid) 2. top -Hp 进程PID:1073 // 找到相关负载 线程PID 3. printf “0x%x\n”线程PID:0x431 // 将线程PID转换为 16进制,为后面查找 jstack 日志做准备 4. jstack 进程PID | vim +/十六进制线程PID - // 例如:jstack 1040|vim +/0x431 - 推荐:面试官问:如何排除GC引起的CPU飙高?我脱口而出5个步骤 总结整个面试过程还是相对轻松的,面试官也还挺好的,只是怪自己没有准备好,作为一个工作两年的我,有些问题确实是没见过,但面试官问得问题貌似都可以实现准备好的(背面试题),也不是一定要亲身经历过。 也许这就是: 以上便是这位同学的本次面试总结,如果对我的知识星球感兴趣,点击下方图片进入知识星球内容介绍: |
|