找不到工作的面试者总结
提示:写文章的时候,我还在找工作!!!
文章目录
- 找不到工作的面试者总结
- 前言
- 一、JAVA面死题
-
- [1. OOP是什么](#1. OOP是什么)
- [2. 重载与重写的区别](#2. 重载与重写的区别)
- [3. java基本类型](#3. java基本类型)
- [4. String、StringBuffer、StringBuilder的区别](#4. String、StringBuffer、StringBuilder的区别)
- [5. 接口和抽象类区别](#5. 接口和抽象类区别)
- [6. 什么是自动拆装箱 int 和 Integer 有什么区别](#6. 什么是自动拆装箱 int 和 Integer 有什么区别)
- [7. ==和 equals 区别](#7. ==和 equals 区别)
- [8. final 、 finally 、 finalize](#8. final 、 finally 、 finalize)
- 9.object有哪些方法?
- [10. 集合有哪些?](#10. 集合有哪些?)
- [11. ArrarList 和 LinkedList 区别](#11. ArrarList 和 LinkedList 区别)
- [12. HashMap底层,为什么要这样用?](#12. HashMap底层,为什么要这样用?)
- [13. HashMap 和 HashTable 区别](#13. HashMap 和 HashTable 区别)
- [14. 线程的创建方式](#14. 线程的创建方式)
- [15. 请写出你最常见的 5 个 RuntimeException](#15. 请写出你最常见的 5 个 RuntimeException)
- [16. java的反射你是如果理解的](#16. java的反射你是如果理解的)
- [17. 什么是 java 序列化, 如何实现 java 序列化](#17. 什么是 java 序列化, 如何实现 java 序列化)
- [18. java中锁](#18. java中锁)
- [19. sleep 和 wait 区别](#19. sleep 和 wait 区别)
- [20. jvm分哪几个区?](#20. jvm分哪几个区?)
- [21. java垃圾回收机制有哪些?](#21. java垃圾回收机制有哪些?)
- [22. 如何判断一个对象是否存活?](#22. 如何判断一个对象是否存活?)
- [23. 什么是线程池,线程池有哪些?](#23. 什么是线程池,线程池有哪些?)
- [24. java单列模式懒汉式和饿汉式了解吗?](#24. java单列模式懒汉式和饿汉式了解吗?)
- 二、Mysql面死题
-
- [1. mysql事务你了解吧,和我说说](#1. mysql事务你了解吧,和我说说)
- [2. mysql隔离级别](#2. mysql隔离级别)
- [3. 事务并发问题](#3. 事务并发问题)
- [4. mysql的引擎](#4. mysql的引擎)
- [5. MySQL 几种索引](#5. MySQL 几种索引)
- [6. mysql的悲观锁和乐观锁如何实现?](#6. mysql的悲观锁和乐观锁如何实现?)
- [7. 什么时候索引会失效?](#7. 什么时候索引会失效?)
前言
提示:学了这些也找不到工作,计算机真的崩了,如果看到这篇文章,别干java,别干大数据,肺腑之言。
一、JAVA面死题
1. OOP是什么
OOP(Object Oriented Programming)即面向对象编程,面向对象的三大特征:封装、继承、多态
2. 重载与重写的区别
方法的重载是编译时多态 ,方法的重写是运行时多态
重载:重载发生在一个类中,同名的方法,不同的参数类型或者不同的参数个数
重写:重写发送在子类和父类之间,要求子类的重写方法和父类的被重写方法的方法名字、方法参数个数、方法类型、返回类型相同,访问权限不能比父类的低。
3. java基本类型
java基本类型八个,六种数字类型(四个整数型,两个浮点型),一种字符串型,还有一种布尔型 。
byte、short、int、long、float、double、boolean、char
注意:string是引用类型
4. String、StringBuffer、StringBuilder的区别
String:字符串由final修饰 的常量,存在常量池 中,所以他是线程安全的。
StringBuffer:它使用了synchronize 关键字,对方法进行了同步处理,所以线程是安全的。
StringBuilder:执行效率虽然高,但是因为线程不安全,所以不建议在多线程的环境下对同一个StringBuilder对象进行操作
5. 接口和抽象类区别
抽象类(abstract):接口需要子类继承、单继承、可以有构造方法,访问修饰符可以有public,protected和default、可以有成员变量。
接口(interface):需要子类实现接口、多实现、不能有构造方法,访问修饰符只能是public、只能有常量
6. 什么是自动拆装箱 int 和 Integer 有什么区别
底层是通过 Integer.valueOf()和 Integer.intValue() 方法实现 。 Integer 的默认值是
null, int 的默认值是 0
所以在[-128,127]区间内,==比较的时候,值总是相等的(指向的是同一对象),在这个区间外是不等的,
7. ==和 equals 区别
== :如果比较的是基本数据类型, 那么比较的是变量的值 如果比较的是引用数据类型, 那么比较的是地址值 (两个对象是否指向同一块内 存)
equals :如果没重写equals方法比较的是两个对象的地址值如果重写了比较的是内容,equals是从object类中继承的,默认实现方法是双等
8. final 、 finally 、 finalize
final修饰符(关键字 ):被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,即不能方法重写。
finally 是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。
finalize是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的
9.object有哪些方法?
protected Object clone()--->创建并返回此对象的一个副本 。
boolean equals(Object obj)--->指示某个其他对象是否与此对象"相等
protected void finalize()--->当垃圾回收器确定不存在对该对象的更多引用时, 由 对象的垃圾回收器调用此方法 。
Class<?extendsObject> getClass()--->返回一个对象的运行时类。
int hashCode()--->返回该对象的哈希码值 。 void notify()--->唤醒在此对象监视器上等待的单个线程。
void notifyAll()--->唤醒在此对象监视器上等待的所有线程。 String toString()--->返回该对象的字符串表示
10. 集合有哪些?
11. ArrarList 和 LinkedList 区别
ArrayList 是实现了基于动态数组的数据结构, LinkedList 基于链表的数据结构
对于随机访问 get 和 set, ArrayList 效率优于 LinkedList, 因为 LinkedList 要移 动指针 。
对于新增和删除操作 add 和 remove, LinkedList 比较占优势, 因为 ArrayList 要 移动数据 。 这一点要看实际情况的。若只对单条数据插入或删除, ArrayList 的速 度反而优于 LinkedList 。但若是批量随机的插入删除数据, LinkedList 的速度大大 优于 ArrayList. 因为 ArrayList 每插入一条数据, 要移动插入点及之后的所有数 据 。
12. HashMap底层,为什么要这样用?
HashMap 底层是 数组+链表+红黑树 数组 Node<K,V>[] table ,哈希表, 根据对象的 key 的hash 值判断在数组里面是哪个节点
链表的作用是解决 hash 冲突, 将 hash 值取模之后的对象存在一个链表放在 hash值对应的槽位
红黑树 JDK8 使用红黑树来替代超过 8 个节点的链表,发送哈希碰撞,会带来链化,效率会变低,引入红黑树会提高查找效率从原来的 O(n)到 O(logn)
当链表长度大于8,且总数据量大于64的时候,链表就会转化成红黑树,
当前存入数据大于阈值即发生扩容或者存入数据到某一条链表时,此时该链表数据个数大于8,且数组总数量小于64即发生扩容每次扩容为初始容量的2倍
13. HashMap 和 HashTable 区别
HashTable 是线程安全的,而 HashMap 不是。
HashMap 的性能要比 HashTable 更好,因为HashTable 采用了全局同步Synchronized来保证安全性,对性能影响较大
HashMap 只有 containsValue 和 containsKey 方法; HashTable 有 contains 、 containsKey 和 containsValue 三个方法, 其中 contains 和 containsValue 方法功 能相同 。
Hashtable 中, key 和 value 都不允许出现 null 值 。HashMap 中, null 可以作为 键, 这样的键只有一个; 可以有一个或多个键所对应的值为 null。
HashTable 在不指定容量的情况下的默认容量为 11, 而 HashMap 为 16 , Hashtable 不要求底层数组的容量一定要为 2 的整数次幂, 而 HashMap 则要求一 定为 2 的整数次幂。
Hashtable 扩容时, 将容量变为原来的 2 倍加 1, 而 HashMap 扩容时, 将容量变 为原来的 2 倍 。
14. 线程的创建方式
线程的5种状态: 新建状态、就绪状态、运行状态、阻塞状态、死亡状态
1、继承 Thread 类创建线程
2、实现 Runnable 接口创建线程
3、实现callable接口和创建Future类创建线程,有返回值
4、使用线程池创建线程
5、使用匿名线程创建
15. 请写出你最常见的 5 个 RuntimeException
java.lang.NullPointerException 空指针异常; 出现原因: 调用了未经初始化的对象或者是不存在的对象 。
java.lang.ClassNotFoundException 指定的类找不到; 出现原因: 类的名称和路径加载错误; 通常都是程序试图通过 字符串来加载某个类时可能引发异常 。
java.lang.NumberFormatException 字符串转换为数字异常; 出现原因: 字符型数据中包含非数字型字符 。
java.lang.IndexOutOfBoundsException 数组角标越界异常, 常见于操作数组对象时发生 。
java.lang.IllegalArgumentException 方法传递参数错误
java.lang.ClassCastException 数据类型转换异常。
16. java的反射你是如果理解的
在运行状态下,任何一个类,你都能知道它的所有方法和属性,对任何一个对象,你都能调用它的方法和属性,这种动态调用和获取的方法叫做反射机制
获取Class对象的三种方式
1 Object ------> getClass();
2 任何数据类型(包括基本数据类型)都有一个"静态"的class属性
3 通过Class类的静态方法:forName(String className)(常用)
17. 什么是 java 序列化, 如何实现 java 序列化
序列化是一种用来处理对象流的机制, 所谓对象流也就是将对象的内容进行流 化 。可以对流化后的对象进行读写操作, 也可将流化后的对象传输于网络之间
序列化的实现: 将需要被序列化的类实现 Serializable 接 口, 该接口没有 需 要 实 现 的 方 法, implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如: FileOutputStream)来构造一个 ObjectOutputStream(对象流) 对象, 接着, 使用 ObjectOutputStream 对象的 writeObject(Object obj)方法就可以将 参数为 obj 的对象写出(即保存其状态), 要恢复的话则用输入流。
18. java中锁
乐观锁 :采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作
悲观锁 :每次去拿数据的时候都认为别人会修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会 block 直到拿到锁
自旋锁 :线程不需要进入阻塞状态,直接在自旋,等待锁释放直接获取,减少线程切换的消耗,但自旋消耗cpu。
非公平锁 :JVM 随机就近原则分配锁的机制则称为不公平锁,非公平锁实际执行的效率要远超公平锁,除非程序有特殊需要,否则最常用非公平锁的分配机制。
公平锁 :公平锁指的是锁的分配机制是公平的,通常先对锁提出获取请求的线程会先被分配到锁加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
同步锁 : 当多个线程同时访问同一个数据时,很容易出现问题。为了避免这种情况出现,我们要保证线程同步互斥,就是指并发执行的多个线程。在同一时间内只允许一个线程访问共享数据
死锁 :就是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。
锁优化通常可以:减小锁粒度比如分段锁,实现锁分离,让读写分离,实现锁粗化让锁的时间尽量短Synchronized,它就是一个:非公平,悲观,独享,互斥,可重入的重量级锁
ReentrantLock,它是一个:默认非公平但可实现公平的,悲观,独享,互斥,可重入,重量级锁。
ReentrantReadWriteLocK,它是一个,默认非公平但可实现公平的,悲观,写独享,读共享,读写,可重入,重量级锁。
19. sleep 和 wait 区别
sleep :不释放锁资源
wait:释放锁资源,一值等待需要notify唤醒,必须配合 synchronized 一起使用, 不然在运行时就会抛出 IllegalMonitorStateException 异常
20. jvm分哪几个区?
1、方法区(永久代):存储类的信息、常量、静态变量等,被线程共享
2、虚拟机栈(java栈):存储局部变量和引用、运算结果和运算操作数、动态链接(将常量池中的符号引用在运行期转化为直接引用)、方法出口等信息,不被线程共享
3、本地方法栈:本地方法栈和虚拟机栈类似, 只不过本地方法栈为 Native 方法服务 。
4、堆:java 堆是所有线程所共享的一块内存, 在虚拟机启动时创建, 几乎所有的对象实例 都在这里创建, 因此该区域经常发生垃圾回收操作 。
5、程序计数器:内存空间小, 字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的字节码指令, 分支 、循环 、跳转 、异常处理和线程恢复等功能都需要依赖这个计数 器完成 。该内存区域是唯一一个 java虚拟机规范没有规定任何 OOM 情况的区域 。
21. java垃圾回收机制有哪些?
采用分区分代回收思想:
1、复制算法 :年轻代中使用的是 Minor GC, 这种 GC 算法采用的是复制算法 (Copying),效率高,内存占用大,使用在占空间比较小 、刷新次数多的新生区
2、标记清除法 :老年代一般是由标记清除或者是标记清除与标记整理的混合实现,效率比较低, 会差生碎片。
3、标记整理法:效率低速度慢,需要移动对象,但不会产生碎片 。
22. 如何判断一个对象是否存活?
1、引用计数法 :每个对象设置一个计数器,每当有一个对象引用+1,失效后-1,为0时没有引用被回收,无法解决循环依赖问题。
2、可达性算法(引用链法):提供gcroots的对象作为起点,向下搜索,当一个对象到gcroots没有任何引用时,证明不可达,回收掉
23. 什么是线程池,线程池有哪些?
线程池是事先将线程放在同一个容器中,当使用的时候不用new线程,而是去线程池中拿线程,节省了线程开销,提供了代码效率。
1、newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要, 可灵活回收空闲线程, 若无可回收, 则新建线程。
ExecutorServicenewCachedThreadPool=Executors.newCachedThreadPool();2、newFixedThreadPool 创建一个指定工作线程数量的线程池 。每当提交一个任务就创建一个工作线程, 如果工作线程数量达到线程池初始的最大数, 则将提交的任务存入到池队列中 。
ExecutorServicenewFixedThreadPool=Executors.newFixedThreadPool(4);3、newSingleThreadExecutor 创建一个单线程化的 Executor, 即只创建唯一的工作者线程来执行任务, 它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序。
ExecutorServicenewSingleThreadExecutor=Executors.newSingleThreadExecutor();4、newScheduleThreadPool 创建一个定长的线程池, 而且支持定时的以及周期性的任务执行 。例如延迟 3 秒 执行。
ScheduledExecutorService newScheduledThreadPool =Executors.newScheduledThreadPool(4);
24. java单列模式懒汉式和饿汉式了解吗?
饿汉式:是立即加载的方式,无论是否会用到这个对象,都会加载。
java
public class GiantDragon {
//私有化构造方法使得该类无法在外部通过new 进行实例化
private GiantDragon(){
System.out.println("私有化构造方法");
}
//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
private static GiantDragon instance = new GiantDragon();
//public static 方法,提供给调用者获取12行定义的对象
public static GiantDragon getInstance(){
return instance;
}
}
懒汉式:是延迟加载的方式,只有使用的时候才会加载。并且有线程安全的考量。用双端检测其实是因为每次访问只有在第一次访问的时候才要加锁,其他时间直接判断是不是null就返回。
java
public class GiantDragon2 {
//GiantDragon2 进行实例化
private GiantDragon2(){
System.out.println("私有化构造方法");
}
//准备一个类属性,用于指向一个实例化对象,但是暂时指向null
private static GiantDragon2 instance;
//public static 方法,返回实例对象 (非线程安全的,不推荐使用该写法)
public static GiantDragon2 getInstance(){
//第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
if(null==instance){
instance = new GiantDragon2();
}
//返回 instance指向的对象
return instance;
}
// 线程安全的,并且通过非空判断提升性能(因为如果只上锁,那么每次调用的时候都会上锁,事实上只有第一次创建对象的时候才需要加锁)
public static GiantDragon2 getInstance(){
if(instance == null){
synchronized(instance){
//第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
if(null==instance){
instance = new GiantDragon2();
}
}
}
//返回 instance指向的对象
return instance;
}
//以上线程安全的写法在java单例设计模式中并非完美的写法,因为在JVM执行过程中可能会存在问题,感兴趣的小伙伴可以去找一下相关的资料。
}
二、Mysql面死题
1. mysql事务你了解吧,和我说说
原子性 (Atomicity):事务过程中,如果其中操作出现错误,所有操作全部回滚,要么全嘎要么全做。
一致性 (Consistency):事务开始和结束,事务完整约束没有被破坏。比如 A 向 B 转账, 不可能 A 扣了钱, B 却没收到
隔离性 (Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有干扰,比如 A 正在从一张银行卡中取钱, 在A 取钱的过程结束前, B 不能向这张卡转账。
持久性(Durability):事务完成后,数据保存好,无法回滚。
2. mysql隔离级别
3. 事务并发问题
脏读 :事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到数据的脏数据。
不可重复读 :事务A多次读同一数据,事务B在多次读取中修改了数据,事务A就出现了结果不一样。
幻读:事务A修改多个数据时,事务B插入了一条新的数据,此事出现了一条数据没有改过来,出现了幻读。
注意:不可重复读的和幻读很容易混淆, 不可重复读侧重于修改, 幻读侧重于新增或删除 。解决不可重复读的问题只需锁住满足条件的行, 解决幻读需要锁表。
4. mysql的引擎
5. MySQL 几种索引
1、普通索引 :最基本的索引,没有任何限制
创建sql create index index_name on table(column(length))
2、唯一索引 :索引列值必须唯一,允许null
创建sql create unique index indexName on table(column(length))
3、主键索引 :是一种特殊的唯一索引,一个表只能有一个主键,不允许空值,在创建的时候一般会同时创建
创建sql 创建表时加上primary key (id)
4、组合索引 :在多个字段上创建索引,只有在查询条件中使用创建索引时的第一个字段,索引才会被使用
创建sql alter table table_name add index name_city_age (name,city,age);
5、全文索引 :主要用来查找文本中的关键字,而不是直接与索引中的值相比较
创建sql create fulltext index index_content ON article(content)
6. mysql的悲观锁和乐观锁如何实现?
悲观锁 :使用 select...for update 锁数据,需要注意锁的级别,MySQL InnoDB 默认行级锁。行级锁都是基于索引的,如果一条 SQL 语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住,这点需要注意。
乐观锁:在更新之前,先查询一下库存表中当前库存数(quantity),然后在做 update 的时候,以库存数作为一个修改条件。当提交更新的时候,判断数据库表对应记录的当前库存数与第一次取出来的库存数进行比对,如果数据库表当前库存数与第一次取出来的库存数相等,则予以更新,否则认为是过期数据。
7. 什么时候索引会失效?
1、字符串不匹配导致索引失效
where 条件字段类型与实际表中字段类型不匹配的时候,Mysql会进行隐式的数据类型转换,而类型转换会使用到内置函数,导致在进行数据查询的时候并没有使用索引
2、被索引字段使用了表达式计算
在where 中条件使用了条件表达式的时候,数据表中的索引就失效了,实际是因为 Mysql需要将索引字段取出来之后再进行表达式的条件判断,因而进行了全表扫描,导致索引失效。
3、被索引字段使用了内置函数
索引保存的是索引列的原始值,如果经过函数计算,Mysql的解释器无法判断计算后的索引在原来的索引树上是否可以被索引到,因此它就直接放弃使用索引查询了。
4、like 使用了 %X 模糊匹配
使用左模糊匹配以及左右模糊匹配都会导致索引失效,但是使用右模糊匹配,还是可以走索引查询的。由于B+树按照索引值进行排序的,实际是按照最左前缀进行比较,而使用了 %作为最左前缀,Mysql 无法判断其有序性,因此只能进行全表扫描查询。
5、索引字段不是联合索引字段的最左字段
如果数据库表中有联合索引的话,我们在 SQL查询语句中使用的索引字段又不是联合索引的最左字段,那么就会导致索引失效。实际上在 Mysql 中的索引检索是遵循最左匹配原则的,同时B+索引树的叶子节点的有序性也是建立在最左匹配原则之上
6、or 分割的条件,如果 or左边的条件存在索引,而右边的条件没有索引,不走索引
因为 OR的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。
7、in、not in 可能会导致索引失效
这里需要说明的是使用 in 以及 not in 走不走索引,实际和 Mysql的版本以及表中的数据量有关系,在 8.0 之后的版本是走索引的。