40、Java技术面试全攻略

Java技术面试全攻略

1 企业Java开发者的必备技能

一个优秀的企业Java开发者,除了要理解抽象类和接口的区别,还需要掌握以下知识:Java Servlet、JSP、Spring框架、EJB、JMS、商业消息中间件、JDBC、JNDI、HTML、XML、Hibernate、Ant或Maven构建工具、SQL、主流应用服务器之一,以及几种关系型数据库管理系统。

理解在当前项目中使用特定Java EE组件的原因也同样重要。当面试官询问使用某个组件的原因时,要给出自己的见解,而不是简单地说决策在自己加入项目之前就已做出。

2 面试小贴士

2.1 面试过程

  • 保持积极态度 :面试时要充满活力,展现出对这份工作的兴趣。即便你是技术专家,也不要表现得好像来面试是给面试官面子。良好的个性在面试中很重要。
  • 准备白板编程 :要做好在白板上写代码的准备并进行练习。即使面试官没有要求,若房间里有白板,也可以主动在上面阐述自己的思路;若没有白板,就用自己的记事本。面试官更关注你思考和解决问题的能力,而非你对算法、类名或方法参数的记忆。
  • 不要害怕犯错 :在白板上写代码时,不要害怕犯错,要一边思考一边说出来。让面试官看到你如何识别错误方法并选择正确方法,这可能对面试有帮助。你可以向朋友或亲戚练习解释小代码片段,他们不需要懂Java就能参与这个角色扮演游戏。

2.2 面试之后

面试结束后,一旦离开面试场所,就要立即记录下面试中的情况。不要等到回家再做记录,以免忘记重要细节。对于回答得不太正确的问题,要做好笔记并进行研究,每次面试后都要提升自己的技术能力。

3 考虑录用 offer

当收到录用 offer 时,要慎重考虑是否接受。建议在工作稳定的时候寻找新工作,这样你可以在没有经济压力的情况下考虑 offer。

不要仅仅因为新工作每年多给 5000 美元(税后每月不到 300 美元)就接受 offer。相反,如果一份工作能让你接触到有趣的技术或商业应用,即使薪水没有增加,也可以考虑接受。

录用 offer 中的非金钱因素也很重要,如健康福利、灵活的工作时间、通勤便利程度,或者你与潜在雇主团队成员的融洽感。有些人甚至不会接受要求穿西装打领带的工作 offer。你需要决定什么对你更重要,是一份有趣的工作,还是展示自己的新纹身。无论你的偏好如何,都要掌控自己的职业生涯,按照自己的意愿积极发展。

4 企业开发者面试现状

4.1 市场现状

当就业市场形势良好时,主要的在线招聘网站会显示数千个职位空缺,人们会为这些职位展开竞争。如今,经验丰富的开发者需要了解大约 10 种不同的工具或技术,才能找到一份好工作,并在几年内保持相对稳定。

4.2 面试观察

  • 头衔偏好 :现在很多人更喜欢称自己为 Java 架构师,而不是 Java 开发者或程序员分析师。但实际上,只有部分人真正理解 Java EE 组件的运作方式并能提出设计解决方案。当然,Java 架构师需要了解的不仅仅是 Java EE 知识。
  • 应聘者资历 :应聘者的资历普遍较高,很少能看到大学毕业生或初级程序员。许多初级职位被外包,而且过去几年计算机科学专业的毕业生数量有所下降。
  • 证书作用 :软件证书并不能让简历脱颖而出。如果简历以证书列表开头,很可能是初学者的简历。虽然证书有助于学习语言或工具,表明你愿意学习,但它并不能使一个人成为熟练的专业人员。
  • 数据库知识 :随着 Hibernate 等中间层对象关系映射框架的引入,很多人不再愿意学习数据库管理系统的工作原理或编写高效的 SQL 查询,只是将 Java 类映射到数据库表。
  • 面试难度 :在经济不景气时,要做好通过至少四轮面试才能获得工作的准备。1999 年时,两轮不错的面试就足够了;而在 2001 年,甚至很难获得面试机会,更别说得到工作了。
  • 海外竞争 :2010 年,很大一部分开发工作在印度进行。尽管海外开发者的小时费率较低,但开发总成本并不低。然而,西方招聘经理往往认为本地候选人也应该在薪资上灵活一些。仅仅是英语母语者并不能保证你能获得高薪,要始终保持技术的先进性,否则来自海外更有动力的开发者会超过你。
  • 业务术语 :了解潜在雇主的业务术语也很重要。在纽约,仅靠技术能力可能不足以获得高级职位,但在谷歌或微软面试可能是个例外。例如,如果你申请金融经纪公司的 Java 职位,却不知道“卖空”是什么,这可能会导致面试失败。作为高级开发者,你应该能够迅速上手工作,尽量从招聘人员那里了解业务的详细信息,做好功课就能获得工作。

