获得徽章 27
- 冗余代码消除
赋值
JVM在类加载阶段会确保全局,static变量付默认值,如果定义的时候已经进行赋默认值那么这个赋值是冗余的,所以要消除这种赋值
确认目标:
Filed是当前类的变量,Field在init和clinit中赋值,并且之前没有付过非默认值,且此次赋值是默认值,那么这个赋值就是可以优化的
实现:
1.遍历init,clinit的字节码找到putField和putStatic指令
2.过滤不是当前类的变量,指令中可以看到File的全路径名,通过对比当前class。筛选出只对本类Filed赋值的指令
3.将Classname和filedname作为一个key,如果付非默认值则保存到集合中
4.当碰到赋默认值的指令时检测是否在集合中,如果不在集合中进行标记该指令是可以删除的冗余指令
5.遍历完整个字节码之后进行统一删除展开赞过评论1 - 协程(coroutines)是一种轻量级的线程管理方式,它允许我们以更简洁、直观的方式编写异步代码。在Kotlin中,协程是通过库 kotlinx.coroutines 实现的。下面是协程内部的一些主要方法和概念的说明:
1. CoroutineScope:协程作用域,用于管理协程的生命周期。通常与作用域相关的类(如Android的ViewModel)会实现CoroutineScope接口。作用域内的所有协程都会在作用域被取消时一起取消。
2. CoroutineContext:协程上下文,包含了协程运行所需的一些信息,如调度器(Dispatcher)和Job。调度器决定协程在哪个线程或线程池上执行,而Job表示协程的一个执行任务。
3. launch:用于启动一个协程。它创建一个新的协程并立即开始执行。launch函数返回一个Job对象,可以用于取消或等待协程完成。
4. async:与launch类似,但它返回一个Deferred对象,表示一个可等待的结果。可以通过调用await方法来获取结果。async用于启动一个带有返回值的协程。
5. suspend:用于标记一个可以暂停执行的函数。这些函数只能在协程或其他suspend函数中调用。当一个suspend函数被调用时,它不会阻塞当前线程,而是将协程挂起,直到结果可用。
6. withContext:用于在指定的CoroutineContext中执行一个suspend函数。这允许我们在不同的上下文(如线程)之间切换协程的执行。展开赞过评论2 - 为什么要生成桥接方法:
由于类型擦除机制,比如接口和类里面如果定义了泛型,在编译后的代码中都会被替换为object。
而在使用这些泛型类和泛型接口时,由于指定了具体的类型,所以实现或者复写的方法都是实际类型的方法;(比如a类实现了b泛型接口,类型是string。那么a里面实现的就是带有strung类型的方法但是源b泛型接口里面是object,不符合实现逻辑所以需要再生产一个object的方法保证实现了b借口)
但是由于父类或父接口是object而不是具体类型的方法,为了保持兼容因此需要实现父类接口带有object类型擦除的方法,内部强转调用实际类型(桥接方法不会被直接调用,可以通过反射调用)展开赞过评论1 - 首先思考下如何定义增量,也就是一个Task有没有必要重新执行。
首先来反着看:从结果事实现象反推原理,前提是要对问题里面涉及到的术语有本质的思考有一定的基础地基知识做反思才行不然就是捏造
Task1-》》Task2:Task2没有执行和Tsak2执行这两个事实间有什么不变量有什么变量;找不到就是因为没有本质的思考(不仅仅是术语的本质,比如这里可以联想成一个人什么时候发生改变,一个函数什么时候发生执行 这些其他现象的本质就是他所处的环境变了,环境--》改变这就是本质)
那么Task2的环境是什么呢?
这就要看技术的本质了,比如函数什么时候需要重新执行:1.依赖的数据源发生改变,参数发生改变或者内部使用的变量发生改变(按钮的点击状态发生改变需要执行onclick);2. 依赖的Task的输出发生改变,也就是Task1发生改变。
所以Task2有没有必要重新执行:1.依赖的数据源是否发生变化(参数,内部全局变量使用)2.依赖的Task输出是否发生变化。
这个是反着看的,基于现象的倒退需要有很强的能力:1.丰富的现实生活经验(比如上面的联想实际生活的例子这是帮助你快速能够定位到变量和不变量的过程也就是更加专注于具体的那一两个因素而不是没有方向,上面的现实经验例子推导出来的就是环境)2. 强大的反思和举一反三能力:根据经验推导出可能的原因回顾之前是如何解决的(比如上面提到的函数和人的例子,)3.对于技术本质的理解(对于Task来说就是Task受影响的环境是什么,如外部依赖,注入参数,内部依赖)
对于正着推就相对比较简单了,只要你对技术有足够深入的理解就行,但是这需要花费大量的时间,所以大部分情况一般都是倒着推,这样其实也可以训练很多思维帮助提升自己展开赞过评论3 - 并不是说函数式语言其他语言更好,是函数式语言在预测未来方面有很好的参考,所以学习他有用,
学习了函数式语言,很可能他的特性会出现在你的下一个语言中
这些具有预测性的技术有两个非常重要的特性后面在java中都出现了:
1. 垃圾回收:回收永远不再使用的内存,Java是在1996年退出第一个版本具有垃圾收集的功能。lisp早就有了垃圾收集因为他是实现编程语言的唯一合理方法,因为在幕后需要进行所有的内存管理,所以有必要设计
但在40,50年的时候,函数式语言lisp已经拥有,lisp是所有函数式语言的祖母,他有个特点是有很多括号,有个笑话是lisp实际上代表了许多恼人的愚蠢括号
2. 泛型:java是在java5才有的泛型,你可以在写的类之后添加一个类型参数,参数代表想要参数化列表的内容。sharp语言在函数式社区中的泛型参数多态性是很厉害的,在1990年他就存在于一种被称作ml的语言中(ml并不是一种语言,他是一个语言家族)展开赞过评论1
![[流泪]](http://lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/img/jj_emoji_6.dde0d83.png)