简介《Java编程面试题》是一份面向Java初中级开发者与求职者的面试练习文档围绕基础语法、循环与条件判断、数学运算及常见算法组织题目适合面试前查漏补缺和动手编码训练。压缩包共1个doc文件大小约104KB内容以可直接运行的示例代码和题目分析为主便于集中阅读与本地调试。节选可见斐波那契数列、101—200素数统计、水仙花数、分解质因数、成绩等级转换及最大公约数与最小公倍数等经典程序既给出实现思路也呈现关键循环与边界处理方式。已有142人学习读者可据此熟悉面试中常见的现场编码题型理解递归与迭代取舍、循环终止条件和取模除法等细节并借助代码示例梳理从读题到实现的解题路径提升基础算法与逻辑表达能力。1. 兔子题翻车现场Java 编程面试题最像送分、最容易丢分的一道Java 编程面试题里最像送分、实际最容易翻车的是那道兔子题一对兔子从第三个月起每月生一对兔子都不死问第 24 个月有多少对。多数人一眼认出这是斐波那契落笔却卡在三个变量的赋值顺序上——先写f2 f1 f2再写f1 f2两个变量立刻变成同一个值答案从 46368 变成一串 2 的幂。这类题不考你会不会写for考的是能不能把一段业务描述翻译成三件事谁是当前值、谁是上个月的值、循环从第几个月开始。校招机试、初中级 Java 岗的电话面、外派与金融科技岗的机考翻来覆去都是这十九道题的变体。下面按考点拆每类给出真题、答题思路和容易踩的坑。2. 考点分布十九道经典题拆成六类先看清面试官在考什么2.1 一张表看懂这十九道题的分值感面试现场不会给你打分表但考官心里的权重很稳定能不能把思路讲清楚占一半代码写不写得出来占三成剩下两成看边界和异常。十九道题按考法归成六类重复率极高。题型原文代表题面试官真正在看的循环递推兔子、猴子吃桃、aaaaaa会不会用变量保存状态赋值顺序对不对素数、数论判定素数统计、分解质因数、最大公约数、完数、完全平方数循环上界、提前 break、有没有数学直觉分支与区间成绩等级、分段提成、日期天数、三数排序边界值、区间是否重叠或漏空字符处理统计字母、空格、数字、其他字符char和int的区别、字符串 API 熟不熟穷举与约束四个数字组成三位数、乒乓球队对阵去重条件写全没有、约束是否互斥图形输出菱形、九九乘法表找行规律、空格与换行的控制从表里能看出一个规律这六类题里真正考察「算法」的只有素数和最大公约数两处其余全是基本功。这也解释了为什么很多公司愿意用它们做初筛——它们筛的不是聪明程度是写代码时有没有纪律。2.2 真题演练兔子问题考的是变量升级而不是递归面试官最想听的答案是先说清楚递推关系第 n 个月的兔子对数等于前两个月之和因为第 n 个月新生的兔子来自第 n-2 个月已有的兔子。说清这层再动笔写循环分数就稳了一半。public class FibRabbit { public static void main(String[] args) { int months 24; // 要求的月数 long f1 1, f2 1; // f1 表示上上个月f2 表示上个月初始都是 1 对 System.out.println(第 1 个月 f1); System.out.println(第 2 个月 f2); for (int i 3; i months; i) { long cur f1 f2; // 先算新值绝不覆盖已有状态 f1 f2; // 状态整体后移一格 f2 cur; System.out.println(第 i 个月 f2); } } }三个参数决定这段代码对不对。months控制循环终点从 3 开始是因为前两个月是已知初值写从 1 开始就要额外特判。f1和f2是滚动变量顺序必须是「先算新值再挪旧值」cur这个中间变量存在的唯一理由就是防止覆盖。类型用long而不是int因为第 47 个月就会突破 int 上限题目只问 24 个月不出事但面试官常顺手改一句「问第 60 个月」。原文版本用f做临时变量f f2; f2 f1 f2; f1 f;逻辑完全等价只是绕了一步。真正危险的是把它改写成f1 f2; f2 f1 f2;这时候f1已经被覆盖f2变成了两倍的旧f2输出会变成 1、1、2、4、8……这一类错误在白板上极常见考官的判断也很直接能意识到赋值有先后才是真的理解递推。有人会主动补一句「用递归也能写但第 24 个月要调用几十万次栈深和时间都吃亏加记忆化数组就退化成动态规划」。这句话说出口兔子题就从送分题变成了加分题。2.3 真题演练素数统计上界写成 sqrt 还是 i*i 有讲究判断 101 到 200 之间有多少个素数是典型的「会写但有瑕疵」题。原文思路正确实现上有一处不大不小的隐患。public class PrimeCount { public static void main(String[] args) { int count 0; for (int n 101; n 200; n 2) { // 偶数不可能是素数步长取 2 if (isPrime(n)) { System.out.print(n ); count; } } System.out.println(); System.out.println(101-200 之间的素数个数 count); // 21 } static boolean isPrime(int n) { if (n 2) return false; // 0、1 和负数不是素数 if (n 2) return true; // 2 是唯一的偶素数 if (n % 2 0) return false; // 其余偶数直接排除 for (int i 3; (long) i * i n; i 2) { // 用乘法代替 sqrt规避浮点误差 if (n % i 0) return false; // 找到一个因子就能跳出 } return true; } }参数与边界说明n从 101 起步、步长 2跳过偶数只为少跑一半循环不影响结果因为 2 被单独处理。内层上界写i * i n而不是i Math.sqrt(n)一是省去每次循环的浮点开方二是避免大数时sqrt的精度问题把边界算错一位前面加(long)是防止i * i在接近 int 上限时溢出成负数导致循环提前结束。原文里的boolean b false是这题的经典写法瑕疵。b在循环外初始化为false只有走到else分支才被改成true也就是说最终结果取决于最后一次迭代走了哪个分支。对 101 到 200 这段数没错但如果传入 2、3 这种内层循环根本不执行的数b会保持false而被误判成非素数。正确做法是把「默认是素数」写在前头一旦发现因子立刻置false并break语义才和判断逻辑对齐。2.4 面试官视角为什么循环题能筛人白板上写循环题考官其实在观察三件小事。看你会不会先要边界问一句「101 到 200 是闭区间吧」说明你写代码前会确认输入。看你会不会主动简化提到偶数步长、sqrt 上界说明你知道暴力法之外还有常数优化。看你写完会不会自测写完素数统计自己念一遍「2、3、4」跑一跑比事后被指出 bug 强得多。这也是刷这十九道题的正确姿势。不要背代码把每道题拆成「输入是什么、输出是什么、中间靠哪几个变量滚动」三段写之前口述一遍。真正上场时脑子空白的概率会低很多毕竟题目的骨架你已经拆过十几次。3. 数论型循环五道题的通用骨架与答题模板3.1 水仙花数取位三板斧位数一变就翻车水仙花数指各位数字的立方和等于自身的三位数。真正的考点不在立方在取位怎么把一个整数拆成千、百、十、个。public class Narcissus { public static void main(String[] args) { for (int m 100; m 999; m) { int hundreds m / 100; // 百位整除 100 int tens m % 100 / 10; // 十位先去掉百位再整除 10 int units m % 10; // 个位对 10 取余 if (hundreds * hundreds * hundreds tens * tens * tens units * units * units m) { System.out.println(m); // 153、370、371、407 } } } }m / 100靠整除截断m % 100保留后两位再/ 10得到十位m % 10直接拿个位。这三个式子是所有拆位题的母版四位数就多加一步m / 1000。参数上唯一的坑是范围水仙花数定义在三位数m从 100 起原文从 101 起也不会漏解但养成「范围按定义写」的习惯遇到 100 这类边界值时才不会心虚。面试官经常在这题上加一句「如果换成四位数的四叶玫瑰数呢」。这时候要能立刻答出两件事判断条件改成四次方和取位改成循环取余。static boolean isArmstrong(int n) { String s String.valueOf(n); // 位数由字符串长度决定 int len s.length(); int sum 0, tmp n; while (tmp 0) { int digit tmp % 10; // 每次取出最低位 sum Math.pow(digit, len); // 累加该位的 len 次方 tmp / 10; // 削掉最低位 } return sum n; }这段的关键参数是len它把「立方」抽象成「位数次方」水仙花、四叶玫瑰、五角星数全部共用同一个方法。写出来之后面试官基本不会再追问拆位因为他已经确认你能把具体问题泛化。3.2 分解质因数除法收缩k 不要回退到 2输入 90 输出902*3*3*5这题的分水岭在于理解「为什么被除掉的因子不会再次出现」。import java.util.Scanner; public class PrimeFactor { public static void main(String[] args) { Scanner sc new Scanner(System.in); int n sc.nextInt(); System.out.print(n ); for (int k 2; k n; k) { // k 只增不减 while (n % k 0 n ! k) { // 能整除且还没除到自身 System.out.print(k *); n / k; // 商作为新的 n继续被 k 除 } if (n k) { // 剩下的 n 本身是质数收尾 System.out.println(n); break; } } } }外层k从 2 开始递增内层while反复用同一个k去除是因为 90 里有三个因子 3必须一次除干净。k不回退到 2 的理由是任何小于当前k的质数都已经被除尽如果n还能被它整除前面的循环早就处理掉了。循环终止条件n k意味着剩下的是最后一个质因子直接打印收尾否则输出末尾会多出一个星号——这是这题最常见的格式扣分点。面试时加一句「最坏情况是 n 本身为大素数循环要跑 n 次改进是只枚举到k * k n循环结束后若n 1剩下的n就是最后一个质因子」能把时间复杂度从 O(n) 讲到 O(√n)。3.3 最大公约数辗转相除的迭代写法与一个溢出坑原文用单独的deff类做辗转相除思路正确但类名可读性差且最小公倍数的算法有溢出风险。public class GcdLcm { public static void main(String[] args) { int a 18, b 24; int g gcd(a, b); // 最大公约数 long l (long) a / g * b; // 先除后乘避免 a*b 溢出 System.out.println(最大公约数 g); // 6 System.out.println(最小公倍数 l); // 72 } static int gcd(int x, int y) { while (y ! 0) { int r x % y; // 余数 x y; // 除数变成被除数 y r; // 余数变成除数 } return x; // 余数为 0 时的被除数即答案 } }while (y ! 0)是辗转相除的核心三轮之内就能收敛不需要判断x和y谁大谁小如果x y第一轮x % y等于x两个变量自动交换位置。原文先做if (x y)交换属于写给人看的保险逻辑上并非必需。返回值是y 0时的x这一点要能解释清楚面试官喜欢追问「循环结束时为什么返回 x」。最小公倍数写成a / g * b而不是a * b / g是纯粹的工程习惯。a * b在 int 下超过 21 亿就溢出先除以最大公约数再乘结果不变但中间值小得多。这类细节单独看不值钱但在一份满是循环的答卷上它能证明你写过的代码不只跑在作业本里。3.4 完数与完全平方数枚举上界和判定写法完数题给的是 1000 以内找因子之和等于自身的数答案是 6、28、496。关键在上界内层枚举到i / 2就够因为真因子最大不超过自身一半写成i - 1只是白跑一半循环。for (int i 2; i 1000; i) { // 从 2 开始1 不是完数 int sum 1; // 1 是所有数的真因子先计入 for (int j 2; j i / 2; j) { if (i % j 0) sum j; } if (sum i) System.out.println(i); }把sum初始化成 1循环从 2 起省掉判断j 1的一步。注意这个版本和原文不同原文sum从 0 起、j从 1 起结果一样但对 1 要特别小心因为 1 会把自己算成完数。完全平方数那题更考验边界意识一个整数加 100 后是完全平方数再加 168 仍是完全平方数求该数。原文从 1 枚举到 10 万注释里自己承认漏掉了负数 -99。面试时正确的处理是先问一句「整数是否含负数」得到确认后再决定起点用 -100 还是 1。判定写法也有讲究Math.sqrt(x 100) % 1 0依赖浮点精确性数值大到一定程度可能因为精度误差误判稳妥写法是取整后平方回去验证static boolean isSquare(int n) { if (n 0) return false; int r (int) Math.sqrt(n); // 向下取整 return r * r n; // 平方回去比对杜绝浮点误差 }3.5 真题演练这类题的统一答题模板数论型的五道题白板上按固定四步走基本不会失分。第一句先说范围与定义比如「水仙花数定义在三位数所以我从 100 循环到 999」。第二步写出核心判定拆位、取余、试除挑最直白的那种别为了炫技写位运算。第三步处理边界包括 0、1、负数、等于 1 的特殊值。最后一步主动报复杂度并给一句优化方向比如试除上界用i * i n。这套模板的价值在于防漏。做过统计这五道题里扣分最多的不是算错而是漏情况漏掉 2 这个偶素数、漏掉负数解、漏掉最后剩下的质因子。把四步当成检查清单过一遍漏项会少很多。4. 分支与边界区间题的拿分点全在临界值上4.1 分段提成区间累加不要整段重新乘比例利润分段提成是这十九道题里最容易写错的没有之一。规则大意是10 万以内提 10%10 万到 20 万的部分提 7.5%20 万到 40 万的部分提 5%40 万到 60 万提 3%60 万到 100 万提 1.5%超过 100 万的部分提 1%。先看正确做法需要的「累计值」这张表利润区间万元本段比例到达该段上限时的累计奖金万元0 - 1010%110 - 207.5%1.7520 - 405%2.7540 - 603%3.3560 - 1001.5%3.95100 以上1%3.95 超出部分 × 1%原文里出现过20 * 0.175 20 * 0.05 20 * 0.03 (x - 60) * 0.015这种写法问题很明显它把前几段的比例和区间宽度随意乘在一起20 乘以 0.175 既不是第一段的 1 万也不是第二段的 0.75 万纯属凑数。利润 60 万时正解是 3.35 万按这行代码算出来是 5.1 万差了将近一倍。public class Bonus { public static void main(String[] args) { double profit 75; // 单位万元 double bonus; if (profit 10) { bonus profit * 0.1; // 只走第一段 } else if (profit 20) { bonus 1 (profit - 10) * 0.075; } else if (profit 40) { bonus 1.75 (profit - 20) * 0.05; } else if (profit 60) { bonus 2.75 (profit - 40) * 0.03; } else if (profit 100) { bonus 3.35 (profit - 60) * 0.015; } else { bonus 3.95 (profit - 100) * 0.01; } System.out.println(应发奖金 bonus 万元); // 75 万利润对应 3.575 } }写法要点是「累计常数 本段超出部分」常数直接查表不需要每次重新累加前几段。这样写的好处是每段只有一个乘法和一个加法审查时逐个区间带临界值验算即可。参数上要注意单位统一题目给的是万元代码里就不要混进元类型用double而不是int否则 7.5% 这类比例会被截断。面试官通常会连问三个数10 万、60 万、100 万正好是各段临界点。带上边界值自测一遍比嘴上说「我检查过了」有说服力。4.2 日期天数闰年判定与 switch 穿透输入年月日判断是这一年的第几天。这题的考点有两处闰年条件写全月份天数别漏。public class DayOfYear { public static void main(String[] args) { int year 2024, month 3, day 1; int[] days {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (isLeap(year)) days[1] 29; // 闰年二月改 29 天 int total 0; for (int i 0; i month - 1; i) { total days[i]; // 累加之前各整月 } System.out.println(year - month - day 是第 (total day) 天); } static boolean isLeap(int y) { return (y % 4 0 y % 100 ! 0) || y % 400 0; // 四年一闰百年不闰四百年再闰 } }闰年条件是固定考点两个分支缺一不可能被 4 整除且不能被 100 整除或者能被 400 整除。1900 年不是闰年、2000 年是闰年这两个例子背下来面试时随口举出来对方就知道你不是碰巧写对的。原文用switch加穿透累加也能得到同样结果case 1: case 3: ... days 31; break;这种写法在教材里很常见优点是直观、缺点是每个分支都要写。数组写法更短但注意数组下标从 0 开始days[1]对应二月别写成days[2]。原文还有一处值得提的校验缺口只判断了day 31没判断某月是否真的有这一天2 月 30 日能顺利通过。补充校验时要注意先判断月再判断日顺序反了会数组越界。4.3 三数排序三次交换和它的替代写法输入三个整数从小到大输出。最直白的解法是三种两两比较最多交换三次。int x 3, y 1, z 2; if (x y) { int t x; x y; y t; } // 保证 x y if (x z) { int t x; x z; z t; } // 保证 x 是三者最小 if (y z) { int t y; y z; z t; } // 保证 y z System.out.println(x y z);顺序不能乱前两次交换把最小值顶到x第三次才处理中间两个。如果先比较y和zx可能还是最大值后面两次比较就白做。这个「分层」思路是排序算法里选择排序的雏形面试时说明这一点等于顺手展示了你对算法脉络的理解。有人会写Math.min、Math.max组合或者Arrays.sort结果都对但这类题被设计出来的目的就是看你会不会手写交换。真要用 API至少先说一句「实际项目里我会用排序 API这里手写是为了展示逻辑」。4.4 真题演练把条件运算符嵌套讲清楚成绩等级那题用条件运算符嵌套grade x 90 ? A : x 60 ? B : C;一行写完。面试官可能会追问两个问题。第一个是「为什么不推荐这么写」回答方向是可读性嵌套超过两层维护成本上升团队代码规范通常要求拆成if-else或提前return。第二个是「如果分数是 -1 呢」这时候要能立刻意识到缺失了输入校验负分会被判成C。答题时把这两点主动说出来比等着被问显得更从容。分支类题目考官最想确认的其实只有一件事你有没有把「输入不合法」当成一种正常分支来处理。5. 字符、递推与图形模拟类题的手感和细节5.1 字符统计一个漏掉的单引号决定对错统计一行字符里字母、空格、数字、其他字符的个数看着简单原文里有个隐蔽错误ch A ch Z左边少了等号导致大写字母 A 被归进「其他字符」。输入ABC会得到字母 2 个、其他 1 个。char ch A; if (ch 0 ch 9) { digital; } else if ((ch a ch z) || (ch A ch Z)) { // 两端都要带等号 character; } else if (ch ) { blank; } else { other; }char在 Java 里是 16 位无符号整数和字符字面量比较时走的是编码值比较所以0到9连续、a到z连续、A到Z连续区间判断才成立。参数上要注意两个细节一是比较必须用单引号写成ch 0会编译失败二是读完一行要用nextLine()先调nextInt()再调nextLine()会读到空串这是血泪经验级别的坑。进阶回答可以提Character.isLetter(ch)、Character.isDigit(ch)这些 API顺带说明它们能处理非 ASCII 字符比手写区间更稳。说完再补一句「但这题的本意是考区间判断所以我先手写」立场就完整了。5.2 aaaaaa递推构造与类型选择求 aaaaaa… 共 n 项的和a 是一位数字n 由键盘控制。核心在一行递推每一项等于上一项乘 10 再加 a。long a 2; // 底数 int n 5; // 项数 long term 0, sum 0; for (int i 0; i n; i) { term term * 10 a; // 2 → 22 → 222 sum term; // 累加 } System.out.println(sum); // 24690用term保存当前项比原文的b b a; a a * 10;更好懂原文靠修改a本身来实现位数增长一旦中途需要原始a就取不到了。sum和term都用long因为 n 稍大一点比如 10 项以上2222222222早就超了 int 上限。参数说明里要强调 n 的范围控制n 超过 18 项long也扛不住实际场景该换BigInteger。5.3 猴子吃桃与自由落体一个逆推一个正推猴子吃桃是逆推题的模板第 10 天早上剩 1 个每天吃掉前一天的一半再多吃一个问第一天摘了多少。正向没法算只能倒着来。int peach 1; // 第 10 天早上剩余 for (int day 9; day 1; day--) { peach (peach 1) * 2; // 逆推先加回多吃的那个再乘 2 } System.out.println(peach); // 1534逆推的公式要把正向操作完整反过来正向是「除以 2 再减 1」逆向就是「加 1 再乘 2」。循环从第 9 天走到第 1 天共 9 次别多算一次变成第 0 天。自由落体是正推球从 100 米落下每次反弹回原高度一半求第 10 次落地时经过的总路程和第 10 次反弹高度。double h 100, s 100; // s 先记入第一次下落 for (int i 1; i 10; i) { // 再补 9 次往返 s h; // 上升 h / 2; s h; // 下降 } System.out.println(总路程 s); // 299.609375 System.out.println(第 10 次反弹 h / 2); // 0.09765625这题的坑在变量语义循环里h始终表示「上一次反弹高度」所以最后一次输出要再除以 2 才是第 10 次反弹高度而s的初值 100 对应第一次下落。把这两个变量的含义在纸上写清楚比反复调试快得多。5.4 菱形与九九表先找行规律再决定循环嵌套菱形是图形题的代表输入高度 7输出 7 行。做法是拆成上下两半上半 4 行行号 i 从 0 开始每行空格数W/2 - i星数2i 1下半 3 行行号从 1 开始空格数等于行号星数W - 2i。int H 7; // 高宽必须相等且为奇数 int half H / 2; for (int i 0; i half; i) { // 上半部分含中间最长一行 for (int j 0; j half - i; j) System.out.print( ); for (int k 0; k 2 * i 1; k) System.out.print(*); System.out.println(); } for (int i half - 1; i 0; i--) { // 下半部分从中间上一行倒着来 for (int j 0; j half - i; j) System.out.print( ); for (int k 0; k 2 * i 1; k) System.out.print(*); System.out.println(); }上下两半共用同一组公式只是遍历方向相反这样写不用记两套数字。参数上唯一的约束是高度必须是奇数否则中间那行会不对称写代码前顺口确认一句能省掉返工。九九乘法表考的是另一个习惯内层循环上界跟着外层走j i才能输出下三角。原文还加了一句「乘积小于 10 补一个空格」这是纯格式化细节能想到说明你注意过输出对齐但面试时不必强求。6. 易错点五个最容易翻车的地方6.1 初值错一位后面全错错在哪斐波那契循环从 1 开始、猴子吃桃多推一天、自由落体的s初值写成 0。这类错误在输出上表现为整体偏移一位但代码看起来毫无破绽。为什么错递推题的实际含义是「前 k 项已知从第 k1 项开始推」写代码时把已知项也放进循环里算了一遍或者把「第 10 天剩 1 个」当成「第 10 天吃完剩 1 个」。怎么答对动笔前先手写出前三项的值贴在注释里循环结束后拿第一项对照。这招在兔子题上尤其有效——第 1、2 个月都是 1第 3 个月是 2写错的话第三个输出立刻露馅。6.2 边界写死和混用错在哪素数判断漏掉平方根本身、完数因子枚举到i - 1、区间题写成x 10 x 20却漏了x 10。为什么错和在数学上只差一个点在代码里差一次循环分段区间的衔接点更是重灾区上一段用、下一段用衔接点就没人管了。怎么答对写完循环先把上界代进去算一遍比如判断 9 是否为素数i * i 9时 i 取 3能测出 3 是因子若写成i * i 9i 只到 29 会被误判成素数。分段题则要求每段都写成「左开右闭」首段用兜住 0。6.3 标记变量在内层循环里反复赋值错在哪素数统计里boolean b在循环外初始化成false只有走到else才变true最终结果依赖最后一次迭代走哪条分支。为什么错把「默认值」和「中途修改」混在一起代码能跑通纯属题目数据凑巧换个输入范围比如从 2 开始判断立刻给出错误答案。怎么答对标记位一律「初始化为乐观值发现问题立刻改并 break」boolean isPrime true;发现因子时isPrime false; break;。这样不管循环执行零次还是十次语义都是对的。6.4 分段题复制粘贴改一半错在哪分段提成的每一段都重新乘一遍比例结果第二段以后全部偏大日期题复制上月分支忘了改天数。为什么错六段代码长得几乎一样复用时只改了else if的条件忘了改里面的系数和常数。怎么答对改成长度更短的写法比如提成题用「前缀累计 本段超出」日期题用数组循环代码量一少复制粘贴的机会就没了。另外每段写完立刻带一个临界值验算10 万、20 万、60 万各代一次错得会非常明显。6.5 类名重复与输入未校验错在哪同一份代码里两次定义class input编译直接报错日期题只校验day 312 月 30 日也能通过。为什么错题目编号相近答案被复制到同一个文件里两个同名类撞车校验逻辑只想着「别超过 31 天」没想着「这个月有没有 31 天」。怎么答对一个文件只留一个 public 类工具类单独命名并加注释校验顺序固定为「年 → 月 → 日」日和月的上限从数组里取天然避免漏判。这两条都属于「写之前想一秒省下调试十分钟」的类型。7. 答题节奏机试三十分钟怎么分配才不慌这十九道题在真实场景里通常给 30 到 40 分钟两道手写。时间怎么切比多背两道题更影响结果。时间块动作检查点0 - 3 分钟读题写清输入、输出、取值范围有没有问清边界与负数3 - 6 分钟口述思路确定用哪几个变量滚动赋值顺序是否安全6 - 20 分钟写代码边写边注释变量含义循环起止、标记位初值20 - 26 分钟手算一个小样例跑一遍第 1 项、最后 1 项、1 个临界值26 - 30 分钟补边界处理说一句复杂度0、1、负数、空输入表里最值钱的是第 20 分钟那一格。绝大多数翻车不是思路错而是写完就交没拿纸笔跑一遍。兔子题写完后如果立刻代months 5手算一次得到 1、1、2、3、5赋值顺序的问题当场就能暴露。再补一份自测清单写完任何一道循环题都过一遍初值对不对循环从第几项开始上界用还是代进去算过一次没有有没有哪个变量在内层循环里被反复赋值类型够不够乘法会不会溢出最后一项的输出格式对不对末尾多不多星号、换行少没少。我自己带人练这十九道题的阶段最常做的一件事不是讲题而是让对方把写好的代码念给我听一句一句念变量在干什么。念到「这里 f1 变成 f2 了」的时候十个里有三个会自己停下来改。从那以后我每次碰递推和分段题都强制先本文还有配套的精品资源点击获取