资讯动态

Java基础知识笔试题深度解析:集合、泛型、异常与避坑

发布时间:2026/10/15 4:52:42 来源:尧图企业网站定制
简介这是一份 Java 基础知识笔试题及答案文档面向 Java 入门学习者、求职笔试备考者以及希望巩固语法基础的开发者适合用来检验对基本概念、数据类型、运算符、控制结构、函数、数组、集合框架、泛型和封装等内容的掌握情况。资源中的题目既有选择题也有程序阅读题和编程题每道题均附参考答案或参考代码内容涉及 String 字符串比较与替换、Calendar 日期计算、LinkedList 模拟堆栈、任意两个日期之间间隔天数统计等经典练习可以帮助读者理解常见考点和易错点。资源包共 1 个 docx 文件整体约 25KB轻量易用便于直接阅读、检索或打印复习。目前已有 1304 人学习下载。通过这份资料读者可以系统梳理 Java 基础知识快速定位薄弱环节并结合实例代码提升程序设计与调试能力。1. Java基础知识笔试题这套资源到底能帮你解决什么拿到这份Java基础知识笔试题及答案时我的第一反应是又是题海。但当我把22道基础题和12道异常相关题全部跑了一遍发现它本质是一套按知识点切片的自测工具集合框架、包装类、泛型、Calendar日期计算、异常机制五大块全覆盖每道题都有答案或参考代码。对准备笔试的新手它是可以直接背诵的题库对带新人的熟手它是现成的面试提问清单。这套题最好的用法不是从头做到尾而是把它拆开按考点逐个验证自己的理解深度。接下来我从出题逻辑、代码实现、常见踩坑三个维度拆给你看。2. 集合与包装类从选择题答案看面试出题逻辑2.1 高频选择题这些考点为什么反复出现先看三道典型选择题它们分别对应包装类、相等比较和集合选型第1题问包装原始字符串类型的类答案是 String。注意这里的包装类是广义说法严格说String是引用类型而非包装类但笔试常这么叫。第2题问 java.lang 包中比较两个对象是否相等的方法答案是 equals()。这里考察的是 和 equals 的语义差异String 类重写了 equals而 Object 默认实现仍然是引用比较。第4题问哪个集合不可以存储重复元素答案是 Map。注意 Set 也不允许重复但 Map 存储的是键值对键不可重复值可以重复。出题人故意把 Set 放在选项里就是让你区分元素和键值对两个概念。这三道题放在一起看出题逻辑很清晰不是考你某个API怎么拼写而是考你是否理解Java集合和对象的底层语义。第5题更典型问 Map 和 List 的关系答案是 DMap 的 value 可以是 List 或 Map这直接考察了集合嵌套的组合能力。实际开发中 JSON 反序列化、树形结构组装都会用到这种嵌套关系所以面试官爱问。2.2 LinkedList插入异常add方法索引边界第6题是这份资源里最容易翻车的代码题原题如下import java.util.*; public class Test { public static void main(String[] args) { LinkedList list new LinkedList(); list.add(A); list.add(2, B); String s (String) list.get(1); System.out.println(s); } }答案是 B运行时引发异常。原因在于 LinkedList 底层是双向链表add(index, element)方法要求索引必须等于当前链表长度或小于长度。链表只有一个元素时索引范围只能是 0 或 1传 2 直接越界。我一般会这样给新人解释LinkedList 不像 ArrayList 有连续内存可以预留位置它必须通过遍历找到插入点索引 2 对应的节点根本不存在所以抛出 IndexOutOfBoundsException。这里有个区分点add(A)是尾插等价于add(size(), A)add(2, B)是任意位置插入需要节点存在。如果改成list.add(1, B)就能输出 B。这个边界条件是笔试和面试的常客记住索引可等于长度不可大于长度就够了。2.3 String.valueOf 三个重载版本输出结果为什么是 10.0、true、bcd第7题要求写出输出结果代码如下char[] data {a, b, c, d}; System.out.println(String.valueOf(10D)); System.out.println(String.valueOf(3 2)); System.out.println(String.valueOf(data, 1, 3));输出结果是10.0 true bcd第一个valueOf(10D)传入 double 类型重载匹配到valueOf(double)返回 10.0第二个传入布尔表达式结果匹配valueOf(boolean)第三个是坑点valueOf(char[] data, int offset, int count)的第二个参数是起始偏移量第三个参数是长度所以从索引 1 开始取 3 个字符正好是 b、c、d。我见过不少人把第三个参数理解成结束索引以为输出是 bc。这里要记住offset 是起始位置count 是复制长度。另外 char[] 重载版本会返回 char 数组的内容本身而valueOf(Object)对数组调用会返回类似[C15db9742的地址字符串这是另一个高频易错点。3. 泛型实战从基础概念到能跑的泛型方法3.1 泛型List与普通List类型安全的代价与收益第10题的参考答案把泛型的优点说得很清楚类型安全、消除强制类型转换、提高代码重用率。我补一个实际对比场景// 普通 List存入时随意取出时强转容易出错 List list new ArrayList(); list.add(hello); Object obj list.get(0); String str (String) obj; // 泛型 List编译期就限制类型取出直接赋值 ListString strList new ArrayListString(); strList.add(hello); String str2 strList.get(0);普通 List 存的是 Object取出来需要强转。如果某处不小心add(123)运行时强转才会抛 ClassCastException问题定位要翻整个调用链。泛型 List 在编译期就把这个风险拦住了。我通常会建议新人集合声明一律带泛型哪怕写ListString比List多几个字符省的是半夜排查类型异常的精力。3.2 泛型方法minmaxT extends Comparable的边界处理第19题要求写一个泛型方法返回 int 数组和 String 数组的最大最小值。参考代码里有几个关键设计值得细看class ArrayAlg { public static T extends Comparable PairT minmax(T[] a) { if (a null || a.length 0) { return null; } T min a[0]; T max a[0]; for (int i 1; i a.length; i) { if (min.compareTo(a[i]) 0) min a[i]; if (max.compareTo(a[i]) 0) max a[i]; } return new PairT(min, max); } }T extends Comparable是这段代码的核心约束它告诉编译器T 类型必须实现了 Comparable 接口这样才能调用compareTo。如果不加这个边界编译器会直接报错因为 Object 没有 compareTo 方法。这里有两个改进点我可以补充泛型边界建议写成T extends Comparable? super T这是 Java 泛型规范里的经典写法能支持父类实现了 Comparable 而子类没实现的情况。数组为空时返回 null调用方需要做判空否则会 NullPointerException。测试部分用了Integer[]而不是int[]因为泛型只能匹配引用类型基本类型 int 不满足T extends Comparable的约束。这一点新人很容易踩坑写int[]进去编译直接失败。3.3 泛型Map实现英文翻译类型参数贯穿存取第22题用泛型 Map 实现英文单词翻译代码很短但把泛型 Map 的完整用法串起来了String[] eng {Apple, Orange, Green}; String[] chs {苹果, 桔子, 绿色}; MapString, String map new HashMapString, String(); for (int i 0; i eng.length; i) { map.put(eng[i], chs[i]); } String test Orange; System.out.println(test 翻译 map.get(test));MapString, String声明了两个类型参数键和值都是 String。put时如果键已经存在会覆盖旧值get不存在时返回 null 而不是抛异常。这题在实际开发里可以扩展成加载配置文件键值对、缓存字典表等场景。注意 HashMap 的遍历顺序不保证插入顺序如果需要按插入顺序输出可以改成LinkedHashMap这是我在项目里的习惯做法。4. 日期计算与字符串转换Calendar和API的四个实操场景4.1 计算10天后的日期Calendar的add与get组合第12题要求计算距当前时间10天后的日期参考代码使用 Calendarimport java.util.Calendar; public class Ex12 { public static void main(String[] args) { Calendar cal Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 10); String strDate cal.get(Calendar.YEAR) 年 (cal.get(Calendar.MONTH) 1) 月 cal.get(Calendar.DATE) 日; System.out.println(10天后的日期为 strDate); } }Calendar.getInstance()获取当前时间的日历实例add(Calendar.DAY_OF_YEAR, 10)在当前日期上增加10天。注意两个细节MONTH从 0 开始所以输出月份时必须加 1DATE和DAY_OF_MONTH等价都是当前月中的第几天。如果跨月或跨年add方法会自动进位这是它比手动计算日期安全的根本原因。参考代码没有包含具体的时间输出只输出了日期。如果你需要完整时间把HOUR_OF_DAY、MINUTE、SECOND拼进去就行。4.2 两个日期间隔天数毫秒差值的整除结果第14题计算任意两个日期之间的天数核心逻辑是毫秒差除以一天的毫秒数Calendar c1 Calendar.getInstance(); c1.set(2010, 7, 1); Calendar c2 Calendar.getInstance(); long ca1 c1.getTimeInMillis(); long ca2 c2.getTimeInMillis(); long days (ca2 - ca1) / (24 * 60 * 60 * 1000); System.out.println(days);这里有个隐藏陷阱c1.set(2010, 7, 1)设置的是 2010年8月1日因为 MONTH 从 0 开始。如果意图是7月1日应该写成set(2010, 6, 1)或set(2010, Calendar.JULY, 1)。另外整除运算会有精度丢失比如间隔时间是25小时整除后得到1天实际上是2天。更严谨的做法是long days (ca2 - ca1) / (24 * 60 * 60 * 1000L); if ((ca2 - ca1) % (24 * 60 * 60 * 1000) ! 0) { days; }4.3 parseInt与valueOf进制参数与返回类型差异第16题考察字符串转数值的两个APIString str1 200; System.out.println(Integer.parseInt(str1, 16)); // 输出 512 String str2 123456; System.out.println(Float.parseFloat(str2)); // 输出 123456.0Integer.parseInt(String, int radix)的第二个参数是进制所以 200 按十六进制解析结果是 2*256512。Float.parseFloat返回基本类型 float而Float.valueOf返回包装类型 Float两者底层解析逻辑一致区别在使用场景需要参与基本类型运算用parseFloat需要放入集合用valueOf。第17题还有一个自定义的十进制转十六进制实现那个方法循环中取余数再翻转字符串逻辑对但用Integer.toHexString(365)一行就能解决。笔试如果要求手写可以写简单的递归或循环不必硬记那个 switch 分支。5. 异常机制与避坑try-catch-finally的五个踩坑记录5.1 Throwable体系与异常分类父子关系必须记牢第3题问所有异常的父类答案是 Throwable。派生关系是Throwable ├── Error (内部错误如硬盘损坏、内存溢出) └── Exception ├── RuntimeException (运行时异常如除数为0、数组越界) └── 其他受检异常 (如文件不存在)第4题问哪些操作不会抛出异常答案是以上都会这题被坑过的人很多。int x 1 / 0抛 ArithmeticException负数索引访问数组抛 ArrayIndexOutOfBoundsException打开不存在的文件抛 FileNotFoundException。三条都对应异常所以选 D。第6题问多重 catch 中最后列出哪个类答案是 Exception 放最后因为子类异常必须排在父类前面否则父类会先捕获子类的 catch 块永远执行不到。5.2 finally与return的优先级为什么返回值是3第9题是这套题里最有含金量的一道public int count() { try { return 5 / 0; } catch (Exception e) { return 2 * 3; } finally { return 3; } }结果返回 3。原因try 中 5/0 抛出异常进入 catch 块catch 准备返回 6但 finally 在 return 之前强制执行finally 中的 return 3 直接覆盖了 catch 的返回值。这是 Java 规范里一个反直觉的设计finally 中的 return 会压制任何其他返回值包括 try 和 catch 块中的异常抛出。我在代码评审里见过有人这样写一条原则解决不要在 finally 里写 returnfinally 只做资源清理如关闭流、释放锁。第8题验证了另一个现象try 中有 return 时 finally 仍然执行所以输出 tryfinally 而不是只输出 try。5.3 自定义异常与Scanner输入异常处理机制的完整落点第11题要求自定义异常并做输入校验class MyException extends Exception { private String errorMsg; public MyException(String errorMsg) { this.errorMsg errorMsg; } Override public String toString() { return errorMsg; } } public class Ex11 { public static void main(String[] args) { Scanner scan new Scanner(System.in); String strIn scan.nextLine(); try { if (strIn.equals(abc)) { throw new MyException(输入的字符串不正确); } } catch (MyException e) { System.out.println(e); } } }自定义异常类继承 Exception重写 toString 可以自定义输出内容。注意这里scan.nextLine()读取的是整行输入如果输入两端有空格equals(abc)判断会不相等。稳妥做法是strIn.trim().equals(abc)或在读取后先trim()。第12题要求从键盘输入两个数做减法输入非数字时程序不崩溃核心思路是在 catch 块里提示用户重新输入而不是直接退出常见做法是用 while 循环包裹输入逻辑直到输入合法为止。5.4 避坑记录五个实测踩坑踩坑一LinkedList add(2,B) 运行时异常。 现象代码编译通过运行时报 IndexOutOfBoundsException。 原因链表中只有一个元素索引 2 对应的插入位置超出了链表长度约束。 解决插入位置必须是 0 到 size() 之间的整数改成add(1, B)或add(B)。踩坑二Calendar 月份从 0 开始set 出来日期不对。 现象写c1.set(2010, 7, 1)期望 7 月 1 日输出却是 8 月 1 日。 原因Calendar.MONTH 的取值范围是 0-117 代表 August。 解决使用常量Calendar.JULY逻辑不会错也不会看走眼。踩坑三finally 里的 return 覆盖 catch 里的 return。 现象count() 方法 catch 块返回 6实际结果返回 3。 原因finally 在 return 前执行其 return 优先级最高。 解决finally 只做清理返回值统一放最后一行或使用临时变量。踩坑四String.valueOf(char[], offset, count) 参数理解偏差。 现象String.valueOf(data, 1, 3)有人以为取索引 1 到 3实际输出 bcd。 原因第二个参数是起始偏移量第三个参数是长度。 解决只需要记住 count 是复制的字符个数不是结束下标。踩坑五泛型方法传入 Integer[]编译期强制约束。 现象写T extends Comparable后传入 int[]编译直接报错。 原因基本类型 int 不是对象不满足泛型边界。 解决使用包装类型Integer[]如果必须处理基本类型数组单独重载非泛型方法。6. 把题库变成面试清单验证方法与背诵技巧6.1 按知识点分组自测这套题的正确打开方式不是从头做到尾而是按知识点分组。我建议你把自己当成面试官拿这份题反过来出问题。比如集合框架部分看到Map 和 List 的区别这道题向自己追问三个层次第一层Map 是键值对List 是有序可重复集合Set 不可重复。第二层HashMap 的键为什么不可重复因为它的底层是数组加链表或红黑树靠 hashCode 和 equals 定位两个键 hashCode 相同还要 equals 判断。第三层如果自定义对象作为 HashMap 的键不重写 hashCode 会怎样会导两个内容相同的对象被当作不同键存入。把每个选择题都这样扩展成三层追问一套题库就能覆盖大部分面试场景。编码题也一样第19题的泛型方法我一般会追一个场景泛型方法能不能放进一个非泛型类里可以泛型方法的方法级类型参数与类是否泛型无关ArrayAlg 类就不是泛型类但它内部定义了泛型方法 minmax。6.2 代码题改造成编码题一份可复现的自测清单我整理了一份对照表把第2章到第5章的核心代码题映射到能力项你可以直接拿去自测题目编号核心考点自测方式容易翻车的点第6题LinkedList 索引边界换 ArrayList 再跑一次对比不知道两者插入机制差异第7题String.valueOf 重载把 double 改成 float观察输出记混 char[] 参数语义第12题Calendar 日期计算改成 -10 天验证跨月进位忘记 MONTH 从 0 开始第14题日期差值设置两个相隔1天的日期验证整除精度丢失第19题泛型边界去掉 extends Comparable 看编译报错用 int[] 提交泛型方法第11题自定义异常输入 abc 带空格再跑没做 trim 导致判断失效这套自测跑一遍大约40分钟但每道题都值得跑。第6题的运行时异常、第12题的月份偏移、第7题的重载匹配都是我实际在编译器和线上日志里见过的真实问题。有些人觉得这些题是背答案但当你亲手把add(2, B)这个越界索引跑出来比看十遍答案都印象深刻。另外一个高效技巧是改参数验证理解第4题的 Calendar 日期计算把DAY_OF_YEAR改成DAY_OF_MONTH和MONTH观察三种情况下的进位区别第16题的 parseInt 第二个参数换成 8 和 2看同一字符串在不同进制下的解析结果。这种改一行参数、看一次输出的方法比死记题目答案更能训练出对 API 边界的敏感度。从那以后我每次带新人过 Java 基础都会强制走一遍这套流程先让他们把这 34 道题按知识点分组跑完再要求每人挑三道题修改参数做扩展验证。整个过程不评价对错只要求记录每个输出结果和自己的推测。这种把题库当实验手册的做法比起直接对答案学习效果要好得多。希望这套方法对你也有用。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