十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

B站Android校招笔试题全解析:高频考点与避坑指南

B站Android校招笔试题全解析:高频考点与避坑指南 2020年B站校园招聘这套Android笔试卷到现在都有不少同学在翻我见过好几个准备大厂校招的人拿它当模拟题练手。原因很简单它考的东西覆盖面广、层次分明既有基础原理的深度追问也有工程实践的综合考察还夹杂着不少“看起来会、一写就错”的陷阱题。这篇文章就围绕这套卷子的核心考点来拆把每类题背后的知识点、答题思路和容易踩的坑都捋一遍给准备Android方向面试的人一份能直接照着复习的清单。1. 笔试卷的整体结构与考察逻辑先说这套卷子给人的整体感觉。B站这种体量的互联网公司出校招笔试题通常不是单纯考“会不会背概念”而是想通过有限的题目快速筛选出“基础扎实、有工程思维、能解决实际问题”的候选人。尤其是Android方向客户端业务迭代快、性能问题敏感、团队成员协作频繁所以考察点会集中在计算机基础、Java功底、Android核心机制、性能优化、网络与数据存储这几个维度。1.1 笔试常见的题型分布从题目构成来看大致是三类单选题/多选题覆盖Java语法、数据结构、操作系统、网络协议、Android基础概念占比一般在30%到40%。这类题看似简单但经常会在选项里埋坑比如“以下哪个说法是错误的”这种反向问法或者把两个相似概念放在一起对比比如Handler.post和View.post的区别、startService和bindService的生命周期差异。简答/问答题重点考察对Android核心机制的理解深度比如Activity启动模式、Handler消息机制、Binder通信原理等。这类题光背结论没用面试官想看的是你能不能讲清楚“为什么这样设计”。编程题/设计题一般是一两道算法题加一个系统设计或场景题。算法题难度适中通常涉及链表、二叉树、动态规划或字符串处理设计题则偏业务比如“如何设计一个图片加载库”“如何实现一个带缓存的视频列表”等。1.2 B站这套卷子的考察侧重点B站作为视频社区客户端有很强的业务特征视频播放、弹幕、评论、推荐流、直播。所以它的笔试题里网络优化、图片加载、列表卡顿优化这类题目出现概率很高。我在实际做题和带人复盘时发现这套卷子特别看重三个方面第一是基础原理的扎实程度。比如Binder机制不只要知道它是Android的IPC方式还要理解为什么用Binder而不是传统的Socket或共享内存涉及拷贝次数、性能、安全性的对比。第二是排查问题的思路。很多题目会给一个场景比如“首页列表滑动卡顿你怎么定位和解决”这考察的是完整的问题排查链路先从UI渲染层面看是否掉帧再检查主线程是否有耗时操作接着看布局是否存在过度绘制最后分析内存和GC影响。第三是工程细节的把控。比如内存泄漏的常见场景、多线程并发下的数据同步、网络请求的缓存策略等这些都是实际开发中每天都在面对的事情。2. 高频核心考点深度解析这套卷子里有几个知识点几乎是必考的而且经常变换形式反复出现。我把它们单独拎出来讲透。2.1 Activity启动模式与任务栈Activity的四种启动模式——standard、singleTop、singleTask、singleInstance是校招笔试的经典题目。但我看很多同学的回答都停留在“背定义”的层面比如“singleTop表示如果栈顶存在就直接复用”这远远不够。真正的考察点在于任务栈的行为变化。例如A启动BB是singleTask模式且栈内已有B的实例那么系统会调用B的onNewIntent同时清除B之上的所有Activity。这里面有几个隐藏考点onNewIntent默认不会刷新界面数据需要手动调用setIntent和重新初始化数据singleTask和singleInstance不会在同一任务栈中重复创建但singleTask的实例可以存在于其他任务的栈中而singleInstance则是独占一个任务栈这个栈中只能有它一个Activity。另外还有一个常考的问法一个singleTask的Activity被多次启动时onCreate会不会再次执行。答案是如果实例已经存在就不会走onCreate而是走onNewIntent onRestart如果被系统回收过则还是走onCreate。这个细节很多人会答错。我在笔试答疑时经常提醒启动模式这块一定要结合onNewIntent、onRestart、taskAffinity这些一起看而且最好在模拟器上实际跑一遍启动流程观察日志输出和返回栈变化比自己死记硬背强得多。2.2 Handler消息机制的灵魂三问Handler机制是Android面试里出镜率最高的考点没有之一。B站这套卷子也毫不例外而且问得相当细往往拆成三个层次第一层Handler、Looper、MessageQueue三者的关系。Looper负责在当前线程开启消息循环MessageQueue是消息队列Handler负责发送消息和处理消息。一个线程只能有一个Looper但可以有多个Handler。这个基本关系如果答不清楚后面的都不用聊了。第二层MessageQueue的消息如何按时间排序。这里涉及同步屏障SyncBarrier、消息的when字段、阻塞唤醒机制。主线程的Looper在没有消息时会通过epoll机制休眠不占用CPU等到有消息或者超时再唤醒。这个设计是Android主线程能够常驻而不死循环消耗资源的关键。第三层为什么Handler能实现线程切换。核心在于Handler在创建时绑定了Looper所在线程当子线程调用handler.post时Message被放入主线程的MessageQueue中由主线程的Looper取出并执行所以回调代码自然运行在主线程。常见陷阱题是“Handler构造方法里调用了Looper.myLooper()如果在非Looper线程new Handler会怎样”答案是会抛出RuntimeException因为myLooper()返回null。在Android 11以前可以new Handler()默认绑定主线程Looper但之后必须显式传入Looper否则崩溃。这块我建议把源码里Handler的几个构造方法都看一遍笔试时遇到Handler相关的判断题基本能全覆盖。2.3 内存泄漏与优化内存泄漏是Android性能面试的必考项这套卷子里肯定会有一两道题而且通常不是直接问“什么是内存泄漏”而是给出场景让你判断是否会泄漏。高频泄漏场景有几个我列一下匿名内部类持有外部类引用典型的如Handler内部类持有了Activity消息还在队列中Activity无法被回收。静态Context引用比如在单例中保存了Activity的Context。注册了Receiver或EventBus没有反注册。流对象、Cursor、数据库连接没有关闭。长时间持有Bitmap且未复用或未回收。动画未停止或无限循环动画导致View无法释放。回答这类题目时光说“会泄漏”还不够要能讲清楚泄漏链路谁持有了谁为什么GC无法回收以及怎么解决。比如Handler泄漏标准回答是Handler在Activity销毁后仍可能持有Activity引用消息队列中的消息引用Handler导致Activity无法被回收解决方案是把Handler改成静态内部类并使用弱引用同时在onDestroy中removeCallbacksAndMessages(null)。B站这类公司对性能优化的要求很高因为视频播放页面和首页推荐流的渲染压力都很大。所以我建议在准备这类题目时把LeakCanary的检测原理也看一下比如它是如何通过Application注册ActivityLifecycleCallbacks来监听Activity销毁再配合ReferenceQueue判断是否发生泄漏的。这些工程细节如果能在笔试里写出来会很加分。2.4 网络协议与HTTP网络这块也是笔试重灾区。HTTP、HTTPS、TCP三次握手四次挥手、DNS解析这些是基础。Android方向还会多考察一些和客户端强相关的内容比如OkHttp的拦截器机制、Retrofit的动态代理、HTTP缓存策略。一个经常出现的简答题是HTTP和HTTPS的区别。除了常规的加密传输、端口不同80和443、需要证书之外有个进阶的点是HTTPS的握手过程——包括客户端验证服务端证书、协商对称加密密钥ECDHE或RSA、之后通过对称加密传输数据。如果能在回答中提到TLS 1.3相比TLS 1.2减少了往返次数会显得你确实了解网络原理而不是背课本。另一个常见的是TCP为什么是三次握手而不是两次。因为三次握手能确认双方的收发能力都正常两次无法保证服务端确认客户端的接收能力而且能防止旧连接请求突然到达服务端导致的资源浪费。至于OkHttp考试中比较喜欢问的是“OkHttp的请求流程”或者“OkHttp的拦截器有哪些”。这个可以按责任链来答应用拦截器自定义Interceptor→ RetryAndFollowUpInterceptor重试和重定向→ BridgeInterceptor补全请求头→ CacheInterceptor缓存→ ConnectInterceptor建立连接→ CallServerInterceptor发起请求并读取响应。每层拦截器职责清晰这就是责任链模式在Android网络库中的典型应用。3. 编程题与算法思路实战拆解算法题在B站这套笔试卷中通常占一道或两道难度不会特别夸张但要求现场写出来的代码必须能跑、能处理边界情况。我根据经验总结了几类最常出现的算法题型和对应的解题模板。3.1 链表类题目链表是校招笔试的最爱因为代码量适中、边界条件多、能考察基本功。典型的题目有反转链表、链表相交、环形链表判断、合并两个有序链表。以反转链表为例如果要求O(1)空间原地反转标准解法是迭代三指针pre、cur、next每次把cur指向pre然后整体右移。另一个常考的是K个一组反转链表这需要先数够K个节点再做子链表反转注意首尾连接。笔试时建议先把链表节点的定义写好注意判空再动手写核心逻辑这样至少能拿到部分分。3.2 二叉树与DFS/BFS二叉树相关的题目比如层序遍历、最近公共祖先、路径总和等也很常见。层序遍历的核心是使用队列每次记录当前层的节点数来控制出队次数。这里有个细节必须提前把当前队列的大小记录下来否则在循环中动态获取queue.size()会随着出队入队而变化导致层边界错乱这个坑我见过无数人踩。如果题目要求输出每一层的平均值或者最大值就是在层序遍历的基础上增加一个汇总逻辑即可。二叉树题目往往可以用递归和迭代两种写法笔试时优先用递归代码更简洁不容易写错。3.3 常见的手写工具类题有时候笔试题不会直接给你算法题而是让你手写某个工具类比如手写单例模式要求线程安全的双重检查锁版本手写线程安全的懒加载缓存手写一个生产者消费者队列手写LRU缓存这些题表面是“写代码”实际上考察的是并发控制、数据结构选型和边界处理能力。以手写LRU为例核心是LinkedHashMap的accessOrder机制重写removeEldestEntry方法即可实现如果要求自己实现而不借助LinkedHashMap则要用HashMap 双向链表每次访问把节点移到链表头部淘汰时删除尾部节点。这里有一个容易被忽视的点并发环境下需要对整个缓存加锁或者使用ConcurrentHashMap 锁分段单纯用HashMap在put和get同时发生时可能产生不一致。我在面试别人时发现很多同学能背出LRU的思路但一写代码就漏掉“访问已存在节点时需要先删除旧节点再头插”这一步导致链表出现重复节点。这种细节就是笔试拉开差距的地方。3.4 动态规划入门题型动态规划在校招笔试中出现概率很高B站这套卷子如果出现了一般属于中等偏下难度比如爬楼梯、最长递增子序列、打家劫舍。解题模板是三步定义dp数组含义、寻找状态转移方程、确定初始化和遍历顺序。举“最长递增子序列”为例定义dp[i]为以nums[i]结尾的最长递增子序列长度转移方程是dp[i] max(dp[j] 1) for all j i and nums[j] nums[i]。这个思路不难但笔试时一定要处理dp数组初始化为1因为单个元素本身就是一个长度为1的子序列。如果不初始化结果全为0。这些算法题准备时没有什么捷径我建议把Hot 100里链表、二叉树、字符串、动态规划的经典题型各刷10道左右重点是理解思路而不是背代码因为笔试题往往会在原题基础上改动条件死记硬背容易翻车。4. 系统设计题与开放性问题的回答策略这套卷子还有一个让很多人头疼的部分就是系统设计题或开放性问题。这类题没有标准答案考察的是你分析问题、设计解决方案和权衡取舍的能力。B站这类视频平台出题会围绕业务场景展开。4.1 典型题型图片加载库的设计假设题目是“设计一个图片加载库需要考虑哪些方面”这是个很典型的开放题。回答时可以按这几个模块来拆内存缓存使用LruCache管理Bitmap根据设备可用内存分配缓存大小一般取maxMemory / 8。磁盘缓存使用DiskLruCache缓存压缩后的图片文件key通常是url的md5值。网络加载通过OkHttp异步下载图片支持HTTP缓存机制ETag、Last-Modified。异步处理线程池加载图片主线程回调更新UI注意线程池核心线程数、队列容量、拒绝策略的配置。图片压缩按ImageView的实际宽高进行采样压缩inSampleSize避免OOM。生命周期感知页面销毁时取消正在进行的加载任务避免回调到已销毁的组件。回答的逻辑要按“加载流程”来串而不是罗列名词。比如一张图片从url到显示先查内存缓存命不中再查磁盘缓存再没有就发起网络请求下载成功后写入两级缓存最后在主线程设置到ImageView。这样回答层次清晰也体现你做过实际项目。4.2 典型题型直播或视频播放场景题B站笔试题偶尔会出现“视频首屏秒开怎么做”或“直播弹幕如何实现不卡顿”这类场景题。这些题目不是让你写代码而是考察对性能优化和业务架构的理解。比如“首屏秒开”可以回答的方向包括预连接提前建立网络连接、预加载提前缓存部分视频数据、分片下载支持边下边播、播放器初始化优化如提前创建播放器实例等。但如果答题只说“加个缓存”就太单薄了需要说清楚预加载的触发时机、缓存大小限制、内存和磁盘的配合策略。我当时的一位同事总结过一个思路我觉得很值得参考回答场景题时给自己定一个框架——用户路径、耗时分析、优化手段、效果验证。先描述用户在什么路径上感知到了什么问题再分析这个问题的耗时分布在哪几个阶段然后针对每个阶段给出优化手段最后说怎么验证优化效果如首帧耗时、缓存命中率、卡顿率。这个框架在笔试和面试场景下都非常好用。4.3 回答开放题的避坑建议写开放题最容易犯的毛病有这几个第一是答得不系统想到哪写到哪。比如问“如何优化列表卡顿”只写“用RecyclerView不用ListView”就结束了。应该从主线程耗时、布局层级、渲染频率、内存分配几个维度展开。第二是只有结论没有方案。比如写“使用缓存”但没有说缓存放在哪、淘汰策略是什么、怎么保证一致性这让面试官感觉你没有真正做过。第三是不考虑边界和异常。设计一个缓存系统时如果能主动提到“磁盘缓存写入失败怎么处理”“应用进程被杀后缓存是否有效”“弱网环境下缓存策略应该怎么调整”这些细节会大幅提升答案质量。5. 备考路线与复习资源推荐如果目标是B站或者其他大厂的Android校招岗位这套卷子可以当作一次摸底测试。我的建议是先限时做一遍找到自己的薄弱模块再有针对性地复习。以下是我根据带人经验总结的比较高效的备考节奏。5.1 基础阶段Java、数据结构和操作系统Java是Android的根基重点看集合源码HashMap、ArrayList、LinkedList、并发synchronized、volatile、Lock、线程池、JVM内存区域和GC算法。数据结构方面数组、链表、栈、队列、二叉树、哈希表、堆这几种类型要熟练。操作系统方面重点看进程与线程、死锁、内存管理、虚拟内存这些在笔试中偶尔会以选择题出现。时间安排上如果每天能投入3到4小时建议用两周时间过一遍Java基础和数据结构的核心内容。这个阶段不建议直接啃源码先理解整体结构和设计意图等面试前再深入细节。5.2 核心阶段Android系统和组件原理Android部分需要重点掌握的内容包括Activity启动流程与启动模式Service生命周期与绑定原理BroadcastReceiver注册方式与作用ContentProvider的跨进程数据共享Handler与Looper机制Binder与AIDL原理View的绘制流程Measure、Layout、Draw事件分发机制RecyclerView的缓存机制与优化四大组件之间的通信方式这里我特别想强调跟着源码看一遍的必要性。很多人觉得读源码难但像Activity启动过程、View的绘制流程其实核心路径并不长花一个周末的时间下载AOSP源码或者直接在Android Studio里看SDK源码把关键方法走一遍效果比刷十篇博客都好。笔试里一些细节题比如“onMeasure传入的MeasureSpec中的EXACTLY和AT_MOST分别对应什么”不读源码很难记得牢。5.3 强化阶段性能优化与大厂真题性能优化是拉开差距的地方。除了前面提到的内存泄漏还要准备弱网优化、启动优化、包体积优化、布局优化、卡顿监控。推荐的资料包括《Android开发艺术探索》关于性能优化的章节官方文档里的应用性能优化指南LeakCanary、BlockCanary的源码与实现原理真题练习方面牛客网、力扣上的Android面试题合集可以作为刷题素材近几年的校招真题多练几套。尤其注意限时演练非常重要很多真实考试挂掉的考生都是因为时间分配不合理——前面选择题纠结太久最后编程题没时间写。5.4 项目经历与简历准备的小建议除了笔试本身B站这种公司也会通过简历和面试来综合评判候选人。我的建议是选一个有代表性、能讲清楚技术难点的项目写在简历上。所谓能讲清楚指的是你能回答这几个问题项目背景是什么解决的是谁的问题你负责的模块技术方案是什么为什么这么选实现了哪些功能和指标踩过哪些坑怎么解决的如果重做一遍哪里会做得不一样把这些准备好笔试通过之后面试环节也会顺利很多。6. 笔试常见失分点与细节陷阱最后这部分我把这套卷子以及类似的大厂Android笔试卷里最容易出错的地方集中做一次整理。每一条都是我见过真实考生栽跟头的拿出来说说。6.1 概念混淆类陷阱startService和bindService混为一谈。startService启动的Service与启动者无关即使启动者退出Service仍然存活bindService则与绑定者绑定解绑时如果没其他绑定则销毁。onSaveInstanceState和onPause的执行顺序。onSaveInstanceState在onPause之后、onStop之前调用不是onStop之后。这个顺序在很多选择题里被当作干扰项。进程和线程的区别。进程是资源分配的最小单位线程是CPU调度的最小单位。Android中每个应用默认运行在自己的进程中但同进程可以有多个线程。dp和px的区别。dp是密度无关像素px是物理像素。在mdpi160dpi下1dp等于1px其他密度下需要按比例换算。6.2 细节记忆类陷阱RecyclerView并没有自带点击事件需要自己实现OnItemClickListener。HashMap允许key和value为nullHashtable不允许ConcurrentHashMap也不允许。接口中的变量默认是public static final接口中的方法默认是public abstract。静态代码块在类加载时执行且只执行一次执行顺序是静态代码块 构造代码块 构造函数。equals相等则hashCode必须相等hashCode相等则equals不一定成立。字符串比较用equals而不是Integer在-128到127之间有缓存超过范围用可能返回false。6.3 答题策略类建议笔试时间有限我的策略是先做会的题再做半会的题最后啃不会的题。选择题如果完全不会不要空着判断题型的概率至少能蒙对一些。简答题即使不知道完整答案也要把相关的、已知的知识点写上因为阅卷时通常按点给分写总比不写好。编程题如果时间不够先写出暴力解法也能拿一部分分数总比交白卷强。很多大厂的笔试通过率并不高但只要你把基础题的分全拿住再在编程题上做出一个题目基本就能过线。我个人在实际操作中的体会这套2020年B站的Android笔试卷虽然过去几年了但我一直把它当作考察Android基本功的“试金石”。它不偏不怪考察的都是日常开发中最核心的知识点同时又有足够的深度来区分“会用”和“懂原理”的人。如果你能把这套卷子里的考点全部掌握再稍作算法题训练应付大部分互联网公司的Android校招笔试应该是够用的。最后再分享一个复习时的小技巧不要只刷题每做完一道题都问自己一句“这题改个条件我还能答对么”。比如Activity启动模式你背会了四种模式但换成“A启动BB又启动C此时C是singleTaskC点击返回会回到哪个Activity”这种变体题还能答对吗这种自我追问式的复习比盲目刷题效率高得多。
返回列表