讨论/求职面试/shopee|一面凉经|2021|/
shopee|一面凉经|2021|

面试官挺年轻的,感觉也就20多岁出头的样子

  1. 请先自我介绍一下

  2. hashMap的实现

    • hashMap的数据结构什么样
    • hashMap的几种操作的时间空间复杂度
    • hashMap取hash时发生碰撞怎么办?
  3. mysql

    • mysql的几种引擎,他们中的区别

      特性 InnoDB MyISAM MEMORY
      事物安全 支持 不支持 不支持
      对外建的支持 支持 不支持 不支持
      存储限制 64TB
      空间使用
      内存使用
      插入数据的速度

      InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM

      1. 当需要使用数据库事务时候,InnoDb就是首选
      2. 由于锁的粒度小,写操作是不会锁定全表的。所以在并发度较高的场景下使用会提升效率的。
      3. 大批量的插入语句时(这里是INSERT语句)在MyIASM引擎中执行的比较的快,但是UPDATE语句在Innodb下执行的会比较的快,尤其是在并发量大的时候。
    • 为什么要使用自增主键

      1. 在业务中,主键最好是设置一个与业务无关的自增id作为主键,然后添加一个与业务有关的字段作为唯一性约束(要求该列唯一,允许为空,但只能出现一个空值)
      2. 要是使用自增主键,每次插入新的记录,记录就会索引到当前索引节点的位置,直接添加,要是一业务写满,就自动开辟一个新的页,总而言之就是提高查询和写入的速度
      3. 如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题
      • 要是我随机生成一个UUid进去会怎么样

        因为innoDB是在索引中存储索引值,也是在叶子节点中存储数据,所以没有定义主要就会使用一个非空的键作为主键聚簇索引中,N行形成一个页(16k),要是有不规则的数据插入时为了保存b+树的平衡,会造成频繁的页分裂和页旋转,插入速度就变慢,所以聚簇索引的注解银根是连续增长的值

    • mysql的索引怎么使用

      1. 利用B-Tree索引进行全局关键字、关键字范围和关键字前缀的查询
      • 索引失效的情况
        1. 以%开头的like查询不能使用B-Tree索引
        2. 隐式转换时,当列类型是字符串时候,要是where查询时候没有引起来,就也不会走索引
        3. 复合索引情况下不满足最左原则Leftmost,也不会使用复合索引。
        4. 如果MySQL估计使用索引比全表扫描更慢,则不使用索引。
        5. 以or分割开的条件,如果or前的条件列中有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。因为or后面的条件列中没有索引,那么后面的查询肯定要走全表扫描,在存在全表扫面的情况下,就没有必要多一次索引扫面增加I/O访问,一次全表扫描过滤条件就足够了。
    • 为什么使用MySQL的最左匹配原则,不能是中间匹配,最右匹配

      **最左匹配原则:**最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

      比如a,b建立索引时候,是先以a建立的索引,此时b是无序的,在以a建立之后的a的子树上再建立b的索引,所以对于整颗b+树来说,a是一定有序的,b是不一定有序的

      当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

    • mysql怎么实现主从复制

      1. Master开启bin-log功能,服务器配置二进制日志(binlog日志),只保留update等的数据。
      2. 需要开启三个线程,Master:I/O线程;Slave:I/O线程,SQL线程。
      3. 从数据库会请求主数据库的binlog日志,将bin-log日志内容写入到relay-log中继日志,创建一个master.info文件,然后按日志执行
      4. Slave已经开启了sql线程,由sql线程实时监测relay-log日志内容是否有更新,如果有更新,则解析文件中的sql语句,并在Slave数据库中执行相同的操作语句。
  4. 计算机网络

    • 简述三次握手和四次挥手

      • ①首先 Client 端发送连接请求报文,

      • ②Server 段接受连接后回复 ACK 报文,并为这次连接分配资源。

      • ③Client 端接收到 ACK 报文后也向 Server 段发生 ACK 报文,并分配资源,这样 TCP 连接就建立了。

      • ①服务端申请断开连接即FIN,发送Seq+Ack

      • ②客户端接收信息返回,表示我已经接收到

      • ③客户端发送信息表示可以断开连接

      • ④服务端接受信息,返回数据表示已接受信息

    • 之间11种状态转移和状态的含义

    • 为什么要Time_Wait

      谁先关闭谁先进入time_wait状态

      1. 可靠的终止TCP连接。
      2. 保证让迟来的TCP报文有足够的时间被识别并丢弃
      3. 让网络上的数据包自动消亡,防止旧连接初始了新的连接

      这个期间这个连接的四元组不能被使用,可以设置端口重用(慎用)

    • 要是没有三次握手会怎么样

      1. 三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。(防止历史连接初始化了连接)
      2. 同步双方初始序列号
      3. 避免资源浪费
    • 要是没有四次挥手会怎么样

      1. 防止旧连接的数据包
      2. 保证连接正确关闭
    • 握手报文里都有哪些关键字段

      • ISN代表什么?意义何在?

        ISN,发送方的字节数据编号的原点,让对方生成一个合法的接收窗口。

      • ISN是固定不变的吗?

        动态随机。

  5. 多线程

    • 线程的几种状态(6种)

      初始,运行,阻塞,终止,等待,超时等待

      • 初始状态Thread new 出一个线程类,这个线程就进入了初始状态

      • 就绪状态:(等于进入可运行池)

        1. 说明这个线程有资格进行,但是要等待调度程序调度到。
        2. 线程start()方法之后就进入了就绪状态
        3. 线程sleep()结束,其他线程join()结束,用户io完毕,线程拿到了对象锁,以就进入就绪状态
        4. 当前线程时间片用完了,自身调用yield()方法,进入就绪状态
      • 运行态:线程运行

      • 阻塞状态:线程阻塞时候,需要获得锁的状态

      • 等待:这种状态并不会被cpu分配执行时间,要需要有被显式的唤醒,否则就会一直是这个状态

      • 超时等待:这种状态并不会被cpu分配执行时间,在到达一定时间后会自动唤醒

      • 终止状态:当run()完成时,或者main()线程完成时,就任务他终止了,

        在一个终止的线程中调用start()方法会抛出java.lang.IllegalThreadStateException异常

    • 他们是怎样转移的

  6. 缓存调度算法

    • 有哪几种实现方法

      1. 先进先出FIFO
      2. 最近最少使用LRU
      3. 最不经常使用算法LFU,根据在一段时间里页面被使用的次数选择出最少使用的页
      4. 最优替换(不能实现)
    • LRU的实现方案

      1. 用一个数组来存储数据,给每一个数据项标记一个访问时间戳,每次插入新数据项的时候,先把数组中存在的数据项的时间戳自增,并将新数据项的时间戳置为0并插入到数组中。每次访问数组中的数据项的时候,将被访问的数据项的时间戳置为0。当数组空间已满时,将时间戳最大的数据项淘汰。
      2. 利用一个链表来实现,每次新插入数据的时候将新数据插到链表的头部;每次缓存命中(即数据被访问),则将数据移到链表头部;那么当链表满的时候,就将链表尾部的数据丢弃。
      3. 利用链表和hashmap。当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样一来在链表尾部的节点就是最近最久未访问的数据项。
  7. Redis

    • redis的数据结构(5种)
      1. String
      2. hash
      3. set
      4. zset
      5. list
    • list的底层数据实现结构
      • ziplist或linkedlist
    • zset的底层数据实现结构
      • zset底层的存储结构包括ziplist或skiplist,在同时满足以下两个条件的时候使用ziplist,其他时候使用skiplist,两个条件如下:
        • 有序集合保存的元素数量小于128个
        • 有序集合保存的所有元素的长度小于64字节
    • hash的底层数据结构
      • ziplist(压缩列表)和hashtable
  8. 要是分布式缓存发生雪崩了怎么办,要怎么防止发生

    ​ 当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。通俗讲就是:缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

    ​ 如何防止:

    1. 缓存失效或,通过加锁或队列来控制读取数据库的访问的线程数量,比如对某个key值运行一个线程访问数据库,其他线程等待
    2. 不同的key,设置不同的过期时间,让环创失效的时间点尽量均匀
    3. 做二级缓存,a1失效时候,访问a2,a1失效的时间设置为短期,a2为长期
    • 按你使用消息队列时候,那就把多线程变成单线程了吗?在高并发时候你觉得这样适用吗?应该怎么处理
  9. 分布式系统中还有哪些地方会发生雪崩

  10. 算法

    • 栈实现队列

    • 队列实现栈

    • 最长不重复子串

      • 暴力
      • 滑动窗口(双指针)
  11. 总结
    我是mysql哪里把我问炸了,之后状态就不好了,开始紧张了,有些记得的专有名词给忘记了,比如网络那里,
    算法那里用暴力给他实现了,然后讲了双指针的思路。

123

别人都说“面试造飞机,工作拧螺丝”是真的吗?

展开全部 54 讨论