这都没挂,2021字节跳动的Android研发岗也太好进了吧?(万字面经+经验分享)

2021-07-13 11:23:28 浏览数 (1)

背景

经历了各种尝试和挣扎,终于在今年入职了今日头条,简直是实现了人生一大梦想!!

本人基本情况是:16年毕业于211院校本科,19-21年在oppo工作,算是有大厂经验了,面试的岗位是Android应用开发工程师。

职位描述:

1、负责手机端系统应用的功能开发,维护和问题修复; 2、负责所维护模块的性能优化,如冷热启动指标优化,滚动优化等; 3、负责所维护模块的内存问题处理,包括解决内存泄漏,内存调优等。 职位要求 1、本科以上学历,计算机或相关专业,3年以上Android实际开发经验 2、熟练掌握Java语言或C 语言,熟练掌握面向对象编程,熟悉Android平台的应用设计规范、具有良好的编程习惯和代码规范意识,熟悉Android平台下的代码调试和调优技术; 3、熟练掌握Android IPC 机制,熟练运用四大组件进行需求开发,有对Framework 如AMS,WMS了解的优先; 4、熟练掌握TCP, Http,Https等通讯协议,熟练使用OKHttp 或 Http其他工具类进行网络编程; 5、熟练掌握Android UI编程,动画编程,对Android事件分发流程,View绘制流程,自定义View 有较深理解; 6、有过Android系统级应用经验者优先; 7、了解并使用过开源框架或技术如 Rxjava,Retrofit,EventBus,Android JetPack,OpenGL,组件化开发经验者优先; 8、有技术亮点与技术热情,希望对某种技术有较深的研究,例如图形,网络,浏览器等; 9、具备积极进取踏实负责的工作态度,强烈的团队合作意识, 能承受工作压力。

下面说说过程和面经吧。

字节跳动面试过程

1、主要是项目经验(占面试时间的40%)

没有问所有项目,你自己挑一个最难的项目来讲 突出项目难点,项目特色,项目突出贡献,要做到通俗易懂,视频面试没法画框架图

2、突出三方能力,要了解核心思想(占面试时间的20%,如果用得多可能会聊更久)
  • OkHttp,retrofit,RxJava,EventBus,
  • OkHttp基本原理,缓存原理,连接池原理,
  • 如果每个请求都需要在url里添加字段,如何用Interceptor实现
  • retrofit的核心设计思想
3、android基础(占面试时间的20%)

3.1、Handler实现原理

  • Looper.loop()源码,即实现原理
  • Handler.postDelay()实现原理

基本情况是: 如果头部的这个Message是有延迟而且延迟时间没到的(now < msg.when),会计算一下时间(保存为变量nextPollTimeoutMillis), 然后在循环开始的时候判断如果这个Message有延迟,就调用nativePollOnce(ptr, nextPollTimeoutMillis)进行阻塞。nativePollOnce()的作用类似与object.wait(),只不过是使用了Native的方法对这个线程精确时间的唤醒。

  • 如果Message会阻塞MessageQueue的话,那么先postDelay10秒一个Runnable A,消息队列会一直阻塞,然后我再post一个Runnable B,B岂不是会等A执行完了再执行?正常使用时显然不是这样的,那么问题出在哪呢?

1、postDelay()一个10秒钟的Runnable A、消息进队,MessageQueue调用nativePollOnce()阻塞,Looper阻塞;

2、紧接着post()一个Runnable B、消息进队,判断现在A时间还没到、正在阻塞,把B插入消息队列的头部(A的前面),然后调用nativeWake()方法唤醒线程;

3、MessageQueue.next()方法被唤醒后,重新开始读取消息链表,第一个消息B无延时,直接返回给Looper;

4、Looper处理完这个消息再次调用next()方法,MessageQueue继续读取消息链表,第二个消息A还没到时间,计算一下剩余时间(假如还剩9秒)继续调用nativePollOnce()阻塞;

5、直到阻塞时间到或者下一次有Message进队;

3.2、Activity的生命周期,还有各场景下,各个生命周期的回调方法