5 是否考取证书

5.1 证书的好处

任何认证项目对于想要销售培训并颁发证书的供应商来说都是一门生意,Oracle 也不例外。你可以在 http://education.oracle.com/pls/web_prod - plq - dad/db_pages.getpage?page_id = 140#13 找到各种 Java SE 和 EE 技术的认证项目。

大多数认证项目要求通过计算机选择题测试,但有些项目(如 Java EE 架构师认证)会给出具有挑战性的设计和编程任务。总体而言,准备并参加认证过程是个不错的主意,因为这肯定会提高你对 Java 语言或特定企业技术或框架的理解,在某些领域还可能提升简历的竞争力,也有助于通过招聘机构的计算机筛选测试。你只需查看潜在雇主的招聘信息,看他们是否要求有证书。

5.2 证书的局限性

不要高估 Java 认证的重要性。当看到简历以证书列表开头时,往往意味着候选人只是擅长通过选择题测试。相比证书,在开源或企业项目中的实际操作经验更有价值。如果有证书,可以把它们放在简历末尾,而不是作为主要成就展示。

6 技术面试常见问题及解答

以下是一些常见的 Java 技术面试问题及简要答案:
|问题|答案|
|----|----|
|接口和抽象类有什么区别?|抽象类的方法体中可以包含代码,而接口中不允许。由于 Java 不支持多重继承,使用抽象类时,你的类必须继承自该抽象类;而一个类可以实现多个接口。|
|如何在当前使用的应用服务器中部署 Web 应用程序?|在大多数 Java EE 应用服务器中,你需要创建一个 Web 归档文件(war 文件),并将其复制到应用服务器文档指定的目录中。你还应该能够解释 war 文件的目录结构。|
|关键字 static 的用途是什么?|用于方法和变量的声明,使它们在不创建类实例的情况下也能使用。例如,main() 方法就是静态方法。如果一个变量是静态的,它的值会被类的所有实例共享。|
|如何强制进行垃圾回收?|不能强制进行垃圾回收,但可以请求它,因为 JVM 不能保证会立即启动垃圾回收。调用 System.gc() 可以请求 Java 进行垃圾回收。|
|解释事件适配器的用途。|一些 Swing 事件监听器接口声明了多个方法(如 WindowListener 有七个方法),一个类必须实现所有这些方法。适配器已经预定义了所有这些方法,且方法体为空。因此,如果一个类只需要处理 WindowListener 事件中的一个,它只需要重写 WindowAdapter 中对应的方法。|
|如何判断是否需要显式类型转换?|当将超类对象赋值给子类数据类型的变量时,需要使用显式类型转换。例如:
java<br>Object a;<br>Customer b;<br>b = (Customer) a;<br>
Java 泛型消除了显式类型转换的需要。对于子类到超类的赋值,类型转换会自动进行。你也可以将对象转换为类实现的接口类型。|
|能否在不同类型的对象之间进行类型转换?|不能。对象之间必须有超类 - 子类关系,或者可以转换为类实现的接口类型。|
|Java 类能否继承自两个类?|Java 不允许多重继承,但一个类可以实现多个接口,在一定程度上可以作为一种变通方法。|
|小程序(Applets)和 Servlet 都部署在服务器上,它们的运行时环境有什么区别?|小程序在用户机器上的 JVM 中,在 Web 浏览器的控制下运行,并且有安全限制,限制对计算机设备的访问。Servlet 在服务器端,在 Servlet 容器或 Java EE 应用服务器的控制下运行。|
|构造函数和普通方法有什么区别?|构造函数的名称必须与类名相同,并且不能返回值。构造函数只被调用一次,而普通方法可以被多次调用。|
|HTML 的 Get 和 Post 方法有什么区别?|Get 方法将参数附加到 URL 后面,生成的 URL 可以被收藏。Post 方法允许发送对象和文本数据,而 Get 方法只处理文本数据。|
|什么是 cookie?哪些 Java 组件可以创建它们?|cookie 是一个表示名/值对的对象。Servlet、JSP 和 JSF 可以创建并向 Web 浏览器发送 cookie,浏览器会将它们保存在用户磁盘的特定目录中。cookie 有助于 Servlet 识别用户。例如,银行可以将你的账户号码存储在你机器上的 cookie 文件中,这样你登录时就不需要再次输入。|
|非抽象类能否同时包含抽象方法和具体方法?|不能,只有抽象类可以有抽象方法。|
|解释 Java 包的用途。|包提供了一种组织多文件项目的方式。当不同包中有同名类时,包可以帮助解决命名冲突。包访问级别还可以保护数据不被未授权的类使用,只允许同一包中的类访问彼此的成员变量。|
|解释关键字 transient 的用途。|transient 关键字表示该成员变量的值不需要随对象一起序列化。当类被反序列化时,transient 变量将被初始化为变量数据类型的默认值(如整数为 0)。|
|关于线程同步你了解多少?解释 public void synchronized myMethod() { ... } public void myMethod() { ... synchronized (some_object) {... } } 的区别。|关键字 synchronized 用于防止多个线程同时更新某些值时出现竞态条件。同步块比同步方法更可取,因为它们加锁的时间更短。但在手动同步代码块之前,你应该考虑是否可以使用 java.util.concurrent 包中的集合类来更好地处理竞态条件。|
|方法 sleep() 和 wait() 有什么区别?| sleep(1000) 会让线程精确地暂停一秒钟; wait(1000) 会让线程最多等待一秒钟,如果线程收到 notify() 或 notifyAll() 调用,它可以提前停止等待。wait() 方法定义在 Object 类中,而 sleep() 方法定义在 Thread 类中。|
|关于方法 invokeLater() 你了解多少?|该方法定义在 SwingUtilities 类中,用于确保 Swing 窗口通过事件调度线程进行更新。你也可以使用 SwingWorker 类来实现相同的功能。|
|通过继承 Thread 类和实现 Runnable 接口创建线程有什么区别?|通过继承 Thread 类创建线程时,你的类必须继承自 Thread 类,然后创建该类的实例并调用其 start() 方法。如果一个类实现了 Runnable 接口,你需要创建该类的实例和 Thread 对象,并将 Runnable 类的实例传递给 Thread 对象。使用 Runnable 接口可以让你从除 Thread 类之外的其他类继承的类创建线程。|
|如何创建一个能从其 run() 方法返回值的线程?|你需要实现 Callable 接口。|
|比较两个 String 变量应该使用 equals() 方法还是 == 运算符?|使用 equals() 方法比较字符串的值,使用 == 运算符检查两个变量是否指向内存中的同一个 String 对象。|
|关于 MVC 设计模式你了解多少?|MVC 代表模型 - 视图 - 控制器设计模式,用于将表示层模块与业务逻辑和数据层分离。模型部分表示应用程序的数据和业务逻辑,视图是可视化表示(如用户界面),控制器接收来自视图的数据并将其传递给模型,反之亦然。例如,JSP 页面是视图,Servlet 是控制器,Java bean 代表模型。|
|如何减少 JVM 创建频繁使用的对象实例所花费的时间?|可以创建自己的对象池或配置现有的对象池(如 DataSource 或 EJB 对象可以配置为使用特定大小的对象池)。|
| File a = new File("xyz.txt"); 语句会在磁盘上创建文件 xyz.txt 吗?|不会,它只是创建一个指向该文件的对象。|
|子类如何调用超类中定义的方法?|Java 有关键字 super。如果一个方法被重写,但你想调用超类中定义的版本,可以使用 super.myMethod(); 语法。要调用超类的构造函数,只需在子类构造函数的第一行写 super(); 。|
|要确保只有同一目录中的类可以访问该目录,需要指定什么访问级别?|不需要指定任何访问级别。在这种情况下,Java 将使用默认的包访问级别,这将确保只有同一目录(包)中的类可以相互访问。|
|JNDI 的用途是什么?|JNDI 是用于命名和目录服务器的 Java API,用于在分布式应用程序中按名称查找 Java 对象。例如,你可以使用 JNDI 获取 DataSource 或 JMS 对象的引用。|
|读取文件的方法是否必须在 try/catch 块中调用?|你要么将其放在 try/catch 块中,要么声明调用该方法的方法可能会抛出异常,例如:
java<br>void myMethod() throws IOException {...}<br> |
|如果需要捕获多个异常(如 FileNotFoundException 和 IOException),catch 语句的顺序重要吗?|重要。FileNotFoundException 继承自 IOException,必须先捕获异常子类。|
|详细解释用户按下提交按钮后,网页和名为 FindBooks 的 Servlet 之间的数据工作流程。|Web 浏览器连接到指定 URL 的服务器,如果 FindBooks 还未启动,Servlet 容器将启动它,调用 Servlet 的 init() 方法,然后调用 service() 方法,service() 方法会根据 HTTP 请求方法调用 doGet() 或 doPost() 方法。HTTPServletRequest 和 HTTPServletResponse 对象用于客户端和 FindBooks 之间的交互。Servlet 的输出可以通过 HTTPServletResponse 的方法(如 println())发送回用户。|
|解释在 Java SE 程序中使用 JDBC 从数据库表中获取数据的过程。需要使用哪些类和方法?|首先使用 Class.forName() 加载合适的 JDBC 驱动程序。然后使用 DriverManager.getConnection() 获取 Connection 对象。接着创建一个 Statement 对象并调用其方法,如 executeQuery() 或 executeUpdate()。如果有结果集,处理结果集,并关闭 Connection、Statement 和 ResultSet 对象。|
|Java 关键字 final、finalize 和 finally 有什么区别?|关键字 final 根据其位置不同,意味着变量只能初始化一次、方法不能被重写或类不能被继承。如果类中定义了 finalize() 方法,当垃圾回收器准备释放该类实例占用的内存时,会调用该方法。关键字 finally 用于 try/catch 块中,放置必须执行的代码,无论 try 块中的代码是否成功执行,例如关闭流的代码。|
|能否在接口中声明字段?|可以,但字段必须是 final 和 static 的。|
|在方法内部声明的内部类能否访问该方法的局部变量?|只有当变量是 final 时才可以。|
|给出一个匿名内部类的例子。|可以动态创建一个事件监听器类作为匿名内部类,例如:
java<br>addActionListener (new ActionListener() {<br> public void actionPerformed (ActionEvent e) {<br> doSomething();<br> }<br>});<br> |
|在 Web 应用程序中可以使用什么来跟踪会话?|可以使用 cookie、URL 重写和 HTTPSession 对象。|
|使用 cookie 进行会话管理是否总是有效?|不是,如果用户在 Web 浏览器中禁用了 cookie,就无法使用。在这种情况下,应用服务器通常会自动切换到 URL 重写。|
|如何停止一个长时间运行的线程?|Thread 类有一个已弃用的方法 stop(),但该方法不能保证线程会停止。根据线程运行的进程,你可以尝试关闭连接或打开的流(如果有的话),或者使用 interrupt() 方法。|
|什么时候可以称一个 Java 类为 bean?|当一个类有一个无参构造函数,实现了 Serializable 接口,并且为其私有属性提供了公共的 setter/getter 方法时,就可以称它为 bean。|
|使用 JSP 而不是 Servlet 有什么优点?|JSP 可以将表示层与业务逻辑分离,生成的网页可以由不懂 Java 的人修改。|
|给出一个例子说明运算符 && 和 & 的区别。|在以下代码片段中,如果变量 a 为 null,if 语句中的第二个表达式将不会被计算。如果使用单个 & 运算符,会抛出 NullPointerException。
java<br>String a = null;<br>if (a == null && a.length() > 10) {...}<br> |
|列举一些预定义的 JSP 变量。|request、response、out、session 等。|
|如何部署 JSP?|可以将 .jsp 文件放在 Servlet 容器或应用服务器的文档根目录中,或者创建一个 war 文件。|
|从 MVC 设计模式的角度来看,为什么 JSF 比 JSP 更可取?|JSF 强制分离表示层和处理逻辑,而 JSP 则没有。|
|Web 服务器进行基于 HTTP 通信时使用的默认端口号是多少?|HTTP 请求使用端口 80,HTTPS 请求使用端口 443。|
|Servlet 类的哪个方法相当于普通 Java 类中的构造函数?|Servlet 的 init() 方法起到类似的作用,但由于所有客户端使用同一个 Servlet 实例,你应该只初始化那些对于每个用户请求都可以有相同值的变量,如数据库服务器的名称。|
|数组和 ArrayList 哪个更快?|大多数情况下数组更快。如果你事先知道数组中的元素数量,可以使用数组。ArrayList 是基于数组的 API,你不需要事先知道其大小,可以根据需要添加新元素。数组更快是因为 JVM 只需要为所有元素分配一次内存。但要给出更准确的答案,需要在具体上下文中编写适当的基准测试。|
|关于 Java 反射你了解多少?|反射是在运行时查找 Java 类信息的一种方式。例如,你可以查找特定类的构造函数和方法签名。Class 类有 getConstructor()、getFields()、getMethods() 等方法。|
|如果 Java 程序在运行时因“内存不足”错误崩溃,你会怎么做?|可以在程序启动时使用命令行参数增加 JVM 的动态内存(堆)大小。例如,你可以请求最小堆大小为 512 MB,最大堆大小为 1024 MB,如下所示:
java<br>java –Xms64 –Xmx512 MyProgram<br> |
|如何确保应用程序中某个类只能创建一个实例?|你需要实现单例设计模式。创建一个具有私有构造函数的类,并提供一个公共的 Get 方法,该方法将返回该类的唯一实例,例如 MyClass.getInstance() 。|
|Hashtable 和 HashMap 有什么主要区别?|Hashtable 类内部是同步的,而 HashMap 不是。|
|列举一些设计模式。|单例模式、MVC 模式、数据传输对象模式、外观模式等。|

