科大讯飞一面,后端

科大讯飞一面,后端
最新回答
杰瑞老大

2024-01-15 13:56:12

答案:以下是针对科大讯飞后端一面问题的详细解答:

1. Java中final关键字的作用
  • 修饰变量:被final修饰的变量为常量,一旦赋值不可再更改(基本类型值不可变,引用类型引用地址不可变,但对象内容可变)。
  • 修饰方法:防止子类重写该方法,保证方法行为不可变。
  • 修饰类:禁止该类被继承,如String类即为final类。
2. HashMap和ConcurrentHashMap的区别
  • 线程安全:HashMap非线程安全,多线程下可能数据不一致;ConcurrentHashMap通过分段锁(Java7)或CAS+synchronized(Java8)实现线程安全。
  • 性能:HashMap单线程下性能更高;ConcurrentHashMap通过锁粒度优化(如Java8的桶锁)减少并发竞争,适合高并发场景。
  • 适用场景:HashMap用于单线程或外部同步的场景;ConcurrentHashMap用于多线程环境。
3. ReentrantLock和Synchronized的区别及Volatile的作用
  • 区别

    锁机制:Synchronized是JVM内置锁,通过monitor对象实现;ReentrantLock是API层面的锁,需手动释放。

    灵活性:ReentrantLock支持公平锁、可中断锁、超时锁等高级功能。

    性能:早期版本ReentrantLock性能更优,Java6后Synchronized优化后差距缩小。

  • Volatile作用

    可见性:保证变量修改对其他线程立即可见。

    禁止指令重排序:防止编译器或处理器优化导致逻辑错误。

    不保证原子性:需结合Synchronized或ReentrantLock实现原子操作。

4. Java版本及特性
  • 当前使用版本:根据项目需求选择,常见为Java8或Java11。
  • 最新版本:Java21(截至2024年)。
  • Java8到Java21流行特性

    Java8:Lambda表达式、Stream API、默认方法、Optional类。

    Java11:局部变量类型推断(var)、HTTP Client API标准化。

    Java17:密封类(Sealed Classes)、模式匹配(instanceof增强)。

5. 线程与协程的区别
  • 调度方式:线程由操作系统内核调度,协程由用户态程序调度(如Go的goroutine)。
  • 资源占用:线程占用更多内存(MB级),协程轻量级(KB级)。
  • 并发模型:线程适合CPU密集型任务;协程适合I/O密集型任务(如网络请求)。
  • 阻塞处理:线程阻塞会占用资源;协程可通过yield主动让出执行权。
6. 优惠券系统超发问题解决方案
  • 数据库乐观锁:通过版本号(version)控制,更新时检查版本是否匹配。
  • 分布式锁:使用Redis或Zookeeper实现跨服务锁,确保同一时间仅一个请求操作库存。
  • 消息队列削峰:将请求写入队列,后端按处理能力消费,避免瞬时高并发。
  • 库存预分配:下单时冻结库存,支付成功后扣减,超时未支付释放。
7. JVM内存模型
  • 程序计数器:记录线程执行的字节码行号,唯一无OOM的区域。
  • 虚拟机栈:存储方法调用的局部变量表、操作数栈等,线程私有。
  • 本地方法栈:为Native方法服务,与虚拟机栈类似。
  • :存放对象实例,所有线程共享,是GC主要区域。
  • 方法区:存储类信息、常量、静态变量等,Java8后改为元空间(Metaspace),使用本地内存。
  • 运行时常量池:方法区的一部分,存放编译期生成的字面量与符号引用。
8. 字符串存储位置
  • 字符串常量池:若字符串为字面量(如String s = "hello"),存储在堆中的常量池(Java7后移至堆内)。
  • 堆内存:若通过new创建(如String s = new String("hello")),对象实例存储在堆中,常量池仅存储引用。
9. Spring解决循环依赖
  • 三级缓存

    一级缓存(singletonObjects):存放完全初始化好的Bean。

    二级缓存(earlySingletonObjects):存放原始Bean对象(未填充属性)。

    三级缓存(singletonFactories):存放Bean工厂对象(Lambda表达式),用于解决AOP代理问题。

  • 流程:BeanA初始化时依赖BeanB,BeanB初始化时又依赖BeanA,此时从三级缓存获取BeanA的工厂对象,提前暴露代理引用,完成BeanB初始化后注入BeanA。
10. SpringBoot对Spring的优化
  • 自动配置:通过@EnableAutoConfiguration自动加载匹配的依赖配置,减少XML配置。
  • 起步依赖:提供spring-boot-starter-*依赖,简化依赖管理。
  • 内嵌服务器:默认集成Tomcat/Jetty,无需部署WAR包。
  • Actuator监控:提供健康检查、指标监控等端点。
11. 分库分表实践
  • 场景:数据量超过单库单表性能阈值(如千万级)时实施。
  • 分库策略:按业务拆分(如用户库、订单库)或水平拆分(如按用户ID哈希分库)。
  • 分表策略:水平分表(如按时间范围分表)或垂直分表(按字段拆分)。
  • 工具:使用ShardingSphere、MyCat等中间件实现透明分片。
12. MySQL索引结构与特性
  • 索引结构

    B+树:InnoDB主索引,支持范围查询,叶子节点存储数据或主键。

    哈希索引:Memory引擎支持,精确匹配快,不支持范围查询。

    全文索引:用于文本搜索,如MATCH AGAINST语法。

  • 覆盖索引:查询字段全部包含在索引中,无需回表。
  • 回表:非覆盖索引需根据索引值回主键索引查询完整数据。
  • 默认隔离级别:REPEATABLE READ(可重复读),通过MVCC和间隙锁避免幻读。
  • 其他隔离级别

    READ UNCOMMITTED:可能脏读。

    READ COMMITTED:避免脏读,可能不可重复读。

    SERIALIZABLE:完全串行化,性能最低。

13. Java书籍推荐
  • 《Effective Java》:涵盖编码规范、设计模式等最佳实践。
  • 《Java并发编程实战》:深入理解多线程与并发控制。
  • 《深入理解Java虚拟机》:剖析JVM原理与调优技巧。
14. 最近遇到的难题
  • 场景:分布式系统下订单ID生成冲突。
  • 解决:采用雪花算法(Snowflake)结合数据库序列,确保全局唯一且有序。
15. 实习项目角色与分工
  • 角色:后端开发工程师,负责核心模块设计与实现。
  • 团队规模:10人,含前端、后端、测试、产品。
  • 分工:后端组4人,分别负责订单、支付、用户、库存模块,通过Git分支管理并行开发。
16. 对讯飞与大模型技术的了解
  • 讯飞:国内AI龙头,语音识别、自然语言处理技术领先,如星火大模型。
  • 大模型技术:基于Transformer架构,通过海量数据预训练,具备多任务处理能力,如文本生成、代码补全。
17. 最有成就感的事
  • 项目:优化优惠券系统接口响应时间,通过缓存预热、异步处理将平均耗时从500ms降至100ms。
18. 讯飞面试轮次
  • 常规流程:3轮(2轮技术面+1轮HR面),特殊情况可能增加1轮。