文档库 最新最全的文档下载
当前位置:文档库 › 黑马程序员入学面试题

黑马程序员入学面试题

黑马程序员入学面试题
黑马程序员入学面试题

黑马程序员入学面试题

第一部分知识点 (3)

1.面试大概流程 (3)

2.面向对象的理解 (3)

3.面向对象和面向过程的区别 (3)

4.abstract与哪些关键字不能共存为什么 (3)

5.static的特点 (3)

6.类与类、类与接口、接口与接口的关系 (3)

7.final、finally、finalize的区别 (3)

8.什么是多态,多态的好处和弊端 (3)

9. 多态实现的机制 (4)

10.wait()和sleep()的区别 (4)

11.网络编程的三要素 (4)

12.UDP和TCP的区别 (4)

13.什么是暴力反射 (4)

14.反射获取字节码对象方式、创建对象的两种方式 (4)

15.怎么理解反射,反射的应用 (5)

16.对匿名内部类的理解 (5)

17.IO体系 (5)

18.集合体系 (5)

19.线程的创建方式,进程线程的理解 (6)

20. 进程与线程 (6)

21.局部变量和成员变量区别 (6)

22.同步函数与同步代码块的区别 (6)

23.数组和集合的区别 (6)

24. StringBuffer和StringBuilder的区别 (7)

25.String和StringBuffer区别 (7)

第二部分知识点 (7)

26. 说明Java中String str=null与String str=""的区别? (7)

27. 使用运算符"= ="和方法equals() 进行比较对象的区别? (7)

28. 接口和抽象类有何区别? (7)

29. 简述方法的重写与重载 (8)

30. final、finally、finallize有何区别? (9)

31. 编程计算3乘8等于几,什么方法效率更高? (9)

32. 不借用第三方变量,互换两个变量。 (9)

33. 传统for和高级for有什么区别呢? (9)

34. Collection和Colections的区别是什么? (9)

35. 面向对象和面向过程的理解 (10)

36. 线程之间通信的理解 (10)

37. 线程的状态 (11)

38. 数组和集合 (11)

39. String、StringBuffer和StringBuilder (12)

40. 集合 (12)

41. 为什么需要配置path,什么时候需要classpath? (13)

42. IO流 (13)

43. OSI参考模型 (14)

44. abstract与哪些关键字不能共存为什么 (14)

45. static的特点 (14)

46. wait()和sleep()的区别 (14)

47. 网络编程的三要素 (14)

第三部分面试题 (16)

48. collection 和collections的区别。 (16)

49. list, set, map是否继承自collection接口? list,set是map不是。 (16)

50. arraylist和vector的区别。 (16)

51. hashmap和hashtable的区别 (16)

第四部分面试题 (16)

52. 1.写一个卖票的程序。 (16)

53. 用代码实现List和map 存储、取出数据使用泛型 (17)

54. 将用户输入在控制台上的指定路径下所有的.txt文件复制到c盘下随意目录(你

可以自己指定路径)并在复制后将.txt后缀名更改成.java后缀名 (18)

55. throw 和throws关键字的区别: (19)

56. 编译时期异常和运行时异常的区别 (19)

57. 定义异常处理时,什么时候定义try,什么时候定义throws呢? (19)

58. 常见的包、类、接口 (19)

59. 常见异常 (19)

第一部分知识点

1.面试大概流程

(1)自我介绍(2) 几道编程题(3) Java基础知识提问

2.面向对象的理解

面向对象是基于面向过程的。在开发过程中,要完成特定的功能就去找相应的对象,如果找不到就创建相应的对象,使用对象,维护完善对象。

面向对象是基于面向过程的,面向对象是把所需要解决的问题按照一定的规则划分为多个独立的对象,强调的是对象,把功能封装成对象,让对象去调用方法来解决问题。

3.面向对象和面向过程的区别

面向过程强调的是功能行为,分析解决问题所需的步骤,然后用函数把这些步骤一一实现,使用的时候一个一个的调用就可以了。

面向过程就是分析解决问题所需要的步骤,然后用函数把这些步骤一一的实现,使用的时候一个一个的调用就可以了,强调是功能行为,解决问题的步骤,以函数为基础,完成各种操作。

面向对象是基于面向过程的,将功能封装成对象,强调的是具备功能的对象,让对象去调用方法来解决问题。

4.abstract与哪些关键字不能共存为什么

private:私有的方法是不可见的,无法被重写

final:被final修饰的方法是最终方法,无法被重写

static:被static修饰的方法,要随类加载到方法区,由于抽象方法没有方法体所以不能加载

5.static的特点

(1)随着类的加载而加载;优先于对象存在;被所有对象所共享;可以直接被类名所调用。