核心知识点:

  • onStart:start表示启动,这是Activity生命周期的第二个方法。此时Activity已经可见了,但是还没出现在前台,我们还看不到,无法与Activity交互。
  • onResume:resume表示继续、重新开始,这名字和它的职责也相同。Activity在这个阶段已经出现在前台并且可见了。
  • onPause:pause表示暂停,当Activity要跳到另一个Activity或应用正常退出时都会执行这个方法。此时Activity在前台并可见,我们可以进行一些轻量级的存储数据和去初始化的工作,不能太耗时,因为在跳转Activity时只有当一个Activity执行完了onPause方法后另一个Activity才会启动,而且android中指定如果onPause在500ms即0.5秒内没有执行完毕的话就会强制关闭Activity。
  • onStop:stop表示停止,此时Activity已经不可见了,但是Activity对象还在内存中,没有被销毁。

这个阶段的主要工作也是做一些资源的回收工作。

  • 在AActivity界面点击按钮后,跳转到BActivity界面,各个activity的生命周期回调顺序

答:(A)onPause→(B)onCreate→(B)onStart→(B)onResume→(A)onStop

  • 在A界面点击按钮后,即startActivity(B)之后调了finish()方法,各个activity的生命周期回调顺序

答:(A)onPause→(B)onCreate→(B)onStart→(B)onResume→(A)onStop→(A)onDestory

  • 在A界面,启动了一个透明的B界面,各个activity的生命周期回调顺序

答:(A)onPause→(B)onCreate→(B)onStart→(B)onResume

  • 在A界面,启动了一个Dialog,activity的生命周期回调顺序

答:不会回调任何函数。

  • 在A界面,启动了一个主题是Dialog的B界面,各个activity的生命周期回调顺序

答:(等测试)

4、算法题(占面试时间20%)

面试特点:链表相关算法必须顺便,大厂常考题目,可以刷leetcode里的题目,要自己动手写,别光看题目和解析,只有自己真正思考题目,模拟考试了,才知道自己的核心问题出在哪,怎么提升

4.1、两个双向链表,返回第一个相同节点

解题思路:

  • 寻找返回结果的特性: 第一相同节点后的内容,两个链表后半段内容都一样
  • 如果是基于多个数据的计算,先对齐数据关键特性: 这里的关键特性就是链表的长度,便于依次对比节点相等 解决方案就是:获取链表长度,先遍历长的链表,让两个链表长度对齐
  • 遍历数据,指针概念:

这里使用双指针概念,一个指针遍历短的链表,另外一个指针遍历长的链表

参考答案:

代码语言:javascript复制
public ListNodetest(ListNode listNode1, ListNode listNode2) {
    if ((listNode1 ==null) || (listNode2 ==null)) {
        return null;
    }
    int length1 = length(listNode1);
    int length2 = length(listNode2);
    ListNode shortListNode = length1 > length2 ? listNode2 : listNode1;
    ListNode longListNode = length1 > length2 ? listNode1 : listNode2;
    int offset = Math.abs(length1 - length2);
    for (int i =0; i < offset; i  ) {
        if (longListNode ==null) {
            return null;
        }
        longListNode = longListNode.next;
    }
    while ((longListNode !=null)
        && (shortListNode !=null)
        && (longListNode.next != shortListNode.next)) {
            shortListNode = shortListNode.next;
            longListNode = longListNode.next;
    }
    return longListNode;
}

private int length(ListNode listNode) {
    ListNode temp = listNode;
    int length =0;
    while (temp !=null) {
        length  ;
        temp = temp.next;
    }
    return length;
}
5、其他大厂有面试,但是字节面试官没有提到的内容
  • java虚拟机相关:内存模型,GC回收机制,同步处理volatile、synchronize
  • 排序算法
  • 线程池
  • Android其他相关的:ANR原理,AIDL原理

总结:

1、面试官人很好,可以有你来主导部分面试内容,需要准备好项目经验,突出项目难点,痛点; 2、准备好三方能力的原理,有深入了解过设计思想,实现方式,是加分项 3、算法题,可以事先和面试官沟通,解题思路,如果有重大漏洞,及时想第二种方案

