Android 面试汇总(不定期更新)

Android

系统架构图

Activity

Service

BroadcastReceiver

ContentProvider

  • 什么是ContentProvider及其使用

  • ContentProvider,ContentResolver,ContentObserver之间的关系
    之间的关系

  • ContentProvider的实现原理

  • Android系统为什么会设计ContentProvider,进程共享和线程安全问题
    (1)提供一种跨进程数据共享的方式:
    由系统来管理ContentProvider的创建、生命周期及访问的线程分配,简化我们在应用间共享数据(进程间通信)的方式。我们只管通过ContentResolver访问ContentProvider所提示的数据接口,而不需要担心它所在进程是启动还是未启动 。

    (2)更好的数据访问权限管理:
    ContentProvider可以对开发的数据进行权限设置,不同的URI可以对应不同的权限,只有符合权限要求的组件才能访问到ContentProvider的具体操作。

    (3)不管Provider使用方是同一个进程的不同线程,还是不同的进程,Provider方实际上是同一个Provider对象实例。(当然,如果Provider方进程重启了,或者Provider本身或者Binder出现问题重启了,那另当别论,不是这里讨论的范围。)
    (4)并发访问时,Provider方query()方法运行在不同的线程,实际上是运行在Provider方的进程的Binder线程池中。

  • ContentProvider的优点

  • Uri 是什么

Handler

这篇文章涵盖了下面许多个问题的答案!!

  • Handler的实现原理
  • 子线程中能不能直接new一个Handler,为什么主线程可以
  • 主线程的Looper第一次调用loop方法,什么时候,哪个类
  • Handler导致的内存泄露原因及其解决方案
  • 一个线程可以有几个Handler,几个Looper,几个MessageQueue对象
  • Message对象创建的方式有哪些 & 区别?
  • Message.obtain()怎么维护消息池的
  • Handler 有哪些发送消息的方法
  • Handler的post与sendMessage的区别和应用场景
  • handler postDealy后消息队列有什么变化,假设先 postDelay 10s, 再postDelay 1s, 怎么处理这2条消息
  • MessageQueue是什么数据结构
  • Handler怎么做到的一个线程对应一个Looper,如何保证只有一个MessageQueue
  • ThreadLocal在Handler机制中的作用
  • HandlerThread是什么 & 好处 &原理 & 使用场景
  • IdleHandler及其使用场景
    原理分析和妙用
  • 消息屏障,同步屏障机制
  • 为什么Android系统不建议子线程访问UI
    Android为什么不允许在子线程中访问UI
  • Android中为什么主线程不会因为Looper.loop()里的死循环卡死
  • MessageQueue#next 在没有消息的时候会阻塞,如何恢复?
  • Handler消息机制中,一个looper是如何区分多个Handler的
    looper如何区分handler
  • 当Activity有多个Handler的时候,怎么样区分当前消息由哪个Handler处理
  • 处理message的时候怎么知道是去哪个callback处理的
  • Looper.quit/quitSafely的区别
  • 通过Handler如何实现线程的切换
  • Handler 如何与 Looper 关联的
  • Looper 如何与 Thread 关联的
  • Looper.loop()源码
  • MessageQueue的enqueueMessage()方法如何进行线程同步的
  • MessageQueue的next()方法内部原理
  • 子线程中是否可以用MainLooper去创建Handler,Looper和Handler是否一定处于一个线程
  • ANR和Handler的联系

