news 2026/9/13 8:09:28

50道SQL练习题:从多表连接到窗口函数,吃透面试高频考点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
50道SQL练习题:从多表连接到窗口函数,吃透面试高频考点

说实话,我见过太多人学SQL的方式是错的。买了一堆书、收藏了一堆教程,打开软件却写不出一条能跑的查询。你问他连表查询会用吗,他说会;你让他现场写一条“查每门课成绩最高的学生”这种题,他当场卡住。SQL这东西,知识点就那么多,真正拉开差距的是你动手写过多少、踩过多少坑。

这份“50道SQL练习题”就是冲着这个问题来的。它不是一堆零散问题的大杂烩,而是按知识点密度和难度梯度排过的题单,覆盖了多表连接、分组聚合、子查询、窗口函数、去重空值处理这些SQL面试和日常开发的高频考点。这篇文章我不打算把50道题全部贴一遍——那样反而让你懒得思考——而是把题目体系的设计思路、核心考点的拆解方法、还有做题时最容易踩的坑全部讲透,并挑几道最有代表性的题带你把完整解题过程过一遍。不管你是准备面试的开发者,还是刚从教程里出来不知道怎么上手的新手,照着这个思路练完,效果会非常明显。

1. 题目体系的设计思路与拆解

1.1 为什么是50道,而不是20道或者100道

先说个实情:我最初整理这套题的时候,其实是从20道开始的。练到后面发现覆盖不全——窗口函数还没练、自连接没涉及、行列转换这种变态题也没放进去。后来加到了50道,才算把基础语法、中级查询、高级分析这三大块都兜住了,同时又把重复度压到了最低。

50道题的数量是有讲究的。20道太少,很多知识点只能浅尝辄止,像GROUP BY配合HAVING的坑、NULL值处理这种细节,不靠题量堆是记不住的;100道又太多,大部分人根本刷不完,刷到30道就开始疲了,导致后面全是无效重复。50道这个量,恰好能在两周内练完,每天抽出40分钟到1小时做3到4道,周末集中攻克难题,节奏正好。

从知识点覆盖上来看,这套题大致是按下面这个比例分配的:

知识点板块题目数量难度区间对应场景
基础查询与条件过滤8道入门WHERE、ORDER BY、LIKE、IN、BETWEEN
聚合与分组统计12道入门到进阶GROUP BY、HAVING、COUNT/SUM/AVG
多表连接与子查询15道进阶JOIN、自连接、EXISTS、IN子查询
窗口函数与排名8道高阶ROW_NUMBER、RANK、SUM OVER 等
去重、空值、时间与综合7道进阶到高阶DISTINCT、NULLIF、日期函数、综合练习

这个比例不是拍脑袋定的。关系型数据库面试的核心无非就是“查得出来、查得对、查得快”——前两类题保证你能正确取数,第三类题是业务开发里最常用的技能,第四类解决的是“分组内排名”“累计求和”这类复杂报表需求,最后一类把各种坑集中踩一遍,加深记忆。

1.2 经典四表模型:为什么练习SQL要有一份稳定的数据

这套50题用的是经典的“学生-课程-成绩-教师”四表模型。为什么要用这个模型?因为它足够简单,四张表之间的关联关系清晰,而且高度贴合真实业务——学生表对应“用户表”、课程表对应“商品/品类表”、成绩表对应“订单/流水表”,你在工作中遇到的绝大多数查询,本质上都是在处理这种“主表+明细表+维度表”的关系。

四张表的建表语句我直接放出来,你可以一次性建好,后面做题反复用:

-- 学生表 CREATE TABLE Student ( SId VARCHAR(10), Sname VARCHAR(20), Sage DATETIME, Ssex VARCHAR(10) ); -- 课程表 CREATE TABLE Course ( CId VARCHAR(10), Cname VARCHAR(20), TId VARCHAR(10) ); -- 教师表 CREATE TABLE Teacher ( TId VARCHAR(10), Tname VARCHAR(20) ); -- 成绩表 CREATE TABLE SC ( SId VARCHAR(10), CId VARCHAR(10), score DECIMAL(5,2) );