这里概括一下几个给同伴们的小建议:

1、把自身的技能练扎实, 2、找跟你过往经历匹配度非常高的岗位, 3.面试的时候充分展现你个人的软实力硬实力,

关于内推的(同公司应该是hr伙伴的良心建议):

1、内推如果长时间没动静可能是简历没过。 2、投递一些部门没过,可以再投别的部门,甚至有可能会有别的部门看到简历,然后捞起来。 3、面试会有记录,面试前充分准备最好不要留下不好的面评。

我当时一共经历了四面,先是直接ld,然后hr,接下来交叉部门ld,然后最后又是hr。

这个过程其实面试官的问题都不刁钻,最主要的就是根据简历里的项目问,有没有发现过什么问题、怎么解决、最终结果怎么样这样的闭环你一定得会总结。然后要给面试官展现出你的软实力,比如快速学习、逻辑思维、沟通表达能力等等。

面经分享

面试过程其实大部分时候是,面试官或者公司是主导方,大部分的节奏是跟着面试官走,但是我觉得面试其实就是一个相互探讨的过程,不仅是公司在选择你,你也在选择公司、以后工作的同事和leader。所以我这次面试中,更多的是和面试官探讨,也会反问面试官一些问题,不仅仅是最后面试官说可以问他几个问题,在面试过程中就会询问一些,优秀的面试官会跟你探讨,并且讨论出一个合理的方案或者正确的答案,整个过程非常愉悦,相互都学习到了,但是有一些面试,则不太友好,问道的问题总是说自己回去百度一下,这个很让我无语。

学历是否重要

我的答案是重要,我就是学历的受益者,只要投递出的简历都会邀请面试(除了一些对工作年限限制非常严格的企业,hulu)。当然,在互联网的圈子中,核心是你本身的技术,但是有多少人的技术能达到逆天或者非常牛逼的地步,如果你是这样的人,啥都不用说了,但是我觉得绝大部分的程序员都是普通人、平常人,不要说什么3年以后公司就不看学历了,学历是一辈子的事情,那些高考能够碾压你的人,出了社会只要他们愿意,照样能碾压你,你努力,你拼命,别人也不会睡大觉等你,所以,能提升自己的学历,还是要尽量提升的。

大公司VS小公司

“大公司拧螺丝、小公司独当一面,进步更快”,我不太认同这句话,当然具体情况具体分析,每个人的情况不同,但是我还是觉得大家能去大公司还是尽量去大公司,原因我总结了以下几点:

镀金,这一点我相信大部分同学都是赞同的,我就不赘言了。知识的深度和积累,在大公司你能学到的东西更深和更加系统,而且可以有时间自己去思考和学习,尤其对于工作时间不长的同学。

和优秀的人一起工作,大公司碰到优秀同事的概率更大,像我这样的普通人其实都是在模仿和学习,正是由于身边有了优秀太多的人,才会有危机感,才有机会跟着他们去学习,学习他们怎样学习、怎样思考问题甚至怎样为人处世。在华为中有到鑫和李桥,在抖音中,有夏老师、江老师还有乐华大佬等等,太多人,我从他们身上学到太多的东西,有一些能让我受益终身。

职业规划

作为技术人员,我大概总结了下面三个方向,其实哪个方向都是大有可为,关键还是要看自己。

  • 技术经理
  • 架构师
  • 专项领域的专家
  • 薪资福利

作为一个不再年轻的程序员来说,已经不能忽略薪资和福利,不再像刚毕业的同学,只要能成长、只要平台好,薪资什么的不重要。其实每个阶段都有自己的侧重点,我大概对薪资、平台、成长排了个序(自己的观点)

  • 1~3年,平台>=成长>薪资
  • 3~5年,平台>=薪资>=成长
  • 5~10年,平台=薪资>成长(这个阶段也可叫做规划)

上面是自己不成熟的看法,从自身的一些经验出发的,仅供参考。

面试准备

这是最辛苦的阶段,你不仅要把日常的工作做好,还要开始着手准备刷题、基础知识准备以及高阶知识的准备。

刷题:

