一、java面向对象
面向对象是什么?
将功能封装到对象里强调是具有某功能的对象,记住:万物皆是对象
面向对象的四大基本特征?
抽象:抽象是将一类对象的共同特征总结出来。
封装:封装是将类中的属性和方法保护起来,封装起来,不允许随意访问,使用private,并且提供getter,setter方法。调用的时候通过getter方法访问
继承:子类继承父类,从已有的类得到继承信息创建新类的过程。继承的类为子类,被继承的类为父类,子类拥有父类的方法和属性。
多态:允许不同子类型的对象对同一消息做出不同的反应
即用同样的对象引用调用同样的方法做不同的事情。
方法重写:子类继承父类兵重写父类的方法
向上转型:父类型引用子类型对象,这样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为
值传递和引用传递?
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。
引用传递一般是对于对象型变量而言的,传递的是对该对象地址的一个副本,并不是原对象本身。
一般认为java内的传递都是值传递,java中实例对象的传递都是引用传递
Java中方法方法重载(Overloading)和重写(Overriding)?
重载:java中的方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同。
重写:发生在父子类,方法名,参数列表必须相同,返回类型是父类的子类或相同,访问修饰符的权限大于等于父类。
自动装箱和拆箱?
装箱:将基本类型用它们对应的引用类型包装起来
拆箱:将包装类型转换为基本数据类型
Java使用自动装箱和拆箱机制,节省了常用数值的内存开销和创建对象的开销,提高了效率,由编译器来完成,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。
什么是泛型?
泛型即参数化类型,创建集合时就指定集合元素的类型,该集合只能保存其指定类型的元素,避免使用强制类型转换
java支持多继承吗?
java中类不支持多继承,只支持单继承(即一个类只有一个父类),java中只允许多层继承,不允许多重继承。存在单继承局限。
接口和抽象类的区别?
从设计层面上来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
接口的所有方法隐含的都是抽象的,抽象类可以同时包含抽象和非抽象的方法。
类可以实现多个接口,但只能继承一个类。
类可以不实现抽象类和接口声明的所有方法,前提他也是抽象类。
java接口中只包含全局常量,使用final修饰,抽象类可以包含非final的变量。
java中接口的成员函数默认是public,抽象类的成员函数可以是private,protected或public
接口是绝对抽象的,不可以被实例化,抽象类也不可以被实例化,但是如果包含main 方法可以被调用的
抽象类可以继承实体类吗?
抽象类可以继承实体类,但前提是实体类必须有明确的构造方法。
四种访问权限
private:只能在同一包的同一类中访问
default:只能在同一包中访问
protected:在不同包子类访问
public :public所有
二、java集合
HashMap和Hashtable 有什么区别?
hashMap是非线程安全的,HashTable是线程安全的
HashMap的键和值都允许有null值存在,而HashTable不行
因为线程安全问题,HashMap效率比HashTable要高
Hashtable是同步的,而HeshMap不是,因此HashMap更适合单线程环境,而Hashtable适合多线程
HashTable使用Enumeration进行遍历,HashMap使用Iterator进行遍历
HashMap和TreeMap?
对于在Map中从插入,删除和定位元素这类操作,HashMap是最好的选择,
ListSet Map比较?
List:可以允许重复的元素,可以插入多个null元素,有序,有get方法
Set: 不允许有重复的元素,只允许有一个空值,无序
Map:键值对存储,键唯一,值可以重复,键只允许有一个null,值可以有多个null,无序
ArrayList和LinkdeList的区别?
ArrayList(数据结构)
ArrayList是动态数组(顺序表)的数据结构。顺序表的存储地址是连续的,所以查找的速度比较快,但是在插入和删除的时候,需要把其他元素移动,所以耗时。
LinkedList(链表结构)
LinkedList是链表的数据结构,链表的存储地址是不连续的,每个存储地址通过指针指向,在查找时需要进行通过指针遍历元素,在查找是比较慢,由于链表插入是不需要移动其他元素,所以在插入和删除是比较快。
HashSet,TreeSet,LinkedHashSet区别?
集合的使用场景:
需要速度快的集合使用HashSet
需要集合有排序功能使用TreeSet
需要按照插入的顺序存储集合使用LinkedHashSet
hashMap、TreeMap和linkedhashmap区别?
HashMap,根据键的HashCode值存储数据,根据键获得它的值,具有很快的访问速度,遍历时,取得数据的顺序完全随机的,
LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到记录肯定是先插入的,在遍历的时候比HashMap慢
TreeMap能够把它保存的记录根据键排序,默认升序,使用Iterator遍历TreeMap时,得到的记录是排过序的,TreeMap的键和值都不能为空。
HashMap和HashSet区别?
HashMap实现了Map接口,HashSet实现了Set接口
HashMap存储键值对,HashSet存储对象
HashMap调用put()向map中添加元素,HashSet调用add()向set中添加元素
HashMap使用Key计算hasncode,HashMap使用成员计算Hashcode
HashMap相对HashSet较快,使用键获取对象
Collection和Collerctions的区别?
Collection是集合类的父接口,继承的接口有List和Set.
Collections是针对集合类的一个帮助类,提供一系列静态方法实现对各种集合的搜索,排序,线程安全化等操作。
三、java线程
什么是线程,什么是进程?
线程是指程序在执行过程中,能够执行程序代码的一个执行单位,每个程序至少有一个线程,即程序本身。
线程的状态?
就绪 运行 阻塞 终止
所有的线程对象必须通过关键字new进行创建,进入到就绪状态
进入到就绪状态之后,将等待着CPU进行资源的抢占,抢占到了资源之后,线程会进如到运行状态,开始执行run()方法体之中所定义的代码,;
每一个线程执行run()方法到一定的时间的时候会让出CPU资源,进入到阻塞状态,而后重新回到就绪状态等待下次资源调度并继续执行run()方法中的代码;
如果全部方法执行完毕之后,将进入到线程的终止状态,并且不会再进入到就绪状态,直接结束。
线程和进程的区别?
线程是进程的子集,一个进程可以有很多线程,每条线程执行不同的任务
一个线程只能属于一个进程,一个进程可以有多个线程。
资源分配给进程,同一进程的所有线程共享该进程的所有资源
调度,线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源
实现线程的方法,有什么区别?
继承Thread类和实现Runable接口:
启动方法不同:继承Thread类,newThread1().start()
实现Runable接口: newThread2(new Thread2()).start()
使用Runable可以有效避免单继承的局限,Thread类是Runable接口的子类。
启动线程是run()还是start(),他们的区别?
启动线程使用start();
run():封装了被线程执行的代码,直接调用相当于普通方法的调用
start():用来启动新创建的线程,而且start()内部调用run()方法,和调用run()方法不一样,调用run()方法只会在原来的线程中调用,没有新的线程启动,start()方法启动新线程
sleep方法和wait()方法的区别,带时间参数时有什么区别?
sleep()方法是线程的静态方法,是当前线程暂停执行一段时间,让其他线程有机会执行,但不释放对象所,如果有Synchronize同步块,其他线程仍然不可访问
wait()方法使当前线程暂停执行并释放对象锁,让其他线程可以进入synchronize数据块,当前线程被放入对象等待池中。
什么是对象锁?
对象锁:同一时间只保证一个线程访问方法或变量
什么是同步代码块?
通过被关键字synchronize修饰的方法或synchronize语句块实现对代码的同步
如何终止一个线程?
stop()方法:该方法不安全,太过暴力强行终止线程
interrupt()方法:捕获InterruptException异常结束线程
什么是线程安全和线程不安全?
(加锁的就是安全的,不加锁的就是不安全的)
(存在竞争的线程不安全,不存在竞争的线程是安全的)
线程安全就是多线程访问的时候,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问知道该线程读取完,其他线程才可使用,不会出现数据不一致或者数据污染
如果代码所在的进程中有很多线程在同时运行,而这些线程可能会同时运行这段代码,如果每次运行结果和单线程运行结果一样,而且其他的变量的值也和预期的一致,就是吸纳成安全的。
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
多线程同步的方法?
同步方法:
同步代码块:
使用特殊域变量(volatile)实现线程同步
使用重入锁实现线程同步:ReentrantLock
使用局部变量实现线程同步:使用ThreadLocal管理变量
同步的概念?
同步是指多个操作在同一个时间段内只能有一个线程进行,其他线程要等待此线程完成后才可以继续执行。
同步和异步,什么时候使用?
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取
当应用程序在对象上调用一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步。
什么时候考虑同步问题?
多个线程访问同一资源时,考虑同步问题。
什么是死锁?
多个线程都是在相互等待着,线程间相互等待资源,又不释放自身的资源。
死锁的出现条件?
互斥条件:一个资源每次只能被一个线程使用
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
循环等待条件:若干进程之间形成一个头尾详解的循环等待资源关系
当一个线程进入一个对象的一个synchronize方法后,其他线程是否可以进入此对象的其他方法?
不能
为什么要使用线程池?
避免频繁的创建和销毁线程,达到线程对象的重用,另外使用线程池可以根据项目灵活的控制并发的数目
线程操作:
等待:wait()
唤醒第一个等待线程:notify()
唤醒全部等待线程:notifyAll()