(2)静态方法只能访问静态成员,非静态方法既可以访问静态也可访问非静态

(3)静态方法中不可以定义this、super关键字,因为静态优先于对象存在,this和super

所代表的对象还没有不存在。

6.类与类、类与接口、接口与接口的关系

继承,继承或实现,继承

7.final、finally、finalize的区别

final:可以修饰类、方法和变量,被final修饰的类无法被继承,方法无法被重写,变量为常量只能赋值一次

finally:异常处理,和try、catch结合使用,可以添加也可以不添加,用于执行一些必须执行的代码,如释放资源等

finalize:Object类中的方法,其中定义了对象要被垃圾收集器回收之前要做的相关的清理工作

8.什么是多态,多态的好处和弊端

多态可以理解为事物存在的多种体现形态。父类的引用指向了自己的子类对象;父类的引用也可以接收自己子类的对象。一个类定义的属性和方法被其他类继承后,可以具有不同

的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。

重写和重载是多态的不同表现形式。

好处:提高了代码的扩展性

弊端:父类的引用只能访问父类中有的成员(父类引用无法调用子类中特有的方法)

9.多态实现的机制

靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。重写、重载是多态性的不同表现。

10.wait()和sleep()的区别

(1)所在的类不同:wait是Object类中的方法,sleep是Thread类中的方法

(2)sleep方法没有释放同步锁,而wait方法释放了同步锁,使得其他线程可以使用同步代码块或者方法。

(3)sleep()必须指定时间,wait()可以指定也可以不指定时间。

(4)wait,notify和notifyAll只能在同步方法或者同步代码块里面使用,而sleep可以在任何地方使用

(5)sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

11.网络编程的三要素

(1)IP:网络中设备的唯一标识

(2)端口:用于标识设备中接收数据的网络应用程序具体是哪一个,有效端口0~65535,0~1024为系统端口及保留端口

(3)传输协议:UDP和TCP协议,信息通讯的规则

12.UDP和TCP的区别

UDP:不需要建立连接,是不可靠协议,将数据及源和目的封装到数据报中,每个数据报限制在64k以内,发送数据较少,速度快

TCP:通过三次握手建立连接通路,是可靠协议,可进行大量的数据传输,效率较低13.什么是暴力反射

java的特性之一就是封装,将对象的属性和具体实现细节隐藏起来,只对外提供公共的方法访问,private修饰的内部属性和方法对我们是不可见的。

我们通过正常的方法是无法获取以及修改的,可是通过反射却可以强制获取并做一些修改,这就破坏了封装性,这就是所谓的暴力反射

14.反射获取字节码对象方式、创建对象的两种方式

获取字节码方式三种:

(1)类名.class,例如:System.class

(2)对象.getClass(),例如:new Date().getClass();

(3)Class.forName("类名"),例如:Class.forName("java.util.Date");

创建对象的两种方式:

(1)直接用字节码创建对象,只能调用默认的构造方法:字节码.newInstance();

(2)获取构造方法Constructor,然后调用构造方法创建,可以通过参数不同调用不同

的构造方式

15.怎么理解反射,反射的应用

在运行状态下,通过类的字节码文件去解剖一个类,使用该类的构造方法、成员变量、成员函数。

反射就是把Java类中的各种成分映射成相应的Java类。

一般情况下我们要解决某个问题,先找到相关的类,创建该类的对象,然后通过该对象调用对应的方法来解决问题。

反射是一个正好相反的过程,开始可能并没有类可以解决这个问题,而我们却先用一个当时可能并不存在的方法解决了这个问题,后来才有的这个类。

这其实就是框架的原理,现有的框架再有的解决问题的类。框架描述了整体,制订了功能方法的规范,具体的实现之后按照这个规范编写。这些都需要靠反射来完成。

使用框架有良好的扩展性,某部分功能的优化不需要涉及程序整体,只需要修改特定的部分就好了,然后通过配置文件,获取对应的类名,就可以了。

16.对匿名内部类的理解

匿名内部类其实是内部类的简写形式。

内部类是定义在类中的类,就好比我们人类,我们人类都有心脏,而心脏又有自己独特组成,可以把心脏也抽象成一个类。

这个心脏类就是人类的内部类。如果要研究某一种心脏疾病,需要一个实例时,我们不需要知道这个患病的心脏到底是谁的,那找到的这个就是匿名的。

匿名内部类必须要继承一个类或实现一个接口,在使用时直接用父类或接口的名称创建了一个子类对象并实现其中的方法,匿名内部类其实是一个匿名的子类对象。

传递参数的时候,需要的是抽象类或者接口的时候,其实需要的是子类或实现类对象,这时可以通过匿名内部类创建。

