2020年度总结
前言不知不觉又到了写年度总结的时候,细翻了下,去年我居然没去写年度总结,想了想,可能当时也的确没什么总结的,可能就算有也不知道咋写吧。当然了这都是借口,不过现在就总结下2020的内容吧。
工作今年工作对比19年来说,相对来说轻松一点,19年除了相关业务开发。因为是新项目所以我还负责管理android小组,虽然总共没几个人。不过要对接PMO,PM,QA等等。在这情况下,还需要负责业务开发,往往忙的只有晚上才能开始写代码。而今年除了业务的开发,其他的到没啥,所以我更注重于自我的成长,以及在团队内部推动相关技术,进行落地。
不过对比上面这些,可能还需要在团队中给自己定位。比如领导对我说的一句话:“你工作很辛苦,也很努力,工时也是团队中最多的,不过做东西都是缩起来,其他同事也不知道你在干嘛。东西做完了,别人认可你做的内容么,有没有和同事讨论你这套东西是不是最实用的,能不能再浓缩一下”。
后来自己想想,的确之前一个技术方案的确定—落地—实施。好像都是自己一个人去进行的。于是后面我就改变了思路,从草稿—沟通确定方案—落地任务细分到人—实施。对比之前的,相对自己会轻松很多,而且团队成员也知道我要做什 ...
Gradle核心之Task
前言gradle命令最终是通过task去执行的,可见task在gradle中的重要性。
Task的定义与配置task的定义有两种形式,一个是直接通过task函数去创建,另一个是通过task的create方法去创建,示例代码如下:
1234567task test1Task{ println("test1Task")}tasks.create(name:'test2Task'){ println("test2Task")}
刚刚我们为task指定了一个name。我们可以看看除了name我们还可以指定什么,我们打开Task的源代码,如下:
1234567891011121314151617181920212223public interface Task extends Comparable<Task>, ExtensionAware { String TASK_NAME = "name"; String TASK_DESCR ...
Gradle核心之Project
前言project在gradle里起到里重要的作用,上节我们也说过可以通过./gradlew projects打印当前项目下所有的project,准确的说是有build.gradle的文件既是一个project。而有多少project取决于在setting.gradle文件中设置了多少个。一个project对应一个输出,而具体输出什么取决于build.gradle里面的内容。
Project核心API每个工程下都有一个build.gradle文件。根目录的build.gradle可以管理子工程下面的build.gradle。下面具体看下project相关api。
getAllProjects()我们可以通过getAllprojects打印出所有的project,可以理解成和./gradlew projects命令一样。示例带入如下:
1234567getAllprojects().eachWithIndex { Project entry, int i -> if (i == 0) { println("RootProject-- ...
Gradle简介及生命周期
Gradle简介gradle主要是由三个部分组成。
groovy 核心语法:包括 groovy 基本语法、闭包、数据结构、面向对象等等。前面我们已经介绍过了。
Android DSL(build scrpit block):Android 插件在 Gradle 所特有的东西,我们可以在不同的 build scrpit block 中去做不同的事情。
Gradle api:包括task,projects,setting等等。
具体如下图:
Gradle优势
灵活性:相对于 Maven、Ant 等构建工具,Gradle 提供了一系列的 API 让我们有能力去修改或定制项目的构建过程。
粒度性:源码的编译,资源的编译,都是一个一个Task的,我们可以修改task来达到精细控制上。
扩展性:Gradle 支持插件机制,所以我们可以复用这些插件,就如同复用库一样简单方便。
兼容性:Gradle 不仅自身功能强大,而且它还能兼容所有的Maven、Ant功能,也就是说,Gradle 吸取了所有构建工具的长处。
Gradle生命周期gradle的生命周期主要是如下三个部分:
初始化阶段: 解析 ...
Gradle入门之Groovy元编程
简介Groovy的元编程是指groovy运行时,可以理解成编写代码所执行的时期,也就是Runtime。在比如有解释执行的Js,编译执行的java,还有运行时期执行的代码java反射。
Groovy运行时的处理逻辑如下图:
元编程按照上图所示,我们可以自己写一个Demo,示例代码如下:
1234567891011121314151617181920212223class Study { public static void main(String[] args) { def person = new Personal(name: "Silence", age: 26) println(person.printName()) println(person.printAge()) println(person.sex) }}class Personal { public String name public int age publi ...
Gradle入门之Groovy语法
前言gradle是一个基于JVM的构建工具,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与Java代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy可以使用其他Java语言编写的库。目前已经应用在多数Android技术体系中,比如,jenkins,插件化,组件化,模块化等等。如果你不了解gradle,那么前面几个技术点很难深入理解。
Groovy 的语法跟 kotlin 类似,如果我们有 kotlin 的经验的话那么学习 groovy 会容易很多。下面我们一起来学习下groovy的核心语法,大家可以跟着样例敲一下加深理解、记忆。
基本特点
构建在强大的Java语言之上 并 添加了从Python,Ruby和Smalltalk等语言中学到的 诸多特征,例如动态类型转换、闭包和元编程(metaprogramming)支持。
为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于 ...
Gradle入门以及环境搭建
前言gradle目前主要是在项目构建的时候使用,如果我们需要了解gradle。首先需要熟悉grooy的语法,本节来搭建groovy的环境,为了后续学习准备。
Groovy环境搭建groovy SDK下载
官网下载,直接解压,然后目录选择groovy/libexec。
brew安装的groovy目录选择/usr/local/opt/groovy/libexec。(另外,在idea中无法切到/user目录下,mac按Cmd + Shift + G来切换目录)
环境变量配置使用sudo vim ~/.bash_profile打开编辑环境变量文本。在末尾加上export GROOVY_HOME=/usr/local/opt/groovy/libexec。然后esc+:wq进行保存
gradle项目在idea中新建一个groovy项目。如下:
创建好项目后,我们新建一个 groovy 文件,并添加 hello world 的代码如下:能够正常输出 hello world,收工!
GC回收机制
为什么需要GC?如果不进行垃圾回收,内存耗空是迟早的。因为我们在不断的进行内存分配,而不进行垃圾回收。除非内存足够大,可以让我们随意分配内存。但事实并非如此。
什么是垃圾?所谓垃圾就是指内存中已经没用的对象。那么我们如何找到这些没用的对象。JVM中使用一种叫做可行性分析的算法来决定对象是否要被回收。
可行性分析这个算法的思想是通过一系列称为“GCRoot”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GCRoot没有任何引用链(即GCRoots到对象不可达)时,则证明此对象是不可用的。
如上图所示,对象A、B、C、D、E与GCRoot之间都存在一条直接或者间接的引用链,这也代表它们与 GC Root之间是可达的,因此它们是不能被GC回收掉的。而对象M和K虽然被对J 引用到,但是并不存在一条引用链连接它们与GCRoot,所以当GC进行垃圾回收时,只要遍历到 J、K、M 这 3 个对象,就会将它们回收。
注意:上图中圆形图标虽然标记的是对象,但实际上代表的是此对象在内存中的引用。包括 GC Root 也是一组引用而并非对象。‘
什么是GCRoo ...
Class初始化过程
概述一个 class 文件被加载到内存中需要经过三大步:装载、链接、初始化。其中链接又可以细分为:验证、准备、解析三小步。如图所示:
装载装载是指JVM找到class文件生成字节流,然后根据字节流创建java.lang.Class对象的过程。
过程如下:
ClassLoader通过一个类的包名+类型来查找.class文件。并生成二进制字节流。
把class文件解析为JVM内部的数据结构,并存储在方法区。(这种解析类似json文件解析成运行时的bean类)
在内存中创建一个java.lang.Class类型的对象。
加载时机
隐式装载:在程序运行过程中,当碰到通过new等方式生成对象时,系统会隐式调用ClassLoader去装载对应的class到内存中。
显示装载:在编写源代码时,主动调用Class.forName()等方法也会进行class装载操作,这种方式通常称为显示装载。
链接链接过程分为 3 步:验证、准备、解析。
验证验证是链接的第一步,目的是为了确保.class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危及虚拟机本身的安全。主要包含以下几 ...
Java JMM内存模型
java内存划分JMM规定了内存主要划分为主内存和工作内存两种。此处的主内存和工作内存跟JVM内存划分(堆、栈、方法区)是在不同的层次上进行的,如果非要对应起来,主内存对应的是Java堆中的对象实例部分,工作内存对应的是栈中的部分区域,从更底层的来说,主内存对应的是硬件的物理内存,工作内存对应的是寄存器和高速缓存。具体如图所示:
正常情况下,java中所有的数据都是放在主存中的,如图所示:
随着 CPU 技术的发展,CPU的执行速度越来越快,但内存的技术并没有太大的变化,如果JAVA线程每次读取和写入变量都直接操作主内存,对性能影响比较大,所以每条线程拥有各自的工作内存,工作内存中的变量是主内存中的一份拷贝,线程对变量的读取和写入,直接在工作内存中操作,而不能直接去操作主内存中的变量。
因此,为了“压榨”处理性能,达到“高并发”的效果,在CPU中添加了高速缓存(cache)来作为缓冲。
但是这样就会出现一个问题,当一个线程修改了自己工作内存中变量,对其他线程是不可见的,会导致线程不安全的问题。也就是缓存一致性的问题。
缓存一致性现在市面上的手机通常有两个或者多个CPU,其中一些 ...