注意这里的几个细节:Sage用的是DATETIME而不是单纯的年份,就是为了让你在练习时接触到时间函数;score用的是DECIMAL而不是INT,是为了保留小数位,方便后续AVG这类聚合运算。成绩表SC是典型的关联表,里面只存ID和分数,和实际业务里的订单表逻辑一样。

我见过有人为了“省事”把所有数据放在一张大宽表里练,这其实是个坏习惯。真实业务几乎不会给你一张现成的宽表,绝大多数时候你需要自己JOIN出宽表。保持多表结构练习,才能锻炼出“看到需求就想到关联路径”的肌肉记忆。

1.3 不同基础的人应该怎么练这套题

新手最容易犯的错就是从头开始一题一题按顺序刷,遇到不会的就开始挠头,挠不出来就看答案,看完觉得自己会了,合上屏幕又不会了。正确的打开方式是按阶段来:

如果你的SQL基础比较薄弱,我建议先跳过带“排名”“累计”字样的窗口函数题,把前20道基础题做扎实了再回头啃。基础题的正确标准不是“写出了就行”,而是“不查资料就能写出来”。我自己的经验是,一道题如果当天做完、第二天还能凭记忆重写一遍,才算真正掌握。

如果你已经有一定经验、主要是为了面试突击,可以直接从第20题之后开始做,但每道题都要问自己三个问题:这个查询用到的关键函数是什么?还有没有别的写法?哪个写法在数据量大时性能更好?比如同样是“查每门课成绩最高的学生”,子查询、窗口函数、自连接三种写法都能实现,但跑在百万级数据上,性能会差出好几倍。这个问题在后面第4部分我会详细展开。

2. 核心考点拆解与答题思路

2.1 多表连接:INNER JOIN、LEFT JOIN 和自连接到底怎么选

多表连接是SQL里最核心也最容易出错的考点。50道题里涉及连接的至少有一半,而连接题里最大的坑不是语法不会写,而是“用错连接类型导致结果比预期多或比预期少”。

我讲讲最常见的场景。比如有一道题是“查询所有学生的学号、姓名、选课数”,这个需求的关键词是“所有学生”。只要出现“所有”,就意味着有的学生可能没有选任何课,如果成绩表里压根没有他的记录,用INNER JOIN就会把这个学生丢掉,结果自然不对。这时候必须用LEFT JOIN把学生表放在左边作为驱动表。

但如果你用的是LEFT JOIN,第二个坑马上会冒出来:COUNT函数的计数对象。我见过太多人写COUNT(SC.CId)COUNT(*)结果对不上的情况。左连接之后,没选课的学生在成绩表对应的列全是NULL,COUNT(SC.CId)只统计非NULL的行,所以结果是0;而COUNT(*)统计的是连接后的所有行,结果是1。这里一定要记住:统计子表的行数,永远用子表的字段去COUNT,不要用COUNT(*)

自连接是另一个让新手头疼的东西。比如“查询每门课成绩不低于该课程平均分的学生”——你需要把同一张成绩表当作两张表来用,一张取学生成绩,一张计算平均分。我第一次练这个连接时脑子绕不过弯,后来我用了个土办法:把同一张表想象成两份独立的打印件放在桌上,一份用于查明细,一份用于聚合计算,写SQL时就写上不同的别名,这样就好理解多了。

2.2 分组聚合:GROUP BY 和 HAVING 的经典陷阱

分组聚合在练习题里占的比重最大,也是日常工作里最常用的功能,但坑也最多。最经典的一个坑就是“GROUP BY之后SELECT了没被分组的列”——这在MySQL里甚至能跑出结果,但那一列的值是随机的、毫无意义;在SQL Server或PostgreSQL里直接报错。我见过不止一个开发同事因为这个“随手写”的查询,在报表里查出了对不上的数据。

正确的聚合查询只有两类:GROUP BY后面跟着的列,或者被聚合函数包起来的列。其他任何裸列都不要出现在SELECT里,这不是语法限制,而是逻辑保证。

