Java笔试面试之Java与Web基础

以下是笔者总结的Java笔试面试题中Java与Web基础部分,答案为笔者自己总结得出,未必完全正确,仅供参考

1.基本数据类型有哪些

(1) 占1个字节的:byte 和 boolean
(2) 占2个字节的:short 和 char
(3) 占4个字节的:int 和 float
(4) 占8个字节的:long 和 double

2.自动拆箱和自动装箱

(1) 自动拆箱是包装类型自动转成基本数据类型
(2) 自动装箱是基本数据类型自动转成包装类型

3.基本数据类型和包装类型的区别

(1) 基本数据类型有不同的默认值,不能存储null。包装类型的默认值都是null
(2) 基本数据类型存放在中。包装类型的对象存放在
(3) 基本数据类型在定义变量时可以自动转型(比如定义long存储int可以不用加L)。包装类型不能自动转型
(4) 基本数据类型不能调用方法。包装类型可以调用方法
(5) 包装类型占用的空间比基本数据类型大

4.HashMap存储函数的实现

(1) 计算出key的两次哈希后的值
(2) 把哈希值和长度减1进行按位与操作,计算出下标
(3) 如果对应的位置没有元素,那么直接把键值对放在这个位置
(4) 如果对应位置有元素,那么对key进行比较,如果发现key相同,那么替换这个位置的键值对,如果不同,那么在后面拉链
(5) 当链长到一定的程度就会把链表转成红黑树

5.HashMap读取函数的实现

(1) 通过key计算两次哈希后的值,并与长度减1进行按位与运算找到对应的下标
(2) 遍历这个下标位置的链表或者查找红黑树,找到对应的值

6.HashMap 和 Hashtable的区别

(1) Hashtable不允许键或值为null。HashMap允许键或值为null,并且只允许一个键的值为null
(2) Hashtable是线程安全的。HashMap是非线程安全的。在效率上,HashMap会略高于Hashtable
(3) Hashtable有contains()方法判断是否存在于某个值,HashMap去掉了contains()方法
(4) Hashtable的初始容量为11,扩容方式为原来的2倍加1。HashMap的初始容量的16,扩容方式为原来的2倍

7.Hashtable 和 ConcurrentHashMap区别

(1) Hashtable使用synchronized锁住整张Hash表来实现线程安全
(2) ConcurrentHashMap利用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问

8.HashMap 和 TreeMap的区别

(1) HashMap是基于哈希表的实现,TreeMap是基于红黑树的实现
(2) HashMap不保证键的排序,TreeMap的键是排序
(3) HashMap的效率通常比TreeMap高

9.ArrayList、LinkedList、Vector有什么区别

(1) ArrayList和Vector 都是基于数组实现的,LinkedList是基于双向链表实现的
(2) ArrayList和Vector 可以通过下标查找,查询速度快空间连续的,在删除元素的时候,需要移动的元素可能较多,效率较低。LinkedList在查找元素的时候要遍历链表查询效率低,空间不是连续的,在插入或删除元素的时候,只需修改头尾指针指向即可,效率高
(3) ArryList在扩容的时候,默认为原来的1.5倍,扩充的方式不能设置。Vector默认扩容为原来的2倍,扩充的方式可以动态改变
(4) ArrayList和LinkedList 非线程安全的。Vector是线程安全

10.将非线程安全的Map(List)转成线程安全的Map(List)

调用Collections类中的synchronizedMap(synchronizedList)方法

11.Iterator如何实现安全删除List中的元素

在Iterator中,有一个字段expectedModCount ,初始化时等于modCount,即调用list.iterator()返回迭代器时,该字段被初始化为等于modCount。在类Iterator中next()/remove()方法都有调用checkForComodification()方法,在该方法中检测modCount == expectedModCount,如果不相等则抛出ConcurrentModificationException。remove()方法,在删除元素后,同步修改expectedModCount的值

12.HashMap 和 HashSet的区别

(1) HashMap实现了Map接口,HashSet实现了Set接口
(2) HashMap是一种键值对的结构,同时存储键和值。HashSet仅存储对象,HashSet的底层实际是一个值为null的HashMap
(3) 添加元素时,HashMap用的是put()方法,HashSet用的是add()方法
(4) 查找元素时,HashMap利用唯一的键可以快速查找到对应的值。HashSet需要遍历查找,所以HashMap查找效率高于HashSet

13.线程安全的集合类

Vector,Statck,Hashtable,Enumeration

14.String、StringBuffer 和 StringBuilder的区别

(1) String对象一旦被创建后内容是不可变的。StringBuffer和StringBuilder内容是可变
(2) String在初始化时可以像基本数据类型以=赋值的方式初始化,也可以通过new关键字初始化。StringBuffer和StringBuilder只能通过new初始化
(3) 在内容需要经常修改的情况下,使用StringBuffer或StringBuilder效率比String高。虽然String也可以采用"+"实现字符串拼接,但它底层实现还是StringBuffer或StringBuilder的append()方法,同时还会产生多余的临时变量,因此垃圾回收器就会频繁进行垃圾回收工作,从而影响性能
(4) StringBuffer 是线程安全的。StringBuilder 非线程安全的。在执行效率上StringBuiler高于StringBuffer,在单线程中建议使用StringBuilder,多线程中才使用StringBuffer

