您现在的位置是:首页 > 编程 > 

Android高级:内部类的理解,多态,run和start,wait和seelp,线程安全,堆和栈,synchronized 和volatile ,AsyncTask,Binder的机,view的原理

2025-07-28 16:46:19
Android高级:内部类的理解,多态,run和start,wait和seelp,线程安全,堆和栈,synchronized 和volatile ,AsyncTask,Binder的机,view的原理 成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用java中内部类主要分为成员内部类、局部内部类(嵌套在方法和作用域内)、匿名内部类(没构造方法)、静态内部类(static修饰的

Android高级:内部类的理解,多态,run和start,wait和seelp,线程安全,堆和栈,synchronized 和volatile ,AsyncTask,Binder的机,view的原理

成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用

java中内部类主要分为成员内部类、局部内部类(嵌套在方法和作用域内)、匿名内部类(没构造方法)、静态内部类(static修饰的类,不能使用任何外围类的非static成员变量和方法, 不依赖外围类)

使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。 因为Java不支持多继承,支持实现多个接口。但有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

哪些情况下的对象会被垃圾回收机制处理掉?

1.所有实例都没有活动线程访问。

2.没有被其他任何实例访问的循环引用实例。

.Java 中有不同的引用类型。判断实例是否符合垃圾收集的条件都依赖于它的引用类型。

要判断怎样的对象是没用的对象。这里有2种方法:

1.采用标记计数的方法:

给内存中的对象给打上标记,对象被引用一次,计数就加1,引用被释放了,计数就减一,当这个计数为0的时候,这个对象就可以被回收了。当然,这也就引发了一个问题:循环引用的对象是无法被识别出来并且被回收的。所以就有了第二种方法:

2.采用根搜索算法:

从一个根出发,搜索所有的可达对象,这样剩下的那些对象就是需要被回收的

Java中实现多态的机制是什么?

答:方法的重写Overriding和重载Overloading是Java多态性的不同表现

重写Overriding是父类与子类之间多态性的一种表现

重载Overloading是一个类中多态性的一种表现.

说说你对Java反射的理解

JAVA反射机制是在运行状态中, 对于任意一个类, 都能够知道这个类的所有属性和方法; 对于任意一个对象, 都能够调用它的任意一个方法和属性。 从对象出发,通过反射(Class类)可以取得取得类的完整信息(类名 Class类型,所在包、具有的所有方法 Method[]类型、某个方法的完整信息(包括修饰符、返回值类型、异常、参数类型)、所有属性 Field[]、某个属性的完整信息、构造器 Ctructors),调用类的属性或方法自己的总结: 在运行过程中获得类、对象、方法的所有信息。

String为什么要设计成不可变的?

1、字符串池的需求 字符串池是方法区(Method Area)中的一块特殊的存储区域。当一个字符串已经被创建并且该字符串在 池 中,该字符串的引用会立即返回给变量,而不是重新创建一个字符串再将引用返回给变量。如果字符串不是不可变的,那么改变一个引用(如: string2)的字符串将会导致另一个引用(如: string1)出现脏数据。

2、允许字符串缓存哈希码 在java中常常会用到字符串的哈希码,例如: HashMap 。String的不变性保证哈希码始终一,因此,他可以不用担心变化的出现。 这种方法意味着不必每次使用时都重新计算一次哈希码——这样,效率会高很多。

、安全 String广泛的用于java 类中的参数,如:网络连接(etwork connetion),打开文件(opening files )等等。如果String不是不可变的,网络连接、文件将会被改变——这将会导致一系列的安全威胁。操作的方法本以为连接上了一台机器,但实际上却不是。由于反射中的参数都是字符串,同样,也会引起一系列的安全问题。

Object类的equal和hashCode方法重写,为什么?

首先equals与hashcode间的关系是这样的:

1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;

2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)

由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的

List,Set,Map的区别

Set是最简单的一种集合。集合中的对象不按特定的方式排序,并且没有重复对象。 Set接口主要实现了两个实现类:HashSet: HashSet类按照哈希算法来存取集合中的对象,存取速度比较快

TreeSet :TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。

List的特征是其元素以线性方式存储,集合中可以存放重复对象。

