一、final的用法
- 修饰类:
final修饰的类不能被继承。例如,String类是final的,无法通过继承扩展。 - 修饰方法:
final修饰的方法不能被子类重写(Override)。用于防止子类修改父类的核心逻辑。 - 修饰变量:
- 基本数据类型:值不可变。
- 引用数据类型:引用地址不可变,但对象内容可以修改。
- 常见场景:常量定义(如
public static final int MAX_VALUE = 100;)。
二、List、Map、Set的区别
- List:
- 特点:有序、可重复。
- 常见实现:
ArrayList(基于数组,查询快)、LinkedList(基于链表,增删快)。
- Map:
- 特点:键值对存储,键唯一,值可重复。
- 常见实现:
HashMap(无序)、TreeMap(按键排序)、LinkedHashMap(按插入顺序)。
- Set:
- 特点:无序、不可重复。
- 常见实现:
HashSet(无序)、TreeSet(排序)、LinkedHashSet(按插入顺序)。
三、在并发场景下,怎么保证顺序执行
- 使用锁机制:
ReentrantLock:通过显式加锁和解锁控制线程顺序。synchronized:通过同步代码块或方法保证同一时间只有一个线程执行。
- 信号量:使用
Semaphore或CountDownLatch控制线程执行顺序。 - 线程池:通过
SingleThreadExecutor确保任务按提交顺序执行。
四、在分布式场景下,怎么保证客户端顺序执行
- 分布式锁:
- 使用Redis或Zookeeper实现分布式锁,确保同一时间只有一个客户端操作资源。
- 消息队列:
- 使用Kafka或RabbitMQ的分区机制,确保同一主题的消息按顺序消费。
- 幂等性设计:
- 在高并发场景下,确保操作具有幂等性,避免重复处理。
五、Java怎么开启多线程
-
继承Thread类:
class MyThread extends Thread { public void run() { System.out.println("Thread running"); } } new MyThread().start(); -
实现Runnable接口:
class MyRunnable implements Runnable { public void run() { System.out.println("Runnable running"); } } new Thread(new MyRunnable()).start(); -
使用线程池:
ExecutorService executor = Executors.newFixedThreadPool(2); executor.submit(() -> System.out.println("Task running")); executor.shutdown();
六、HashMap的数据结构和扩容过程
- 数据结构:
- JDK 1.8之前:数组+链表。
- JDK 1.8之后:数组+链表/红黑树(链表长度超过8时转换为红黑树)。
- 扩容过程:
- 默认初始容量为16,负载因子为0.75。
- 当元素数量 > 容量 * 负载因子时,扩容为原容量的2倍。
- 扩容时重新计算哈希值并分配到新数组中。
七、try-catch-finally-throw-throws分别干啥
- try:捕获可能抛出异常的代码块。
- catch:捕获并处理特定类型的异常。
- finally:无论是否发生异常,都会执行的代码块(常用于释放资源)。
- throw:手动抛出异常(如
throw new Exception("Error");)。 - throws:声明方法可能抛出的异常类型(如
void method() throws IOException {})。
八、直接获取Class对象的方法
Class.forName("全限定类名"):动态加载类。对象.getClass():获取对象的运行时类。类名.class:直接获取类的Class对象。
九、反射实现原理和优缺点
- 实现原理:
- 通过
Class对象获取类的构造器、方法、字段等信息,并动态调用。
- 通过
- 优点:
- 灵活性高,支持动态加载和调用类。
- 缺点:
- 性能开销大,破坏封装性,可能存在安全隐患。
十、IoC原理和实现方式
- 原理:
- 控制反转,将对象的创建和依赖注入交给容器管理。
- 实现方式:
- 工厂模式:通过工厂类创建对象。
- 注解:如
@Autowired自动注入依赖。 - XML配置:通过XML文件配置Bean及其依赖关系。
十一、Minor GC和Full GC触发条件
- Minor GC:
- 触发条件:Eden区满时触发。
- 优化策略:调整新生代大小(如
-Xmn参数)。
- Full GC:
- 触发条件:老年代空间不足、Metaspace空间不足、显式调用
System.gc()。 - 优化策略:减少对象晋升到老年代的频率。
- 触发条件:老年代空间不足、Metaspace空间不足、显式调用
十二、InnoDB引擎下事务的隔离级别及默认设置
- 隔离级别:
- 读未提交(Read Uncommitted)
- 读已提交(Read Committed)
- 可重复读(Repeatable Read)
- 串行化(Serializable)
- 默认隔离级别:可重复读(Repeatable Read)。
十三、乐观锁与悲观锁
- 乐观锁:
- 实现方式:版本号、CAS(Compare-And-Swap)。
- 适用场景:读多写少的场景。
- 悲观锁:
- 实现方式:
select ... for update。 - 适用场景:写多读少的场景。
- 实现方式:
十四、MySQL中基于版本号实现乐观锁时需要注意什么
- 实现方式:
- 在表中添加
version字段,更新时校验版本号是否一致。
- 在表中添加
- 注意事项:
- 版本号更新必须是原子操作。
- 高并发场景下,需考虑版本号冲突导致的失败重试。
十五、MQ什么时候用
- 使用场景:
- 异步处理:如发送邮件、短信。
- 削峰填谷:如秒杀活动中的流量削峰。
- 解耦系统:如微服务之间的通信。
- 广播消息:如通知多个消费者。
十六、grep命令的功能及其大小写忽略的实现方式
- 功能:
- 搜索文件中的匹配内容。
- 示例:
grep "keyword" filename。
- 大小写忽略:
-
使用
-i参数:grep -i "keyword" filename。
-
关注【码间烟火录】,可以获取更多技术干货噢~