面试复习

二、技术题

1.对面向对象的理解是什么,详细说明面向对象三个特点,用生活子的例子描述下什么是面向对象。
       面向对象是基于面向过程的。将功能封装在对象里,调用具备该功能的对象。如:人开门(开门是属于门对象)(如果面向过程:推这个门,门转动)所以面向对象将复杂的事情变得简单。
	   面向对象的三大特征:封装---(通过权限修饰符)将对象的属性和实现细节隐缠起来,仅对外提供公共的访问方式。(提高了重用性,提高了安全性)如电脑的封装。
						  继承---让类与类直接产生了关系,子类继承父类,子类就拥有了父类的属性和方法。(提高了代码的复用性),Java只支持单继承,但支持多层继承。
						  多态---某种事物具有多种表现形式。覆盖和重载都是多态的表现。(多态的出现,大大提高了程序的扩展性)
								 父类的引用指向了自己的子类对象,父类的引用也可以接受子类的对象。

2.重载和覆盖
	重载:子类拥有和父类相同函数名,但参数类型或者参数个数和父类不相同,就会重载。
	覆盖:子类出现和父类一模一样的方法(Overwrite)--子类函数名、参数类型与参数个数和父类一样时,覆盖时,子类方法权限一定要大于等于父类方法权限 .

3.staitc代码块、构造代码块、构造函数的作用与执行顺序,静态代码块的特点与作用,还有静态的作用,静态方法能不能调用非静态方法或成员,为什么?
	static代码块,构造代码块,构造函数。static代码块是随着类的加载而加载进堆内存中。
	静态代码块特点:随着类的加载而执行,并且只运行一次,用于给类初始化
	静态的作用:对对象的共享数据进行单独存储,节省空间。可以直接类名调用。生命周期长,访问有局限性,静态只能访问静态
	静态优先于对象存在,在有静态的时候,非静态还没有被加载到内存,所以不能访问非静态!

4.成员变量与局部变量、构造函数与一般函数 的区别,内部类与匿名内部类?
	成员变量:定义在类中,整个类都可以访问。随对象的建立而建立,存在对象的堆内存中。有默认的初始化值。
	局部变量:定义在局部范围内:如函数内。存在于栈内存中,随作用的范围结束会自动释放空间。没有默认初始化值。
	构造函数:构造函数的函数名和类名一致,没有返回值,对类进行初始化。只给对应的对象初始化。
	构造代码块:给所有的对象进行初始化,
	内部类: 将一个类定义在另一个类的里面。特点:a.内部类可以访问外部类中的成员,包括私有成员。
												b.外部类要访问内部类中的成员必须建立内部类的对象。
			定义在成员位置上时,可以被private static成员修饰符修饰。
			定义在局部位置上时可以直接访问外部类中的成员,同时只可以访问被final修饰的局部类中的局部变量。不能被成员修饰符修饰。
	匿名内部类:前提--内部类必须继承一个接口或者外部类。 就是建立一个带内容的外部类或者接口的子类匿名对象。

