面试记录

443 阅读36分钟

面试题

1、各种分布式中间件 选举算法
        2、倒计时门栓、信号量、循环栅栏 完成。
3wait、notify原理(Lock可重入锁)源代码。
        4、redis主从切换细节(主节点进行选举)
        5、spring boot启动流程:各个注解作用。
        6、spring bean 生命周期。
        7、线程池原理。(阻塞队列原理)
8、guava chache 源码。阻塞、淘汰。
9、京东:jmq、jsf、ump、日志、ducc、jimdb。
        10、mybatis:源码
        11select、poll、epoll

mysql 主从复制、同步、半同步 blog.csdn.net/K_520_W/art…

redis数据结构

String
        int 、raw、ziplist
hash
        ziplist、hashtable
set
        intset、hashtable
list
        ziplist、linkedlist
zset
        ziplist、skiplist

字节 1、小于n的最大数 2、最长公共子序列 3、薪资第二大的薪资(相同薪资

蔚来 包含指定子串的最短字符串。

亚马逊

 [[1,2],[2,3],[3,4],[1,3]]

 [1,2,3,0,2]

 [[1,2],[2,3],[5],[0],[5],[],[]]

jimdb 单机版管理,配置中心获取拓扑信息,定时轮询获取拓扑信息。 jsf 流程基本一直,注册中心使用mysql存储,注册中心缓存全部数据,使用index服务屏蔽注册中心变更。 jmq 基于active mq开发,采用主从架构,存储模式与rocketmq类似。

重点刷题:

1:排序算法(冒泡,堆排序,二分法,所有的排序算法都刷一下),
2:二叉树,
3:链表,
4:字符串,
5:数据结构,
6:数组 ,
7:动态规划
刷leetcode或者牛客网 中等难度的或者简单难度高频次的题目

您最好是去 牛客网上去刷,上边有题库。可以用您最擅长的技术栈来写就ok

字节跳动一般考算法题是在牛客网

ZGC

有色指针 只扫描指针,通过指针记录对象移动  
ZGC过程
* 并发标记
* 并发预备重分配
* 并发重分配
* 并发重映射

类加载过程:双亲委派模型

自定义类加载器 -> 应用程序类加载器(applicaiton) -> 扩展类加载器(extension) -> 启动类加载器(bootstrap)

类加载过程

* 加载
* 验证
* 准备-静态变量
* 解析-符号引用替换为直接引用
* 初始化

spring bean生命周期、spring boot启动流程

cpu飙升

mybatis、自动实现接口源代码 动态代理

1.  在映射文件初始化完成后,将对应的Mapper接口的代理工厂类`MapperProxyFactory`注册到`MapperRegistry`
2.  每次操作数据库时,`sqlSession`通过`MapperProxyFactory`获取Mapper接口的代理类
3.  代理类通过增强器`MapperProxy`调用XML映射文件中SQL节点的封装类`MapperMethod`
4.  通过`MapperMethod`将Mybatis 面向接口的编程模型转换成iBatis编程模型(SqlSession模型)
5.  通过`SqlSession`完成对数据库的操作
  • 设计模式:代理模式与装饰器模式区别

  • nio 三种模式

  • 零拷贝

  • cms 过程

    1、初始标记 2、并发标记 3、并发预清理 4、可终止的预清理 5、重新标记 6、并发清理 7、并发重置

面试经历

中邮

1、链路追踪原理
2、hystrix 原理
3、mycat原理

瑞幸咖啡

1、cms过程
2、元模型
3、分布式事务 seta
    4、订单下单过程,库存、优惠券、生成订单,一致性保证

小米

1、jsf 序列化方式 msgpack、hession坑,新增字段必须在后面。
2、dubbo 泛化调用
3、索引下推、索引覆盖
4、意向锁、间隙锁、死锁

联通

1、redis map 结构 refresh过程
2、事务 过程   间隙锁
3、g1、ZGC区别。

电信

1、深分页 
2、es 查询优化
3、crm系统介绍一下。

中设

1、hashmap 多线程 不扩容,put是否出现问题。
2、多线程特点 原子性、可见性、有序性
3、redis扩容 jimdb原理、优点
4、mysql 分表
5、架构设计过程,识别系统复杂度、选型、评审、详细设计、开发

字节面试

1、zk 选举 分布式选举 zab、raft,zk如何确定leader挂了,心跳(哪几种),脑裂问题怎么处理?
过半机制,防止脑裂

2、salesforce 与美团crm区别
成熟、配置
3、crm数据流转
公海-私海-成单(开团、关团、关团复开)
4、kafka 顺序消费
producer:发送到同一个partition
consumer:消费一个partition5、kafka发送到指定partition
指定分区,就是指 构建ProducerRecord的时候,topic为topic1的ProducerRecord指定partition1,假定broker此时有3个,分别为broker0、broker1、broker2,那这个消息将会发送给broker1。
实现接口,获取所有partition,发送到指定partition6、布隆过滤器:不能删除。
10、一致性哈希
虚拟节点,解决hash倾斜问题。
11、字典树、前缀树 es,倒排索引
12、最长公共子序列(动态规划)、小于n的最大数
回溯+贪心

小米面试

1final、finally、finalize
    finalize ,是方法名。Java 允许使用 `#finalize()` 方法,在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。
2String类为什么是final类型?
    final的出现就是为了为了不想改变,而不想改变的理由有两点:设计(安全)或者效率。
    final 修饰的类是不被能继承的,所以 final 修饰的类是不能被篡改的。
3、Stirng 存放位置
    常量池,堆,常量池在方法区。
4、HashMap
    * 当链表超过8且数组长度(数据总量)超过64才会转为红黑树
    将链表转换成红黑树前会判断,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树,以减少搜索时间。
    * 1.8采用尾插,1.7采用头插入。
    * jdk1.8里面的扩容机制,已经不再是1.7那样重新计算hashcode然后采用头插法的方式扩容了。而是采用高低位指针的形式,将低位上的数据移动到原来的位置,高位上的数据移动到【原来的位置+旧数组容量】的位置。 这样的做法避免了rehash,效率大大提升。
    * 红黑树退化:扩容时,个数小于6, 如果不设退化阀值,只以8来树化与退化,
那么8将成为一个临界值,时而树化,时而退化,此时会非常影响性能,因此,我们需要一个比8小的退化阀值;
    * jdk1.7 头插,同时扩容,成环。
    * 红黑树:红黑树确保没有一条路径会比其它路径长出两倍,AVL树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树的高度差不超过1,和红黑树相比,AVL树是严格的平衡二叉树
5、aio:异步非阻塞。
6、select、poll、epoll。
7、设计模式:策略模式
8、单例模式破坏
    * 序列化:readResolve
    * 反射:通过标志变量
9String.intern 在常量池创建变量,如果存在,返回引用。
10、类加载流程:加载、验证、准备、解析、初始化
11、通过一个类只被加载一次。破坏双亲委派:热部署,使用不同的类加载器。实例:jsp、模块化(osgi)
12、类加载器:1.9 app、平台类加载器、启动类加载器
13、ExecutorService创建线程池缺点:队列无界或最大线程数无上限。
14、threadlocal内存泄漏原因:生命周期与thread一样长。为什么不适用thread做key,可以存放多个threadlocal。
15、jit
c1:客户端编译器,c2:服务端编译器。
**client模式**是一种轻量级编译器,也叫**C1**编译器,占用内存小,启动快,耗时短,它会进行简单并可靠的优化,更注重**效率**。
**server模式**是一种重量级编译器,也叫**C2**编译器,启动慢,占用内存大,耗时长,但编译的代码执行效率更高,甚至会根据性能监控信息进行一些不可靠的激进优化,更注重**质量**。
编译对象:多次调用的方法、多次执行非循环体。
热点代码确认:计数器、采样,次数:客户端1500次,服务端10000次。
优化措施:方法内联、逃逸分析(栈上分配)、同步消除
16、oracle jdk、openjdk区别
    oracle jdk:商用
    open jdk:开源
17、对象不可达立即回收吗?
经过两次标记,执行finallize方法,第二次标记后清除。
18、共享锁、排它锁,查询不阻塞,使用mvcc。
19、spring boot starter加载流程:factory文件中的配置类加载,其它不加载。
20、epoll:socket句柄放入红黑树,有事件发生时,放入就绪队列。
21、Reactor模式使用多路复用进行事件监听,收到事件后根据事件类型分配给对应的线程和进程,它由以下两个部分组成:
    1.  Reactor :负责监听和分发事件,事件类型包含连接事件、读写事件;
    2.  处理资源池:负责处理事件,如 read -> 业务逻辑 -> send;
22、binlog canal bug:
23、rocketmq:消息重试,最多16次,每次间隔时间不同,最后订阅失败通知。
24、零拷贝
    内存映射(mmap) 1次cpu 4次上下文切换
    sendfile:1次cpu 2次上下文切换
    sendfile+dma copy 0次cpu,2次上下文切换(文件描述符+长度)
    splice:0次 cpu,2次上下文切换。(内核建立管道)

小米二面

1、字符串 转ip地址。 2、链表转平衡二叉树。

蔚来面试

1、包含指定字符串的所有子串。  
2、合并有序数组。  
3、 两个广告 AB 分数 为 5 10,设计redis,返回分布于分数分布一致。  
参考负载均衡-加权
4、kafka:offset存放位置(broker)

联通面试

1、G1、ZGC原理

而G1回收器只是逻辑分代,并且为了在更大heap范围拥有高速回收的效率,G1采用了分而治之的思想。G1把整个heap切分成了很多的Region,每个Region大小为2的N次幂M,而每个Region都有可能是Eden区,Survivor区,Old区和Humongous区。
过程

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收 2、synchronized底层原理。

Synchronized是由JVM实现的一种实现互斥同步的一种方式,如果你查看被Synchronized修饰过的程序块编译后的字节码,会发现,被Synchronized修饰过的程序块,在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。
这两个指令是什么意思呢?在虛拟机执行到monitorenter指令时,首先要尝试获取对象的锁:如果这个对象没有锁定,或者当前线程已经拥有了这个对象的锁,把锁的计数器+1;当执行 monitorexit指令时将锁计数器-1;当计数器为O时,锁就被释放了。如果获取对象失败了,那当前线程就要阻塞等待,直到对象锁被另外一个线程释放为止。Java中> Synchronize通过在对象头设置标记,达到了获取锁和释放锁的目的。

3、redis淘汰策略 过期策略 1、定期删除 扫描 2、惰性删除 访问时删除 3、定时删除 每个key设置定时器 内存淘汰策略

  1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
  2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
  3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
  4. allkeys-random:加入键的时候如果过限,从所有key随机删除
  5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
  6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
  7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
  8. allkeys-lfu:从所有键中驱逐使用频率最少的键

4、数据库、缓存不一致。

* 先写数据库、后删除缓存(写数据之前查询缓存,删除缓存时候,设置缓存,概率低)
* 中间失败 使用binglog
延迟双删
a、先删除缓存  
b、再写数据库  
c、休眠500ms(根据统计线程读取数据和写缓存的时间)
(休眠的作用是当前线程等其他线程读完了数据后写入缓存后,删除缓存)
d、再删除缓存

5、顺序消费 使用同一个队列 6、类加载过程:双亲委派。
7、线程池优点:充分利用cpu资源。

用友面试

1、ZK分布式锁实现原理。

2、spring cloud gateway比zuul好在哪里?

springcloud getway 它是基于spring 5.0 、spring boot 2.0 和spring reacter,为微服务提供一个简单有效的网关API路由接口。
Spring Cloud GetWay 作为Spring Cloud生态系统的网关,目标是为了代替zuul,SpringCloud GetWay 是基于webFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
spring cloud getway的目标,提供统一的路由方式,基于Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
Spring Cloud Gateway 底层使用了高性能的通信框架Netty。

3、devops、K8S
4、事务传播:类型
PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。(required需要,没有新建,有加入) PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。(supports支持,有则加入,没有就不管了,非事务运行) PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。(mandatory强制性,有则加入,没有异常) PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。(requires_new需要新的,不管有没有,直接创建新事务) PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。(not supported不支持事务,存在就挂起) PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。(never不支持事务,存在就异常) PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。(nested存在就在嵌套的执行,没有就找是否存在外面的事务,有则加入,没有则新建) 5、垃圾收集器G1原理。
6、中间件:选一个深刻了解。
7、分布式事务:TCC原理,中间失败,回滚还是cancel。

cancel

8、cpu使用率过高

1、top命令
2、ps -mp 进程号 -o THREAD,tid,time 或者 top -Hp 进程号 3、线程号转换为16进制。
4、jstack 9994 | grep 270c

9、jdk命令行
jps(java process status tool), 用于查看java进程及相关信息,如果你想找到一个java进程的pid,可以使用jps命令代替linux的ps命令。
jstat 命令主要用于查看jvm运行时状态信息, 包括内存状态、垃圾回收等 jstat -gcutil -pid jinfo:java配置信息工具 jmap jmap可以生成java程序的dump文件 jhat jhat 用来分析jmap生成dump文件的命令 jstack jstack是用来查看jvm线程快照的命令

中信银行

1、sql执行流程
image.png 2、FLP理论 CAP理论 数据库CA中的哪一个。
在网络可靠,但允许节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性共识算法
3、jdk1.8 使用cms,低版本不是,高版本是,cms六个过程,STW。
Parallel Scavenge,1.9:G1,cms没有默认过
4、系统设计:网银转账、明细。注意点:安全、一致性。
分布式事务,重试。
5、sharding-jdbc,扩容。
6、分页 PageHelper 坑。

使用threadlocal传递参数,线程没有remove。
7、分布式系统:一个副本数据不一致,怎么处理?
好像没有办法
8、autowired实现原理。
AutowiredBeanPostProcessor,后置处理器。
9、前缀索引
字符串一部分建立索引
10、那些操作让出cpu
wait、sleep、Thread.yield、LockSupport.park、join
11、happens-before
指令重排规则 8条规则
12、火焰图

头条一面

1、es

深度分页

es 默认采用的分页方式是 from+ size 的形式,在深度分页的情况下,这种使用方式效率是非常低的。es为了性能,限制了我们分页的深度,es目前支持的最大的 max_result_window = 10000;也就是说我们不能分页到10000条数据以上。

在es中如果我们分页要请求大数据集或者一次请求要获取较大的数据集,scroll都是一个非常好的解决方案。使用scroll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来scroll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的。每次发送scroll请求,我们还需要指定一个scroll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。一个滚屏搜索允许我们做一个初始阶段搜索并且持续批量从Elasticsearch里拉取结果直到没有结果剩下。这有点像传统数据库里的cursors(游标)。滚屏搜索会及时制作快照。这个快照不会包含任何在初始阶段搜索请求后对index做的修改。它通过将旧的数据文件保存在手边,所以可以保护index的样子看起来像搜索开始时的样子。这样将使得我们无法得到用户最近的更新行为。

增加一个id字段,每次查询大于id的数据。

准实时

总结一下,数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。

查询 过程,如何确定数据在那个节点

根据id查询:协调节点根据路由算法定位分片所在机器,路由到相应机器。 搜索:所有节点查询,协调节点聚合。

模糊查询、精确查询

text:支持fields属性,可以在fields中添加keyword子类型,以实现精确检索 keyword:不分词

2、redis 穿透 击穿 雪崩概念,一致性哈希优点

缓存穿透,是指查询一个一定不存在的数据,由于缓存是不命中时被动写,并且处于容错考虑,如果从 DB 查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,失去了缓存的意义。
解决方案:布隆过滤器,空对象。

缓存雪崩,是指缓存由于某些原因无法提供服务( 例如,缓存挂掉了 ),所有请求全部达到 DB 中,导致 DB 负荷大增,最终挂掉的情况。
解决方案

  • 缓存高可用
  • 请求 DB 限流

缓存击穿,是指某个极度“热点” 数据在某个时间点过期时,恰好在这个时间点对这个 KEY 有大量的并发请求过来,这些请求发现缓存过期一般都会从 DB 加载数据并回设到缓存,但是这个时候大并发的请求可能会瞬间 DB 压垮。

一致性哈希优点

扩缩容方便,只影响一小段范围 节点宕机影响范围小 虚拟节点解决不平衡问题。

3、mysql binlog格式,binlog同步数据有什么注意点,主从同步过程,大数据、小数据同步区别。
三种格式

  • Statement

Statement 模式只记录执行的 SQL,不需要记录每一行数据的变化,因此极大的减少了 binlog 的日志量,避免了大量的 IO 操作,提升了系统的性能。
但是,正是由于 Statement 模式只记录 SQL,而如果一些 SQL 中包含了函数,那么可能会出现执行结果不一致的情况。比如说 uuid() 函数,每次执行的时候都会生成一个随机字符串,在 master 中记录了 uuid,当同步到 slave 之后,再次执行,就获取到另外一个结果了。
所以使用 Statement 格式会出现一些数据一致性问题。

  • Row

从 MySQL5.1.5 版本开始,binlog 引入了 Row 格式,Row 格式不记录 SQL 语句上下文相关信息,仅仅只需要记录某一条记录被修改成什么样子了。
Row 格式的日志内容会非常清楚的记录下每一行数据修改的细节,这样就不会出现 Statement 中存在的那种数据无法被正常复制的情况。
不过 Row 格式也有一个很大的问题,那就是日志量太大了,特别是批量 update、整表 delete、alter 表等操作,由于要记录每一行数据的变化,此时会产生大量的日志,大量的日志也会带来 IO 性能问题。

  • Mixed

从 MySQL5.1.8 版开始,MySQL 又推出了 Mixed 格式,这种格式实际上就是 Statement 与 Row 的结合。
在 Mixed 模式下,系统会自动判断该用 Statement 还是 Row:一般的语句修改使用 Statement 格式保存 binlog;对于一些 Statement 无法准确完成主从复制的操作,则采用 Row 格式保存 binlog。
Mixed 模式中,MySQL 会根据执行的每一条具体的 SQL 语句来区别对待记录的日志格式,也就是在 Statement 和 Row 之间选择一种。

4、并发包
threadlocal 注意点 造成oom原因

由于ThreadLocal对象是弱引用,如果外部没有强引用指向它,它就会被GC回收,导致Entry的Key为null,如果这时value外部也没有强引用指向它,那么value就永远也访问不到了,按理也应该被GC回收,但是由于Entry对象还在强引用value,导致value无法被回收,这时「内存泄漏」就发生了,value成了一个永远也无法被访问,但是又无法被回收的对象。
Entry对象属于ThreadLocalMap,ThreadLocalMap属于Thread,如果线程本身的生命周期很短,短时间内就会被销毁,那么「内存泄漏」立刻就会得到解决,只要线程被销毁,value也会随之被回收。问题是,线程本身是非常珍贵的计算机资源,很少会去频繁的创建和销毁,一般都是通过线程池来使用,这就将线程的生命周期大大拉长,「内存泄漏」的影响也会越来越大。

concurrenthashmap 1.8优化点

1、锁范围减小:分段锁-锁住桶的第一个节点,桶为空,使用cas插入,节点存在数据时使用synchronized插入。
2、size:增加变量,通过cas自增。
3、链表-红黑树。
4、

5、cap、base理论

Basically Available:基本可用 Soft state:软状态 Eventually consistent:最终一致性

6、设计模式原则

1.开放封闭原则(Open - ClosedPrinciple ,OCP) 2.单一职责原则(Single Responsibility Principle, SRP) 3.里氏代换原则( Liskov Substitution Principle ,LSP ) 4.依赖倒置原则( Dependence Inversion Principle ,DIP ) 5.接口隔离法则(Interface Segregation Principle,ISL) 6.迪米特法则(Law of Demeter, LoD)

头条二面

salefforce实现方案
存储:EAV

虽然EAV模型能够解决以上三种模型的缺点,有着灵活性强,完美解决数据稀疏性,但是它也因为太过于复杂,有着明显的学习曲线,查询性能也相对低下,必须为其提升性能做大量的辅助工作。

头条三面

限流算法 计数器 滑动窗口 漏桶 令牌桶 juejin.cn/post/687039…

**漏桶算法的出水速度是恒定的,**那么意味着如果瞬时大流量的话,将有大部分请求被丢弃掉(也就是所谓的溢出)。漏桶算法通常可以用于限制访问外部接口的流量,保护其他人系统,比如我们请求银行接口,通常要限制并发数。

令牌桶算法生成令牌的速度是恒定的,而请求去拿令牌是没有速度限制的。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌,可以处理瞬时流量,而且拿令牌的过程并不是消耗很大的事情。令牌桶算法通常可以用于限制被访问的流量,保护自身系统。

操作系统:同步、互斥

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

美团面试(一面)

1、频繁young gc可能原因。

新生代过小。
负载过高
内存泄漏
对象晋升年龄太长

2、微信朋友圈设计方案。 数据存储方案。

3、thread local 使用场景。

无参传递、链路跟踪

4、多线程共享资源 保证一致性。

5、mvcc使用场景。 隔离性:RR、RC 6、shareding-jdbc 查询所有数据。

美团面试(二面)

1、最长公共前缀 2、单链表-指定位置翻转 3、二叉树-所有路径之和

美团面试(一面)

1、限流、降级方案。sentinel原理。

计数器、滑动窗口、漏桶、令牌桶。 sentinel 使用滑动窗口。 Resilience4j 令牌桶 Guava RateLimiter 令牌桶

2、G1 原理。

G1算法将堆划分为若干个区域(Region),它仍然属于分代收集器。不过,这些区域的一部分包含新生代,新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者Survivor空间。老年代也分成很多区域,G1收集器通过将对象从一个区域复制到另外一个区域,完成了清理工作。这就意味着,在正常的处理过程中,G1完成了堆的压缩(至少是部分堆的压缩),这样也就不会有cms内存碎片问题的存在了。 初始标记,并发标记,重新标记,筛选清除

3、关闭System.gc。每分钟多少次young gc。

-XX:-+DisableExplicitGC

4、mysql同步原理-offset存放位置。索引B+树。

复制的基本过程如下:
1)、Slave 上面的 IO_thread 连接上 Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;

