面试真题之收钱吧问题与总结

600 阅读3分钟

收钱吧面试技术笔记​编辑

1. 线程安全相关

什么叫线程安全  
线程安全指的是多个线程访问同一个资源时,不会引起数据不一致或者程序异常的行为。实现线程安全的方式有:

  • 互斥锁(synchronized、ReentrantLock)  
  • 原子操作(AtomicInteger 等)  
  • 线程安全的数据结构(ConcurrentHashMap)  

2. Java 基本类型及包装类

基本类型包装类说明
byte    Byte  -
short    Short  -
int      Integer-
long    Long  -
float    Float  -
double  Double-
char    Character-
boolean  Boolean-

使用场景  

  • 当需要使用泛型(Collection 只能存对象)  
  • 需要对象方法(如 Integer.parseInt())  
  • 与反射或框架交互  

包装类线程安全吗?  

  • 不可变对象 → Integer、Long、String 等都是线程安全的  
  • 注意:线程安全只针对对象不可变性,引用本身的赋值不是线程安全的  

除了不能修改值,还不能修改什么  

  • 对象的内部状态不可变  
  • 没有 setter 或修改内部数组/集合的接口  

​编辑

3. String 与线程安全

为什么 split 方法线程安全  

  • String 是不可变对象  
  • split 返回的是新的数组或字符串,不会修改原字符串  
  • 线程安全来源于对象不可变性  

4. 线程池

线程池主要参数(以 Java ThreadPoolExecutor 为例)  

corePoolSize:核心线程数  
maximumPoolSize:最大线程数  
keepAliveTime:非核心线程空闲存活时间  
unit:时间单位  
workQueue:任务队列  
threadFactory:线程创建工厂  
handler:拒绝策略  

创建线程时,是先放队列还是先放线程  

  • 如果当前线程数 < corePoolSize → 创建核心线程  
  • 超过 corePoolSize → 放入队列  
  • 队列满 → 创建非核心线程(直到 maximumPoolSize)  
  • 超过 maximumPoolSize → 执行拒绝策略  

IO 密集型线程池参数设置  

  • 核心线程数可以设大一些(CPU × 2 或更多)  
  • 使用 LinkedBlockingQueue 避免阻塞  

保证核心线程不销毁  

  • allowCoreThreadTimeOut(false)(默认 false)  

5. Java POJO 与 HashCode/Equals

POJO 是否要重写 hashCode 和 equals  

  • 必须重写:存入 HashMap、HashSet 或需要按内容比较对象时  
  • 不必要:只是普通存储或不比较对象的场景  

除了判断相等情况下,是否有必要重写  

  • 可以不重写,除非你需要放入 hash 系列集合或者基于对象内容比较  

6. 数组与字符串

数组 length 和字符串 length 区别  

  • 数组:arr.length → 属性  
  • 字符串:str.length() → 方法  

数组元素如何存储  

  • 数组连续存储在堆中,元素可以是基本类型或对象引用  ​编辑

7. 反射与类加载器

反射  

  • 获取类信息:Class<?> clazz = Class.forName("com.example.MyClass");  
  • 创建对象:clazz.newInstance()  
  • 调用方法、获取字段、修改字段  

ClassLoader 和 Class 区别  

  • Class:类的字节码对象,Java 层抽象  
  • ClassLoader:负责加载字节码文件到 JVM  
  • 两者都可以用于加载类,但 ClassLoader 更底层  

8. 单例模式

常见场景  

  • 全局配置对象  
  • 线程池、缓存管理  

最简单实现(懒汉/饿汉)  

// 饿汉  
public class Singleton {  
    private static final Singleton INSTANCE = new Singleton();  
    private Singleton() {}  
    public static Singleton getInstance() {  
        return INSTANCE;  
    }  
}  

9. HTTP 与 TCP

HTTP 版本区别  

版本特点
1.0  每次请求创建新 TCP 连接
1.1  支持 Keep-Alive、管道化
2.0  二进制帧、多路复用、头部压缩

TCP 实现 HTTP  

  • 理论上用 Socket 建立 TCP 连接,手动发送 HTTP 请求报文  
  • Java 示例略(面试一般不要求完整实现)  

10. 数据库 ACID 与事务

ACID  

  • Atomicity 原子性  
  • Consistency 一致性  
  • Isolation 隔离性  
  • Durability 持久性  

事务隔离级别  

隔离级别现象
READ UNCOMMITTED脏读
READ COMMITTED不可重复读
REPEATABLE READ幻读
SERIALIZABLE串行化

不同隔离级别下锁  

  • 读锁、写锁、间隙锁(防止幻读)  

千万级数据表索引策略  

  • 自增 ID → 主键索引  
  • 年龄 → 可加普通索引,考虑范围查询  
  • 不建议频繁变化字段建索引  

事务传播机制  

  • 默认:REQUIRED  
  • 并发事务修改:数据库通过锁和隔离级别解决,也可通过乐观锁/悲观锁在代码控制