尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java基础校招笔试高频考点全拆解:从语法到集合与排序

Java基础校招笔试高频考点全拆解:从语法到集合与排序 欢聚时代2017校招笔试那套JAVA基础类A卷到现在我还能记起几个印象特别深的题目。当时拿到卷子翻了一遍第一反应是“怎么全是基础题”第二反应是“这些题我好像都会但真做起来未必能拿满分”。事后复盘才发现校招笔试里的基础题恰恰是最能区分“背过知识点”和“真正理解语言”的试金石。这篇博文就以这套题为主线把Java基础笔试里的高频考点、答题思路和容易踩的坑完整拆一遍给正在准备校招或者想自查基础的朋友做个参考。1. 出题人想用这张A卷筛出什么样的人1.1 一份基础类笔试题的标准考察版图欢聚时代这份A卷虽然叫“基础类”但覆盖面并不小。从这类校招笔试题的普遍结构来看Java基础卷基本都会围绕以下几个板块展开语法细节标识符、运算符、流程控制、面向对象三大特性、常用类String、包装类、枚举、集合框架List、Map、Set、异常处理、以及1到2道手写算法题。各板块的权重基本符合“基础为王”的原则框架和中间件相关的内容很少说明出题人首先想确认的是候选人的语言功底是否扎实。拿我当时对这套题的回忆来说选择题占了相当大的比重题型多数是“以下说法正确的是”或“以下代码输出什么”。这类题看起来简单实际上每个选项都是精心埋过雷的出题人不是考你会不会背概念而是考你在具体场景下能不能判断对。判断题和简答题则集中在面向对象、集合和异常这几个方向最后一道大题通常是手写排序或者字符串处理。1.2 基础题为什么比框架题更能看出水平很多人觉得校招笔试应该多考Spring、多考微服务这样才能筛出“能干活的人”。但站在出题人的角度基础题恰恰是最有效的筛选工具。原因很直接框架可以速成但Java基础很难速成。一个候选人如果能把集合扩容机制、异常处理流程、equals和hashCode的约定这些基础问题讲清楚说明他至少是认真读过源码、做过实践的反过来一个只会背框架注解、连HashMap底层结构都说不清的人即便简历上写满了项目也很难让人相信他能在出问题时定位到根因。另外基础题还有一个隐藏功能考察候选人的学习态度。Java基础是每个Java开发者入行第一年就要接触的内容如果连这些都不愿意扎实掌握那后面的成长曲线大概率不会太理想。所以看到这份A卷以基础题为主我当时反而觉得这家公司的招聘思路是务实的至少筛出来的人不会太虚。2. 语言特性与语法细节题背过和真懂是两回事2.1 标识符、运算符、switch这些“送分题”的埋点Java基础笔试题最喜欢在语法细节上做文章因为这些内容教材里都有但很多人写代码时根本不注意。标识符命名规则就是典型的例子字母、下划线、美元符开头不能以数字开头不能是关键字这些大家都背过但题目一旦换成“以下哪个是合法标识符”选项里混入123abc、class、true、$name就有人开始犹豫。这里要特别提醒true、false、null虽然不是关键字但属于字面量也不能用作标识符这个细节经常被忽略。运算符相关的题目也是重灾区。自增自减的运算顺序、短路与和短路或||的求值规则、三目运算符的类型转换这些在笔试里几乎是必考的。印象里有一类题特别容易错int i 0; i i;问输出是多少。很多人凭直觉回答“i变成了1”但实际上结果是0因为i返回的是自增前的值。这类题目在真实开发中未必会写但笔试考的就是你对语言规范的理解精确度。switch语句的考察点则集中在支持的数据类型上。从Java 7开始switch支持String之前只支持byte、short、char、int以及对应的包装类型和枚举。笔试题目如果给出一个用long做switch条件的代码片段正确答案一定是编译报错。这类题没什么技巧纯粹看基础扎不扎实。2.2 枚举、lambda、泛型这类新特性的考察方式2017年那会儿Java 8已经发布了三年多lambda表达式成了笔试的新宠。不过基础卷里对lambda的考察通常不会太深更多是看你会不会用函数式接口、知不知道lambda表达式能捕获哪些变量。一个很经典的坑是lambda表达式内部引用外部的局部变量时该变量必须是final或 effectively final。题目往往会给一段代码在lambda里修改外部变量问是否编译通过答案当然是不通过。泛型这块考察点主要集中在类型擦除、泛型通配符? extends T和? super T的区别、以及泛型与集合的配合。这里有个实用的记忆方法? extends T只能读不能写? super T只能写不能读但读出来的类型是Object。笔试选择题经常拿这个来挖坑。枚举在基础笔试里一般不会出太复杂的题通常就是考察枚举的本质——枚举是一个继承了java.lang.Enum的类可以定义构造器、字段和方法枚举的构造器默认是private的枚举常量必须在第一行声明。有些基础不牢的候选人会觉得枚举就是个“特殊的常量集合”一旦题目问到枚举能不能定义抽象方法或者枚举能不能实现接口就开始发懵。这两个问题的答案都是肯定的而且在实际项目里用枚举实现策略模式的场景并不少见。3. 面向对象、常用类与异常分值最重的“判断题”里藏着哪些坑3.1 重载与重写概念都懂一判断就错面向对象三大特性是Java笔试的绝对核心其中重载和重写是出题频率最高的知识点。重载看的是方法签名方法名参数列表返回值类型不参与重载判断重写要求方法名、参数列表、返回值类型或协变返回类型一致并且访问权限不能比父类更严格。笔试题最经典的坑就是给出两个方法public int add(int a, int b)和public long add(int a, int b)问是否构成重载。答案是不构成因为参数列表完全相同返回值类型不同是不允许的。还有个容易出错的点是重写时的异常声明。子类重写父类方法时抛出的受检异常不能比父类更宽泛可以更具体也可以不抛。题目如果给一个父类方法声明throws Exception子类重写时声明throws IOException这是合法的。但如果反过来父类抛IOException子类抛Exception就会编译报错。继承与多态的题目则集中在“编译看左边运行看右边”这句话上。笔试里经常会给出类似Father f new Son(); f.method();的代码问输出什么。这里只要记住调用方法时编译阶段看引用类型有没有这个方法运行阶段看实际对象类型有没有重写这个方法。如果父类没有定义某个方法子类定义了那通过父类引用调用这个方法会直接编译失败。3.2 equals/hashCode、String、包装类缓存基础题的三座大山这三个知识点在Java笔试里地位极高几乎每套卷子都会出现。equals和hashCode的约定是如果两个对象equals相等那么它们的hashCode必须相等但hashCode相等equals不一定相等。笔试题目通常会给一个重写了equals但没有重写hashCode的类问把它放到HashSet里会有什么问题。答案是因为hashCode不同两个equals相等的对象可能被放到不同的桶里导致集合里出现“重复”元素破坏Set的去重语义。String的考察点更多了。字符串常量池、String s1 abc;和String s2 new String(abc);的区别、intern()方法的作用这些老生常谈的内容依然是笔试的保留项目。一个高频题目是用比较两个内容相同的字符串字面量答案是true因为它们在常量池中是同一个对象但用new String(abc)创建的对象与字面量比较答案是false。这个知识点在开发中写代码时可能不会直接用到但理解它能帮你避开很多字符串比较的坑。包装类缓存是Java 5引入的特性Integer默认缓存-128到127之间的值Boolean缓存true和falseCharacter缓存0到127。笔试题最经典的就是Integer a 127; Integer b 127; a b是true但Integer c 128; Integer d 128; c d是false。很多人第一次看到这个结果都会惊讶但这就是自动装箱时调用valueOf方法导致的。答题时只要记住用比较包装类时除了缓存范围其他情况比较的都是引用地址应该用equals比较内容才对。3.3 异常体系与数组越界题的实际场景异常体系在基础笔试里主要考察分类受检异常和非受检异常的区别。受检异常如IOException、SQLException必须显式捕获或抛出非受检异常RuntimeException及其子类不需要强制处理。这里有个容易混淆的点Error类也继承自Throwable但一般不在“异常”讨论范围内笔试题目如果问“Error是否属于异常”答案是不属于它表示严重的系统级错误程序通常无法恢复。数组越界异常是Java基础里最典型的运行时异常之一对应的类是ArrayIndexOutOfBoundsException。笔试题目一般会给一个数组初始化的代码然后问通过某个索引访问元素会抛出什么异常。这里要特别注意负索引和索引等于数组长度这两种情况只要索引超范围就会当场抛出异常。另外基础卷还喜欢考StringIndexOutOfBoundsException字符串的索引范围和数组略有差异同样是从0开始最长是length()-1但很多人会把这两个异常搞混答题时写错名字就亏了。4. 集合框架题ArrayList、HashMap高频考点的答题模板4.1 ArrayList扩容一道题可以看出有没有读过源码集合框架是Java笔试的大头ArrayList和HashMap又是其中的重中之重。ArrayList的高频考题是扩容机制默认初始容量是10每次扩容为原来容量的1.5倍扩容时需要把原数组的元素复制到新数组。笔试如果出这个题单回答“扩容为1.5倍”只能拿一半分完整的答法要说清楚底层是grow方法中通过oldCapacity (oldCapacity 1)计算新容量并且要提到add方法在插入前会先检查容量是否足够。有个面试官常追问的点是构造ArrayList时传入初始容量0然后添加第一个元素容量会变成多少答案是10因为第一次扩容时会调用grow方法计算出的新容量小于默认容量10所以直接取默认值。这个细节如果没看过源码很难答对但如果提前了解过反而能成为回答中的亮点。另一个高频考点是Arrays.asList和new ArrayList的区别。Arrays.asList返回的是一个固定长度的内部类对象不能调用add和remove否则会抛UnsupportedOperationException。笔试选择题经常把这个方法包装成“ArrayList初始化”的选项看起来像是创建了一个可以正常操作的List实际上固定大小扩展操作会直接报错。4.2 HashMap的底层与并发问题答出深度和答出广度HashMap在Java 8之后底层改成了数组链表红黑树初始容量16负载因子0.75当链表长度大于等于8且数组长度大于等于64时链表会转成红黑树。笔试题目通常会直接问“HashMap底层数据结构是什么”如果你只说个“数组加链表”而没提红黑树基本会被认为知识停留在Java 7时代。回答时要按版本把几个关键细节顺一遍先说Java 7前是数组加链表再说Java 8优化后引入红黑树最后提到为什么是8这个阈值——这里涉及到泊松分布理想情况下链表长度达到8的概率极低选择这个值是为了平衡时间和空间。HashMap的线程安全问题也是笔试常客。HashMap本身不是线程安全的多线程写入时可能造成数据覆盖甚至死循环Java 7的头插法在扩容时可能出现循环链表Java 8改为尾插法后这个经典问题得到解决但数据丢失问题依然存在。如果笔试题目问“并发场景下应该用什么”标准答案是ConcurrentHashMap它采用锁分段或CAS加锁机制来保证线程安全。这里不要只答一个名字最好说明一下ConcurrentHashMap在Java 8后的实现变化——放弃了分段锁改用CAS和synchronized对头节点加锁并发度更高。4.3 fail-fast机制笔试最爱问的一个“现象”集合框架还有一个高频考点是ConcurrentModificationException也就是fail-fast机制。题目通常给一段代码在增强for循环遍历ArrayList的过程中调用remove方法问会有什么结果。正确答案是抛出ConcurrentModificationException因为增强for循环底层使用的是迭代器迭代器的next方法会检查modCount和expectedModCount是否一致不一致就抛异常。很多候选人能答出“会报错”但答不出“为什么报错”。要拿到满分需要说清楚modCount是集合被结构性修改增删元素的次数迭代器在创建时会记录当时的modCount为expectedModCount每次调用next时都会比对。所以想在遍历时删除元素正确做法是使用迭代器的iterator.remove()方法这个方法会同步更新expectedModCount不会触发fail-fast。5. 手写排序冒泡和快排在笔试现场的写法与加分项5.1 冒泡排序边界条件比算法本身更容易丢分手写算法题在基础类笔试题里通常安排在最后目的不是考你算法多难而是看你写代码的基本功。冒泡排序是出现概率最高的排序题之一代码本身只有十几行但能一次写对的人并不多。最常见的错误是内外层循环的边界写错导致数组越界或者漏排最后一个元素。标准写法如下public static void bubbleSort(int[] arr) { if (arr null || arr.length 2) { return; } int n arr.length; for (int i 0; i n - 1; i) { boolean swapped false; for (int j 0; j n - 1 - i; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; swapped true; } } if (!swapped) { break; } } }这里有两个细节很加分一是加上swapped标记内层循环没有发生交换就提前结束这是冒泡排序的经典优化二是先做空值和长度判断这会让阅卷人觉得你平时写代码有边界意识。冒泡排序的时间复杂度是O(n²)空间复杂度O(1)是稳定排序这些如果笔试题目没有问也可以在代码旁边用注释标注一下展示你的基础功底。5.2 快速排序两种写法和一个容易忽略的优化快速排序同样是高频手写题比冒泡排序稍难核心是分治思想和分区操作。最常见的写法是以数组的最后一个元素作为基准值pivot用两个指针遍历数组public static void quickSort(int[] arr, int left, int right) { if (left right) { return; } int pivotIndex partition(arr, left, right); quickSort(arr, left, pivotIndex - 1); quickSort(arr, pivotIndex 1, right); } private static int partition(int[] arr, int left, int right) { int pivot arr[right]; int i left; for (int j left; j right; j) { if (arr[j] pivot) { swap(arr, i, j); i; } } swap(arr, i, right); return i; } private static void swap(int[] arr, int i, int j) { int temp arr[i]; arr[i] arr[j]; arr[j] temp; }笔试时快速排序只需要写清楚基准值选取、分区逻辑和递归调用三个部分就能拿分但有两个易错点一是递归退出条件不能写成left right当区间只有一个元素时left right也应该停止否则会陷入无限递归二是数组越界问题很多人在递归调用quickSort(arr, left, pivotIndex - 1)时忽略pivotIndex - 1可能小于left虽然这个场景下left right的退出条件已经能兜住但逻辑上要心里有数。5.3 面试官围绕排序题的三连追问笔试结束后如果排序题写得好面试环节大概率会被追问。最常见的追问题有三类。第一类“快排最坏时间复杂度是多少”答案是O(n²)发生在每次选到的基准值都是最大或最小值时比如数组本身就是有序的又固定选最后一个元素做基准。第二类“如何优化”答案是随机选取基准值、三数取中、在数据量小时改用插入排序。第三类“快排是稳定的吗”答案是不是因为分区过程中相同元素的相对顺序可能改变。这里有一个很实用的复习思路不要只背答案要理解为什么。比如快排为什么不稳定可以用一个具体例子走一遍分区流程看到相同大小的元素在交换后顺序颠倒你才算真正理解了这个结论。笔试和面试问问题的方式千变万化但底层原理是不变的把原理吃透了怎么问都能答上来。6. 复盘这类基础笔试真正教给我的几件事6.1 错题归因把“不会”和“粗心”分开处理做完这套题之后最重要的一步不是对答案而是把错题按“知识盲区”和“粗心失误”归类。知识盲区的题说明这个知识点你压根没掌握或者理解有偏差需要回到书本或源码里重新学一遍。粗心失误的题比如没看清选项问的是“不正确的一项”、数组索引数错了这类错误光提醒自己“下次仔细”没用正确做法是每次模拟练习时统计粗心做错的题目数量逼自己养成“先划关键词再作答”的习惯。我见过太多人刷了上百道Java面试题但每次错的还是那几个类型原因就是只做题不复盘。一道题做错了不应该只看正确答案而应该问自己三个问题我当时是怎么想的正确思路应该是什么两种思路的差距出在哪个环节把这三个问题写下来才算完成一道错题的闭环。6.2 八股文的正确用法背题不是为了背题“Java八股文”这个词在技术社区里讨论度很高很多人一边背一边吐槽也有不少人觉得背八股文没有意义。我的看法是八股文本身是中性的关键是背的方式。如果只背“HashMap默认容量是16负载因子是0.75”那面试官一追问“为什么是16为什么是0.75”立马露馅但如果顺着八股文的结论去翻源码、看注释理解容量取2的幂次方是为了位运算优化、负载因子0.75是时间空间上的折中那背下来的东西就成了真本事。所以我建议把八股文当“索引”而不是“答案”。看到一个高频考点先回忆结论再反推原理最后用白纸把它默写出来。这套流程走下来一个知识点基本就能内化成自己的东西了。这套欢聚时代的A卷也是这样题目本身只是索引题目背后涉及的那些源码和底层机制才是真正值得花时间研究的内容。6.3 手写代码的日常练习方法笔试手写代码和IDE里写代码完全是两种体验没有代码补全、没有编译提示、也不能CtrlF查找方法名全靠平时的积累。我的练习方法是每周抽两到三次定时25到30分钟手写一道基础算法题写完之后再默写一遍直到能无差错写出为止。排序、二分查找、链表反转、字符串去重、括号匹配这些基础题覆盖了笔试90%的考察范围。另一个小技巧是练习的时候有意训练代码的分层结构——先写方法签名和空值判断再写核心逻辑最后写返回结果。这样的代码一眼看上去就清晰阅卷人扫一眼就能找到你的答案分数自然比写得乱七八糟的代码高。而且这个习惯到了正式工作的Code Review环节也是个加分项。Java基础笔试说到底是门“熟能生巧”的功课这套欢聚时代A卷只是无数套同类试卷中的一个样本但它背后考察的知识点、出题思路和答题技巧是相通的。如果能从每一道错题里看到自己认知的边界再把这个边界一点一点推远那准备笔试的过程本身就已经是在提升一名Java工程师最核心的竞争力了。
返回列表