2)、Master 接收到来自 Slave 的 IO_thread 的请求后,通过负责复制的 IO 进程根据请

求信息读取指定日志指定位置之后的日志信息,返回给 Slave 的 IO_thread。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到 Master 端的 bin-log file 的以及bin-log pos3)、Slave 的 IO_thread 接收到信息后,将接收到的日志内容依次添加到 Slave 端的relay-log 文件的最末端,并将读取到的 Master 端的 bin-log 的文件名和位置记录到master-info 文件中,以便在下一次读取的时候能够清楚的告诉 Master“我需要从某个bin-log 的哪 个位置开始往后的日志内容,请发给我”;

4)、Slave 的 Sql_thread 检测到 relay-log 中新增加了内容后,会马上解析 relay-log的内容成为在 Master 端真实执行时候的那些可执行的内容,并在本数据库中执行。

索引 B+树

5、redis string数据结构。jimdb原理。redis集群。

mp.weixin.qq.com/s/-NFlyGcaF… 集群方案

6、redis分布式锁 主从同步存在问题、主从切换。

正确的获得锁 set 指令附带 nx 参数,保证有且只有一个进程获得到。 正确的释放锁 使用 Lua 脚本,比对锁持有的是不是自己。如果是,则进行删除来释放。 主从切换导致锁丢失,使用多个实例,一半以上获得锁即可。readlock

