面试题day6
招银网络
-
自我介绍
-
实习项目的具体情况
-
ES的具体操作
-
Redis的常用数据结构
- string 缓存 session共享 分布式锁 int embstr简单动态字符串 简单动态字符串
- list 消息队列 ziplist linkedlist
- hash 存储对象 ziplist hashtable
- set 集合 intset hashtable
- zset 排行榜 ziplist skiplist
-
如何对用户画像标签做缓存
-
ArrayList、Linkedlist
底层 数组 双向链表
不同步 线程不安全
数组扩容
-
HashMap、HashTable
是否线程安全
效率 空值
链表散列+红黑树
-
SpringCloud的具体组件
服务注册中心、配置中心、断路器、网关路由、负载均衡
-
项目中网关的具体实现及作用
-
线程、线程池的理解
程序执行任务最小单位
管理线程的池化技术 降低资源消耗 提高响应效率
-
JVM内存模型、垃圾收集算法、判断是否可回收
堆 直接内存 方法区 本地方法栈 虚拟机栈 程序计数器
分代 复制 压缩 清除
引用计数法 可达行算法
静态变量 常量 本地方法栈 虚拟机栈
类加载 对象创建
-
手撕:实现String的equals()
对比地址 对比是否为子类 对比数组长度 对比每个字符串
-
性能优化(SQL、并发)
sql语句
-
慢SQL优化
explain
-
水平分库分表场景
-
垂直分表:把一个宽表的字段按照访问频率、是否是大字段的原则拆分为多个表,这样既能使业务清晰,还能提高部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失。
-
垂直分库:把多个表按照业务的耦合性来进行分类,分别存放在不同的数据库中,这些库可以分布在不同的服务器,从而使访问压力被分摊在多个服务器,大大提高性能,同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。
-
水平分库:把一个表的数据(按数据行)分到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同的服务器,从而使访问压力被多服务器负载,提升性能。它不仅需要解决跨库带来的问题,还需要解决数据路由的问题。
-
水平分表:把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表的数据只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。
-
-
IO密集型优化
线程池优化参数
-
和技术经理方案不同如何应对
-
团队开发最重要的是什么
-
敏捷开发的理解
美团
-
最长连续子序列
-
GC算法、垃圾收集器、CMS
parnew+cms g1
parallel+parallelold
-
对象头、markword
存储锁标志位 锁消息
同一线程再次进入 偏向锁 线程id
不同线程竞争 轻量级锁 lockrecord双向绑定
cas10+ 重量级锁 互斥量指针
-
类加载器、准备和初始化在干什么
此时是为类变量(静态变量或者静态代码块)分配内存并进行初始化的阶段。这些变量都是分配在方法区的,而不是在堆中。并且这里的初始化指的是数据类型的零值,对于基本数据类型就是0,对于引用类型则是 null。
在准备阶段被初始化为零值的那些变量会在初始化阶段赋值为在代码中定义的值。
-
集合类的顶级接口
Collection Map
-
HashMap原理、扩容
(n-1)^hash
-
HashSet、Hashtable
基于hashmap
-
ReentrantLock、AQS
类似mesa模型
state flfo队列 condition队列
-
synchronized的改进
管程 1.7用偏向锁 轻量级锁优化
-
wait-notify、线程的状态
wait()方法是Object 类的方法,它的作用是使当前执行wait()方法的线程等待,在wait()所在的代码行处暂停执行,并释放锁,直到接到通知或中断。
notify()方法用来通知那些可能等待该锁的其他线程,如果有多个线程等待,则按照执行wait方法的顺序发出一次性通知,使得等待排在第一顺序的线程获得锁。
出生 死亡 运行 等待 超时等待 阻塞
-
引擎、索引、undo log、bin log、redo log
myisam innodb
b+树
是否支持行级锁
是否支持事务
是否支持外键
索引底层
mvcc基于undolog
-
隔离级别、幻读
ru rc rr s
读时插入删除提交事务
RC隔离级别中:
- 多次快照读使用不同一致性视图,出现幻读;
- 当前读(只有Record lock)时,读最新版本,会阻塞删除操作,当不阻塞插入,与多次快照读一样出现幻读;
RR隔离级别中:
- 快照读中:可避免部分幻读,但两次快照读中间有更新语句(包含其它事务提交的插入数据-在第一次快照读后开启并提交),第二次快照读则出现幻读;RR+快照读例子
- 当前读中:默认使用next-lock实现的行锁,不会导致幻读;
-
慢查询
-
发现慢SQL
show processlist
查询当前慢sql的语句- 开启慢日志
set global slow_query_log=1;
-
优化慢SQL
explain sql语句
的方式查看慢sql的执行计划- type 表示表的连接类型
- key 表示实际使用的索引
- rows 扫描出的行数(估算的行数)
- 分析该SQL语句索引使用情况,全表扫描情况
-
-
spring aop的实现机制?动态代理的实现机制?
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理。常用于计算接口运算时间、记录日志。
-
Redis用来干什么?多大规模?
缓存、session一致性、分布式锁、消息队列、计数器
10万qps
美团
-
场景题:一个时间段、年龄 > 50 怎么建立索引
联合索引
-
索引下推是什么?
索引过滤数据
-
覆盖索引是什么?
索引查询即可拿到结果,无需回表
-
JVM:yong GC 的发生时间?发生频繁,发生时间长的原因和解决方案?
新生代堆满
配置过小,代码问题
jmap堆 jstack线程
-
CMS的过程?怎么标记垃圾的?三色标记法?G1的区别?
初始标记 并发标记 重新标记 并发清除
初始标记 重新标记
三色标记最大的好处是可以异步执行,白色,灰色,黑色
-
CMS什么时候会STW?为什么要STW?
初始标记为什么需要STW?
因为初始标记标记的是GC Root,而GC Root容易变动,比如栈帧中的本地变量表。所以需要STW。
重新标记为什么需要STW?
因为在重新标记之前是并发标记,在并发标记的期间会出现漏标和多标的对象,所以为了修正这部分对象,需要在重新标记期间STW。 -
手写多线程生产者消费者
-
-
Synchronized
public class SynchronizedData { private Integer number = 0; private Integer max = 10; public synchronized void put() throws InterruptedException { if (number < max) { number++; notifyAll(); } else { wait(); } } public synchronized void get() throws InterruptedException { if (number > 0) { number--; notify(); } else { wait(); } } }
-
ReentrantLock
public class ReentrantLockData { private Integer number = 0; private Integer max = 10; private Lock lock = new ReentrantLock(); private Condition putCondition = lock.newCondition(); private Condition getCondition = lock.newCondition(); public void put() throws InterruptedException { lock.lock(); if (number < max) { number++; getCondition.signal(); } else { putCondition.await(); } lock.unlock(); } public void get() throws InterruptedException { lock.lock(); if (number > 0) { number--; putCondition.signal(); } else { getCondition.await(); } lock.unlock(); } }
-
BlockingQueue
public class BlockingQueueData { BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(10); public void put() throws InterruptedException { blockingQueue.put("产品"); } public void get() throws InterruptedException { blockingQueue.take(); } }
-
Semaphore
- 同步信号量
- 用途:防止被抢占 初始为空
- 值的含义:值为资源可以使用的个数,信号量小于0,则线程进行等待,信号量大于0,表示可用资源个数。初始值0.
- 互斥信号量
- 用途:对临界区上锁 初始为满
- 值的含义:只有两个值0或1,0表示资源正在被占用,线程等待。1表示,资源没有被使用,线程可以进入。初始值为1
public class SemaphoreData { Semaphore provider = new Semaphore(10); Semaphore consumer = new Semaphore(0); Semaphore mutex = new Semaphore(1); private Integer number = 0; public void put() { try { provider.acquire(); mutex.acquire(); number++; } catch (InterruptedException e) { e.printStackTrace(); } finally { mutex.release(); consumer.release(); } } public void get() { try { consumer.acquire(); mutex.acquire(); number--; } catch (InterruptedException e) { e.printStackTrace(); } finally { mutex.release(); provider.release(); } } }
- 同步信号量
-
-
项目中最大的难点?有多少张表?有哪些表?有哪些服务?
-
kafka用来干什么?
-
Redis用来干什么?过期时间怎么设置?
-
遍历二叉树
-
删除所有重复的节点
-
Spring aop的原理?
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理。常用于计算接口运算时间、记录日志。
-
jdk 和 cglib的区别?
接口实现和无接口实现
-
DDD,DDD有了解吗?
麦吉太文
-
介绍一下项目功能,只说了功能,没有延伸
-
问个人优势是什么?希望以后在公司干什么方向的?
-
你的项目是 springboot做的为什么用springboot?
-
aop ioc介绍一下?
Spring IOC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。 IOC 容器负责创建对象,将对象连接在一起,配置这些对象,并从创建中处理这些对象的整个生命周期,直到它们被完全销毁。
-
用过mybatis吗?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
-
说几种熟悉的设计模式?
单例模式 工厂模式 代理模式
-
讲一下事务
acid 原子性 一致性 隔离性 持久性
-
讲一下Mysql索引
b+树
锁 事务 外键 mvcc 聚簇索引 场景
-
你的项目里用索引了吗?
-
你的项目里存了多少数据?如果让你存1亿条数据你怎么办?
分库分表
-
分库分表会遇到什么问题?怎么解决?
分布式id问题 用redis,雪花算法解决
-
如果你发现查询很慢怎么办?(答:explain)
-
常见数据结构有什么?
Arraylist
Linkedlist
Hashmap
-
实现接口,继承抽象类区别?
-
单继承多实现
-
抽象类可以有成员变量,而接口中只可有常量final
-
抽象类可有有成员方法用(public、protected和default),而接口中只有抽象方法(public)
-
抽象类可以有构造器,而接口不能有构造器
-
-
数组链表区别
底层实现
插入删除复杂度
适合场景
内存大小
-
说说jvm?(说了内存区域和垃圾回收)
堆 直接内存 本地方法栈 虚拟机栈 方法区 程序计数器
加载 连接(验证准备解析) 初始化 使用 回收
-
看过源码吗?String源码知道吗?
String类是final char[]数组实现的,注意这个是java8的时候,java9变成了byte[]
-
因为上一个问题,面试官问我知道java9的时候有什么变化吗?
java9改了String 类的实现(byte)
-
平时用jdk哪个版本?
-
在浏览器中输⼊url地址 ->>会发生什么过程?
缓存 dns ip tcp https
-
反问:一共几轮面试? 一共两轮