7 技术问题解答的流程梳理

为了更清晰地理解这些技术问题的解答思路,我们可以梳理一些关键问题的流程:

7.1 使用 JDBC 从数据库表中获取数据的流程

graph LR
    A[加载 JDBC 驱动] --> B[获取 Connection 对象]
    B --> C[创建 Statement 对象]
    C --> D[执行查询或更新操作]
    D --> E[处理 ResultSet]
    E --> F[关闭资源]

具体步骤如下:
1. 加载 JDBC 驱动 :使用 Class.forName() 方法加载合适的 JDBC 驱动程序。
2. 获取 Connection 对象 :通过 DriverManager.getConnection() 方法建立与数据库的连接。
3. 创建 Statement 对象 :使用 Connection 对象创建一个 Statement 对象,用于执行 SQL 语句。
4. 执行查询或更新操作 :调用 Statement 对象的 executeQuery() executeUpdate() 方法执行相应的 SQL 操作。
5. 处理 ResultSet :如果执行的是查询操作,会返回一个 ResultSet 对象,通过遍历该对象获取查询结果。
6. 关闭资源 :依次关闭 ResultSet、Statement 和 Connection 对象,释放资源。

7.2 用户按下提交按钮后,网页和 Servlet 之间的数据工作流程

graph LR
    A[用户按下提交按钮] --> B[Web 浏览器连接服务器]
    B --> C{Servlet 是否启动}
    C -- 否 --> D[Servlet 容器启动 Servlet]
    C -- 是 --> E[直接处理请求]
    D --> F[调用 init() 方法]
    F --> G[调用 service() 方法]
    E --> G
    G --> H{HTTP 请求方法}
    H -- GET --> I[调用 doGet() 方法]
    H -- POST --> J[调用 doPost() 方法]
    I --> K[使用 HTTPServletRequest 和 HTTPServletResponse 交互]
    J --> K
    K --> L[Servlet 输出返回用户]

