1018 数字马力一面,秒过,已拒二面
timeline:1008 笔试,1010 AI 面,1014 邮件约一面
1018 上午 10:45一面,下午 15 点收到二面面试预约,已拒。
问题列表
八股偏多,看样子是有题单。大概时长 38 分钟。
1. 请展开聊一下关于分布式锁的原理和应用场景的一些理解。
2. 如果想用 SQL 去实现分布式锁的话,有什么方式吗?
3. 你对 MySQL 的行锁有了解吗?
4. 在 MySQL 里面,用 SQL 去实现行锁的话,怎么实现?
5. 在你的实习过程中,或者在平常学习的过程中遇到的一个最大的困难是什么?
6. 如果给到你一个需求,你会怎么样去分析它的具体实现?有什么分析方法吗?
7. 从架构上去思考,怎么样设计,或者说怎么样实现这个需求?
8. 在技术选型上有什么思考吗?
9. 怎么识别和拦截请求,不让它直接打到后端服务?
10. Java 面向对象有哪些特性?
11. Java 的异常体系可以简单介绍一下吗?
12. HashMap 的 put 过程可以简单描述一下吗?
13. JVM 运行时候有哪些数据区域?
14. 双亲委派机制可以简单介绍一下吗?
15. 线程池的参数有哪些?
16. 线程池的拒绝策略可以大概讲一下吗?
17. CAS 思想是什么?
18. 事务有哪些特性?
19. MySQL 的 InnoDB 和 MyISAM 引擎有什么区别?
20. 用 B+ 树索引有什么优点?
21. 获取所有主流电商平台的支付方式,你有什么设计思路?
22. 如果通过接口调用获取支付方式,怎么设计?
23. 用什么设计模式来设计获取支付方式的功能?
24. 优化接口调用效率有什么思路?
25. 你有什么问题想问我吗?
GPT 解答
自己回答的可能不完整,所以让 GPT 回答一下方便大家对照着看。
1. 请展开聊一下关于分布式锁的原理和应用场景的一些理解。
解答:
分布式锁是一种用于在分布式系统中控制对共享资源的访问的机制。其原理主要包括以下几点:
- 唯一性 :锁需要是唯一的,确保同一时间只有一个客户端能持有锁。
- 超时机制 :为了防止死锁,锁需要设置超时时间,确保当客户端崩溃或网络分区时,锁能自动释放。
- 可重入性 :某些场景需要支持同一客户端多次加锁和解锁。
- 高可用 :锁服务需要高可用,避免单点故障。
应用场景 :
- 分布式事务 :确保多个服务之间的数据一致性。
- 资源控制 :控制对共享资源的访问,如文件、数据库记录等。
- 任务调度 :确保某个任务在同一时间只能被一个节点执行。
2. 如果想用 SQL 去实现分布式锁的话,有什么方式吗?
可以使用数据库的行锁或表锁来实现分布式锁。常见的方法是通过 SELECT ... FOR UPDATE
或 INSERT
操作来实现:
- 基于
SELECT ... FOR UPDATE
:通过对一行数据加锁来实现,当锁定行存在时,其他客户端无法获取锁。 - 基于
INSERT
:通过尝试插入一个唯一键值来获取锁,成功插入表示获取锁,失败表示锁已被占用。
-- 获取锁 INSERT INTO distributed_lock (lock_name, lock_value) VALUES ('my_lock', 'unique_value'); -- 释放锁 DELETE FROM distributed_lock WHERE lock_name = 'my_lock' AND lock_value = 'unique_value';
3. 你对 MySQL 的行锁有了解吗?
解答:
MySQL 的行锁是通过存储引擎(如 InnoDB)来实现的。InnoDB 的行锁是基于索引实现的,如果没有索引,InnoDB 会锁定全表。行锁的类型主要有两种:
- 共享锁(S 锁) :允许事务读取一行数据,但不允许修改。
- 排他锁(X 锁) :允许事务读取和修改一行数据,同时阻止其他事务访问该行。
4. 在 MySQL 里面,用 SQL 去实现行锁的话,怎么实现
可以使用 SELECT ... FOR UPDATE
和 SELECT ... LOCK IN SHARE MODE
来实现行锁:
13. Java 面向对象有哪些特性?
解答:
Java 面向对象编程具有以下四个主要特性:
- 封装 :将数据(属性)和行为(方法)封装在对象内部,控制对数据的访问。
- 继承 :通过继承,子类可以复用父类的属性和方法,实现代码重用。
- 多态 :允许对象在不同的上下文中表现出不同的行为,通过方法重载和方法重写实现。
- 抽象 :通过抽象类和接口,定义一组方法的集合,而不具体实现,具体实现由子类完成。
14. Java 的异常体系可以简单介绍一下吗?
解答:
Java 的异常体系分为两大类:
Checked Exception
(受检查异常)和 Unchecked Exception
(未经检查异常)。
- 受检查异常 :继承自
Exception
类,必须在编译时处理(通过try-catch
或throws
声明)。例如:IOException
,SQLException
。 - 未经检查异常 :继承自
RuntimeException
类,不强制要求处理。一般是程序逻辑错误导致的,例如:NullPointerException
,ArrayIndexOutOfBoundsException
。
15. HashMap 的 put 过程可以简单描述一下吗?
解答:
HashMap 的put
过程主要包括以下几个步骤:
- 计算 hash 值 :根据键的
hashCode
计算出 hash 值,并确定存储位置。 - 检查容量 :如果当前存储已超过阈值,进行扩容。
- 插入或更新 :根据计算出的索引位置,将键值对插入到数组中;如果位置上已经有元素(发生哈希冲突),则使用链表或树结构存储。
- 返回旧值 :如果键已存在,返回旧值;否则,返回
null
。
16. JVM 运行时候有哪些数据区域?
解答:
JVM 运行时的数据区域主要包括:
- 堆(Heap) :存储对象实例和数组,所有线程共享。
- 方法区(Method Area) :存储类信息、常量、静态变量等,所有线程共享。
- 虚拟机栈(JVM Stack) :每个线程私有,存储局部变量、操作数栈、方法返回地址等。
- 本地方法栈(Native Method Stack) :每个线程私有,存储本地方法调用信息。
- 程序计数器(Program Counter Register) :每个线程私有,记录当前线程执行的字节码指令地址。
17. 双亲委派机制可以简单介绍一下吗?
解答:
双亲委派机制是一种类加载机制,其核心思想是让子类加载器在加载类之前,先委托父类加载器尝试加载。具体流程如下:
- 检查缓存 :类加载器首先检查是否已经加载过该类。
- 委派父类 :如果没有加载过,委派父类加载器尝试加载。
- 加载失败 :如果父类加载器无法加载,则由子类加载器尝试加载。
这种机制的好处是避免重复加载类,确保核心类库的安全性和稳定性。
18. 线程池的参数有哪些?
解答:
Java 的线程池(如ThreadPoolExecutor
)的主要参数有:
- corePoolSize:核心线程数,线程池中始终保持的线程数量。
- maximumPoolSize:最大线程数,线程池中允许的最大线程数量。
- keepAliveTime:空闲线程存活时间,超过这个时间,空闲线程会被终止。
- unit:时间单位,用来指定
keepAliveTime
的时间单位。 - workQueue:任务队列,用于存储等待执行的任务。
- threadFactory:线程工厂,用于创建新线程。
- handler:拒绝策略,当任务无法提交到线程池时的处理策略。
19. 线程池的拒绝策略可以大概讲一下吗?
解答:
Java 提供了四种内置的线程池拒绝策略,当任务无法提交到线程池时,会触发这些策略:
- AbortPolicy:默认策略,直接抛出
RejectedExecutionException
异常。 - CallerRunsPolicy:调用者线程执行该任务,以减缓新任务的提交速度。
- DiscardPolicy:直接丢弃任务,不予处理。
- DiscardOldestPolicy:丢弃队列中最旧的任务,然后重新尝试提交新任务。
20. CAS 思想是什么?
解答:
CAS(Compare-And-Swap,比较并交换)是一种无锁编程技术,用于实现线程安全。其基本思想是:
- 比较 :比较内存中的值是否为预期值。
- 交换 :如果是预期值,则更新为新值;否则,不进行更新。
CAS 操作是原子性的,常用于实现无锁的并发数据结构,如 AtomicInteger
。
22. MySQL 的 InnoDB 和 MyISAM 引擎有什么区别?
解答:
InnoDB 和 MyISAM 是 MySQL 的两种存储引擎,主要区别如下:
- 事务支持 :InnoDB 支持事务,MyISAM 不支持。
- 外键支持 :InnoDB 支持外键,MyISAM 不支持。
- 锁机制 :InnoDB 使用行级锁,MyISAM 使用表级锁。
- 崩溃恢复 :InnoDB 支持自动崩溃恢复,MyISAM 不支持。
- 全文索引 :MyISAM 支持全文索引,InnoDB 在 MySQL 5.6 及以上版本支持。
23. 用 B+ 树索引有什么优点?
解答:
B+ 树索引具有以下优点:
- 平衡性 :B+ 树是平衡树,所有叶子节点在同一层,查询效率稳定。
- 范围查询 :B+ 树的叶子节点通过链表相连,方便范围查询。
- 磁盘访问 :B+ 树的非叶子节点只存储键,节省空间,提高磁盘访问效率。
- 顺序访问 :B+ 树的叶子节点按顺序排列,适合顺序扫描。
24. 获取所有主流电商平台的支付方式,你有什么设计思路?
解答:
设计获取所有主流电商平台支付方式的思路如下:
- 抽象接口 :定义一个统一的支付方式获取接口。
- 平台适配器 :为每个电商平台实现适配器,负责调用平台的支付方式接口。
- 缓存机制 :使用缓存机制,减少频繁调用外部接口的次数。
- 并发处理 :使用多线程或异步处理,提高效率。
- 错误处理 :设计健壮的错误处理机制,确保获取支付方式的稳定性。
25. 如果通过接口调用获取支付方式,怎么设计?
- 工厂模式 :使用工厂模式,根据平台类型创建对应的服务实例。
public class PaymentMethodServiceFactory { public static PaymentMethodService getService(String platform) { switch (platform) { case "Amazon": return new AmazonPaymentMethodService(); case "eBay": return new EbayPaymentMethodService(); // 其他平台... default: throw new IllegalArgumentException("Unknown platform: " + platform); } } }
26. 用什么设计模式来设计获取支付方式的功能?
解答:
可以使用以下设计模式来设计获取支付方式的功能:
- 工厂模式 :用于创建不同电商平台的支付方式服务实例。
- 适配器模式 :用于将不同电商平台的支付方式接口适配到统一的接口。
- 策略模式 :用于根据不同平台选择不同的支付方式获取策略。
- 模板方法模式 :定义获取支付方式的通用流程,具体实现由子类完成。
27. 优化接口调用效率有什么思路?
解答:
优化接口调用效率的思路包括:
- 缓存 :使用缓存减少重复调用,提高响应速度。
- 异步调用 :使用异步调用减少等待时间,提高并发性能。
- 批量处理 :将多个请求合并为一个批量请求,减少网络开销。
- 负载均衡 :使用负载均衡分配请求,避免单点瓶颈。
- 超时控制 :设置合理的超时时间,避免长时间等待。
- 重试机制 :在请求失败时进行重试,提高成功率。
主要收录一部分我的笔试面试经历文章,欢迎订阅。