View绘制

  • View绘制流程
    一篇文章带你完全梳理自定义View工作流程!

  • MeasureSpec是什么
    MeasureSpac它是一个32位 int类型数值,高两位 SpacMode代表测量模式,低30位 SpacSize代表测量尺寸
    UNSPECIFIED :父布局不会对子View做任何限制,例如我们常用的 ScrollView就是这种测量模式。
    EXACTLY :精确数值,比如使用了 match_parent或者xxxdp,表示父布局已经决定了子 View的大小,通常在这种情况下 View的尺寸就是 SpacSize
    AT_MOST :自适应,对应 wrap_content子View可以根据内容设置自己的大小,但前提是不能超出父 ViewGroup的宽高。

  • 子View创建MeasureSpec创建规则是什么

  • 自定义View Wrap_content不起作用的原因

  • 在Activity中获取某个View的宽高有几种方法

  • 为什么onCreate获取不到View的宽高

  • View#post与Handler#post的区别

  • Android绘制和屏幕刷新机制原理
    动画系列(一)Android 屏幕刷新机制

  • Choreography原理
    Android图形系统(十一)-Choreographer

  • 什么是双缓冲

  • 为什么使用SurfaceView

  • 什么是SurfaceView

  • SurfaceFlinger是什么东西
    SurfaceFlinger是一个特殊进程,主要负责合成所有Surface到Framebuffer,然后屏幕去读取这个Framebuffer,然后显示给用户看。
    SurfaceFlinger是什么东西
    Android Systrace 基础知识 - SurfaceFlinger 解读

  • View和SurfaceView的区别

  • SurfaceView为什么可以直接子线程绘制

  • SurfaceView、TextureView、SurfaceTexture、GLSurfaceView
    关于 SurfaceView 和 TextureView

  • getWidth()方法和getMeasureWidth()区别

  • invalidate() 和 postInvalidate() 的区别

  • Requestlayout,onlayout,onDraw,DrawChild区别与联系

  • LinearLayout、FrameLayout 和 RelativeLayout 哪个效率高

  • LinearLayout的绘制流程

  • 自定义 View 的流程和注意事项

  • 自定义View如何考虑机型适配

  • 自定义控件优化方案

  • invalidate怎么局部刷新

  • View加载流程(setContentView)

View事件分发

RecycleView

RecyclerView 面试题 | 滚动时表项是如何被填充或回收的?

  • RecyclerView的多级缓存机制,每一级缓存具体作用是什么,分别在什么场景下会用到哪些缓存
  • RecyclerView的滑动回收复用机制
  • RecyclerView的刷新回收复用机制
  • RecyclerView 为什么要预布局
  • ListView 与 RecyclerView区别
  • RecyclerView性能优化

Viewpager&Fragment

  • Fragment的生命周期 & 结合Activity的生命周期
  • Activity和Fragment的通信方式, Fragment之间如何进行通信
  • 为什么使用Fragment.setArguments(Bundle)传递参数
  • FragmentPageAdapter和FragmentStatePageAdapter区别及使用场景
  • Fragment懒加载
  • ViewPager2与ViewPager区别
  • Fragment嵌套问题

WebView

  • 如何提高WebView加载速度
  • WebView与 js的交互
  • WebView的漏洞
  • JsBridge原理

动画

  • 动画的类型
  • 补间动画和属性动画的区别
  • ObjectAnimator,ValueAnimator及其区别
  • TimeInterpolator插值器,自定义插值器
  • TypeEvaluator估值器

Bitmap

  • Bitmap 内存占用的计算
  • getByteCount() & getAllocationByteCount()的区别
  • Bitmap的压缩方式
  • LruCache & DiskLruCache原理
  • 如何设计一个图片加载库
  • 有一张非常大的图片,如何去加载这张大图片
  • 如果把drawable-xxhdpi下的图片移动到drawable-xhdpi下,图片内存是如何变的。
  • 如果在hdpi、xxhdpi下放置了图片,加载的优先级。如果是400800,10801920,加载的优先级。

