好记性不如烂笔头,时间久了还是容易忘,先列出大致的知识点,后续慢慢填充,以此记录。
(1)、多线程技术,了解多少
实现多线程的方式:继承thread;实现Runnable
(2)、Jvm的内存模型/内存结构
java内存模型:要先了解计算机术语的内存模型的意义。
java内存模型主要解决的是多线程并发编程带来的工作内存和主内存数据不一致的问题,满足三大特性:
- 原子性:同步synchronized/lock机制 (要在深入了解)
- 可见性;volatile、synchronized、final(要查阅了解下)
- 一致性:volatile、synchronized (禁止 编译器指令重排序、处理器乱序执行)
jvm的内存结构:
1、java堆、方法区(包含运行时常量池) //gc回收的地方,二者是线程共享的
- java堆:主要存储new对象实例,是GC回收的主战场,堆内没有内存空间也无法扩展的时候抛出OutOfMemoryError。
- 方法区:主要存储类的信息、常量池、静态变量、静态方法等。逻辑上属于堆的一部分,又叫Non-Heap。
2、java栈、本地方法栈、PC //三者是线程独享的
- java虚拟机栈:描述java方法执行的内存模型,每个java方法对应一个栈帧,虚拟机栈里存放的也就是各个java方法创建的栈帧,每个方法的调用到执行完成的过程,对应着一个栈帧的入栈到出栈的过程,每个栈帧里面存有局部变量表(8种基本数据类型、对象引用)、操作数栈、动态链接、返回地址等。(每个线程都有一个私有栈)栈的大小可以扩展,当栈调用深度超过jvm允许的范围,跑出StackOverflowError。如果扩展没有足够的内存也会跑出OutOfMemoryError。
- 本地方法栈:主要是执行native方法的内存模型,jvm对本地方法及语言没有强制规定,本地方法栈也可以抛出StackOverflowError和OutOfMemoryError。
- PC寄存器:用来存放下一条需要执行的指令地址(java对应字节码的地址,native则为空),每个线程都有一个PC,不会造成OutOfMemoryError。
PS:深入了解下JVM内存结构图,Jdk不同版本似乎有区别。注意堆和方法区、常量池的位置。可找下jvm内存结构图看看。
(3)、设计模式23种,了解多少种
- 创建型:
- 单例(饿汉/懒汉/内部静态类/synchronized double check):满足线程安全、lazy loading、效率高
- 建造者builder、工厂方法、抽象工厂、..
- 结构型:适配器模式、..
- 行为型:观察者模式、命令模式、迭代模式、...
(4)、设计模式的六大原则,了解多少
- 开闭原则:对扩展开放,对修改关闭
- 单一职责原则:类的功能尽量单一
- 里式替换原则:基类出现的地方要能够用子类替换,子类可以扩展相关基类,但不能影响功能。
- 接口隔离原则:细分接口,实现多个接口编程
- 依赖倒置原则:细节依赖抽象,不是抽象依赖细节,依赖抽象编程更稳定些。接口:抽象。具体类:细节。接口制定了规范和契约,具体类去执行。
- 迪米特法则:最少知道原则,降低类之间的相互依赖,做到模块相互独立,高内聚,低耦合。
(5)、Hash容器类
HashSet、HashMap、HashTable、ConcurrentHashMap..
- Hashset不允许有重复的对象,采用hashcode+equal来提高存储效率,加入对象先通过hashcode判断和当前位置对象是否相同,不同则加入,hashcode相同则进一步由equal判断否相同。
- Hashmap是线程不安全的,可以加入key值为null的对象
- jdk1.7版本之前,采用entry数组+链表来存储数据,1.8之后才用entry数组+链表+红黑树。
- Hashtable是线程安全的,内容采用syschronized同步锁机制。多线程的话就会有上下文切换,效率问题。
- ConcurrentHashMap 线程安全的,jdk7上采用segment锁分段机制/锁分离机制,将数据分段,分别加锁segment,这样不同的线程可以访问不同的数据段。Jdk8上采用红黑树机制,具体要看下。
PS:"=="、equals、hashcode的区别?深入了解下。
- ==:对于基本数据类型,==比较的是栈中的value;对于Object类型,则比较的是存在栈中引用的value,这个value指向存在堆中的对象。其实这个value就是对象的物理首地址。
- equals:object的原始方法,也是通过==来实现。一般的类需要重写equals方法,比如String、Integer等都有重写equals方法。equals比较的是堆中存储对象是否一样。
- hashcode:一组随机数,hash算法得来,也是object的原始方法,通常也需要被重写。hashcode相同,equals不一定相同,因为会有hash值冲突;equals相同,hashcode则相同。也就是说比较两个对象,hashcode不同,两个对象肯定不同,通常用在hashset存储的时候用来判断是否有重复的对象。
- hash冲突的解决方法:再hash法、公开地址法、
(6)、Set、List、Vector、Map 这些集合类的区别联系?
Collection | |
|--List | LinkedList ArrayList Vector |--Stack |
|--Set | |
Map | HashTable HashMap WeakHashMap ... |
List、Set继承自Collection,Map没有继承Collection接口
参考:https://www.cnblogs.com/panjun-Donet/archive/2009/03/11/1409019.html
...
(7)、泛型了解多少?
1、泛型编程的优势:类型安全(编译期间检查)、消除强制类型转换
2、了解掌握集合类型的泛型编程(HashMap、ArryList:put/get)
3、类型通配符的使用
- <?>:无限制类型通配符
- <? extend x>和<? super x>:有限制类型通配符,?是x的子类或父类。
4、泛型类最常见的用例是容器类(比如集合框架list、map等)或者值持有者类(比如 WeakReference 或 ThreadLocal)
PS:泛型没有继承关系,不是协变的,通配符的使用中要注意:ex,不能将List<String> 赋值给List<Object>,但是可以将List<String> or List<Object>赋值给List<?>。
参考:https://blog.csdn.net/echojiangyq_fight/article/details/46124409
(8)、基本数据类型和包装类
1、8种基本数据类型:int、float、double、char、boolean、byte、short、long
2、包装类型:Integer、Double、BOOL、String..
- Object
- String的用法值得深入了解,与StringBuffer、StringBuilder在性能和用法上的区别:StringBuffer/StringBuilder是可变字符序列,可以更方便、快速、灵活地操作字符串。
String | StringBuffer | StringBuilder | |
推出版本 | JDK1.0 | JDK1.0 | JDK1.5 |
是否可变 | 不可变 | 可变 | 可变 |
线程安全 | 线程安全 | 线程安全 | 线程不安全 |
运行速度 | 最慢 | 快 | 最快 |
占用内存 | 最多 | 少 | 最少 |
https://www.cnblogs.com/huan-guo/p/8404891.html
(9)、四种引用类型
- 强引用,默认建立的对象是强引用,只有不在活着的对象才会被gc回收,可以显示的赋值将obj=null,等待gc回收软引用。
- 软引用,比强引用弱,内存不足/发生oom之前会被gc回收,用于内存敏感的缓存。
- 弱引用,比软引用弱,发生gc回收的时候,会被回收,用于内存敏感的缓存。
- 虚引用,比弱引用还弱,在任何一个时段发生gc会被回收,用户回收时像系统发送一个通知。
ps:这4个引用类型的区别和联系,还需要进一步了解。
(10)、内存泄漏
强引用持有弱引用的对象,导致被弱引用的对象没有释放,发生oom.
ps:一般Activity/Service不作为被弱引用的对象。需要进一步理解内存泄漏知识点。
(11)、ThreadLocal实现原理
(12)、并发编程的互斥和同步机制
1、互斥:同一时刻只能有一个线程获取到共享资源。
2、同步:线程/进程间的通信协作机制。
synchronized和lock(三个实现类ReentrantLock、ReadLock、WriteLock)
- synchronized 原子特性,不可被中断、不可被抢占已占有的资源,执行完后自动释放资源
- lock有lockInterruptibly、tryLock等方法支持中断,支持抢占获取的资源,执行完后需要手动unlock释放资源
PS:java各种锁机制需要进一步了解。
(13)、 线程状态
Waiting-Blocked-Runnable-Running
PS:深入了解下线程/进程的状态,最好找个状态图看看
(14)、同步、异步、阻塞、非阻塞
(15)、select、poll、epoll io复用机制
(16)、java的反射机制
- 反射机制是什么?
- 为什么需要反射机制?
- 反射机制的作用和实现?
(17)、构造函数的显示调用与隐式调用
....
(18)、Android中的消息处理机制:Handler、Looper、MessageQueue
- 一个thread对应一个looper,对应一个MessageQueue
- Handler和looper之间的对应关系?
...
(20)、linux内核子模块,了解多少
1、内存管理模块
- 逻辑地址、线性地址、物理地址之间的区别联系,MMU是怎么实现虚拟地址到物理地址之间的转换。
- mmap的实现
- OOM机制
2、进程管理/调度模块
- 了解进程的同步机制(Semaphore、Mutex、管程Monitor)
- android中的同步机制:Mutex、Condition、Barrier、Autolock(Mutex的内部类用于加解锁的自动化操作)、ReaderWriterMutex
- 了解cpu轮转时间片、上下文切换
- cpu什么时候发生上下文切换:发生进程/线程调度的时候
- 系统调用和上下文切换的区别:系统调用是发生一个进程里面的用户态和内核态的切换;进程上下文切换是发生在两个进程之间的切换
- 进程的上下文切换
- 线程的上下文切换
- 中断上下文切换
3、进程间通信模块
- 进程间通信的方式:pipe、socket(Unix domain socket/Network socket)、shared Memory、RPC、Binder
ps:pipe用于具有血缘关系的进程(父子进程)通信;shared memory减少了内存数据复制的次数,速度上占优;unix domain socket用于单机内进程通信,可以利用socketpair建立全双工的通信模式;RPC用于多机之间通信;Binder在android中应用最多。
4、网络接口模块
- socket编程
5、虚拟文件系统模块
- /sys、/proc
- 应用不用通过java->jni->native->内核,app可以通过vfs直接调用到内核,了解这种方式怎么实现的。
(21)、进程的VSZ、RSS、SHR
在ps or top下的意义
- VSS or VSZ:进程访问的虚拟内存的大小,包括进程使用链接的共享库、swap、stack/heap大小等
- RSS or RES:进程常驻物理内存大小 ,不包括Swap,包括实际加载共享库、heap/stack的大小等
- SHR:共享内存大小,包括其他进程的共享内存。某个进程实际占用的物理内存大小:RSS-SHR
https://www.cnblogs.com/leijiangtao/p/4049076.html http://blog.itpub.net/29757574/viewspace-2150678/
https://www.cnblogs.com/WFM1997/p/9897742.html
22、数据结构和算法
需要系统的了解下常用的排序算法,及数据结构的常用知识点。