我的方式还是之前的老套路LeetCode 《剑指offer》,虽然老,但是效果非常不错。LeetCode,刷了300 的题,这里的刷并不是指仅仅只刷一遍,我来回刷了四遍,手写了一遍(写了200多道),保证我看到题目或者类似的题目,我能第一时间想出最优的解题思路。

基础知识:

由于面的Android岗位,需要准备一些Java和Android方面的知识,有很多的文章都会去介绍怎么去复习基础的知识或者进阶知识,或者是阅读一些经典的面试数据,例如任玉刚的《Android开发艺术探索》,都是非常不错的。大家可以根据网上的文章和一些数据梳理一个自己的知识体系,将一个一个知识点形成点再到面,这样能更加深刻的理解,而且有自己的侧重点。

简历:

简历的重要性就不言而喻了,怎么样写好简历是个技术活,当然如果你有很好的背景(学校或者公司),那么不管你怎么写,基本上都不刷掉你,我们作为一般的人还是需要下一番功夫的。拿我的简历作为例子,大概有以下几个部分:

  • 个人信息:姓名、出生日期、教育背景、博客地址、github地址、联系方式(手机、邮箱和微信号)
  • 工作经历:毕业后待过哪些公司,一般是倒序,项目尽量精简明了,可以参考SMART原则
  • 专业技能:自己熟悉的一些技能,这个为什么我写到最后,因为对于工作三年的同学来说,面试官更加注重的是你的项目经历,大部分面试都是看你的项目经历来提问。

怎样写简历,这个开源网站不错,教你怎么写简历,而且有一个在线markdown在线网站,可以导出pdf。

面试前准备—技术积累冲击大厂

Android面试会涉及到很多杂而乱的知识点,所以想要进入大厂,你不仅需要有十分扎实的基本功,还需要有完整的解答逻辑

接下来分享的这份锦囊里还包含了百度、阿里、腾讯、京东等众多大厂的Android面试真题,详细介绍了各企业的面试重点、解决方案,帮助大家做好面试准备,斩获大厂高薪 offer!

通过这份锦囊,你能收获:

  • 了解大厂的面试考核标准,有的放矢地准备面试;
  • 掌握一手最新Android面试真题,有针对性地刷题;
  • 为自己心仪的公司提前做好准备,面试更有信心。

多余的话就不讲了,接下来将分享面试的一个复习路线,如果你也在准备面试但是不知道怎么高效复习,可以参考一下我的复习路线,有任何问题也欢迎一起互相交流,加油吧!

Android学习路线图

首先,对于没有学习方向,知识不体系的人,我把我工作几年整理的学习路线分享给大家,做一个借鉴作用,还不知道怎么学习的人可以直接照着我这个学习路线一个个的去学习,知识不体系的人可以参考下我整理路线的方式,总之希望能够帮到你们!

除了上面的学习路线,还可以额外的配合以下方式学习,效果翻倍~

①看视频进行系统学习

前几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。

另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你。

②读源码,看实战笔记,学习大神思路

“编程语言是程序员的表达的方式,而架构是程序员对世界的认知”。所以,程序员要想快速认知并学习架构,读源码是必不可少的。阅读源码,是解决问题 理解事物,更重要的:看到源码背后的想法;程序员说:读万行源码,行万种实践。

主要内含微信 MMKV 源码、AsyncTask 源码、Volley 源码、Retrofit源码、OkHttp 源码等等。

③面试前夕,刷题冲刺

面试的前一周时间内,就可以开始刷题冲刺了。请记住,刷题的时候,技术的优先,算法的看些基本的,比如排序等即可,而智力题,除非是校招,否则一般不怎么会问。

关于面试刷题,我个人也准备了一套系统的面试题,帮助你举一反三。

④2020大厂面试高频知识点

  • 图片
  • 网络和安全机制
  • 数据库
  • 插件化、模块化、组件化、热修复、增量更新、Gradle
  • 架构设计和设计模式
  • 性能优化
  • Android Framework
  • Android优秀三方库源码
以上这些内容均免费分享给大家,需要完整版的朋友,点这里可以看到全部内容。或者点击 【这里】 查看获取方式。

0 人点赞