Android面试题:小米+百度+360+美团

前言

很多人在这一段时间面试了很多公司确迟迟得不到心仪公司的offer 接下来,我会整理一些一线互联网公司的面试题,希望能在面试的时候帮助到大家


image

一.什么情况导致oom-乐视-美团

1)使用更加轻量的数据结构
2)Android里面使用Enum
3)Bitmap对象的内存占用
4)更大的图片
5)onDraw方法里面执行对象的创建
6)StringBuilder

二.Service与Activity之间通信的几种方式

通过Binder对象
通过broadcast(广播)的形式

三.如何保证service在后台不被Kill

1.onStartCommand方法,返回START_STICKY

START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。

2.提升service优先级

在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。

3.提升service进程优先级

Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。Android将进程分为6个等级,它们按优先级顺序由高到低依次是:

前台进程( FOREGROUND_APP)
可视进程(VISIBLE_APP )
次要服务进程(SECONDARY_SERVER )
后台进程 (HIDDEN_APP)
内容供应节点(CONTENT_PROVIDER)
空进程(EMPTY_APP)

当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground 将service放到前台状态。这样在低内存时被kill的几率会低一些。

4.onDestroy方法里重启service

service +broadcast 方式,就是当service走ondestory的时候,发送一个自定义的广播,当收到广播的时候,重新启动service;

5.pplication加上Persistent属性

6.听系统广播判断Service状态

通过系统的一些广播,比如:手机重启、界面唤醒、应用状态改变等等监听并捕获到,然后判断我们的Service是否还存活,别忘记加权限啊。

四.Requestlayout,onlayout,onDraw,DrawChild区别与联系-猎豹

requestLayout()方法 :会导致调用measure()过程 和 layout()过程 。

将会根据标志位判断是否需要ondraw

onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局)

调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)

drawChild()去重新回调每个子视图的draw()方法

五.优化自定义view百度-乐视-小米

为了加速你的view,对于频繁调用的方法,需要尽量减少不必要的代码。先从onDraw开始,需要特别注意不应该在这里做内存分配的事情,因为它会导致GC,从而导致卡顿。在初始化或者动画间隙期间做分配内存的动作。不要在动画正在执行的时候做内存分配的事情。

你还需要尽可能的减少onDraw被调用的次数,大多数时候导致onDraw都是因为调用了invalidate().因此请尽量减少调用invaildate()的次数。如果可能的话,尽量调用含有4个参数的invalidate()方法而不是没有参数的invalidate()。没有参数的invalidate会强制重绘整个view。

另外一个非常耗时的操作是请求layout。任何时候执行requestLayout(),会使得Android UI系统去遍历整个View的层级来计算出每一个view的大小。如果找到有冲突的值,它会需要重新计算好几次。另外需要尽量保持View的层级是扁平化的,这样对提高效率很有帮助。

如果你有一个复杂的UI,你应该考虑写一个自定义的ViewGroup来执行他的layout操作。与内置的view不同,自定义的view可以使得程序仅仅测量这一部分,这避免了遍历整个view的层级结构来计算大小。这个PieChart 例子展示了如何继承ViewGroup作为自定义view的一部分。PieChart 有子views,但是它从来不测量它们。而是根据他自身的layout法则,直接设置它们的大小。

六.ctivity Window View三者的差别,fragment的特点-360

Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)
LayoutInflater像剪刀,Xml配置像窗花图纸。
在Activity中调用attach,创建了一个Window
创建的window是其子类PhoneWindow,在attach中创建PhoneWindow
在Activity中调用setContentView(R.layout.xxx)
其中实际上是调用的getWindow().setContentView()
调用PhoneWindow中的setContentView方法
创建ParentView:作为ViewGroup的子类,实际是创建的DecorView(作为FramLayout的子类)
将指定的http://R.layout.xxx进行填充,通过布局填充器进行填充【其中的parent指的就是DecorView】
调用到ViewGroup
调用ViewGroup的removeAllView(),先将所有的view移除掉
添加新的view:addView()