Binder

  • Android中进程和线程的关系,区别
    进程和线程的区别

  • 为何需要进行IPC,多进程通信可能会出现什么问题

  • Android中IPC方式有几种、各种方式优缺点
    Android系统中一个应用默认只有一个进程,每个进程都有自己独立的资源和内存空间,其它进程不能任意访问当前进程的内存和资源,系统给每个进程分配的内存会有限制。如果一个进程占用内存超过了这个内存限制,就会报OOM的问题

    多进程模式出现以下问题:
    1、静态成员和单例模式完全失效
    2、线程同步机制完全失效
    3、SharedPreferences的可靠性下降
    4、Application多次创建

  • 为何新增Binder来作为主要的IPC方式
    为什么 Android 要采用 Binder 作为 IPC 机制?

  • 什么是Binder
    从机制、模型角度来说,Binder是Android为了满足系统对通信方式,传输性能和安全性的要求而建立的一套新的IPC机制。Binder基于Client-Server通信模式,传输过程只需一次拷贝(这是通过内存映射实现的),为发送方添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。
    从模型的结构、组成来说,Binder是一种虚拟的物理设备驱动,连接着Service进程、Client进程和ServiceManager进程。
    从Android代码角度来说,Binder是一个实现了IBinder接口的类,将Binder机制模型以代码的形式实现在Android中。

  • Binder的原理
    Android通信方式篇(四)-Binder机制(开篇)
    Android通信方式篇(五)-Binder机制(Kernel层)
    Android通信方式篇(六)-Binder机制(Native层(上))
    Android通信方式篇(七)-Binder机制(Native层(下))
    Android通信方式篇(八)-Binder机制(Framework层)

  • Binder Driver 如何在内核空间中做到一次拷贝的?
    谈一谈Binder的原理和实现一次拷贝的流程

  • 什么是AIDL
    Android AIDL
    你真的懂AIDL的oneway嘛?

  • AIDL支持哪些数据类型
    Java基本类型、String、List、Map(List,Map内的元素必须是AIDL支持,List接收方必须是ArrayList,Map接收方必须是HashMap)、其他AIDL定义的AIDL接口(传递的是引用)、实现Parcelable的类

  • AIDL的关键类,方法和工作流程
    AIDL接口:继承IInterface。
    Stub类:Binder的实现类,服务端通过这个类来提供服务。
    Proxy类:服务器的本地代理,客户端通过这个类调用服务器的方法。
    asInterface():客户端调用,将服务端的返回的Binder对象,转换成客户端所需要的AIDL接口类型对象。返回对象。
    asBinder():根据当前调用情况返回代理Proxy的Binder对象。
    onTransact():运行服务端的Binder线程池中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法来处理。
    transact():运行在客户端,当客户端发起远程请求的同时将当前线程挂起。之后调用服务端的onTransact()直到远程请求返回,当前线程才继续执行。
    若客户端和服务端位于同一进程,则直接返回Stub对象本身;
    否则,返回的是系统封装后的Stub.proxy对象。

  • 如何优化多模块都使用AIDL的情况
    AIDL的本质是系统提供了一套可快速实现Binder的工具。关键类和方法:当有多个业务模块都需要AIDL来进行IPC,此时需要为每个模块创建特定的aidl文件,那么相应的Service就会很多。必然会出现系统资源耗费严重、应用过度重量级的问题。解决办法是建立Binder连接池,即将每个业务模块的Binder请求统一转发到一个远程Service中去执行,从而避免重复创建Service。

  • 使用 Binder 传输数据的最大限制是多少,被占满后会导致什么问题
    一次Binder通信最大可以传输是1MB-8KB(PS:8k是两个pagesize,一个pagesize是申请物理内存的最小单元)
    一次Binder通信最大可以传输多大的数据

  • Binder 驱动加载过程中有哪些重要的步骤
    Android10.0 Binder通信原理(五)-Binder驱动分析

  • Activity的bindService流程
    由浅入深 学习 Android Binder(二)- bindService流程
    Android四大组件系列6 bindService流程

