Java高级开发工程师面试考纲.docx
- 文档编号:26196174
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:27
- 大小:163.52KB
Java高级开发工程师面试考纲.docx
《Java高级开发工程师面试考纲.docx》由会员分享,可在线阅读,更多相关《Java高级开发工程师面试考纲.docx(27页珍藏版)》请在冰豆网上搜索。
Java高级开发工程师面试考纲
Java高级开发工程师面试考纲
当前,市面上有《JavaXX宝典》类似的图书,而且图书中的内容都着重在讲解Java最为基础的部分,最严重的是,里面有着大量错误的内容,极具误导性。
另外,网上也有各种各样的Java面试题,很多也是着重在Java语言基础上。
实际上,如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构、算法、网络、操作系统等知识。
因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对Java高级开发工程师职位的考核纲要,希望可以帮助到需要的人。
1Java基础
1.1Collection和Map
(1)掌握Collection和Map的继承体系。
(2)掌握ArrayList、LinkedList、Vector、Stack、PriorityQueue、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap、TreeMap、WeakHashMap、EnumMap、TreeMap、HashTable的特点和实现原理。
(3)掌握CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap的实现原理和适用场景。
1.2IO
(1)掌握InputStream、OutputStream、Reader、Writer的继承体系。
(2)掌握字节流(FileInputStream、DataInputStream、BufferedInputStream、FileOutputSteam、DataOutputStream、BufferedOutputStream)和字符流(BufferedReader、InputStreamReader、FileReader、BufferedWriter、OutputStreamWriter、PrintWriter、FileWriter),并熟练运用。
(3)掌握NIO实现原理及使用方法。
1.3异常
(1)掌握Throwable继承体系。
(2)掌握异常工作原理。
(3)了解常见受检异常(比如FileNotFoundException)、非受检异常(比如NullPointerException)和错误(比如IOError)。
1.4多线程
(1)掌握Executors可以创建的三种(JAVA8增加了一种,共四种)线程池的特点及适用范围。
(2)掌握多线程同步机制,并熟练运用。
1.5Socket
(1)掌握Socket通信原理。
(2)熟练使用多线程结合Socket进行编程。
2Java虚拟机
2.1JVM内存区域划分
(1)掌握程序计数器、堆、虚拟机栈、本地方法栈、方法区(JAVA8已移除)、元空间(JAVA8新增)的作用及基本原理。
(2)掌握堆的划分:
新生代(Eden、Survivor1、Survivor2)和老年代的作用及工作原理。
(3)掌握JVM内存参数设置及调优。
2.2类加载
(1)掌握类的加载阶段:
加载、链接(验证、准备、解析)、初始化、使用、卸载。
(2)掌握类加载器分类及其应用:
启动类加载器、扩展类加载器、应用程序类加载器、自定义加载器。
3J2EE
(1)掌握JSP内置对象、动作及相关特点和工作原理。
(2)掌握Servlet的特点和工作原理。
(3)掌握Spring框架的IOC和AOP实现原理(反射和动态代理)。
(4)至少掌握一个MVC框架(SpringMVC,Struts等)的工作原理,并熟练运用。
(5)至少掌握一个ORM框架(Hibernate,MyBatis等)的工作原理,并熟练运用。
4数据结构及算法
(1)掌握线性表和树的特点并熟练运用。
(2)掌握常用排序和查找算法:
插入排序(直接插入排序、希尔排序)、选择排序(直接选择排序、堆排序)、交换排序(冒泡排序、快速排序)、归并排序,顺序查找、二分查找、哈希查找。
(3)熟练运用常见排序和查找算法思想解决编程问题。
(4)了解几大基本算法:
贪心算法、分治策略、动态规划。
5计算机网络
(1)掌握网络的分层结构,及每层的功能特点。
(2)掌握TCP/IP的通信原理(三次握手、四次挥手)
6数据库
(1)掌握复杂的SQL语句编写。
(2)掌握数据库的优化(SQL层面和表设计层面)。
(3)至少掌握一款数据库产品。
(4)熟悉高并发、大数据情况下的数据库开发。
7Web技术
(1)掌握AJAX的工作原理。
(2)至少熟悉一款JS框架(比如JQuery)。
8设计模式
(1)熟悉常见的设计模式。
(2)会将设计模式理论应用到实际开发中。
9Linux
(1)熟练运用Linux常见命令。
(2)熟悉Linux操作系统基本概念及特点。
(3)熟悉Shell脚本。
10操作系统
(1)掌握操作系统的进程管理。
(2)了解操作系统的I/O。
11正则表达式
(1)掌握常见正则表达式符号。
(2)熟练运用正则表达式解决实际问题(比如匹配电话号码、邮箱、域名等)。
Java高级开发工程师面试-对象创建及销毁
1.考虑用静态工厂方法代替构造器。
(1)因为构造器的参数很难反应返回的对象,而静态工厂方法的名称就弥补了这一点。
(2)静态工厂方法不必在每次调用的时候都创建一个新的对象,比如单例模式。
(3)静态工厂方法可以根据实际需要返回原返回类型的派生类型(可以是非公有的)对象,比如EnumSet既可返回RgularEnumSet类型,也可返回JumboEnumSet类型,而它们都是声明在EnumSet中的非公有类。
服务提供者框架也是基于静态工厂方法的典型例子。
(4)静态工厂方法创建参数化类型实例的时候,代码会更加简洁。
(5)静态工厂方法所属的类,如果不包含公有的或受保护的构造器,就不能被继承。
(6)静态工厂方法跟其它静态方法没有什么区别。
2.遇到多个构造器参数时考虑用构建器。
3.添加私有构造器,可以防止类被实例化。
4.对于同时提供了静态工厂方法和构造器的不可变类(如被final修饰的类),通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。
5.要优先使用基本类型而不是装箱类型,使用装箱类型可能会产生大量的对象。
6.在基于数组实现的栈中,当弹出一个元素之后,栈的currentSize自减1,但原始currentSize所对应的元素的引用再也不能被解除,因此形成了过期引用,这种情况下,每次弹出元素后就应该把对应元素的引用置为null,对象才能被垃圾回收机制回收。
7.使用WeakHashMap代替HashMap使用缓存功能,当key没有正常使用的时候,GC会清理对应的条目。
8.除非是做安全网,或者为了终止非关键的本地资源,否则请不要使用终结方法,因为它消耗资源特别严重。
若子类重写了finalize()方法,可以采用终结守卫方式,即在子类中创建一个父类对象引用,当子类被销毁时就会自然执行父类finalize并销毁父类对象。
Java高级开发工程师面试——多线程
1.进程和线程的区别?
进程是一个具有独立功能的程序关于某个数据集合的执行活动,不同的进程拥有独立的内存空间;线程是程序执行的最小单位,一个或多个线程组成一个进程,同一个进程中的所有线程共享相同的内存空间,运行时都有一个线程栈来保存变量值信息。
2.Thread类中的start()和run()有什么区别?
start()是用来启动新创建的线程,在start()内部调用了run(),当前线程仅能通过start()启动一次线程;若在本线程中直接调用run(),则它为一个普通的方法调用而已,没有创建新的线程,可以调用多次。
3.Runnable和Callable有什么区别?
Runnable和Callable的核心功能没什么区别,只是Callable可以返回值和抛出异常。
4.volatile有什么作用?
使用volatile修饰的变量,线程每次在使用变量的时候,都会读取变量修改后的最新值。
具体工作方式:
从堆内存加载变量值到线程本地内存,建立一个变量副本,线程对变量的修改在线程内存完成,然后再将值写回堆内存。
若两个线程对堆中的同一个变量进行操作,也会出现并发问题。
5.什么是竞态条件?
当多个线程同时执行一段代码(或使用相同资源),因为顺序原因导致执行结果不符合预期,就出现了竞态条件。
6.如何处理线程运行时发生的异常?
我们知道,Thread的run()是不抛出任何检查型异常(CheckedException)的,而它自身有可能因异常而终止执行,即使用try…catch也没法捕获。
Java5.0提供了一个Thread.setUncaughtExceptionHandler来设置对线程中未捕获异常的处理。
7.请简述ThreadLocal的作用。
当使用ThreadLocal修饰变量时,ThreadLocal为每个使用该变量的线程提供了独立的变量副本,每个线程可以独立地操作自己的副本,而不会影响到其它线程的副本。
8.为什么wait()和notify()需要在同步块中调用?
首先,JDK强制要求这样做,否则会抛出IllegalMonitorStateException;还有就是,这样可以避免wait和notify之间产生竞态条件。
9.请简述join()和yield()的作用。
t.join()表示阻塞主线程,等待t线程直到t线程运行结束;t.yield()表示阻塞t线程,将CPU资源让给其它相同优先级的资源。
10.请简述wait()和sleep()方法有什么不同?
sleep()是由Thread提供的,它会释放CPU资源一段时间,但不会释放锁,等待的时间到了会恢复运行;wait()是由Object提供的,它会放弃对象锁,进入等待锁定池,直到针对此对象的notify()才能获取锁进入运行状态。
Java高级开发工程师面试——基础知识
1.简述Java5、Java6、Java7和Java8的若干功能更新。
Java5:
引入泛型,允许指定集合元素的类型,避免了强制类型转换。
引入枚举类型。
自动装箱和拆箱(int->Integer等)。
可变参数和新的遍历语句,比如:
public void test(object... objs){
for(Object obj:
objs){
System.out.println(obj);
}
}
Java6:
对UI、WebService和安全等一系列的增强。
Java7:
switch可以传递字符串参数。
获取环境信息的工具方法。
Java8:
Java8允许给接口添加一个非抽象的方法实现,仅需要使用default关键字修饰即可。
Lambda表达式。
函数式接口。
2. 请简述Collection、LinkedList、ArrayList、PriorityQueue、HashSet、HashMap的关系。
下图截取自官方文档:
3.请简述HashMap实现原理。
HashMap的数据结构是数组和链表的结合体,称为“链表散列”结构。
元素的键值均可为null。
其中的数组元素类型为Node[],Node包含hash、key、value和next四个属性,其中hash为元素节点的hash值,key为键,value为值,next为指向下一个元素的指针(将hash值相同的元素当作链表来存储)。
当向HashMap中put元素A的时候,先根据key.hashCode()计算hash值,根据hash值得到数组的索引,如果数组在该索引位置已经存放了其它元素,则遍历这个位置的元素(把所有元素当作链表看待),找到这个元素的尾节点B,将元素B的next指向元素A,即B为链头,A为链尾;若该索引位置未放置其它元素,则直接存放到这里。
在遍历元素时,程序会根据equals方法对key进行判断,若已存在该key,则用新值替换旧值。
当向HashMap中get元素时,先根据key.hashCode()计算hash值,根据hash值找到数组索引,遍历索引所对应的元素,根据key的equals方法找到对应的节点,最后返回节点的value属性。
4.请简述HashMap、HashTable和ConcurrentHashMap的特点。
HashMap是非线程安全的;HashTable是线程安全的,但由于采用对象锁方式,在并发环境下效率低下;ConcurrentHashMap是线程安全的,及HashTable不同的是,它采用锁分段技术,即容器里有多把锁,每把锁用于其中的一部分数据,因此在并发环境下比HashTable效率高。
5.TreeMap及HashMap的区别?
HashMap是基于hashCode的,适于快速查找元素,而TreeMap是基于一种固定的树顺序结构。
6.请简述JVM内存设置。
堆内存:
堆是运行时数据区域,所有的对象和数组均存放在这里,它在虚拟机启动时创建,通过-Xms设定。
非堆内存:
堆以外的内存,通过-XX:
PermSize来设置。
Java高级开发工程师面试——正则表达式
1. 请使用正则表达式匹配中国大陆的手机号码。
(1)手机号码前有+86字符串:
^\+861[3|5|7|8][0-9]{9}$
解释:
^匹配输入字符串的开始位置。
\+匹配+这个符号。
[3|5|7|8]匹配3、5、7和8中的一个字符。
[0-9]匹配0-9中的一个字符。
{9}匹配前面的表达式9次。
$匹配输入字符串的结束位置。
|指明两项之间的一个选择。
(2)手机号码前无+86字符串:
^1[3|5|7|8][0-9]{9}$
2. 请使用正则表达式匹配电子邮件地址。
^\w+(\.\w+)*@\w+(\.\w{2,3}){1,3}$
解释:
\w匹配包括下划线的任何单词字符。
*匹配前面的子表达式零次或多次。
{2,3}最少匹配2次且最多匹配3次,{1,3}同理。
3. 请使用正则表达式从下列域名中找出“”和“”。
sanesee.io,
sanesee.org,
sanesee.au,
sanesee.jp,
sanesee.click
sanesee.(cn|com)
解释:
()标记一个子表达式的开始和结束位置。
4. 请使用正则表达式匹配“a._/”和“b\_”。
[a|b].?
(\\\_|\_/)
解释:
?
匹配前面的子表达式零次或一次。
\\匹配\。
也可以有其它多种匹配方式,读者可以自己去尝试。
9个Java初始化和回收的面试题
1.Java中是如何区分重载方法的?
通过重载方法的参数类型和顺序来进行区分的。
注意:
若参数类型和顺序均相同时,不管参数名是否相同,编译器均会报错,提示方法已经被定义。
且不能根据返回值类型来区分,如果根据返回值来区分的话,有时程序里调用方法时并不需要返回值,那么程序都无法确定该调用那个重载方法。
2.阅读以下程序,解释其中的错误。
public static void testLong(long i) {
System.out.println("test long");
}
public static void testFloat(float i) {
System.out.println("test float");
}
public static void main(String[] args) {
testLong(50);
testFloat(1.5);
}
testLong没有问题,因为传递的参数50是int型的,而接收方参数是long型的,小范围可以自动转型为大范围的数据类型;testFloat不会通过编译,因为传递的参数1.5是double类型的,而接收方参数是float类型的,大范围转型为小范围数据类型需要显式转换,即改为testFloat(1.5f)。
3.阅读以下程序,解释其中的错误。
public static class A {
A(int i) {
System.out.println("A(int i)");
}
}
public static void main(String[] args) {
A a = new A();
}
在定义了自定义构造器后,若要使用默认构造器,则需要显式指定默认构造器,否则Aa=newA();不能编译通过。
4.阅读以下程序,解释其中的错误。
public static class A {
A() {
System.out.println("A()");
}
A(int i) {
System.out.println("A(int i)");
}
A(int i, int j) {
A();
A(i);
System.out.println("A(int i, int j)");
}
}
在一个构造器中调用其它构造器时,需要使用this关键字进行调用,如this();在一个构造器中可调用仅一个其它构造器,并且调用其它构造器的语句需放在调用者(即发出调用行为的构造器)语句块的第一行。
5.阅读以下程序,写出执行结果。
public static class A {
private int i;
private String j;
int getI() {
return i;
}
String getJ() {
return j;
}
A(int i) {
i = i;
}
A(String j) {
this.j = j;
}
}
public static void main(String[] args) {
System.out.println(new A(5).getI());
System.out.println(new A("hello").getJ());
}
执行结果为:
0
hello
对于i=i;这个语句而言,它并未改变实例变量i的值,且i的默认值为0,因此结果也为0,若需要改变实例变量i的值,需要改为this.i=i;
6.在一个类中,声明了若干个static方法和非static方法,请谈谈声明的static方法是否能访问声明的非static方法,说明理由?
static方法不能访问非static方法,因为static方法是属于这个类本身的一个方法,在编译期间就已经确定了;而非static方法是属于这个类的对象的方法,需要在实例化之后才能访问到。
若在static方法中访问非static方法,将不能通过编译。
7.static关键字为何不能修饰局部变量?
static关键字修饰的变量或方法是属于类的,在编译时就已经确定了;而普通变量或方法是属于该由类生成的对象,需要在实例化后才能确定。
因此,若static关键字修饰了方法的局部变量,一方面方法需要在实例化之后才能确定,另一方面static修饰的变量需要在编译时确定,这就会导致矛盾。
8.finalize()有何用途?
什么情况下需要调用这个函数?
在需要释放内存的地方调用finalize(),则在下一轮垃圾回收时会回收占用的内存,一般情况下不需要显式调用此函数。
垃圾回收器只能回收那些由new关键字创建的对象所占用的内存,那么有些不是通过这种方式(比如调用C++本地方法)所占用的内存如何回收呢?
那么就需要使用finalize()了。
由于C++中需要使用free()函数来释放内存,所以Java程序在调用C++时需要调用finalize()方法来释放内存。
9.列出并简要解释几种常见垃圾回收技术。
引用计数:
每个对象都包含了一个引用计数器,每被引用一次,计数器都加1,引用者被置为null或者销毁,计数器就减1。
垃圾收集器进行轮询,一旦发现计数器的值小于1,就回收该对象占用的内存。
停止复制:
在垃圾回收机制运行时,程序需要停止运行,将每个活动的对象由一个堆转移到另一个堆,留下的垃圾会被回收。
标记清除:
从堆栈和静态存储区域开始,寻找到活的对象就对其进行标记,所有的标记过程完成后,就对垃圾进行回收。
40个Java集合面试问题和答案
1.Java集合框架是什么?
说出一些集合框架的优点?
每种编程语言中都有集合,最初的Java版本包含几种集合类:
Vector、Stack、HashTable和Array。
随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。
在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久。
它还包括在Java并发包中,阻塞接口以及它们的实现。
集合框架的部分优点如下:
(1)使用核心集合类降低开发成本,而非实现我们自己的集合类。
(2)随着使用经过严格测试的集合框架类,代码质量会得到提高。
(3)通过使用JDK附带的集合类,可以降低代码维护成本。
(4)复用性和可操作性。
2.集合框架中的泛型有什么优点?
Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。
泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。
这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。
泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。
它也给运行时带来好处,因为不会产生类型检查的字节码指令。
3.Java集合框架的基础接口有哪些?
Collection为集合层级的根接口。
一个集合代表一组对象,这些对象即为它的元素。
Java平台不提供这个接口任何直接的实现。
Set是一个不能包含重复元素的集合。
这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。
List是一个有序集合,可以包含重复元素。
你可以通过它的索引来访问任何元素。
List更像长度动态变换的数组。
Map是一个将key映射到value的对象.一个Map不能包含重复的key:
每个key最多只能映射一个value。
一些其它的接口有Q
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 高级 开发 工程师 面试