7、jmq原理。rocketmq主从切换原理。
blog.51cto.com/u_14612575/…

选举,raft协议,超过一半,随机休眠

8、zk选主原理。

zab 算法 (myid, zxid) 服务器id,事务id,投票,比较zxid,选择zxid最大的投出,zxid相同,选myid最大的,超过一半即可。

9、kafka原理:副本 选举原理。保证不丢消息。

消费端,自动提交offset改为手动提交,可能导致重复消费,做好幂等处理。 broker:服务端保证所有副本都写入成功后,才成功。 服务端:服务端保证所有副本都写入成功后,否则不断重试。

topic 分为多个分区,每个分区包含多个副本。

选举
在 Kafka 中并不是所有的副本都能被拿来替代主副本,所以在 Kafka 的Leader 节点中维护着一个 ISR(In sync Replicas)集合,翻译过来也叫正在同步中集合,在这个集合中的需要满足两个条件: 1、节点必须和 Zookeeper 保持连接。 2、在同步的过程中这个副本不能落后主副本太多。 blog.csdn.net/u013256816/…

10、算法:链表无环。链表第二大的数据。
11、家庭号-活跃用户数。

美团面试(二面)

1、mq原理,丢消息问题

三个方向

3、缓存数据库数据一致性,cannel写失败处理

