• Java 超经典面试题



    A、Redis 五种数据类型是什么?哪些场景使用?如何选择?

    五种数据类型:String、Hash、set、zset 和 list

    String 常用于做缓存分布式锁计数器分布式ID存token 等等。。。。

    Hash 用于将结构化数据 (对象、多键值对) 缓存到 Redis 中,常用来存储部分变更的数据(用户信息等)

    list 用作异步队列和存储多个有序的字符串,例如朋友圈、Twitter 的关注列表、粉丝列表等等等

    set 系统部署在多台机器上,可以用 Redis 中的 set 进行全局去重,单机可以基于 JVM 的HashSet 去重,基于其可以交集并集的操作可以做用户标签和抽奖。。

    zset 去重且排序,Redis 的 zset天生是用来做排行榜的,榜单,总榜,热榜。。

    此问题的答案参考:https://blog.csdn.net/CSDN2497242041/article/details/122530152


    B、HashTable 和 HashMap 的区别 ? HashMap 的扩容原理 ?及两者的使用场景

    HashMap 和 HashTable 都实现了 map、Cloneable(可克隆)、Serializable(可序列化) 这三个接口

    但 HashTable 不允许 key 为 null 值,HashMap 则无所谓

    而且 HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的负载因子默认都是:0.75。

    HashMap 只允许迭代器遍历。。。

    关于翻倍:当已用容量 > 总容量 * 负载因子 时将会进行扩容,HashMap 的扩容是翻倍,HashTable 是 翻倍 + 1。。。

    HashTable 是线程安全,在单线程环境下它比 HashMap 要慢。如果你不需要同步,只需要单一线程,那么使用 HashMap 性能要好过 HashTable。

    使用场景:

    非并发场景使用 HashMap,并发场景可以使用 HashTable,但是推荐使用 ConcurrentHashMap (锁粒度更低、效率更高)


    C、MySQL 索引机制 ? 锁机制 ?为什么会走错索引 ?

    为什么要使用索引 ?

    • 索引能极大的减少存储引擎需要扫描的数据量。
    • 索引可以把随机IO变成顺序IO。
    • 索引可以帮助我们在进行分组、排序等操作时,避免使用临时表。

    索引分类 ?

    • 主键索引、唯一索引、前缀索引、普通索引、全文索引

    索引原理 (底层数据结构) ?

    Hash 表支持精准的定位查询,但不支持范围查询和顺序查询,导致 > < != 这些条件查不出来

    平衡二叉树:当数据量为100w时,树的高度大约为20,这样的话,在最坏的情况下读取一个数组需要进行20次查找,每次查找都是一次IO操作,性能就成为了一个问题。

    B+Tree

    B+Tree 是 B-Tree 基础上的优化,将非叶子节点冗余,提高范围查找的效率。

    • 所有的非叶子节点只存储关键字信息。

    • 所有具体数据都存在叶子结点中。

    • 所有的叶子结点中包含了全部元素的信息。

    • 所有叶子节点之间都有一个链指针

    在这里插入图片描述
    MySQL 索引默认采取的数据结构就是 B+Tree

    索引优化建议 ?

    • 避免在 where 子句中对字段施加函数,这会造成索引无法命中。
    • 尽量不要在重复数据多的列上使用索引。
    • like 的模糊查询以%开头,会导致索引失效。
    • 删除长期未使用的索引。

    锁机制 ?

    主要了解乐观锁悲观锁,共享锁排他锁就 ok 。。

    MySQL 走错索引 ?

    MySQL 在选择使用索引时,有一套自己的评估机制。查询可能会扫描多少行、是否有排序、是否有用到文件排序、索引的区分度等等。用错索引的情况多是一条SQL语句中可以有多个索引备选。
    全表扫描和使用索引就是一个例子。当数据库中数据比较少的时候,MySQL查询是执行索引查询呢?还是全表扫描呢?因为索引扫描会有一个二次回表的过程,而全表扫描没有。但全表扫描就一定比二次回表快吗,这倒不见得。

    MySQL 判断选择哪个索引时,这个是优化器的工作。优化器会根据扫描的行数、是否回表、是否使用临时表、排序等来判断使用索引还是全表扫描。

    优化器计算扫描行数的逻辑是预估的方式 ,是通过对索引的采样统计计算出来的,所以判断的行数不准确时就会选错索引。


    D、哪些是需要使用 Redis 存放的数据,为什么?哪些需要直接查询?

    非敏感且需要立即返回的数据、热点数据需要用 Redis存放,直接查的一般是敏感数据(价格)和非热点(比如很久之前)的数据


    E、MySQL 和 PostgreSQL 如何选择?

    MySQL 针合业务逻辑相对简单、数据可靠性要求较低的互联网单表场景,Pg 适合大量单表破亿以及更加严格的企业的场景,常用于电商订单、金融、电信等


    F、MySQL 为什么需要分库分表?

    随着平台的业务发展,数据可能会越来越多,甚至达到亿级。以MySQL为例,单库数据量在5000万以内性能比较好,超过阈值后性能会随着数据量的增大而明显降低。单表的数据量超过1000w,性能也会下降严重。这就会导致查询一次所花的时间变长,并发操作达到一定量时可能会卡死,甚至把系统给拖垮。

    ​分库分表就是把较大的数据库和数据表按照某种策略进行拆分。目的在于:降低每个库、每张表的数据量,减小数据库的负担,提高数据库的效率,缩短查询时间。另外,因为分库分表这种改造是可控的,底层还是基于RDBMS,因此整个数据库的运维体系以及相关基础设施都是可重用的。


    G、微服务为什么要使用流量网关?

    服务网关 = 路由转发 + 过滤器

    在微服务架构中,由于系统和服务的细分,导致系统结构变得非常复杂, 为了跨平台,为了统一集中管理 API ,同时为了不暴露后置服务。甚至有时候需要对请求进行一些安全、负载均衡、限流、熔断、灰度等中间操作,基于此类种种的客观需求一个类似综合前置的系统,这就是为什么需要 API 网关。

    H、 哪些场景使用 ArrayList 、LinkedList ?

    当需要对数据进行对随机访问的时候,选用 ArrayList。
    当需要对数据进行多次增加删除修改时,采用 LinkedList。
    如果容量固定,并且只会添加到尾部,不会引起扩容,优先采用 ArrayList。

    当然,绝大数业务的场景下,使用 ArrayList 就够了,但需要注意避免 ArrayList 的扩容,以及非顺序的插入。

    ArrayList 不是线程安全的,多线程下 synchronizedList 方法将 ArrayList 转换成线程安全的容器后再使用,或者对其方法进行加锁。。。

  • 相关阅读:
    Vue 3 组合式编程:革新前端开发的新时代
    如何写好技术文档 - 排版格式和规范(一)
    Linux下的 /etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc 笔记2208300059
    React Hooks 源码学习
    linux安装MySql
    Flutter屏幕适配
    HTML中<a>标签和target=“_blank“属性的使用方法及作用(清晰易懂,带例子)
    高性能MySQL实战第11讲:如何做到MySQL高扩展性?
    【学习笔记】拉格朗日插值
    40 行 Python 代码,写一个 CPU
  • 原文地址:https://blog.csdn.net/m0_51111980/article/details/127840368