内存泄漏&内存溢出

  • 什么是OOM & 什么是内存泄漏以及原因

  • Thread是如何造成内存泄露的,如何解决?
    匿名内部类 Thread 实例会长久运行,不会被系统 GC 回收。Threads 在 Java 中是 GC roots,意味着 Dalvik Virtual Machine (DVM) 会为所有活跃的 threads 在运行时系统中保持一个硬引用,这会导致 threads 一直处于运行状态,垃圾收集器将永远不可能回收它。
    其次,非静态内部类会持有外部类的引用。Thread 会长久地持有 Activity 的引用,使得系统无法回收 Activity 和它所关联的资源和视图。

  • Handler导致的内存泄露的原因以及如何解决
    同上面的做法一样

  • 如何加载Bitmap防止内存溢出
    bitmap引起的内存溢出OutOfMemory解决方案

性能优化

Android 性能优化必知必会
java中的垃圾回收机制,你理解了嘛?
强引用置为null,会不会被回收
图解 Java 垃圾回收机制

Window&WindowManager

WMS

AMS

系统启动

Android系统启动(一)-开篇
Android系统启动(二)-Init篇
Android系统启动(三)-Zygote篇
Android系统启动(四)-SystemServer篇

Android是怎么启动的-[Android取经之路]
Android 10.0系统启动之init进程-[Android取经之路]
Android 10.0系统启动之Zygote进程-[Android取经之路]
Android 10.0系统启动之SystemServer进程-[Android取经之路]
Android 10.0系统服务之ActivityMnagerService-AMS启动流程-[Android取经之路]
Android 10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]

Android 源码解读-应用是如何启动的

  • android系统启动流程
    Android系统启动流程分析
  • SystemServer,ServiceManager,SystemServiceManager的关系
  • 孵化应用进程这种事为什么不交给SystemServer来做,而专门设计一个Zygote
    我们知道,应用在启动的时候需要做很多准备工作,包括启动虚拟机,加载各类系统资源等等,这些都是非常耗时的,如果能在zygote里就给这些必要的初始化工作做好,子进程在fork的时候就能直接共享,那么这样的话效率就会非常高。这个就是zygote存在的价值,这一点呢SystemServer是替代不了的,主要是因为SystemServer里跑了一堆系统服务,这些是不能继承到应用进程的。而且我们应用进程在启动的时候,内存空间除了必要的资源外,最好是干干净净的,不要继承一堆乱七八糟的东西。所以呢,不如给SystemServer和应用进程里都要用到的资源抽出来单独放在一个进程里,也就是这的zygote进程,然后zygote进程再分别孵化出SystemServer进程和应用进程。孵化出来之后,SystemServer进程和应用进程就可以各干各的事了。
  • Zygote的IPC通信机制为什么使用socket而不采用binder
    第一个原因,我们可以设想一下采用binder调用的话该怎么做,首先zygote要启用binder机制,需要打开binder驱动,获得一个描述符,再通过mmap进行内存映射,还要注册binder线程,这还不够,还要创建一个binder对象注册到serviceManager,另外AMS要向zygote发起创建应用进程请求的话,要先从serviceManager查询zygote的binder对象,然后再发起binder调用,这来来回回好几趟非常繁琐,相比之下,zygote和SystemServer进程本来就是父子关系,对于简单的消息通信,用管道或者socket非常方便省事。第二个原因,如果zygote启用binder机制,再fork出SystemServer,那么SystemServer就会继承了zygote的描述符以及映射的内存,这两个进程在binder驱动层就会共用一套数据结构,这显然是不行的,所以还得先给原来的旧的描述符关掉,再重新启用一遍binder机制,这个就是自找麻烦了。

App启动&打包&安装

序列化

  • 什么是序列化
  • 为什么需要使用序列化和反序列化
  • 序列化的有哪些好处
  • Serializable 和 Parcelable 的区别
  • 什么是serialVersionUID
  • 为什么还要显示指定serialVersionUID的值?