先写数据库,后删除缓存,延迟双删

4、新生代回收时间过长。

大量对象没有回收 年龄不合理 oom

5、jsf负载均衡。 负载均衡分为集中式负载均衡与客户端负载均衡,ribbon是客户端负载均衡

  • 随机 (Random)
  • 轮询 (RoundRobin)
  • 一致性哈希 (ConsistentHash)
  • 哈希 (Hash)
  • 加权(Weighted)

6、分布式限流。

redis incr

快手面试

1、renttrendlock 原理。aqs。
结构:队列(head、tail)、状态 加锁:cas设置state 为1,成功获取锁(或者同一线程),失败加入队列等待唤醒 释放锁:state减1,为0时,唤醒等待队列中的线程。 2、公平锁、非公平锁。可重入、非可重入。原理
mp.weixin.qq.com/s/E2fOUHOab… 公平锁:排队,第一个获取锁 非公平锁:先获取锁,获取失败,在排队

可重入锁:state 为0,获取锁成功,本线程state++ 不可重入:state 置为1 读写锁:state:高16位读锁,低16位写锁。读写、写读、写写互斥,读读共享

3、限流方案-令牌桶、漏桶 完成

4、mvcc 原理 rr实现读取最新的数据。快照读、当前读。
版本链,最大事务号、最小事务号、活跃事务列表

