Java程序员面试题(基础篇)(三)

1、 Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

  • 方法的重写 Overriding 和重载 Overloading 是 Java 多态性的不同表现。重写 Overriding 是父类与子类之间多态性的一种表现,重载 Overloading 是一个类中多态性的一种表现。
  • 如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的 定义如同被”屏蔽”了。
  • 如果在一个类中定义了多个同名的方法,它们或有不同的参数个数,或有不同的参数类型,则称为方法的重载(Overloading)。
  • Overloaded 的方法是可以改变返 回值的类型。

2、Collection 和 Collections 的区别。

  • Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.
  • Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

3、java 中有几种类型的流?JDK 为每种类型的流提供了 一些抽象类以供继承,请说出他们分别是哪些类?

  • 字节流,字符流 。
  • 字节流继承于 InputStream OutputStream ,
  • 字符流继承于 InputStreamReader OutputStreamWriter。
  • 在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。

4、error 和 exception 有什么区别 ?

  • error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
  • exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

5、父类子类多态关系

A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

  • 类的继承具有传递性,子类可以通过向上转型的方式无条件地赋值给父类对象;
  • 父类通过向下转型赋值给子类时,必须通过强制类型转换。

6、Math中floor、ceil、round方法区别

  • floor: 求小于参数的最大整数。返回double类型 n. 地板,地面 例如:Math.floor(-4.2) = -5.0
  • ceil:求大于参数的最小整数。返回double类型 vt. 装天花板 例如:Math.ceil(5.6) = 6.0
  • round: 对小数进行四舍五入后的结果。返回int类型 例如:Math.round(-4.6) = -5

7、list是一个ArrayList的对象,如何在Iterator遍历的过程中正确并安全的删除一个list中保存的对象?

  • Iterator 支持从源集合中安全地删除对象,只需在 Iterator 上调用 remove() 即可。
  • 这样做的好处是可以避免 ConcurrentModifiedException ,当打开 Iterator 迭代集合时,同时又在对集合进行修改。
  • 有些集合不允许在迭代时删除或添加元素,但是调用 Iterator 的remove() 方法是个安全的做法。

8、jsp中静态include和动态include的区别

  • 静态的include:是jsp的指令来实现的,< %@include file=”xx.html”%> 是共享request请求域,先包含再编译,不检查包含页面的变化。不允许有相同的变量。 是在翻译阶段执行。
  • 动态的include:是jsp动作来实现的, 是不共享request请求域,先编译在包含,是要检查包含页面的变化的。在请求处理阶段执行。

9、Servlet的生命周期可以分为初始化阶段,运行阶段和销毁阶段三个阶段

  • init():仅执行一次,负责在装载Servlet时初始化Servlet对象
  • service() :核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
  • destory():在停止并且卸载Servlet时执行,负责释放资源

10、线程与进程的区别?

  • 地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  • 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  • 调度和切换:线程上下文切换比进程上下文切换要快得多。
  • 在多线程OS中,进程不是一个可执行的实体。

Java程序员面试题(基础篇)(二)

1、自增前置和后置操作符

  • ++i 在程序执行前进行自增
  • i++ 在程序执行完毕后自增

2、String,StringBuilder,StringBuffer 区别

  • String 是不可变类,线程安全的, 对象一旦被创建,字符串的内容将不能被改变。
  • StringBuffer 是可变类,线程安全的,当对象被创建后,仍然可以对字符串的内容进行修改。
  • StringBuilder是可变类,非线程安全的,当对象被创建后,仍然可以对字符串的内容进行修改 。
  • 执行效率:StringBuilder > StringBuffer > String

3、线程中方法

  • wait():使线程暂停执行的方法,如果线程对一个同步对象发出了一个 wait()调用请求,那么该线程会暂停执行,被调对象进入等待状态,直到被唤醒(通常使用 notify()唤醒)或等待时间超时。
  • sleep():使当前运行的线程休眠指定的时间。
  • stop():终止线程的执行,会释放已经锁定的所有的监视资源。
  • suspend():将一个线程挂起(暂停),并且不会自动恢复,必须通过调用对应的resume(),才能使得线程重新进入可执行状态。

4、 Hashtable和HashMap 相同点和区别

相同点:

  • 都是键值对(key-value)形式
  • 都实现了 Map 接口

区别:

  • HashMap允许空(null)键值(key)(注意,最多只允许一条记录的键为null),而Hashtable不允许。
  • Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。
  • Hashtable 的方法是线程安全的,而 HashMap 不是线程安全的。所以效率上HashMap可能高于Hashtable。
  • 由于Hashtable是线程安全的,没有采用快速失败机制;HashMap是非线程安全,迭代HashMap 采用了快速失败机制。
  • 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
  • Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

快速失败(fail-fast)是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,可能会产生 fail-fast事件。例:两个线程(线程1与线程2)当线程1通过 Iterator(迭代器)在遍历集合A中的元素,如果线程2修改了集合A(删除或增加新的元素),这个时程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast事件。

