尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

京东Java校招笔试题解析:从集合框架到JVM内存的考点复盘

京东Java校招笔试题解析:从集合框架到JVM内存的考点复盘 每年七八月牛客网和各类求职群里就会冒出大量“求京东Java笔试题”的帖子。我见过太多简历漂亮、项目经历扎实的学弟学妹最后却栽在笔试这一关。原因不是代码能力差而是没有摸透校招笔试题的“出题逻辑”。京东这套2019校招Java开发工程师笔试题放在今天回头看依然是国内大厂Java校招笔试里很有代表性的样本。它不考偏门框架不追新版本特性核心就盯住三件事Java基础语法与集合框架、JVM内存与异常机制、算法与数据结构基本功。换句话说它考的是“你写Java到底写得稳不稳”而不是“你背了多少面试八股文”。这篇文章我把这套笔试题里最有代表性的考点拆开逐一讲清楚考点背后的原理、做题时的思考路径以及我在实际开发和面试复盘里总结出来的易错点。如果你是正在准备校招的应届生或者工作一两年后想系统回炉一遍Java基础这篇内容可以直接拿来当复习提纲用。1. 京东校招笔试题的选题逻辑为什么它总爱考“基础中的基础”1.1 校招笔试的真正筛选目的很多人对校招笔试有误解以为企业是想通过笔试招到“什么都会”的全能型候选人。实际不是。校招笔试的定位是第一轮粗筛它的目标有两个一是验证候选人有没有扎实的计算机基本功二是把“能独立写代码解决问题”和“只能在IDE里拖组件”的候选人区分开。京东这套Java笔试题明显是按照这两条线来设计的。Java基础语法、集合类、String、异常处理这类题目考察的是第一条线——基本功扎不扎实排序算法、代码阅读题这类题目考察的是第二条线——能不能把脑子里的逻辑用代码准确表达出来。理解了这个逻辑备考方向就清晰了重基础、重原理、重手写代码能力而不是堆砌框架名和工具名。1.2 高频考点模块分布结合这套笔试题和历年口碑我把京东Java笔试题的高频考点模块做了个梳理考察模块典型考点出题频次Java语法基础面向对象特性、访问修饰符、运算符优先级极高集合框架ArrayList/LinkedList、HashMap原理、迭代器极高字符串String不可变性、常量池、拼接机制高JVM基础内存区域划分、OOM场景、GC基本概念中高异常处理受检异常与非受检异常、try-catch-finally高并发基础线程创建方式、线程安全类、synchronized中算法与数据结构冒泡排序、快速排序、链表操作极高新特性Lambda表达式、函数式接口逐年上升这套笔试题没有考Spring、MyBatis这类框架内容这是校招笔试的常见风格——笔试考基础面试聊项目。框架可以在实际工作中快速上手但Java基础不扎实的人项目做得越深踩的坑就越诡异。1.3 为什么“八股文”背多了反而吃亏现在网上流传的“Java面试八股文”很多但题库类资料有天然缺陷它只给答案不讲推导过程。比如“HashMap底层是数组链表红黑树”这句话背下来容易但笔试不会直接这么问。它可能给你一段代码问“这段代码在JDK 1.8下执行会发生什么”或者给你一个场景问“如何设计一个线程安全的HashMap”。这时候靠背答案就没用了。备考笔试的正确姿势是对每一个考点能自己推导出它的设计理由。HashMap为什么要用链表来解决哈希冲突为什么链表长度到8才转红黑树这些问题想通了题目怎么变你都能接住。这篇文章后面每个考点我都会有意识地讲“为什么”而不仅仅是“是什么”。2. 面向对象、集合框架与String别让送分题变成丢分题2.1 面向对象三大特性答题不要只背概念京东这套笔试题里面向对象特性的题目几乎每年都出现但提问方式很狡猾。它很少直接问“什么是封装、继承、多态”而是给你一段代码让你判断输出结果或者让说出某段代码违反了哪个设计原则。举一个常见的变形考法给你两个类父类有一个方法public void hello()子类重写了这个方法。然后写一段代码Parent p new Child(); p.hello();问输出是什么。这里考的就是“多态”的底层机制——方法调用在运行时根据实际对象类型确定而不是编译时变量类型。静态方法不存在重写属性也不存在多态这些是更细的坑。如果笔试里遇到“子类和父类具有同名属性通过父类引用访问输出什么”这类题目记住规则成员变量看编译时类型成员方法看运行时类型。这也是我建议大家复习时别只背“三大特性的定义”的原因。你要能画出一张“继承体系下代码执行顺序”的流程图父类静态块、子类静态块、父类实例块、父类构造器、子类实例块、子类构造器。这套顺序在京东的笔试题里反复出现本质是在考你对JVM类加载和对象创建过程的理解。2.2 集合框架从“数据结构”角度理解而不是死记API集合框架是笔试中的必考大项。京东这套题里ArrayList和LinkedList的区别、HashMap的底层实现、HashSet如何保证元素不重复这些都是高频题。先说ArrayList和LinkedList的区别。很多人能背出“一个数组实现、一个链表实现”但笔试往往问得更具体在什么场景下LinkedList的插入性能优于ArrayList如果回答“LinkedList插入快”那就掉坑了。LinkedList在中间插入确实比ArrayList快不需要移动元素但如果是在尾部插入ArrayList反而更快因为LinkedList每次插入都要new节点对象还有指针操作的开销。笔试里的正确答法是分场景讨论// 场景一尾部插入1万条数据 ArrayListInteger list1 new ArrayList(); LinkedListInteger list2 new LinkedList(); long start System.currentTimeMillis(); for (int i 0; i 100000; i) { list1.add(i); } System.out.println(ArrayList耗时: (System.currentTimeMillis() - start)); start System.currentTimeMillis(); for (int i 0; i 100000; i) { list2.add(i); } System.out.println(LinkedList耗时: (System.currentTimeMillis() - start));实测跑下来ArrayList的耗时通常是LinkedList的一半左右。但同样是这两个类在头插或者随机插入的场景下结论就反过来了。所以笔试里面试官真正想听的是你得先问清楚场景再给出结论。这体现的是工程思维而不是背答案。再说HashMap。这是集合框架里最值得深挖的知识点。笔试中关于HashMap的题从“底层数据结构”到“put方法的完整流程”再到“为什么线程不安全”各个层次都可能出现。我建议你把HashMap的put流程完整走一遍用画图的方式根据key计算hash - 定位数组桶 - 桶为空直接放 - 桶不为空遍历链表/红黑树 - 存在相同key则更新value - 不存在则插入 - 检查是否需要扩容。JDK 1.8之后链表长度超过8且数组长度超过64时转红黑树小于6时退化为链表中间的7是为了避免频繁转换。这些细节背下来不如自己推导一遍来得扎实。HashSet保证元素不重复的原理也常考。底层其实是HashMap元素作为key存储value是一个固定的Object常量利用HashMap key不可重复的特性来实现去重。判断重复的方式是先比较hashCode再比较equals。这两步缺一不可。所以笔试里如果问“两个对象hashCode相同但equals为falseHashSet会怎么处理”答案是两个对象都会存进去因为它们不相等。2.3 String的不可变性笔试题的“钉子户”String是Java笔试中出场率最高的类之一。京东这套题里字符串相关的题目同样不少核心考点集中在不可变性、常量池、equals与的区别这三点。先理解“String不可变”到底指的什么。不是说你不能改变一个String引用指向的值而是说String对象内部维护的字符数组被final修饰且类本身是final的一旦创建就不能修改。所以String s abc; s s d;这个操作其实是创建了一个新的String对象“abcd”旧的“abc”还留在字符串常量池里等待GC回收。这个特性直接牵出“字符串拼接的效率问题”String s ; for (int i 0; i 10000; i) { s i; // 这个操作创建了大量中间对象 }笔试里如果问这段代码有什么问题标准答法是“效率低会产生大量临时对象应使用StringBuilder”。但更好的答法还要补一层为什么StringBuilder效率高因为StringBuilder内部是可变的字符数组append操作直接修改数组内容不创建新对象。equals与的区别也是必考题。对于String比较的是引用地址equals比较的是内容且String重写了equals方法。笔试最常见的变形题是String a abc; String b abc; System.out.println(a b); // true因为都在常量池中指向同一对象 String c new String(abc); String d new String(abc); System.out.println(c d); // false因为new了两次 System.out.println(a.equals(c)); // true System.out.println(a c); // false这道题的底层逻辑是JVM字符串常量池的机制。用字面量创建String时先查常量池存在就复用用new创建时不管常量池有没有都会在堆中new一个新对象。这个原理想通了所有的变形题都迎刃而解。3. JVM内存异常与OOM题笔试卷子里最经典的“诊断题”怎么答3.1 OOM的类型与定位思路京东这套笔试里JVM相关的题目占了不小比例。其中关于内存异常的核心概念在历年Java岗位笔试里也几乎从未缺席。笔试不会直接让你写一段产生OOM的代码但会给你一段代码问“运行后会报什么错”或者给你一个线上系统OOM的场景让你说排查思路。OOM本身是一个大家族笔试里最常出现的是下面几类异常类型触发场景常见原因java.lang.OutOfMemoryError: Java heap space堆内存耗尽大对象过多、内存泄漏java.lang.OutOfMemoryError: Metaspace方法区/元空间耗尽动态生成类过多如CGLIB代理java.lang.OutOfMemoryError: GC overhead limit exceededGC时间占比过高堆过小、对象基本是垃圾java.lang.OutOfMemoryError: Unable to create new native thread创建线程数超限线程池无界、系统线程数上限被耗尽笔试里如果给你一个堆OOM的场景最简单的答题框架是四步走先确认是不是内存泄漏再获取堆转储快照然后分析快照中的大对象最后定位到具体代码行。这个思路放到任何一家公司的笔试里都能拿分因为它体现的是规范的排查流程而不是瞎猜。3.2 数组越界与空指针看着简单其实在考防御式编程Java中常见的运行时异常也是京东笔试的常客。数组越界异常ArrayIndexOutOfBoundsException和空指针异常NullPointerException看似是最基础的内容但笔试会把它们包装成“找bug”题考的是你写代码时有没有防御意识。举个例子这道题直接决定了候选人是否理解Java数组的边界特性int[] arr new int[3]; for (int i 0; i arr.length; i) { arr[i] i; }这段代码运行到i3时会抛出数组越界异常。Java数组的下标范围是0到length-1用一个不存在的下标访问时JVM会主动做越界检查并抛异常。C语言里这种操作是未定义行为可能直接踩到堆上其他内存而Java选择用异常来兜底。这背后体现的是语言设计的取舍——用运行时的安全检查换取出错时的明确反馈。我在代码评审时反复强调过凡是涉及数组、集合遍历的代码优先使用增强for循环或迭代器需要下标时也要尽量从0开始并严格遵循length边界。笔试里的数组题目代码写得再简洁如果没做边界判断都是瑕疵。空指针异常在笔试里的变形题也很多。最常见的一种是“下面这段代码在什么情况下会抛出NullPointerException”public void process(User user) { String name user.getName(); System.out.println(name.toUpperCase()); }只要user是nulluser.getName()这一行就会抛空指针只要user.getName()返回nullname.toUpperCase()这一行就会抛空指针。所以一段代码里可能存在多处空指针风险点笔试的坑就在这里。现在的工程实践里Java 8的Optional、Objects.requireNonNull、以及Lombok的NonNull注解都是处理空指针的常用手段。我在写代码时习惯性地要求自己任何从外部传入的对象参数进入方法第一件事就是判空。这已经成了肌肉记忆。3.3 笔试中的异常设计题受检异常与非受检异常的边界关于异常的笔试题目还有一个常考的知识点受检异常checked exception和非受检异常unchecked exception的区分。京东这套题里的异常相关题目也绕不开这个概念。受检异常是编译器强制要求处理的异常比如IOException、SQLException方法内部如果可能抛出这类异常要么用try-catch捕获要么在方法签名上用throws声明。非受检异常包括RuntimeException及其子类如NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException编译器不会强制你处理。笔试里更进一步的考法是让你判断自定义一个异常类时应该继承Exception还是RuntimeException这里考察的是你对异常语义的理解——如果这个异常是“可恢复的调用方可以处理并继续执行”继承Exception如果这个异常是“程序自身bug调用方无法优雅处理”继承RuntimeException。我在实际项目里看过的反例太多了有人把所有业务异常都继承RuntimeException导致调用方完全不知道方法会抛出哪些异常只能靠猜。这套笔试题里涉及try-catch-finally执行顺序的题也是高频。关键点是finally块中的代码一定会执行除非JVM退出且如果finally里有return语句它会覆盖try或catch里的return值。这个坑在笔试里出现率极高。4. 函数式编程与运算符表达式新版JDK带来的“新八股”4.1 Lambda表达式笔试不是考默写而是考“能不能读懂”Lambda表达式在前几年的大厂笔试中出现频率不高但随着Java 8全面普及现在已经是必考内容了。京东这套题里的Lambda相关题目主要考察函数的本质——Lambda是一个匿名函数它允许把函数作为方法参数传递。笔试最常见的考法是问你下面这段代码能否编译通过或者输出什么ListString list Arrays.asList(java, python, go, rust); list.stream() .filter(s - s.length() 3) .sorted() .forEach(System.out::println);这条链式调用如果读不懂说明还没理解Stream的三个核心步骤创建流 - 中间操作惰性求值- 终端操作立即执行。filter和sorted都是中间操作不会真正执行只有forEach这个终端操作出现后整个流水线才开始跑。这个“惰性求值”的机制是理解Lambda和Stream的钥匙也是笔试重点考察的点。4.2 函数式接口与Lambda的对应关系理解了Lambda的语法还要知道它背后的“函数式接口”概念。所谓函数式接口就是只有一个抽象方法的接口。Java里常见的函数式接口有Runnable、Comparator、Predicate、Function、Consumer等。看这段代码ComparatorString comparator (a, b) - a.length() - b.length();它等价于ComparatorString comparator new ComparatorString() { Override public int compare(String a, String b) { return a.length() - b.length(); } };如果笔试里要求你用匿名内部类改写Lambda或者用Lambda改写匿名内部类本质上就是在考你对函数式接口的理解。这里有个实际应用的坑Lambda表达式捕获的外部变量必须是“事实不可变”的即没有被重新赋值过。我曾经因为在一个循环里用同一个变量名接收不同结果导致编译报错排查了半天才意识到Lambda的变量捕获约束。笔试里也喜欢用这个点出题。4.3 运算符与表达式优先级比你想的更容易错Java运算符与表达式的内容在京东这套笔试题里也时有出现而且往往是“一看就会、一做就错”的类型。比如int a 5; int b a a; System.out.println(b); // 输出多少这道题考的是自增自减运算符的前置与后置区别。a先返回值5再自增此时a变6a先自增到7再返回值7所以b 5 7 12。很多人第一眼看过去算成11就是因为没有区分“先取值”和“先自增”的顺序。更复杂一点的是位运算和逻辑运算结合的题目int x 4; int y 3; boolean result (x y) (x 5); System.out.println(result); // false System.out.println(x); // 4因为短路x没有执行短路的逻辑是如果左侧表达式已经能确定整个结果右侧表达式就不再计算。这是笔试中的经典陷阱。和||都支持短路而和|不支持。这条规则在生产代码中也很关键比如用if (list ! null list.size() 0)来判断集合非空左侧为false时右侧不会执行从而避免空指针。5. 冒泡排序与快速排序代码题拿满分的写法与理由5.1 冒泡排序笔试最基础算法的优化空间排序算法在京东这套笔试题中出现率极高尤其是冒泡排序和快速排序。冒泡排序作为基础中的基础笔试通常不会只让你写出标准实现而是让你写优化版本或者分析某段冒泡代码的时间复杂度。标准冒泡排序的核心思想是相邻的两个元素两两比较逆序则交换每一轮把最大或最小的元素冒泡到数组末尾。时间复杂度O(n^2)空间复杂度O(1)稳定排序。我建议笔试时直接写出带优化标志位的版本public static void bubbleSort(int[] arr) { if (arr null || arr.length 2) { return; } // 外层循环控制轮数 for (int i 0; i arr.length - 1; i) { boolean swapped false; // 优化标记本轮是否发生交换 // 内层循环控制比较范围每轮结束后末尾元素已经有序 for (int j 0; j arr.length - 1 - i; j) { if (arr[j] arr[j 1]) { int tmp arr[j]; arr[j] arr[j 1]; arr[j 1] tmp; swapped true; } } // 如果本轮没有发生交换说明数组已经有序直接结束 if (!swapped) { break; } } }这个优化版本的好处是当数组本身有序时只需遍历一轮就能提前结束时间复杂度退化到O(n)。笔试中写出这个版本比默写教科书版本更能体现你的工程意识。5.2 快速排序从partition设计看考点快速排序是各大厂笔试和面试中的主角。京东这套题里快速排序相关的考题大概率让你完成partition函数的编写或者分析快排的时间复杂度。快排的核心是分治选取一个基准值将数组中小于基准值的元素放左边大于的放右边然后递归处理左右两部分。关键在于partition函数的实现方式。我推荐一种在笔试中最稳的写法——挖坑法public static void quickSort(int[] arr, int left, int right) { if (left right) { return; } int pivot partition(arr, left, right); quickSort(arr, left, pivot - 1); quickSort(arr, pivot 1, right); } private static int partition(int[] arr, int left, int right) { int pivot arr[left]; int i left; int j right; while (i j) { // 从右向左找小于基准值的元素 while (i j arr[j] pivot) { j--; } if (i j) { arr[i] arr[j]; i; } // 从左向右找大于基准值的元素 while (i j arr[i] pivot) { i; } if (i j) { arr[j] arr[i]; j--; } } arr[i] pivot; return i; }快排的平均时间复杂度是O(n log n)最坏情况下O(n^2)——当数组已经有序且每次选取的基准值恰好是最大值或最小值时。笔试很容易在这里挖坑问你“什么时候快排会退化为最坏情况如何避免”。标准答法是随机选择基准值或者取左中右三数取中法。我在笔试答题时通常会先写基础实现再补一句“加上三数取中优化”分数会明显不一样。5.3 笔试题里的排序综合题稳定性和场景选型京东这类大厂笔试还喜欢把排序算法包装成综合题。比如给你一个链表让你用O(n log n)的时间复杂度排序。这就是在考察你是否理解各种排序算法的数据结构适用性。数组上的快速排序可以随机访问元素而链表只能顺序访问。所以链表的归并排序更合适不需要额外开辟数组空间只通过修改节点指针就能完成排序。这是一个典型的“算法与数据结构结合”的考点需要提前准备。再来看看稳定性。排序算法的稳定性指相同值的元素在排序后保持原有相对顺序。举一个实际业务场景一个学生列表先按班级排序再按成绩排序如果排序算法不稳定同成绩的学生顺序可能被打乱。笔试中常考的是冒泡排序是稳定的选择排序是不稳定的插入排序是稳定的快速排序是不稳定的归并排序是稳定的。这些结论想清楚原理就不会记混。6. 编译报错与环境配置工程师日常里隐藏的笔试考点6.1 环境变量配置从“跳过的坑”变成“答对的题”在讨论技术笔试的内容之外还有一个很多应届生准备笔试时容易忽略的环节——本机环境的搭建。这套笔试题里尽管不会直接要求你写环境变量配置但在线上笔试或面试环节中候选人常常会被要求共享屏幕演示代码这时候如果本地环境出问题相当影响印象分。而且笔试的Java代码题很多候选人会在本地跑一遍验证结果如果环境没配好连运行都做不到。环境变量配置的核心是两个变量JAVA_HOME和PATH。JAVA_HOME指向JDK安装目录很多依赖Java的工具如Maven、Gradle、Tomcat会通过它找到JDK。PATH里需要追加%JAVA_HOME%/binWindows或$JAVA_HOME/binLinux/macOS这样命令行才能直接使用java和javac命令。有个细节很容易被忽略配完环境变量后Windows下需要重新打开命令行窗口才能生效因为cmd启动时才读取当前用户的环境变量。我见过太多人在旧的cmd窗口里敲java -version发现还是老版本就误以为配置失败其实只是没重开窗口。6.2 版本号报错与编译期异常现代Java笔试的“隐形题”近两年Java笔试还有一个新趋势考点不再局限于语言本身还包括构建工具和编译器的常见报错。虽然这不是京东这套2019笔试里直接出现的题型但如今几乎所有线上笔试平台的自动判题都会暴露这类问题值得提前了解。比如“源发行版17需要目标发行版17”这类报错就是Maven或Gradle配置的Java编译版本与当前JDK版本不一致导致的。POM文件里配置了maven.compiler.source和maven.compiler.target为17但本机JDK版本是8就会报这个错。解决方案是把编译版本降到8或者安装更高版本的JDK。另一个常见报错是“Lombok不工作”的问题。当IDE里的Lombok插件与当前Java版本不兼容或者项目没有正确配置注解处理器时编译器会提示找不到getter/setter方法。这个问题的根源是Lombok在编译期通过注解处理器生成代码如果IDE的注解处理没开启编译时Lombok就不会生效。笔试里如果遇到运行不了的情况十有八九是环境配置问题而不是代码逻辑问题。6.3 线上笔试的实战建议把环境问题消灭在笔试之前基于我这些年带新人和帮学弟学妹做笔试模拟的经验线上笔试前强烈建议先做一次完整的“环境自检”确认JDK版本与笔试题要求的版本一致。京东校招笔试一般默认Java 8虽然已经是2019年的题但很多公司至今仍用Java 8作为主力版本。准备一个不依赖网络、能离线运行的开发环境。有些在线笔试平台的代码编辑器很笨拙自动补全和语法高亮都缺失。提前在本地练习“不借助IDE提示”手写Java代码能让笔试时更从容。在记事本或极简编辑器里写一个HelloWorld用命令行javac和java跑通一遍。这一步不是为了学东西而是为了确保命令行环境下Java工具链可用防止线上笔试系统出问题时完全没退路。这些准备看着小但在笔试的紧张氛围下一个环境报错就可能打乱整场节奏。我在指导学弟学妹时反复强调笔试不光是脑力的比拼也是环境准备充分度的比拼。7. 一轮完整复习路径与经验建议7.1 按“知识模块—原理推导—代码复现”三层法复习前面把这些高频考点都拆开了最后给出一套完整的复习路径。这套方法我一直在给团队里带的新人用效果不错核心原则是“每一块知识都要能落到代码上”。第一层是知识模块梳理。把Java基础拆成语法、集合、JVM、并发、IO、新特性、算法七大块依次逐个击破。每块给自己出三道题这个知识点的核心机制是什么它解决了什么问题如果不这么设计会怎样三问都能答上来才算真的掌握。第二层是原理推导。以HashMap为例不要只背“数组链表红黑树”要能推导出为什么引入红黑树——因为链表在极端哈希冲突下查找退化为O(n)而红黑树保证最坏O(log n)。不要只背“加载因子0.75”要能说出这是空间与时间的折中。这一层复习到位的标志是你能在不看任何资料的情况下给别人讲清楚JDK 1.8里HashMap的变更原因。第三层是代码复现。所有经典算法、所有集合核心方法、所有线程创建方式都用手写一遍。我在辅导时发现很多候选人看别人代码都能看懂但一到自己写就卡壳这就是典型的“眼高手低”。笔试考场是纯手写环境平时不练手写考场上就会暴露出各种边界条件考虑不周的问题。7.2 复盘错题不追求刷题数量京东这套笔试题完整做一遍可能只需要两三个小时但真正吃透它需要你花一到两周的时间反复复盘。我做笔试训练时有一个习惯每道错题不只记录正确答案还要写下“我当时为什么选错了”“我被哪个选项误导了”“下次遇到同类题应该先看什么”。这个复盘过程比刷十套新题都管用。比如前面举例的int b a a第一次做错的人复盘时要写清楚我把“a的值”和“a自增后的值”混淆了。下次遇到自增运算先在草稿纸上写出“先取值还是先自增”再代入计算。这种深度复盘能帮你把一个具体错误泛化成一类问题的解题策略。7.3 关于笔试时间的分配策略京东这类大厂的笔试通常有固定的时间限制题型覆盖单选题、多选题、编程题。时间分配上我建议单选题控制在总时间的三分之一以内给编程题留足时间。不要追求每道题都完美要追求“会做的全对、不会做的能拿部分分”。编程题的答题顺序也有讲究先把所有编程题都看一遍挑最有把握的做。因为编程题通常是按测试用例给分的做了但只通过部分用例也能拿部分分直接跳过就一分都没有。先把容易拿分的题目确保通过再回头去啃难题总分会更可观。拿这套京东2019校招笔试Java开发工程师笔试题来说它给我最大的感受是这些题不偏不怪完全在Java工程师的日常知识体系之内但考察的是你是否真正理解这些知识还是只是浮于表面的知道。所以备考核心始终是把基础原理吃透把代码写扎实把每道题背后的“为什么”想明白。
返回列表