5、缓存、高可用、高并发。 集群,主从 选举:从发起,其它master具备投票权限。超过一半替换故障转移成功。

6、redis:淘汰机制。rdb、aof:主执行rdb、从执行aof
主不建议进行rdb。 存量rdb、增量aof,aof配置刷盘频率。

7、架构准备。
8、数据分库、分表原理。
哈希取模 9、cglib实现原理。 继承被代理对象,增强后调用被代理对象方法。 10、threadlocal最佳实践。弱引用。
11、select poll epoll select、poll:轮询,select 上限1024,poll 使用链表,突破限制。 epoll :事件驱动,时间复杂度O(1) 12、零拷贝。
原来:4次状态切换,2次CPU复制,2次DMA复制。 零拷贝:2次状态切换,0次CPU拷贝,2次DMA复制。 算法:二叉树所有路径之和。

美团面试

1、线程池实现原理,为什么使用线程池,配置原则,核心线程数,最大线程数,线程池没有任务时在干什么? (阻塞,使用阻塞队列)

线程池的优点是显而易见的:它可以重用线程,避免线程创建的开销,在任务过多时,通过排队避免创建过多线程,减少系统资源消耗和竞争,确保任务有序完成

如何配置线程池

  • CPU密集型任务 尽量使用较小的线程池,一般为CPU核心数+1。 因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,会造成CPU过度切换。

  • IO密集型任务 可以使用稍大的线程池,一般为2*CPU核心数。 IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候有其他线程去处理别的任务,充分利用CPU时间。

  • 混合型任务 可以将任务分成IO密集型和CPU密集型任务,然后分别用不同的线程池去处理。 只要分完之后两个任务的执行时间相差不大,那么就会比串行执行来的高效。 因为如果划分之后两个任务执行时间有数据级的差距,那么拆分没有意义。 因为先执行完的任务就要等后执行完的任务,最终的时间仍然取决于后执行完的任务,而且还要加上任务拆分与合并的开销,得不偿失。