HAVING的坑则在于很多人分不清它和WHERE的区别。一句话记住:WHERE在分组之前过滤行,HAVING在分组之后过滤组。写“查询平均分大于60分的学生”这种题时,逻辑上必须先按学生分组、计算平均分,然后才能把平均分大于60的筛选出来,所以只能用HAVING;而“查询2024年入学的学生”这种条件,在分组之前就能过滤掉,用WHERE是最优选择——因为WHERE过滤掉的行不参与分组计算,顺带还能减少聚合的开销。

2.3 去重与空值:DISTINCT 和 NULL 的那些坑

去重是SQL入门就学的东西,但题目里真正想考的是“用对地方”。有一个常见的误区是认为COUNT(DISTINCT 列名)和先DISTINCT再COUNT结果一样——确实一样,但前者在数据量大时会有严重的性能问题,因为DISTINCT本质上是排序去重,消耗很大。更高效的做法是先用子查询把要去重的集合缩小,再在外层做聚合。这套练习题里专门有一道“统计每门课的选课人数(一个学生同一门课只算一次)”,考的就是这个逻辑。

NULL值的处理更是SQL里永恒的坑。举个最典型的例子:WHERE 字段 != 'A'这个查询查不出字段为NULL的行——因为NULL和任何值比较都是UNKNOWN,WHERE只保留结果为TRUE的行。50道题里专门设计了“查询没有参加任何考试的学生”“统计成绩为空的学生人数”这类题,目的就是把IS NULLIS NOT NULLIFNULLCOALESCE这类处理手法练熟。

我在实际开发中还踩过一个更隐蔽的坑:用COUNT(列名)统计某列非空数量时,如果列里有NULL,统计结果会自动把它们剔除。这个特性有时候是好事,有时候却会掩盖数据质量问题——比如统计“订单金额大于100的订单数”时,如果部分订单金额字段是NULL,这单就会被悄悄漏掉,而业务方根本不知道。所以每次写完带COUNT和NULL判断的SQL,最好像强迫症一样检查一遍逻辑覆盖的范围。

2.4 窗口函数:解决“分组内排名”“累计求和”这类问题的利器

窗口函数是近几年面试的高频考点,也是从“会写SQL”到“写得优雅”的分水岭。这套题里至少有8道题涉及窗口函数,其中最常考的是三兄弟:ROW_NUMBERRANKDENSE_RANK

它们的区别必须刻在脑子里:ROW_NUMBER无脑给每一行分配一个连续不重复的编号;RANK遇到相同值会并列,但下一个名次会跳过(比如1、1、3);DENSE_RANK遇到相同值也并列,但下一个名次不跳过(比如1、1、2)。我见过有人面试时在这三个函数上翻车的——题目没变,只是数据里恰好有并列分数,他想当然以为排名永远是连续的。

比如经典题“按课程分组,查询每门课程成绩排名第一的学生”,用窗口函数是最直接的写法:

SELECT CId, SId, score FROM ( SELECT CId, SId, score, ROW_NUMBER() OVER (PARTITION BY CId ORDER BY score DESC) AS rn FROM SC ) t WHERE rn = 1;

这段SQL的逻辑分三步:先用窗口函数在每门课内部按分数降序编号,再在外层过滤出编号为1的行。PARTITION BY就是“分组”的意思,但它和GROUP BY最大的不同是:窗口函数不会压缩行数,每一行都保留自己的编号,这样后续还能拿到整个分组的上下文信息。

除了排名,窗口函数还有一个高频应用是“累计求和”,比如“查询每门课程每个学生的分数,并计算该学生在本课程中的所有分数排名”——这类问题用自连接写会很痛苦,用SUM(score) OVER (PARTITION BY CId ORDER BY score)一行就能搞定。

3. 实操过程:从建表到完整解题演示

3.1 环境准备与模拟数据的生成

工欲善其事,必先利其器。开始做题前,建议先准备一个干净的执行环境。如果你电脑上装了MySQL 8.0或SQL Server 2019以上版本,直接用就行;如果什么都没装,强烈推荐Docker方式拉一个MySQL 8.0镜像,两分钟就能跑起来,还不会把系统搞乱。

事务和数据部分,我建议不要手工一行行往表里插,写个脚本来生成模拟数据更高效。下面是我用来生成学生表和成绩表的常用写法,你直接抄走就能用:

-- 生成1000个学生(这里只示例几个) INSERT INTO Student (SId, Sname, Sage, Ssex) VALUES ('01', '赵雷', '1990-01-01', '男'), ('02', '钱电', '1990-12-21', '男'), ('03', '孙风', '1990-05-20', '男'), ('04', '李云', '1990-08-06', '男'), ('05', '周梅', '1991-12-01', '女'); -- 生成成绩数据时,可以用笛卡尔积快速填充 INSERT INTO SC (SId, CId, score) SELECT s.SId, c.CId, ROUND(50 + RAND() * 50, 2) -- 随机生成50到100之间的分数 FROM Student s CROSS JOIN Course c WHERE RAND() > 0.2; -- 留出20%的空选,模拟真实情况

这里有个细节:我用ROUND(50 + RAND() * 50, 2)生成随机分数,这比手工写死分数实用得多——数据量一大,你才能体会到分组聚合和连接查询在真实数据量下的性能和结果差异。另外我在插入成绩时故意留了20%的缺考记录,就是为了让后面“查没选课的学生”“处理NULL值”这类题目有数据可查。真实业务的数据永远是“脏”的,练习时就应该用带坑的数据。

3.2 五道代表性题目的完整拆解

下面我从50道题里挑5道最有代表性的,把思考过程和写法完整过一遍,你可以看完之后举一反三。

第1题:查询“01”课程比“02”课程成绩高的所有学生的学号。这道题看似简单,其实考的是“同表多行转列”的思路——你需要把同一个学生的两门课成绩放到同一行才能比较,而成绩表里每个学生每门课是单独一行。解法是用自连接或两个子查询分别取出两门课成绩后再JOIN。经典写法:

SELECT a.SId FROM SC a JOIN SC b ON a.SId = b.SId WHERE a.CId = '01' AND b.CId = '02' AND a.score > b.score;

这里把SC表当作两个表用,别名a和b分别对应课程01和02的成绩。我最初练这道题时想的就是“怎么把行变成列”,后来才明白本质是“同表不同行的字段需要横向比较时,就用自连接把多行变成一行”。

第2题:查询平均成绩大于60分的学生学号和平均成绩。这道题核心是GROUP BY + HAVING组合,非常经典。写法如下:

SELECT SId, AVG(score) AS avg_score FROM SC GROUP BY SId HAVING AVG(score) > 60;

有人第一反应会用WHERE,写了WHERE AVG(score) > 60,结果报错。原因之前讲过了:WHERE是在分组前执行的,它没法知道分组的聚合结果。这里补充一个经验:HAVING里写AVG(score)不是必须与SELECT里的聚合函数重复,但为了可读性建议保持一致,不要一个写AVG一个写SUM,排查问题时会很崩溃。

第3题:查询所有课程成绩小于60分的学生姓名。这道题暗藏了一个逻辑陷阱。“所有课程都小于60分”不等于“最少有一门课小于60分”。如果你写成找成绩小于60的记录,那结果会把只挂了一科的人也包含进去。正确逻辑是:先找所有课程里最高分都小于60的学生——也就是不存在任何一门课大于等于60分。用NOT EXISTS子查询写清晰又高效:

SELECT Sname FROM Student s WHERE NOT EXISTS ( SELECT 1 FROM SC sc WHERE sc.SId = s.SId AND sc.score >= 60 );

NOT EXISTS的语义是“不存在满足条件的行”,顺着这个思路反着想,很多“所有”“全部”类型的问题都能转化成NOT EXISTS。这套题里类似的反向思维还有好几道,练多了你会发现SQL的逻辑其实很像数学里的逆否命题。

第4题:查询每门课程成绩排名前三的学生。这道题用窗口函数是最自然的方式:

SELECT CId, SId, score FROM ( SELECT CId, SId, score, DENSE_RANK() OVER (PARTITION BY CId ORDER BY score DESC) AS rk FROM SC ) t WHERE rk <= 3;

注意这里我用了DENSE_RANK而不是ROW_NUMBER。为什么?因为业务需求往往关心“并列前三”——如果第三名有并列,ROW_NUMBER会把并列的人拆成第3和第4,导致排名结果不完整;DENSE_RANK会正确地把并列第三的两个人同时保留。实际开发里做排行榜、TopN报表时,这个选择直接影响结果的正确性,一定要根据业务语义来选。

