当前位置: 首页 > news >正文

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行为错乱,键值对「丢失」。


#2equalshashCode的契约是什么? 🔥

标准回答

契约:equals相等则hashCode必须相同;hashCode相同对象可不等。HashMap先算哈希定位桶,再用equals比对链表/树节点。

面试官可能继续追问

  • Android 里equals/hashCode注意什么?
    自定义Parcelable数据类或 Room 实体作Map键时,用 IDE 生成二者,避免缓存命中失败。

  • 为什么HashMap先比hashCode再比equals
    先缩小桶范围,减少全字段比较,O(1) 均摊依赖此两步。

  • data class 自动生成够吗?
    Kotlindata class已生成;Java 手写实体务必同步维护两方法。


#3ArrayListLinkedList怎么选? 🔥

标准回答

ArrayList底层数组,随机访问 O(1),尾部增删均摊快;LinkedList双向链表,头尾插删快但随机访问慢。

面试官可能继续追问

  • Android 里ArrayListLinkedList怎么选?
    列表数据几乎都用ArrayListRecyclerView适配器数据源;LinkedList极少用,除非明确队列语义且规模可控。

  • ArrayList扩容机制?
    容量不足时约 1.5 倍扩容并拷贝,频繁扩容有分配开销。

  • 主线程遍历大LinkedList会卡吗?
    会,get(i)每次从头/尾遍历,大列表禁止随机索引访问。


#4HashMapput/get流程? 🔥

标准回答

put:算hash扰动 → 定位桶 → 无冲突直接放;冲突则链表或红黑树插入,超阈值扩容。get:同定位桶,再equals匹配。

面试官可能继续追问

  • Android 里HashMap怎么用?
    临时 ID 映射、内存缓存键值对常用HashMap;需淘汰策略改LruCache(内部也是LinkedHashMap)。

  • 为什么容量建议取 2 的幂?
    (n-1) & hash代替取模,位运算更快且分布均匀。

  • 多线程能直接用HashMap吗?
    不能,并发写可能死循环或丢数据,用ConcurrentHashMap或加锁。


#5 基本类型和包装类有什么区别? ⭐

标准回答

局部变量中的基本类型在栈帧内;作为对象字段或数组元素时随对象在堆。包装类是对象,有额外头与装箱开销。int/Integer在 -128~127 有缓存池。

面试官可能继续追问

  • Android 里基本类型和包装类怎么选?
    性能敏感路径(游戏循环、大量坐标计算)优先基本类型数组;泛型集合必须用包装类或 Kotlin 专用数组。

  • 自动装箱的坑?
    循环里反复Integer装箱产生大量短生命周期对象,加重 GC。

  • Kotlin 还有这个问题吗?
    有,但可用IntArray等原生数组避免装箱。


#6StringStringBuilderStringBuffer怎么选? ⭐

标准回答

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 改为尾插但仍非线程安全。


#10ComparableComparator有什么区别? ⭐

标准回答

Comparable是类内部自然排序(compareTo),如StringIntegerComparator是外部比较器,可灵活定义多套规则。TreeMap/TreeSetCollections.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:继承RuntimeExceptionError,如NullPointerExceptionIllegalArgumentException

面试官可能继续追问

  • 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同样有持有外部类风险。


#15SparseArrayHashMap怎么选? ⭐

标准回答

SparseArray用两个数组存 int key 与 value,无装箱、内存更省,key 必须 int;HashMap通用但Integer键有装箱开销。

面试官可能继续追问

  • Android 里SparseArrayHashMap怎么选?
    SDK 大量用SparseArray/LongSparseArray替代Map<Integer, ?>,如View的 tag、监听器缓存;通用对象键仍用HashMap

  • 查找复杂度?
    SparseArray二分查找 O(log n);小数据常比HashMap更省。

  • ArrayMap又是什么?
    Android 对少量映射的数组实现,适合小集合。


核心层(7 题)

#16LruCacheHashMap怎么选? 🔥

标准回答

LruCache基于LinkedHashMap访问顺序,超容量自动淘汰最久未用条目,并可重写sizeOf按字节计;HashMap无淘汰。

面试官可能继续追问

  • Android 里LruCache怎么用?
    图片内存缓存、解析结果缓存用LruCache;临时请求映射用HashMap。Glide 内部有更复杂分层缓存,思路同源。

  • sizeOf返回什么?
    条目权重,Bitmap 缓存常返回像素字节数。

  • 线程安全吗?
    LruCache本身非线程安全,多线程需外部同步或每线程实例。


#17 深拷贝和浅拷贝的区别? ⭐

标准回答

浅拷贝共享引用字段;深拷贝递归复制引用对象。Object.clone()默认浅拷贝。

面试官可能继续追问

  • Android 里深/浅拷贝注意什么?
    传递可变ListBitmap配置时,浅拷贝可能导致一处修改处处可见;需要隔离时用拷贝构造、copy数据类,或不可变集合。

  • 序列化算深拷贝吗?
    通过字节流重建对象,通常算深拷贝但性能差,注意Parcelable仍要设计字段。

  • Kotlindata class copy
    浅拷贝按字段复制,引用字段仍共享。


#18 BIO 和 NIO 在 Android 网络中的视角? ⭐

标准回答