Fragment 特点

Fragment可以作为Activity界面的一部分组成出现;
可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
在Activity运行过程中,可以添加、移除或者替换Fragment;
Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。

七.LinearLayout和RelativeLayout性能对比-百度

RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure
RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。
在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。

最后再思考一下文章开头那个矛盾的问题,为什么Google给开发者默认新建了个RelativeLayout,而自己却在DecorView中用了个LinearLayout。因为DecorView的层级深度是已知而且固定的,上面一个标题栏,下面一个内容栏。采用RelativeLayout并不会降低层级深度,所以此时在根节点上用LinearLayout是效率最高的。而之所以给开发者默认新建了个RelativeLayout是希望开发者能采用尽量少的View层级来表达布局以实现性能最优,因为复杂的View嵌套对性能的影响会更大一些。

八.View刷新机制-百度-美团

由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该视图需要重绘时,就会为该View添加该标志位。

调用流程 :

mView.draw()开始绘制,draw()方法实现的功能如下:

绘制该View的背景
为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框)
调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)
调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能

九.腾讯公司面试题精选

1.2000万个整数,找出第五十大的数字?

答:思路:通过冒泡、选择、建堆方法

2.从网络加载一个10M的图片,说下注意事项

答:图片缓存、异常恢复、质量压缩

3.自定义View注意事项

答:渲染帧率、内存

4.、项目中常用的设计模式

答:单例、观察者、适配器、建造者

十.阿里面试题精选

1.进程间通信方式

1.通过Intent在Activity、Service或BroadcastReceiver间进行进程间通信,可通过Intent传递数据
2.AIDL方式
3.Messenger方式
4.利用ContentProvider
5.Socket方式
6.基于文件共享的方式

2.什么是协程

答:我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

3.内存泄露是怎么回事

答:由忘记释放分配的内存导致的

4.程序计数器,引到了逻辑地址(虚地址)和物理地址及其映射关系

答:虚拟机中的程序计数器是Java运行时数据区中的一小块内存区域,但是它的功能和通常的程序计数器是类似的,它指向虚拟机正在执行字节码指令的地址。具体点儿说,当虚拟机执行的方法不是native的时,程序计数器指向虚拟机正在执行字节码指令的地址;当虚拟机执行的方法是native的时,程序计数器中的值是未定义的。另外,程序计数器是线程私有的,也就是说,每一个线程都拥有仅属于自己的程序计数器。

5.数组和链表的区别

答:数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组。

链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表数据结构了。

6.二叉树的深度优先遍历和广度优先遍历的具体实现

7.堆的结构

答:年轻代(Young Generation)、年老代(Old Generation)和持久代(PermanentGeneration)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃 圾收集影响比较大的

8.什么是深拷贝和浅拷

答:浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。

深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝

9.对象锁和类锁是否会互相影响

答:对象锁:Java的所有对象都含有1个互斥锁,这个锁由JVM自动获取和释放。线程进入synchronized方法的时候获取该对象的锁,当然如果已经有线程获取了这个对象的锁,那么当前线程会等待;synchronized方法正常返回或者抛异常而终止,JVM会自动释放对象锁。这里也体现了用synchronized来加锁的1个好处,方法抛异常的时候,锁仍然可以由JVM来自动释放。

类锁: 对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。我们都知道,java类可能会有很多个对象,但是只有1个Class对象,也就是说类的不同实例之间共享该类的Class对象。

Class对象其实也仅仅是1个java对象,只不过有点特殊而已。由于每个java对象都有1个互斥锁,而类的静态方法是需要Class对象。所以所谓的类锁,不过是Class对象的锁而已。获取类的Class对象有好几种,最简单的就是MyClass.class的方式。

类锁和对象锁不是同1个东西,一个是类的Class对象的锁,一个是类的实例的锁。也就是说:1个线程访问静态synchronized的时候,允许另一个线程访问对象的实例synchronized方法。反过来也是成立的,因为他们需要的锁是不同的。

10.looper架构

