
Java基础数据类型、引用传递、/equals、final/finally/finalize()、接口/抽象类、static/finalJVM 内存模型运行时数据区、GC、类加载双亲委派、JMM、volatile并发编程线程状态、锁升级、CAS/ABA、线程池、DCL单例、wait/notify网络 IOBIO/NIO、TCP三次握手/四次挥手、HTTP/HTTPSMySQL索引B树、事务隔离级别、MVCC、SQL优化Spring全家桶IoC/DI、AOP、事务传播机制、循环依赖三级缓存、自动配置原理Redis五种数据类型、持久化、哨兵、集群、缓存三大问题、分布式锁MyBatis/MyBatis-Plus#{} vs ${}、动态SQL、条件构造器项目实战博客系统、图书管理系统、Linux部署这基本覆盖了 Java 后端初中级面试 95% 以上的核心考点。中小厂Java开发岗模拟面试完整问答实录这份模拟面试完全基于你简历上的项目在线赛题评测系统 个人博客系统和你复习过的技术栈量身定制。难度对标中小厂1-3年经验注重实战落地能力不会故意刁难底层源码但会深挖“为什么这样设计”和“遇到了什么问题”。面试官你好先做个自我介绍吧参考答案面试官你好我叫许栋是嘉兴大学软件工程专业24届毕业生。我从大二开始接触Java系统学习了Java基础、JVM、并发编程、Spring全家桶、MySQL和Redis。大学期间我做过两个项目一个是个人博客系统用SpringBoot JWT MyBatis-Plus实现主要锻炼了后端接口设计和登录鉴权的能力另一个是在线赛题评测系统这是一个微服务项目用到了Spring CloudNacos、RabbitMQ、Redis和Docker。我独立完成了系统架构设计、数据库设计和核心模块开发包括用Docker做代码沙箱、用RabbitMQ异步判题、用Redis ZSet做实时排行榜。我对Java后端开发有很强的热情平时也会看一些源码和博客来提升自己。希望有机会加入贵公司跟大牛们一起学习成长。面试官好那我先从你的项目开始问。说说你在“在线赛题评测系统”中为什么要把判题服务拆成微服务拆了之后遇到了什么问题考点微服务架构设计、分布式问题认知参考答案拆分原因拆微服务主要是两个考虑。第一是业务解耦用户提交、判题、排名这些业务变化频率不同拆开可以独立部署升级不影响彼此。第二是资源隔离判题服务要跑用户提交的代码占CPU很高如果和其他服务放在一起可能把整个系统拖垮拆开后可以独立扩容。当时也是考虑到简历上写微服务会比较加分笑但确实在可控范围内做了合理拆分。遇到的问题第一个是服务调用超时。判题需要拉起Docker容器编译运行这个过程有时候比较慢前端HTTP请求会超时。我们的解决办法是改成异步 轮询用户提交代码后立刻返回“判题中”后端把任务投到RabbitMQ判题服务消费完把结果存到Redis前端轮询获取结果。第二个是分布式事务。比如用户提交代码后要在提交表插入记录还要更新题目表的提交次数。这两个操作在不同服务里。我们当时用的是最终一致性的思路先扣减题目计数如果失败就通过消息队列重试不追求强一致性因为这种场景允许短暂的数据不一致。面试官你们用Docker做代码沙箱怎么保证用户提交的恶意代码不把服务器搞挂考点容器安全、资源隔离参考答案这个问题我们上线前重点考虑过。主要做了三层防护第一层限制容器的资源使用。启动容器时加上--memory和--cpus参数限制内存和CPU使用上限防止用户代码吃满宿主机资源。比如内存限制在256MBCPU限制在0.5核。第二层限制系统调用。用--cap-dropALL去掉容器的大部分权限只保留必要的如--cap-addSYS_PTRACE让用户代码无法执行危险操作。第三层限制文件系统和网络。挂载只读文件系统禁止写入网络用--network none切断外网防止用户代码向外发起攻击或下载恶意脚本。另外编译和运行都设置了超时时间比如编译5秒、运行3秒超时直接kill容器并判为超时错误。面试官你的博客系统用了JWT替代Session为什么这么选JWT有什么缺点考点认证机制选型、JWT原理参考答案为什么用JWT因为博客系统虽然目前是单体但我希望将来如果扩展成微服务认证信息可以无状态地传递。Session的话每个服务都要存一份用户状态或者得单独搞一个Session共享的中间件比较麻烦。JWT直接在Token里携带用户信息服务端只需要验证签名不需要查存储扩展性更好。缺点JWT的主要问题是无法主动失效。用户如果改了密码旧的Token在过期前仍然有效除非我们维护一个黑名单。另一个问题是Token体积比SessionId大每次请求都要在Header里带会增加网络开销。还有一个是安全性JWT里的payload只是Base64编码不是加密所以不能放敏感信息如密码。面试官看你简历写了熟悉集合框架你能说一下 HashMap 的底层实现吗它线程安全吗考点集合框架基础必考题参考答案底层实现JDK 1.8HashMap底层是数组 链表 红黑树。数组是NodeK,V[] table每个元素是一个链表头。插入键值对时先算key的hashCode再通过(n-1) hash定位到数组下标。如果该位置没有元素直接放进去如果有元素哈希冲突就尾插法把新节点挂到链表后面。当链表长度超过8且数组长度大于64时链表会树化为红黑树提高查找效率。当红黑树节点数小于6时会退化为链表。线程安全HashMap线程不安全。多线程并发put时JDK 1.7里会形成死循环头插法扩容时。JDK 1.8改成了尾插法解决了死循环问题但仍有数据覆盖问题两个线程同时put后put的会覆盖前一个的值导致数据丢失。如果要线程安全可以用ConcurrentHashMap推荐或Collections.synchronizedMap不推荐锁粒度太大。面试官那 ConcurrentHashMap 是怎么保证线程安全的JDK 1.7 和 1.8 有什么区别考点并发集合参考答案这是两个版本的重构区别很大。JDK 1.7采用分段锁Segment。整个Map分成多个Segment每个Segment继承ReentrantLock相当于每个Segment是一把小锁。put操作时先定位到哪个Segment再锁住这个Segment。优点是多个线程操作不同Segment时互不影响缺点是锁粒度还是有点大。JDK 1.8做了大重构。取消了分段锁直接用CAS synchronized锁住数组的每个桶链表头结点。put操作时如果对应桶为空用CAS尝试插入不用加锁。如果桶不为空用synchronized锁住桶的头结点再操作链表或红黑树。另外1.8还引入了红黑树优化长链表查询性能size()方法也用CAS累加不再像1.7那样有全局计数器锁。总之1.8的锁粒度更细并发度更高。面试官你项目里用到了RabbitMQ那你说说怎么保证消息不丢考点消息队列可靠性参考答案消息可能丢在三个环节生产者丢、MQ自己丢、消费者丢。我们在每个环节都做了保障① 生产者端开启生产者确认机制Publisher Confirm。消息发到Exchange后RabbitMQ会回调confirm()方法成功就ack失败就nack。我们配合重试机制发送失败后重试3次如果还失败就记录到数据库人工介入处理。② MQ服务端开启持久化。创建队列时设置durabletrue发消息时设置deliveryMode2这样消息会写入硬盘RabbitMQ重启后不丢失。但要注意刚写入内存还没刷盘时有极小概率丢失我们业务可以接受。③ 消费者端关闭自动ACK改为手动ACK。消费者处理完业务逻辑并且成功落库后才手动调用channel.basicAck()确认。如果处理中抛异常就不ACK消息会重新入队被其他消费者消费或者留到队列里。面试官你们的消息队列有没有遇到消息重复消费怎么处理的考点幂等性设计参考答案有的。比如消费者处理完业务、准备发送ACK的时候网络闪断了RabbitMQ没收到ACK就会把消息重新投递给其他消费者导致同一条消息被处理两次。我们的解决方案是幂等性设计。判题服务消费消息时每条消息带一个唯一的消息ID由生产者生成用UUID 时间戳。消费者先拿着这个消息ID去Redis查如果查不到说明第一次处理正常执行判题逻辑完成后把消息ID存入Redis设置过期时间比如1小时再ACK。如果查到了说明已经处理过了直接ACK丢弃不再重复判题。这样即使RabbitMQ重发消息也只会生效一次。面试官MySQL方面你的博客系统用索引优化过查询能说说你是怎么优化的吗考点MySQL索引优化实战参考答案当时博客列表页加载慢我查了一下核心SQL是SELECT * FROM blog WHERE user_id ? ORDER BY create_time DESC。我做了几步优化加联合索引给(user_id, create_time)建联合索引。这样user_id过滤 create_time排序都能走索引避免了Using filesort。查询结果只扫索引树不用额外排序。用覆盖索引如果只查id, title, create_time这几个字段不查content这种大字段就建(user_id, create_time, title, id)覆盖索引直接在索引树上拿数据不需要回表速度更快。用 EXPLAIN 看执行计划优化前typeALL全表扫描Extra里有Using filesort优化后typerefExtra变成Using index condition扫描行数从几万降到几十。核心思想就是尽量让查询走索引避免回表避免排序。面试官你能说说 MySQL 事务隔离级别吗你项目里用的哪个考点MySQL事务参考答案MySQL InnoDB 默认是可重复读Repeatable ReadSpringBoot项目没有特殊配置用的也是这个默认级别。四个隔离级别从低到高读未提交Read Uncommitted有脏读问题基本不用。读已提交Read Committed解决了脏读但有不可重复读问题。可重复读Repeatable Read解决了脏读和不可重复读InnoDB通过MVCC解决。MySQL的默认级别。串行化Serializable所有事务串行执行性能最差基本不用。关于幻读RR级别下通过间隙锁Gap Lock解决。比如SELECT * FROM user WHERE id 100 FOR UPDATE不仅锁住匹配的行还会锁住100后面的间隙阻止其他事务插入新数据从而避免幻读。面试官Spring 的 Transactional 什么时候会失效你遇到过吗考点Spring事务原理高频参考答案遇到过。主要有这几种情况① 方法不是 publicSpring事务代理只对public方法生效。如果写成private或protected注解不生效。② 同类内调用自调用比如 A 方法调用 B 方法A有TransactionalB也有。如果 A 在内部直接this.B()绕过了代理对象B的事务不生效。解决办法是注入自身代理对象Autowired private UserService self;然后self.B()调用。③ 异常被 catch 吞掉Spring默认只对未捕获的 RuntimeException 和 Error回滚。如果在 catch 里把异常吃了事务就提交了。解决办法是在 catch 里throw new RuntimeException(e)或者手动TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()。④ 数据库引擎不支持事务比如 MySQL 的 MyISAM 引擎不支持事务换成 InnoDB 就好了。我们项目里遇到过第2种和第3种后来都修复了。面试官你的项目里用了Redis说说你用Redis都做了什么怎么保证缓存和数据库一致考点Redis实战参考答案使用场景在线赛题评测系统里Redis用了三个地方排行榜用ZSetkey是ranking:contest:123member是用户IDscore是解题积分。每次用户解出一道题用ZINCRBY增加积分查询时用ZREVRANGE取前十名。读多写少性能很好。判题结果缓存同一个题目同一个代码判题结果可能相同。用 String 存MD5(代码)→ 判题结果命中缓存直接返回避免重复消耗Docker资源。分布式Session微服务场景下用户登录状态用 Redis 存多个服务共享实现一次登录到处可用。缓存一致性我们用的是延时双删策略先删除 Redis 缓存。更新 MySQL 数据库。延迟几百毫秒再次删除 Redis 缓存。为什么要延迟因为数据库的主从同步有延迟删太快的话从库还没同步完读请求可能把旧数据又刷回缓存了。延迟一下保证从库同步完毕后再删一次。虽然不能保证100%强一致但在业务允许的范围内做到了最终一致。面试官如果我现在有个接口一次返回几千条数据页面加载很慢你会怎么优化考点接口性能优化思维开放式问题参考答案这个问题我分几个层面来优化① 数据层看SQL能不能加索引能不能用覆盖索引。如果数据量确实大考虑分页查询前端做分页组件一次只返回20条用LIMIT加偏移量。② 缓存层如果数据是热点数据比如热门商品列表把查询结果序列化后放到Redis设置合理的过期时间下次请求直接从缓存拿不走DB。③ 业务层看能不能异步处理。如果是报表类数据可以先返回一个任务ID后台慢慢生成Excel生成好了让用户下载不要让用户HTTP请求等着。④ 传输层返回的JSON数据量如果很大可以在Nginx或Spring配置里开启Gzip压缩传输体积能缩小70%以上网络传输会快很多。具体用哪种方案看业务场景如果是列表页分页 缓存就够了如果是导出报表用异步。面试官好最后来个简单的算法题。你写一个方法把一个字符串里的每个单词反转但单词顺序不变。比如 hello world 输出 olleh dlrow。考点基础编程能力参考答案javapublic class StringReverse { public static String reverseWords(String s) { if (s null || s.isEmpty()) { return s; } String[] words s.split( ); StringBuilder result new StringBuilder(); for (int i 0; i words.length; i) { String reversed new StringBuilder(words[i]).reverse().toString(); result.append(reversed); if (i words.length - 1) { result.append( ); } } return result.toString(); } public static void main(String[] args) { System.out.println(reverseWords(hello world)); // olleh dlrow System.out.println(reverseWords(I love Java)); // I evol avaJ } }边写边讲思路先按空格拆成单词数组然后遍历每个单词用StringBuilder的reverse()方法反转再拼回一个字符串。注意单词间的空格不要多不要少。时间复杂度 O(n)空间复杂度 O(n)。面试官好的我的问题差不多了。你有什么想问我的吗参考答案选2-3个问关于技术栈贵公司目前后端主要用的是 Spring Boot MyBatis 吗有没有在用 Spring Cloud 或者 Docker 这些关于团队咱们后端团队大概多少人我入职后主要是负责哪个业务模块关于成长公司对于新人的培养机制是怎样的有没有导师带平时会有技术分享吗关于项目我进来之后主要会参与到哪个项目里使用的技术栈和我学的匹配度高吗 面试复盘 表现评估考察维度你的表现建议自我介绍结构清晰有项目有亮点时间控制在1.5-2分钟语速适中项目深挖能说出设计思路和遇到的问题准备2个“遇坑-解决”的故事更有说服力Java基础HashMap、ConcurrentHashMap答得很好可以顺手提一下红黑树特性并发/锁没问到锁升级但JUC基础扎实如果被追问准备一下synchronized锁升级MySQL索引优化和事务隔离都OK多说说EXPLAIN的具体使用Spring事务失效回答完整可以再备一个AOP的案例Redis/MQ实战经验加分分布式锁如果被追问可以说Redisson算法基础题秒杀中小厂算法以简单/中等为主不用太担心整体评价你现在的水平中小厂Java开发岗初级稳过可以冲一下中厂的中级岗。面试时保持自信项目里用的东西一定要能讲明白为什么这么选。放轻松你准备得已经非常充分了Java开发岗模拟面试基础篇这份模拟面试比上一份更基础覆盖Java核心基础、面向对象、集合、异常、MySQL、Spring、Redis等必考知识点。适合校招、实习、初级社招场景。每个问题都附有详细的参考答案和考点说明。面试官你好先做个自我介绍吧参考答案面试官你好我叫许栋是嘉兴大学软件工程专业24届毕业生。我大学期间主要学习Java方向系统学过Java基础、SpringBoot、MySQL和Redis这些后端技术。做过两个项目一个是个人博客系统一个是在线赛题评测系统都是用SpringBoot MyBatis/MyBatis-Plus做的用到了JWT、RabbitMQ、Redis和Docker。平时也会看一些技术博客和源码对后端开发挺感兴趣的。希望能有机会加入贵公司学习和成长。面试官Java是面向对象的语言你能说一下面向对象的三大特性吗考点面向对象基础必考题参考答案面向对象有三大特性封装、继承、多态。封装把对象的属性和方法包装在一起对外隐藏内部实现细节只暴露必要的接口。比如类的成员变量用private修饰对外提供public的getter/setter。这样做的目的是保护数据安全也方便以后修改内部实现而不影响外部调用。继承子类可以继承父类的属性和方法实现代码复用。Java是单继承一个类只能有一个父类但可以多层继承。继承要符合is-a的关系比如“狗是动物”。多态同一个行为在不同对象上有不同的表现形式。比如Animal父类有eat()方法Dog和Cat分别重写后调用同一个eat()狗和猫的行为不一样。多态的三个条件是继承、重写、父类引用指向子类对象。面试官你能说说和equals的区别吗考点基础比较运算参考答案这个问题要看是基本类型还是引用类型。对于基本类型如int、double比较的是数值是否相等。对于引用类型如String、Integer、自定义类比较的是内存地址也就是两个引用是否指向同一个对象。equals()是Object类的方法默认实现也是用比较地址。但很多类重写了equals()比如String和Integer重写后比较的是内容是否相等。有个经典的坑Integer有缓存池-128 ~ 127在这个范围内的值Integer a 100; Integer b 100;比较a b是true因为复用同一个对象。超出这个范围就是false。所以包装类比较值推荐用equals()。面试官String是基本类型还是引用类型它有什么特点考点String基础参考答案String是引用类型不是基本类型。它有这几个特点① 不可变性String对象一旦创建内容就不能改变。因为它的底层char[]或byte[]是final的。每次对字符串的“修改”操作比如或concat()其实都是创建了一个新对象。② 字符串常量池用字面量双引号创建的字符串会放在堆里的字符串常量池中。相同内容的字面量会复用同一个池子里的对象节省内存。用new String()创建的则是在堆里新建一个对象不走常量池。③ 线程安全因为不可变所以多线程环境下是安全的不需要额外的同步。由于不可变性循环拼接字符串时要用StringBuilder或StringBuffer避免产生大量中间对象。单线程用StringBuilder多线程用StringBuffer。面试官Java 的异常体系你了解吗Error和Exception有什么区别考点异常处理基础参考答案Java 所有异常和错误的父类是Throwable下面分两个分支Error和Exception。Error表示严重的系统级错误程序不应该去捕获。比如OutOfMemoryError内存溢出、StackOverflowError栈溢出。这类错误通常是因为环境或硬件问题不是代码能处理的程序会直接终止。Exception表示程序运行中可能出现的异常情况需要程序员处理。Exception又分两类运行时异常RuntimeException编译时不强制处理运行时才可能抛出。比如NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException。这类异常通常是代码逻辑问题应该通过改进代码来避免。检查异常Checked Exception编译时必须处理要么 try-catch要么 throws。比如IOException、SQLException、FileNotFoundException。关于finally不管try里有没有异常finally的代码都会执行。常用于释放资源比如关闭数据库连接、关闭文件流。唯一不执行的情况是调用了System.exit(0)。面试官ArrayList和LinkedList有什么区别你平时怎么选考点List集合基础参考答案它们底层数据结构不同ArrayList底层是动态数组。随机访问get和set很快时间复杂度 O(1)因为可以通过索引直接定位。但插入和删除尤其是中间位置慢因为要移动元素时间复杂度 O(n)。LinkedList底层是双向链表。插入和删除尤其是两端很快时间复杂度 O(1)。但随机访问慢需要从链表头开始遍历时间复杂度 O(n)。平时怎么选如果查询多、改多、增删少用ArrayList。如果增删多尤其是头尾、查询少用LinkedList。实际开发中90% 以上的场景用ArrayList因为大部分业务都是查询和遍历。LinkedList在队列或栈的场景下会用。补充ArrayList扩容时新容量 旧容量 * 1.5会复制原数组频繁扩容有性能开销。如果能预估数据量建议在构造时指定初始容量。面试官多线程你熟悉吗创建线程有哪几种方式考点多线程基础参考答案Java 创建线程有四种方式① 继承 Thread 类重写run()方法然后调用start()启动。javaclass MyThread extends Thread { public void run() { System.out.println(run); } } new MyThread().start();② 实现 Runnable 接口更灵活因为 Java 单继承实现了 Runnable 还能继承其他类。配合 Lambda 表达式更简洁。javanew Thread(() - System.out.println(run)).start();③ 实现 Callable 接口和 Runnable 类似但有返回值需要配合FutureTask使用。javaCallableInteger callable () - { return 1; }; FutureTaskInteger task new FutureTask(callable); new Thread(task).start(); Integer result task.get();④ 使用线程池通过Executors或ThreadPoolExecutor创建。线程池的好处是减少频繁创建和销毁线程的开销。关于run()和start()run()是普通方法调用不开启新线程start()才会在操作系统层面创建新线程然后自动调用run()。面试官synchronized是什么怎么用考点synchronized基础参考答案synchronized是 Java 的关键字用来加锁保证同一时刻只有一个线程能执行被锁的代码块或方法。它保证了原子性和可见性。三种用法① 修饰代码块锁的是括号里指定的对象。javasynchronized (locker) { // 业务代码 }② 修饰普通方法锁的是当前对象this。javapublic synchronized void method() { }③ 修饰静态方法锁的是类的 Class 对象类的全局锁。javapublic static synchronized void method() { }注意多个线程想互斥必须用同一个锁对象。synchronized是可重入锁同一个线程可以重复获取同一把锁不会死锁。面试官你项目里用了MySQL能说说事务的ACID特性吗考点MySQL事务基础参考答案ACID 是事务的四个特性A原子性Atomicity事务里的一组操作要么全部成功要么全部失败回滚。不能只成功一部分。C一致性Consistency事务执行前后数据库的状态要一致。比如转账A扣了100B就得加100总额不变。如果中间出错回滚了也要回到一致的状态。I隔离性Isolation多个事务同时执行时彼此之间互不干扰。MySQL有四种隔离级别来控制隔离程度。D持久性Durability事务一旦提交成功数据就永久保存下来了。即使数据库宕机或断电数据也不会丢。项目中我一般用Transactional注解管理事务Spring 会帮我们自动开启和提交。如果要手动控制也可以自己调commit()和rollback()。面试官你刚才说TransactionalSpring 里Autowired是干什么的怎么用考点Spring依赖注入基础参考答案Autowired是 Spring 用来做依赖注入DI的注解Spring 容器会自动把匹配的 Bean 注入进来我们不用手动new对象。三种注入方式① 属性注入最常用但官方不推荐javaAutowired private UserService userService;② 构造方法注入官方推荐javaAutowired public UserController(UserService userService) { this.userService userService; }③ Setter 注入javaAutowired public void setUserService(UserService userService) { this.userService userService; }构造方法注入为什么推荐因为注入的对象可以用final修饰保证不可变而且构造方法在类加载时就会执行能尽早发现依赖问题也方便单元测试。另外有个注意点如果有多个相同类型的 Bean需要用Qualifier指定具体要注入哪一个或者用Primary标记默认的。面试官能说说 IoC 是什么意思吗考点IoC核心概念参考答案IoC 是Inversion of Control控制反转。它是一种设计思想把对象的创建权和依赖管理权从程序代码本身转移给了 Spring 容器。传统方式是我们自己new对象比如UserService service new UserService();主动权在我们手里。用了 IoC 之后我们只需要在类上标Service、Component这些注解Spring 启动时就会帮我们创建好对象存到容器里。需要用的时候用Autowired注入就行了。用个比喻传统方式是自己动手组装电脑IoC 是告诉销售你要什么配置人家组装好给你送过来。控制反转的好处是解耦。类之间不再直接依赖而是依赖 Spring 容器代码更灵活也更容易测试和替换实现。面试官简单说说你了解的 Redis项目里用来干什么考点Redis基础应用参考答案Redis 是一个基于内存的键值对数据库读写速度非常快10万/秒左右。它是单线程模型但正因为单线程避免了多线程的竞争开销。我在项目里主要用 Redis 做三件事① 缓存把热点数据比如热门题目、用户信息放 Redis下次查询先走 Redis没命中再查 MySQL减少数据库压力。② 排行榜用ZSet有序集合存用户的解题积分。ZINCRBY增加分数ZREVRANGE取前几名实现实时排行榜。③ 分布式Session多个微服务共享用户登录状态用 Redis 存 Session不同服务之间可以共享。Redis支持的数据类型主要有5种String、List、Hash、Set、ZSet。不同的场景用不同的类型。面试官好的我这边没什么问题了。你还有什么想问我的吗参考答案选2-3个关于岗位这个岗位日常主要做哪些业务是偏向业务开发还是中间件/基础架构关于技术栈公司现在后端主要用哪些技术栈框架版本大概是怎样的关于团队咱们团队现在有多少人我入职后会有导师带吗关于成长公司对于应届生或初级开发有没有培训或者学习计划 面试复盘问题考点难度自我介绍表达能力、项目概括⭐面向对象三大特性OOP基础⭐vsequals基础比较⭐String特点String基础⭐Error vs Exception异常体系⭐⭐ArrayList vs LinkedList集合基础⭐⭐线程创建方式多线程基础⭐⭐synchronized锁基础⭐⭐事务ACIDMySQL基础⭐⭐AutowiredSpring DI⭐⭐IoC含义Spring核心概念⭐⭐Redis用途NoSQL基础⭐⭐整体评价这套基础题如果都能答出来说明Java基础是过关的。中小厂校招/实习面试中这些题的命中率很高。建议在回答时适当带一两个项目中的例子比如讲到Redis时顺嘴提一句“我在排行榜里用了ZSet”会让回答更有说服力。祝你面试顺利