Java Web面试题(三)

发布于:2024-04-04 ⋅ 阅读:(101) ⋅ 点赞:(0)

1. 什么是 XSS 攻击,如何避免?

XSS攻击,即跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如cookie等。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、VBScript、ActiveX、Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

XSS攻击可以分为存储型、反射型和DOM型。存储型指的是恶意脚本会存储在目标服务器上,当浏览器请求数据时,脚本从服务器传回并执行。

为了避免XSS攻击,可以采取以下几种方法:

  1. 输入合法性验证:在服务端对用户输入的数据进行合法性验证,如检查输入是否符合指定格式,排除恶意字符等。
  2. 转义特殊字符:在网页中用户输入的内容需要使用转义字符,例如将“<”转义成“<”,将“>”转义成“>”,避免浏览器将这些字符误解为标签等。
  3. 设置HTTP头部:设置HTTP头部,包括Content-Security-Policy、X-Content-Type-Options、X-XSS-Protection等,来使浏览器拦截来自第三方资源的恶意脚本。
  4. 使用脚本过滤器:使用脚本过滤器,如Google的Closure Library和jQuery库等,能够对来自用户的数据进行过滤和检查。
  5. 限制cookie的使用:限制cookie只能在HTTPS连接下使用,并使用HttpOnly标识确保cookie不能通过JavaScript代码访问。
  6. 使用Web应用防火墙(WAF):WAF是一种位于Web应用程序和Web服务器之间的安全设备,可以检测和阻止恶意请求。WAF可以检测XSS攻击的特征,并阻止恶意脚本的注入,保护Web应用程序的安全。
  7. 安全编码实践:在编写Web应用程序代码时,应该遵循安全的编码实践,尽量避免使用具有潜在安全风险的函数,如eval()、innerHTML等。

请注意,上述方法并非绝对的安全保障,而是提高系统安全性的手段。为了全面保护系统免受XSS攻击,需要综合运用多种安全策略,并定期更新和维护。同时,定期进行安全漏洞扫描和风险评估也是非常重要的。

2. 什么是 CSRF 攻击,如何避免?

CSRF(Cross-Site Request Forgery)攻击是一种常见的网络安全威胁。攻击者利用已认证的用户身份,在用户不知情的情况下伪造请求,冒充用户的操作向目标网站发起请求。这种攻击通常利用用户浏览器的跨站请求机制,使用户在浏览器中加载恶意的URL或点击恶意链接,从而实现攻击的目的。

要避免CSRF攻击,开发者可以采取以下防范措施:

  1. 使用随机令牌:在每次向目标网站发送请求时,携带一个随机生成的令牌(Token)。目标网站在处理请求时会校验该令牌的有效性,如果无效则拒绝请求。这样,攻击者无法伪造有效的令牌,从而避免了CSRF攻击。
  2. 充分利用好Cookie的SameSite属性:Cookie是浏览器和服务器之间维护登录状态的一个关键数据。通过设置Cookie的SameSite属性,可以防止第三方站点在未经用户允许的情况下发送带有Cookie的请求。这有助于降低CSRF攻击的风险。

此外,还有其他一些措施可以帮助防范CSRF攻击,如限制敏感操作的访问权限、使用HTTPS协议进行通信等。同时,用户也应保持警惕,避免点击来源不明的链接或下载可疑的附件,以减少被攻击的风险。

请注意,防范CSRF攻击需要综合考虑多个方面,包括技术实现、用户教育和安全管理等。因此,建议开发者在设计和实现Web应用程序时,充分了解CSRF攻击的原理和防范措施,并采取相应的安全措施来保护用户的数据和隐私。

3. 什么是JDBC?

JDBC,全称Java Database Connectivity,即Java数据库连接,是一种用于执行SQL语句的Java API。它由一组用Java语言编写的类和接口组成,为Java程序提供了连接和操作各种关系型数据库的标准化接口。

JDBC的主要作用包括:

  1. 提供统一的数据库访问方式:JDBC定义了一套标准的API,使得Java程序可以以一种统一的方式访问不同的数据库系统。
  2. 简化数据库操作:JDBC API提供了丰富的方法来执行SQL语句和管理数据库连接,极大地简化了数据库编程的复杂性。
  3. 支持事务处理和批处理:JDBC支持事务控制和批处理操作,提高了数据处理的效率和可靠性。
  4. 增强代码的可移植性:由于JDBC是基于Java语言的,所以使用JDBC编写的数据库访问代码具有很好的跨平台性和可移植性。