2、aqs数据结构、公平锁、非公平锁、可重入、非可重入。 concurrenthashmap:原理。 cas原理:循环次数(怎么设置)。死循环 aqs中文名字。

cas:对于并发环境中的计数、产生序列号等需求,考虑使用原子变量而非锁,乐观锁

3、guava cache lru实现原理。

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private int maxEntries;

    public LRUCache(int maxEntries) {
        super(16, 0.75f, true);
        this.maxEntries = maxEntries;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxEntries;
    }
} 

4、索引:B+树,执行过程,年龄、性别、姓名、省份。 > 50 男 北京 索引执行过程。mvcc原理。 5、限流、降级。 6、项目好好准备。
7、indexOf自己实现 aaab ab

    public static int indexOf(String target, String sub) {
        if (target == null || sub == null) {
            return -1;
        }
        if (sub.length() > target.length()) {
            return -1;
        }
        boolean flag = true;
        for (int i = 0; i < target.length() - sub.length() + 1; i++) {
            int start = i;
            for (int j = 0; j < sub.length(); j++) {
                if (target.charAt(start) != sub.charAt(j)) {
                    flag = false;
                    break;
                }
                start++;
            }
            if (flag) {
                return i;
            }
            flag = true;
        }
        return -1;
    }

阿里面试