Art & Dalvik 及其区别

  • Art & Dalvik 及其区别
    Android虚拟机ART和Dalvik区别

    ART 是一种执行效率更高且更省电的运行机制,执行的是本地机器码,这些本地机器码是从dex字节码转换而来。ART采用的是AOT(Ahead-Of-Time)编译,应用在第一次安装的时候,字节码就会预先编译成机器码存储在本地。在App运行时,ART模式就较Dalvik模式少了解释字节码的过程,所以App的运行效率会有所提高,占用内存也会相应减少。谷哥在5.0以后的Android版本中默认了ART模式启动,就是希望Android能摆脱卡顿这个毛病。

    Dalvik 虚拟机采用的是JIT(Just-In-Time)编译模式,意思为即时编译,我们知道apk被安装到手机中时,对应目录会有dex或odex和apk文件,apk文件存储的是资源文件,而dex或odex(经过优化后的dex文件内部存储class文件)内部存储class文件,每次运行app时虚拟机会将dex文件解释翻译成机器码,这样才算是本地可执行代码,之后被系统运行。

    Dalvik虚拟机可以看做是一个Java VM,他负责解释dex文件为机器码,如果我们不做处理的话,每次执行代码,都需要Dalvik将dex代码翻译为微处理器指令,然后交给系统处理,这样效率不高。为了解决这个问题,Google在2.2版本添加了JIT编译器,当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。

模块化&组件化

  • 什么是模块化
  • 什么是组件化
  • 组件化优点和方案
  • 组件独立调试
  • 组件间通信
  • Aplication动态加载
  • ARouter原理

热修复&插件化

Android全面插件化RePlugin流程与源码解析

  • 插件化的定义
  • 插件化的优势
  • 插件化框架对比
  • 插件化流程
  • 插件化类加载原理
  • 插件化资源加载原理
  • 插件化Activity加载原理
  • 热修复和插件化区别
  • 热修复原理

AOP

  • AOP是什么
  • AOP的优点
  • AOP的实现方式,APT,AspectJ,ASM,epic,hook
  • jectpack
  • Navigation
  • DataBinding
  • Viewmodel
  • livedata
  • liferecycle

开源框架

java