5、变量名、方法名和数组命名规范

  • 只有由字母,数字,下划线和$组成
  • 并且第一个字符只能是 字母,下滑线或$

6、List<? extends T>List<? super T>区别

  • <? extends T>表示类型的上界,参数化的类型可能是 T 或者 T 的子类。
  • <? super T>表示类型的下界,参数化的类型可能是 T 或者 T 的父类。

7、final,finally 和 finalize 有什么区别

  • final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
  • finally 是异常处理语句结构的一部分,表示总是执行,try catch finally。
  • finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

8、equals 和==的区别

  • equals 比较引用对象类型内容,对象需要 override 覆写。
  • == 基本类型,比较的是栈内存地址。

9、Java默认序列化如何去做,哪些字段不会被序列化

  • 序列化的实现:将需要被序列化的类实现 Serializable 接口,该接口没有需要实现的方法,默认序列化机制。
  • 使用默认机制,在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化,同样地,这些其它对象引用的另外对象也将被序列化,以此类推。所以,如果一个对象包含的成员变量是容器类对象,而这些容器所含有的元素也是容器类对象,那么这个序列化的过程就会较复杂,开销也较大。
  • 对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。
  • static和transient字段不能被序列化。

10、Vector、ArrayList和LinkedList 有什么特点

相同点

  • 都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组

不同点

  • ArrayList 是线程序不安全的,它的元素可以通过get/set方法直接访问。
  • Vector 是线程安全的,和ArrayList类似。
  • LinkedList 是线程序不安全的,一个双链表,允许所有元素(包括 null)。在添加和删除元素时具有比ArrayList更好的性能。但在get与set方面弱于ArrayList。当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比。它还实现了 Queue 接口,该接口比List提供了更多的方法,包括 offer()、peek()、poll()等。

参考资料 https://zhuanlan.zhihu.com/p/34828859

Java程序员面试题(基础篇)(一)

1、方法修饰符访问级别

  • public > default > protected > private

2、修饰符的使用范围

3、常见Java容器类型区别

4、接口和抽象类的相同和不同点

相同点:

  • 都不能被实例化
  • 只有在实现或继承后实现类或子类才能实例化

不同点:

  • 关键字:实现接口implements;继承抽象类 extends。
  • 关系:接口可以有多个实现类;抽象类只能有一个继承类。
  • 成员变量:接口只能是public static final修饰的,且必须赋初值;抽象类可以是public,default,protected,private修饰的。
  • 成员方法:接口只能public abstract修饰的;抽象类可以是public abstract的抽象方法,也可以是其他正常方法。

5、Object类中方法

6、原始类型 (8种)

  • 浮点型:float,double(包装类:Float,Double)
  • 布尔型:boolean(包装类:Boolean)
  • 字符型:char(包装类:Character)
  • 数值型:byte,short,int,long(包装类:Byte,Short,Integer,Long)

7、实现多线程的方法

  • 继承Thread类,重写run方法
  • 实现Runnable接口,实现run方法
  • 实现Callable接口,重写call方法

8、什么是不可变量类,包括哪些

  • 不可变类:是指创建实例之后,就不允许修改它的值,只允许读操作
  • 基本类型的包装类:Short, Integer, Long, Float, Double, Byte, Character, Boolean
  • 此外String类等

参考资料: https://www.cnblogs.com/jaylon/p/5721571.html https://www.zhihu.com/question/20618891

9、关键字功能介绍

static

  • 为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。
  • 在不创建对象的情况下,可以通过类来直接调用方法或使用类的属性。
  • 被static修饰的属性(方法)是类的属性(方法),不属于任何对象。

synchronized

  • 主要用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块时,同一时刻最多只有一个线程执行这段代码。

serialize

  • 序列化,将对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
  • 在网络上传送对象的字节序列。

对象的序列化指的是把对象转换为字节序列的过程。 对象的反序列化指的是把字节序列恢复为对象的过程。

transient

  • 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
  • transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
  • 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

volatile

  • 保证变量对所有的线程的可见性,即当一个线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。
  • 禁止编译器 指令重排优化。

final

  • 修饰类,表明这个类不能被继承(断子绝孙类)。
  • 修饰方法,这个方法不能被子类重写。
  • 修饰变量,如果是基本数据类型的变量,则其数值一旦被初始化之后便不能更改,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

supper

  • 调用父类的构造方法、父类的方法和属性

this

  • 调用当前对象的某个方法或某个成员时

10、构造方法

  • 类中的构造方法是可以省略的,当省略的时候,编译器会提供一个默认的构造方法以供使用。
  • 构造方法必须与类名相同。
  • 构造方法可以重载,一个类可以定义多个构造方法。
  • 当一个对象被 new的时候必定会调用构造方法。