Android&java基础面试题总结(二)

更新日期2019-4-8

volatile关键字

volatile:一个线程修改了volatile修饰的变量,其他线程立即可见(可见),volatile修饰的变量在修改之后强制更新到主存,,并让其他线程的这个变量的缓存无效,使得再次向主存读取值。

volatile修饰的变量不能保证原子性操作

volatile用于作为状态标志位或单例的双重检查这些常用场景。性能优于Synchronized同步。

TCP 三次握手四次挥手(有的面试者低概率会问这个问题)

握手:

  1. 客户端向服务端发送建立连接请求,
  2. 服务器接收请求,反馈给客户端
  3. 客户端收到反馈,建立连接

挥手:

  1. 客户端向服务器端发送断开连接的请求
  2. 服务器端收到请求,反馈给客户端
  3. 客户端发送断开连接请求,客户端自己断开连接
  4. 服务端收到断开请求或者长时间没有搜到请求就断开

ArrayList,LinkList,Vector区别

  • 都是实现了list接口。
  • ArrayList和Vector区别基于数组,就有查询优势,LinkList是链表具有删除优势。
  • vector是同步的,ArrayList不同步,vector效率低于ArrayList

java内存分配

  • JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method,也叫静态区)
  • 每个java进程可能包含一个或者多个线程,每一个Java进程对应唯一一个JVM实例,每一个JVM实例唯一对应一个堆,每一个线程有一个自己私有的栈。
  • 进程所创建的所有类的实例(也就是对象)或数组(指的是数组的本身,不是引用)都放在堆中,并由该进程所有的线程共享。
  • 虽然Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在栈中分配,也就是说在建立一个对象时在堆和栈中都分配内存,在堆中分配的内存实际存放这个被创建的对象的本身,而在栈中分配的内存只是存放指向这个堆对象的引用而已。
  • 局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收。

堆区:

  1. 存储的全部是对象,每个对象都包含一个与之对应的class的信息(class的目的是得到操作指令) ;
  2. jvm只有一个堆区(heap),且被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身和数组本身;

栈区:

  1. 每个线程包含一个栈区,栈中只保存基础数据类型本身和自定义对象的引用;
  2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问;

方法区(静态区)

  1. 被所有的线程共享,方法区包含所有的class(class是指类的原始代码,要创建一个类的对象,首先要把该类的代码加载到方法区中,并且初始化)和static变量。
  2. 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

http://www.importnew.com/18548.html

类加载的三种方式

  • 静态加载:直接new对象
  • 动态加载1:class.forname
  • 动态加载2:classloader
    https://blog.csdn.net/weixin_42447959/article/details/81255112

类加载机制

类生命周期

加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)

加载

在加载阶段(可以参考java.lang.ClassLoader的loadClass()方法),虚拟机需要完成以下3件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等);
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

加载阶段和连接阶段(Linking)的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序。

验证

验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

类加载周期

加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)

对于静态字段,只有直接定义这个字段的类才会被初始化

Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。

静态常量池,运行时常量池

  1. 所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。这种常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

    • 类和接口的全限定名
    • 字段名称和描述符
    • 方法名称和描述符
  2. 而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

你可能感兴趣的:(android框架)