5.数组和集合有什么区别?介绍集合类,谈谈集合框架;说下集合类体系Collection,List和Set当中的一些类及区别。介绍Map映射集合及其子类,如何取出Map中的元素?HashMap和Hashtable的区别?
	数组是固定长度的,集合是可变长度的;数组只能存基本数据类型,集合只能存储对象,可以存储不同类型的对象。
	集合框架就是容器对数据存储的方式(各有不同)。集合中存储的都是对象的地址或引用。
	Collection: 是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用子接口List、Set。
    Collections: 是集合框架中的一个工具类。该类中的方法都是静态的。它提供的方法中有可以对List集合进行排序、二分查找等方法。
	Collection集合包括List和Set集合
	Collection
     |---List :集合中元素是有序的,元素可以重复,该集合体系按索引进行操作。
	    |---ArrayList  :底层是数组结构。查询速度快,但增删稍慢。线程不同步。-->可变长度数组,自动50%延长
		|---LinkedList :底层是链表结构。查询稍慢,  但增删快。  线程不同步。-->可变长度数组,自动100%延长
		|---Vector     :底层是数组结构。线程同步,被ArrayList替代了,因为效率低。
	 |---Set  :集合中元素是无序的(存入和取出的顺序不一定一致),元素不可重复,
	    |--HashSet  :底层数据结构是哈希表,是线程不安全的,不同步。
		            (哈希表按哈希值进行存储,如果哈希值相等则判断元素是否相等,如果元素相等则哈希值进行顺延)
		   HashSet是如何保证元素唯一性的呢?
					是通过元素的两个方法,hashCode和equals来完成。
					如果元素的HashCode值相同,才会判断equals是否为true。
					如果元素的hashCode值不同,不会调用equals。
		   注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
		      Object的toString()方法其实调用的是:getClass().getName()+'@'+Integer.toHexString(hashCode());

		|--TreeSet  :可以对Set集合中的元素进行排序,
					底层数据结构的二叉树。 保证元素唯一性的依据:compareTo方法return 0.
			TreeSet排序的第一种方式:
					让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。
					这种方式也成为元素的自然顺序,或者叫做默认顺序。
			TreeSet的第二种排序方式:
					当元素自身不具备比较性时,或者具备的比较性不是所需要的。
					这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。
	怎样取出set集合中的元素?   当然是通过调用iterator()使用迭代器(Iterator)
	怎样取出List集合中的元素?  List集合特有的迭代器。ListIterator是Iterator的子接口。
	Map
		Map集合的特点:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
		Map
		 |--Hashtable:底层是哈希表数据结构,不可以存入null键,null值.该集合是同步的,JDK1.0出现的,效率低
		 |--HashMap:底层是哈希表数据结构。并允许使用null键和null值,该集合是不同步的,JDK1.2出现的,效率高
		 |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序
		1.HashMap: 底层是双列的哈希表,不存储重复元素,存储自定义对象时,必须覆盖HashCode和equals方法.此集合可以运行null键和null值.
		2.TreeMap: 内部使用二叉树算法,可以对存入的元素进行自然顺序的排序
	Map遍历集合: 1.Set<k>  keySet:将map中所有的键存入到Set集合。因为set具备迭代器.
								  所有可以迭代方式取出所有的键。再根据get方法获取每一个键对应的值.
					Map集合的取出原理:将map集合转换成set集合,通过迭代器取出.
				 2.Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中, 而这个关系的数据类型就是Map.Entry
												map→(entrySet,将map集合中的映射关系取出,这个关系就是Map.Entry类型)→Set
												那么关系对象Map.Entry获取到后,就可以通过Map.Entry中的getKey和getValue方法获取关系中的键和值.

17.如何让一个类的对象具有可比性?
	有3种比较方式:Object类是所以类的父类,可以实现Object类的equals()方法,判断返回值是否为ture。
	如果想俩个对象按照某种值来比较大小,也可以实现Object类的hashCode()代码来进行比较。
	也可以定义比较器,让该类实现Comparable接口,覆盖compareTo()方法。

HashSet集合中的内存泄露

6.多线程,如何实现多线程,如何开启多线程;多线程的创建方式.继承Thread类和实现Runnable接口建立线程的区别?为什么要用同步代码块?sleep()和wait()的区别?
	一个进程(一个正在执行中的程序)中可能包含有多条线程(如:迅雷),每个线程就是一个独立的控制单元。多线程的创建方式:1.继承Thead类(a.定义类继承Thread;b.实现run方法;c.调用start方法来启动线程);2.实现Runnable(a.定义类实现Runnable接口;b,覆盖Runnable接口中的run方法。c.通过Thread类建立线程对象。d.将Runnable接口的子类对象作为参数传递给Thread类的构造函数。e.调用Thread的start方法开启线程并调用Runnable接口的子类Run方法);线程的一个特性:随机性。都在抢占CPU的执行权。
 两种线程创建方式的区别: 继承Thread:线程代码存放Thread子类run方法中。 
			实现Runnable: 线程代码存在接口的子类的run方法。可以共享对象中的数据,避免了单继承的局限性。	
	①.同步代码块解决死锁问题:死锁 (当多个线程操作同一个数据的时,会发生死锁)
	②.sleep()和wait()的区别?
		sleep()不会释放对象锁,时间结束,自动恢复线程,有执行权。
		wait()对象释放锁资源,进入等待此对象的等待锁定池,
		当别的线程调用此对象的notify方法(或notifyAll)后此线程就会醒来,进入运行状态。