匿名内部类就是没有名字的内部类,是内部类的简化形式。一般只使用一次的时候使用匿名内部类,匿名内部类本质上是一个匿名子类对象。匿名内部类的使用前提:内部类继承一个类或实现接口。

17.IO体系

字节流InputStream/OutputStream

|--FileInputStream/FileOutputStream:文件字节流,用于文件的读写操作

|--BufferedInputStream/BufferedOutputStream:加缓冲区的字节流,用于提高效率

字符流Reader/Writer

|--FileReader/FileWriter:文件字符流,用于文本文件的读写操作

|--BufferedReader/BufferedWrite:加缓冲区的字符流,用于提高效率转换流InputStreamReader/OutputStreamWriter:是字节流和字符流之间的桥梁配置文件Properties

18.集合体系

|--Collection

|--List:元素是有序的,元素允许重复,因为该集合体系都具有索引

|--ArrayList:底层数据结构是数组,查询速度快,增删操作较慢,线程不同步,数据增长是100%的增长。

|--LinkedList:底层数据结构是链表,查询效率较低,增删操作快,线程不同步

|--Vector:功能同ArrayList类似,底层也是数组,不同是线程是同步的,效率较低,数据增长是50%的增长。

|--Set:元素是无序的,元素不允许重复,底层用到了Map

|--HashSet:底层hash表,存储的对象最好复写hashCode和equals方法,保证元素不会重复

|--TreeSet:底层自平衡的二叉树,存储的对象具备比较性,有两种方法:自然排序、比较器排序

|--Map:数据是以键值对的形式存储的,有的元素存在映射关系就可以使用该集合,元素不允许重复

|--HashMap:允许有null键或值,线程不同步

|--TreeMap:元素可排序

|--HashT able:类似HashMap,不允许有null键或值,线程同步

19.线程的创建方式,进程线程的理解

三种:继承Thread类,实现Runnable接口,实现Callable接口。

20.进程与线程

进程是一个正在执行中的程序,每一个程序都至少有一个执行顺序,该顺序是一个路径,或者叫一个控制单元。

线程是进程中的一个独立的控制单元,线程在控制着进程的执行,是进程的执行路径。进程:正在运行的程序

线程:进程的执行单元,执行路径。

21.局部变量和成员变量区别

成员变量:作用于整个类中,随对象存储在堆内存中,生命周期跟对象一样

局部变量:作用于方法或语句中,方法或语句结束则生命周期结束,存放在栈内存中。

22.同步函数与同步代码块的区别

它们的作用都是封装多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可参与进来。

同步代码块:位置比较灵活,封装了操作共享数据的语句,多个线程中只有持有锁的才可以操作共享数据,需要指定一个对象作为锁,锁可以是任意对象,但必须是同一对象。

同步方法:声明方法时加synchronized关键字修饰,同步函数使用的锁是this,持有锁的线程调用这个方法时其他线程无法调用。静态方法的锁是类的字节码文件。

23.数组和集合的区别

A:长度区别

数组的长度固定

集合长度可变

B:内容不同

数组存储的是同一种类型的元素

而集合可以存储不同类型的元素

C:元素的数据类型问题

数组可以存储基本数据类型,也可以存储引用数据类型

集合只能存储引用类型

24.StringBuffer和StringBuilder的区别

StringBuffer是线程安全的,StringBuilder是线程不安全的,所以效率比起来StringBuilder要比StringBuffer快。

一般单线程的程序使用StringBuilder比较好,多线程的情况下可以自己加锁,也可以直接使用StringBuffer

25.String和StringBuffer区别

String对象一经创建就不会发生变化了,即便是赋新值也不是在原对象的基础上改变,而是创建一个新的字符串对象,将引用指向这个新的对象,会造成空间的浪费,效率较低StringBuffer只创建一个对象,是在同一个实例的基础之上追加,效率更高,当需要用到String的时候toString就可以了

第二部分知识点

26.说明Java中String str=null与String str=""的区别?

String str = null 表示声明了一个String对象的引用str,但是没有为其分配内存空间。

String str = "" 表示创建了一个长度等于0的空字符串,并在内存中为其分配了内存空间。

String str = new String("tw"); str在内存中有两个对象,1.堆内存有一个new Sting 2.常量池中有一个字符串。

27.使用运算符"= ="和方法equals() 进行比较对象的区别?

使用"= ="算符比较基本数据类型时,比较的是值相等;使用"=="算符比较对象时,比较的是内存地址值

使用equals()方法比较对象时,比较的是对象的内容,与地址无关,如果没有重写equals()方法就直接调用的是Object的equals()方法。