具体步骤如下:
1. 用户按下提交按钮 :触发网页向服务器发送请求。
2. Web 浏览器连接服务器 :根据指定的 URL 连接到相应的服务器。
3. 检查 Servlet 是否启动 :如果 Servlet 尚未启动,Servlet 容器会启动它,并调用其 init() 方法进行初始化。
4. 调用 service() 方法 :无论 Servlet 是否刚启动,都会调用其 service() 方法。
5. 根据 HTTP 请求方法调用相应方法 service() 方法会根据请求的 HTTP 方法(GET 或 POST)调用 doGet() doPost() 方法。
6. 使用 HTTPServletRequest 和 HTTPServletResponse 交互 :在 doGet() doPost() 方法中,使用这两个对象处理请求和响应。
7. Servlet 输出返回用户 :通过 HTTPServletResponse 对象的方法(如 println() )将处理结果返回给用户。

8 面试应对策略总结

8.1 知识储备策略

  • 全面学习 :要掌握 Java 相关的多种技术和工具,如 Java Servlet、JSP、Spring 框架等,同时理解它们在实际项目中的应用场景。
  • 深入理解 :对于核心概念,如抽象类和接口的区别、关键字的用途等,要深入理解其原理和应用。
  • 实践积累 :通过参与开源或企业项目,积累实际操作经验,这比单纯的理论知识和证书更有价值。