在使用JDBC时,需要提供数据库驱动程序,这是一个特定数据库的实现,它允许JDBC与数据库进行通信。

4. JDBC访问数据库的基本步骤是什么?

JDBC(Java Database Connectivity)是用于Java编程语言访问关系数据库的标准API。它提供了一组方法和接口,使Java程序能够连接到数据库并执行SQL语句。以下是使用JDBC访问数据库的基本步骤:

  1. 加载并注册JDBC驱动
    首先需要加载数据库的JDBC驱动。这通常通过调用Class.forName()方法来实现,其中参数是驱动类的完整名称。加载驱动后,JDBC会知道如何与特定的数据库通信。

    Class.forName("com.mysql.cj.jdbc.Driver"); // 以MySQL为例
    
  2. 建立数据库连接
    使用DriverManager类的getConnection()方法建立与数据库的连接。需要提供数据库URL、用户名和密码。

    Connection conn = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/mydatabase", "username", "password");
    
  3. 创建Statement对象
    通过Connection对象创建一个Statement对象,这个对象用于执行静态SQL语句并返回结果。

    Statement stmt = conn.createStatement();
    

    或者,为了执行预编译的SQL语句,可以使用PreparedStatement,它提供了更高的性能和安全性,特别是当处理用户输入时。

    String sql = "SELECT * FROM mytable WHERE id = ?";
    PreparedStatement pstmt = conn.prepareStatement(sql);
    pstmt.setInt(1, 123); // 设置参数值
    
  4. 执行SQL语句
    使用StatementPreparedStatement对象执行SQL语句。对于查询操作,可以使用executeQuery()方法;对于更新、插入或删除操作,可以使用executeUpdate()方法。

    ResultSet rs = stmt.executeQuery("SELECT * FROM mytable");
    // 或者
    int rowsAffected = pstmt.executeUpdate();
    
  5. 处理结果
    如果执行的是查询操作,则处理返回的ResultSet对象。通过遍历ResultSet,可以获取查询结果中的数据。

    while (rs.next()) {
        int id = rs.getInt("id");
        String name = rs.getString("name");
        // 处理数据...
    }
    
  6. 关闭资源
    在完成数据库操作后,必须关闭所有打开的资源,包括ResultSetStatementConnection对象。这可以通过调用它们的close()方法实现。通常使用try-with-resources语句可以自动管理资源的关闭。

    try (Connection conn = DriverManager.getConnection(...);
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("...")) {
        // 使用资源...
    } catch (SQLException e) {
        // 处理异常...
    }
    // try-with-resources确保资源自动关闭
    

在实际应用中,这些步骤可能需要根据具体需求进行调整,例如使用连接池来管理数据库连接,或者处理更复杂的SQL语句和事务。此外,处理数据库时,还需要注意异常处理、安全性(如防止SQL注入)以及性能优化等问题。

5. 常见的JDBC异常有哪些?

常见的JDBC异常包括以下几种:

  1. java.lang.ClassNotFoundException:当尝试加载JDBC驱动类时,如果类名或包名写错,或者没有正确引入JDBC的驱动jar包,就会抛出此异常。
  2. java.sql.SQLException: ORA-01017: invalid username/password; logon denied:当提供的用户名或密码无效时,数据库拒绝登录,会抛出此异常。
  3. java.sql.SQLSyntaxErrorException: ORA-00904 或其他SQL语法错误:当SQL语句中存在语法错误,如列名写错时,会抛出此异常。
  4. java.sql.SQLException: connection holder is null:这通常表示数据库连接已经关闭或者超时,但尝试再次使用它时出现了问题。
  5. com.mysql.jdbc.PacketTooBigException:当批量插入大量数据时,如果数据包太大,可能会抛出此异常。这通常建议将数据分片录入到数据库中。
  6. com.mysql.jdbc.exceptions.jdbc4.MySQLDataException:这通常发生在通过ORM框架映射到PO对象时,从数据库中查询出的值和Java类型不匹配,或者执行关联查询时各个表的编码格式不一致。
  7. java.sql.SQLException: ORA-00942: table or view does not exist:这表示SQL语句中引用的表或视图名称不存在。
  8. java.sql.SQLException: 无效的列索引:这可能是因为SQL语句中包含了错误的符号,或者代码中的statement为null。
  9. java.sql.SQLException: Io 异常: Connection resetThe Network Adapter could not establish the connection:这些异常通常与数据库服务的重启、网络断开或数据库连接问题有关。