ArrayList() : 代表长度可以改变得数组。可以对元素进行随机的访问,向ArrayList()中插入与删除元素的速度慢。

LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,访问速度慢。

Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。 Map没有继承于Collection接口 从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。

HashMap:Map基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能。

LinkedHashMap: 类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点。而在迭代访问时发而更快,因为它使用链表维护内部次序。

TreeMap : 基于红黑树数据结构的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparabel或Comparator决定)。TreeMap的特点在 于,你得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。

WeakHashMao :弱键(weak key)Map,Map中使用的对象也被允许释放: 这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收。

开启线程的三种方式

java有三种创建线程的方式,分别是继承Thread类、实现Runable接口和使用线程池

run()和start()方法区别

这个问题经常被问到,但还是能从此区分出面试者对Java线程模型的理解程度。start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

在Java中wait和seelp方法的不同;

Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。

什么导致线程阻塞?线程如何关闭?

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket的accept()方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。

一种是调用它里面的stop()方法

另一种就是你自己设置一个停止线程的标记 (推荐这种)

如何保证线程安全?

1.synchronized;

代码语言:javascript代码运行次数:0运行复制
class Parent {
   public synchronized void method() { }
}
class Child extends Parent {
   public synchronized void method() { }
}

2.Object方法中的wait,notify;

.ThreadLocal机制 来实现的。

如何实现线程同步? 并行

1、synchronized关键字修改的方法。2、synchronized关键字修饰的语句块、使用特殊域变量(volatile)实现线程同步

Java中堆和栈有什么不同?

每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。

而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

synchronized 和volatile 关键字的区别

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。

2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的

.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性

4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。

5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

AsyncTask的工作原理

AsyncTask是Android本身提供的一种轻量级的异步任务类。它可以在线程池中执行后台任务,然后把执行的进度和最终的结果传递给主线程更新UI。实际上,AsyncTask内部是封装了Thread和Handler。虽然AsyncTask很方便的执行后台任务,以及在主线程上更新UI,但是,AsyncTask并不合适进行特别耗时的后台操作,对于特别耗时的任务,个人还是建议使用线程池。

AsyncTask提供有4个核心方法:

1、onPreExecute():该方法在主线程中执行,在执行异步任务之前会被调用,一般用于一些准备工作。

2、doInBackground(String... params):这个方法是在线程池中执行,此方法用于执行异步任务。在这个方法中可以通过publishProgress方法来更新任务的进度,publishProgress方法会调用onProgressUpdate方法,另外,任务的结果返回给onPostExecute方法。

、onProgressUpdate(Object... values):该方法在主线程中执行,主要用于任务进度更新的时候,该方法会被调用。

4、onPostExecute(Long aLong):在主线程中执行,在异步任务执行完毕之后,该方法会被调用,该方法的参数及为后台的返回结果。

Binder的工作机制

直观来说,Binder是Android中的一个类,它实现了IBinder接口,从IPC的角度来说,Binder是Android中的一种跨进程通信的一种方式,同时还可以理解为是一种虚拟的物理设备,它的设备驱动是/dev/binder/。从Framework角度来说,Binder是ServiceManager的桥梁。从应用层来说,Binder是客户端和服务端进行通信的媒介。

我们先来了解一下这个类中每个方法的含义:

DESCRIPTOR:Binder的唯一标识,一般用于当前Binder的类名表示。

asInterface(IBinder obj):用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,这种转化过程是区分进程的,如果客户端和服务端位于同一个进程,那么这个方法返回的是服务端的stub对象本身,否则返回的是系统封装后的Stub.proxy对象。

asBinder():用于返回当前Binder对象。

onTransact:该方法运行在服务端的Binder线程池中,当客户端发起跨进程通信请求的时候,远程请求通过系统底层封装后交给该方法处理。注意这个方法public boolean onTransact(int code, Parcel data, Parcel reply, int flags),服务端通过code可以确定客户端所请求的目标方法是什么,接着从data中取出目标方法所需的参数,然后执行目标方法。当目标方法执行完毕后,就像reply中写入返回值。这个方法的执行过程就是这样的。如果这个方法返回false,客户端是会请求失败的,所以我们可以在这个方法中做一些安全验证。

