面试题总结
JAVA基础
1,arraylist和linkedlist区别
一个底层实线是数组,一个是链表
数组是连续性的,所以读很快,但是如果写的话,就涉及到扩容,复制再写,就会比较慢
链表是随机的,读比较慢,但是写因为不用扩容,所以很快
2,String,Stringbuffer,StringBuilder 的区别
string是常量,定死的,不能更改的
stringbuffer是多线程环境下的string相加
stringbuilder是单线程环境下的string相加
3,hashmap和concurrenthashmap
hashmap
数组组成,每个数组里面都是一个链表的头数据,在JAVA8里,是往链表的后面加数据的,JAVA8之前是往头上加
然后如果链表大于等于7了,就改成红黑树(如果hashmap小于64就扩容,else红黑树)
如果数组本身满了,比如设置8,大于6个数据了,就会进行扩容
默认容量8,负载因子0.75,表示到达8/0.75的时候就进行扩容(size+1大于负载因子就扩容)
hash冲突,往链表上加数据
一个是线程不安全,因为容易出现死锁
死锁
在扩容达到64,128这种数字的时候,出现两个数同时添加,就会导致同时调用两次resize方法,
然后线程1把element a放到了新的table节点的头部,形成新table a打头,旧table是null 打头,b跟着的一个情况
然后线程2进来,第0个数据是空,就去找第一个数据b,拿到b作为当前数据,然后暂停
这时候t1把b设置进去,形成b指向a的链路
然后t2继续,获得b。next,本来应该是null,现在变成a了,然后b设置到newtable的头节点,再把b。next 的a设置到头节点前面,形成死循环
concurrenthashmap
一个通过分段锁来实现线程安全,性能上其实和hashmap差不太多
通过hashcode来决定放入哪个分段里
数据库知识
1. 数据库隔离级别有哪些,各自的含义是什么,MYSQL 默认的隔离级别是是什么。
READ UNCIMMITTED(未提交读)
读不加锁,写加锁,只能被一个事务写,存在脏读
写的时候加的是行级共享锁(其他事务可以读到数据)
读会有不可重复读的问题,写会有脏读的问题
READ COMMITTED(提交读)
读不加锁,写加锁,只能被一个事务写,解决脏读,存在不可重复读问题,因为读数据的时候不阻止其他事务写,所以多次读可能出现不一致
写的时候加的是行级拍他锁(其他事务不可以读到脏数据,只能读到之前版本的数据)解决脏读
读一半被其他事务把数据更新了,出现不可重复读的问题
然后写的话是安全的,其他事务不会读到我的数据
REPEATABLE READ(可重复读)
解决了脏读和不可重复读,因为读事务会阻止其他写事务,所以读的东西就不出错。保证每行的记录结果是一致的,其他事务可读不可写
但是会出现幻读,因为只能阻止update和delete,如果是insert是没办法锁上的,就会读到别的事务中途插入的数据
解决脏读和不可重复读,存在幻读(新插入数据不能阻止),但是一旦我开始读数据,其他事务都不能修改它
SERIALIZABLE(可串行化)
强制事务串行执行,锁表,添加表级共享锁和表级排他锁
只能读并且,读写和谐写都要串行化执行
幻读:读到别人新插入的,不应该存在的数据
脏读:别人事务中更新的数据,事务还没结束
2. MYSQL 有哪些存储引擎,各自优缺点。
只知道InnoDB是可以有事务的,然后比起MyISAM写效率会慢一点,以及占用更多空间
MyISAM不支持事务,但是访问速度快。
3. 乐观锁和悲观锁是什么
乐观锁,默认数据是不会被修改的,通过版本号来做锁,吞吐量高
悲观锁,默认数据会被修改,通过事务或者redis锁来锁数据,然后再操作
4. SQL 优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义。
呃。。用explain
5. 数据库会死锁吗,举一个死锁的例子,mysql 怎么解决死锁。
会死锁,如果我有一个事务更新数据123,另一个更新数据321,那1和3就分别被人拿了,然后就互相形成了死锁,然后就会有个最长等待时间,我记得是150秒,就会释放
6. MYsql 的索引
B-tree索引,平衡树,然后把id和对应的物理地址存上去,如果是自己创建的索引,就会存对应的索引数据和物理地址
覆盖索引:说白了就是索引里的值足够覆盖查询内容了
聚簇索引,首先一个表只能有一个聚簇索引,数据的索引逻辑顺序和数据存储的物理地址顺序是一致的
就是它的索引和数据,或者说数据页是在一起的
然后一般是用主键做聚簇,因为如果聚簇字段不是递增的,可能在后面去往前面某个页上插入新数据,就会把原来的页挤满,然后就会造成页面分裂,那效率就低了。
非聚簇索引,就是物理顺序和逻辑顺序不一致
7. select for update 是什么含义,会锁表还是锁行或是其他。
锁表后再更新,如果select的时候指定了主键,就是锁行
8. 数据库的 ACID 是什么。
原子性(Atomicity)
要么全部执行成功,要么全部失败
一致性(Consistency)
数据一致性,更新前更新后,没有数据丢失
隔离性(Isolation)
事务之间互相不干扰,隔离开执行的
持久性(Durability)
事务成功以后,数据是持久化保存的
9. 某个表有近千万数据,CRUD 比较慢,如何优化。
1,分库分表
2,对历史数据单独存放
3,优化索引
4,优化查询语句
10. 如何写 sql 能够有效的使用到复合索引。
首先是最左匹配原则,保证查询条件里,有符合索引最左的那一栏,如果是涉及了order by语句,最好是保证order by后面的那栏是最左栏
然后就是尽量用多的索引栏了
还有就是比如在创建复合索引的时候,尽量把分类少的数据放前面,比如那种含有枚举类型的数据,总共就2-3种可能性的数据,放在索引靠前的位置
11. mysql 中 in 和 exists 区别。
exists 就是逐条取出所有数据,做一次判断exists里面的内容判断
每次都要循环执行exists里的内容,exists返回的是boolean值
in 相当于多个or条件叠加
in里面的内容只执行一次,拿到结果集,去外圈做or查询
12. 数据库自增主键可能的问题。
对分库分表的时候不方便,可能主键重复之类的,
一般做法是,要么设置库表之间1357,2468的增长,缺点是不利于扩展
还有一种做法是,去一台统一的服务器/数据库上,一次性取大量的id来先用着
还有一种根据自身的服务器ip,加上去数据库请求到的唯一id,加一些自增长id来做唯一id。
13. MVCC 的含义,如何实现的。
多版本的并发控制协议
顾名思义,有多个版本的并发控制方式
读的时候,会读到一个一致性版本的快照
写的时候,每个事物写的是自己的版本,一条数据有多个版本号,提交事物的时候,覆盖原有的版本,如果已经被人覆盖了,那就提交失败呗
版本号可以是时间戳或者是全局递增的事务id
这样就保证同一时间点,每个事务看见的数据,都是自己版本的