4.1 基本概念
4.1.1 java 语言有点
4.1.2
Java 解释型语言
c/c++ 编译型语言
4.1.3 main方法 可以重名但类型等不能重复
4.1.5 static
初始化顺序 : 父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数
代码不需要加载
4.1.6 Java中的作用域
public:可以被其他所有类访问
protected:可以被自身,子类,以及同一包下的类访问。
default:可以被自身和同一包中的类访问。
private:只可以被自身访问。
4.1.8 构造函数不能被覆盖
4.1.9 空的接口常作为 标识接口
4.1.10 clone()
o = (Obj)super.clone()
4.1.11 反射机制
Class c = Class.forName("className");
className name = (className)c.newInstance();
a.method();
4.1.12 package
4.1.13 利用接口实现类似指针功能
4.2 面向对象技术
4.2.1 面向对象与面向过程有什么区别
1.出发点不同
2.层次逻辑关系不同
3.数据处理方式与控制程序方式不同。
4.分析设计与编码转换方式不同
4.2.2面向对象的特征
封装、继承、多态、抽象
4.2.3面向对象的开发方式有什么优点
1.较高的开发效率
2.保证软件的鲁棒性
3.保证软件的高可维护性
4.2.6 多态的实现机制
方法重载、方法覆盖
4.2.8 抽象类与接口
·包含抽象方法就是抽象类 变量默认static final类型
·接口就是指一个方法的集合没有方法体
4.2.9 内部类静态内部类(可以直接使用不必先实现外部类)、成员内部类、局部内部类
4.2.10获取父类名字
this.getClass().getSuperclass().getName()
4.2.11 this与super
4.3 关键字
4.3.2 brea、continue、return
中断多层循环
out:
代码
for()
for()
break out;
4.3.3 final、finally、finalize
一旦垃圾回收器准备好释放对象占用的空间,首先调用其finalize()方法。
4.3.4 assert有什么作用
assert 判定条件 : 错误提示
4.3.5 static关键词
4.3.7 volatile 每次用到它修饰的尘缘变量后每次都从内存中取,而不是缓存
4.3.8 instanceof 是不是类(接口、抽象类、父类)的实例
4.3.9 strictfp 修饰类或者接口或者方法 精确浮点
4.4 基本类型与运算
4.4.1 基本数据类型 int、short、long、byte、float、double、char、boolean
4.4.2 不可变类
4.4.3 值传递与引用传递
4.4.4 不同数据类型的转换有哪些规则
自动转换规则
操作数1的类型 | 操作数2的类型 | 转换后的类型 |
long | byte short char int | long |
int | byte short char | int |
float | byte short int char long | float |
double | byte short int long char float | double |
强制转换规则
原操作数的类型 | 转换后操作数的类型 |
byte | char |
char | byte char |
short | byte char |
int | byte short char |
long | byte short char int |
float | byte short char int long |
double | byte short char int long double |
4.4.7 Math类中的
round 加0.5向下取整
floor 向下取整
ceil 向上取整
4.4.8 ++i与I++
4.4.9 >> 与 >>>
4.4.10 char与string编码问题
Java Unicode编码
char 一个字符占用两个字符
string 英文占一个字节,汉字占用两个字节
4.5 字符串与数组
4.5.1 new String(“abc”) 创建一个或者两个 常量区及堆区 要看原先常量区是否有原先有“abc”字符串
4.5.2
- == 判断两个变量值是否相等 不适合判断对象 适合判断基本类型或引用
- equals object对象提供的方法判断内容是否相等
- hashCode 将地址转换成int
public boolean equals(Object anObject){
if(this==anObject){
return true;
}
if(anObject instanceof String){
String anotherString = (String)anObject;
int n = value.length;
if(n == anotherString.value.length){
char v1[] = value;
char v2[] = anotherString.value;
int i=0;
while(n--!=0){
if(v1[i]!=v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
4.5.3
- Character 用于单个字符串
- String
-
- 值不可变
- 可以直接赋值初始化也可以构造函数初始化
- 修改值时会调用StringBuffer方法
- 由于值不可变(常量)所以线程安全
- StringBuffer (字符串缓存区)
-
- 值可变
- 只能构造函数初始化
- 线程安全 (使用synchronized同步)
- StringBuilder
-
- 与StringBuffer相似
- 但线程不安全
4.5.4 数组是对象 有属性(length)及方法(clone)可调用
4.5.5数组声明及初始化
- 声明 type[] arrayName 或 type arrayName[] (不推荐)
- 数组创建后会有初始值
- 声明之后不会分配内存
- arrayName = new type[arraySize] 分配内存的方法
- 初始化方法 int[] a = new int[5] 或者 int[] a = {1,2,3,4,5}
- 也可以分开写
-
- int[] a; a = new int[5];
- int[] a ; a = new int[]{1,2,3,4,5};
- 二维数组
-
- 可以 int[][] a = new int[2][]; 数组内可变长度
- a[0] = new int[]{1,2,3};
- a[1] = new int[]{1};
4.5.6
- StringName.length() 获取字符串的长度
- arrayName.length 获取数组长度
- size 计算对象大小
4.6 异常处理
4.6.1 finally 什么时候被调用
- finally 在执行return方法之前执行
- finally的return会覆盖try或catch里面的return
- return的值会存储到一个位置 所以finally对返回值操作可以有影响 (可以当作存的是指针)
-
- 当返回类型为基本数据类型时,没有影响
- 引用类型时 (改变引用类型的值 不是改变引用)会有变化
- finally不一定被执行
-
- 进入try之前就发生了异常
- 在try会catch中强制退出 (System.exit(0))
4.6.2 异常处理原理
- 异常时程序在运行时发生的错误,JVM会抛出
- java语言将异常当作对象来处理
- 违反语义规则包括两种情况
-
- 一种是java类库内值的语义检查
- 另一种是开发人员扩展这种语义检查
- 异常继承图
4.6.3运行时异常和普通异常的区别
- Error
-
- 属于在运行期间发生了特别严重的错误
- 会导致程序终止
- 是由于逻辑错误导致的
- 不推荐捕获
- 应当解决错误
- Exception
-
- 表示可恢复的错误
- 编译器可以捕获到
- 两类
-
- 检查异常 编译器强制捕获
- 运行时异常 编译器没有强制对其捕获
- 异常处理注意事项
-
- 捕获异常应先捕获子类,然后再捕获父类
- 尽早抛出异常
- 可根据实际需求自定义异常
- 异常能处理就处理,不能处理就抛出
4.7 输入输出流
4.7.1 Java IO 流的实现机制
- 流的两大类
-
- 字节流 (8 bit 为单位) 不会用到缓存
-
- InputStream(输入流)
- OutputStream (输出流)
- 字符流 (16 bit) 一次可读性多个字节 缓存机制
-
- Reader (输入流)
- Writer (输出流)
- 读取文件 FileInputStream(“test.txt”);
4.7.2 管理文件和目录的类
方法 | 作用 |
File(String pathname) | 根据制定的路径创建File对象 |
createNewFile() | 若目录存在,则返回false,否则穿件文件或者文件夹 |
delete() | 删除文件或者文件夹 |
isFlie() | 判断这个对象表示的是否是文件 |
isDirectory() | 判断这个对象表示的是否是文件夹 |
listFiles() | 若是文件夹,列出所有文件 |
mkdir() | 根据当前对象指定的路径创建目录 |
exists() | 判断对象对象应的文件是否存在 |
4.7.3 Java Socket
- 网络七层结构
- Socket可分为两种
-
- TCP 面向连接的Socket通信协议
- UDP 面向无连接的Socket通信协议
4.7.4 Java NIO 非阻塞IO
4.7.5 什么是java序列化
实现持久化的方式
- 序列化
-
- 使用方式 实现Serializable接口
- 序列化的两个特点
-
- 如果一个类被序列化了其子类也能被序列化
- static、transient(临时数据),不能被序列化
- 什么时候需要序列化
-
- 需要通过网络来发送对象,或对象的状态需要被持久化到数据库或文件中。
- 序列化能实现深复制,即复制引用对象。
- 外部序列化
4.7.6 System.out.println() 注意事项
- 输出的是字符串
- 想输出对象需要定义 toString()方法
4.8 Java 平台与内存管理
4.8.1 java平台独立性语言
- 环境次序 Java程序、JRE/JVM、操作系统、硬件
4.8.3 JVM 家在 class 文件的原理机制
- 三类 加载器(系统类加载器、扩展类加载器、自定义类加载器)
-
- Bootstrap Loader -负责家在系统类(jre/lib/rt.jar的类)
- ExtClassLoader -负责加载扩展类(jar/lib/ext/*.jar 的类)
- AppClassLoader -负责加载应用类(classpath 指定的目录或 jar 中的类)
- 加载器优先由上级加载器加载,如果没有找到向下降级
- 加载器加载步骤
-
- 装载。根据查找路径找到相对的class文件,然后导入。
- 链接。链接分为三个小步骤。
-
- 检查。检查待加载的class文件的正确性。
- 准备。给类中的静态变量分配内存空间。
- 解析。给符号引用转换成直接引用。(可选)
- 初始化。对静态变量和静态代码块执行初始化工作。
4.8.4 什么是GC
- 垃圾回收算法
-
- 引用计数算法:没有引用时回收,由于无法解决相互引用的问题,JVM没有采用。
- 追踪回收算法:使用对象引用图没有被引用的回收。
- 压缩回收算法:把堆中活动的对象移动到堆的另一端。
- 复制回收算法:将堆分成连个相同的区,一个满了后将活动的对象复制到另一个区。
- 按代回收算法:青年代、老年代、持久代。
- System.gc() 通知垃圾回收运行,但未必马上运行垃圾回收。
4.8.5 java是否存在内存泄漏
- 内存泄漏的两种情况
-
- 堆申请的内存没有释放(java已经解决)
- 对象不在被使用但内存中仍然保留。
- 引发内存泄漏的原因
-
- 静态集合类,例如HsahMap和Vector。这些为静态容器,生命周期和程序一样长。
- 各种链接没有关闭。
- 监听器,删除对象时没有相应的删除监听器。
- 变量不合理的作用域。
- 单例模式可能会导致内存泄漏。
3.8.6 java中堆和栈有什么区别
- 堆
-
- 局部的基本类型以及对象的引用
- 栈
-
- 引用的变量内存
- 对象 包括对象内的变量引用(基本类型也存在堆区)
4.9 容器
4.9.1 Java Collections框架是什么
- Set 集合
-
- HashSet
- TreeSet
- List 列表
-
- LinkedList
- ArrayList
- Vector
- Map
-
- HashMap
- TreeMap
- LinkedHashMap 采用列表维护内部顺序
- WeakHashMap
- IdentityHashMap
4.9.2 什么是迭代器
- 不暴露内部细节
- 使用注意事项
-
- 通过iterator()方法返回iterator,next()获取下一个。
- hasNext() 判断是否还有新的元素
- remove()删除返回的元素
- 单线程解决ConcurrentModificationException异常,把想要删除的元素保存到一个集合中,然后使用removeAll()方法全部移除
- 多线程解决ConcurrentModificationException异常,使用synchronized同步或者ConcurrentHashMap等安全容器。
- Iterator和ListIterator的区别,Iterator只能正向遍历,适用于修改;ListIterator可以双向同时支持修改
4.9.3 ArrayList、Vector和LinkedList 有什么区别
- 均为可伸缩数组
- ArrayList、Vector基于Object[] array
-
- Vector默认扩展到原先的2倍(可以设置扩展方法)大多数方法使用synchronization同步,线程安全
- ArrayList默认扩展到原先的1.5倍(没有设置扩展方法)线程不安全
- LinkedList采用双向列表实现,非线程安全
4.9.4 HashMap、HashTable、TreeMap和WeakHashMap 有哪些区别
- HashMap 非线程安全、允许null为键值、使用Iterator遍历、默认大小是11 增加方式是old*2+1
- HashTable 线程安全、不允许null为键值、使用Enumeration遍历、默认大小是16而且一定是2的指数
- WeakHashMap与HashMap相似,WeakHashMap采用弱引用方式,当key不再被外部引用就可以被垃圾回收器回收。
- HashMap实现线程安全, Map m = Collections.synchronizedMap(new HashMap());
4.9.5 Map注意事项
- key不能重复
4.9.6 Collection和Collections有什么区别
- Collection是集合接口。
- Collections是针对集合的包装类。它提供了一系列静态方法以实现对各种集合的操作。
4.10 多线程
4.10.1 什么是多线程
- 程序执行是的最小单元 (进程是资源分配的基本单位)
- 栈是独立的,其他是共享的
- 一个进程可拥有多个线程
- 线程的四种状态:运行、就绪、挂起和结束。
- 新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)
- 多线程优点:
-
- 减少程序响应时间
- 线程创建和切换开销更小
- 多CPU有多线程执行能力
- 简化程序结构
4.10.2 同步和异步有什么区别
4.10.3 如何实现多线程
- 继承Thread类,重写run()方法。
Thread myThread = new Thread(){
public void run() {
//do something
}
};
myThread.start();
- 实现Runnable接口,并实现该接口的run()方法。(推荐)
public class testMain {
public static void main(String[] args) {
MyThread thread = new MyThread();
Thread t = new Thread(thread);
t.start();
}
}
class MyThread implements Runnable{
public void run() {
//do something
}
}
- 实现Callable接口,重写call()方法。
-
- Callable 比 Runnable更强大
- Callable可以在任务结束后返回一个值
- Callable中的call()方法可以抛出异常
- 运行时Callable可以拿到一个Future对象。
public class testMain {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
//启动线程
Future<String> future = threadPool.submit(new MyThread());
try {
System.out.println("wating!");
System.out.println(future.get());//等待线程结束返回结果集
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyThread implements Callable<String> {
public String call() throws Exception {
System.out.println("go");
return "Hello World";
}
}
- 推荐使用实现Runnable接口方式。
-
- 使用继承Thread也需要重写run()方法。
- 滥用继承是个坏习惯
- 可以既继承Thread类又实现Runnable接口,不必须写run()方法,因为从Thread类继承了run()方法;
4.10.4 run()方法和start()方法有什么区别
- start()开始一个线程,异步的调用run()方法
- 直接调用run()则认为是普通函数调用
4.10.5 多线程同步的实现方法
- synchronized关键字
-
- synchronized方法
-
- public synchronized void mutiThreadAccess()
- synchronized块
-
- synchronized(syncObject){
//访问syncObject对象的代码
}
- wait()和notify()
-
- wait()自己停止争抢线程,释放资源
- notify()唤醒等待队列中的第一个线程
- notifyAll()唤醒所有的等待线程
- Lock
-
- lock() 以阻塞的方式获取锁,如果没获取到等待,获取到立刻返回。
- tryLock() 尝试一下,获取到了返回true,没有返回false
- tryLock(long timeout,TimeUnit unit)在一段时间内尝试
- lockInterruptibly() 与lock()相似但可以被其他线程中断,会收到InterruptedException异常。
-
- 演示
-
4.10.6 sleep()方法与wait()方法有什么区别
- sleep() 不推荐使用
-
- 是Thread的静态方法,
- 暂停执行把执行机会让给其他线程,时间到自动苏醒,
- 不涉及线程间的通信
- 不释放锁
- 可以放在任何地方
- 必须捕获异常
- wait()
-
- 是Object的方法,
- 可使用notify()唤醒或设定时间,
- 用于线程通信
- 释放锁
- wait()只能放在同步方法或同步块中
- yield() 暂停当前正在执行的线程对象,并执行其他线程。 让优先级更高的线程运行
- yield()和sleep()的区别
-
- sleep()不考虑优先级 yield()考虑
- sleep()在时间内不会被执行, yield()没有时间限制可能立即被执行
- sleep()会抛出InterruptedException异常。
- sleep()有更好的可移植性。
4.10.7 终止线程的方法有哪些
- 不建议
-
- stop() 会释放资源
- suspend() 不会释放锁资源
- 使用 flag标志
- 使用休眠模拟阻塞
-
4.10.8 Lock和synchronixed有什么区别
- 用法不同synchronized可以下载方法前或者写成代码块,Lock需要写在起始和终止位置。
- 性能不同,不激烈的情况下synchronized优秀,激烈的情况下Lock更好用。
- 锁机制不同Lock需要人为的开启释放,synchronixed不需要。
- 使用事例
4.10.9 守护进程
- 用户进程都结束了,守护进程也会结束。
- 通过setDaemon(true) 设置该线程为守护线程。
4.10.10 join()方法的作用是什么
- join的作用是线程合并,用于实现同步,等待线程结束。
- 也可以添加参数join(2000)表示最多等待2s。
4.11 Java数据库操作
4.11.1 如何通过JDBC访问数据库
- 步骤
-
- 加载JDBC驱动器,既导包
- 加载JDBC驱动,一般使用反射Class.forName(String driveName)
- 建立数据库连接,取得Connection对象,一般通过DriverManager.getConnection(url, username,passwd)
- 建立Statement对象或者PreparedStatement对象。
- 执行SQL语句。
- 访问结果集ResultSet对象。
- 关闭
- 事例
4.11.2 JDBC处理事务的方法
- 通过commit()和rollback()结束事务。
- 可通过setAutoCommit(false) 设置不自动提交
- 事务隔离级别
-
- TRANSACTION_NONE 说明不支持事务。
-
TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化。这样脏读、不可重复的读和虚读都是允许的。
-
TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生。
-
TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
-
TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、不可重复的读和虚读。
4.11.3 Class.forName()的作用是什么
- 把类加载到JVM虚拟机
4.11.4 Statement、PreparedStatement和CallableStatement区别
- Statement 用于执行不带参数的SQL语句。
- PreparedStatement执行带参数语句,预编译,预防sql注入。
- CallableStatement提供了调用存储过程的接口。
4.11.5 getString()与getObject()的区别
- getString()等会在数据集合非常大的时候发生异常,因为会一次性读取到内存。
- getObject()不是一次性读取到内存。
4.11.6 JDBC注意事项
- 先连接
- 记得关闭连接
- 创建Statement的语句放在循环外面
4.11.7 什么是JDO
- Java数据数据对象
- 是一种用于存储某种数据仓储的对象的标准化API。
4.11.8 JDBC和Hibernate的区别
- Hibernate是对JDBC的封装