1谈谈集合框架;
集合框架分为两大派系
|--单列集合 Coloection
|-- List 有序,可重复,元素都有索引值
|-- ArrayList 底层是数组数据结构,查询速度快,增删稍慢,线程不安全的
|-- LinkedList底层是链表数据结构,增删速度快,查询稍慢,线程不安全的
|-- Vector 底层是数组数据结构,查询也删除都慢,线层安全的,jdk1.0时出现,后来被ArrayList替代
|-- Set 无序,不可重复,因为底层是封装的一个Map集合,它使用了Map的key,丢弃了Map的vlaue,所以必须保证元素的唯一性.
|-- HashSet 底层是哈希表数据结构,线程不安全的,无序高效,必须保证元素的唯一性.
|-- TreeSet 底层是二叉树数据结构,线程不安全的,可以对存入的数据进行排序,但是必须保证元素的唯一性,否则会导致元素覆盖
要使用TreeSet集合对元素进行排序,前提是必须让元素具备可比性,有两种方式:
|-- 让元素自身具备比较性,也就是让元素实现Comparable接口并覆盖compareTo方法来指定比较规则
|-- 如果元素自身不具备比较性或者具备的比较性不是所需要的,
我们可以定义一个比较器,也就是实现Comparator接口并覆盖compare放来指定比较规则,通过TreeSet的构造方法传递给集合即可.
|-- 迭代器:要遍历集合,则需要使用到Iterator接口,也就是迭代器,调用集合的一个iterator方法返回的就是一个Iterator迭代器,
通过该迭代器的hasNext和next方法就可以循环得到集合中的每一个元素
|--双列集合 Map
|-- Hashtable 底层是哈希表数据结构,线程安全的,不可以存储null键null值,jdk1.0时出现,后来被HashMap替代
|-- HashMap 底层是哈希表数据结构,线程不安全的,可以存储null键null值,数据是以键值对的形式存储的,键和值之间存在着映射关系.
|-- TreeMap 底层是是二叉树数据结构,线程不安全的,可以对集合中的key进行排序,排序方式和TreeSet相同
|-- Map集合本身是没有迭代器的,要想迭代该集合中的元素有两种方式
|-- 调用该集合的keySet方法返回的是集合中所有的key的Set集合,在使用Set集合的迭代器对返回的Set集合进行迭代,再通过Map集合的get(key)方法获取key对应的value值
|-- 调用该集合的entrySet方法返回的是Map集合中键和值的眏射关系,数据类型为Map.Entry,在迭代返回的Set集合获取每一个键和值的眏射关系,在调用Map.Entry的getKey和getValue方法回去对应的键和值
2,如何实现多线程,如何开启多线程;
|-- 有两种方式:
|-- 继承Tread,复写run方法,通过start方法开启该线程
|-- 实现Runnable接口,复写run方法,通过start方法开启该线程
常用的是第二种方式,因为是第二种方式把线程开启后要执行的代码块也封装成了对象,java是面向对象的语言,所以这样做可以更符合java思想
|-- 在java1.5的时候引入了java.util.concurrent线程并发包,加入了线程池的概念,通过Exceutors工具类来创建线程池.
3,反射及暴力反射;
|-- 获取字节码的三种方式:
|-- 类名.class
|-- 对象.getClass
|-- Class.forName
|-- 反射就是将java类中的各个成分映射成相应的java类,通过字节码.getConstructor获取构造方法,通过字节码.getField获取类中的字段
通过字节码.getMethod获取类中的方法
|-- 暴力反射 ,暴力反射就是去掉JVM的访问检查
如果一个类中的字段是私有的,使用getField获取该类中的字段的时候就会抛字段未找到异常,可以通过getDeclaredFields方法来获取该字段
通过字段点.setAccessible(true)来告诉编译器是否进行访问检查,true表示不进行访问检查
4,谈谈对面向对象的理解;
|-- java是全面向对象的语言,在java中一切都是对象,谁拥有数据谁就提供来操作这些数据的方法
5,如何取出Map中的元素
|-- 请参见上面的集合框架,有详细介绍...
6,动态代理:
|-- 动态代理就是JVM在运行期间动态生成的字节码文件,这种动态生成的字节码文件通常用来做代理类,即动态代理
虚拟机动态生成的字节码文件必须实现一个或多个接口,所以生成的动态类只能用作具有相同接口的代理类
通过Proxy的静态方法newProxyInstance方法来生成一个动态代理类,该方法接受三个参数,第一个是需要一个类加载器
第二个是被代理类所实现的一个或者多个接口,第三个是一个InvoctionHandler,并覆盖该接口中的invoke方法来完成相的系统功能
7,委托机制;
|-- java中可以有对个类加载器,默认的有三个
|-- BootStrap 用来加载rt.jar文件
|-- ExtClassLoad 用来加载ext目录下的所有.jar文件
|-- AppClassLoad 用来加载Class Path指定目录下的jar文件
|-- 为了保证父类加载器优先加载到类,java采用了委托机制,也就是当需要加载一个类的时候,首先会委托给父类的来加载,父类在委托给父类
直到BootStrap还是没有加载到该类的时候在一级级的退回来,到了类加载器的发起者还是不能加载该类的话就会抛ClassNotFoundException类未找到异常
8,IO字符流复制文件、字节流复制文件、复制文件夹;
|--
9,泛型,说了个上下限说是什么时候用;
|-- 泛型就是为了限定集合中的输入类型,让编译器挡住程序的非法输入,避免了强制类型转换的问题
|-- 上限 格式<? extends T> 表示只能是T或者T的子类类型
|-- 下限 格式<? super T> 表示只能是T或者T的父类类型
10,单例的设计模式作用,懒汉式和饿汉式的区别;
|-- 单例设计模式就是为了保证对象在内存中的唯一性
|-- 懒汉式 懒汉式是在调用获取该对象的静态方法的时候才初始化该对象
|-- 饿汉式 饿汉式是在类加载的时候就初始化对象,
11,银行系统哪里用到了单例,问银行卡上有账号是不是单例;
|-- 银行卡上有账号不是单例设计模式,因为银行有很多客户,每个客户都有一张属于自己的银行卡和卡号
|-- 银行系统的号码管理器使用了单例设计模式,必须让所有的客户都通过同一个号码管理器来获取相应的号码,如果有多个号码管理器的话就会造成号码重复
12,详细说明面向对象三个特点
|-- 继承 可以使用现有类的所有功能,在不改变现有类的情况下对它进行功能的扩充和增强
好处就是提高了代码的复用性,让类与类之间产生关系,为多态做前提
|-- 封装 将不需要对外提供的内容都隐藏起来,并对外提供公共的访问形式
好处就是将变化隔离,提高了代码的重用性和安全性
|-- 多态 父类和接口的引用指向了自己的子类对象
如果父类的引用指向了自己的子类对象,只能访问从父类继承的成员,不能访问子类独有的成员,弊端就是有局限性
好处就是提高了程序的可扩展性
13,List和Set集合的区别
|-- 请参见上面的集合框架,有详细的介绍
14,类加载
|-- 参见委托机制
15,List和Set当中的一些类及区别
|-- 请参见集合框架
16,为什么使用字符流
|-- 字符流是用来操作纯文本文件的,在java中一个字符是用两个字节在表示的,使用字符流操作文本文件更加的方便,也提高了效率
17,数组和集合有什么区别?
|-- 数组是固定长度的,存储的元素必须一致,内存空间是连续的
|-- 集合是可变长度的,在不考虑泛型的情况下可以存储任意类型的元素,而且集合中有更加丰富的对元素进行操作的功能
18,讲讲集合的整个框架以及相关的内容?
|-- 请参见集合框架
19,在枚举种,可以使用抽象方法么?
|-- 可以,但是没有任何实际意义.
20,什么时候会用到泛型?举例说明下
|-- 为了保证集合中元素类型的一致性,就可以使用泛型,例如,要对一个集合中的元素进行排序的话,使用泛型可以避免强制类型转换问题,
还可以使用在方法的参数类型的返回值类型不明确的情况下,可以提高方法的重用性
21,如何获得字节码文件?
|-- 请参见反射和暴力反射
22,讲一讲代理是什么?如何运用
|-- 代理就是为已存在的多个具有相同接口的类添加一些系统功能
例如:计算每个方法的运行时间,异常处理,打印日志文件等..
23,你还知道其他的设计模式么?分别介绍一下
|-- 单例设计模式
|-- 享元设计模式
|-- 代理设计模式
|-- 装饰设计模式
24,java的特点是什么?
|-- 面向对象
|-- 跨平台
|-- 安全性高
|-- 多线程
|-- 支持图形化用户界面
|