1、
final修饰的类不能被继承,一个类不能被同时被final和abstract修饰;final修饰的方法不能被重写,但是可以重载
2、
final用于声明属性,方法和类,分别表示属性不可改变,方法不可重写(覆盖),类不可继承
finally是异常处理语句结构的一部分,表示总是执行,无论return continue还是break都无法停止
finaliz是Object类中的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾手机时的其他资源回收,例如关闭文件等。
3、
1.8后
HashMap是线程不安全的,底层数据结构是使用链表和数组和红黑树实现的,继承的是AbstractMap类;初始容量为16,负载因子为0.75;添加key-value的hash值算法时,使用的是自定义的哈希算法;扩容机制,当已用容量>总容量 * 负载因子时,HashMap 扩容规则为当前容量翻倍;只支持Iterator遍历;不支持contains(Object value)方法,没有重写toString()方法;不是同步的,适用于单线程环境
HashTable是线程安全的,底层数据结构是使用链表实现的,继承的是Dictionary类;初始容量为11,负载因子为0.75;添加key-value的hash值算法时,直接采用key的hashCode();扩容规则为当前容量翻倍 +1;支持Iterator和Enumeration两种方式遍历;支持contains(Object value)方法,而且重写了toString()方法;是同步(synchronized)的,适用于多线程环境
4、
sleep()是使得当前线程进行停滞状态(阻塞当前线程),让出CPU的使用,给其他线程执行的机会
wait()是Object类里的方法,当一个线程执行到wait()方法是,他就进入到一个和该对象相关的等待池中,同时释放了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
wait()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。
sleep()睡眠时,保持对象锁,仍然占有该锁; 而wait()睡眠时,释放对象锁。
但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。
5、
&是逻辑运算符,也可以进行位运算,将两个树的二进制按位进行与运算。
&&是逻辑运算符,两边都为true时结果为true,否则为false,具有短路功能,当左边的表达式为false时停止计算后边的表达式。
6、
使用位移运算符,因为是2*8,所以是左移,所以是8向左移动一位, 代码为: 8
7、
== 等于比较运算符,如果进行比较的两个操作数都是数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true.如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成==比较的是两个变量的内存地址)
equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.
== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.
8、
不可以。一个static方法只能调用静态成员,不可以调用非静态成员
9、
overload是方法重载,
1)方法名称必须相同;
2)参数列表必须不同,即参数个数、参数类型或参数顺序中任有一个不同。
3)方法的返回类型可以相同也可以不同,对此无限制。
4)若仅满足方法的返回类型不同,不属于方法重载。
override是方法重写,
1)发生方法重写的两个方法返回值、方法名、参数列表必须完全一致(子类重写父类的方法)。
2)子类抛出的异常下不能超过父类相应方法抛出的异常(子类异常不能大于父类异常)。
3)子类方法的访问级别不能低于父类相应方法的访问级别(子类访问级别不能低于父类访问级别)。
4)如果子类想使用被隐藏的方法,必须使用关键字super。
10.
接口能够继承接口,并且能够同时继承多个接口,继承时使用关键字extends;
抽象类能够实现接口
11、抽象类能继承具体类
抽象类可以有静态的 main 方法。抽象类在面向对象中是被用来描述现实中的抽象事物, 抽象类没有对象概念所以不能被实例化. 但可以定义属性和方法, 其中属性方法都可以是静态的. 静态的意义其实就是在栈内存中只有一个, 所以该成员也会先于对象出现在内存中, 所以静态并没有违反抽象的原则. 抽象类中可以定义静态成员.
12、可以继承其他类或实现其他接口,在Swing编程和Android开发中常用此方式来实现事件监听和回调。
13、会执行,finally{}中代码的执行不受return break continue的影响。 执行完tyr{}中的代码后执行
14、Error类对象由 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Exception中的这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
15、ArithmeticException, 算术异常
ClassNotFoundException 类没找到时,抛出该异常
FileNotFoundException, 文件未找到异常
SQLException, 操作数据库异常
NullPointerException, 空指针异常
16、
多线程实现的方式有四种:
(1.继承Thread类,重写run方法
public class ThreadDemo01 extends Thread{
public ThreadDemo01(){
//编写子类的构造方法,可缺省
}
public void run(){
//编写自己的线程代码
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args){
ThreadDemo01 threadDemo01 = new ThreadDemo01();
threadDemo01.setName("我是自定义的线程1");
threadDemo01.start();
System.out.println(Thread.currentThread().toString());
}
}
程序结果: Thread[main,5,main] 我是自定义的线程1
(2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
public class ThreadDemo02 {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
Thread t1 = new Thread(new MyThread());
t1.start();
}
}
class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"-->我是通过实现接口的线程实现方式!");
}
}
程序运行结果: main Thread-0–>我是通过实现接口的线程实现方式!
(3.通过Callable和FutureTask创建线程
public class ThreadDemo03 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Callable<Object> oneCallable = new Tickets<Object>();
FutureTask<Object> oneTask = new FutureTask<Object>(oneCallable);
Thread t = new Thread(oneTask);
System.out.println(Thread.currentThread().getName());
t.start();
}
}
class Tickets<Object> implements Callable<Object>{
//重写call方法
@Override
public Object call() throws Exception {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"-->我是通过实现Callable接口通过FutureTask包装器来实现的线程");
return null;
}
}
程序运行结果
main Thread-0–>我是通过实现Callable接口通过FutureTask包装器来实现的线程
(4.通过线程池创建线程
public class ThreadDemo05{
private static int POOL_NUM = 10; //线程池数量
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i = 0; i<POOL_NUM; i++)
{
RunnableThread thread = new RunnableThread();
//Thread.sleep(1000);
executorService.execute(thread);
}
//关闭线程池
executorService.shutdown();
}
}
class RunnableThread implements Runnable
{
@Override
public void run()
{
System.out.println("通过线程池方式创建的线程:" + Thread.currentThread().getName() + " ");
}
}
程序运行结果:
通过线程池方式创建的线程:pool-1-thread-3
通过线程池方式创建的线程:pool-1-thread-4
通过线程池方式创建的线程:pool-1-thread-1
通过线程池方式创建的线程:pool-1-thread-5
通过线程池方式创建的线程:pool-1-thread-2
通过线程池方式创建的线程:pool-1-thread-5
通过线程池方式创建的线程:pool-1-thread-1
通过线程池方式创建的线程:pool-1-thread-4
通过线程池方式创建的线程:pool-1-thread-3
通过线程池方式创建的线程:pool-1-thread-2
17、冒泡排序,插入排序,快速排序,选择排序,归并排序,希尔排序,基数排序,堆排序
//快速排序
public static void order5(int[] a) {
quickSort(a,0,a.length-1);
}
private static void quickSort(int[] a, int left, int right) {
if(left < right) {
int i = getMiddle(a,left,right);
quickSort(a, left, i - 1);
quickSort(a, i + 1,right);
}
}
private static int getMiddle(int[] a, int low, int high) {
int pivot = a[low];
int i = low;
int j = high;
while(i < j) {
while(pivot <= a[j] && i < j) j--;
while(pivot >= a[i] && i < j) i++;
if(i < j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
a[low] = a[i];
a[i] = pivot;
return i;
}
18、
int[] a= {1,2,3,4,5,9,9,9,9,99,9,0,9};
for(int i=0,j=a.length-1;i<j;i++,j--) {
int temp=a[j];
a[j]=a[i];
a[i]=temp;
}
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
19、
String s = "打算dasdfs23525225 ";
int chineseNum = 0, letterNum = 0, figureNum;
int length = s.length();
figureNum = length - s.replaceAll("\\d", "").length();
letterNum = length - s.replaceAll("[a-zA-Z]", "").length();
chineseNum = length - s.replaceAll("[\\u4E00-\\u9FA5]+", "").length();
System.out.println("汉字数目:"+chineseNum);
System.out.println("字母数目:"+letterNum);
System.out.println("数字数目:"+figureNum);
20、
对于GC(垃圾收集)来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。
垃圾回收器不可以马上回收内存。垃圾收集器不可以被强制执行,但程序员可以通过调研System.gc方法来建议执行垃圾收集。记住,只是建议。一般不建议自己写System.gc,因为会加大垃圾收集工作量
程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
21、
1.装载:查找和导入class文件;
2.连接:
(1)检查:检查载入的class文件数据的正确性;
(2)准备:为类的静态变量分配存储空间;
(3)解析:将符号引用转换成直接引用(这一步是可选的)
3.初始化:初始化静态变量,静态代码块。
22、
Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。
将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化.