解决这些异常通常需要检查数据库连接配置、SQL语句的正确性、数据类型匹配以及网络状态等。对于具体的异常信息,应该仔细阅读异常堆栈跟踪,以找到问题的根源,并采取相应的解决措施。

6. JDBC的DataSource是什么,有什么好处?

JDBC中的DataSource是一个接口,它位于javax.sql包中,用于Java应用程序中管理数据库连接。DataSource通常被称为数据源,它包含连接池和连接池管理两个部分,但习惯上也经常把DataSource称为连接池。

DataSource接口替代DriverManager获取Connection的方法,具有多个好处:

  1. 灵活性:DataSource允许在部署时灵活更换Connection实现,使得应用程序更加灵活和可配置。
  2. 屏蔽数据库相关性:通过使用DataSource,可以更好地屏蔽数据库的相关性,使得应用程序更加独立和可移植。
  3. 连接池管理:DataSource提供了连接池管理功能,通过维护一定数量的数据库连接,应用程序可以从连接池中借用连接用于数据库操作,并在使用完后归还到连接池中。这样可以大大减少应用程序连接和释放数据库连接的频率,提高系统性能和稳定性。
  4. 安全性与便利性:使用DataSource,可以将连接相关的数据(如URL、用户名、密码等)配置在外部文件中,而不是直接写在应用程序的代码中,这样既方便管理和维护,也提高了应用程序的安全性。

DataSource有三种类型的实现:基本实现,它生成标准的Connection对象;连接池实现,它生成自动参与连接池的Connection对象。这使得DataSource能够根据不同的需求和应用场景提供适合的连接管理方式。

DataSource为Java应用程序提供了一个标准、统一的方式来获取和释放数据库连接,使得数据库操作更加简便、灵活和安全。

7. execute,executeQuery,executeUpdate的区别是什么?

executeexecuteQuery,和executeUpdate都是JDBC API中java.sql.Statement接口的方法,用于执行SQL语句。它们之间的主要区别如下:

  1. execute()

    • 这个方法用于执行任何类型的SQL语句,包括DDL(数据定义语言)语句,如CREATE TABLEDROP TABLE,以及DML(数据操作语言)语句,如SELECTINSERTUPDATEDELETE
    • 执行后,该方法返回一个布尔值,表示是否返回了结果集。如果返回的是ResultSet对象,则值为true;如果返回的是更新计数(即受影响的行数)或没有结果,则值为false
  2. executeQuery()

    • 这个方法专门用于执行SELECT查询语句。
    • 执行后,它返回一个ResultSet对象,该对象包含与查询语句匹配的所有行。这个ResultSet对象可以用于遍历和访问查询结果。
    • 注意,虽然executeQuery通常与SELECT语句一起使用,但实际上它可以执行任何返回结果集的SQL语句。如果执行的不是SELECT语句,它将抛出SQLException
  3. executeUpdate()

    • 这个方法用于执行INSERTUPDATEDELETE语句,以及SQL DDL语句(如CREATE TABLEDROP TABLE)。
    • 对于INSERTUPDATEDELETE语句,executeUpdate()返回一个整数,表示受影响的行数(即更新计数)。
    • 对于不操作行的DDL语句,executeUpdate()的返回值总是-1

在选择使用哪个方法时,你应该基于你要执行的SQL语句类型来决定。如果你执行的是查询操作(如SELECT),那么应该使用executeQuery()。如果你执行的是更新操作(如INSERTUPDATEDELETE),或者需要执行DDL语句,那么应该使用executeUpdate()。如果你不确定要执行的SQL语句类型,或者需要执行多种类型的语句,那么可以使用execute(),但请注意,你需要根据返回的布尔值来判断结果类型,并相应地处理ResultSet或更新计数。


网站公告

今日签到

点亮在社区的每一天
去签到