需求已改活已加,加班通宵看朝霞。 终是上线已延期,bug还是改不完。
面试造火箭,工作拧螺丝,虽然我只想拧螺丝,可是我需要用造火箭的技术去寻找拧螺丝的工作,如何能在面试过程中让自己处于不败的地步呢,刷题是一个比较好的捷径,今天就汇总了一些比较经典的面试题进行了汇总,分享给大家。
大厂面试真题
嘀d出行:
-
handler原理,主线程发送message给子线程
-
recyclerview列表的优化
-
自定义view,onmeasure的如何测量,测量模式起什么作用?
-
大图片如何处理?
-
sp支持多进程吗?多线程呢?
-
数据库读写在同一个线程吗?
-
一个文本文件中每行有一个手机号或电话号,给定一个手机号,判断该文件中是否存在。给出时间复杂度较低的方案。
最y:
-
对着项目一通问,包括项目结构、自己参与的部分等等
-
OKhttp原理,链式调用、链接复用等
-
对exoplayer、ijkplayer的了解,如果在视频未播放时就调用暂停,会有什么问题?如何解决视频的边下边播?如何解决列表中的视频滑动到屏幕中间就自动开始播放?
-
列表滑动卡顿该如何定位问题?
-
对以空间换时间的理解?
-
HashMap、LinkedHashMap原理
作y帮:
-
主线程给子线程发送消息,handler、threadlocal、threadlocalmap、thread之间是怎么联系的
-
glide的结构设计、btimap的复用和系统的复用比较,有什么优点?与生命周期的绑定
-
自定义view测量、布局、绘制,有没有做过复杂的自定义view,举个例子
-
一个scrollview里有个button,button有点击事件,列表可滑动,怎么去做事件分发的
-
项目架构设计、mvp的实现、model里的请求分页怎么实现?
-
视频播放器、exoplay的优缺点,ijkplay的优缺点
小m:
-
handler、massage、massager、Loop之间的关系和区别
-
view的绘制和事件分发,Android的绘制机制?布局的绘制流程?
-
Activity在oncreate中finish,生命周期是怎样的?
-
Glide、okhhtp、retrofit等三方库的原理,简单阐述
-
视频播放器封装、弹幕的实现,自己项目的结构和路由框架、新闻列表的实现、mpv的实现等
-
android内存泄露有哪些?怎么处理?handler为什么会发生内存泄露?它的gcRoot是什么?强软弱虚引用哪些可以解决内存泄露?为什么?
-
一个view上每秒显示一个数字,每隔一秒改变一次,想出解决办法,越多越好
-
代码健壮性和质量怎么控制?appbug怎么统计的?怎么处理的?
-
一个string值传入方法,值改变吗?换成stringbuild呢?
-
Java垃圾回收、分代算法的原理,如何判定对象死亡?gcRoot有哪些?Java内存模型,哪些区可以作为gcRoot?内存怎么释放?线程的工作内存放在哪?强软弱虚四种引用的区别?
-
给定数组-1,0,1,0,-1,-4,0找出其中3个数相加为0的全部组合,给出解决方案
-
判断单链表相交,找出节点,手写代码
-
反转单链表,手写代码
-
给定两个链表,存储着两个16进制数,链表的一个节点存储着16进制数的其中一个数,从高位到低位,求相加的值,返回一个链表,链表中保存相加的结果。(先反转链表,然后逐位相加,记录进位值,再与高位相加)手写代码
百d:
-
抽奖转盘,分四份,中奖概率为5%,UI和逻辑怎么实现
-
数据库查询,至少参与了三项考试,且分数均超过80的人,写出sql语句
-
线程同步:线程1循环输出1到10,线程2循环输出1到10,启动线程1、2,要求做到线程2输出5之后,线程1才开始输出(用wait、notify实现)
-
jvm内存模型,垃圾回收机制
-
手写单例
-
kotlin类的扩展,【】方括号该扩展什么?
-
怎么在项目中进行架构设计的?MVP模式的优点,如何实现?MVVM了解吗?
-
网络请求大量图片并展示在页面上,需要注意什么?网络请求资源复用、图片缓存等
-
内存泄露有哪些?怎么处理?
-
数据查出来为什么用cursor游标,而不直接返回个list集合?
-
缓存了10000条数据、怎么查出来并显示?项目中数据库大概是什么量级的?数据量及占内存量?
-
content provide是干什么的?Google为什么设计它?
-
一个网格页面、显示9张图片,弱网情况下,滑到下一页,怎么去调度线程加载下一页面的图片?
-
了解的设计模式,代理模式流程、观察者模式流程、涉及几个类
-
了解哪些google推出的比较新的库、livedata?databinding?jetpack?
-
kotlin相对于Java有什么优势?函数式编程的优势?函数式和面向对象比较
-
商城里有图片、文档、视频,字段有(id,name,type,pic,author,price),选择购买后在我的订单页可以查看,可选择下载至手机本地,给出客户端实现方案、写关键代码,给出数据库实现,写关键sql语句
-
文件中每行有一个手机号对应用户信息,给定手机号查找出对应信息,如果手机号排序了,怎么查?用了二分法查,写了简单的二分法实现
-
任意二叉树,求出其中最远的两个节点间的距离
-
对未来职业生涯的规划?怎么去做有深度的工程师?开发中遇到的困难?怎么解决的?自己项目里做的亮点!面对一份新工作怎么去适应?自己公司开发项目的流程是怎样的?你参与了哪些流程?项目中你有没有主动提出过对产品优化的意见?
Android面试原题解析
1.Bundle被用来传递数据,为什么不用HashMap代替?
从Bundle源码分析,说明我们的Bundle它实现的数据传递是通过我们的ArrayMap实现的,所以说实际上我们的这个Bundle为什么不用HashMap来替代。实际上就是说为什么我们的Android传递数据的时候要用ArrayMap,而不用HashMap。
Bundle的优势:
1). ArrayMap适合于小数据量操作,如果在数据量比较大的情况下,它的性能将退化。HashMap内部则是数组+链表结构,所以在数据量较少的时候,HashMap的Entry Array比ArrayMap占用更多的内存。而使用Bundle的场景大多数为小数据量。所以使用ArrayMap实现更合适。
2).Android中如果使用Intent来携带数据的话,需要数据是基本类型或者是可序列化类型,Bundle使用Parcelable进行序列化,而HashMap则是使用Serializable进行序列化。Parcelable它的性能是要优于Serializable的。
2. 什么是内存泄漏,Java是如何处理它的?
**内存泄漏(Memory Leak)**是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
产生的原因:一个长生命周期的对象持有一个短生命周期对象的引用。
通俗讲:就是该回收的对象,因为引用问题没有被回收,所以最终的结果,如果内存泄漏太多,那么我们内存会不断的变大,最后会产生一个OOM的过程。
Java是如何处理它的,Java本身并不会把我们处理的内存泄漏。
3. LRUCache原理
LRUCache是个泛型类,主要原理是:把最近使用的对象用强引用存储在LinkedHashMap中,当缓存满时,把最近很少使用的对象从内存中移除,并提供get/put方法完成缓存的获取和添加。LRUCache线程是安全的,因为使用了synchronized关键字。
当调用put方法时,将元素添加到链表头,如果链表头没有该元素,大小不变,如果没有,需调用trimToSize方法判断是否超过最大缓存量,trimToSize()方法中有一个while(true)死循环,如果缓存大小大于最大缓存值,会不断删除LinkedHashMap中队尾的元素,即最少访问的,直到缓存大小小于最大缓存值。当调用LRUCache的get方法时,LinkedHashMap会调用recordAccess方法将此元素添加到链表头部。
4. Synchronized使用和底层原理
Synchronized是Java中的关键字,是一种同步锁,它修饰的对象有一下几种:
1). 修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
2). 修饰一个静态的方法:其作用的范围是整个静态的方法,作用的对象是这个类的所有对象;
3). 修饰一个代码块:被修饰的代码块称为同步块,起作用是范围的大括号{}起来的代码,作用的对象是调用这个代码块的对象;
4). 修饰一个类:其作用范围是Synchronized后面括号括起来的部分,作用主对象是这个类的所有对象。
Synchronized作用主要有三个:
1). 确保线程互斥的访问同步代码;
2). 保证共享变量的修改能够及时可见;
3). 有效解决重排序问题。
5. Java 关键字Synchronized 和 volatile 的区别?
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰后,就具备了两层含义:
1).保证不同线程对该变量进行操作时的可见性,即一个线程修改了变量的值,新值对其他线程来说是立即可见的;
2). 禁止进行指令重排序。
volatile本职是告诉jvm当前变量在寄存器(内存)中的值是不确定的,需要从主存中读取。Synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞。
1). volatile仅能使用在变量上;Synchronized 可以使用在变量、方法、类上;
2). volatile仅能实现变量的修改可见性,不能保证原子性;Synchronized 则可以保证变量的修改可见性和原子性;
3). volatile不会造成线程阻塞;Synchronized 可能会造成线程阻塞;
4). volatile标记的变量不会被编辑器优化,Synchronized 标记的变量可以被编辑器优化。
6. 数组和链表的区别
**数组:**是将元素在内存中连续存储的;
**它的优点:**因为数据是连续存储的,内存地址连续,所以在查找数据的时候效率比较高;
**它的缺点:**在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间大小。在运行的时候空间大小是无法随着你的需要进行增加或者减少而改变的,当数据量比较大的时候,有可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变整个数据个数时,增加、插入、删除数据效率比较低。
**链表:**是动态申请内存空间,不需要像数组需要提前申请好内存的大小,链表只需要在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组灵活。还有就是链表中数据在内存中可以在任意的为止,通过应用来关联数据(就是存在元素的指针来联系)。
7. java中的线程创建方式,线程池的工作原理。
Java 中有三种创建线程的方式,或者4种
1).继承Thread类实现多线程;
2).实现Runnable接口;
3).实现Callable接口;
4).通过线程池。
线程池的工作原理:
线程池可以减少创建和销毁线程的次数,从而减少系统资源的消耗,当一个任务提交 到线程池时
a. 首先判断核心线程池中的线程是否已经满了,如果没满,则创建一个核心线程执行任务,否则进入下一步
b. 判断工作队列是否已满,没有满则加入工作队列,否则执行下一步
c. 判断线程数是否达到了最大值,如果不是,则创建非核心线程执行任务,否则执行饱和策略,默认抛出异常。
8.内存泄漏的场景和解决办法。
1).非静态内部类的静态实例非静态内部类会持有外部类的引用,如果非静态内部类的实例是静态的,就会长期的维持着外部类的引用,组织被系统回收,解决办法是使用静态内部类。
2).多线程相关的匿名内部类和非静态内部类匿名内部类同样会持有外部类的引用,如果在线程中执行耗时操作就有可能发生内存泄漏,导致外部类无法被回收,直到耗时任务结束,解决办法是在页面退出时结束线程中的任务。
3).Handler内存泄漏Handler导致的内存泄漏也可以被归纳为非静态内部类导致的,Handler内部message是被存储在MessageQueue中的,有些message不能马上被处理,存在的时间会很长,导致handler无法被回收,如果handler是非静态的,就会导致它的外部类无法被回收,解决办法是1.使用静态handler,外部类引用使用弱引用处理2.在退出页面时移除消息队列中的消息。
4).Context导致内存泄漏根据场景确定使用Activity的Context还是Application的Context,因为二者生命周期不同,对于不必须使用Activity的Context的场景(Dialog),一律采用Application的Context,单例模式是最常见的发生此泄漏的场景,比如传入一个Activity的Context被静态类引用,导致无法回收。
5).静态View导致泄漏使用静态View可以避免每次启动Activity都去读取并渲染View,但是静态View会持有Activity的引用,导致无法回收,解决办法是在Activity销毁的时候将静态View设置为null(View一旦被加载到界面中将会持有一个Context对象的引用,在这个例子中,这个context对象是我们的Activity,声明一个静态变量引用这个View,也就引用了activity)。
6).WebView导致的内存泄漏WebView只要使用一次,内存就不会被释放,所以WebView都存在内存泄漏的问题,通常的解决办法是为WebView单开一个进程,使用AIDL进行通信,根据业务需求在合适的时机释放掉。
7).资源对象未关闭导致如Cursor,File等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为null。
8).集合中的对象未清理集合用于保存对象,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的。
9).Bitmap导致内存泄漏bitmap是比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的bitmap对象。
10).监听器未关闭 很多需要register和unregister的系统服务要在合适的时候进行unregister,手动添加的listener也需要及时移除。
9.冷启动的流程是什么,如何优化。
当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上
**冷启动的生命周期简要流程:**Application构造方法 –> attachBaseContext()–>onCreate –>Activity构造方法 –> onCreate() –> 配置主体中的背景等操作 –>onStart() –> onResume() –> 测量、布局、绘制显示。
冷启动的优化主要是视觉上的优化,解决白屏问题,提高用户体验,所以通过上面冷启动的过程。能做的优化如下:
a) 减少onCreate()方法工作量;
b) 不要让Application参与业务的操作;
c) 不要再Application进行耗时操作;
总结:
各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。
-
BAT大厂面试题、独家面试工具包,
-
资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
的操作;
c) 不要再Application进行耗时操作;
总结:
各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。
-
BAT大厂面试题、独家面试工具包,
-
资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter
[外链图片转存中…(img-Upq4r8aY-1715431421772)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!