面试题day16
华为
Java开发
-
HashMap及其底层结构
链表散列+红黑树
(n-1)&hash
2倍扩容1.7 头插法(循环引用) 1.8 尾插法
-
快速失败
单线程
当在用迭代器(Iterator)或者增强for循环(增强for循环的底层也是迭代器)对一个集合进行遍历操作时,如果遍历的过程中集合的结构发生了变化,就会抛出并发修改异常ConcurrentModificationException。多线程
当一个线程在对一个集合进行遍历操作的时候,如果其他线程对这个集合的结构进行了修改,就会抛出并发修改异常ConcurrentModificationException。 -
避免快速失败
迭代器使用remove
使用线程安全的类
-
hashtable和Concurrenthashmap
初始长度 hashtable为11,Concurrenthashmap为16
扩容 hashtable为2n+1,Concurrenthashmap为2n
空值 hashtable不支持,Concurrenthashmap支持
底层数据结构: JDK1.7 的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟 HashMap1.8 的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
实现线程安全的方式: ① 在 JDK1.7 的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。 到了 JDK1.8 的时候已经摒弃了 Segment 的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6 以后 对 synchronized 锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在 JDK1.8 中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。 -
项目用到的设计模式
单例模式、工厂模式、代理模式
-
建造模式、装饰者模式
-
数据库的索引数据结构
B+树、hash、数组
-
spring ioc aop
-
说说Redis吧、用了什么数据结构
-
Redis的速度为什么快
-
快排
选出一个哨兵,其他元素分左右
不断递归到底层
nlogn,最坏n2(n为极值)
-
分布式锁吗
-
怎么同步的
-
动态代理吗
动态代理只有在运行时才能够确定执行对象是谁。代理可以看作是对最终调用目标的一个封装,我们能够通过操作代理对象来调用目标类,这样就可以实现调用者和目标对象的解耦合。
-
JDK和cglib的底层原理
jdk继承 cglib组合
-
AQS
一个以Node为节点实现的链表的队列(CHL队列),一个STATE标志,并且通过CAS来改变它的值
-
事务模型
acid 原子性 隔离性 持久性 一致性
-
为什么MySQL不用红黑树
红黑树是一颗平衡二叉树,数据量大的时候,树的深度也很深,如果树的深度有20层,而查找的数据在叶子节点,就要进行20次IO操作,性能低。
美团
-
聊项目
-
判断对象不再使用
引用计数法、可达性算法
-
gcroot
虚拟机栈 本地方法栈 静态变量 常量
-
垃圾回收过程
标记GC Roots,从GC Roots开始向下搜索,当对象到GC Roots都没有任何引用相连时,说明对象是不可用的,可以被回收
-
安全点和安全区域
只有在安全点和安全区域会把对象引用的相关信息给记录下来
-
跨代引用
卡表/Rset,记录脏表
-
两次minor gc存活的对象在哪
-
哪些字段适合建索引,索引失效
在经常需要搜索的列上、在作为主键的列上、在经常用在连接的列上、在经常需要根据范围进行搜索的列上、在经常需要排序order by的列上
where 条件计算、隐式计算、函数、不满做最左前缀原则、like%、select *
-
联合索引底层数据结构
联合索引是每个树节点中包含多个索引值,在通过索引查找记录时,会先将联合索引中第一个索引列与节点中第一个索引值进行匹配,匹配成功接着匹配第二个索引列和索引值,直到联合索引的所有索引列都匹配完;如果过程中出现某一个索引列与节点相应位置的索引值不匹配的情况,则无需再匹配节点中剩余索引列,前往下一个节点。
-
算法:字符串转整数(注意溢出判断)
-
反问部门:
-
基础技术架构,做内部系统的
-
SpringMVC执行流程
处理映射器、处理适配器、视图解析器
-
SpringMVC的一个Servlet
DispatcherServlet
-
Mybatis优点
把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。
封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象, 大大简化了 Java 数据库编程的重复工作。
可以结合数据库自身的特点灵活控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复杂查询。
-
Mybatis如何防止SQL注入
{}
-
Redis在项目里实现的功能
-
RabbitMQ在项目中实现的功能
-
MQ重复消费消息的解决方案(不太清楚)
-
Springboot有哪些配置文件
application.yml、bootstrap.yml
-
SpringBoot的两种配置文件的区别
加载顺序
若application.yml 和 bootstrap.yml 在同一目录下:bootstrap.yml 先加载,application.yml 后加载bootstrap.yml 用于application上下文的引导阶段。bootstrap.yml 由父Spring ApplicationContext加载。
属性覆盖问题
启动上下文时,Spring Cloud 会创建一个 Bootstrap Context,作为 Spring 应用的 Application Context 的父上下文。初始化的时候,Bootstrap Context 负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的 Environment。
-
Springboot启动时要执行一段代码如何实现
-
Redis的数据结构
-
Redis如何实现分布式锁
-
AOP有哪些注解
@Aspect:
作用:把当前类声明为切面类。@Before:
作用:把当前方法看成是前置通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。@After
作用:把当前方法看成是始终通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。@Around
作用:把当前方法看成是环绕通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。@Pointcut
作用:指定切入点表达式
属性:
value:指定表达式的内容@AfterReturning
作用:把当前方法看成是后置通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。@AfterThrowing
作用:把当前方法看成是异常通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。 -
线程实现方式
thread、runnable、callable
-
线程池的优点,几大参数,拒绝策略
降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
核心线程数、最大线程数、阻塞队列、存活时间、时间单位、线程工厂、拒绝策略
直接丢弃、丢弃最早、发起者调用、拒绝抛异常
-
什么是线程安全
线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
锁
原子类
本地变量
-
ThreadLocal了解过吗
- 每个Thread维护着一个ThreadLocalMap的引用
- ThreadLocalMap是ThreadLocal的内部类,用Entry来进行存储
- 调用ThreadLocal的set()方法时,实际上就是往ThreadLocalMap设置值,key是ThreadLocal对象,值是传递进来的对象
- 调用ThreadLocal的get()方法时,实际上就是往ThreadLocalMap获取值,key是ThreadLocal对象
- ThreadLocal本身并不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value。
-
ThreadLocal应用场景
-
如何在事务中开启一个新的事务
事务传播行为
-
事务传播属性
- REQUIRED:需要事务 如果外层没有事务 则开启新的事务 如果外层存在事务,则融入当前事务
- SUPPORTS:支持事务 如果外层没有事务 不会开启新的事务 如果外层存在事务,则融入当前事务
- REQUIRES_NEW:每次开启新的事务 如果外层存在事务,外层事务挂起,自己开启新的事务执行,执行完成,恢复外部事务继续执行
- NOT_SUPPORTED:不支持事务 如果外层存在事务,外层事务挂起,自己以非事务方式执行,执行完成,恢复外部事务执行。
- NEVER:不能有事务 存在事务报错
- MANDATORY:强制事务 没有事务报错
- NESTED:嵌套事务 事务之间可以嵌套运行 数据库 oracle mysql 不支持
-
ThreadLocal怎么防止内存泄漏
-
JMM内存模型
主内存、工作内存、cpu
原子性、可见性、有序性
-
数据库中密码的保存
md5+hash+salt
-
了解什么其他的加密算法
-
反转链表
递归法、使用尾插
遍历法、使用头插
-
了解SpringCloud之类的吗
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!