28.接口和抽象类有何区别?

(1)成员特点:

构造方法:接口没有构造方法;抽象类有构造方法。

成员变量:接口中只有常量;抽象类中可以是常量,也可以是变量。

成员方法:接口中只有抽象方法;抽象类中既有抽象方法,也有非抽象方法。

(2)关系特点:

类与类:类与类之间只有单继承,可以有多层继承。

类与接口:类与接口之间是实现关系,可以单实现,也可以多实现。

接口与接口:接口与接口之间是继承关系,可以单继承,也可以多继承。

(3)设计理念:

接口对应的设计模式是简单工厂设计模式,它被实现,这个接口中定义的是整个体现的扩展内容,体现:like a。

抽象类对象的设计模式是模板设计模式,它被继承,这个类中定义的是整体体现的共性内容,显现is a。

(4)抽象关键字abstract和哪些不可以共存?final , private , static

(5)必须实现抽象类或接口的所有抽象方法才可以实例化。

(6)继承extends,实现implements

29.简述方法的重写与重载

重写是指子类重新实现父类中的方法,方法声明不变,方法体改变。在运行过程中,如果将子类创建的对象赋值给子类的引用或父类的引用,则无论通过哪个类型的引用,真正调用的方法都将是在子类中重写的方法。如果希望调用父类中的方法,则需要通过父类创建类的实例,然后通过该实例才能访问父类定义的方法。重写方法是实现多态的一个重要表现。

在Java中,一个类的内部可以定义多个同名的方法,但是它们的方法参数要有所不同。重写的是与父类同名的方法,与返回值有关。重载是同名方法,与返回值无关,与参数有关,如:个数、类型、排列。

重写注意事项:

(1)父类中的私有方法不可以被重写

(2)子类方法访问权限一定要大于父类的访问权限

(3)静态的方法只能被静态的方法重写,这个其实不能算对象的关系。

30.final、finally、finallize有何区别?

final表示一个修饰符,如果用它来修饰一个类,则该类是不能继承的;如果用它来修饰一个变量,则该变量一旦赋值之后就不能再修改;如果用它来修饰一个方法,则该方法不能够被重写。

finally用于异常处理,它用来修饰一个代码块,即使前面的代码处理异常,该代码块中的代码也会执行。它通常用于释放资源。finally代码块之前有调用System.exit()方法的话,finally里面的代码就不会执行。

finallize表示Object类中定义的一个方法,他可以重写,用于回收资源。

31.编程计算3乘8等于几,什么方法效率更高?

位运算的方法效率更高。编程运算其实质是二进制的运算,运用位运算的方法移动后补位即可得结果,比一般的3*8更高效。

32.不借用第三方变量,互换两个变量。

n=11,m=3

(2)n=n^m;

m=n^m;//(n^m)^m一个数异或另一个数两次,还是得原来那个数

n=n^m//n^(n^m)

小编强力推荐第二种方法,这是提升逼格的强劲手段。当面试官问你这个问题,你跟他拓展到位移运算,你的背后就会出现万丈光芒,那时你就会神一样存在在面试官的心里。

33.传统for和高级for有什么区别呢?

1.增强for对集合进行遍历,集合不能为空。只能获取集合元素,但是不能对集合进行操

作。高级for有一个局限性,必须要有被遍历的目标。

2.迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中进行增删改查的动作。

建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义角标。

1.增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,但是增强for循环有些缺点,例如不能在增强循环里动态的删除集合内容。不能获取下标等。

2.ArrayList由于使用数组实现,因此下标明确,最好使用普通循环。

3.而对于LinkedList由于获取一个元素,要从头开始向后找,因此建议使用增强for 循环,也就是iterator。

34.Collection和Colections的区别是什么?

Collection是一个单列集合的顶层接口,它是List、Set、Queue等接口的父接口。在这个接口中,定义了集合类中通用的方法。

Collections是针对集合操作的工具类,有对集合进行排序和二分查找等静态方法。35.面向对象和面向过程的理解

面向对象时相对面向过程而言的。比如说:人坐地铁去上班。人面向地铁这个对象,地铁拥有运输的功能,人通过地铁调用这个功能,只重结果,不重于过程。面向过程就如我们开门,锁孔对齐,门轴转动,门才开了,相对于结果,侧重于过程。

曾经跟朋友聊对面向对象,我说就像搭积木,找到需要的,一个一个往上累;她说这就是JAVA方便之处。

(1)面向过程是以函数为基础,完成各种操作,强调的是过程,例如:C语言;

(2)面向对象以对象为基础,完成各种操作,强调的是对象和结果。

(3)面向对象是基于面向过程的。