1、spring 循环依赖(3级缓存、为什么不用2级缓存)

三级缓存:segmentfault.com/a/119000002…
第三级缓存解决动态代理问题,二级缓存可以,提前创建代理对象,与spring流程不一致。 提前曝光,三级依赖。

2、arraylist 扩容机制

默认10,满时扩容,扩容为原来的1.5倍。

3、guava cache 阻塞原理

被动过期 load方法加锁,只能一个加载。

4、rocketmq 事务消息 分布式事务

5、限流算法 sentinel,令牌桶、漏桶 使用哪种(滑动窗口)

6、ump监控原理了解一下。

头条面试

1、nio 异步 epoll机制。为什么突破1024限制。 io多路复用。

poll 使用链表

2、redis:内存、单线程、无锁、nio。
3、redis扩容机制,一致性哈希、哈希槽。扩容如何保证数据准确性。 zset数据结构,调表,有时候是跳表。

扩容通过move重定向 zset 底层实现:ziplist 个数超过128 大小64字节 skiplist

4、统计单词个数。

按照单词hash,分成多个文件 每个文件计算topk(折半、快排、堆) 合并

5、单调栈 给的一个无序正整数数组,找出数组中每个元素右边第一个比它大的元素,没有输出-1 输入: [4, 3, 4, 5, 1, 2]
输出: [5, 4, 5, -1, 2, -1]

        Stack<Integer> stack = new Stack<>();
        int[] arr = {4, 3, 4, 5, 1, 2};
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            if (!stack.isEmpty() && arr[i] < arr[stack.peek()]) {
                stack.push(i);
                continue;
            }
            while (!stack.isEmpty() && arr[i] > arr[stack.peek()]) {
                res[stack.pop()] = arr[i];
            }
            stack.push(i);
        }
        while (!stack.isEmpty()) {
            res[stack.pop()] = -1;
        }
        System.out.println(Arrays.toString(res));

美团面试

1、guava cache 源代码。
3、架构准备。 6、项目。架构性问题。 7、netty-nio:模型、线程。 io模型。 select poll epoll 非阻塞 家庭号项目准备一下 paas化准备一下 jimdb jsf ducc ump原理了解一下

数据补偿 家庭号补偿研究一下。 最终一致性 jimdb:主从。选举。

腾讯面试

1、分布式事务 两阶段提交、TCC、事务消息 2、缓存数据库一致性 先写数据库,后删除缓存;延迟双删;过期时间短一些;binlog删除。 3、redis主从 高可用原理,淘汰策略
集群,主从切换。 4、tomcat参数设置

maxThreads -- tomcat接收客户端请求的最大线程数,也就是同时处理任务的个数,它的默认大小为200;一般来说,在高并发的I/O密集型应用中,这个值设置为1000左右比较合理

