又到了万人挤独木桥的时候,离职后就对自己放纵懒散了1个月,这两天才开始打起精神看一点书。
前几天的阿里笔试出问题,反倒是给了我一记响钟,似乎在告诉我自己掌握的有多烂,回去补补再来吧。
我庆幸没有收到面试通知,这样才能多些时间准备下一次的笔试。
而这两天看书之后,越看越发现要掌握的东西原来这么多,就好像树一样,不断扩展,我掌握的速度完全跟不上它。
然而也欣慰,终于找回了一些学习的状态,每天进步一点,已经很满足。
言归正传,虽然丢弃java很多年,但为了面试还是得重新捡起来,把昨天看的一点java基础的东西记一下,以便以后查阅。
一.Java相关概念
JDK Java Development Kit 包括JAVA语言+JAVA虚拟机+JAVA API
JRE 包括 Java SE API 子集 + JAVA 虚拟机
JAVA虚拟机: 提供运行时环境,提供垃圾回收功能
javac 编译.java文件生成.class, java 运行java程序
运行时数据区:
堆区: 存放对象
方法区: 线程共享,类的类型信息(静态变量和方法信息) .class 文件
本地方法栈:为native方法服务,由另一种语言实现的本地方法
Java虚拟机栈:线程私有,基础数据类型的变量和自定义对象的引用
程序计数器:当前线程所执行的字节码的行号指示器
运行时常量池
方法区的一部分,存放编译期生成的字面量和符号引用 。eg,String.intern() 将常量放入池中
二.类和对象的生命周期
当需要使用一个类时,需要经过类的加载,连接,初始化
加载:查找并加载二进制数据,放入内存
连接:包括验证,准备,解析
验证:确保类的正确性,检查文件结构,语义,字节码
准备:静态变量分配内存,初始化为默认值
解析:由符号引用转变为直接引用
初始化:给静态变量正确的初值
类加载器,使用父亲委托机制,主要包括四种加载器
1.启动类加载器加载虚拟机核心库,JDK_HOME/lib
2.扩展类加载器从指定目录中加载,.jar
3.系统类/应用类加载器 从环境变量classpath和用户程序目录中
4.自定义类加载器 继承java.lang.ClassLoader 运行期间动态加载
创建对象的方式
1.new
2.反射
3.clone
4.反序列化
三.java异常处理
java异常都继承自java.lang.Throwable,主要分为Error和Exception
Exception又分为运行时异常RuntimeException和受检查异常
(运行时异常, java不会检查,没有try-catch或者throws也可以正常编译)
常见异常有: AirthmeticException,NullPointerException,ArrayIndexOutofBoundsException,ClassCastException等
四.java多线程
创建方式:Thread or Runnable
java采用抢占式调度模型,优先运行高优先级的线程,优先级相同则随机选择,占用cpu的线程一直运行知道不得不放弃
放弃cpu的三种方式:Thread.sleep(),Thread.yield(),调用另外一个线程的join()等待其运行结束
Thread.setPriority(int) 设置优先级 (1,5,10)
Thread.setDaemon(bool)设置为后台线程
线程的同步
在代表原子操作的程序代码上加上synchronized,每个java对象有且只有一个同步锁
五.I/O
分为字节流(InputStream,OutputStream)和字符流(以Unicode字符为导向,Reader/Writer)
六.网络编程
java.net
基于TCP Socket,ServerSocket
基于UDP DatagramPacket,DatagramSocket,MulticastSocket
七.对象的序列化和反序列化
API: java.io.ObjectOutputStream writeObject(Object obj) 序列化
ObjectInputStream readObject() 反序列化
只有实现了Serialiable 或者 Externalizable (需要实现write/readExternal方法控制流格式和内容)才能被序列化
transient关键字表示在该域上关闭序列化
反序列化时不会执行对象的构造函数
八.java反射机制
java.lang.reflect.Class/Field/Method/Constructor/Array
利用反射机制新建实例的方法:
Class oneClass = Class.forname(className);
Class[] argsClass = new Class[args.length];
for(int i=0;j=args.length;i<j;i++){
argsClass[i]=args[i].getClass();
}
Constructor cons = oneClass.getConstructor(argsClass):
return cons.newInstance(args);
九.java中内部类
详见: http://android.blog.51cto.com/268543/384844
内部类是指在一个外部类中定义另一个类,类名不与文件名相同,可以用static,public/protected/private修饰,编译后成为outer$inner.class
内部类分为以下几种:
1 成员内部类,作为外部类的成员,可以使用外部类的所有成员和方法,不能用static修饰
2 局部内部类,内部类定义在外部类的方法和作用域内
3 嵌套内部类,修饰static的内部类,可以有static的数据和属性,一般为public
4 匿名内部类,比如setOnClickListener(new XXListener(){});
当所在方法的形参被调用时,需要用final修饰,因为在内部类使用它时,会创建一个副本,为保持数据一致性
5 内部类的继承, 在子类中的构造函数中需要用外部类作为形参,创建外部类
十.java垃圾回收机制
对象标记:
1引用计数法,给对象添加引用计数器,引用时+1,失效时减1,计数为0时可以被回收(难以解决对象间循环引用的问题)
2 根搜索算法,以一系列名为'ac Roots'的对象作为起点,从这些节点开始向下搜索,走过的路径称为引用链,当一个对象没有任何引用链相连时,可以被回收
引用
强引用: obj = new Object() 不会回收
软引用: 非必须的,将要发生内存溢出异常前回收
弱引用: GC时被回收
虚引用:
finalize() 只执行一次,当一个对象要死亡之前调用
垃圾收集算法
1 标记-清除,标记需要回收的对象,统一回收 (效率不高,存在内存碎片)
2 复制,将内存分为大小相等的两块,每一次使用一块,将存活的对象复制到另外一块,再清空内存
同常用一块较大的Eden 和 两块较小的Survivor 8:1
3 标记-整理, 让所有存活的对象向一端移动
4 分代收集算法, 新生代用复制算法,老年代 采用标记-清除/整理
内存分配与回收策略
1 对象优先在Eden分配,Eden没有足够空间时,虚拟机发起一次Minor GC
新生代GC: 频繁,速度快 (Minor GC)
老年代GC(Major/Full GC) 经常伴随至少一次的Minor GC,速度慢
2 大对象直接进入老年代
3 长期存活的对象将进入老年代 ,新生代中每熬过一次Minor GC ,年龄+1,到一定程度则(15岁)晋升
4 动态对象年龄判定,若果Survior 中相同年龄的所有对象大小和大于Survivor空间的一半,则年纪大于等于该年龄的对象直接进入老年代
5 空间分配担保 发生MinorGC 时,升到老年代的平均大小是否大于老年的剩余空间,如果是,进行一次Full GC
十一 SSH
Stuts
1 实现了MVC模式
2 有丰富的tag和标签库
3 包含一个controller servlet
4 通过java反射机制自动处理java beans
Hibernate
1 通过jdbc进行封装,屏蔽了jdbc api的底层访问细节
2 对java类和关系数据库进行映射
3 延时加载 load()/get()
4 缓存机制 一级缓存(Session)/二级缓存
5 查询方式: 本地SQL Criteria Hql
Spring
1 IOC 控制反转 由系统进行统一控制
2 AOP 面向切片 将多个类的行为进行封装,将程序中涉及到的公共问题集中解决
十二 其他
1 switch() 只能作用与一个整数表达式or枚举常量 byte short char 可以隐式转化为int 。String,long 不行
2 == 和equals区别
烂掉的问题,==比较变量对应内存中的数值 equals 比较独立对象的内容
3 Math.round() 四舍五入 Math.ceil 向上取整 Math.floor 向下取整
4 overload 和 override 依然是烂掉的问题
5 抽象类和接口的区别
接口是特殊的抽象类,所有方法都是抽象的,成员变量默认为public static final
一个类可以实现多个接口,但只能继承一个抽象类
6 String 类是final类,不可被继承,String 对象有length() 方法,数组为length属性
7 final finally finalize
8 HashMap 和 HashTable
HashMap 可以有空值, HashTable 线程安全