1.工厂模式
工厂模式是一种创建型设计模式,旨在通过将对象的创建过程与其使用分离。
简单工厂模式:又叫静态工厂方法,由一个工厂类根据参数决定创建哪种具体类的实例
工厂方法模式:定义一个用于创建对象的接口,将实例化推迟到子类
抽象工厂模式:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定具体类
2.策略模式
策略模式是一种行为设计模式,通过将算法的实现从具体业务中分离出来,让不同的算法可以独立地变化和复用。
结构:
- 上下文类:持有对策略接口的引用,负责调用算法的接口,不负责具体实现(有一个构造方法,可以确定引用的策略)
- 策略接口:定义算法方法的接口
- 具体策略类:实现策略接口,提供具体的算法
3.http和websocket,为什么选择websocket
1.连接模式
http采用短连接,每次连接都要建立新的连接
websocket采用长连接,建立连接后,客户端和服务器保持持续的双向连接
2.通信方式
http是单向通信的,只能由客户端发起请求,服务器响应
websocket是双向通信,允许客户端二哈服务器之间保持持续的双向连接
3.协议层次
http是基于请求-响应模式的引用层协议
websocket最初使用http进行握手,是全双工通信协议
4.数据传输效率
http:每次请求都会携带大量的头部信息(cookie,user-agent),数据开销大
websocket:握手成功后,数据传输开销小,数据包头部信息非常轻量
5.实时性
http:是基于请求-响应模式,实时性较差
websocket:服务器可以主动推送信息到客户端,实时性较强
4.hashmap哈希冲突是怎么解决的,红黑树和链表的转换,为什么用红黑树
解决有两种方法,一种是拉链法,一种是红黑树
在java8之前,hashmap采用的是链表,在java8之后,当链表的长度超过一定阙值(默认是8),链表会转为红黑树。
红黑树的使用原因:红黑树的查询、插入和删除的时间复杂度是O(log n),相比与链表O(n),查询效率更高,尤其是当冲突较多时,使用红黑树能显著提升性能
红黑树和链表的转换:当哈希桶中的链表长度超过8,会转化为红黑树
当桶中的元素小于6时,会将红黑树还原为链表
为什么选择红黑树:
自平衡性:保证了树的高度在最坏的情况下也是O(log n)
高效的插入和删除:相比与其他平衡树,红黑树的插入和删除较为简单,红黑树对平衡性的要求相对较低,只要求大致平衡
复杂度平衡:红黑树在插入、删除和查找都保持了O(log n)
5.hashmap是线程安全的吗,替代的是什么,为什么是线程不安全的
HashMap是线程不安全的:
- 并发修改会导致数据不一致,比如丢失更新(两个线程同时插入相同的键会被覆盖)
- 扩容的死循环问题:如果多个线程同时触发扩容,有可能导致链表结构被破坏,从而出现死循环。java 7 中在并发扩容可能出现环形链表问题
- 非原子操作:无法包装多个线程同时访问的正确
替代方案:ConcurrentHashMap
java8之前使用分段锁,通过将哈希桶分成多个段,并为每一个段设置一个独立的锁。
在java8之后,通过CAS操作和分段锁的结合。
6.可重复度级别,与读已提交的区别,mvcc的时机
可重复读:确保在一个事务中,无论何时读取相同的记录,结果都是一致的,即使有其他事务在并发地修改数据
读已提交:只保证每次读取到的是已经提交的数据,但不保证在同一个事务中,读取同一行的值是一致的。
MVCC的应用时机:
可重复读:mvcc保证在同一个事物中,读取到的都是事务开始的快照(即事务在启动的一个数据版本)
读已提交:mvcc在每次读取都只读取已经提交的最新版本数据
7.string的拼接
String q = "ab";
String a = "a";
String b = "b";
String c = "a" + "b";
String d = a + b;
其中q是在常量池中,对于c,这一拼接操作是发生在编译期,编译期在编译时就会变成“ab”直接放入常量池,对于d,是在运行时拼接的字符串,java会用StringBuilder进项拼接,拼接后会自动生成一个新的字符串对象,等同与new StringBuilder().append(a).append(b).toString();
8.try catch
try可以不捕获错误,直接执行finally的代码
9.mysql什么时候会加表锁,行锁
MySQL锁、加锁机制(超详细)—— 锁分类、全局锁、共享锁、排他锁;表锁、元数据锁、意向锁;行锁、间隙锁、临键锁;乐观锁、悲观锁-腾讯云开发者社区-腾讯云 (tencent.com)
10.消息队列如何防止消费同一条数据,如何防止重复发送
MQ 有可能发生重复消费,如何避免,如何做到幂等-腾讯云开发者社区-腾讯云 (tencent.com)
11.前后端,中间件实现一个排行榜,只会显示前五的交易量,但是会一直交易,用户很多。
4、场景题系统设计题很简单,直接背套路!_牛客网 (nowcoder.com)
使用消息队列,每当用户进行交易,就推送交易信息
后台消费这些信息并进行交易量的更新
消费信息时可以批量消费,进行批量更新
使用定时任务比如每隔十分钟计算当前排行榜并更新到Redis
12.堆和栈是线程安全的吗,怎么设置堆的内存大小
栈:每个线程都有自己独立的栈空间,所以是线程安全的
堆:是一个全局共享的内存区域,是线程不安全的
在JVM中,堆的内存可以用参数来控制:
-Xms:设置堆的初始内存大小
-Xmx:设置堆的最大内存大小
设置较大的初始堆可以减少频繁的内存分配,从而提升程序启动的性能,设置堆的最大值可以确定程序不会占用过多的内存,同时防止堆内存溢出。