面向对象的特点是:

(1)是一种个符合人们思考习惯的思想

(2)把复杂的事情简单化

(3)把我们从执行者变成了指挥者

举例:老师您口渴想喝茶,如果你自己去拿杯子,放茶叶,

接水这些是面向过程的;但这时您恰好知道我是个打水小能手,

又正好我很尊敬您,一见如故、一见钟情啥的,很愿意帮您去泡茶。

您调用我帮您泡茶,使用我的拿杯子、放茶叶、接水等方法。

您由执行者上升到了指挥者,让泡茶这件事更简单化。

36.线程之间通信的理解

其实,Java提供了3个非常重要的方法来巧妙地解决线程间的通信问题。

这3个方法分别是:wait()、notify()和notifyAll()。

它们都是Object类的最终方法,因此每一个类都默认拥有它们。

虽然所有的类都默认拥有这3个方法,但是只有在synchronized关键字作用的范围内,并且是同一个同步问题中搭配使用这3个方法时才有实际的意义。

这些方法在Object类中声明的语法格式如下所示:

final void wait() hrows InterruptedException

final void notify()

final void notifyAll()

调用wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行态退出,进入等待队列,直到被再次唤醒。

调用notify()方法可以唤醒等待队列中第一个等待同一共享资源的线程,并使该线程退出等待队列,进入可运行态。

调用notifyAll()方法可以使所有正在等待队列中等待同一共享资源的线程从等待状态退出,进入可运行状态,此时,优先级最高的那个线程最先执行。

显然,利用这些方法就不必再循环检测共享资源的状态,而是在需要的时候直接唤醒等待队列中的线程就可以了。这样不但节省了宝贵的CPU资源,也提高了程序的效率。

由于wait()方法在声明的时候被声明为抛出InterruptedException异常,因此,在调用wait()方法时,需要将它放入try…catch代码块中。此外,使用该方法时还需要把它放到一个同步代码段中,否则会出现如下异常:

"https://www.wendangku.net/doc/3a25446.html,ng.IllegalMonitorStateException: current thread not owner"

37.线程的状态

线程的五种状态:

1)新建(new) 用new语句创建的线程对处于新建状态,此时它和其它Java对象一样,仅仅在Heap中被分配了内存。当一个线程处于新建状态时,它仅仅是一个空的线程对象,系统不为它分配资源。Thread t = new Thread(new Runner());

2)就绪(Runnable) 程序通过线程对象调用启动方法start()后,系统会为这个线程分配它运行时所需的除处理器之外的所有系统资源。这时,它处在随时可以运行的状态,在随后的任意时刻,只要它获得处理器即会进入运行状态。t.start()

3)运行(Running) 处于这个状态的线程占用CPU,执行程序代码。在并发环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于这个状态。如果计算机中有多个CPU,那么同一时刻可以让几个线程占用不同的CPU,使它们都处于运行状态,只有处于就绪状态的线程才有机会转到运行状态。

4)阻塞(Blocked) 阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到运行状态。

阻塞状态可分为以下3种:

位于对象等待池中的阻塞状态(Blocked in object's wait pool):当线程处于运行状态时,如果执行了某个对象的wait()方法,Java虚拟机就会把线程放到这个对象的等待池中。

位于对象锁池中的阻塞状态(Blocked in object's lock pool):当线程处于运行状态,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池中。

其他阻塞状态(Otherwise Blocked):当前线程执行了sleep()方法,或者调用了其他线程的join()方法,或者发出了I/O请求时,就会进入这个状态。当一个线程执行System.out.println()或者System.in.read()方法时是,就会发出一个I/O请求,该线程放弃CPU,进入阻塞状态,直到I/O处理完毕,该线程才会恢复执行。

5)死亡(Dead) 当线程退出run()方法时,就进入死亡状态,该线程结束生命周期。线程有可能是正常执行完run()方法而退出,也有可能是遇到异常而退出。不管线程是正常结束还是异常结束,都不会对其他线程造成影响。

38.数组和集合

1)数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。

2)数组要声明元素的类型,集合类的元素类型却是object。

数组转成集合注意事项:

1.不能使用集合的增删方法。因为数组长度不能改变,其它方法可以使用;

2.如果数组中的元素是引用数据类型,转成集合时,数组元素直接作为集合的元素;如果数组中的元素是基本数据类型,转成集合时,会将数组作为集合中的元素。

39.String、StringBuffer和StringBuilder

1)在执行速度方面的比较:StringBuilder > StringBuffer

2)StringBuffer与StringBuilder,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。

3)StringBuilder:线程非安全的,是线程不同步的(JDK1.5后出现)

StringBuffer:线程安全的,是线程同步的

