自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

汤坤

微笑人生~

  • 博客(75)
  • 收藏
  • 关注

原创 Kotlin总结

TOC。

2023-07-02 23:17:40 553 1

原创 一、设计模式的作用和六大原则

但是,过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。通过重写父类的方法来完成新的功能写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。而单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则和迪米特法则作为设计模式的六大原则,是我们在编码过程中所要遵守的。使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的实现操作,把展现细节的任务交给它们的实现类去完成。

2023-07-02 21:43:11 555 1

原创 二、Java原生网络编程

三大核心组件及关系Selector在一个线程中维护着一个或多个Selector,根据客户端的数量决定;Channel服务端:ServerSocketChannel,相当于BIO中的ServerSocket客户端:SocketChannel,有几个客户端就有几个SocketChannelBuffer读取和写入数据都分别对应一个缓冲区,不同的客户端之间通信也对应不同的缓冲区。零拷贝(Zero-copy)技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。

2023-06-15 19:40:52 1312

原创 一、网络协议和常用的网络工具

通过网络服务所在的端口发送大量伪造原地址的攻击报文,发送到服务器,造成服务端上的半开连接队列被占满,从而阻止其他用户进行访问。

2023-06-15 19:07:02 1603 3

原创 六.热修复

应用在上线后出现bug需要及时修复,不用再发布新的安装包,只需要发布补丁包,在用户无感知情况下修复掉bug。所谓字节码插桩,就是在字节码文件中进行代码编写,而我们的class文件就属于字节码文件。我们编写的java文件在经过编译后,会生成class文件,class文件是2进制格式的,0101这种格式,我们肯定是无法直接在这种格式的文件上进行编码的。第三方框架ASM。如果直接对字节码操作是什么样的一个流程呢?通过文件输入流将字节码文件读到字节数组(byte[])中;对字节数组(byte[]

2023-05-31 23:24:50 838

原创 五.Glide

Glide 4.11.0版本代码剖析with通过一个空白的Fragment去管理生命周期,最终返回RequestManager对象load构建出RequestBuilder对象给后面into方法使用into实现了缓存机制等待队列和运行队列活动缓存内存缓存磁盘缓存网络请求。

2023-05-29 14:33:40 729

原创 四.Retrofit

核心思想就是AOP思想,面向切面编程。AOP使用场景比如:LeakCanary、BlockCanary、Matrix、LifeCycle、OkHttp(拦截器)等。

2023-05-26 18:00:45 650

原创 三.OkHttp

Retrofit对我们的网络请求框架OkHttp进行了一次封装,从而可以实现一些别的功能,比如:设置BaseUrl、添加Gson解析、添加RxJava线程间切换、添加OkHttp网络请求客户端.应用拦截器()会添加到所有拦截器的第一位,因此,应用拦截器会最先收到发送的请求数据,最后收到从服务器返回的数据;网络拦截器()会添加到所有拦截器倒数第二位,也就是请求服务器拦截器的前面,因此,网络拦截器会接收到最完整的请求数据。应用拦截器一定会执行,而网络拦截器不一定会执行,因为可能使用了缓存数据。

2023-05-25 11:40:56 818

原创 二.组件化配合ARouter框架使用

大型项目、多人协作开发,此时就可以采用组件化,减少编译时间,减少多人协作代码提交导致的冲突.小型项目、独立完成,这种情况下就没有必要采用组件化来进行过度设计.这里我们拿上面创建的global.gradle文件使用来举例.在project目录下创建全局控制的global.gradle文件,ext {

2023-05-23 20:09:53 652

原创 一.RxJava

给上面的代码分配线程最终会通过线程池来进行管理,因此后面执行的任务都是在子线程中进行.执行步骤:(Schedulers.io() == IoScheduler(持有线程池)//构造函数中将线程池变量evictor赋值给成员变量evictorService CachedWorkerPool(long keepAliveTime , TimeUnit unit , ThreadFactory threadFactory) {

2023-05-22 00:04:06 476

原创 八. WMS原理分析

是一个View控件,他单独拥有一个画布Canvas,正常情况下是一个窗口Window(比如:我们的应用程序窗口,也就是是一个Activity中的PhoneWindow窗口)拥有一个画布Canvas;当我们的系统帧速率跟不上屏幕刷新率的速度时,假如屏幕刷新率时候60HZ,但是系统帧速率是10PFS,也就是说屏幕原本1秒中可以刷新60帧,但是现在只提供给了10帧给屏幕刷新,就会造成刷新完10帧后,最终停留在第10帧画面上,1s-1s/6=5/6s的剩余时间都卡在了第10帧画面上,给用户带来的视觉体验就是卡顿.

2023-05-17 01:08:35 375

原创 七. WindowManager对窗口的操作

Window在Android视图体系中,Window就是一个窗口的概念.Android中所有的视图都是依赖于Window显示的.对Window进行管理,包括新增、更新和删除等.WMS窗口的最终管理者,他负责窗口的启动、添加和删除,另外窗口的大小和层级也是由WMS进行管理的.

2023-05-16 17:24:30 637

原创 数据结构基本概念

学习数据结构实例教程书籍,主要是了解数据结构中的一些基本概念,为学习数据结构和算法课程做准备。

2023-05-15 17:03:09 372

原创 7.ViewPager原理分析

在滑动的过程中,会有一个预取(GapWorker)的操作,这个操作会去更改缓存大小,在原有缓存大小为。ViewPager2和ViewPager的区别?在滑动的过程中,会缓存加载过的。.我们可以通过这个方法关闭预取。抬起事件,这个事件中会去处理。那种继续滚动或者回弹的效果.最终使得缓存中的最多缓存。继续滚动或者回弹,达到画廊。实现的,所以我们去分析。,这个操作就叫做预取。就可以得到底层实现的。

2023-05-15 16:39:02 493

原创 六. Activity启动模式

Activity属于App进程,但是Task属于操作系统,Task里面的Activity可以是属于不同的App的,所以App之间是可以相互调用的.比如:App里面可以使用打电话、地图等.当我们查看手机后台运行的程序,他们其实就是一个个任务栈。onCreate和onStart的区别?onStart和onResume的区别?onStop和onDestory的区别?onPause和onStop的区别?,我们平时可能会把他认为是一个个。

2023-05-15 16:20:52 511

原创 五. AMS实践,Hook启动未注册的Activity

保活、让部分业务逻辑存在一个新的任务栈中,防止对我们原有的任务栈造成影响等.,就可以启动未注册的页面,不过这里要注意版本适配问题,因为不同的。存在两个后台程序,但是他们属于同一个进程.不在同一个任务栈里面了,当我们把。,达到改变原有的执行流程的目的.)里面的,也就是我们app的。进程时,就会发现我们当前的。中包含一个或者多个任务栈(都是运行在同一个任务栈()中可以存放不同的进程(运行在不同的任务栈呢?退到后台,查看后台的。进程中都包含了很多的。

2023-05-15 13:28:34 810

原创 6.RecyclerView缓存机制

如果没有添加到这两个缓存集合中去,就将。内部类就是用来做缓存和复用的,里面包含了。如果从缓存和缓存池中都没有取到。缓存集合中第一个元素取出添加到缓存池。中去分析缓存和复用,也可以从。缓存集合中第一个元素移除.作为切入点,去分析我们的。相当于是列表中的一个。中去分析缓存和复用.

2023-05-15 12:15:58 466

原创 5.View的事件分发机制/事件处理机制原理分析

来处理,如果事件还没有被处理,那么该事件就不会被处理.都没有消费该事件,就会把该事件依次分发给。方法就表示该事件被消费了!方法就表示该事件被消费了!方法就表示该事件被消费了!方法将事件分发下去,最终会由。方法对我们的事件进行处理.主要是负责事件分发的。

2023-05-14 17:01:39 391

原创 4.自定义View

布局的坐标更该,即可达到换行的效果。,否则会导致测量的控件大小不对;的宽和高的测量大小保存即可;布局在屏幕的具体坐标上;测量的宽高来计算自定义。的宽高,直接使用自定义。测量的宽高来计算自定义。在布局时候,在布局子。

2023-05-14 16:32:07 381

原创 3.View的绘制流程

ViewGroup之所以不会执行onDraw方法,是因为源码中只有dispatchDraw方法,查看该方法的代码逻辑,默认他会走dispatchDraw方法逻辑,而不会走draw方法逻辑(这个方法会同时执行onDraw和dispatch方法),所以ViewGroup不会执行onDraw方法.值,所以我们布局文件中的根控件的宽高是不起作用的,从而导致了上面的问题.如果在预测量后,窗体大小可能还会发生变化,的线程和当前线程是否为同一个线程,如果创建。方法,然而实际的调度是分配给一个个的。绘制的过程中,会调用。

2023-05-14 16:14:07 546

原创 2.App换肤框架实现原理

【代码】App换肤框架实现原理。

2023-05-14 15:45:30 672

原创 1.setContentView流程分析

达到将旧版本中的布局控件迁移至新版布局文件和。局部变量,并把他作为这个方法的返回值返回给。下面的控件迁移过来,同时移除。中逻辑类似,这里就会执行创建。方法,获取到的其实是一个。第二行代码中就会执行创建。方法,正常情况下是调用。

2023-05-14 15:40:10 691

原创 数据结构和算法-算法题

指针指向他的上一个结点,整个链表的指针指向就会反转,就达到了逆转单链表的目的.首先定义一个结点。链表,在遍历的过程中,将当前结点指向上一个结点.,用于记录头结点指向的下一个结点,然后将头结点。调用递归方法,然后将当前结点的下一个结点的。指针指向当前结点,将第一个结点的。遍历整个单链表,将每个结点的。(即逆转后的最后一个结点的。注意:链表长度大于等于。,否则链表会生成环.

2023-05-14 12:00:09 236

原创 通过单链表实现LRU算法

1.自定义单链表类/*** 自定义单链表//头结点的指针 public Node < T > node;//链表的结点总数量 public int size;} /*** 新增 指定索引位置新增//插入结点位置的前一个结点 Node < T > prev = node;//插入结点位置原来那个结点,新结点插入后,这个结点就在新结点后面 Node < T > cur = node;//遍历出插入位置上一个结点和原来的结点 for(int i = 0;i < index;i ++) {

2023-05-14 11:56:27 142

原创 图(Graph)

无向图顶点边的条数叫度,有向图顶点的边叫入度和出度。如果图G有n个顶点,则邻接矩阵是一个n*n的方阵。图中存在任意两个顶点之间的边都是没有方向的。任意两个顶点之间都存在方向互为相反的两条弧。图中存在任意两个顶点之间的边都是有方向的。无向图的边数组(二维数组)是一个对称矩阵。/ˈvɜːrteks/)和边(有些图的边或弧具有与他相关的数字。/edʒ/)组成的一种结构。从顶点v到顶点v‘存在路径。深度优先和广度优先算法,图的存储结构(邻接矩阵)构建张图的矩阵信息,

2023-05-14 11:49:40 406

原创 树(Tree)

包含的基本概念代码举例:二叉排序树(BST树,又名:二叉查找树、二叉搜索树)二叉平衡树(AVL树)作用插入代码举例,这个构建平衡二叉树理解起来比较困难:红黑树()特点插入变色插入结点调整规则()

2023-05-14 11:44:18 358

原创 队列Queue和栈Stack

queue。

2023-05-14 11:37:12 879

原创 HashMap源码和原理

HashMapsizethresholdsizethresholdloadFactor单链表NodehashkeyvalueHashMap源码中iHashMap源码中方法剖析keyhashhashtable[]1indexindextable[]hashkeyNodeNodevalueHashMap源码中resize()putresize()tablethreshold0sizethresholdresize()threshold2table2数组中的每个元素Node都是单链表的表头。

2023-05-13 13:45:45 536

原创 链表LinkedList和HashMap源码分析

从头结点开始遍历,遍历每一个结点失败,则结点后移,直至遍历出我们的。这里的操作步骤同单链表的新增结点,只是要注意每个结点增加了一个。LinkedList在删除一个结点的源码,首先调用。如果按照我们正常的思维方式,是将。结点下一个结点关系的同时也要处理。注意操作步骤,首先是将插入结点。指针,用于指向前一个结点;结点的关系的同时也要处理。这两行代码执行顺序不影响。自己,显然是不正确的)

2023-05-13 11:56:44 1095

原创 顺序表ArrayList源码分析

通过索引增加和删除某个元素,涉及到该元素后面所有元素的移动操作,因此效率很低.每一次扩容采用到了位运算右移加上当前容器大小,扩容后大小是原来的。在集合末尾添加元素,适用于查找和修改操作频繁的情况。方法确定要删除元素的索引,然后通过。方法来实现删除该索引对应的元素.方法进行遍历,也可以使用。

2023-05-13 11:30:51 658

原创 11. 深入理解并发编程-AQS与JMM

做蛋糕分为3个步骤,定一个抽象类,重写3个方法,做模型、烘焙和涂抹原料,然后在另外1个方法做蛋糕中,将这3个方法步骤依次放入;然后具体的实现类继承自上面抽象类,比如做奶油蛋糕有奶油蛋糕的制作流程,做芝士蛋糕有芝士蛋糕的制作流程等等.次,然后进入阻塞状态),查看前一个结点是否已经使用完锁并释放,前一个结点释放锁的同时当前结点的。,并且每个子线程之间这个变量的副本是相互之间不可见的,当每个线程在运算完成后,会将这个变量副本。,这个操作过程是放在工作内存中完成的,每个工作内存都拥有一个这个主内存变量。

2023-05-13 11:15:51 915

原创 10.阻塞队列和线程池

阻塞队列通常使用在生产者消费者设计模式当中,生产者不用关心生成的产品由哪个消费者来执行,只需将生产的产品放入队列中,消费者直接从队列中取出产品使用,达到了生产者与消费者之间解耦的目的和性能均衡问题.因为线程的创建、执行和销毁都是需要耗费时间和资源的,所以通过线程池来避免线程的重复创建和销毁。线程池的创建 (各个参数的含义)线程池是用来管理线程的.

2023-05-13 11:05:14 1645

原创 9.并发基础与CAS基本原理

利用了现代处理器都支持的CAS指令,循环这个操作,直至成功为止。要么全部完成,要么全部都不做,不可再分。

2023-05-13 10:59:59 1453

原创 8.线程与进程

一个线程a启动后,另外一个线程b也启动了,如果正常情况下,应该是a线程执行完成后再执行b线程;但是如果线程b使用join方法,那么线程的执行顺序就会发生变化,线程b执行完成后才会执行线程a.可以在线程调用interrupt方法后,在Thread的run方法中判断线程是否中断,或者在Runnable的run方法中判断线程是否中断(计数器和线程数不一定是相等的,计数器可以大于等于线程数,线程执行完成一个任务,就调用。,在主线程中更改他的值,那么在子线程去打印这个值,此时这个变量的值,是更改后的值.

2023-05-13 10:49:52 139

原创 7.序列化Serializable

json字符串->排除器->自定义的TypeAdapter->Gson自带的TypeAdapter->反射ReflectiveTypeAdapter->JavaBean。不需要,反序列化是将二进制串转换成对象的过程,直接将我们反序列化的对象进行强转就能得到我们的对象.子类实现了序列化,父类没有实现,那么从父类继承的实例变量都是默认值.序列化是为了实现进程间数据的交互,而持久化是为了数据的存储与使用.,当对象的属性添加或者删除的时候,则已经序列化的对象将无法更新.是对象的一个常量,通常是对象的。

2023-05-13 10:24:57 1067

原创 6.Java流在Android中的应用

以输出流为例,输入流除外,和输出流是一一对应的使用案例同样以输出流举例,出了打印流外,其他的输入流和输出流有着一一对应的关系使用案例注意: 流使用到了装饰器设计模式Component(抽象接口)——> Concreate Component(具体实现类)——>Decorator(装饰器,该抽象类持有Component的引用) ——>Concreate Component(具体实现类)

2023-05-12 18:07:45 851

原创 5. Android虚拟机和类加载机制

——>DexPathList ——>Element[]数组(遍历)——>Element元素——>DexFile ——>loadClassBinaryName()方法——>拿到这个class对象。如果某个类加载器在加载类时,首先将加载任务委托给父类加载器,一次递归,如果父类可以完成加载任务,就成功返回;中的组成部分,是有存储容量的高速存储部件,用来暂存指令、数据和地址.如果父类加载器无法完成任务加载或者没有父类加载器,才自己去加载。数组的前面,每次在加载类的时候,就会先加载我们修复。的代码的类通过编译(

2023-05-12 18:03:27 1013

原创 3. 反射(这是Java被称为动态语言的关键)

反射就是在运行状态中,对于任意一个类,都能够知道这个类的属性和方法;对于任意一个对象,都能够调用的属性和方法;并且能够修改它的属性.(网络请求框架的封装,网络请求的工作本质是由。框架使用到了动态代理、反射和注解技术;仅负责网络请求接口的封装.

2023-05-12 18:02:14 63

原创 4. JVM内存管理

JVMJVM是一种规范.JVMJava虚拟机将字节码文件(.class)编译成操作系统可以识别的机器码.Javajava程序首先经过javac编译成.class文件,然后jvm将其翻译成操作系统可以识别的机器码.JVM只是一个翻译,将字节码文件翻译成机器识别的代码JRE除了包含JVM外,提供了很多类库(jar包)JDK除了包含JREjavac(编译代码)、javap(反编译代码)、jar(打包代码)、java等直接内存方法区堆每个私有线程包含一个虚拟机栈,每个虚拟机栈中可以包含多个栈帧。

2023-05-12 18:02:13 925

原创 2. 注解Annotation

定义为class级别的注解,会被保留在class文件中,但是会被虚拟机忽略(即无法在运行期间反射获取注解).此时完全符合这种注解的应用场景为字节码操作,如:ASpect、热修复Robust。)又称为Java标注,是JDK5.0引入的一种注释机制.注解是原数据的一种形式,提供有关于程序但不属于程序本身的数据.注解对他们注解的代码的操作没有直接的影响.用于处理注解.注解处理器是javac自带的一个工具,用来在编译时期扫描处理注解信息,你可以为某些注解注册自己的注解处理器.

2023-05-12 18:00:51 1186

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除