Android 高级工程师面试:Java 基础知识 近1年高频追问 22 题

📅 2026/7/4 3:59:12
Android 高级工程师面试:Java 基础知识 近1年高频追问 22 题
文章目录学习建议基础层8 题#1 和 equals 有什么区别 标准回答面试官可能继续追问#2 equals 和 hashCode 的契约是什么 标准回答面试官可能继续追问#3 ArrayList 和 LinkedList 怎么选 标准回答面试官可能继续追问#4 HashMap 的 put/get 流程 标准回答面试官可能继续追问#5 基本类型和包装类有什么区别 ⭐标准回答面试官可能继续追问#6 String、StringBuilder、StringBuffer 怎么选 ⭐标准回答面试官可能继续追问#7 接口和抽象类的区别 ⭐标准回答面试官可能继续追问#8 重载和重写的区别 ⭐标准回答面试官可能继续追问进阶层7 题#9 HashMap 扩容与树化机制 标准回答面试官可能继续追问#10 Comparable 和 Comparator 有什么区别 ⭐标准回答面试官可能继续追问#11 final 关键字能修饰什么有什么作用 ⭐标准回答面试官可能继续追问#12 checked 异常和 unchecked 异常怎么区分 ⭐标准回答面试官可能继续追问#13 static 成员在 Android 里要注意什么 ⭐标准回答面试官可能继续追问#14 Java 有哪几种内部类各有什么特点 ⭐标准回答面试官可能继续追问#15 SparseArray 和 HashMap 怎么选 ⭐标准回答面试官可能继续追问核心层7 题#16 LruCache 和 HashMap 怎么选 标准回答面试官可能继续追问#17 深拷贝和浅拷贝的区别 ⭐标准回答面试官可能继续追问#18 BIO 和 NIO 在 Android 网络中的视角 ⭐标准回答面试官可能继续追问#19 Java 8 lambda 在 Android 中如何工作 标准回答面试官可能继续追问#20 try-with-resources 和 AutoCloseable 是什么 标准回答面试官可能继续追问#21 Java 是值传递还是引用传递 标准回答面试官可能继续追问#22 Java 8 Stream 在 Android 里能用吗 标准回答面试官可能继续追问面试策略速查必背知识高频追问加分项容易踩坑完整链路一句通相关推荐学习建议目标层级建议初级掌握基础层 8 题/equals、集合 API、String 选型工程联想看追问第 1 条中级通读全文进阶层能讲清 HashMap 扩容、final/异常体系、内部类分类高级核心层 LruCache/拷贝/lambda/Stream 必答能串联「相等语义→集合选型→资源关闭」工程链路基础层8 题#1和equals有什么区别 标准回答比较引用是否同一对象equals比较业务语义是否相等。equals默认同重写后按字段逻辑判断。面试官可能继续追问Android 里和equals怎么用比较Bitmap缓存 key 或自定义User对象时必须明确用equals而非否则HashMap查不到或去重失败。String 用为什么有时为 true字面量进字符串池同一字面量共享引用new String()必为 false。重写equals不重写hashCode会怎样相等对象哈希不同HashMap/HashSet行为错乱键值对「丢失」。#2equals和hashCode的契约是什么 标准回答契约equals相等则hashCode必须相同hashCode相同对象可不等。HashMap先算哈希定位桶再用equals比对链表/树节点。面试官可能继续追问Android 里equals/hashCode注意什么自定义Parcelable数据类或 Room 实体作Map键时用 IDE 生成二者避免缓存命中失败。为什么HashMap先比hashCode再比equals先缩小桶范围减少全字段比较O(1) 均摊依赖此两步。data class 自动生成够吗Kotlindata class已生成Java 手写实体务必同步维护两方法。#3ArrayList和LinkedList怎么选 标准回答ArrayList底层数组随机访问 O(1)尾部增删均摊快LinkedList双向链表头尾插删快但随机访问慢。面试官可能继续追问Android 里ArrayList和LinkedList怎么选列表数据几乎都用ArrayList或RecyclerView适配器数据源LinkedList极少用除非明确队列语义且规模可控。ArrayList扩容机制容量不足时约 1.5 倍扩容并拷贝频繁扩容有分配开销。主线程遍历大LinkedList会卡吗会get(i)每次从头/尾遍历大列表禁止随机索引访问。#4HashMap的put/get流程 标准回答put算hash扰动 → 定位桶 → 无冲突直接放冲突则链表或红黑树插入超阈值扩容。get同定位桶再equals匹配。面试官可能继续追问Android 里HashMap怎么用临时 ID 映射、内存缓存键值对常用HashMap需淘汰策略改LruCache内部也是LinkedHashMap。为什么容量建议取 2 的幂用(n-1) hash代替取模位运算更快且分布均匀。多线程能直接用HashMap吗不能并发写可能死循环或丢数据用ConcurrentHashMap或加锁。#5 基本类型和包装类有什么区别 ⭐标准回答局部变量中的基本类型在栈帧内作为对象字段或数组元素时随对象在堆。包装类是对象有额外头与装箱开销。int/Integer在 -128127 有缓存池。面试官可能继续追问Android 里基本类型和包装类怎么选性能敏感路径游戏循环、大量坐标计算优先基本类型数组泛型集合必须用包装类或 Kotlin 专用数组。自动装箱的坑循环里反复Integer装箱产生大量短生命周期对象加重 GC。Kotlin 还有这个问题吗有但可用IntArray等原生数组避免装箱。#6String、StringBuilder、StringBuffer怎么选 ⭐标准回答String不可变拼接产生中间对象StringBuilder可变、非线程安全StringBuffer线程安全但同步开销大。面试官可能继续追问Android 里 String 系列怎么选主线程拼 JSON、日志、SQL 用StringBuilder常量文案用String多线程共享拼接极少见一般各线程本地StringBuilder。Kotlin 字符串拼接呢编译器优化为StringBuilder简单小量拼接可接受。String.intern()在 Android 慎用吗慎用池在堆中滥用占内存且版本行为差异大。#7 接口和抽象类的区别 ⭐标准回答接口定义能力契约Java 8 可有default/static方法抽象类可有状态与构造器单继承。面试官可能继续追问Android 里接口和抽象类怎么选OnClickListener是接口RecyclerView.Adapter是抽象类承载模板方法。多实现用接口共享基类逻辑用抽象类。为什么Activity是类不是接口框架需统一生命周期与上下文实现抽象类更合适承载模板。Kotlin 接口还能有属性吗可以有但通常无 backing field注意与 Java 互操作。#8 重载和重写的区别 ⭐标准回答重载同类同名不同参编译期绑定。重写子类覆盖父类实例方法运行期多态。面试官可能继续追问Android 里重载和重写例子onCreate(Bundle)是重写多个findViewById重载已随 ViewBinding 淡化。理解多态有助于读RecyclerView各类onBindViewHolder重写链。能重写static方法吗不能子类是隐藏hide而非多态重写。Override有必要吗有必要父类签名变更时编译期即可发现错误。进阶层7 题#9HashMap扩容与树化机制 标准回答负载因子默认 0.75元素数超容量×0.75则翻倍扩容并 rehash。单桶链表长度 ≥8 且表容量 ≥64 时链表转红黑树≤6 退化为链表防哈希攻击与过长查找。面试官可能继续追问Android 里 HashMap 扩容注意什么大缓存HashMap应预估容量减少扩容Profiler 看分配峰值是否来自频繁 rehash。为什么树化阈值是 8泊松分布下链表达 8 的概率极低权衡树维护成本。扩容是线程安全的吗否并发扩容可能导致 JDK7 环形链表问题JDK8 改为尾插但仍非线程安全。#10Comparable和Comparator有什么区别 ⭐标准回答Comparable是类内部自然排序compareTo如String、IntegerComparator是外部比较器可灵活定义多套规则。TreeMap/TreeSet、Collections.sort都依赖二者。面试官可能继续追问Android 里排序接口怎么用列表按时间、优先级排序时实体实现Comparable或传入ComparatorDiffUtil比较项也常自定义Comparator逻辑。能用 lambda 写Comparator吗可以Comparator.comparing(User::getName)更简洁。compareTo返回 0 表示什么相等TreeSet中返回 0 视为重复元素不插入。#11final关键字能修饰什么有什么作用 ⭐标准回答可修饰类不可继承、方法不可重写、字段赋值一次、局部变量引用不可改指向。面试官可能继续追问Android 里final怎么用final字段配合构造器可做不可变对象匿名内部类访问外部局部变量要求final或 effectively final。final引用和不可变对象是一回事吗不是final只保证引用不变对象内容仍可能可变如final List仍可add。为什么 lambda 捕获的变量要 effectively final捕获的是值快照允许隐式修改会破坏语义一致性。#12 checked 异常和 unchecked 异常怎么区分 ⭐标准回答checked编译期必须处理或声明抛出如IOExceptionunchecked继承RuntimeException或Error如NullPointerException、IllegalArgumentException。面试官可能继续追问Android 里异常怎么处理现代代码倾向用 unchecked 统一异常处理IO 在边界层捕获转业务错误不要在每个回调层层 throws。为什么有人反对 checked 异常样板代码多与函数式/回调风格不契合。Retrofit 网络错误算哪种调用方通过onFailure处理不强制 checked 传播。#13static成员在 Android 里要注意什么 ⭐标准回答静态字段属于类生命周期与进程一致不能持有Activity/View等短生命周期 Context否则易泄漏。静态方法无this适合工具函数。静态块做类加载期初始化。面试官可能继续追问Android 里static成员注意什么Application级单例可用静态但应持ApplicationContext而非Activity。静态变量存在哪类元数据区逻辑归属所指对象实例仍在堆。静态方法能重写吗不能子类是隐藏hide而非多态。#14 Java 有哪几种内部类各有什么特点 ⭐标准回答成员内部类持外部类引用、静态内部类不持外部实例、局部内部类方法内、匿名内部类一次性实现接口/抽象类。面试官可能继续追问Android 里内部类怎么选new OnClickListener(){}是匿名内部类非静态内部类隐式持有外部类引用长生命周期回调优先静态内部类 弱引用或改用 lambda/协程。为什么推荐静态内部类不隐式绑定外部Activity生命周期更易控。lambda 和匿名内部类关系lambda 是更简洁的函数式写法捕获this同样有持有外部类风险。#15SparseArray和HashMap怎么选 ⭐标准回答SparseArray用两个数组存 int key 与 value无装箱、内存更省key 必须 intHashMap通用但Integer键有装箱开销。面试官可能继续追问Android 里SparseArray和HashMap怎么选SDK 大量用SparseArray/LongSparseArray替代MapInteger, ?如View的 tag、监听器缓存通用对象键仍用HashMap。查找复杂度SparseArray二分查找 O(log n)小数据常比HashMap更省。ArrayMap又是什么Android 对少量映射的数组实现适合小集合。核心层7 题#16LruCache和HashMap怎么选 标准回答LruCache基于LinkedHashMap访问顺序超容量自动淘汰最久未用条目并可重写sizeOf按字节计HashMap无淘汰。面试官可能继续追问Android 里LruCache怎么用图片内存缓存、解析结果缓存用LruCache临时请求映射用HashMap。Glide 内部有更复杂分层缓存思路同源。sizeOf返回什么条目权重Bitmap 缓存常返回像素字节数。线程安全吗LruCache本身非线程安全多线程需外部同步或每线程实例。#17 深拷贝和浅拷贝的区别 ⭐标准回答浅拷贝共享引用字段深拷贝递归复制引用对象。Object.clone()默认浅拷贝。面试官可能继续追问Android 里深/浅拷贝注意什么传递可变List或Bitmap配置时浅拷贝可能导致一处修改处处可见需要隔离时用拷贝构造、copy数据类或不可变集合。序列化算深拷贝吗通过字节流重建对象通常算深拷贝但性能差注意Parcelable仍要设计字段。Kotlindata class copy浅拷贝按字段复制引用字段仍共享。#18 BIO 和 NIO 在 Android 网络中的视角 ⭐标准回答BIO 阻塞 IO一线程一连NIO 多路复用少量线程管多连接。OkHttp 早期基于阻塞 IO 线程池底层仍可见 socket 阻塞语义上层用连接池与 Dispatcher 复用线程。面试官可能继续追问Android 网络里 BIO/NIO 怎么理解应用层优先 OkHttp/Retrofit不必手写 NIO但要理解「阻塞调用别放主线程」。为什么 NetworkOnMainThreadExceptionStrictMode 禁止主线程阻塞网络 IO。OkHttp Dispatcher 做什么限制并发请求数复用线程执行Runnable。#19 Java 8 lambda 在 Android 中如何工作 标准回答源码是 lambdaDEX 编译经 desugar 转为匿名类或 invokedynamic 兼容实现取决于 AGP 版本。面试官可能继续追问Android 里 Java 8 lambda 怎么用点击监听、StreamAPI 24 desugar都依赖此机制。注意 lambda 捕获外部变量会形成合成类不当持有Activity会泄漏。和 Kotlin lambda 比Kotlin 默认更轻量但捕获this同样有泄漏风险。能直接上 Java 17 语法吗看compileOptions与 desugar 支持AGP 8 支持更广。#20try-with-resources和AutoCloseable是什么 标准回答Java 7 语法糖在try括号内声明AutoCloseable资源块结束自动close()异常时先抑制关闭异常再抛主异常。面试官可能继续追问Android 里try-with-resources怎么用读InputStream、数据库Cursor、文件流应优先使用Kotlin 对应use {}。避免手动finally漏关导致文件描述符泄漏。close抛异常怎么办try-with-resources会 addSuppressed 保留两个异常信息。哪些 Android API 实现了AutoCloseableParcelFileDescriptor、Cursor等用完即关。#21 Java 是值传递还是引用传递 标准回答永远是值传递。传基本类型传值副本传对象传的是引用的副本地址值通过副本仍可修改堆上同一对象但不能让调用方变量的引用指向新对象。面试官可能继续追问Android 里值传递常见坑方法内list.add()有效但list new ArrayList()不影响外部引用——面试高频考点。为什么很多人说是引用传递把「传对象引用」口语化成引用传递严格语义是传引用值的副本。Kotlin 一样吗一样JVM 上语义相同。#22 Java 8Stream在 Android 里能用吗 标准回答部分 API 需 AGP desugar 且minSdk配合小数据转换可用列表很大或主线程路径慎用因中间操作产生装箱与临时对象。面试官可能继续追问Android 里Stream能用吗小数据转换可用列表很大或主线程路径慎用。列表处理更常见for循环或 Kotlin 集合 API不在 UI 热路径滥用。并行parallelStream能在 Android 用吗一般不推荐共享ForkJoinPool与 UI 线程竞争难控。和 Kotlin 序列比KotlinSequence惰性求值更适合链式处理大数据。面试策略速查面试等级建议掌握初级★★★☆☆中级★★★★☆高级★★★★★必背知识/equals/hashCode三连ArrayListvsLinkedListHashMapput/get、扩容树化SparseArray/LruCache选型final/异常体系。高频追问HashMap 为何容量 2 的幂值传递 vs 引用传递非静态内部类为何易泄漏try-with-resources关闭顺序。加分项lambda desugar深/浅拷贝BIO/NIO 与 OkHttpJava 8 Stream 在 Android 的边界。容易踩坑重写equals忘hashCodestatic持 Activity主线程网络/大列表HashMap多线程写final List误以为内容不可变。完整链路一句通Java 基础在 Android 里的主线用正确的相等语义与hashCode驱动HashMap/LruCache/SparseArray选型 → 掌握final、异常、内部类与值传递等 OOP 规则 → 资源用try-with-resources关闭 → 网络与拼接遵守「阻塞不放主线程、少在热路径分配」。相关推荐​Android 16API Level 36Activity 启动流程源码级解析Android 高级工程师面试参考答案性能优化​