Binder的工作机制但是要注意一些问题:1、当客户端发起请求时,由于当前线程会被挂起,直到服务端返回数据,如果这个远程方法很耗时的话,那么是不能够在UI线程,也就是主线程中发起这个远程请求的。

2、由于Service的Binder方法运行在线程池中,所以Binder方法不管是耗时还是不耗时都应该采用同步的方式,因为它已经运行在一个线程中了。

view的事件分发和view的工作原理

Android自定义view,我们都知道实现有三部曲,onMeasure(),onLayout(),onDraw()。View的绘制流程是从viewRoot的perfromTraversal方法开始的。它经过measure,layout,draw方法才能够将view绘制出来。其中measure是测量宽高的,layout是确定view在父容器上的摆布位置的,draw是将view绘制到屏幕上的。

Measure:

view的测量是需要MeasureSpc(测量规格),它代表一个2位int值,高2位代表SpecMode(测量模式),低(0)位的代表SpecSize(某种测量模式下的规格大小)。而一组SpecMode和SpeSize可以打包为一个MeasureSpec,反之,MeasureSpec可以解包得到SpecMode和SpeSize的值。SpecMode有三类:

unSpecified:父容器不对view有任何限制,要多大有多大。一般系统用这个多。

Exactly:父容器已经检测出view所需要的精确大小,这个时候,view的大小就是SpecSize所指定的值,它对应者layout布局中的math_parent或者是具体的数值

At_most:父容器指定了一个可用大小的SpecSize,view的大小不能够大于这个值,它对应这布局中的wrao_content.

对于普通的view,它的MeasureSpec是由父容器的MeasureSpec和自身的layoutParam共同决定的,一旦MeasureSpec确定后,onMeasure就可以确定view的宽高了。

View的measure过程:

onMeasure方法中有个setMeasureDimenSion方法来设置view的宽高测量值,而setMeasureDimenSion有个getDefaultSize()方法作为参数。一般情况下,我们只需要关注at_most和exactly两种情况,getDefaultSize的返回值就是measureSpec中的SpecSize,而这个值基本就是view测量后的大小。而UnSpecified这种情况,一般是系统内部的测量过程,它是需要考虑view的背景这些因素的。

前面说的是view的测量过程,而viewGroup的measure过程:

对于viewGroup来说,除了完成自己的measure过程以外,还要遍历去调用子类的measure方法,各个子元素在递归执行这个过程,viewGroup是一个抽象的类,没有提供有onMeasure方法,但是提供了一个measureChildren的方法。measureChild方法的思想就是取出子元素的layoutParams,然后通过getChildMeasureSpec来常见子元素的MeasureSpec,然后子元素在电泳measure方法进行测量。由于viewGroup子类有不同的布局方式,导致他们的测量细节不一样,所以viewGroup不能象view一样调用onMeasure方法进行测量。

注意:在activity的生命周期中是没有办法正确的获取view的宽高的,原因就是view没有测量完。

1.在onWindowFocuschanged方法中获取 ----改方法含义是view已经初始化完毕 2.View.post()方法,将润那边了投递到消息队列的尾部。 .使用viewTreeObserver的回调来完成。 4.通过方式手动测量。

onLayout

普通的view的话,可以通过setFrame方法来的到view四个顶点的位置,也就确定了view在父容器的位置,接着就调用onLayout方法,该方法是父容器确定子元素的位置。

onDraw

该方法就是将view绘制到屏幕上。分以下几步

绘制背景, 绘制自己, 绘制child, 绘制装饰。

Android中性能优化

由于手机硬件的限制,内存和CPU都无法像pc一样具有超大的内存,Android手机上,过多的使用内存,会容易导致oom,过多的使用CPU资源,会导致手机卡顿,甚至导致anr。我主要是从一下几部分进行优化:

布局优化,绘制优化,内存泄漏优化,响应速度优化,listview优化,bitmap优化,线程优化

布局优化:工具 hierarchyviewer,解决方式: 1、删除无用的空间和层级。

2、选择性能较低的viewgroup,如Relativelayout,如果可以选择Relativelayout也可以使用LinearLayout,就优先使用 LinearLayout,因为相对来说Relativelayout功能较为复杂,会占用更多的CPU资源。