4.什么时候使用字符串缓冲区:数据多,个数无所谓确定,类型无所谓确定,只要最后都转变成字符串,就用字符串缓冲区。

对于三者使用的总结:

1)如果要操作少量的数据用String

2)单线程操作字符串缓冲区下操作大量数据StringBuilder

3)多线程操作字符串缓冲区下操作大量数据StringBuffer(多线程中通常不建议使用StringBuffer,最好使用StringBuilder然后自己加同步)

40.集合

集合名称阅读技巧:

JDK1.2出现的集合框架中常用的子类对象

前缀名是结构名,后缀名是体系名。

ArrayList:数组结构,看到Array就知道查询速度快,看到List就知道可以又重复元素,可以增删改查

LinkedList:链表结构,增删快

HashSet:哈希结构,查询速度更快,不保证有序,不可以重复,必须覆盖hashCode和equals方法

LinkedHashSet:链表加哈希结构,可以实现有序

TreSet:二叉树结构,可以排序。有两种方法:1.自然排序compable,2.比较器comparator Java提供了只包含一个compareTo()方法的Comparable接口。这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。

Java提供了包含compare()和equals()两个方法的Comparator接口。compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等。只有当输入参数也是一个comparator并且和当前comparator的排序结果是相同的时候,这个方法才返回true.

ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,允许直接按序号索引元素. 但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,

Vector由于使用了synchronized 方法(线程安全),通常性能上较ArrayList 差,Vector属于遗留容器,现在已经不推荐使用,

LinkedList 使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,其实对内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

由于ArrayList和LinkedListed都是非线程安全的,如果需要多个线程操作同一个容器,可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这其实是装潢模式最好的例子,将已有对象传入另一个类的构造器中创建新的对象来增加新功能)。

Map集

Map(k,v)k:此映射所维护的键的类型v:映射值的类型

Map集合:双例集合,一次存一对,称为键值对。要保证键的唯一性。

Map集合没有迭代器,必须先将map集合转成set集合,在使用迭代器,就可以取出结合中的元素;或者使用map集合特有的entrySet方法,也可以取出map集合中虽有元素。Map集合常见子类:

1.HashTable:底层数据结构是哈希表结构,线程同步的,不允许null键,null值;

2.HashMap:哈希表结构,不同步,允许null键,null值;

3.TreeMap:二叉树结构,不同步,可以对map集合众多键进行排序。

41.为什么需要配置path,什么时候需要classpath?

答:path路径:是操作系统的环境变量,目的是希望在任意目录下都能执行该命令操作起来更加方便快捷;

classpath是给类提供路径:想在其他目录下执行java程序时需要配置classpath路径。

42.IO流

输入流:InputStream 输出流:OutputStream

字节输入流:FileInputStream 字节输出流:FileOutoutStream

字节输入流缓冲区:BufferedInputStream 字节输出流缓冲区:BufferedOutputStream

转换流:InputStreamReader 字符输出流:OutputStreamWriter

字符流:FileReader FileWriter

字符输入流缓冲区:BufferedReader 字符输出流缓冲区:BufferedWriter

43.OSI参考模型

一共7层:1.物理层;2.数据化链路层;3.网络层ip;4.传输层tcp\udp;5.会话层;6.表示层;7.应用层http

物理层:定义物理设备标准,作用:传输比特流。这一层的数据叫做比特;

数据化链路层:接受物理层的数据对MAC地址(网卡地址)进行封装与解封装,工作设备:交换机,这一层的数据叫做帧;

网络层:对下面接受的数据进行IP地址的封装与解封装,工作设备:路由器,这一层的数据叫做数据包;

传输层:定义一些数据协议和端口号,对下面接收的数据进行分段和传输,到达目的后进行重组,这一层的数据叫做段;

会话层:通过传输层建立数据传输的通路;

表示层:对接收的解释进行加密和解密,封装和解封装;

应用层:终端应用,FTP(各种文件下载)。

TCP(传输控制协议):传输效率低,可靠性高,用于操作可靠性要求高,数据量小的数据;

UDP(用户数据协议):传输效率高,可靠性低,用于操作可靠性要求低,数据量大的数据。

44.abstract与哪些关键字不能共存为什么

final:1.被final修饰的类不可以有子类;2.被final修饰的方法不可以被覆盖;private:1.成员方法私有化,子类不能访问;2.private私有化的,不可以被覆盖static:被static修饰的方法,可以直接通过类名方式调用,但调用抽象方法没有意义45.static的特点

1.被静态修饰的成员,可以直接通过类名方式调用;

2.静态成员优先与对象存在;

3.静态成员随着累的加载而出现

注意事项:

1.静态只能访问静态;

2.静态方法中不能出现this和super关键字;

3.主函数是静态函数

46.wait()和sleep()的区别

1. wait()是object类中的方法,可以指定时间,也可以不指定时间;sleep()是Thread 类中的方法,必须指定时间;

2. wait()释放资源,释放锁;sleep()释放资源,不释放锁。

3、sleep必须捕获异常,wait不需要捕获异常

47.网络编程的三要素

(1)IP:网络中设备的标识

(2)端口:用于标识设备中接收数据的网络应用程序具体是哪一个,有效端口

0~65535,0~1024为系统端口及保留端口

(3)传输协议:UDP和TCP协议,信息通讯的规则

23.什么是多态,多态的好处和弊端

多态可以理解为事物存在的多种体现形态。父类的引用指向了自己的子类对象;父类的引用也可以接收自己子类的对象。

好处:提高了代码的扩展性

弊端:父类的引用只能访问父类中有的成员(父类引用无法调用子类中特有的方法) 24.什么是暴力反射

我们知道java的特性之一就是封装,将对象的属性和具体实现隐藏起来,只对外提供公共方法访问,private修饰的内部属性和方法对我们是不可见的。

我们通过正常的方法是无法获取以及修改的,可是通过反射却可以强制获取并做一些修改,这就破坏了封装性,这就是所谓的暴力反射

25.反射获取字节码对象方式、创建对象的两种方式

获取字节码方式三种:

(1)类名.class,例如:System.class

(2)对象.getClass(),例如:new Date().getClass();

(3)Class.forName("类名"),例如:Class.forName("java.util.Date");

创建对象的两种方式:

(1)直接用字节码创建对象,只能调用默认的构造方法:字节码.newInstance();

(2)获取构造方法Constructor,然后调用构造方法创建,可以通过参数不同调用不同的构造方式

26.怎么理解反射,反射的应用

反射就是把Java类中的各种成分映射成相应的Java类。

一般情况下我们要解决某个问题,先找到相关的类,创建该类的对象,然后通过该对象调用对应的方法来解决问题。

反射是一个正好相反的过程,开始可能并没有类可以解决这个问题,却先用一个当时可能并不存在的方法解决了这个问题,后来才有的这个类。

这其实就是框架的原理,先有的框架再有解决问题的类。框架描述了整体,制订了功能方法的规范。这些都需要靠反射来完成。

使用框架有良好的扩展性,某部分功能的优化不需要涉及程序整体,只需要修改特定的部分就好了,然后通过配置文件,获取对应的类名,就可以了。

27.同步函数与同步代码块

它们的作用都是封装多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可参与进来。

同步代码块:位置比较灵活,多个线程中只有持有锁的才可以操作共享数据,需要指定一个对象作为锁

同步方法:声明方法时加synchronized关键字修饰,同步函数使用的锁是this,持有锁的线程调用这个方法时其他线程无法调用。

第三部分面试题

48.collection 和collections的区别。

collections是个java.util下的类,是操作集合的工具类,可以对集合进行查找、排序、安全化,它包含有各种有关集合操作的静态方法。

collection是个java.util下的接口,它是各种集合结构的父接口。

49.list, set, map是否继承自collection接口? list,set是map不是。

50.arraylist和vector的区别。

一.同步性:vector是线程安全的,也就是说是同步的,而arraylist是线程序不安全的,

不是同步的

二.数据增长:当需要增长时,vector默认增长为原来一培,而arraylist却是原来的一半

51.hashmap和hashtable的区别

一.历史原因:hashtable是基于陈旧的dictionary类的,hashmap是java 1.2引进的map 接口的一个实现

二.同步性:hashtable是线程安全的,也就是说是同步的,而hashmap是线程序不安全的,不是同步的

三.值:只有hashmap可以让你将空值作为一个表的条目的key或value

第四部分面试题

52.1.写一个卖票的程序。

1)写一个类,该类实现了Runnable接口。有一个私有类型的int型的参数:tickets。票

的总数,为100,完成run方法,输出结果的格式如下:

2)当前窗口为:窗口a ,剩余的票数为:19,其中窗口a为线程的名称。

3)开启四个卖票窗口(起四个线程),同时执行卖票的程序。

public class SellTicketDemo {

public static void main(String[] args) {

SellTicket st = new SellTicket(new Ticket());

new Thread(st,"窗口1").start();

new Thread(st,"窗口2").start();

new Thread(st,"窗口3").start();

new Thread(st,"窗口4").start();

}

}

class SellTicket implements Runnable {

private Ticket t;

public SellTicket(Ticket t) {

this.t = t;

}

@Override

public void run() {

while (t.getTickets() > 0) {

t.sellTicket(new Random().nextInt(5) + 1);

}

}

}