maxConnections 这个参数是指在同一时间,tomcat能够接受的最大连接数。对于Java的阻塞式BIO,默认值是maxthreads的值;如果在BIO模式使用定制的Executor执行器,默认值将是执行器中maxThreads的值。对于Java 新的NIO模式,maxConnections 默认值是10000,所以这个参数我们一般保持不动即可

acceptCount -- 当线程数量达到上面设置的值,所能接受的最大排队数量。超过了这个值,请求就会被拒绝。我一般会设置成和maxThreads设置成一样大的

minSpareThreads -- 一直处于活跃状态的线程数

5、spring 启动 spring boot启动原理 依赖注入 ioc 生命周期:容器, boot: 6、事物注解原理 spring。 动态代理 7、超时策略
1000ms一般
8、请求数据库流程。 连接、缓存、解析、优化、执行 9、innodb保证一致性与隔离型 隔离性:mvcc、锁 原子性:undo log 持久性:redo log 10、kafka zk存放数据 broker信息、topic 分区、副本,consumer信息。 元信息 11、redis mysql mq spring rpc spring mvc

12、日志快1倍原理 log4j2
行号:但是,请注意,建立运行时的堆栈跟踪,对JVM来说,是一项非常大的开销!

13、内存泄露排查方法 jmap,到处dump日志,mat分析

14、接口优化措施
缓存、异步、日志、线程池 方法:监控、压测

15、mysql锁类型 死锁
共享锁、排它锁 行锁、表锁、间隙锁(范围加锁),解决幻读。 死锁:相互等待。 结论:中间件原理不清楚

美团面试

1、降级工具限流 2、spring 过滤器 拦截器 执行顺序。

过滤器 - 拦截器 - 切面

1.过滤器是servlet中的对象,拦截器是SpringMVC框架中的对象,即脱离了框架后拦截器将无法使用

2.过滤器是实现Filter接口的对象,拦截器是实现HandlerInterceptor

3.过滤器是用来设置request、response的参数、属性的,侧重对数据过滤的、拦截器是用来验证请求的,能截断请求。

4.过滤器是在拦截器之前先执行的

5.过滤器是tomcat服务器创建的对象,拦截器是SpringMVC容器创建的对象

6.过滤器是一个执行时间点、拦截器有三个执行时间点

7.过滤器可以处理jsp、js、html等等;拦截器是侧重拦截对controller的对象。如果你的请求不能被DispatcherServlet接收,这个请求就不会执行拦截内容

8.拦截器拦截普通类方法执行,过滤器过滤servlet请求响应

3、threadlocal主线程 线程池参数传递 注意删除

4、算法二叉树 左看右看
5、楼层配置化 6、rpc自动降级 限流工具
7、迁移过程中不一致问题 redis?重定向

8、项目:活跃用户

美团二面

1、5分钟内取消订单超过3次,标记为下架。 2、索引 大于 等于 排序 3、栈实现队列
4、jmq原理 了解一下

面试提纲

  • 1.基础部分:
    集合:
    HashMap,ConcurrentHashMap,HashTable
    ArrayList,LinkedList,Vector
    设计模式:单例模式,适配器,装饰器,模板,工厂,策略
    设计原则: 单一职责、里式替换、迪米特法则、接口隔离、依赖倒置、开闭原则 多线程/线程池: 线程池,同步,CAS, 锁,并发工具包
    JVM/GC调优/类加载机制: 加载 验证 准备 解析 初始化 内存模型,垃圾回收算法,调优策略及命令

  • 2.框架部分
    Spring:
    ioc aop 动态代理 源码,事务传播
    SpingBoot/SpringCloud
    Mybatis:源码

  • 3.工具类
    MAVEN
    GIT

  • 4.中间件
    Redis:数据类型,分布式锁,缓存更新策略,集群模式,哨兵,持久化,主从同步, 槽指派
    /Mysql,索引,分库分表,事务隔离级别,主从架构,读写分离
    /MQ,使用场景,作用,重复消费,失败重试,顺序消息,事务消息,消息持久化
    /ES:技术选型,使用场景,倒排索引,建索引的优化
    /Zookeeper:应用场景,配置中心,分布式锁,调度,原理选举
    /Netty:NIO\BIO,多路复用
    /Dubbo:rpc框架原理
    /Nginx:负载均衡 反向代理 限流 缓存
    /Tomcat: 类加载机制 7/8区别

  • 5.网络
    http/https,tcp/ip,socket

  • 6.分布式理论
    CAP\BASE,分布式事务,分布式锁,幂等性

  • 7.网关,限流,熔断,降级,安全。Hash,一致性hash。

  • 8.负载均衡相关
    K8s,docker。系统设计,组件设计,通用设计"

      		、、