15.抽象类和接口

(1) JDK7及之前版本的接口中只能包含公有的抽象(public abstract)方法和常量(public static final),JDK8中接口中的方法可以用default或static修饰,可以定义方法默认的实现。抽象类中可以包含抽象方法和普通方法,可以包含普通成员变量
(2) 接口比抽象类更常用,接口中定义一系列的方法,便于维护。抽象类一般充当公共类使用

16.值传递与引用传递

(1) 值传递,传递的是,修改形参不影响实参的值,基本数据类型都是按值传递的
(2) 引用传递,传递的是对象本身,修改形参会影响实参,除基本数据类型外的其它类型都是按引用传递
(3) 在引用传递中,传递对象的地址也是按值传递的,也就是说改变形参时改变的是对象的内容,而不改变对象地址

17.static的作用

(1) 修饰字段,可以在没有实例的情况下直接通过类名访问,可以当成是全局变量使用
(2) 修饰方法,可以在没有实例的情况下直接通过类名调用
(3) 修饰代码块,在JVM类加载的初始化过程执行,代码只会执行一次
(4) 修饰内部类,可以不依赖外部类的实例来创建对象

18.静态变量与非静态变量的区别

(1) 静态变量可以直接通过类名来访问,非静态变量需要通过类的实例来访问
(2) 静态变量在类加载的初始化阶段时,就把变量放入永久代,伴随着整个程序从运行到终止,不会被垃圾回收器回收。非静态变量则在类实例化后才被加载,变量放入堆区,可能会被垃圾回收器回收
(3) 静态变量是在内存中是共享的,非静态变量是不共享

19.final的作用

(1) 修饰,表示类不能被继承
(2) 修饰方法,表示方法不能被重写
(3) 修饰字段,表示属性初始化后不能被修改
(4) final修饰的属性是指它的引用不可变,但它的内容是可以变的

20.重载和重写的区别

(1) 重写发生在具有继承关系的两个或多个类中,重载发生在一个类
(2) 被重写的方法方法名、参数列相同,子类的访问权限不能低于父类,返回值类型相同或相容(子类方法返回值类型可以为父类方法返回值类型的子类),抛出的异常相同或相容(子类方法异常类型可以为父类方法异常类型的子类)。被重载的方法方法名相同,参数列不同,返回值和抛出的异常类型不能作为重载的依据
(3) 私有和静态方法不能被重写,父类和子类可以定义一模一样的私有或静态方法,但是父类方法会被隐藏。私有和静态方法可以被重载
(4) 重写是一种运行时多态,重载是一种编译时多态

21.Error 和 Expection的区别

(1) Expection是指程序在编译或运行时出现的一种异常,出现这种异常时程序不会终止,是由代码抛出的,可以进行捕获和处理
(2) Error是程序在运行时出现了严重的错误,这种错误直接导致程序终止,是JVM抛出的,不应该尝试进行捕获,而应该对程序进行修改,或者进行JVM调参优化

22.检查时异常和运行时异常有什么相同点和不同点

(1) 相同点:两种异常都继承自Exception类,出现异常都可以进行捕获和处理,不会导致程序终止
(2) 不同点:检查时异常是编译时的异常,在编译时就能检查出,并且必须捕获和处理。运行时异常只有在运行时才能检查出的异常,不一定要捕获和处理,是可以避免的

23.内部类

(1) 成员内部类。普通的内部类,定义成员内部类跟定义成员方法一样
(2) 局部内部类。定义在代码块里,跟定义局部变量一样,作用域为代码块内
(3) 静态内部类。用static修饰的内部类,表示该类可以在没有外部类实例的情况下创建该类对象
(4) 匿名内部类。没有类名的内部类,匿名内部类可以使代码简洁,但是可读性会降低,一般情况下直接创建接口对象,并实现接口中的方法,多用于事件处理

24.构造函数

(1) 构造函数是一种特殊的函数,与类名完全相同没有返回值,并且不是void
(2) 在一个类中,可以有多个参数列不同的构造函数
(3) 构造函数不能被继承或重写,在子类可以通过super关键字调用父类的构造函数
(4) 当类中没有定义构造函数的时候会自动创建一个无参的构造函数,父类中没有定义无参的构造函数,在子类必须显式调用父类的有参构造函数
(5) 构造函数随着new一起被调用,多用于初始化工作

25.== 和 equal的区别

(1) ==比较的是两个变量的地址是否相同,equal()是Object类中的方法,一般用于比较内容是否相同
(2) 对于基本数据类型,可以直接用==比较值是否相等。对于String,如果两个String定义方式跟基本数据类型一样并且内容相同,那么用==也返回true(例如String s1=”abc” String s2=”abc” s1==s2返回true),因为指向的是常量池的同一块区域,即地址相同