BIO 阻塞 IO,一线程一连;NIO 多路复用,少量线程管多连接。OkHttp 早期基于阻塞 IO + 线程池;底层仍可见 socket 阻塞语义,上层用连接池与 Dispatcher 复用线程。

面试官可能继续追问

  • Android 网络里 BIO/NIO 怎么理解?
    应用层优先 OkHttp/Retrofit,不必手写 NIO,但要理解「阻塞调用别放主线程」。

  • 为什么 NetworkOnMainThreadException?
    StrictMode 禁止主线程阻塞网络 IO。

  • OkHttp Dispatcher 做什么?
    限制并发请求数,复用线程执行Runnable


#19 Java 8 lambda 在 Android 中如何工作? 💡

标准回答

源码是 lambda,DEX 编译经 desugar 转为匿名类或 invokedynamic 兼容实现,取决于 AGP 版本。

面试官可能继续追问

  • Android 里 Java 8 lambda 怎么用?
    点击监听、Stream(API 24+ desugar)都依赖此机制。注意 lambda 捕获外部变量会形成合成类,不当持有Activity会泄漏。

  • 和 Kotlin lambda 比?
    Kotlin 默认更轻量,但捕获this同样有泄漏风险。

  • 能直接上 Java 17 语法吗?
    compileOptions与 desugar 支持,AGP 8+ 支持更广。


#20try-with-resourcesAutoCloseable是什么? 💡

标准回答

Java 7+ 语法糖:在try括号内声明AutoCloseable资源,块结束自动close(),异常时先抑制关闭异常再抛主异常。

面试官可能继续追问

  • Android 里try-with-resources怎么用?
    InputStream、数据库Cursor、文件流应优先使用;Kotlin 对应use {}。避免手动finally漏关导致文件描述符泄漏。

  • close抛异常怎么办?
    try-with-resources会 addSuppressed 保留两个异常信息。

  • 哪些 Android API 实现了AutoCloseable
    ParcelFileDescriptorCursor等,用完即关。


#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 与 OkHttp;Java 8 Stream 在 Android 的边界。

容易踩坑

重写equalshashCodestatic持 Activity;主线程网络/大列表;HashMap多线程写;final List误以为内容不可变。


完整链路一句通

Java 基础在 Android 里的主线:用正确的相等语义与hashCode驱动HashMap/LruCache/SparseArray选型 → 掌握final、异常、内部类与值传递等 OOP 规则 → 资源用try-with-resources关闭 → 网络与拼接遵守「阻塞不放主线程、少在热路径分配」。


相关推荐


Android 16(API Level 36)Activity 启动流程源码级解析

Android 高级工程师面试参考答案:性能优化

http://www.cnnetsun.cn/news/3126971.html

相关文章:

  • Prometheus的告警数据上传指定api接口
  • 两大智驾强制国标报批稿公示,仿真测试成高阶智驾“安全准入门票”
  • 7 月 15 日起,追踪影视的 TV Time 应用停服,难盈利成主因
  • 小程序商城制作工具实测对比:餐宝盈/BBWEYY/比文云/Jasper Chat/Chatsonic(2026年7月更新)含零代码SAAS、AI编程、源码定制交付
  • AI服务选型实战:Token计费、模型调度与Obsidian工作流优化
  • 机械手技术解析:从核心部件到行业应用全景
  • Java SHA256加密实战:从原理到密码存储与API签名的完整指南
  • 证件照还要去照相馆?这款免费AI抠图工具,在家就能做出标准证件照
  • 【C++】008、sizeof与strlen的区别
  • 总线舵机技术解析与应用实践
  • 热成像车辆行人数据集 目标检测数据集
  • AI大模型实战选型指南:ChatGPT、Gemini、Claude、Grok工作流适配策略
  • 【EIS芯片应用专题之二】SENSIPLUS DCMU深度解读:面向锂离子电池的紧凑低功耗ASIC芯片在线高分辨率EIS
  • 百度抓取诊断:你的网站侦察兵
  • UVa 479 Irrigation Flow Rates
  • HoRain云--C++多线程编程
  • 《唤醒你的AI同事:WorkBuddy从零上手》035:工作流程优化
  • 长文档总结不卡顿,128k 上下文在 Strix Halo 上的表现
  • Gemini 1.5与GPT-4o真实对比:大模型选型的技术逻辑与落地实践
  • 垃圾短信识别项目深度复盘:中文文本分类全流程实战 + 3 个数据泄漏避坑指南
  • AI赋能非技术行业实战:我用DeepSeek+混元整理了2026河北高考志愿填报完整指南
  • DeepSeek 开源 DSpark,一个可将 LLM 推理速度提升高达 85% 的新框架
  • 【ROS】 ros学习日记(1)
  • swagger增强knife4j
  • C++:拷贝构造函数
  • 椭圆曲线 Diffie-Hellman 密钥交换解题思路
  • 集团知识管理平台建设方案:74页PpT爆款干货全解析!
  • 【2026万字实录】从理论到实战:网络信息安全全景深度解析与避坑指南
  • 后 Django 时代:SQLAlchemy 2.0、Tortoise 与 Piccolo 三大异步 ORM 选型指南
  • 几分钟完成 OpenClaw 安装,Windows 可视化步骤新手直接照搬