千寻简刷八股文丨第一天

千寻简刷八股文

笔记介绍

大家好,这里是千寻简笔记,我是作者星辰,笔记内容整理并发布,内容有误请指出,笔记源码已开源,前往Gitee搜索《chihiro-notes》感谢您的观看。

作者各大平台直链: GitHub | Gitee | CSDN

笔记所有题目均来源于网络,仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。

网站目录格式有问题,建议下载原版阅读。

刷题

️第一天

1️⃣【JAVA基础】解释对象创建的过程?

  1. 申请堆内存(半初始化,变量赋值)
  2. 变量赋值。
  3. 建立引用关系。

注意区分对象创建问题与类加载过程问题!

2️⃣【JAVA基础】"=="和equals方法究竟有什么区别?

  1. ==:对基本类型和引用类型的作用效果是不同的

    • 对于基本数据类型来说,==比较的是指。
    • 对于引用数据类型来说,==比较的是对象的内存地址。

    因为只有Java只有值传递,所以对于==来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址

  2. equals():用来比较两个对象的内容是否相等。需要注意的是equals方法不能用于比较基本数据类型的变量。

    • 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的地址。
    • 很多类重写了equals方法,比如String、Integer等把它变成了值比较,所以一般情况下 equals比较的是值是否相等。

3️⃣【JAVA基础-集合】Java集合类框架的基本接口有哪些?

Java中的集合分为 value(Conllection),key-value(Map)两种存储结构。

  1. 存储 value又分为 ListSetQueue.
    • List:有序,可存储重复元素。
    • Set:无序,元素不可以重复。根据 equalshashcode判断(如果一个对象存储在 Set中,必须重写 equalshashcode方法)
    • Queue:队列
      千寻简刷八股文丨第一天_第1张图片
  2. 存储 key-value的为 map

千寻简刷八股文丨第一天_第2张图片

其他答案:

顶层接口有:collection

之后的子接口有List,Queue, Set;

还有一个单独的Map接口

List集合是有序可重复的,支持随即访问,List接口的实现类有LinkedList,ArrayList,Vector

LinkedList底层是双向链表,不支持随即访问,但是插入与删除效率较高,ArrayList支持随机访问,但是插入与删除效率较低

Vector是线程安全的,它在一些关键方法上加了synchronized

Set集合是无序不可重复的,不支持随机访问

Map的存储方式是通过键值对的方式存储值的,键是唯一的,不可重复,value值是可重复的

4️⃣【JAVA基础-集合】Collection和 Collections的区别?

  1. Collection:是最基本的集合接口,它提供了对集合对象进行基本操作的通用接口方法。一个 Collection代表一组Object,即Collection的元素。它的直接继承接口有ListSetQueue
  2. Conllections:是不属于Java的集合框架的,它是集合类的一个工具类。此类不能被实例化,服务于JavaCollection框架。它包含有关集合操作的静态多态方法,实现对各种集合的搜索、排序、线程安全等操作。

5️⃣【缓存】Redis集群有没有了解过,主从和选举是怎么样子的?

  1. 主从复制:读写分离,主库负责写,从库负责读,当主库宕机时,从库依然可以提供读的服务。
  2. 哨兵机制:是一个独立的进程,通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例,当主机宕机时,哨兵会通过投票,重新选举一个从库做为主库,是一种容灾机制。
  3. 高可用集群:去中心化,要求最少三个节点,每个节点时平等,高可用集群会预先设置16384个插槽,当存储一个key-value时,会通过算法计算出放在哪个插槽中。

6️⃣【缓存】Redis的缓存击穿及解决方案

提问:什么是缓存击穿

缓存击穿是指某一个热点数据缓存中没有但数据库中有数据(一般是缓存时间到期)。这时由于并发用户特别多,同时读缓存没读到数据,有同时去数据库去取数据,引起数据库压力瞬间增大的,造成过大压力。

追问:缓存击穿你会怎么解决?

  1. 预先设置热门数据:在Redis高峰访问之前,把一些热门数据提前存入Redis里面,加大这些热门数据的key时长。

  2. 实时调整:现场监控哪些数据热门,实时调整key的过期时长。

  3. 接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。

  4. 使用锁:

    • 在缓存失效的时候(判断拿出来的值为空),不是立即去load db
    • 先使用缓存工具的某些带成功操作返回值的操作(比如RedisSETNX)去set一个mutex key
    • 当操作返回成功时,再进行load db的操作,并回设缓存,最后删除mutex key
    • 当操作返回失败,证明有线程在load db,当前线程睡眠一段时间再重试mutex key
  5. 设置互斥锁:在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。(可以使用Redis分布式锁)