HashMap

  • HashMap原理
    HashMap实现原理
    HashMap底层实现原理

  • HashMap1.7和1.8有哪些区别
    1、jdk8中当链表长度大于8时会将链表转化成为红黑树
    2、节点插入顺序不同,jdk7采用头插法,而jdk8采用尾插法
    3、hash算法的简化
    4、扩容不同,在jdk7中,发生扩容,它会把原来所有的元素重新计算hash。再插入到新的位置。而jdk8中则是直接copy过去,要么位置不变,要么位置更改为索引+原数组长度

  • 解决hash冲突的时候,为什么用红黑树
    如果冲突过多,会导致链表过长,降低查询性能,均匀的hash函数能有效的缓解冲突过多,但是并不能完全避免。所以HashMap加入了另一种解决方案,在往链表后追加节点时,如果发现链表长度达到8,就会将链表转为红黑树,以此提升查询的性能。

  • 红黑树的效率高,为什么一开始不用红黑树存储

  • 不用红黑树,用二叉查找树可以不
    之所以选择红黑树是为了解决二叉查找树的缺陷,二叉查找树在特殊情况下会变成一条线性结构(这就跟原来使用链表结构一样了,造成很深的问题),遍历查找会非常慢。而红黑树在插入新数据后可能需要通过左旋,右旋、变色这些操作来保持平衡,引入红黑树就是为了查找数据快,解决链表查询深度的问题,我们知道红黑树属于平衡二叉树,但是为了保持“平衡”是需要付出代价的,但是该代价所损耗的资源要比遍历线性链表要少,所以当长度大于8的时候,会使用红黑树,如果链表长度很短的话,根本不需要引入红黑树,引入反而会慢。

  • 为什么阀值是8才转为红黑树
    TreeNodes占用空间是普通Nodes的两倍,所以只有当bin(bin就是bucket-桶,即HashMap中hashCode值一样的元素保存的地方)包含足够多的节点时才会转成TreeNodes,而是否足够多就是由TREEIFY_THRESHOLD的值决定的。当bin中节点数变少时,又会转成普通的bin。

  • 为什么退化为链表的阈值是6
    如果不设退化阀值,只以8来树化与退化:
    那么8将成为一个临界值,时而树化,时而退化,此时会非常影响性能,因此,我们需要一个比8小的退化阀值;

    考虑到内存(树节点比普通节点内存大2倍,以及避免反复转化),所以,退化阀值最多为6。

  • HashMap在什么条件下扩容
    新建的HashMap容量为DEFAULT_INITIAL_CAPACITY=16,

    系数DEFAULT_LOAD_FACTOR=0.75,
    当第一次扩容时目前的元素数量>=DEFAULT_INITIAL_CAPACITY*DEFAULT_LOAD_FACTOR时,会将HashMap的容量扩大一倍(x2),一次类推每次加入数据时都会判断当前的元素数与容量的占比。
    最大个数为Integer.MAX_VALUE即2147483648。
    造成HashMap扩容的操作:

    putMapEntries():插入
    putVal()
    put()
    treeifyBin()
    merge():合并

  • HashMap中hash函数怎么实现的,还有哪些hash函数的实现方式
    HashMap中hash函数怎么是实现的?

  • 链表的查找的时间复杂度是多少
    单向链表要删除某一节点时,必须要先通过遍历的方式找到前驱节点(通过待删除节点序号或按值查找)。若仅仅知道待删除节点,是不能知道前驱节点的,故单链表的增删操作复杂度为O(n)。

  • 红黑树
    30张图带你彻底理解红黑树

Jvm

  • Jvm的内存模型,每个里面都保存的什么
    jvm 内存模型
    JVM 内存共分为虚拟机栈,堆,方法区,程序计数器,本地方法栈五个部分

    程序计数器(线程私有):
    是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果是Native方法,则为空。

    java 虚拟机栈
    也是线程私有的。
    每个方法在执行的时候也会创建一个栈帧,存储了局部变量,操作数,动态链接,方法返回地址。
    每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈。
    通常所说的栈,一般是指在虚拟机栈中的局部变量部分。
    局部变量所需内存在编译期间完成分配,
    如果线程请求的栈深度大于虚拟机所允许的深度,则StackOverflowError。
    如果虚拟机栈可以动态扩展,扩展到无法申请足够的内存,则OutOfMemoryError。

    本地方法栈(线程私有)
    和虚拟机栈类似,主要为虚拟机使用到的Native方法服务。也会抛出StackOverflowError 和OutOfMemoryError。

    Java堆(线程共享)
    被所有线程共享的一块内存区域,在虚拟机启动的时候创建,用于存放对象实例。
    对可以按照可扩展来实现(通过-Xmx 和-Xms 来控制)
    当队中没有内存可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。

    方法区(线程共享)
    被所有方法线程共享的一块内存区域。
    用于存储已经被虚拟机加载的类信息,常量,静态变量等。
    这个区域的内存回收目标主要针对常量池的回收和堆类型的卸载。

  • 类加载机制的几个阶段加载、验证、准备、解析、初始化、使用、卸载
    Java类加载机制,你理解了吗?

  • 对象实例化时的顺序
    Java程序在执行过程中,类,对象以及它们成员加载、初始化的顺序如下:
    1、首先加载要创建对象的类及其直接与间接父类。
    2、在类被加载的同时会将静态成员进行加载,主要包括静态成员变量的初始化,静态语句块的执行,在加载时按代码的先后顺序进行。
    3、需要的类加载完成后,开始创建对象,首先会加载非静态的成员,主要包括非静态成员变量的初始化,非静态语句块的执行,在加载时按代码的先后顺序进行。
    4、最后执行构造器,构造器执行完毕,对象生成。

    java对象实例化时的顺序为:
    1,父类的静态成员变量和静态代码块加载,加载时按代码的先后顺序进行。
    2,子类的静态成员变量和静态代码块加载,加载时按代码的先后顺序进行。
    3,父类成员变量和方法块加载,加载时按代码的先后顺序进行。
    4,父类的构造函数加载
    5,子类成员变量和方法块加载,加载时按代码的先后顺序进行。
    6,子类的构造函数加载

  • 类加载器,双亲委派及其优势
    系统类加载器 (3种)
    BootClassLoader Android 系统启动时会使用BootClassLoader来预加载常用类
    PathClassLoader 用来加载系统类和应用程序的类
    DexClassLoader 可以加载dex文件,也可以加载包含dex的压缩文件(apk 和jar文件)

    双亲委派模型是指当我们调用类加载器的loadClass()进行类加载时,该类加载器会首先请求它的父类加载器进行加载,依次递归.如果所有父类加载器都加载失败,则当前类加载器自己进行加载操作.

    1-类加载器收到类加载的请求;
    2-把这个请求委托给父加载器去完成,一直向上委托直到启动类加载器;
    3-启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载.
    4-重复步骤三

    优点:
    1:安全,可避免用户自己编写的类动态替换Java的核心类,如java.lang.String
    2:避免全限定命名的类重复加载(使用了findLoadClass()判断当前类是否已加载)
    这种设计有个好处是,如果有人想替换系统级别的类:String.在双亲委派机制下这些系统类已经被Bootstrap classLoader加载过了,不会再去加载,从一定程度上防止了危险代码的植入.

  • 垃圾回收机制
    图解 Java 垃圾回收机制
    java中的垃圾回收机制,你理解了嘛?
    强引用置为null,会不会被回收