7.单例模式, 单例的设计模式作用,懒汉式和饿汉式的区别?你还知道其他的设计模式么?分别介绍一下(N个设计模式说下功能等)
	单例设计模式--解决一个类在内存只存在一个对象。
	a.将构造函数私有化。b.在类中创建一个本类对象。c.提供一个方法获得该对象。
	饿汉式:先初始化对象
	懒汉式:方法被调用时才被初始化,特点:延时加载,如果多线程访问时会出现安全隐患。
			可以加同步代码块来解决,用同步代码块和同步函数都行,但是稍微有点低效,用双重判断可以解决低效,加同步的时候锁是该类所属的字节码对象。
			同步函数被静态修饰后同步锁不再是this.而是该类所属的字节码文件。
	其它设计模式:享元模式/工厂模式/单例模式

8.IO字符流复制文件、字节流复制文件、复制文件夹的区别? 为什么使用字符流,说下复制一个文件夹的思路?如何拷贝一个图片?
   如何获得字节码文件?如何使用字节流?什么时候会用到转换流呢?
	字节流(用字节流复制文件,字节流可以复制任何类型的文件)字符流(只能复制文本文件)
	//字节流复制文件夹:
	1.首先要看这个文件夹是否存在,如果不存在则要先新建一个新的文件夹。
	2.获取文件夹中的所有文件的文件名和子文件夹名
	3.将获取的文件名或文件夹名封装成一个File对象。
	4.判断File对象是一个文件还是一个文件夹。如果是文件,就要用复制文件的方式来复制这个文件。
		如果是一个子文件夹,那么在编辑完源和目的路径后递给调用函数本身,重复上面的步骤。
	read()是一个阻塞式的方法,
	/*	拷贝一个图片思路:
	1.用字节读取流对象和图片关联;
	2.用字节流写入流对象创建一个图片文件。用于存储获取到的数据。
	3.通过循环读写,完成数据的存储。
	4.关闭资源。*/
13.什么是递归?
	函数自己调用自己的时候就递归。注意防止死循环,尽量避免溢出。 
  
12.让我描述Properties
	Properties是hashTable的子类,也就是具有Map的特点,它里面存储的键值对都是字符串。
	特点:可以用于键值对形式的配置文件。


9.在枚举中,可以使用抽象方法么?
答:可以使用抽象方法,但是每一个枚举元素必须实现该枚举类中的抽象方法。
	枚举就相当于一个类,其中也可以定义构造方法,成员变量,普通方法和抽象方法。
	枚举元素---必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。
	枚举 ---就是让某个类型的变量的取值只能为若干个固定值中的一个。
	枚举中的静态方法---valueof(Class<T> enumType, String name)--返回带指定名称的指定枚举类型的枚举常量

10.类和结构的区别 委托和事件的区别?

10.内省---是对内部进行检查,主要针对JavaBean进行操作。//使用BeanUtils工具包进行获取和设置属性

10.注解---相当于一种标记,在程序中加了注解就等于为程序打上了某种标记.
		  标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
		  @SuppressWarning 、@Override  / @Deprecated
		  @Retention(SOURCE、CLASS、RUNTIME)//告诉程序说,这个注解要保存到运行时期
		  @Target({ElementType.METHOD,ElementType.TYPE})//告诉编译器,这个注解可以用在方法上,也可以用在类上

11.泛型、泛型的上下限是什么时候用?泛型中定义了一种对象能不能传另一种 (必然不能啊,不过我把向上限定向下限定说了)什么时候会用到泛型?举例说明下
	对于参数化的泛型类型: getClass()方法的返回值和原始类型完全一样.因为程序加载进内存中运行的时候会去泛型化。只要能跳过编译器
	就可以往某个泛型集合中加入其它类型的数据,例如: 用反射得到集合,再用集合的add方法去添加其它类型的数据.
	泛型其实就是一种类型格式,只是这个类型主要是用在集合中,并用<> typeof来接收。
	//泛型限定
		? 通配符。?只能用作引用,不能用它去给其他变量赋值
		泛型的限定;
		? extends E: 可以接收E类型或者E的子类型。上限。
		? super E: 可以接收E类型或者E的父类型。下限
	参数化类型可以引用一个原始类型的对象。
	原始类型可以引用一个参数化类型的对象。
	参数化类型不考虑类型参数的继承关系。Vector<Object> v = new Vector<String>(); //也错误!
	//类型参数的类型推断-----取参数类型的最大公约数