11.自定义控件原理

12.ActivityThread,Ams,Wms的工作原理

答:ActivityThread: 运行在应用进程的主线程上,响应 ActivityManangerService 启动、暂停Activity,广播接收等消息。

ams:统一调度各应用程序的Activity、内存管理、进程管理

13.Java中final,finally,finalize的区别

final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
finally 是异常处理语句结构的一部分,表示总是执行.
finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. JVM不保证此方法总被调用.

14.一个文件中有100万个整数,由空格分开,在程序中判断用户输入的整数是否在此文件中。说出最优的方法

15.两个进程同时要求写或者读,能不能实现?如何防止进程的同步?

16.volatile 的意义?

答:防止CPU指令重排序

17.烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢?

答:先用2根绳子,其中1根一头点火,另1根两头点火,当第2根烧完的时候(即半小时),把第1根的另一头也点火,则当第1根烧完的时候,时间为45分钟;再另外用第3根绳子两头同时点火,烧完为30分钟,加起来为1小时15分钟。

更多面试题整理正在路上,稍后补充

十一.经验分享

我也算是一线公司都踩过点的码农了,Facebook也踩过一次,现在就说说我自己的一些感受。

之前我作为面试官接触过几十个面试者,能左右我是不是通过这个人的,主要因素还是这个人对技术的热爱程度。因为有这种极客精神,做任何技术上的事情都是时间上的问题,所以面试过程中要尽可能表现出对技术的热爱。

那除了这种因素外,我们怎么做才能更大概率的进入一线公司呢?

面试中非理性因素也有较大比重,但是这种东西是我们没办法掌控的,如果因为这种因素失败了,也没必要气馁。我认为能力是和回报成正比的,就算此刻没发生,下一刻也会出现,只要掌握了我们该掌握的能力,总有一天会进入我们理想的公司。

还有一个比较重要的因素就是知识的深度。我认为深度优于广度,广度通过看各种文章都能了解,但一旦碰到实际问题,这时候往往靠的是自己的知识深度。比如,Java程序猿都知道Java是跨平台的,因为会编译成和平台无关的字节码,但是有多少人会知道是怎么编译的?如果不知道虚拟机运行原理,就不可能做出手淘的Atlas容器框架。再比如,很多人知道四大组件职责都是什么,还会些性能优化,但是如果不知道Framework层系统服务原理,就做不出插件化框架。

因为一线公司业务的复杂度也决定了业务的深度,如果没有较好的深度探究能力,是很难胜任的,所以知识的深度也很重要。


image

想学习更多Android知识,或者获取相关免费资料请加入Android开发交流群:1018342383。 有面试资源系统整理分享,Java语言进阶和Kotlin语言与Android相关技术内核,APP开发框架知识, 360°Android App全方位性能优化。Android前沿技术,高级UI、Gradle、RxJava、小程序、Hybrid、 移动架构师专题项目实战环节、React Native、等技术教程!架构师课程、NDK模块开发、 Flutter等全方面的 Android高级实践技术讲解。还有在线答疑

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 1,java 接口的意义: 规范,扩展,回调 规范:比如,有两个及上的的类拥有相同的方法,但是实现功能不一样,就可...
    漫唐阅读 957评论 0 6
  • java 接口的意义-百度 规范、扩展、回调 抽象类的意义-乐视 为其子类提供一个公共的类型封装子类中得重复内容定...
    交流电1582阅读 2,207评论 0 11
  • 又是一年毕业时,忍不住感慨时光在飞逝。一晃很多年,那些年的人和事,大多已随着时光逐渐被遗忘,但我却依然记得那年摆放...
    春天的木棉阅读 329评论 0 0
  • 一剪梅·红藕香残玉簟秋 【作者】李清照【朝代】宋 红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来,雁字回时,月...
    ShakespeareSky阅读 207评论 0 0
  • 人生如行在旅途,须放空心情,才能一路风景一路歌。 ——题记 雾气迷蒙...
    七八点读书阅读 1,280评论 2 3