第5题:查询各科成绩的总分排名。这道题综合了聚合函数和窗口函数的配合:

SELECT CId, SUM(score) AS total_score, RANK() OVER (ORDER BY SUM(score) DESC) AS ranking FROM SC GROUP BY CId;

注意窗口函数是在GROUP BY完成之后才计算的,所以窗口函数里可以直接用SUM(score)作为排名字段。这算是一道典型的综合题——如果GROUP BY和窗口函数的执行顺序搞混,这道题基本写不出来。SQL的执行顺序大概是:FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> 窗口函数,理解这个顺序对调试复杂查询帮助极大。

3.3 从练习题到面试题的迁移能力

很多人练习时会陷入一个误区:题做完了就完了,没有总结。但面试官真正想考察的从来不是“你会不会做这道题”,而是“你面对一个从没见过的业务需求时,能不能用SQL高效解决”。

比如上面第4题“每门课前三名”,面试时可能换皮变成“查每个部门工资最高的员工”“查每个品类销量最好的商品”。结构完全一样,只是换了表和字段。所以我的建议是:每做完一道题,停下来花1分钟想一下——这个查询模式还能用在什么业务场景?能不能换个表复现一遍?

我自己的经验是,50道题做完后,真正内化成能力的是十几种查询模式,而不是50个孤立答案。这些模式包括:行转列、取分组TopN、累计求和、多条件关联、存在性判断、非空处理等。把这些模式融会贯通,遇到任何新需求都能快速匹配到对应的解法。

4. 常见问题与排查技巧实录

4.1 查询结果和预期不符,第一步该查什么

做题和实际开发中遇到“结果不对”是常态,关键要有一套高效的排查顺序。我自己的排查经验是三步走:第一步,把SQL拆成小块逐段执行,尤其是子查询和JOIN部分,先分别跑一遍看中间结果对不对;第二步,确认关联字段是否有重复值,如果关联字段在子表中不是唯一的,JOIN结果会成倍膨胀,这也是“结果比预期多”的头号原因;第三步,检查过滤条件中是否存在NULL值数据,如果你查“分数小于60”的学生,那些成绩为NULL的缺考学生会默默被过滤掉——这往往是“结果比预期少”的元凶。

举一个我踩过的具体例子:有一次统计“每门课的报名人数”,我直接对成绩表做GROUP BY,得出的数字比业务方给的少了将近三成。排查了半天才发现,问题在于成绩表只存了“已出分”的记录,还有一些学生选了课但分数为NULL、根本没进这张表。要拿到真实报名数,必须左连接选课表和成绩表,再按选课表分组。这个坑就是典型的数据表设计语义和业务语义不一致造成的,练习时遇到这类题不要只满足于“能跑通”,还要多想一步“统计口径对不对”。

4.2 EXPLAIN 怎么看:慢SQL优化的核心入口

热搜词里“慢sql优化 explain主要看哪些信息”这个关键词特别典型。50道练习题虽然主要目的是“写对”,但等你写到后面涉及大数据量的题目时,必然会遇到“能跑但跑得慢”的情况。这时候EXPLAIN就是最重要的工具。

EXPLAIN输出结果里,我最关注的永远是四个东西:

  • type列:这是访问类型,从好到差大致是const -> eq_ref -> ref -> range -> index -> ALL。看到ALL(全表扫描)而表数据量又很大时,基本可以确定需要加索引了。
  • key列:实际用到的索引。如果key是NULL,说明没走索引,得检查WHERE条件里的列有没有被索引覆盖。
  • rows列:预估扫描行数。这个数字越大,查询越可能慢。优化目标就是让这个数字尽量小。
  • Extra列:如果出现Using filesort(文件排序)或者Using temporary(临时表),意味着排序和去重操作占了额外资源,数据量在大并发下容易成为瓶颈。

我举个例子,第4题窗口函数那个查询在外层加了WHERE rk = 1,如果子查询里没有在(CId, score)上建联合索引,EXPLAIN会显示如下:

id select_type table partitions type possible_keys key rows Extra 1 PRIMARY <derived2> ALL NULL NULL 1000 Using where 2 DERIVED SC ALL NULL NULL 1000 Using temporary; Using filesort