7️⃣【锁】乐观锁和悲观锁的解释及其应用场景

悲观锁:特点是总觉得正在操作的数据会被别人修改,所以自己在数据处理的过程中会将数据进行加锁。

悲观锁实现:在MySQL中使用悲观锁,需要将自动提交关闭。使用 SELECT XXX FROM XXX FOR UPDATE这样就对查询结果加上了悲观锁(如果查询条件走了索引,则锁定的仅为查询结果集;若查询条件未走索引,则对全表加锁)

乐观锁:特点是在对数据进行操作时不会对数据或表加锁,而是在提交时判断操作过程是否有第三方对数据进行了修改,如果发现冲突,则返回错误系信息。

乐观锁实现:

  1. 利用数据版本号 version机制是乐观锁常用的一种实现方式,一般是在数据库表中增加一列数据类型的 version字段,查询数据时,将 version字段读出,数据每更新一次就对version值+1。当提交更新时,判断数据库对应的version字段的当前值是否与第一次查询的值是否一致,若相等,则允许更新,否则认为数据过期,返回更新失败。
  2. 利用时间戳,类似于 version。在数据库中新增时间戳字段。提交前进行比较。

8️⃣【锁】什么是死锁(deadlock)?

死锁就是资源无法被释放,举个例子:线程A占有一号锁,正在请求二号锁,且线程B占有二号锁,正在请求一号锁,A、B线程互相等待对方释放锁,进入了无限等待的状态。

死锁有四个必要条件:

  1. 资源互斥:锁在同一时刻只能被一个线程使用。
  2. 不可剥夺:其他线程无法抢夺已经被占有的锁,只能等待占有者自行释放锁。
  3. 请求与保持:例如A线程的行为。
  4. 循环等待:例如A、B线程的互相等待。

如何避免死锁?破坏四个条件之一即可:

  1. 资源不互斥。
  2. 可剥夺。
  3. 同时请求,要么同时持有所有需要的资源,要么都不持有。
  4. 为资源编号,线程只能从小到大依次请求资源,不能请求一个更小编号的资源。

9️⃣【数据库】什么是索引?

提问:索引是什么?

索引是依靠某些数据结构和算法来组织数据,最终引导用户快速检索出所需要的数据。工作方式:利用b+树链表二分查找法,做到快速定位目标数据,快速范围查找。

索引有两个特点:

  1. 通过数据结构和算法来对原始的数据进行一些有效的组织。
  2. 通过这些有效的组织,可以引导使用者对原始数据进行快速检索

索引的本质:

  • 通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

索引的数据结构:B+树

InnoDB 的数据是按数据页为单位来读写的。也就是说,当需要读取一条记录的时候,并不是将这个记录本身从磁盘读取出来,而是以页为单位,将整个页加载到内存中,一个页当中可能有很多记录,然后在内存中对页进行检索。在innodb中,每个页的大小默认是16kb。

千寻简刷八股文丨第一天_第3张图片

千寻简刷八股文丨第一天_第4张图片

B+树的特征:

  1. 每个节点至少有m个子女。
  2. 根节点外,每个节点至少有[m/2]个子女,根节点至少有两个子女。
  3. 有k个子女的节点必有k个关键字
  4. 父节点的关键字在子节点中都存在,要么是最小值,要么是最大值,如果节点中关键字是升序的方式,父节点的关键字是子节点的最小值
  5. 最底层的节点是叶子节点
  6. 除了叶子节点之外,其他节点不保存数据,只保存关键字和指针。
  7. 叶子节点包含了所有数据的关键字以及data叶子节点之间用链表连接起来,可以非常方便的支持范围查找。
  8. 有k个子树的中间节点包含了有一个k元素(B树中是k-1个元素),每个元素不保存数据,所有的数据均保存在叶子节点上。
  9. 所有的叶子节点中包含了全部元素的信息及指向含这些元素记录的指针,且叶子节点本身以关键字的大小自小到大顺序连接
  10. 所有的中间节点元素都同时存在于子节点中,在子节点元素中卫最大值或则最小值。

B+树的优势:

  1. 单一节点存储更多的元素,使得查询的IO次数更少。
  2. 所有查询都要查找叶子节点,查询性能稳定。
  3. 所有叶子节点形成有序链表,便于范围查询。

⭐️ 索引分类:

分为聚集索引非聚集索引

  1. 聚集索引

    • 每个索引有且一定会有一个聚集索引,整个表的数据存储在聚集索引中,MySQL索引是B+树结构保存在文件中,叶子节点存储主键的值以及对应记录的数据,非叶子节点不存储记录的数据,值存储主键的值。

    • 当表中未指定主键时,MySQL内部自动给每条记录添加一个隐藏的rowid字段(默认4个字节),用于rowid构建聚集索引。

    • 聚集索引在MySQL中又叫主键索引。

  2. 非集聚索引(辅助索引)

    • 也是B+树结构,不过有一点和聚集索引不同,非聚集索引叶子节点存储字段(索引字段)的值以及对应记录主键的值,其他节点只存储字段的值(索引字段)。

    • 每个表可以有多个非聚集索引。

⭐️MySQL非集聚索引分为:

  • 单例索引:即一个索引只包含一个列。
  • 多列索引(又称复合索引):即一个索引包含多个列。
  • 唯一索引:索引列的值必须是唯一,允许有一个空值。

索引常见问题:

  • 回表:根据where条件找到主键ID,利用主键ID再去查询当前这条数据的过程叫回表。
  • 索引覆盖:查询中采用的索引树中包含了查询所需要的所有字段的值,不需要再去聚集索引检索数据,这种叫索引覆盖。
  • 索引下推:简称ICPIndex Condition Pushdown(ICP)MySQL 5.6的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式,ICP可以减少存储引擎访问基本表的次数以及MySQL服务器访问存储引擎的次数。

⭐️建议:

  1. 区分度高的字段上面建立索引可以有效的使用索引,区分度太低,无法有效的利用索引,可能需要扫描所有数据页,此时和不适用索引差不多。
  2. 联合索引注意最左匹配原则:必须按照从左到右的顺序匹配,MySQL会一直向右匹配直到遇到范围查询 >、<、between、like就停止匹配,比如 a = 1 and b = 2 and c >3 and d = 4如果建立 a,b,c,d顺序的索引,d是用不到索引的,如果建立 a,b,d,c的索引则都可以用到,a,b,d的顺序可以任意调整,就是 c要放在最后,因为遇到 >就停止匹配。
  3. 查询记录时候,避免使用 select *,尽量去利用索引覆盖,可以减少回表操作,提升效率。
  4. 有些查询可以采用联合索引,进而使用到索引下推(ICP),也可以减少回表的操作,提升效率。
  5. 禁止对索引字段使用函数、运算符操作,会使索引失效。
  6. 字符串字段和数字比较的时候会使索引无效。
  7. 模糊查询 %值%会使索引无效,变为全表扫描,但是 值%这种可以有效利用索引。
  8. 排序中尽量使用到索引字段,这样可以减少排序,提升查询效率。

【数据库】Sql语句优化有哪些?数据库的优化怎样优化?

  1. 优化表结构

    • 尽量使用数字型字段。若只含数值信息的字段尽量不要设计为字符型,这回降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中的每一个字符,而对于数字型而言只需要比较一次就够了。
    • 尽可能的使用varchar代替char。可变长字段存储空间小,可以节省存储空间。
    • 索引列存在大量重复数据时,可以把索引删除掉。比如有一列是性别,只有男、女,这样的索引是无效的。
  2. 优化查询

    • 尽量避免在where子句中使用!=<>操作符,否则将引擎放弃使用索引而进行全表扫扫描
    • 尽量避免在where子句中使用or来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描。建议使用union替换or
    • 尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描
    • innot in也要慎用,否则会导致全表扫描
    • 优化嵌套查询时可以将子查询尽量替换为多表连接查询(JOIN)。
    • 任何查询也不要出现select *
  3. 索引优化

    • 尽量使用复合索引,而少使用单列索引。
    • 最左前缀法则:如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。
    • 对做为查询条件order by的字段建立索引。
    • 对查询进行优化,要尽量避免全表扫描,首先考虑在whereorder by设计的列上个建立索引。
  4. 其他优化

    当进行数据的insert操作的时候,可以考虑采以下集中优化方案。

    • 如果需要同时对一张表插入很多行数据时,应该尽量避免使用多个值表的insert语句,这种方式大大缩减客户端与数据库之间的连接、关闭等消耗。使得效率比分开执行的单个insert快。
    • 手动开启事务后进行数据插入。
    • 数据有序插入(按主键)。

你可能感兴趣的:(Java,面试题,Java基础,java,jvm,面试,数据库,算法)