多线程

  • Java中创建线程的方式,Callable,Runnable,Future,FutureTask
    Java中创建线程到底有几种方式?
    FutureTask详解

  • 线程的几种状态
    线程的5种状态详解
    线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。
    1.新建状态(New):
    当用new操作符创建一个线程时, 例如new Thread®,线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码

    2.就绪状态(Runnable)
    一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。

    3.运行状态(Running)
    当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.

    4.阻塞状态(Blocked)
    线程运行过程中,可能由于各种原因进入阻塞状态:
    1>线程通过调用sleep方法进入睡眠状态;
    2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
    3>线程试图得到一个锁,而该锁正被其他线程持有;
    4>线程在等待某个触发条件;

    5.死亡状态(Dead)
    有两个原因会导致线程死亡:
    1) run方法正常退出而自然死亡,
    2) 一个未捕获的异常终止了run方法而使线程猝死。
    为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.

  • synchronized和Lock的使用、区别,原理;
    详解synchronized与Lock的区别与使用

    Syschronized的底层实现原理以及各种锁的理解

  • synchronized和volatile的区别?为何不用volatile替代synchronized?
    1、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。
    2、volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。
    3、volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。

  • 锁的分类,锁的几种状态,CAS原理
    Java中的锁分类与使用
    Java 常见的锁分类及其特点

  • Java多线程通信
    JAVA多线程之线程间的通信方式

  • Java中的线程池参数,共有几种
    Java线程池使用和常用参数

  • 线程安全的 List 集合有什么
    CopyOnWriteArrayList、SynchronizedList

  • CopyOnWriteArrayList 的特点以及使用场景?
    CopyOnWriteArrayList 的写时复制

反射

  • 什么是反射
  • 反射机制的相关类
  • 反射中如何获取Class类的实例
  • 如何获取一个类的属性对象 & 构造器对象 & 方法对象
  • Class.getField和getDeclaredField的区别,getDeclaredMethod和getMethod的区别
  • 反射机制的优缺点
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值