26.i++和++i的区别

(1) i++是先把i进行赋值操作,再把i本身的值加1(分两步:①j=i,②i+=1)
(2) ++i是先把i本身的值加1,再进行赋值操作(分两步:①i+=1,②j=i)

27.break,continue和return的区别

(1) break(破坏)用于破坏当前循环条件,并且跳出当前循环
(2) continue(继续)用于退出当次循环,继续下一次循环
(3) return(返回)用于方法中的结束返回

28.final,finally和finalize的区别

(1) final用于修饰字段,方法和类,表示是不可变的
(2) finally用在异常处理中,表示无论是否出现异常都要执行的代码(代码中有Sys
tem.exit(0)除外)
(3) finalize是Object类的方法,可以调用这个方法标记对象需要被回收

29.程序初始化顺序

(1) 父类的静态变量和静态代码块
(2) 子类的静态变量和静态代码块
(3) 父类的非静态变量和非静态代码块
(4) 父类的构造函数
(5) 子类的非静态变量和非静态代码块
(6) 子类的构造函数

30.序列化的作用

序列化可以将对象转成字节流流,方便网络传输,保存文件

31.面向对象的特征

(1) 继承。一种层次模型,允许和鼓励类的重用,新类可以由旧的类派生
(2) 封装。将客观事物抽象成类,每个类对自身的数据和方法进行保护和隐藏
(3) 多态。允许不同类的对象对同一消息作出响应,分为编译时多态(重载)和运行时多态(重写)

32.组合和继承的区别

(1) 组合是兄弟关系,继承是父子关系。组合是在新的类中调用已有类的代码,而继承相当于子类完全把父类的代码复制下来
(2) 能用组合尽量不使用继承,当类继承层次多了就会让编译后的class变得臃肿,从而浪费空间

33.Java如何读写文件

(1) 按字节读取。通过创建字节流并把文件内容读取并保存到一个byte数组中,这种方式多用于读取二进制文件
(2) 按字符读取。通过创建字符流的方式读取文件内容并转换成字符类型,这种方式多用于读取文本文件
(3) 按读取。通过缓冲区的方式依次读取行的内容,多用于读取行格式文件

34.clone的作用

clone作用是实现对象的复制。clone()方法存在Object类中,该方法返回的是一个对象的副本,默认是浅复制。浅复制只复制基本数据类型和对象的引用。深复制不仅复制基本数据类型还完全复制对象,实现深复制必须要重写clone()方法

35.Java反射机制

反射机制可以在运行时动态的创建类的对象,大大提高了程序的灵活性。利用反射机制可以在未给出源码,只给出.class文件或jar包的情况下,创建类的实例,可以调用其中所有(包括私有和非私有)的方法、字段等
反射获得Class类的方法
(1) 通过Class.forName()方法
(2) 通过类名.class
(3) 通过实例.getClass()方法

36.bio和nio的区别

(1) bio为阻塞io,nio为非阻塞io
(2) bio面向流,nio面向缓冲区
(3) nio有选择器

37.CGI与Servlet的区别

(1) Servlet是一种用Java语言编写的服务器程序。CGI为公共网关接口,利用的Perl脚本编写
(2) Servlet拥有Java语言的所有特点,具有跨平台性和较好的移植性,无需修改代码就能部署在不同的WEB服务器上
(3) Servlet执行效率更高。CGI会为每个请求创建一个进程。Servlet是创建一个线程,线程比进程开销小
(4) Servlet功能更强大,Servlet可以直接与服务器交互。CGI不能直接跟服务器交互
(5) Servlet使用更方便,因为Servlet提供了很多接口可以读取和设置HTTP头消息

38.Web三大组件

(1) Servlet,用于处理客户端的请求,主要任务有接收请求数据,处理请求和完成响应
(2) Filter,也可用于处理请求,但主要作用是过滤请求,负责请求的拦截和放行
(3) Listener,用于监听Application、Session、Request对象

39.Filter拦截方式

(1) REQUEST,直接访问目标资源时执行过滤器。在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST
(2) FORWARD,转发访问执行过滤器。包括RequestDispatcher的forward()方法、< jsp:forward>标签都是转发访问
(3) INCLUDE,包含访问执行过滤器。包括RequestDispatcher的include()方法、< jsp:include>标签都是包含访问
(4) ERROR,出现异常执行过滤器。当目标资源在web.xml中配置为< error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器

40.Listener接口分类

按监听的作用域可以分为三种:
(1) ServletContextListener,监听ServletContext对象,即Application域,可以用统计在线用户数量
(2) HttpSessionListener,监听Session对象
(3) ServletRequestListener,监听Request对象

按功能可以分为三种:
(1) 三个域对象的创建和销毁的监听器
(2) 监听三个域对象的属性变更的监听器
(3) 监听HttpSession对象中的JavaBean的状态的改变

你可能感兴趣的:(Java笔试面试之Java与Web基础)