看到Using temporary; Using filesort就要有警觉了——这说明窗口函数的排序是在临时表里完成的,数据量大时会比较吃力。解决办法是给SC表建一个(CId, score)的联合索引,让排序直接走索引。

4.3 练习题阶段常犯的三个语法细节错误

除了逻辑错误,练习题阶段还有三个特别常见的语法细节错误,我几乎在每一个来求助的人身上都见过:

第一,字符串和数值比较时类型不匹配。比如WHERE Sage = '1990',如果Sage是DATETIME类型,这个写法在部分数据库里能跑但结果诡异,在另一些数据库里直接报错。正确做法是用年份函数:WHERE YEAR(Sage) = 1990

第二,别名表名用了中文或保留了空格。比如ORDER BY 平均分 desc,这在某些数据库配置下会报错或者引发奇怪的排序结果。正确做法是给别名加反引号或双引号:ORDER BY 平均分 DESC

第三,分页时ORDER BY字段不唯一导致数据重复或丢失。比如你用LIMIT 10 OFFSET 0LIMIT 10 OFFSET 10分页,但排序的列有重复值,MySQL的排序在值相同时是不保证顺序的,两页之间可能出现重复记录或漏掉记录。解决办法是在ORDER BY最后加一个唯一字段(比如自增ID)。

说实话,这些错误都不是“不会写SQL”造成的,而是“没有养成好习惯”造成的。我在做完50道题之后回头看,成长最快的不只是会写的语法变多了,而是写完SQL之后会自动检查这些细节——这本身就是高级工程师和初级工程师的差别之一。

4.4 练习题之外的提醒:心法比题量更重要

最后再说一点隐藏的“潜规则”。搜SQL相关热词时,你一定看到过“SQL注入万能密码绕过”这个词。SQL注入的本质是“用户输入拼接进了SQL语句,被当作代码执行了”——比如一个登录框里输入' OR '1'='1,如果你的SQL写的是字符串拼接,这个输入就会绕过密码校验。作为写SQL的人,一定要建立一道底线思维:永远不要在前端/后端代码里用字符串拼接的方式写SQL,必须使用参数化查询或预编译语句。这不是练习题里能直接考出来的,但它是每一个真正在工作中写SQL的人必须刻在脑子里的安全意识。

还有一点,很多人练完50道题觉得自己“会SQL了”,但真实业务里的SQL基本都不会像练习题这样把条件给得明明白白。实际工作中你需要自己判断:这个查询该不该开只读事务?要不要限制返回行数?要不要加索引?要不要考虑数据倾斜?这些软技能,恰恰是练习题之外更需要刻意培养的。所以我更建议把这50道题理解为一个起点——先把底子打牢,再往真实场景里扎。

根据我自己的实操体会,刷完这50道题之后,最值得做的事是拿一份真实的脱敏业务数据,自己给自己出题:比如分析“最近30天各品类的销售趋势”“各区域用户的复购率”这种综合需求。只有这样,SQL才会从“题目里的语法”变成“你手里的工具”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 8:09:03

信创环境下DevOps实践:国产化工具链与性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 8:08:01

Elasticsearch 写入链路优化:Bulk 批量、Refresh 策略与写入吞吐调优

Elasticsearch 写入链路优化&#xff1a;Bulk 批量、Refresh 策略与写入吞吐调优 Elasticsearch 作为一款强大的搜索引擎&#xff0c;其写入性能往往成为整个系统的瓶颈。本文将深入探讨 Elasticsearch 写入链路优化的三个关键方面&#xff1a;Bulk 批量操作、Refresh 策略调整…

作者头像 李华
网站建设 2026/9/13 8:07:59

多模态推理架构落地:端侧部署与端云协同的四大关键方向

2025年我做技术评审时&#xff0c;几乎每一场研讨都会争同一个问题&#xff1a;多模态推理到底应该放在哪一端&#xff1f;云端算力充分&#xff0c;但延迟和隐私兜不住&#xff1b;端侧响应快&#xff0c;可模型一上视觉就发热、掉电、内存爆掉。争论到最后&#xff0c;经常变…

作者头像 李华