8.2 面试表现策略

  • 积极态度 :面试时保持活力和对工作的兴趣,展现良好的个性,避免表现得过于自负。
  • 清晰表达 :在回答问题时,要清晰、有条理地表达自己的思路,对于不确定的问题,可以边思考边说出来,让面试官看到你的思考过程。
  • 代码能力 :做好在白板上写代码的准备,注重思考和解决问题的能力,而不是死记硬背代码。

8.3 决策策略

  • 慎重考虑 offer :收到录用 offer 时,不要只看薪资,还要考虑非金钱因素,如工作内容、发展机会、工作环境等。
  • 掌控职业生涯 :根据自己的兴趣和目标,主动规划和发展自己的职业生涯,不要盲目跟从他人的选择。

9 总结

Java 技术面试涵盖了广泛的知识领域,包括语言基础、框架应用、数据库操作、设计模式等。面试者需要具备扎实的理论知识、丰富的实践经验和良好的表达能力。在面对面试时,要做好充分的准备,不仅要掌握常见的技术问题,还要理解其背后的原理和应用场景。同时,在考虑录用 offer 时,要综合考虑各种因素,做出符合自己职业发展规划的决策。

希望通过本文的介绍,能帮助你更好地应对 Java 技术面试,在职业生涯中取得更好的发展。不断学习和实践,提升自己的技术水平和综合素质,是在竞争激烈的 IT 行业中立足的关键。

总之,无论是面试前的准备、面试中的表现,还是面试后的决策,都需要你积极主动地去把握,为自己的职业生涯创造更多的机会和可能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值