1.java char
占两个字节 unicode 字符集 不是编码,类似于ASCII码char 不存utf-8,而是存utf-16utf-8 占1~3个字节 字符串长度与字符数不相等
2.java String
最大长度 字面量,代码中,栈 字节码,65535 javac 65534 kt正常 读文件,堆 虚拟机指令newarray Integer.MAX_VALUE 内存大小限制
3.java匿名内部类限制
匿名内部类有名字的,只是我们看不太懂 xx.xx.xx$1匿名内部类的继承结构 匿名内部类的构造方法 SAM类型 只能是接口,并且只能有一个方法
4.java方法分派
方法分给谁 静态分派 重载 编译的时候确认,根据调用者的声明类型和参数的类型 动态分派 覆写 运行的时候,根据实际的类型来分派 Groovy 根据实际的类型调用哪个方法
5.java 泛型
类型擦除 与C#对比类型擦除后为Object,所以不兼容基本数据类型 基本类型无法作为实参,只能引用装箱,拆箱,需要有开销 泛型类型无法用作方法重载 无法当做真实的类型使用 java选择类型擦除主要考虑到了兼容问题 擦除后,在一定场景下可以通过反射获得泛型类型签名信息 Gson Retrofit
6.onActivityResult
实际中怎么使用 使用的时候有哪些不好的地方 能否用回调来替代 自己设计一个方案来替代onActivityResult
7.线程的终止
线程的stop都被废弃了 因为不安全boolean标志位 interrupt
8.线程安全
可变资源(内存)线程间共享 不变,即安全 可见,能正常处理,也会安全 原子性,每一个指令都没有争议 禁止指令重排序
9.ConcurrentHashMap
如何支持并发HashTable 整个都加锁,线程安全,暴力,影响效率JDK1.5,引入段,分段锁,给段加锁,但hash散列值不均匀,会退化成HashTableJDK1.6,优化散列值不均匀的问题JDK1.7,之前的16个段都直接初始化了,这个版本的段延迟初始化,用到哪个初始化哪个,并对数组使用volatile,保证段的可见性JDK1.8,没有分段锁,直接给table使用volatile
10.AR 和 ARFU
AtomicReference 和 AtomicReferenceFiledUpdater 保证原子性,作用于线程安全 AtomicReference 比较消耗内存,每个实例需要额外开辟空间存储一些信息 一般用在实例化较少的场景 AtomicReferenceFiledUpdater 不用额外开辟一些空间,但使用起来比较不友好,一般用于静待对象
11.异步
不是按照顺序执行代码,可以是在同一线程 当回调嵌套态度,就会出现回调地狱,看起来累 引入RxJava,扁平化,解决嵌套,但要注意异常处理和取消处理的操作 Kotlin协程异步同步化,看起来和同步产不多,还是要注意异常与取消 的处理
12.CPU架构 适配
native开发关注 mips 废弃 x86 废弃 armeabi 兼容性最好 armeabi-v7a arm64-v8a 机器根据自身对应的cpu架构,查找对应的目录so库,因此提供so要提供一整套,要么某一个架构下一个也不提供 兼容也会出现一些问题 提供合适的架构(一个目录),里面也可以放入其他架构的so库,使用时使用动态加载(动态识别机器的cpu架构) 线上监控,根据实际数据来判断哪些应该使用动态加载其他架构的so库 云端下载 so库体积优化 默认隐藏所有符号,只公开必要的 禁用 C++ Exception RTTI,会增加so库大小,Android一般用不了 iostream尽量不使用,尽量使用Android log使用gc-sections 去除无用代码,类似java中的proguard混淆 构建时分包,不同架构只有相应的so库,依靠应用商城,用户下载 时下载相应cpu架构下的ap
13.java native方法和native函数的绑定
静态绑定 命令规则映射 java包名的点替换成下划线native方法中需要有修饰符号 避免 C++编译的时候把名字给搞乱了,找不到函数 动态绑定 通过jni函数注册 NativeRegister 在动态 绑定之前调用,还是走静态绑定方式 动态绑定后,走动态绑定方式,可以取消绑定,恢复静态绑定方式,比较灵活 比较 函数名 动态绑定无要求,静态绑定有命名规则 可见性 动态绑定无要求,静态绑定需要明文符号修饰,可见 动态更换 动态绑定可以替换,静态绑定写死的,更换不了 调用性能 动态绑定无需查找,静态绑定需要查找,有额外开销 开发体验 动态绑定没啥副作用,静态绑定重构的时候比较繁琐 AS的支持 动态绑定没法自动关联,静态绑定可以关联,可以点击跳过去,开发时方便查看
14.jni数据传递
通过long类型传递底层对象指针给java层 注意string的几组函数操作的区别于适用场景 GetStringUTFChars/ReleaseStringUTFChars const char * MUTF-8 \0编码成两个字节,避免C字符的结尾 GetStringChars/ReleaseStringChars const jchar* jni函数自动处理字节序转换 GetStringUTFRegion/GetStringRegion 拷贝一部分字符串出来 GetStringCritical/ReleaseStringCritical GC停掉,回收不了这一块内存 注意对象数组较大时的LocalRef超过上限的问题 注意使用DirectBuff时字节序的问题
15.捕获native异常
捕获系统sig信号来捕获native异常 使用JniEnv的findClass 堆栈的classLoader Native线程绑定到jvm 有内存泄露问题 java对象全局引用 获取到的都是LocalRef,需要新建一个全局 Native调用Java方法 反射 异常回调到java层
16. 其他native语言
Golang Kotlin native@CName静态绑定 动态绑定
作者:进击的欧阳
链接:https://www.jianshu.com/p/6975b768b8a6