格力后端笔试全解析:Java、MySQL与场景设计题备考指南

格力后端笔试全解析:Java、MySQL与场景设计题备考指南 1. 格力的后端笔试题到底在选什么样的人先交代一下背景。2020年秋季招聘格力作为制造业头部企业开启了规模不小的数字化人才招募后端开发岗是其中核心方向之一。当年这波笔试在牛客和各类校招群里流传度很高原因倒不是题目有多难而是这份卷子非常“制造业数字化转型”的混合气质——既没有互联网大厂那种动辄hard级算法的下马威也不是传统软件公司那种纯背八股文的套路卷它在基础能力、工程习惯和业务理解之间找平衡筛的是“能直接干活的人”。如果你正在准备制造业或泛工业领域的后端校招这份笔试题非常有参考价值。先说结论格力这类制造业巨头的后端笔试重点不在“谁更聪明”而在“谁的底子更扎实、谁更靠谱”。原因很简单制造业的信息化系统有大量真实业务约束——生产计划、库存台账、设备数据接入、经销商订单流转这些场景对稳定性和数据一致性的要求远高于对花哨架构的需求。笔试出题时不会像互联网大厂那样疯狂堆算法和系统设计深度而是用更务实的方式考察一个应届生能不能理解业务、能不能把基础知识落到实际场景里。2020年这波秋招的岗位方向也能佐证这一点。当时格力正在大力推进智能家居、工业互联网和电商渠道的数字化后端岗位既要支撑传统的ERP、MES类业务也要兼顾IoT设备接入、电商订单、售后服务平台等新方向。这种复合背景决定了笔试题的覆盖面会比较广但每块难度都控制在“本科阶段认真学就能答出来”的范围内。1.1 制造业后端和互联网后端考察偏好有明显差异互联网后端笔试偏爱考高并发、分布式、缓存一致性这类架构题因为业务体量摆在那里每秒几万请求是常态。但制造业后端很多系统的并发量其实没那么夸张——工厂车间的工单系统、经销商管理系统、售后工单平台日活在几千到几万不等。真正让人头疼的是业务逻辑复杂、数据链条长、异常场景多比如一台空调从生产入库到经销商提货再到用户安装中间涉及库存锁定、物流单、结算单多个环节任何一个环节数据不一致都会引发连锁问题。所以你会发现格力的笔试题里不太会出现“设计一个支撑双十一秒杀的系统”或“单机百万连接的IM架构”这类问题反而更可能出现“订单状态流转时如何保证数据一致性”“并发下单时如何防止超卖”这类贴近真实业务的问题。备考时如果还按照互联网大厂的高并发八股文路子去准备方向就偏了。1.2 从笔试题能反推技术栈Java系为主Spring生态是主力结合当年各渠道流传的题目复盘格力的后端笔试明显偏向Java技术栈Spring Boot/Spring Cloud相关的题目占了不小比例数据库方面MySQL是绝对主流Redis和消息队列也有涉及。这符合国内制造业信息化的普遍现状Java生态成熟稳定、人才供给充足、适合复杂业务系统的长期维护。具体到题目类型大致可以分成四块基础选择题、简答题、编程题、场景设计题。下面我按实际笔试的答题逻辑逐块拆解每块都会结合当年的高频题目和踩坑经验来讲。2. 题型全览与答题顺序笔试第一步是战术不是知识很多人拿到卷子就开始埋头做题这个习惯在校招笔试里很吃亏。特别是格力的题量不算小选择题约20道、简答题4到6道、编程题2到3道、场景设计题1到2道总时长一般120到150分钟。如果你按试卷顺序从前做到后很可能会在前面纠结太久把后面分值更高的设计题挤得没时间写。2.1 先花3分钟分配时间再开始答题我当年做这类笔试题的习惯是先快速扫一遍全部题目把每道题的分值和预估用时写在草稿纸上然后按“先易后难、先高分后低分”的顺序作答。具体建议如下题型数量单题分值建议总用时答题优先级基础选择题约20道2-3分25-30分钟第一优先简答题4-6道5-8分30-40分钟第二优先编程题2-3道10-15分40-50分钟第三优先场景设计题1-2道15-20分25-35分钟第四优先但如果分值高优先留足时间注意最后一条的优先级有点反直觉场景设计题虽然排最后但你必须在扫题环节就判断它是否好写。如果看到一道“设计一个设备数据上报系统”的题目而你恰好对这类场景有积累那就直接跳到这道题先做因为这类题主观性强写得好不好有比较大的发挥空间性价比很高。相反编程题如果一看就是要用复杂动态规划或高级数据结构先放一放不要死磕。2.2 选择题的高频失分点不是不会是“想太多”选择题是基础分的保证正常情况应该拿到80%以上正确率。但很多同学偏偏在选择题上翻车原因不是没复习到而是被干扰项带着走。举几个当年出现过的典型陷阱类型第一类是“看似正确但表述绝对化”的选项。比如考察Java异常处理的题目选项里出现“finally块中一定不能有return语句”这种绝对化表述基本可以直接排除。虽然finally块中写return确实会吞掉异常但语言本身没有禁止只是不推荐所以不能选“不能”。第二类是“概念混淆型”选项。比如考察线程池参数会把核心线程数和最大线程数的默认值调换或者把饱和策略的触发条件搞混。这类题要求你不仅记住参数值而且要理解它们在什么时机生效。说实话这类题做错不是因为你记性差而是因为你只背了结论没推演过过程。后面第3章我会用一个典型例子详细拆解。第三类是“版本差异陷阱”。比如HashMap在JDK 7和JDK 8中的数据结构变化问“链表在什么条件下转红黑树”如果对版本差异不够敏感很容易选错。格力2020年笔试就出现过类似题目考察的是HashMap在JDK 8中链表长度到8且数组长度到64时才转红黑树两个条件缺一不可。建议的答题策略是一眼能确定答案的直接选不确定的先跳过全部做完后再回来推敲。不要在单题上超过1分钟选择题总时长必须控制在30分钟以内否则后面大题会被严重压缩。3. Java与并发基础这部分不能靠“背答案”过关Java是格力后端岗的核心语言笔试中占比最大的基础题几乎都围绕Java展开。但值得注意的是2020年这波题目对Java基础的考察并不是简单的知识点复述而是更偏向“理解原理并能说明为什么”的层次。比如考集合类会问“HashMap为什么线程不安全”、考并发会问“线程池参数应该怎么设”这些题没有标准死答案但答得好不好一眼就能看出你是背的还是懂的。3.1 线程池参数这道题怎么答出“用过的人”的感觉线程池相关题目在制造业后端笔试里出现频率极高格力也不例外。常见问法有两种一种是直接问“ThreadPoolExecutor的核心参数有哪些分别是什么作用”另一种是给场景问“线程池参数怎么设置”。简单说下参数核心线程数corePoolSize、最大线程数maximumPoolSize、空闲线程存活时间keepAliveTime、阻塞队列workQueue、线程工厂threadFactory、拒绝策略handler。背出来不难但大多数人栽在“参数怎么设”上。我当时答题的思路是这样先说清楚两个关键参数的关系——**当提交的任务数大于核心线程数且队列未满时新任务会进入队列等待而不是直接创建新线程只有当队列也满了才会继续创建线程直到最大线程数如果达到最大线程数还有任务进来才触发拒绝策略。**这个过程必须表述准确因为它直接决定线程池的实际行为。然后针对场景设计参数时我会分情况讨论CPU密集型任务核心线程数设为CPU核数1队列用有界队列避免无限堆积。IO密集型任务核心线程数可以设到CPU核数的2倍甚至更高因为线程大部分时间在等待IO可以多开线程提高吞吐。混合型任务看哪个占比高或拆成两个线程池分别处理。最后一定要带上一句**“参数没有绝对标准必须结合业务的并发量、任务耗时和可接受的排队时间来确定而且要压测验证。”**这句话能让阅卷人看到你是有工程思维的而不是只会背书。实际上这个题在面试环节被追问的概率也很高我认识有同学笔试题写了“根据场景灵活设置”面试时就被考了“如果任务平均耗时500msQPS峰值为200核心线程数怎么估算”——这类问题你现场推一下得出结果远比背参考答案更让人信服。3.2 集合类源码题HashMap的线程不安全点在哪里格力笔试中集合类考得最多的是HashMap尤其是它线程不安全的表现和原因。这题常见但不简单因为需要你理解HashMap的内部结构才能讲明白。HashMap线程不安全主要体现在三个地方**JDK 7及以前扩容时多线程并发put可能导致环形链表get时出现死循环。**原因是扩容采用头插法并发转移元素时链表顺序会反转形成闭环。**JDK 8以后头插改为尾插死循环问题解决了但并发put仍可能导致数据覆盖。**比如两个线程同时算得同一个数组下标都执行到插入位置后写的会把先写的覆盖掉。**size字段不是原子性的并发操作时Map的元素个数统计不准确。**这个很多人容易忽略但它确实是线程不安全的体现之一。答题时我建议先讲清楚这个演进过程再点出核心结论**HashMap设计上就不是给并发场景用的并发场景应该用ConcurrentHashMap。**然后可以补充ConcurrentHashMap的实现差异JDK 7用分段锁Segment继承自ReentrantLockJDK 8改为CASsynchronized锁Node节点锁粒度更细并发性能更好。这种答法的好处是把“背结论”和“理解过程”区分开了。阅卷人看到的不是一个只会说“HashMap线程不安全”的候选人而是一个能讲清楚“为什么不安全、怎么演进、替代方案是什么”的候选人。注意笔试答题不是面试不用展开太多但关键脉络必须完整。3.3 synchronized和ReentrantLock的区别不要只背表格这道题几乎每次笔试都会出现但大部分答案都停留在“synchronized是关键字、ReentrantLock是类”“synchronized自动释放锁、ReentrantLock要手动释放”这种表格对比上。这样答没毛病但太平了拉不开差距。更有价值的答法是把视角放在“JDK 6之后synchronized经历了什么”上。JDK 6对synchronized做了大量优化引入了偏向锁、轻量级锁、重量级锁的升级过程锁的粒度从无锁到偏向锁、再到轻量级锁、最后到重量级锁。在低竞争场景下synchronized的性能已经不输ReentrantLock而且它使用更简单、不容易出错。那ReentrantLock还有什么存在的意义答案是它的功能更丰富支持公平锁和非公平锁synchronized只能是非公平的支持尝试获取锁tryLock和超时获取锁这在实际业务中非常有用支持多个条件变量Condition可以用更细的粒度控制线程的等待和唤醒。回答时把这些点串成一个逻辑链**为什么有了synchronized还需要ReentrantLock因为需求多样性有了多样化的工具才能应对复杂的并发控制场景。**如果再结合一个实际案例比如“使用tryLock避免多线程竞争时长时间阻塞”这题的答案就很完整了。4. 数据库与场景设计题真正拉开差距的地方数据库是后端笔试的另一座大山尤其是MySQL。格力这份题里数据库相关的分值占比肉眼可见地高而且简答题和场景设计题往往围绕数据库展开。原因不复杂——制造业业务系统里数据是核心资产而MySQL是绝大多数中小型系统的存储底座。哪怕你Java写得再漂亮数据库设计不合理、SQL写得烂系统一样跑不起来。4.1 索引失效类题目别死记“最左前缀”要理解B树的行为索引题几乎是MySQL笔试的必考项格力2020年的卷子里出了不少。常见问法是“以下SQL哪些能用到索引哪些会失效为什么”选项设计得很刁钻专门挑那些“看似能用但实际用不上”的写法当干扰项。失效场景我就不一一列举了大家应该都背过对索引列使用函数、隐式类型转换、前导模糊查询、OR连接非索引列、在索引列上做计算等。但有一个问题——**如果你只背场景换个问法就懵了。**比如“为什么对索引列使用函数会导致索引失效”这时候你需要理解B树的索引结构。B树的索引是有序排列的存储的是列的实际值。当你对列使用函数时比如WHERE DATE(create_time) 2024-01-01数据库需要在每个索引值上先执行函数再比较函数的返回值是无序的B树有序索引的优势就没了优化器只能放弃索引扫描改走全表。同理隐式类型转换本质上也是让列参与了一个函数操作。理解到这一层哪怕题目怎么变你都能判断出来。我建议在备考时不要只背“口诀”而是每次遇到索引题都问自己一句**这个条件下B树还能不能保持有序地定位到目标数据**这样做的效果远好于背二十条失效规则。4.2 场景设计题像“设备数据上报”这种题怎么答出层次感格力2020年秋招笔试里有一道很有代表性的场景设计题**“工厂有大量设备设备会定时上报运行状态数据高峰时每秒上报数千条数据。请设计一个数据接收和存储方案。”**这种题没有标准答案考察的是综合分析能力和业务理解。我当时答题时把方案拆成了四层第一层是接入层。设备数据上报需要一个统一的HTTP接口或MQTT网关接口要做到幂等因为网络不稳定时设备会重试同一份数据可能被发送多次。幂等的实现可以用唯一请求ID数据库唯一索引来处理。第二层是削峰层。几千条每秒的写入量如果直接压进MySQL虽然勉强能扛但会让业务查询变慢尤其当数据持续堆积时。所以中间加一个消息队列如Kafka或RocketMQ做缓冲消费端异步写入数据库削峰填谷同时利用队列的重试机制保证数据不丢。第三层是存储层。设备运行数据时序性很强可以按天分表以设备ID和时间戳作为联合索引。高频查询场景是用设备ID查某个时间段的数据加一个时间范围条件能有效利用索引。如果有条件冷数据可以定期归档到单独的库或转为文件存储避免单表数据量过大。第四层是数据一致性保障。消息队列可能重复消费所以消费端要做幂等处理方案可以是利用数据库的唯一索引或者在业务表里加一个“上报记录ID”的字段消费时先查重再插入。另外如果设备数据影响生产决策还需要监控消费积压积压超过阈值就告警。这四层写下来体现的不只是知识储备更是对真实业务场景的打法理解。笔试题里遇到这类系统设计的问题框架感很重要先给一个整体流程再逐一填充细节比想到哪写到哪强得多。4.3 事务隔离级别与并发状态更新别把“默认”当“正确”事务隔离级别也是数据库部分的常客。MySQL默认是REPEATABLE READ可重复读Oracle默认是READ COMMITTED这个考点本身不难但结合业务场景时很多人容易答偏。格力笔试出现过类似问题**“一个订单系统多个用户并发修改同一个订单的状态如何避免更新丢失”**这题考察的是事务隔离级别和锁机制的综合应用。首先要明确MySQL的REPEATABLE READ虽然解决了不可重复读问题但不能完全避免更新丢失。两个事务同时读取到同一版本的数据然后各自修改并提交后提交的会覆盖先提交的结果。解决办法有几种一是使用SELECT ... FOR UPDATE给数据行加锁这是悲观锁思路简单可靠但并发性能一般。二是使用乐观锁在订单表加version字段更新时带上WHERE version 当前版本号如果影响行数为0说明版本冲突需要重试。这个方案并发性能更好也是实际业务中常见做法。三是用原子更新语句比如UPDATE order SET status PAID WHERE order_id ? AND status UNPAID让数据库在单条语句内完成判断和更新的原子操作。这种方式不需要额外字段但对状态流转复杂的场景不适用。答题时最好把这三种方案都列出来然后指出各有利弊根据实际业务选择。这种“给出多个方案分析取舍”的答法比只推荐一种更能体现工程能力。5. 算法题中档题的稳定性比难题的突破更值钱格力后端笔试的算法题难度整体定位在LeetCode Easy到Medium之间偶尔出现一道接近Medium偏上的动态规划或双指针题。相比互联网大厂这个难度对非竞赛型选手相当友好。但友好不意味着能拿满分很多人折在不是“不会做”而是“会做但没做完”或“做出来了但细节错”。5.1 拿到一道编程题先做这三件事第一件事不要急着写代码先读三遍题目确认输入输出格式和边界条件。校招笔试的编程题经常在边界上埋坑比如数组可能为空、链表可能只有一个节点、字符串可能包含空格。这些情况考虑不全代码再正确也过不了全部用例。第二件事估一下数据范围判断解法是否可行。如果数组长度是10^5那O(n^2)的暴力法会超时必须想O(n)或O(nlogn)的解法。如果长度是100以内暴力法完全够用没必要想复杂解法。这个判断要在30秒内完成。第三件事写之前先想好测试用例至少想一个普通场景、一个边界场景、一个极端场景代码写完立刻用这三个用例自测。很多人在笔试环境里不敢花时间做测试用例觉得浪费时间实际情况是——写完后编译通过但逻辑错误反而要花更多时间调试。5.2 一道有代表性的动态规划题从暴力递归到状态定义2020年格力的算法题里有一道版本流传较广的题目变体很多大概是“给定一个整数数组找出一段连续子数组使其和最大返回这个最大值”。这是经典的“最大子序和”问题。很多人在笔试中第一反应是暴力双重循环把所有子数组的和都算一遍。这个解法在数据量小的时候没问题但如果数组长度较大就会超时。更优的解法是动态规划状态转移方程是dp[i] max(dp[i-1] nums[i], nums[i])其中dp[i]表示以第i个元素结尾的子数组的最大和。这样一次遍历就能得出结果时间复杂度O(n)空间复杂度可以优化到O(1)。笔试时如果你能写出这个解法已经超过了大多数候选人。但如果你想在这道题上更亮眼可以再补一句如果数组允许为空需要特殊处理如果题目要求返回子数组的起始和结束位置需要用变量记录状态变化的时刻。这种“拿到题先想清楚变体和边界”的习惯在阅卷时很加分。5.3 字符串处理题要小心“实现细节”翻车另一类高频算法题是字符串处理常见的有反转字符串、判断回文串、字符串匹配等。这类题思路不复杂但实现细节非常考验基本功。比如反转字符串时是否允许使用额外空间不允许的话就要用双指针原地交换判断回文串时是否忽略空格和标点大小写是否敏感这些条件不确认清楚代码写得再漂亮都是白搭。一个很实用的建议是笔试编程题里尽量用最直白的解法不要炫技。能用常规循环解决的问题就不要玩函数式编程能用数组就不要硬用Map代码越简单越不容易出bug。毕竟是限时环境稳定跑通所有用例永远比写一个优雅但容易翻车的解法更划算。6. 复盘方法把每次笔试变成下一轮面试的资产很多同学笔试完就扔到一边等结果出来才后悔这个没复习、那个没想到。但真正有效的做法是**每一次笔试结束不管结果如何立刻做一次结构化复盘。**笔试题目是面试官亲自出的或精选的等于他们亲口告诉你“我们重视什么”这些信息比任何面经都值钱。6.1 复盘四步法把笔试题吃干榨净我的复盘方法分四步。第一步重做一遍所有错题和不会的题不看答案独立推导到得出正确结果。第二步整理每道题背后的知识点建立知识点清单比如“索引失效”这件事对应的是B树结构、查询优化器原理、Explain执行计划把它们关联起来形成一个知识簇而不是散点。第三步针对没答好的题目预测面试时可能追问的方向并提前准备好回答。第四步把这份复盘笔记保存下来面试前翻一遍往往会有奇效。这四步里第三步最容易被忽略但其实最值得做。比如你笔试时线程池参数设置题答得不完整面试官极大概率会追问“如果任务执行中抛异常会怎样”“队列大小怎么定”“拒绝策略选了AbortPolicy会发生什么”。这些问题如果不提前准备面试现场很容易卡壳。笔试题的本质是面试官给的“考点提纲”顺着提纲深入准备效率远高于漫无目的地刷面经。6.2 从笔试题到面试的衔接你能讲出来的才真正是你的有这么一个规律你在笔试里写的每一句话都可能在面试中被拎出来反复盘问。如果你写了“使用了Redis缓存热点数据”面试官一定会追问“缓存和数据库的一致性怎么保证”“缓存穿透和雪崩怎么解决”“如果Redis挂了怎么办”。所以笔试时尽量写自己真正理解的内容千万不要为了显得厉害而堆砌名词。这不是说不能写不了解的东西而是说写了之后要马上补课。每次笔试结束后凡是出现在自己答案里的技术点都要能做到“能画图、能举例、能写Demo”的程度。所谓“能画图”是能画出系统交互流程“能举例”是能讲出一个真实场景中的应用案例“能写Demo”是能在本地快速跑通一个小示例。能达到这个标准笔试答案里的内容才能真正内化成自己的能力。我自己当年参加校招时有一道场景设计题里提到了“使用Kafka做削峰”但其实那时我对Kafka的认识相当浅只是在博客里看过这种方案。笔试结束后我花了整整两天时间把Kafka的架构原理、消费者组机制、消息可靠性保障全啃了一遍并写了一个生产者消费者的Demo跑通。果不其然那场面试的面试官真的围绕Kafka问了十几个问题我因为提前补了课全部答了上来面试环节直接扭转了笔试的劣势。所以我的建议是**从笔试结束的那一刻开始就把笔试内容当作面试的预演而不是已经翻篇的过去式。**你在这份卷子上写的每一个字都可能在面试时成为你的进阶题或送命题关键看你后续怎么处理。回想2020年那次格力秋招我发现最有价值的收获不是最终拿到了什么Offer而是通过这份笔试题我重新校准了自己对“后端工程师”这个岗位的认知——技术栈可以迁移工程思维和解决问题的框架才是核心竞争力。希望这篇文章能帮你少走一些弯路在笔试题面前不只是“会答”而是“知道为什么这么答”。