、使用标签<include/>重用布局,<Merge/>减少层级,<viewStub/>进行预加载,使用的时候才加载。

绘制优化

绘制优化指view在ondraw方法中避免大量的耗时操作,由于ondraw方法可能会被频繁的调用。

1、ondraw方法中不要创建新的局部变量,ondraw方法被频繁的调用,很容易引起GC。

2、ondraw方法不要做耗时操作。

内存优化:参考内存泄漏。

响应优化

主线程不能做耗时操作,触摸事件5s,广播10s,service20s。

listview优化:

1、getview方法中避免耗时操作。

2、view的复用和viewholder的使用。

、滑动不适合开启异步加载。

4、分页处理数据。

5、图片使用缓存。

Bitmap优化:

1、等比例压缩图片。

2、不用的图片,及时recycler掉

线程优化

线程优化的思想是使用线程池来管理和复用线程,避免程序中有大量的Thread,同时可以控制线程的并发数,避免相互抢占资源而导致线程阻塞。

其他优化

1、少用枚举,枚举占用空间大。

2、使用Android特有的数据结构,如SparseArray来代替hashMap。

、适当的使用软引用和弱引用。

加密算法(base64、MD5、对称加密和非对称加密)和使用场景。

什么是Rsa加密?

RSA算法是最流行的公钥密码算法,使用长度可以变化的密钥。RSA是第一个既能用于数据加密也能用于数字签名的算法。

RSA算法原理如下:

1.随机选择两个大质数p和q,p不等于q,计算=pq;

2.选择一个大于1小于的自然数e,e必须与(p-1)(q-1)互素。

.用公式计算出d:d×e = 1 (mod (p-1)(q-1)) 。

4.销毁p和q。

最终得到的和e就是“公钥”,d就是“私钥”,发送方使用去加密数据,接收方只有使用d才能解开数据内容。

RSA的安全性依赖于大数分解,小于1024位的已经被证明是不安全的,而且由于RSA算法进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,这是RSA最大的缺陷,因此通常只能用于加密少量数据或者加密密钥,但RSA仍然不失为一种高强度的算法。

使用场景:项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密。

什么是MD5加密?

MD5英文全称“Message-Digest Algorithm 5”,翻译过来是“消息摘要算法5”,由MD2、MD、MD4演变过来的,是一种单向加密算法,是不可逆的一种的加密方式。

MD5加密有哪些特点?

压缩性:任意长度的数据,算出的MD5值长度都是固定的。

容易计算:从原数据计算出MD5值很容易。

抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

强抗碰撞:已知原数据和其MD5值,想到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

MD5应用场景:

一致性验证 数字签名 安全访问认证 什么是aes加密?

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2020-0-16,如有侵权请联系 cloudcommunity@tencent 删除volatilewait线程安全原理view

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1259663.html

相关标签:无
上传时间: 2025-07-28 06:28:19
留言与评论(共有 16 条评论)
本站网友 清晰度
13分钟前 发表
而sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间
本站网友 郴州二手房网
18分钟前 发表
本站网友 葡萄胎治疗
29分钟前 发表
绘制child
本站网友 川贝炖雪梨的做法
11分钟前 发表
string2)的字符串将会导致另一个引用(如
本站网友 田园小区租房
10分钟前 发表
直到服务端返回数据
本站网友 最萌身高差
26分钟前 发表
e必须与(p-1)(q-1)互素
本站网友 东海租房
7分钟前 发表
算出的MD5值长度都是固定的
本站网友 新滨铁板烧
27分钟前 发表
当目标方法执行完毕后
本站网友 幸孕网
1分钟前 发表
一个线程中存储的变量对其它线程是不可见的
本站网友 男男性爱
22分钟前 发表
选择性能较低的viewgroup
本站网友 朱盈盈
7分钟前 发表
绘制优化
本站网友 孩子性格内向怎么办
29分钟前 发表
通过反射(Class类)可以取得取得类的完整信息(类名 Class类型
本站网友 广安门医院挂号
19分钟前 发表
对于特别耗时的任务
本站网友 红茶菌的功效
5分钟前 发表
在实现中采用链表数据结构
本站网友 延安租房网
20分钟前 发表
MD5加密有哪些特点?压缩性:任意长度的数据