14.反射及暴力反射,反射的概念应用.用反射的方式得到字节码文件中的方法步骤?
  反射就是把Java类中的各种成分映射成相应的java类。如:Method(invoke())、Field(get())、Package、
  ①.构造方法Constructor,用getConstructor(),
  构造方法的放射应用,成员变量的反射应用、成员方法的放射应用
  暴力反射:可强制使用自已看到但不能用的私有变量。
  反射的作用-->实现框架功能,例如做房子和装门窗问题

	第一步: Methord 文件名 = String.class.getMethord(想要得到的方法名,和数据类型.class);
	第二步: 调用Methord方法中的invoke()方法,调用其方法

15.怎样得到字节码文件?
	Class.forName("java.lang.String")的作用:返回字节码文件.
	类名.class
	对象。getClass();

16.类加载器.系统默认的有哪几个类加载器?
   有九个预定义的Class对象:八个基本类型()+一个void
   Class.forName("类名")--的作用?  返回类加载器加载的字节码
   ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。
   类加载器---加载类的工具。当要用到一个类的时候,Java虚拟机首先将类字节码加载进内存,通常字节码的原始信息放在硬盘上的classpath指定的目录下。
   类加载器作用:将.class文件中的内容加载进内存进行处理,处理完后的结果就是字节码。

   Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。
   系统中默认的类加载器:a..BootStrap 类,他是加载java类的工具.
						b.ExtClassLoader 用来加载扩展类.
						c.AppClassLoader 是加载Classpath路径的.

   类加载器的委托机制?---
   当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
		1.首先当前线程的类加载器去加载线程中的第一个类。
		2.如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。 
		3.还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。--每个类加载器加载类时,又先委托给其上级类加载器。
    能不能自己写个类叫java.lang.System ?
	自定义的类加载器必须继承ClassLoader类,继承loadClass方法,并覆盖findClass方法

12.动态代理:如何创建动态代理,代理类可以代理被代理类的所有方法么?一讲代理是什么?如何运用

18.代理和动态代理  代理及其应用,举例说明: 
	代理---就是给具有相同接口的目标类里的各个方法增加一些系统功能.如异常处理、日志等
	代理类的优点---如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换。
	AOP---面向方面编程。就是要使交叉业务模块化。抽取里面相同功能的方法。代理是实现AOP功能的核心和关键技术。
	//动态代理---JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
		JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。

	动态代理机制: 其实动态代理机制最核心的就是InvocationHandler(调用处理器)这个接口InvocationHandler 是代理实例的调用处理程序 实现的接口。
	每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法

19.String里的方法,说几个,都是用来干什么的?String与StringBuffer、StringBuiled的区别?
	获取: int length();  char charAt(int index);   int indexOf(int ch);  int hashCode();
	判断: boolean contains(Str); boolean equals(str); boolean isEmpty();
	转换: String toUpperCase(); String toLowerCase(); int campareTo(str) ;//进行自然顺序的比较,返回>0,<0,=0;
		  char[] toCharArray();//将字符串转换成字节数组; static String valueOf(double);//将基本数据类型转换成字符串;
	替换: String replace(oldchar newchar);//

					  4.equals():判断两个字符串是否相同,复写了Object里的方法
	String是固定长度的
	StringBuffer是长度可变的,可以通过toString()转变成字符串,在单线程中用StringBulider效率低,因为它需要考虑线程安全问题。
	StringBuilder在一般应用中和StringBuffer一样,只是在单线程中用StringBuilder效率高,因为它不考虑线程安全问题。

20.银行系统哪里用到了单例,银行卡上有账号是不是单例(我回答的不是,卡是一个类,这个类有很多账号,也就是很多具体的对象,不知道是否对了)
	银行系统中号码机器这个类用到了单例。号码机器用来对号码管理器进行统一管理的,因为号码管理机器在整个系统中只能有一个,
	所以号码机器这个类必须设计成单例。
	
	由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。
	这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值