//车票类

class Ticket {

private int tickets = 100;//车票的整数是100张

public int getTickets() {//获取车票的余数

return tickets;

}

public synchronized void sellTicket(int num) {//售票

if (tickets >= num) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

tickets -= num;

System.out.println(Thread.currentThread().getName() + "卖出" + num

+ "张票,余票为:" + tickets);

} else {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("余票不足");

}

}

}

53.用代码实现List和map 存储、取出数据使用泛型

54.将用户输入在控制台上的指定路径下所有的.txt文件复制到c盘下随意目录(你可以自

己指定路径)并在复制后将.txt后缀名更改成.java后缀名

public class Test1 {

public static void main(String[] args) throws IOException {

// 封装目录

File srcfile = new File(“d:\\test”);

File desfile = new File("d:\\demo");

if (!desfile.exists()) {

desfile.mkdir();

}

File[] fileArray = srcfile.listFiles(new FilenameFilter() {

@Override

public boolean accept(File file, String name) {

return new File(file, name).isFile() && name.endsWith(".txt");

}

});

for (File file : fileArray) {

// d:\\demo\\a.mp3

File newfile = new File(desfile, file.getName());

copyFile(file, newfile);

}

// 在目的地下改名

File[] files = desfile.listFiles();

for (File file : files) {

File newfile = new File(desfile, file.getName().replace(".txt",".java"));

file.renameTo(newfile);

}

}

//复制文件

private static void copyFile(File file, File newfile) throws IOException { //封装数据源,高效流

BufferedInputStream bis = new BufferedInputStream(new FileInputStream( file));

//封装目的地,高效流

BufferedOutputStream bos = new BufferedOutputStream(

new FileOutputStream(newfile));

//一次复制一个字节数组

byte[] bys = new byte[1024];

int len = 0;

while ((len = bis.read(bys)) != -1) {

bos.write(bys, 0, len);

bos.flush();

}

//释放资源

bos.close();

bis.close();

}

}

55.throw 和throws关键字的区别:

(1)throw用于抛出异常对象,后面跟的是异常对象;throw用在方法体内。

(2)throws用于抛出异常类,后面跟的异常类名,可以跟多个,用逗号隔开。throws用在

方法上。

(3)异常处理方式:抛出、捕捉try-catch-finally

56.编译时期异常和运行时异常的区别

1.编译被检查的异常在函数内被抛出,函数必须要声明,否编译失败。

声明的原因:是需要调用者对该异常进行处理。

必须进行处理,否则无法编译通过。

2.运行时异常如果在函数内被抛出,在函数上不需要声明。

不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理的,直接让程序停止,由调用者对代码进行修正。

57.定义异常处理时,什么时候定义try,什么时候定义throws呢?

功能内部如果出现异常,如果内部可以处理,就用try;

如果功能内部处理不了,就必须声明出来,让调用者处理。

58.常见的包、类、接口

(1)常用的类:BufferedReader BufferedWriter FileReader FileWirter String Integer

java.util.Date,System,Class,List,HashMap

(2)常用的包:https://www.wendangku.net/doc/3a25446.html,ng、java.io、java.util、java.sql 、javax.servlet、org.apache.strtuts.action、

org.hibernate

(3)常用的接口:List、Map、HttpSession、Servlet、HttpServletRequest、Comparable

59.常见异常

二.简答题(每题5分)

1. 简述JRE与JDK的区别?

答案:

JRE: Java Runtime Environment; Java运行环境,包括jvm虚拟机和Java核心类库,面向用户

JDK: Java Development Kit; Java开发工具包,包括Java编译器,Java运行工具,Java 文档生成工具,Java打包工具,面向开发者。

2. &和&&有什么区别?

答案:

&: 与,不管左右两边结果如何,都会运行;

&&:短路与,左边为False,则右边不会运行。

3. 什么是方法的重载?

答案:

在同一个类中,允许一个以上的同名函数,只要他们的参数类型或者参数列表不同即可。

4.说说continue和break的区别?

答案:

continue: 只用于循环语句,跳出本次循环继续下次循环。

break: 用于switch语句和循环语句,结束循环语句。

三.编程题2题(每题10分)

1. 设计一个方法,取名叫getCount用来计算出1-100之间有多少能被3整除,要求有返回值,并把结果打印在控制台上.

class ThreeDemo

{

public static void main(String[] args)

{

int c = getCount();

System.out.println("个数是:"+c);

}

public static int getCount()

{

int x = 0;

for(int i = 1;i<=100;i++)

{

int r = i % 3;

相关文档