乘兴裸辞心甚爽,面试工作屡遭难。 幸得大厂原题伴,点击关注莫偷懒。
最近网上有篇热帖引发了互联网圈内码农们的共鸣:
随着2021届高校毕业生秋招的工作接近尾声,职场新人接连入厂。大多数码农们也愈发感叹这种被新人薪资倒挂的现象是越来越严重了。
正所谓长江后浪推前浪,这一浪有时候就真能把你拍在沙滩上...
一些行业大佬表示:老员工工资被职场新人倒挂,更多的则是要多多反思自己。
近几年,随着互联网新兴行业的不断涌现和发展,整个行业技术也是需要不断更新迭代的。新技术的发展,对于程序员们来说既是机会,也是挑战。不断学习新知识是不可避免的,更重要的是需要确立自己未来的发展方向以及如何才能提高自身价值提升竞争力。
对于老码农来说,目前普遍存在的问题主要体现在:技术上缺少深度和广度,缺少系统性结构化知识;缺少中大型复杂项目的经验,最重要的是因为自身能力局限,使其错过很多发展的机会。
想要突破困局,老码农应该如何找准定位呢?
又要到金九银十的跳槽季了,为了让更多的小伙伴可以在面试的时候取的更好的offer,下面整理了近年来大厂面试中的原题,希望大家能在跳槽前做好准备。
以下Android大厂高频面试题目,所有题目都是来自于一线大厂真题,题目还会继续填充,答案已整理打包好,需要的伙伴点击下面二维码可以查看获取。
Part 1—Android基础
Android系统
AMS
- binder讲解
- binder Native
- AIDL使用
- binder原理
- binder原理和实现一次拷贝的流程
- Android跨进程通信
- ActivityThread里面启动那个线程是干嘛的?
binder
- 进程间通信的优势
- binder是不是异步的?
- linux有哪些线程间通信,android这种线程间通信有什么优势
- 安卓有进程通信方式有哪些
- binder的内存映射为什么只需要复制一次
handler
- handler的实现原理
- msg队列中没有消息线程处于什么状态、怎么唤醒的
- looper的阻塞是通过什么实现的
管道 - 怎么给线程创建looper的
- handler的定时任务的实现
- looper.loop做了什么
- 线程 looper hander 消息队列分别都会有几个
- message队列中没有消息后,当前线程处于什么状态,当消息再次来到的时候怎么通知当前线程
- 信号量唤起线程是怎么实现的
- Looper为什么不会造成ANR
四大组件
Activity
- Activity的生命周期
- activity生命周期,A到B按返回,生命周期顺序。
- B是SingleTop、B启动B会执行哪些生命周期方法
- A到B到C,C退出想跟A通信,怎么设计启动模式,如果A被回收了呢(有涉及onNewIntent)会不会启动onResum?
- Activity的启动模式有哪些
- Android为啥么要有Activity的存在
- Activity和window的关系
- Activity的启动流程
- 如何知道Activiyt渲染完成
- 在Activity的oncreate方法中调用finish都执行哪些生命周期
- fragment生命周期
- Fragment只能在Activity中运行吗
- Activity外部启动是否运行到其他进程、Activity的崩溃是否会影响其他进程的崩溃
- 怎么解决,如何设置只在自己的进程中运行
Service
- service的生命周期
- intentService和Service区别
- HandlerThread的实现和作用
- service和Thread的区别还有优缺点
- 一个app中两个service 一个服务进程 一个前台进程是否同时回收
- Service和Thread如何选择
Broadcase
- 有哪几类广播
- LocalBroadcas的实现原理
ContentProvider
- 四大组件哪些是运行在主线程的
View相关
View的事件分发
- view事件分发原理
- view的cancel事件都什么时候触发
- view的cancel事件都什么时候触发
- 一个listenerview里面有button,当点击button以后再划出 抬起,整个事件是怎么分发的
- 两个view 、蓝色在外、红色在内,点击红色移动到蓝色,松手哪个click事件执行了,事件怎么传递的
- 手指离开view时view收到的最后一个事件
- Activity可以做事件拦截吗,可以在开始就拦截吗,有dispatchTouchEvent吗
- 怎么解决滑动冲突
- 怎么加大view事件点击区域
view的绘制
- view的绘制流程
- view的三个重要方法的详细实现
- view和viewgroup中onLayout的区别
- 介绍一下mesure方法
- Measure三种模式的含义
- ondraw方法都什么时候调用
- 如何自定义一个ui组件,请举例介绍下
- 实现圆形头像的方法
- 自定义view,getWith和getMeasureWith什么区别,什么时候不一样,layout的时候给left和right的宽度如果跟getMeasureWith不一样会怎样
- 两个view在父布局中比重为1和2,显示结果是什么。(重点为2次measure,最终宽度为本身宽度+剩余父空间在比重所占的比例)
- 怎么获取view的高度
- handler.post 能不能获取到高度
- onCreate设置了contentView之后,获取它里面的一个textview的宽高能获取吗,如果想获取宽高如何去做?
- 如果想让一个imageView高度跟着一个textview的高度变化怎么做
- onGlobalLayoutChange里能获取到宽高吗
-还在onCreate的时候用textView.post,之后再runnable中能获取宽高吗,为什么 - view.post有自己的队列吗
- view的x和left区别
- vsynch信号收到以后有没有做什么特殊处理
- view的requestLayout和Initlayout区别
动画
- 动画分哪几类。
- 动画总结。 重点是属性动画内部实现原理,差值器和估值器的使用
- 属性动画和补间动画的区别
- 怎么实现一个View怎么绕着圆心转
Window
- Activity,Window,DecorView之间的关系
- 一个Activity一定会有一个window吗,如果有什么时候创建的
- setContentView是加在DecorView的什么地方,DecorView是什么样的布局,什么样的结构
- 如何开启一个window
- popupwindow的原理
- Activity中的window是什么时候创建的
Activity的attach方法中 - DecorView是什么时候创建的
setContentView
sp
- 实现原理
- 是不是线程安全
- 是不是进程安全的
- 怎么实现进程安全
context
- android有哪些Context
两个虚拟机区别
Dalvik
- Dalvik基于寄存器
- jvm基于栈
- 执行的是dex字节码格式
- 多个class装载在一个dex文件
ART
- 应用在第一次安装的时候会预编译成机器码
- Dalvik每次启动都要编译、ART只需要首次。所以后面启动速度更快
- ART占用空间大(原始代码占用空间大)
- 减少编译、减少cpu使用频率
进程
- 进程之间的优先级。 前台进程、可见进程、后台进程、不可见进程与空进程
- 如何起多进程
- 起多进程有什么好处
- 实现跨线程通信和跨进程通信的方式
其他
- aar打包R文件怎么处理的
- 65535方法数限制的原理、及怎么解决
- android里面的序列化方式有哪些,分别有什么区别,性能上哪个好,为什么,parceable可以持久化到本地吗?
- AsyncTask内部实现原理
- 安卓里有哪些ClassLoader,有用过pathClassLoader吗
- Serializable和Parcelable的区别,各自的优势
- 一个bitmap,怎么计算内存(RGB888)
- Android 4.0, Android5.0,Android8.0版本安装过程有啥区别
- 不同drawe文件加载在内存的区别
- 一个图片加载到内存占用占有多大内存
- 一个图片像素除了四个字节的表示还有什么表示方法
- recylerview缓存机制
- ASyncTask原理
Part 2—Java基础
类加载
- ClassLoader的双亲委派原理
- loadclass和findclass方法的关系
- 类加载机制:
DexClassLoader可以加载jar/apk/dex,可以从SD卡中加载未安装的apk
PathClassLoader只能加载系统中已经安装过的apk - java类在虚拟机中分哪几种状态
引用类型
- 内存泄漏的场景
- 强软弱虚引用分别什么区别
- 什么场景下使用虚引用
JVM
- GC的原理
- java垃圾回收算法
- JVM内存模型
- 方法区里面存的是什么
- 虚拟机中堆有几个栈有几个
- java内存结构,分成哪几个区域,其中哪些区域是线程共享的?
- jvm哪些放在栈哪些放在堆
语言特性
- hash和equel方法的区别,不都实现会有什么问题
- 对多态的理解
- 对泛型的理解和使用场景
- 什么是类型擦除
- 内部类为什么能使用外部类的私有方法
- 反射的实现原理
- 面向对象6大原则
Part 3—数据结构
- hashmap的实现原理
- hashmap扩容因子是怎么计算的,分子分母是谁
- hashmap怎么找到index
- size为啥是2的倍数
- 怎么样resize,resize之后之前的hash冲突还存在吗
- hashmap1.7之前和之后有什么区别
- 为什么1.7以后hashmap用了红黑树 不用别的树
- hashmap是不是线程安全的、有没有什么实现线程安全的方案
- CocurrentHashMap的实现原理
- LinkedHashMap 是不是线程安全的
- SparseArray与HashMap的区别
- ArrayList是线程安全的吗?默认初始容量是多少?
- ArrayMap和SparseArray
- LruCache实现原理(分为内存lru和diskLru两种实现)
- 了解红黑树吗
- recyclerview工作原理与绘制流程,以及多层缓存机制怎么做的
- 系统中用到代理模式的地方
Part 4—性能优化
包体积
- 包体积优化
1.删除无用资源
2.图片只保存一份
3.资源下沉,上层业务只使用一份
4.开启代码混淆、优化代码混淆
5.图片压缩
6.资源混淆,微信的资源混淆工具
7.zip压缩
8.so静态链接转动态链接。
9.搬,将大文件进行远程下载
10.监控:图片过大、体积过大、无用资源。
内存优化
- 内存泄漏的检测
- 内存泄漏出现的场景
- 内存泄露的本质原因
长生命周期对象引用短生命周期对象 - 什么是内存抖动
不断创建和回收重复对象,导致系统频繁GC,而GC会引起主线程阻塞,最终导致UI卡顿 - 不用Leatcanary怎么分析内存泄露
- 如果要加载一个大图片如何优化
1.缩放比例
2.采样率
3.解码格式
4.lrucache
布局绘制
- 布局优化的几个方法
1.减少嵌套层级使用 include、merge和viewstub等标签 - 减少重复绘制
1.减少不必要的背景
2.widow设置空背景
3.clipRect方法设置绘画区域 - viewstub 可以重复加载吗
不能,只能inflate一次 - 绘制优化(不要在onDraw方法里面创建新的对象)
- 影响feed流体验的关键指标,如何优化
- 如何优化fps
网络优化
- 网络优化
1.优化数据结构,压缩数据
2.根据业务合并/拆分请求
3.根据屏幕密度下发不同size的图片
4.dns缓存,缓存多个域名对应的缓存,减少解析频率
5.根据网络状态下发不同size的图片
6.根据网络状态动态调整轮训频率
7.列表数据分页加载
启动速度优化
- 启动速度优化
1.延迟初始化
2.耗时操作开线程
3.设置主题背景,防止黑屏
卡顿优化
- cpu占用过大怎么排查
- ANR是怎么发生的,如何排查
1.5S内无法响应用户输入事件
2.广播在10s内没处理结束 - trace文件内容和如何生成
- 如果一个list中加载了很多图片怎么优化
Part 5—计算机网络
- http1.0和2.0之前的区别
- https的加密原理
- https抓包原理
- 如何防止抓包
- 对称加密和非对称加密的区别
- md5和sha1区别
- http协议的组成
- .http请求头中都有哪些参数
- 简单说下网络请求的整个过程。
- 发起一个网络请求,经历哪些步骤
- http协议几次握手,几次挥手?
- TPC为什么需要三次握手
- UDP和TCP的区别
- http和https的区别:
- https的请求流程
- http1.0和2.0区别
- post和ger区别
- tcp链接数据包什么时候发出,数据包间时间间隔
- 网络优化有啥方案
Part 6—设计模式
- mvc 、mvp、mvvm的区别
- mvp的内存泄露怎么搞
- mvvm使用livedata会不会有什么内存泄露问题
- 你理解的MVVM是什么样的
- 动态代理的实现
- 项目中用到了哪些设计模式
- 责任链模式的优缺点
- 了解android中哪些设计模式
- AOP IOC DI
- 代理模式的类图
- 依赖注入和控制反转
- 一系列依赖任务的场景用什么设计模式
- 看源码中哪些设计比较印象深刻
- 静态代理和动态代理的区别
Part 7—算法
- 经典的排序算法
- N中有多少个7 (77算两个7)
- 二叉树的层序遍历
- 算数表达式转化成二叉树
- 01背包问题
- LeetCode 11 盛水最多的容器
- 两个无序数组,查找重复元素
- 链表上删除倒数第K个节点
- 写个二分查找
- 在旋转数组中输出一个数的index,不存在就输出-1
- 一个字符串去重且保持原有相对顺序
- 一个数组中,数都是成对出现只有一个是单独的 如何快速的找出它
- 链表逆转
- 最大子段和
- 层序遍历二叉树
- 合并两个有序的数组
- 归并排序
- 一个无序的int数组,给一个target数字找出数组中两个数字相加为target并输出坐标
- 桶排序
- 之字形打印二叉树
- 插入排序
- 快排
- 二维数组中全是0和1,求岛的个数
- 二维数组(n,n),横向和纵向都是升序,给定数字查找是否在其中:从(0,n)位置开始找,大于往下走,小于往左走
- 无序数组找第K大的值:采用快排思路,先按某个值划分大小组,如果大组数量大于K,那么用大组的数据继续进行大小组划分,如果大组数量小于K,累计记录大组的个数和,
- 两个有序链表合并成一个链表
- 二分查找
- 二叉树公式
Part 8—其他技术
- hotpach的实现
- 多渠道怎么打
- 进程保活的方法
- .google的jetpact
- 安卓中进程分哪几种,什么区别,这么分的作用
- webview和js通信的方式
flutter
- flutter三个绘画树的工作原理
- Flutter channel设计
- flutter如何做状态管理
- Flutter中inheritedwidget是怎么实现的
- Flutter的动态化怎么搞的
- flutter和native直接怎么共享图片,内存的共享
- dart的消息机制
Part 9—HR
- 为什么离职
- 和前面面试官聊的怎么样
- 了解我们公司吗
- 讲一个你最骄傲的项目
- 你之前公司给你带来了哪些成长
- 这次出来主要看哪个方向的机会
冲击大厂
大厂到底还是大厂……一言不合就写代码,而且相当重视基础。说是面经,其实就是帮助各位查漏补缺,完善技术栈。毕竟面经只是面试官拿来采样你的水平的测试用例,我遇到过各种奇怪的问题……
如果你觉得自己学习效率低,缺乏正确的指导,可以参考下下面分享我多年工作以来收集整理的学习路线,给大家做个参考:
1、确定好方向,梳理成长路线图
不用多说,相信大家都有一个共识:无论什么行业,最牛逼的人肯定是站在金字塔端的人。所以,想做一个牛逼的程序员,那么就要让自己站的更高,成为技术大牛并不是一朝一夕的事情,需要时间的沉淀和技术的积累。
关于这一点,在我当时确立好Android方向时,就已经开始梳理自己的成长路线了,包括技术要怎么系统地去学习,都列得非常详细。
接下来是每个模块我整理出来的文档学习资料,帮助大家更细致化的学习。
2、看视频进行系统学习
前几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。
另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你。
3、通过源码来系统性地学习
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
“编程语言是程序员的表达的方式,而架构是程序员对世界的认知”。所以,程序员要想快速认知并学习架构,读源码是必不可少的。阅读源码,是解决问题 + 理解事物,更重要的:看到源码背后的想法;程序员说:读万行源码,行万种实践。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
《486页超全面Android开发相关源码精编解析》
4、简历准备充分
可以去知乎上面搜搜别人写的有关简历的帖子,怎么准备,吸引hr, 突出自己的优点和能力,或者让朋友帮你看看简历有没有问题,比如过于简单或者浮夸,没有重点等。
尽量把你的亮点总结成一句简练的话,再加上数字来说明它的影响和意义。
其次在简历里中加入了可交互、可展示的内容,更能显出你的能力与众不同。
有很多人经常也会遇到很多关于简历制作,职业困惑、HR经典面试问题回答等有关面试的问题。同样我也搜集整理了全套简历制作、金三银四社招困惑、HR面试等问题解析,有疑问,可以提供专业的解答。
5、刷题备战,直通大厂
面试的前一周时间内,就可以开始刷题冲刺了。请记住,刷题的时候,技术的优先,算法的看些基本的,比如排序等即可,而智力题,除非是校招,否则一般不怎么会问。
关于面试刷题,我个人也准备了一套系统的面试题,帮助你举一反三。
《379页Android开发面试宝典》
以上这些资料都已打包整理完毕: