欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

2020年10月份面试问题记录

程序员文章站 2022-06-27 19:47:33
映客1.ConstraintLayout 、FrameLayout 右下方放一个view2.从架构层面介绍自己设计的模块3.项目中遇到多线程的问题4.Recycler中onCreateViewHolder何时被调用多次 ,利用RecyclerView如何画圆环5.线程池的原理,线程个数最优分配 ,如果是无限长队列,如何设置拒绝策略6.volatile的作用7.Activity生命周期方法,透明和非透明两种8.onDraw方法需要注......

映客

1.ConstraintLayout 、FrameLayout  右下方放一个view

        约束布局,可以对他的子view,比如TextView,约束其右边界在某某控件的右部一侧,约束其底部在某某控件的底部一侧,layout_constraintRight_toRightOf="parent",layout_constraintBottom_toBottomOf="parent";FrameLayout,默认其子控件都是堆叠在布局的左上角,如果要实现将一个View放在其右下角,可以给view设置layout_gravity="right|bottom"属性,相对其父控件居右、居底。

2.从架构层面介绍自己设计的模块

 

3.项目中遇到多线程的问题

       

4.Recycler中onCreateViewHolder何时被调用多次 ,利用RecyclerView如何画圆环

 

5.线程池的原理,线程个数最优分配  ,如果是无限长队列,如何设置拒绝策略

 

6.volatile的作用

 

7.Activity生命周期方法,透明和非透明两种

 

8.onDraw方法需要注意什么

 

9.图片压缩的几种方式

 

10.大图片加载

 

11.jpg和png的差别

 

12.数据库升级遇到的过什么问题,怎么解决?

 

TraxChina

1.String  、StringBuffer 、 StringBuilder区分

2.Invalidatefinish方法

3.是否可以在方法里定义静态变量

public void test(){

 Static int a = 3;

}

跟谁学

1.Android事件分发机制,dispatchTouchEvent方法返回true、false、super.dispatchTouchEvent各表示什么意思

2.属性动画、和帧动画,从性能上有何优缺点。

3.Arouter核心原理

4.Glide核心原理

5.如何从view层性能优化,TraceView如何使用

6.Activity的启动流程,可以从哪些地方做优化

7.UI卡顿的检查、处理

8.HashMap底层原理,ArrayList底层原理

9.两个int类型的链表,合并成一个链表并按顺序排列。

作业帮

1.ClassLoader的双亲委派机制

2.HashTable、HashMap原理

3.Arouter关联表关系,EventBus实现原理。

4.对象的结构

5.IPC Binder机制

6.归并排序,二叉树遍历

7.View.post()和handler.postDelay()实现原理

8.系统源码有没有留意单例的使用

9.LogUtils的封装

10.线程池阻塞队列的实现原理

11.WebView优化    (加载的时候先将资源缓存)

12.泛型擦除

微博一面

1.方法锁、类锁的区别

2.ThreadLocal的实现原理

3.一个view被绘制到页面上的流程

4.OkHttp原理

5.事件分发流程,如果所有View都不消耗,最后事件由谁处理

6.怎样确保A、B、C三个线程都执行完后,才执行D线程

7.观察者模式和订阅者模式的区别

8.UI优化

9.亮点功能

微博二面:

1.Glide缓存原理,LruCache如何实现,如果让你自己实现该如何做?

2.内存优化都做了哪些优化?

3.Handler机制原理,可否利用handler机制监控页面卡顿,怎么做?

4.Dalvik和ART虚拟机差别?

5.青蛙跳箱子问题

WiFi钥匙

1.什么是服务,前台服务和后台服务有没有了解?

2.AIDL流程

千喜鹤

1.HashMap底层原理,怎么判断存链表还是存红黑树?

2.ConcurrentHashMap如何使用,如何保证线程安全?

3.Handler消息机制,同步消息、异步消息、消息屏障区别,post和send的区别

4.APP绘制流程

setContentView 其内部是通过PhoneWindow将我们的布局添加到其内部的mContentParent中。在ActivityThread的handleResumeActivity中,会调用WindowManager的addView方法将DecorView添加到WMS中,这样DecorView被渲染到屏幕上显示,并且可以接收屏幕触摸事件;而WindowManager的最终实现是WindowManagerGlobal,在其setView方法中创建了一个最关键的对象ViewRootImpl对象,通过ViewRootImpl的setView方法,执行requestLayout()完成测量绘制,并将View添加WMS中,而且在setView中还设置了输入事件的处理,设置了一系列的输入管道。一个触屏事件发生后,经过驱动层一系列计算通过Socket跨进程通知WMS,最终屏幕事件会被发送到输入管道里,最终调用PhoneWindow的dispatchTouchEvent,其内部的callback指的就是activity,这样事件就到了Activity的dispatchTouchEvent中了。

5.AMS、PMS

6.6.0~10.0的适配

7.Glide使用流程,传入Application和Activity有什么区别

8.OKHTTP原理,拦截器加载顺序

9.Retrofit的使用

10.APP启动流程

1.ActivityA --> ActivityManagerService:我们的调用startActivity后最终交由Instrumentation的exeStartActivity方法,Instrumentation是用来做应用进程和系统进程交互的,在其方法内通过AIDL 来调用AMS的startActivity方法。

2.ActivityManagerService --> ApplicationThread:AMS只做了两件事,一是综合处理LaunchMode和Intent的flag标志位,并根据处理结果生成一个目标Activity对象,二是判断是否要为目标对象创建一个新的进程或新的任务栈。我们在执行Instrumentation的方法时传入了一个ApplicationThread的引用,这个类就是负责进程间通信的,AMS最终就是调用了B进程中的一个ApplicationThread引用,从而间接通知B进程进行相应操作。

3.ApplicationThread -> Activity:通过ApplicationThread引用,最终调用ActivityThread的scheduleTransaction方法,该方法通过Handler发送了一个Message,Message的obj就是启动Activity的事务对象,最终调用事务的execute方法,最终调用ActivityThread的handleLaunchActivity方法,通过反射创建指定的Activity,最终通过Instrumentation调用其onCreate方法。

 

小红书

1.自定义view ,在draw方法里画个背景,设置Wrap_content,放到一个100*100的父布局里,view的宽高多大

不处理wrap_content,默认是match_parent的效果,我们可以在wrap_content的时候设置一个最小默认宽高,来解决这个问题;

2.在onCreate能获取View的宽高吗,onResume里可以吗?

都不可以,在onResume方法里,DecorView才被添加到WMS中,触发View的绘制。

在onCreate中

3.EventBus原理,EventBus是跨进程的吗?

不是跨进程的。

首先在EventBus的register方法中通过反射遍历注册对象的所有方法,将带有@Subscribe标签的方法放入到一个列表里,最后以注册对象为key,以列表为value放入一个HashMap中。

订阅事件和订阅者之间也有一个关联关系表,当post执行的时候会查找订阅了该Event的订阅者并调用其方法。

postSticky的时候会将event和event.getClass保存起来,当有新事件要注册监听时,遍历map,如果有会执行一次回调。

4.在ListView和RecyclerView中LayoutInflater的inflate方法,最后一个布尔值设置什么,设置为true会有问题吗?

  1. root不能为空,否则布局文件中设置的布局参数不会起作用
  2. attach不能设置为true,否则inflate返回的布局为RecylerView,而不是我们希望返回的自定义布局对象
  3. 必须为RecylerView指定LayoutManager,否则会抛出异常

就拿我们的Adapter来说吧,在创建item布局时,有下列几种情况:

  • inflate(R.layout.xxx,null);
  • inflate(R.layout.xxx,parent,false);
  • inflate(R.layout.xxx,parent,true);

那么就讲一下这三种情况把。

首先,inflate(R.layout.xxx,null) 。这是最简单的写法,这样生成的布局就是根据http://R.layout.xxx返回的View。要知道,这个布局文件中的宽高属性都是相当于父布局而言的。由于没有指定parent,所以他的宽高属性就失效了,因此不管你怎么改宽高属性,都无法按你想象的那样显示。

然后,inflate(R.layout.xxx,parent,false)。相较于前者,这里加了父布局,不管后面是true还是false,由于有了parent,布局文件的宽高属性是有依靠了,这时候显示的宽高样式就是布局文件中的那样了。

最后,inflate(R.layout.xxx,parent,true)。这样……等等,报错了???哦,不要惊奇,分析一下原因:首先,有了parent,所以可以正确处理布局文件的宽高属性。然后,既然attachToRoot为true,那么根据上面的源码就会知道,这里会调用root的addView方法。而如果root是listView或者RecyclerView都会报错。

adpater里面不要用true。那么什么时候用true呢?答案是fragment。在为fragment创建布局时,如果为true,那么这个布局文件就会被添加到父activity中盛放fragment的布局中

5.自定义view滑动的时候,通过设置什么方法实现滑动位置。

   在MOVE事件里获取坐标,然后设置setX(),setY()

6.启动优化都做了哪些?

影响启动速度的因素有:

  1. 高耗时任务:比如三方框架初始化、MultiDex的加载、大文件读取导致c阻塞;
  2. 复杂的View层级:嵌套的Layout过多,导致View渲染过程中,影响Measure、layout的执行速度;
  3. 类过于复杂:Java对象创建需要一定的时间,如果一个类结构特别复杂,new一个对象也比较耗资源,特别是单例;
  4. 主题及Activity配置:由于主题切换,可能导致白屏,或者点了icon,过了一会才启动页面;

解决方案:

  1. 优化方法数:通过配置minify选项,打包时删除掉没有用的方法,少用一些不必要的框架,或者找轻量级框架;
  2. Dex懒加载,将dex的加载放到Splash页面;
  3. 三方框架放到线程池里初始化,或者通过异步工作协程;
  4. 一些优先级低的三方库初始化,我们可以通过Looper.myQueue().addIdleHandler(),向MessageQueue中插入一条IdleHandler,IdleHandler只会在主线程空闲时才会被Looper从队列中取出来执行。
  5. 避免在APP启动的时候做数据库的耗时任务;
  6. 通过Studio工具Layout Inspector,分析层级嵌套,优化布局;
  7. 使用没有ActionBar、TitleBar的主题,相当于在DecorView里少了一个view,所以能有效提高启动速度;(全屏主题,并设置背景为layer-list,这样不 生成view,减少view绘制时间)

7.怎么优化Activity的启动速度,怎么优化跨进程的Activity启动速度

通过Studio工具Layout Inspector,分析层级嵌套,优化布局;在onPause方法里少做操作;在第二个页面里尽量避免大对象的使用;

8.Arouter原理,Arouter怎么生成java文件

Arouter使用Apt技术,在编译阶段将路由path和组件类生成具有映射关系类,Arouter根据用户请求的postcard,需要要跳转的目标地址。

Arouter采用了分组+按需加载的思想,分组就是在原来的path到目标的map外,再加一个新的map,这个map保存了组名到组加载器的映射关系,组加载器是一个类,可以加载组内的path到目标的映射关系。按需加载时,当调用navigation方法时,线程内存里的path到目标的映射表去找(第一次通常为空),找不到然后再从通过组名找到对应的组加载器,组加载器加载改组内的路由映射关闭,并将其添加到缓存中。

9.ConcurrentHashMap支持并发读吗,支持并发写吗?

10.事件分发流程。

11.HashMap插入链表的时候,是在表头插入还是表尾插入?

12.Kotlin

13.Glide的加载流程

14.二叉树遍历

前、中、后遍历,以根节点父节点的遍历顺序来区分的,如果先遍历父节点,再遍历左子树、右子树就是前序遍历;

15.Android做了哪些适配,8.0通知栏适配,和10.0适配

6.0隐私权限动态申请;7.0的FileProvider,和不支持权限组申请;

Android 8.0通知栏消息分渠道,如果不适配,消息通知可能无法完全弹出,所以一定要适配。我们可以创建自己的通知渠道,然后在自定义通知的时候设置下发到哪个渠道。

Android8.0应用图标适配,将其分为前景层和背景层。

Android9.0默认不支持Http协议;要求启动前台服务的时候要先请求FOREGROUND_SERVICE权限。

Android10.0设备id非系统APP无法获取,可以通过硬件信息加上一些计算生成一个;取消读写本地文件的权限,新增获取系统媒体文件的权限;

 

16.怎样启动一个Activity,是new出来的吗?

ActivityThread调用performLaunchActivity方法,通过反射创建Activity对象,并执行其attach方法,Window就是在attach方法中被创建的;

17.Http和Https区别,抓包方式有差异吗,Http的post请求和get请求能抓包吗,都是明文传输吗?

阿里影业

1.Handler机制里Message是怎么获取的,Message类似什么设计模式

2.session机制过期,后续的处理逻辑是怎样的,要注意哪些(比如多个请求session失效,请求队列存储)

3.Kotlin、Jetpack

4.vue知识

5.Okhttp里线程池的阻塞队列和两个队列怎么配合使用的?

6.SharePreferences是线程安全的吗,是进程安全的吗,commit和apply的区别?

sp是线程安全的,谷歌使用3把锁保证多线程下sp的写操作安全;commit是在UI线程做提交,apply是在子线程中操作,设计apply的初衷是为了解决ANR,但也无法完全规避,当Activity.onStop()以及Service处理onStop等相关方法时,则会执行 QueuedWork.waitToFinish()等待所有的等待锁释放,因此如果SharedPreferences一直没有完成更新任务,有可能会导致卡在主线程,最终超时导致ANR;sp没有使用跨进程锁,所以是进程不安全的,跨进程读写会有数据丢失的可能,我们可以使用文件锁,保证同一时刻只有一个进程在操作sp,也可以使用谷歌倡导的跨进程通信组件ContentProvider,其他进程通过定制ContentProvider,用于访问sp,同样也能保证sp的进程安全。同时sp在写的时候也有文件备份机制,能够保证之前存储的数据恢复。

滴滴

startActivity是同步还是异步,哪个线程给哪个线程发消息?

Hander能发送同样的消息吗

Postdelay 1秒和10秒,谁先执行

按执行时间插入排序,所以1秒的先执行,只是他只能保证1秒后执行,不能保证正好在1秒的时候执行。

Aidl是同步还是异步

类点class是什么类型的对象

在主线程做耗时操作会报什么异常

如果在主线程做网络请求,会抛NetWorkOnMainThreadException异常,如果做其他耗时操作比如遍历大数组,IO,会导致ANR。

对象锁类锁会不会互相影响

静态变量是在什么时候被加载到内存的

Retroit livedata

Socket 和aidl差别

掌阅

有没有遇到过https安全性问题

证书篡改、DNS劫持

美团

1.LeakCanary原理

它通过监控Activity的声明周期,当activity调用onDestroy方法时,将activity对象包装到弱引用中,如果该弱引用对象被回收,弱引用对象就会被放到ReferenceQueue队列中,通过监控队列里的内容就能检查到Activity是否被真正回收。

2.OKHTTP相比HTTPURLConnection的优点是哪里

透明的gzip压缩;各种拦截器;支持多种类型的数据缓存;

3.TCP和UDP的区别

有没有遇到过线上OOM的情况

一般批量图片加载的时候,或者加载大图时,容易OOM,线上遇到过窗体泄漏、栈溢出的情况(递归的结束条件没处理好),线程池使用时有可能OOM。

插件化原理

一般实现方式有反射、hook等方案,插件化原理多用hook方案,比如hook主IActivityManager,先在清单文件里占坑,再在合适时候将目标对象塞到启动占坑页面的Intent中,在将要启动占坑页面的时候再修改具体要跳转的Activity。

火花思维

深拷贝、浅拷贝区别

引用拷贝:创建一个指向对象的引用变量的拷贝,它指向同一个对象。

对象拷贝:创建对象本身的一个副本。对象拷贝的方法,调用对象的clone方法,比如Student stu2 = stu1.clone();

深拷贝和浅拷贝都是对象拷贝,区别如下:

浅拷贝,拷贝原对象里的属性,但如果属性有对象属性,那么只是拷贝对象属性的引用;深拷贝的话,是拷贝原对象的所有,包括其属性是对象类型的,也会clone新的地址。

什么是泛型,作用是什么?

泛型字面意思就是广泛的类型,可以是接口、类、方法应用于非常广泛的类型,它使代码和他们操作的数据类型不再绑定在一起,同一套代码可以用于多种数据类型。降低耦合性、提高代码复用性、安全性。

编译的时候,编译器会将泛型转为非泛型的对象,将泛型擦除,替换为Object,插入必要的强制类型转换。

什么是反射?

反射就是让我们获得一个类的所有信息。

HashMap相关问题

1.HashMap的初始容量是怎么计算的?

通过位运算,将传入的参数右移一位、两位、四位、8位这样,然后做异或,计算出第一个大于该参数的2的n次幂。HashMap初始容量是16,初始扩容因子是0.75,之所以用位运算,是因为其效率高。

2.hash函数是怎么计算的?

static final hash(Object key){
    int h ;
    return (key == null)? 0 : (h = key.hashCode()^(h >>> 16));
}

key.hashCode()返回的是一个int类型,也即32位的数。然后将其右移16位后做异或(异或就是相同返回0,不同返回1)。

hash函数计算出的结果值,再和(容量-1)做与运算,便得出下标索引。

3.put过程是怎样的?

先获取位置,然后获取位置上的值,如果没有则放置上,如果有,则遍历节点,通过key判断是否有和其相同key的Node,如果有直接覆盖,如果没有,则采用头插法,插入元素。

4.什么时候扩容,机制时怎么实现的?

HashMap容量达到容器长度*扩容因子时,就会扩容。原容量左移一位,也即是原容量的二倍;遍历原数组,其中每个item变成游离的状态,重新计算各个元素下标,如果下标处没有值,直接复制,如果有值,变成头结点,之前的值变成子节点。

5.链表过长,每次遍历这个链表,会影响性能吗?

红黑树:能够减小查找范围,不用从头到尾遍历。红黑树是一个搜索树,是一种接*衡的二叉树。

红黑树的特性:每个节点要么是黑色,要么是红色;根节点是黑色;如果节点是红色,那么它的子节点必须是黑色(反之不一定成立);从根节点到叶节点或者空子节点的每条路径,都包含相同数目的黑色节点;

6.HashMap,线程不安全,可能出现两种情况,一可能同一个位置的值被覆盖;二可能会在扩容的过程中抛异常;

Android中setOnTouchListener、onTouchEvent、setOnClickListener的调用顺序?

setOnTouchListener  ---->   onTouchEvent   ---->    setOnClickListener。setOnTouchEvent的onTouch事件,返回true表示不想下传递,就不进入到onTouchEvent中了。

onTouchEvent的返回值,返回true、false、super.onTouchEvent()的区别?

true,表示消费此次时间,false即不消费;super.onTouchEvent()即直接交由父view的onTouchEvent()方法。

LeakCanary原理

1.通过ActivityLifeCycleCallbacks监听Activity的声明周期,在其onDestroy被调用的时候,将Activity包装成一个WeakReference对象,并在弱引用的构造方法里传入一个ReferenceQueue。

2.同时这个弱引对象会标记一个随机数key,并将这个key存储在强引用set集合里;

3.当系统gc的时候,会把被回收对象的弱引用都添加到ReferenceQueue中。主动触发gc,遍历队列,将将队列里的弱引用对象的key从Set集合里移出。遍历完之后,仍然在Set集合里的key,对应的WeakReference所包含的对象就是内存泄漏的对象。

BlockCanary原理

如果主线程被卡住,则其实是在Looper的loop方法里的 msg.target.dispatchMessage(msg)耗时,我们可以记录该方法执行前后的时间戳,得到差值再跟设置的阀值对比,大于阀值则dump出堆栈信息,以及CPU信息。

1.ContentProvider

它主要用来实现跨进程间数据共享,是一套安全的访问机制,Android通过ContentProvider实现图片、音频、视频数据共享。底层使用的是Binder机制。

1.Service

本地服务:指的是服务和启动服务的activity在同一个进程中

远程服务; 指的是服务和启动服务的activity不在同一个进程中。

启动本地服务用的是显式启动; 远程服务的启动要用到隐式启动。

3.BroadCastReceiver

普通广播:完全异步执行的广播,当广播发出后,几乎所有广播接收器都会在同一时间收到这条广播。

有序广播:是一种同步执行的广播,广播发出后,只会有一个广播接收器能接收到广播消息,当这个广播接收器接收到后,广播才会继承传递,对于有序广播有了先后顺序,在Android中提供了优先级的属性(priority)来控制先后,有序广播中可以截断广播,不被下一个广播接收器接收,这是有序广播的特点。

4.线程池的shutdown和shutDownNow区别

shutDown是将当前执行的线程状态置为SHUTDOWN状态,而且不再往线程池里添加任务,只在执行的任务执行完毕后才退出;shutDownNow是将当前执行线程状态都置为STOP,并试图停止线程执行,而且不再往线程池里添加任务,终止线程的办法是通过调用Thread.interrupt()方法来实现的,但如果线程中没有sleep、wait、Condition、定时锁等,则无法响应中断,所以仍然会执行下去。

阿里二面

1.final修饰的变量,如果是对象,对象里的属性能修改吗?

final修饰的变量,如果是基本数据类型,则初始化后不能再被修改,如果是引用类型,初始化后则不能再指向别的对象,但他指向的对象,其内部属性是可以更改的。

2.重写equal和hashCode需要注意什么?

==比较的是两个引用的指针地址是否相等;equal方法则比较的是两个对象的内容是否相等,不过Object的equal方法也是==判断,比的是地址。

如果只重写equal不重写hashCode,则在一些集合容器里,相同的对象会散列到不同的位置,导致相同对象不能覆盖的问题。

小米

1.自己对自己的定位评价、能给团队带来什么?

2.WebView + Recycler这种如何实现?

3.A (standard)、B(standard)、C(singleTask) D(singleInstance)、B、C,页面销毁的先后顺序

C销毁后,同栈里的A销毁,然后才是单独栈里的D销毁

4.一个大文件里有很多很多个数,没法一直读取到内存,请找出最大的数?

5.强、软、弱、虚的作用

强引用,只要对象和引用直接没有切断联系(没有置null),即便内存不足,也不会被回收,会抛OOM;

软引用,只有内存不足的时候才会被GC回收,常用来实现缓存技术,图片缓存、浏览器缓存等;

弱引用,GC时被回收,可以用来监控对象是否被回收;虚引用,随时可能被回收,主要用于监控对象是否从内存中删除。

6.ConcurrentHashMap 1.7和1.8的改动,为什么要这么改?

7.Handler机制里,入队列不俺顺序可以不?

百度

1.MVC,MVP、MVVM区别

MVC:View触发事件,传递到Controller层,Controller层完成业务逻辑后,调用Model层更改状态,Model处理完后将数据传递给View,View更新。所有的通信都是单向的。

MVP:以P层为核心,从Model中取数据,并通过接口回调的形式填充到View中,Model和View不再有联系,P分别于View和Model保持双向通信。

MVVM:它与MVP类似,V层和Model层不互相通信,ViewModel层取代了Presenter层,不同点是View和ViewModel采用双向绑定,View的变动自动反应在ViewModel上。

2.Retrofit的使用

3.RxJava

RxJava把复杂的逻辑串成一条线,很简洁的实现异步操作。RxJava的观察者模式,Observable是被观察者,Observer是观察者,通过subscribe()方法实现订阅关系。类比Android中的点击事件也是观察者模式,View是被观察者,OnClickListener是观察者,setOnClickListener来实现订阅,也就是被观察者持有观察者的引用,当被观察者的某种状态改变时,调用观察者的回调方法做通知。RxJava与之不同的是,他不但有onNext()方法,还有onComplete()和onError()方法来处理事件队列是否正常执行,后两个方法是互斥执行的。

RxJava默认的规则中,事件的发送和处理都是在同一个线程中。但观察者模式本身的目的就是”后台处理,前台回调“的异步机制,RxJava实现异步的另外一个概念是Scheduler。

  • Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler
  • Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。

map()方法是一对一的对象转换,flatMap()是一对多的转换。

小米二面

1.EventBus的优点是什么,为什么不用广播,EventBus怎么实现切线程?

2.静态广播和动态广播的注册时机分别是什么时候?

3.EventBus使用反射影响效率,这个问题有没有得到解决?

4.如何实现字母索引,继承View可以实现吗?

5.Sysnchronized与ReentrantLock实现原理有何不同?

6.volatile是线程安全的吗?

7.startActivity的时候有哪个类加载器去加载?

PathClassLoader

8.APP启动时发生的事情?

1.先去从zygote进程fork一个进程。

2.fork进程后,会调用ActivityThread的main()方法,new出一个ActivityThread对象,并且会把它与Application做关联,即attach()方法;

3.attach会引发一些列的事件,这个过程会先后创建ClassLoader、appContext和Application,把Application和ActivityThread关联到一起;

4.调用Instrumentation的callApplicationOnCreate(app)触发Application的onCreate方法;

9.Synchronized和lock的底层实现原理

Synchronized是JVM层面的锁,映射到字节码指令时,会产生两个指令,monitorEnter、monitorExit。当线程遇到monitorEnter的时候就会尝试获取锁,monitorExit释放锁。Synchronized是悲观锁,而Lock底层是CAS和Volatile来实现。竞争激烈的环境下用lock锁,竞争不激烈建议用Synchronized,因为Synchronized锁不可降级,经历一个短暂的高峰之后,synchronized所有的锁都会成为重量级锁,这个时候效率就会降低。

瓜子

1.组件间如何通信,大文件如何共享读写

2.通过脚本转换格式

3.介绍一次网络通信过程,以及可能遇到的问题

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文地址:https://blog.csdn.net/qq_21924213/article/details/109203489